Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-devel / 2006-09

Additional notes to bug 0007453 (parameter passing linux-x86_64)

2 messages · 2 people ·

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Ivo Steinmann

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

Reply by email