While working on a binding for the development branch for the Allegro
game library I ran in to a bit of a problem in that one of the methods
takes a structure of four floating point values (which is how it stores
colors) and this is not done through a pointer to a color struct but by
passing the structure directly to the method; this never actually works
and exploring with GCC shows that the should-be C compatible record
built by FPC 2.5 was fine but the version C had was corrupted. I went to
FPC 2.4rc1 and tried again, and the same issue remains. 32-bit builds
seem to work properly, so I conclude that only the 64-bit version of FPC
is emitting broken code.
The following was generated with 2.4rc1;
Recreating this problem is fairly simple; first you have a source file
written in C code `cpart.c`:
/* Start */
#include stdio.h
struct Bagel
{
float roundness, tastiness;
};
void PrintBagel(struct Bagel b)
{
printf([Bagel Round:%f Tasty:%f]\n, b.roundness, b.tastiness);
}
/* End */
Then you have the trivial Pascal application `ppart.pp`:
(* Start *)
program ppart;
{$LINK cpart}
uses ctypes;
type
{$PACKRECORDS C}
TBagel = record
roundness, tastiness : CFloat;
end;
Procedure PrintBagel(bagel : TBagel); cdecl; external;
var
b : TBagel;
begin
b.roundness := 42.0;
b.tastiness := 1.0;
PrintBagel(b);
end.
(* End *)
Then we compile these:
skrylar)fpc-bug % gcc -c cpart.c ppcx64 ppart
Free Pascal Compiler version 2.4.0rc1 [2009/10/24] for x86_64
Copyright (c) 1993-2009 by Florian Klaempfl
Target OS: Darwin for x86_64
Compiling ppart.pp
Assembling ppart
Linking ppart
22 lines compiled, 0.1 sec
skrylar)fpc-bug %
Run it:
skrylar)fpc-bug % ./ppart
[Bagel Round:0.00 Tasty:-170141183460469231731687303715884105728.00]
skrylar)fpc-bug %
Disassembling through GDB (ATT Syntax ahead):
Dump of assembler code for function PASCALMAIN:
0x000109f0 PASCALMAIN+0: push %rbp
0x000109f1 PASCALMAIN+1: mov%rsp,%rbp
0x000109f4 PASCALMAIN+4: callq 0x100013970
fpc_initializeunits
0x000109f9 PASCALMAIN+9: lea0x1d218(%rip),%rax
# 0x10001dc18 $PPART$_Ld1
0x00010a00 PASCALMAIN+16: mov(%rax),%eax
0x00010a02 PASCALMAIN+18: lea0x2329f(%rip),%rdx
# 0x100023ca8 U_P$PPART_B
0x00010a09 PASCALMAIN+25: mov%eax,(%rdx)
0x00010a0b PASCALMAIN+27: lea0x1d20a(%rip),%rax
# 0x10001dc1c $PPART$_Ld2
0x00010a12 PASCALMAIN+34: mov(%rax),%eax
0x00010a14 PASCALMAIN+36: lea0x2328d(%rip),%rdx
# 0x100023ca8 U_P$PPART_B
0x00010a1b PASCALMAIN+43: mov%eax,0x4(%rdx)
0x00010a1e PASCALMAIN+46: lea0x23283(%rip),%rax
# 0x100023ca8 U_P$PPART_B
0x00010a25 PASCALMAIN+53: mov(%rax),%rdi
0x00010a28 PASCALMAIN+56: callq 0x10a3c PrintBagel
0x00010a2d PASCALMAIN+61: callq 0x100013d70 SYSTEM_DO_EXIT
0x00010a32 PASCALMAIN+66: leaveq
0x00010a33 PASCALMAIN+67: retq
End of assembler dump.
Dump of assembler code for function PrintBagel:
0x00010a3c PrintBagel+0: push %rbp
0x00010a3d PrintBagel+1: mov%rsp,%rbp
0x00010a40 PrintBagel+4: sub$0x10,%rsp
0x00010a44 PrintBagel+8: movq %xmm0,-0x8(%rbp)
0x00010a49 PrintBagel+13: movss -0x4(%rbp),%xmm0
0x00010a4e PrintBagel+18: cvtss2sd %xmm0,%xmm1
0x00010a52 PrintBagel+22: movss -0x8(%rbp),%xmm0
0x00010a57 PrintBagel+27: cvtss2sd %xmm0,%xmm0
0x00010a5b PrintBagel+31: lea0x1d164(%rip),%rdi
# 0x10001dbc6
0x00010a62 PrintBagel+38: mov$0x2,%eax
0x00010a67 PrintBagel+43: callq 0x10001d976
dyld_stub_printf
0x00010a6c PrintBagel+48: leaveq
0x00010a6d PrintBagel+49: retq
0x00010a6e PrintBagel+50: nop
0x00010a6f PrintBagel+51: nop
End of assembler dump.
I asked in IRC and was referred to here; unfortunately with Snow Leopard
GCC compiles in 64-bit by default and so falling back to 32-bit is
exceptionally painful.
___
fpc-devel maillist - fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel