reg_alloc: Fix for LLVM's interpretation of the System V ABI

This aspect of the System V ABI is under-defined. LLVM choses a
different interpretation from GCC and ICC.

Most other compilers assume the callee is responsible zero-ing the
upper bits of the register if necessary. LLVM assumes the caller
has zero-extended the register.

This is a quick fix for this problem until zext-tracking is
implemented.
This commit is contained in:
MerryMage 2017-04-08 22:04:16 +01:00
parent a5bb81a97c
commit 9ac890c62d

View file

@ -308,6 +308,20 @@ void RegAlloc::HostCall(IR::Inst* result_def, boost::optional<Argument&> arg0, b
for (size_t i = 0; i < args_count; i++) { for (size_t i = 0; i < args_count; i++) {
if (args[i]) { if (args[i]) {
UseScratch(*args[i], args_hostloc[i]); UseScratch(*args[i], args_hostloc[i]);
#if defined(__llvm__) && !defined(_WIN32)
// LLVM puts the burden of zero-extension of 8 and 16 bit values on the caller instead of the callee
Xbyak::Reg64 reg = HostLocToReg64(args_hostloc[i]);
switch (args[i]->GetType()) {
case IR::Type::U8:
code->movzx(reg.cvt32(), reg.cvt8());
break;
case IR::Type::U16:
code->movzx(reg.cvt32(), reg.cvt16());
break;
default:
break; // Nothing needs to be done
}
#endif
} }
} }