<div dir="ltr"><div> Hi Balazs,</div><div>I confirm what you observe.</div><div>If I compile the source with:</div><div><br></div><div>    clang --shared -o libalientest.so -Os alientest.c</div><div><br></div><div>then disassemble with:</div><div><br></div><div>    objdump -D libalientest.so  | less</div><div><br></div><div>I get this:</div><div><br></div><div>    000000000000057c <atv>:<br>     57c:   c3                      retq   <br><br>    000000000000057d <at34>:<br>     57d:   f2 0f 10 05 1b 00 00    movsd  0x1b(%rip),%xmm0        # 5a0 <_fini+0x10><br>     584:   00 <br>     585:   f2 0f 10 0d 1b 00 00    movsd  0x1b(%rip),%xmm1        # 5a8 <_fini+0x18><br>     58c:   00 <br>     58d:   c3                      retq  <br></div><div><br></div><div>Code is highly suspicious for atv...<br></div><div>at34 just load the constants in dregs, then do nothing (inline atv).</div><div>So this does not work as advertized...</div><div><br></div><div>The non optimized version is very convoluted:</div><div><br></div><div>0000000000000580 <atv>:<br> 580:   55                      push   %rbp<br> 581:   48 89 e5                mov    %rsp,%rbp<br> 584:   f2 0f 11 45 e8          movsd  %xmm0,-0x18(%rbp)<br> 589:   f2 0f 11 4d e0          movsd  %xmm1,-0x20(%rbp)<br> 58e:   f2 0f 10 45 e8          movsd  -0x18(%rbp),%xmm0<br> 593:   f2 0f 11 45 d0          movsd  %xmm0,-0x30(%rbp)<br> 598:   f2 0f 10 45 e0          movsd  -0x20(%rbp),%xmm0<br> 59d:   f2 0f 11 45 d8          movsd  %xmm0,-0x28(%rbp)<br> 5a2:   0f 10 45 d0             movups -0x30(%rbp),%xmm0<br> 5a6:   0f 29 45 f0             movaps %xmm0,-0x10(%rbp)<br> 5aa:   f2 0f 10 45 f0          movsd  -0x10(%rbp),%xmm0<br> 5af:   f2 0f 10 4d f8          movsd  -0x8(%rbp),%xmm1<br> 5b4:   5d                      pop    %rbp<br> 5b5:   c3                      retq   <br> 5b6:   66 2e 0f 1f 84 00 00    nopw   %cs:0x0(%rax,%rax,1)<br> 5bd:   00 00 00 <br><br>00000000000005c0 <at34>:<br> 5c0:   55                      push   %rbp<br> 5c1:   48 89 e5                mov    %rsp,%rbp<br> 5c4:   48 83 ec 10             sub    $0x10,%rsp<br> 5c8:   f2 0f 10 05 38 00 00    movsd  0x38(%rip),%xmm0        # 608 <_fini+0x10><br> 5cf:   00 <br> 5d0:   f2 0f 10 0d 38 00 00    movsd  0x38(%rip),%xmm1        # 610 <_fini+0x18><br> 5d7:   00 <br> 5d8:   e8 a3 ff ff ff          callq  580 <atv><br> 5dd:   f2 0f 11 45 f0          movsd  %xmm0,-0x10(%rbp)<br> 5e2:   f2 0f 11 4d f8          movsd  %xmm1,-0x8(%rbp)<br> 5e7:   f2 0f 10 45 f0          movsd  -0x10(%rbp),%xmm0<br> 5ec:   f2 0f 10 4d f8          movsd  -0x8(%rbp),%xmm1<br> 5f1:   48 83 c4 10             add    $0x10,%rsp<br> 5f5:   5d                      pop    %rbp<br> 5f6:   c3                      retq   <br></div><div>
<div><br></div><div>It's clear that the resulting structure is passed via first 2 dregs (xmm0 and xmm1).<br></div><div>Doesn't it qualify as a clang bug? Or is our interpretation of ABI erroneous?</div>

</div><div>I would opt for the later...<br></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">Le mar. 5 nov. 2019 à 23:54, Balázs Kósi <<a href="mailto:rebmekop@gmail.com">rebmekop@gmail.com</a>> a écrit :<br></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>Hi all,</div><div><br></div><div>I'm having trouble with calling struct returning functions with alien on a 64bit linux vm using the hidden first argument mechanism [1]. The function gets called, but the result is not copied into the struct pointed by the hidden argument.</div><div><br></div><div>I tried to debug what happens with gdb, but everything looks fine, except not getting the result back. The address is copied into %rdi (regs[0]) in dax64business.h:92 [2], which is exactly what the spec says [3].<br></div><div><br></div><div>Here is a minimal example calling a C function returning a struct with two doubles:<br></div><div><br></div><div>at34 := Alien lookup: 'at34' inLibrary: 'libalientest.so'.<br>at34 primFFICallResult: nil with: (r := Alien newC: 16) pointer.<br>vec := (r doubleAt: 1) @ (r doubleAt: 9). r free. vec " 0.0@0.0 "<br></div><div><br></div><div>returns 0.0@0.0 instead of 3.0@4.0<br></div><div><br></div><div>the C code goes like this:<br></div><div><br></div><div>typedef struct atvect{double x, y;} atvect;</div><div><br></div><div>atvect atv(double x, double y) {<br>  atvect v = {x, y};<br>  return v;<br>}<br></div><div><br></div><div>atvect at34() {<br>  return atv(3.0, 4.0);<br>}</div><div><br></div><div>The vm is sqcogspur64linuxht 5.0-201910291408. The image is a recent trunk image (update: #19142), image format 68021 (64 bit). Alien is Alien-Core-TorstenBergmann.101.mcz.</div><div><br></div><div>What am I missing?<br></div><div><br></div><div>Thanks, Balázs</div><div><br></div><div>[1] "The rules for structure results vary slightly by platform. Most functions returning structures expect a “hidden” first parameter holding the result struct’s address. Because the FFI provides no abstraction one must pass this parameter explicitly. ... On linux all struct results are re-turned through the hidden first argument mechanism ... ". <br></div><div><br></div><div><a href="https://wiki.squeak.org/squeak/uploads/6100/Alien%20FFI.2.pdf" target="_blank">https://wiki.squeak.org/squeak/uploads/6100/Alien%20FFI.2.pdf</a></div><div><br></div><div>[2] <a href="https://github.com/OpenSmalltalk/opensmalltalk-vm/blob/a8a1dc1e33267e0fa2dab22959e41d0a072420d9/platforms/Cross/plugins/IA32ABI/dax64business.h#L92" target="_blank">https://github.com/OpenSmalltalk/opensmalltalk-vm/blob/a8a1dc1e33267e0fa2dab22959e41d0a072420d9/platforms/Cross/plugins/IA32ABI/dax64business.h#L92</a></div><div><br></div><div>[3] "2. If the type has class MEMORY, then the caller provides space for the return value and passes the address of this storage in %rdi as if it were the first<br>argument to the function. In effect, this address becomes a “hidden” first ar-<br>gument. This storage must not overlap any data visible to the callee through<br>other names than this argument. <br></div><div>On return %rax will contain the address that has been passed in by the<br>caller in %rdi."</div><div><br></div><div> <a href="https://github.com/hjl-tools/x86-psABI/wiki/x86-64-psABI-1.0.pdf" target="_blank">https://github.com/hjl-tools/x86-psABI/wiki/x86-64-psABI-1.0.pdf</a> p.24.<br></div></div>
<br>
</blockquote></div>