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);
   }