LongInt on 32 bit architecture
-
- Posts: 556
- Joined: Mar 10, 2007 15:44
- Location: Ohio, USA
- Contact:
LongInt on 32 bit architecture
How does the 32 bit version of FB "emulate" a LongInt (64 bit).
Re: LongInt on 32 bit architecture
There is an extra virtual register to handle the higher 32 bits.
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.
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
In memory not a problem : 2 * 32bit contiguous memory.
Hope that is clear and enough.
Re: LongInt on 32 bit architecture
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.
-
- Posts: 556
- Joined: Mar 10, 2007 15:44
- Location: Ohio, USA
- Contact:
Re: LongInt on 32 bit architecture
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!
I am also adding a signed version.
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
Re: LongInt on 32 bit architecture
There is no problem it's just manipulate data. You could even have 1024 or more bits.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!
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).
Re: LongInt on 32 bit architecture
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).
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).
Re: LongInt on 32 bit architecture
@jj2007 I was just replying to OP. That how it's handled in 32bit version. No judgment all roads lead to Rome.
You often say : I in assembly I do thing like that but here the starting point is Basic.
And when moving longints
I don't want to start a war with you, there are enough IRL. :-)
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.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
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
Re: LongInt on 32 bit architecture
Absolutely no war intended on my side, SARG - you are doing excellent work! But the starting point is Assembly, under the hood ;-)SARG wrote:here the starting point is Basic
-
- Posts: 556
- Joined: Mar 10, 2007 15:44
- Location: Ohio, USA
- Contact:
Re: LongInt on 32 bit architecture
Looked into GMP, although the library is not included, in the ".bi' file has all the functions needed.SARG wrote:use a library like GMP to all the calculations (+,-, etc) or code it yourself (add or sub are easily done).
So ... not going to reinvent the wheel. GMP would be like a monster truck tire, while mine would be a "Fred Flintstone" tire!
Re: LongInt on 32 bit architecture
Maybe you have already found the library.bcohio2001 wrote:Looked into GMP, although the library is not included,
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. :-)
Re: LongInt on 32 bit architecture
@bcohio2001
if you only want to use big integers then have a look at viewtopic.php?t=25684
if you only want to use big integers then have a look at viewtopic.php?t=25684
Re: LongInt on 32 bit architecture
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.
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.
Re: LongInt on 32 bit architecture
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" ;-)marcov wrote:SSE2 XMM registers are not volatile in 32-bits ABI so need costly register save
In contrast, the x64 ABI considers the registers RAX, RCX, RDX, R8, R9, R10, R11, and XMM0-XMM5 volatile
Re: LongInt on 32 bit architecture
Yes. X(86_)64 is fine. Bit x32/x86 it is not defined. Kernel support for preserving registers is something else then ABI awareness.jj2007 wrote: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" ;-)marcov wrote:SSE2 XMM registers are not volatile in 32-bits ABI so need costly register save
In contrast, the x64 ABI considers the registers RAX, RCX, RDX, R8, R9, R10, R11, and XMM0-XMM5 volatile
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.
Re: LongInt on 32 bit architecture
Agner Fog's manuals are a great source of information.jj2007 wrote:Strangely enough, Google refuses to give me the x86 ABI - but I'm pretty sure that xmm0 ... xmm3 are volatile registers
https://www.agner.org/optimize/calling_conventions.pdf
Chapter 6 page 10 : register usage
Don't forget Linux and Windows ABI are different.