[fpc-devel] Additional notes to bug 0007453 (parameter passing linux-x86_64)

Ivo Steinmann ivo_steinmann at gmx.net
Sat Sep 23 02:34:34 CEST 2006


Hello

I dont know how to add my own notes to the bug 
http://www.freepascal.org/mantis/bug_view_advanced_page.php?bug_id=7453
so I will do it here.

The following pascal code is translated wrong into assembler on x86_64

type
  OggVorbis_File = record
    //...
  end;

  ov_callbacks = record
    read            : read_func;  // callbacks
    seek            : seek_func;
    close           : close_func;
    tell            : tell_func;
  end;

function ov_open_callbacks(datasource: pointer; var vf: OggVorbis_File; 
initial: pointer; ibytes: clong; callbacks: ov_callbacks): cint; cdecl; 
external

var
  source: pointer;
  ogg_vorbis: OggVorbis_File
begin
  ov_open_callbacks(source, ogg_vorbis, nil, 0, ogg_callbacks);
end;

output:

# ov_open_callbacks(source, ogg_vorbis, nil, 0, ogg_callbacks)
        movq    $U_P$TEST_OGG_CALLBACKS,%r8
        movq    $0,%rcx
        movq    $0,%rdx
        movq    $U_P$TEST_OGG_VORBIS,%rsi
        movq    U_P$TEST_SOURCE,%rdi
        call    ov_open_callbacks

This asm code is wrong, because the rules of passing a structure to a 
function an linux/amd64 are:
Entire object is transferred in integer registers and/or XMM registers 
if the size is no
bigger than 128 bits, otherwise on the stack. Each 64-bit part of the 
object is
transferred in an XMM register if it contains only float or double, or 
in an integer
register if it contains integer types or mixed integer and float. Two 
consecutive floats
can be packed into the lower half of one XMM register. Consecutive 
doubles are not
packed. No more than 64 bits of each XMM register is used. Use S if not 
enough
vacant registers for the entire object.

so, the asm code should look like this:

        movq    U_P$TEST_SOURCE,%rdi
        movq    $U_P$TEST_OGG_VORBIS,%rsi
        movq    $0,%rdx
        movq    $0,%rcx
        pushq   $P$TEST_OGG_TELL_FUNC$POINTER$$INT64
        pushq   $P$TEST_OGG_CLOSE_FUNC$POINTER$$LONGINT
        pushq   $P$TEST_OGG_SEEK_FUNC$POINTER$INT64$LONGINT$$LONGINT
        pushq   $P$TEST_OGG_READ_FUNC$POINTER$QWORD$QWORD$POINTER$$QWORD
        call    ov_open_callbacks


I tested that with inline assembler, and it's working ;)


greetings
Ivo Steinmann



More information about the fpc-devel mailing list