<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On Thu, Oct 9, 2014 at 1:51 AM, David Chisnall <span dir="ltr"><<a href="mailto:David.Chisnall@cl.cam.ac.uk" target="_blank">David.Chisnall@cl.cam.ac.uk</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span class="">On 8 Oct 2014, at 18:19, Reid Kleckner <<a href="mailto:rnk@google.com">rnk@google.com</a>> wrote:<br>
<br>
> The one target I know about where varargs are passed differently from normal arguments is aarch64-apple-ios/macosx. After thinking a bit more, I think this forwarding thunk representation works fine even on that target. Typically a forwarding thunk is called indirectly, or at least through a bitcast, so the LLVM IR call site would look like:<br>
<br>
</span>MIPS also has some subtle (and annoying) differences between variadic and non-variadic function calls.  Most notably (o32-only) that the stack pointer will be in a different place in the callee for variadic and non-variadic calls.<br>
<br>
The variadic calling convention that we're using for our extension currently requires all variadic arguments to be spilled to the stack (we found this actually improves performance very slightly, as most things that use variadic functions call a function that takes a va_list argument and you can construct the va_list by just saving the stack pointer, but we did it for correctness and simplicity originally).<br>
<br>
Implementing perfect forwarding would require that the caller calls the thunk with the non-variadic calling convention and that the thunk is aware that it must (potentially) preserve some more registers.  In particular, it mustn't touch any of the argument registers for the specified calling convention, unless explicitly modifying those arguments.<br></blockquote><div><br></div><div>This sounds similar to the aarch64 case. We just need to copy all unconsumed physical register parameters to virtual registers in the prologue, and copy them back into physical registers before a variadic musttail call.</div><div><br></div><div>As long as the thunk does not intend to read and modify arguments in the va_list, this approach should work. It just means we'll preserve more registers than we need to if the thunk target is actually a variadic function.</div><div><br></div><div>Again, my use case is C++ adjustor thunks, where the 'this' parameter is always "prototyped" and never part of the va_list.</div><div><br></div><div>----</div><div><br></div><div>As an aside, the Windows x64 calling convention has an interesting solution to this problem. They require the caller to allocate stack space for all the register parameters that might be passed. If it turns out that the callee is variadic, it can simply spill the register parameters in order to the stack and use a simple char * for the va_list type. It has the downside that vectors cannot be passed directly in xmm registers, because a vector argument is bigger than the normal 8-byte register parameter stack slot, hence the recent addition of __vectorcall.</div></div></div></div>