Skip to content

x86-64 uses FPU instructions to prepare stack arguments.

On x86-64/win64, this code:

{$mode objfpc} {$longstrings on}
var
	dummyString: string;

procedure DoSomething1(p0, p1, p2, p3, p4: uint32; p5: double);
begin
	WriteStr(dummyString, p0, p1, p2, p3, p4, p5);
end;

procedure DoSomething2(p5: double; p0, p1, p2, p3, p4: uint32);
begin
	WriteStr(dummyString, p0, p1, p2, p3, p4, p5);
end;

begin
	DoSomething1(1, 2, 3, 4, 5, 123.45);
	DoSomething2(123.45, 1, 2, 3, 4, 5);
end.

compiles (-O3) into:

; [16] DoSomething1(1, 2, 3, 4, 5, 123.45);
	movl	$5,32(%rsp)
	fldl	_$PROGRAM$_Ld1(%rip)
	fstpl	40(%rsp)
	movl	$3,%r8d
	movl	$2,%edx
	movl	$1,%ecx
	movl	$4,%r9d
	call	P$PROGRAM_$$_DOSOMETHING1$LONGWORD$LONGWORD$LONGWORD$LONGWORD$LONGWORD$DOUBLE
; [17] DoSomething2(123.45, 1, 2, 3, 4, 5);
	movl	$5,40(%rsp)
	movl	$4,32(%rsp)
	movsd	_$PROGRAM$_Ld1(%rip),%xmm0
	movl	$3,%r9d
	movl	$2,%r8d
	movl	$1,%edx
	call	P$PROGRAM_$$_DOSOMETHING2$DOUBLE$LONGWORD$LONGWORD$LONGWORD$LONGWORD$LONGWORD

Are these FLD and FSTP intended? I mean, FLD RIP-relative + FSTP to address with 1-byte offset occupy 10 bytes which is 2 bytes shorter than their alternative MOV RIP-relative to 64-bit reg + MOV 64-bit reg to address with 1-byte offset that occupy 12, but isn’t FPU deprecated?

To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information