LongInt on 32 bit architecture

General FreeBASIC programming questions.
bcohio2001
Posts: 556
Joined: Mar 10, 2007 15:44
Location: Ohio, USA
Contact:

LongInt on 32 bit architecture

Post by bcohio2001 »

How does the 32 bit version of FB "emulate" a LongInt (64 bit).
SARG
Posts: 1763
Joined: May 27, 2005 7:15
Location: FRANCE

Re: LongInt on 32 bit architecture

Post by SARG »

There is an extra virtual register to handle the higher 32 bits.

Code: Select all

type IRVREG
	typ			as IRVREGTYPE_ENUM				'' VAR, IMM, IDX, etc
	dtype		as FB_DATATYPE					'' CHAR, INTEGER, ...
	subtype		as FBSYMBOL ptr
	reg			as integer						'' reg
	regFamily		as IR_REGFAMILY
	vector		as integer
	value		as FBVALUE						'' imm value (hi-word of longint's at vaux->value)
	sym			as FBSYMBOL ptr					'' symbol
	ofs			as longint					'' +offset
	mult		as integer						'' multipler, only valid for IDX and PTR under ir-tac
	vidx		as IRVREG ptr					'' index vreg
	vaux		as IRVREG ptr					'' aux vreg (used with longint's)     <----------------------------------- there
	tacvhead	as IRTACVREG ptr				'' back-link to tac table
	tacvtail	as IRTACVREG ptr				'' /
	taclast		as IRTAC ptr					'' /
end type
And when data is put in real register, two registers are used which must always be kept associated.
In memory not a problem : 2 * 32bit contiguous memory.

Hope that is clear and enough.
jj2007
Posts: 2326
Joined: Oct 23, 2016 15:28
Location: Roma, Italia
Contact:

Re: LongInt on 32 bit architecture

Post by jj2007 »

I don't know how FB handles this under the hood, but in 32-bit Assembly you can declare QWORDs, move them into xmm registers with the movlps instruction, and do all kinds of mathematical stuff by loading 64-bit memory variables with fild qword ptr [reg32] onto the FPU.
bcohio2001
Posts: 556
Joined: Mar 10, 2007 15:44
Location: Ohio, USA
Contact:

Re: LongInt on 32 bit architecture

Post by bcohio2001 »

I understand about the 2 associated registers/variables.
But a little to technical for my use.

I thought that if a 32 bit system could handle a 64 bit number, then why couldn't a 64 bit system handle a 128 bit integer!

Code: Select all

'LONGINT (64 signed integer) -9223372036854775808 to +9223372036854775807 
'ULONGINT (64 unsigned integer) 0 to +18446744073709551615

Type fwdbit128 As Bit128

Dim Shared As String strHigh(63)
strHigh(0) = "18446744073709551616" 'High 0 bit set

Type UBit128
	As ULongInt Low, High
	Declare Constructor(ByVal LI As ULongInt=0)
	Declare Constructor(ByRef B128 As UBit128)
	'Declare Constructor(ByRef B128 As fwdbit128)
	Declare Operator Let (ByVal LI As ULongInt)
	Declare Operator Cast() As String
	Declare Operator += (Byref u As UBit128)
End Type
I am also adding a signed version.
SARG
Posts: 1763
Joined: May 27, 2005 7:15
Location: FRANCE

Re: LongInt on 32 bit architecture

Post by SARG »

bcohio2001 wrote:I thought that if a 32 bit system could handle a 64 bit number, then why couldn't a 64 bit system handle a 128 bit integer!
There is no problem it's just manipulate data. You could even have 1024 or more bits.
A small issue : you need to use a library like GMP to all the calculations (+,-, etc) or code it yourself (add or sub are easily done).
jj2007
Posts: 2326
Joined: Oct 23, 2016 15:28
Location: Roma, Italia
Contact:

Re: LongInt on 32 bit architecture

Post by jj2007 »

On the hardware side, a 32-bit program can easily handle 64-bit (using SSE) and even 80-bit numbers (using the FPU). There is no need to "emulate" a LongInt. For 128-bit numbers, you need a library like QuadMath, see here for a non-FB example.

Honestly, I don't understand why FB would need one virtual register or two real registers to do that; it can't be efficient. The FPU has 8 registers for doing 64-bit or 80-bit math, and SSE is designed to handle 64-bit values in 8 xmm registers. There are shrewd instructions like shrd that need two registers, but they are rarely useful (I use them twice in a 40,000 lines source).
SARG
Posts: 1763
Joined: May 27, 2005 7:15
Location: FRANCE

Re: LongInt on 32 bit architecture

Post by SARG »

@jj2007 I was just replying to OP. That how it's handled in 32bit version. No judgment all roads lead to Rome.
jj2007 wrote:Honestly, I don't understand why FB would need one virtual register or two real registers to do that; it can't be efficient
About virtual registers remember that the compilation is not done directly in assembly there are few stages before emitting asm code. It's in these stages that data is handled with virtual registers.
You often say : I in assembly I do thing like that but here the starting point is Basic.

And when moving longints

Code: Select all

##dim as longint aaa,bbb
	mov dword ptr [ebp-12], 0
	mov dword ptr [ebp-8], 0
	mov dword ptr [ebp-20], 0
	mov dword ptr [ebp-16], 0

##bbb=aaa
	mov ebx, dword ptr [ebp-12]
	mov eax, dword ptr [ebp-8]
	mov dword ptr [ebp-20], ebx
	mov dword ptr [ebp-16], eax
I don't want to start a war with you, there are enough IRL. :-)
jj2007
Posts: 2326
Joined: Oct 23, 2016 15:28
Location: Roma, Italia
Contact:

Re: LongInt on 32 bit architecture

Post by jj2007 »

SARG wrote:here the starting point is Basic
Absolutely no war intended on my side, SARG - you are doing excellent work! But the starting point is Assembly, under the hood ;-)
bcohio2001
Posts: 556
Joined: Mar 10, 2007 15:44
Location: Ohio, USA
Contact:

Re: LongInt on 32 bit architecture

Post by bcohio2001 »

SARG wrote:use a library like GMP to all the calculations (+,-, etc) or code it yourself (add or sub are easily done).
Looked into GMP, although the library is not included, in the ".bi' file has all the functions needed.
So ... not going to reinvent the wheel. GMP would be like a monster truck tire, while mine would be a "Fred Flintstone" tire!
SARG
Posts: 1763
Joined: May 27, 2005 7:15
Location: FRANCE

Re: LongInt on 32 bit architecture

Post by SARG »

bcohio2001 wrote:Looked into GMP, although the library is not included,
Maybe you have already found the library.
Otherwise there is a topic where srvaldez posted a link to download it. https://freebasic.net/forum/viewtopic.php?f=3&t=24110

@jj2007 Thanks. :-)
srvaldez
Posts: 3379
Joined: Sep 25, 2005 21:54

Re: LongInt on 32 bit architecture

Post by srvaldez »

@bcohio2001
if you only want to use big integers then have a look at viewtopic.php?t=25684
marcov
Posts: 3462
Joined: Jun 16, 2005 9:45
Location: Netherlands
Contact:

Re: LongInt on 32 bit architecture

Post by marcov »

Usually for 2*wordsize emulated routines are fairly thin and can be inlined. A int32*int32 with 64-bit result is often included in the instruction sets. Larger helpers (like Divide) are part of the library (for gcc in libgcc).

COMP (64-bit int in FPU) used to be slow and was rarely used for this purpose. SSE2 XMM registers are not volatile in 32-bits ABI so need costly register save and possible aligning (older CPUs can only load naturally aligned values and unaligned loads are SSE3). To my best knowledge they are not commonly used to emulate int64, but I have to confess that I haven't looked at libgcc in a long time. Maybe it does for DIV/MOD.
jj2007
Posts: 2326
Joined: Oct 23, 2016 15:28
Location: Roma, Italia
Contact:

Re: LongInt on 32 bit architecture

Post by jj2007 »

marcov wrote:SSE2 XMM registers are not volatile in 32-bits ABI so need costly register save
Strangely enough, Google refuses to give me the x86 ABI - but I'm pretty sure that xmm0 ... xmm3 are volatile registers. From my own experience, certain Windows functions started trashing these registers from Win7-64 onwards (maybe from XP-64, but I never owned that version). I like this one: "The MMX and floating-point stack registers (MM0-MM7/ST0-ST7) are preserved across context switches. There's no explicit calling convention for these registers" ;-)

In contrast, the x64 ABI considers the registers RAX, RCX, RDX, R8, R9, R10, R11, and XMM0-XMM5 volatile
marcov
Posts: 3462
Joined: Jun 16, 2005 9:45
Location: Netherlands
Contact:

Re: LongInt on 32 bit architecture

Post by marcov »

jj2007 wrote:
marcov wrote:SSE2 XMM registers are not volatile in 32-bits ABI so need costly register save
Strangely enough, Google refuses to give me the x86 ABI - but I'm pretty sure that xmm0 ... xmm3 are volatile registers. From my own experience, certain Windows functions started trashing these registers from Win7-64 onwards (maybe from XP-64, but I never owned that version). I like this one: "The MMX and floating-point stack registers (MM0-MM7/ST0-ST7) are preserved across context switches. There's no explicit calling convention for these registers" ;-)

In contrast, the x64 ABI considers the registers RAX, RCX, RDX, R8, R9, R10, R11, and XMM0-XMM5 volatile
Yes. X(86_)64 is fine. Bit x32/x86 it is not defined. Kernel support for preserving registers is something else then ABI awareness.

But maybe I'm wrong and you can consider them volatile, always. And is my gut feeling unease is caused by the exact opposite of what I said, iow no non-volatile registers, and that you can't rely on anything staying safe when calling another function.

It might be that some compilers define some additional ABI stuff when certain options (e.g. SSE floating point) are used. To be honest, all but one of my work apps are x64, and the one that isn't is only 32-bit because it runs faster (x87 faster than SSE2 FP it seems, which might also be a Delphi issue). As such I mostly concentrate on x64 now.
SARG
Posts: 1763
Joined: May 27, 2005 7:15
Location: FRANCE

Re: LongInt on 32 bit architecture

Post by SARG »

jj2007 wrote:Strangely enough, Google refuses to give me the x86 ABI - but I'm pretty sure that xmm0 ... xmm3 are volatile registers
Agner Fog's manuals are a great source of information.
https://www.agner.org/optimize/calling_conventions.pdf
Chapter 6 page 10 : register usage

Don't forget Linux and Windows ABI are different.
Post Reply