Personally, I'd love to see a setup where instead of LLVM implementing each calling convention and ABI hack, we provide a means of actually describing this. Specifically, I'd love to see a design for how to specify in the IR which register(s) (if any register(s)) a particular value should be placed into.<div>
<br></div><div>Don't get me wrong, I don't have any good ideas about how to do this, I'm just hoping someone does. End result might allow something like:</div><div><br></div><div>declare void @foo(double inreg <eax,edx> %x)</div>
<div class="gmail_extra"><br><br><div class="gmail_quote">On Fri, Oct 19, 2012 at 8:17 AM, Rafael Espíndola <span dir="ltr"><<a href="mailto:rafael.espindola@gmail.com" target="_blank">rafael.espindola@gmail.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Functions with __attribute__((fastcall)) pop their arguments and take<br>
up to two arguments in ecx and edx. Currently we represent them by<br>
just setting the x86_fastcallcc calling convention. The problem is<br>
that the ABI has some strange conventions on when a register is used<br>
or not. For example:<br>
<br>
void __attribute__((fastcall)) foo1(int y);<br>
<br>
will take 'y' in ecx, but<br>
<br>
struct S1 {<br>
  int x;<br>
};<br>
void __attribute__((fastcall)) foo2(struct S1 y);<br>
<br>
will use the stack. Even more surprising is that<br>
<br>
void __attribute__((fastcall)) foo8(struct S1 a, int b);<br>
<br>
will take 'a' in the stack but 'b' in *edx*. That is, the first<br>
argument consumed ecx but didn't use it. The implement this the IL<br>
needs to be able to represent that<br>
* an argument will go on registers<br>
* a register was consumed but unused<br>
<br>
A way to do this is to make clang produce byval for anything that goes<br>
on the stack, but that produces worse code as the caller now has to<br>
use an alloca instead of a simple value.<br>
<br>
Another option (which I implemented in a patch just sent to<br>
llvm-commits) is use the inreg attribute which we already use for the<br>
regparm C attribute. The above requirements are handled by putting<br>
inreg in the arguments that should go in register and creating a inreg<br>
padding argument when a register should be consumed but not used.<br>
<br>
The above examples would be irgened to:<br>
<br>
declare x86_fastcallcc void @foo1(i32 inreg<br>
<br>
declare x86_fastcallcc void @foo2(i32 inreg  /*dummy*/ , i32)<br>
<br>
declare x86_fastcallcc void @foo8(i32 inreg /*dummy*/, i32, i32 inreg)<br>
<br>
As Eli pointed out on llvm-commits, this would change the meaning of<br>
existing  x86_fastcallcc IL files, but given that they are only<br>
produced for fastcall C functions and those are fairly broken without<br>
this fix, I assume that is OK.<br>
<br>
Cheers,<br>
Rafael<br>
_______________________________________________<br>
LLVM Developers mailing list<br>
<a href="mailto:LLVMdev@cs.uiuc.edu">LLVMdev@cs.uiuc.edu</a>         <a href="http://llvm.cs.uiuc.edu" target="_blank">http://llvm.cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev</a><br>
</blockquote></div><br></div>