<div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div>Hi Martin,</div><div><br></div><div>Doesn't implementing "always back up and restore x18 on any call to any other function" boil down to having a PCS (procedure call standard) variation where x18 is caller saved?</div><div>I think that in the calling convention code (e.g. see AArch64CallingConvention.td) when a register is not marked as callee saved (CalleeSavedRegs), it is implicitly caller saved.</div><div>My guess without looking further as to what results in x18 not being saved/restored around function calls is that it is marked as a Reserved Register when the -ffixed-x18 command line optoin is used. AFAIU, reserved registers are not taking into account during liveness analysis, and code to save/restore it will never be generated.</div><div>See e.g. AArch64Subtarget::AArch64Subtarget doing the following:</div><div><div><font face="monospace, monospace">  if (AArch64::isX18ReservedByDefault(TT))</font></div><div><font face="monospace, monospace">    ReserveXRegister.set(18);</font></div></div><div><br></div><div>Apart from how to implement this behaviour: are you sure that always saving/restoring x18 on function boundaries would be the correct thing to do?</div><div>Couldn't some functions on the windows/WINE side change the value of X18? In that case you'd want to see the new value of X18 after a function returns, not restore the value from before the function call?</div><div><br></div><div>Thanks,</div><div><br></div><div>Kristof</div></div></div></div></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">Op vr 26 apr. 2019 om 14:30 schreef Martin Storsjö via llvm-dev <<a href="mailto:llvm-dev@lists.llvm.org">llvm-dev@lists.llvm.org</a>>:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">Hi,<br>
<br>
When using Wine to run Windows ARM64 executables on Linux, there's one <br>
major ABI incompatibility between the two; Windows treats the x18 <br>
register as the reserved platform register, while it is free to be <br>
clobbered anywhere in code on Linux.<br>
<br>
The Wine code sets up this register before passing control over to the <br>
Windows executable code, but whenever the Windows code calls a function <br>
implemented in Wine, this register ends up clobbered.<br>
<br>
The initial solution is to compile Wine itself with the -ffixed-x18 flag, <br>
to treat the x18 register as reserved within Wine, so that no compiler <br>
generated code touches it. This works fine as long as Wine makes no calls <br>
to other libraries from the outside Linux distribution - but e.g. as soon <br>
as any glibc function is called, it can end up clobbered again.<br>
<br>
The full, proper solution would of course to be rebuilding one's Linux <br>
distribution from scratch with -ffixed-x18 on every single library. But <br>
this is of course pretty much impractical.<br>
<br>
My current makeshift workaround for the matter is to reroute calls from <br>
native Windows code to Wine functions via a relay wrapper, which backs up <br>
and restores the register. This works in practice, but hasn't been <br>
accepted upstream, as it is not deemed a correct/complete solution. Also, <br>
if the emulated Windows API functions do callbacks, the register would <br>
need to be restored before the callbacks call windows code.<br>
<br>
Another idea which was raised in <br>
<a href="https://bugs.winehq.org/show_bug.cgi?id=38780#c13" rel="noreferrer" target="_blank">https://bugs.winehq.org/show_bug.cgi?id=38780#c13</a>, which disucsses this <br>
matter, was if it would be possible to make Clang/LLVM always back up and <br>
restore x18 on any call to any other function, to make sure that the <br>
register maintains the right value as long as running in Wine code. (One <br>
concern is that this could end up rather expensive though.)<br>
<br>
I didn't really find any straighforward way of starting to implement this <br>
however. Does anyone here happen to have ideas about how one could either <br>
implement this, or solve it in another way?<br>
<br>
// Martin<br>
<br>
_______________________________________________<br>
LLVM Developers mailing list<br>
<a href="mailto:llvm-dev@lists.llvm.org" target="_blank">llvm-dev@lists.llvm.org</a><br>
<a href="https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev" rel="noreferrer" target="_blank">https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev</a><br>
</blockquote></div>