Support 64-bit call targets.
The x86-64 call instruction only supports 32-bit IP-relative direct
calls or 64-bit indirect calls. So handle 64-bit direct calls by
storing the value into a register and making an indirect call.
Bug chromium:860533
Change-Id: I3781d1e8a489ce9ab7c17b098ffe830cae62477e
Reviewed-on: https://swiftshader-review.googlesource.com/19828
Tested-by: Nicolas Capens <nicolascapens@google.com>
Reviewed-by: Alexis Hétu <sugoi@google.com>
diff --git a/third_party/subzero/src/IceTargetLoweringX8664.cpp b/third_party/subzero/src/IceTargetLoweringX8664.cpp
index ba72a3b..de2d996 100644
--- a/third_party/subzero/src/IceTargetLoweringX8664.cpp
+++ b/third_party/subzero/src/IceTargetLoweringX8664.cpp
@@ -685,12 +685,19 @@
Context.insert(ReturnAddress);
} else {
- if (CallTargetR != nullptr) {
- // x86-64 in Subzero is ILP32. Therefore, CallTarget is i32, but the
- // emitted call needs a i64 register (for textual asm.)
+ if (CallTargetR != nullptr && CallTarget->getType() == IceType_i32) {
+ // x86-64 in PNaCl is ILP32. Therefore, CallTarget is i32, but the
+ // emitted call needs an i64 register (for textual asm.)
Variable *T = makeReg(IceType_i64);
_movzx(T, CallTargetR);
CallTarget = T;
+ } else if (llvm::isa<Constant>(CallTarget) &&
+ CallTarget->getType() == IceType_i64) {
+ // x86-64 does not support 64-bit direct calls, so write the value
+ // to a register and make an indirect call.
+ Variable *T = makeReg(IceType_i64);
+ _mov(T, CallTarget);
+ CallTarget = T;
}
NewCall = Context.insert<Traits::Insts::Call>(ReturnReg, CallTarget);
}