Hello,
I'm finding myself with a peculiar problem. I have a Pascal command-line application using Zeos (trunk) to access databases. I'd like to use this application on a 64-bit Linux server, so I installed a cross-compiler (x86_64-win64 to x86_64-linux, latest fixes3_2 revision) using FPCUpDeluxe and was able to successfully make a binary. The binary runs and is able to connect to the database etc., but as soon as it tries to access a timestamp field, it crashes with a floating point exception. When compiling for Win64, it works fine though.
I was able to trace the exception down to SysUtils.TimestampToMSecs (called from DateTimeToNative in Zeos):
.text:000000000047AE20 lea rsp, [rsp-18h]
.text:000000000047AE25 mov [rsp+18h+var_18], rdi
.text:000000000047AE29 fild dword ptr [rsp+18h+var_18+4]
.text:000000000047AE2D lea rax, unk_67FA40
.text:000000000047AE34 fild qword ptr [rax]
.text:000000000047AE36 fmulp st(1), st
.text:000000000047AE38 fild dword ptr [rsp+18h+var_18]
.text:000000000047AE3B faddp st(1), st
.text:000000000047AE3D fistp [rsp+18h+var_10]
.text:000000000047AE41 fild [rsp+18h+var_10]
.text:000000000047AE45 lea rsp, [rsp+18h]
.text:000000000047AE4A retn
It crashes in the fild instruction with code 0xC0000090.
I then went and looked at the Win64 binary, and to my surprise the code there is much cleaner, utilizing SSE2:
.text:0000000100049640 movsxd rdx, dword ptr [rcx+4]
.text:0000000100049644 imul rdx, 5265C00h
.text:000000010004964B movsxd rax, dword ptr [rcx]
.text:000000010004964E add rax, rdx
.text:0000000100049651 retn
So knowing that in terms of application logic, everything should be fine, I figured that it's probably just the x87 instruction set being a bitch (I really don't feel like diving into it deeper, it usually causes nothing but headaches). I then wanted to get FPC to emit SSE2 code for the Linux build of SysUtils too, but to no avail. I fiddled with the cross compiler options in FPCUpDeluxe (-CpCOREAVX -CfAVX -OpCOREAVX, also other variations for -Cf...) but it's being extremely stubborn and will always output the same legacy code. I don't get why, because the underlying processor architecture is the same for both systems and I don't see anything OS-specific in that function. The only thing I can think of is that it has some dumb ABI restrictions or gets confused by one of the million floating-point type aliases (Comp in this case).
By the way, when I cross-compile to i386-win32, I get the same FPU code with fild and it crashes at the same place. Native x64 is legit the only thing that's working.
It'd be great if someone could shed some light on this frustrating matter.