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
_______________________________________________
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel

Reply via email to