<div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div class="gmail_quote"><div dir="ltr">On Thu, Nov 1, 2018 at 2:11 AM silvioprog <<a href="mailto:silvioprog@gmail.com" target="_blank">silvioprog@gmail.com</a>> wrote:</div><div dir="ltr">[...]</div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div class="gmail_quote"><div>I took a look at some System V ABI manuals to start a draft based on them, adapting the assembly to the <font face="monospace, monospace" size="1">InvokeKernelWin64()</font> signature idea. The draft works fine for six or more arguments and returns the function value too, but I need to check (probably next weekend) how to pass floating-point values to the <font face="monospace, monospace">XMM</font> registers (I'm looking for references/manuals about).</div></div></div></div></div></div></div></div></div></div></div></div></blockquote></div><div><br></div><div>Finally, I found a awesome material to study: the GCC's X86-64 assembly for compiler writers. And after some successful tests, I concluded that:</div><div><br></div><div>- floating-point types with size 8 or less (double, single etc.) must be set in XMM registers aligned in 8;</div><div>- floating-point types larger than 8 (extended) must be pushed to the stack aligned in 10.</div><div><br></div><div>This is a small example to check it (environment used in the tests: Lazarus 2.1.0 r59363 FPC 3.1.1 x86_64-linux-gtk2):</div><div><br></div><div>===</div><div><div><font face="monospace, monospace" size="1">program project1;</font></div><div><font face="monospace, monospace" size="1"><br></font></div><div><font face="monospace, monospace" size="1">{$MODE DELPHI}</font></div><div><font face="monospace, monospace" size="1">{$MACRO ON}</font></div><div><font face="monospace, monospace" size="1">//{$DEFINE USE_EXTENDED}</font></div><div><font face="monospace, monospace" size="1">{$IFDEF USE_EXTENDED}</font></div><div><font face="monospace, monospace" size="1"> {$DEFINE FLOAT_TYPE := extended} // size 10</font></div><div><font face="monospace, monospace" size="1">{$ELSE}</font></div><div><font face="monospace, monospace" size="1"> {$DEFINE FLOAT_TYPE := double} // size 8</font></div><div><font face="monospace, monospace" size="1">{$ENDIF}</font></div><div><font face="monospace, monospace" size="1"><br></font></div><div><font face="monospace, monospace" size="1">uses sysutils;</font></div><div><font face="monospace, monospace" size="1"><br></font></div><div><font face="monospace, monospace" size="1">procedure test(const a, b: FLOAT_TYPE);</font></div><div><font face="monospace, monospace" size="1">begin</font></div><div><font face="monospace, monospace" size="1">  writeln(a:0:2, ' - ', b:0:2);</font></div><div><font face="monospace, monospace" size="1">end;</font></div><div><font face="monospace, monospace" size="1"><br></font></div><div><font face="monospace, monospace" size="1">procedure call_test(arr: pointer; f: codepointer); assembler; nostackframe;</font></div><div><font face="monospace, monospace" size="1">asm</font></div><div><font face="monospace, monospace" size="1">  { save the base pointer }</font></div><div><font face="monospace, monospace" size="1">  pushq %rbp</font></div><div><font face="monospace, monospace" size="1">  { set new base pointer }</font></div><div><font face="monospace, monospace" size="1">  movq  %rsp, %rbp</font></div><div><font face="monospace, monospace" size="1"><br></font></div><div><font face="monospace, monospace" size="1">  { save callee-saved registers }</font></div><div><font face="monospace, monospace" size="1">  pushq %rbx</font></div><div><font face="monospace, monospace" size="1">  pushq %r12</font></div><div><font face="monospace, monospace" size="1">  pushq %r13</font></div><div><font face="monospace, monospace" size="1">  pushq %r14</font></div><div><font face="monospace, monospace" size="1">  pushq %r15</font></div><div><font face="monospace, monospace" size="1"><br></font></div><div><font face="monospace, monospace" size="1">{$IFDEF USE_EXTENDED}</font></div><div><font face="monospace, monospace" size="1">  leaq 0(%rdi), %rdx</font></div><div><font face="monospace, monospace" size="1">  movq (%rdx), %rax</font></div><div><font face="monospace, monospace" size="1">  movq %rax, (%rsp)</font></div><div><font face="monospace, monospace" size="1">  movq 0x8(%rdx), %ax</font></div><div><font face="monospace, monospace" size="1">  movq %ax, 0x8(%rsp)</font></div><div><font face="monospace, monospace" size="1"><br></font></div><div><font face="monospace, monospace" size="1">  leaq 10(%rdi), %rax</font></div><div><font face="monospace, monospace" size="1">  movq (%rax), %rdx</font></div><div><font face="monospace, monospace" size="1">  movq %rdx, 0x10(%rsp)</font></div><div><font face="monospace, monospace" size="1">  movq 0x8(%rax), %ax</font></div><div><font face="monospace, monospace" size="1">  movq %ax, 0x18(%rsp)</font></div><div><font face="monospace, monospace" size="1">{$ELSE}</font></div><div><font face="monospace, monospace" size="1">  movq 0(%rdi), %xmm0</font></div><div><font face="monospace, monospace" size="1">  movq 8(%rdi), %xmm1</font></div><div><font face="monospace, monospace" size="1">{$ENDIF}</font></div><div><font face="monospace, monospace" size="1"><br></font></div><div><font face="monospace, monospace" size="1">  { call the function }</font></div><div><font face="monospace, monospace" size="1">  callq *%rsi</font></div><div><font face="monospace, monospace" size="1"><br></font></div><div><font face="monospace, monospace" size="1">  { restore callee-saved registers }</font></div><div><font face="monospace, monospace" size="1">  popq %r15</font></div><div><font face="monospace, monospace" size="1">  popq %r14</font></div><div><font face="monospace, monospace" size="1">  popq %r13</font></div><div><font face="monospace, monospace" size="1">  popq %r12</font></div><div><font face="monospace, monospace" size="1">  popq %rbx</font></div><div><font face="monospace, monospace" size="1"><br></font></div><div><font face="monospace, monospace" size="1">  { reset stack to base pointer }</font></div><div><font face="monospace, monospace" size="1">  movq %rbp, %rsp</font></div><div><font face="monospace, monospace" size="1">  { restore the old base pointer }</font></div><div><font face="monospace, monospace" size="1">  popq %rbp</font></div><div><font face="monospace, monospace" size="1">  { return to caller }</font></div><div><font face="monospace, monospace" size="1">  retq</font></div><div><font face="monospace, monospace" size="1">end;</font></div><div><font face="monospace, monospace" size="1"><br></font></div><div><font face="monospace, monospace" size="1">var</font></div><div><font face="monospace, monospace" size="1">  arr: array of FLOAT_TYPE;</font></div><div><font face="monospace, monospace" size="1">begin</font></div><div><font face="monospace, monospace" size="1">  Writeln(IntToStr(SizeOf(FLOAT_TYPE)));</font></div><div><font face="monospace, monospace" size="1">{$PUSH}{$WARN 5090 OFF}</font></div><div><font face="monospace, monospace" size="1">  setlength(arr, 2);</font></div><div><font face="monospace, monospace" size="1">{$POP}</font></div><div><font face="monospace, monospace" size="1">  arr[0] := 12.34;</font></div><div><font face="monospace, monospace" size="1">  arr[1] := 45.67;</font></div><div><font face="monospace, monospace" size="1">  call_test(@arr[0], @test);</font></div><div><font face="monospace, monospace" size="1">end.</font></div></div><div>===</div><div><br></div><div>and the results was:</div><div><br><font face="monospace, monospace">//{$DEFINE USE_EXTENDED}:</font></div><div><br>===<br><font face="monospace, monospace" size="1">...<br>8<br>12.34 - 45.67</font><br>===<br></div><div><br></div><div><span style="font-family:monospace,monospace">{$DEFINE USE_EXTENDED}:</span><br></div><div><br></div><div>===</div><div><font face="monospace, monospace" size="1">...</font></div><div><div><font face="monospace, monospace" size="1">10</font></div><div><font face="monospace, monospace" size="1">12.34 - 45.67</font></div></div><div>===</div><div dir="ltr"><br></div><div>I'm going to clone the Free Pascal repository from Github to work on this feature (sysv ABI for Linux 64 for now). After some functional code I'll send it as patch to the Mantis issues. I'm very interested in <font face="monospace, monospace" size="1">rtti.invoke()</font> support on Linux/ARM and Win32. :-)</div><div dir="ltr"><br></div><div>(P.S.: Could you check the issue #34496? I'm not sure if saving the base pointer is best way to solve the problem, but at least fixed the AV for extended types)</div><div dir="ltr"><br></div>--<br><div dir="ltr" class="m_8828512317851345641gmail_signature"><div dir="ltr"><div>Silvio Clécio</div></div></div></div></div></div></div></div></div></div></div></div></div>