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:
parent
a5bb81a97c
commit
9ac890c62d
1 changed files with 14 additions and 0 deletions
|
@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue