Support 64-bit jump tables with LP64 data model.

BUG=swiftshader:9

Change-Id: I779abfe7775632e1108e9d608bf21a63c8cefe9e
Reviewed-on: https://chromium-review.googlesource.com/407882
Reviewed-by: Jim Stichnoth <stichnot@chromium.org>
Tested-by: Nicolas Capens <nicolascapens@google.com>
diff --git a/src/IceELFSection.cpp b/src/IceELFSection.cpp
index d9539bb..cc8e1e5 100644
--- a/src/IceELFSection.cpp
+++ b/src/IceELFSection.cpp
@@ -45,11 +45,12 @@
 
 void ELFDataSection::appendRelocationOffset(ELFStreamer &Str, bool IsRela,
                                             RelocOffsetT RelocOffset) {
+  const SizeT RelocAddrSize = typeWidthInBytes(getPointerType());
   if (IsRela) {
     appendZeros(Str, RelocAddrSize);
     return;
   }
-  static_assert(RelocAddrSize == 4, " writeLE32 assumes RelocAddrSize is 4");
+  assert(RelocAddrSize == 4 && " writeLE32 assumes RelocAddrSize is 4");
   Str.writeLE32(RelocOffset);
   Header.sh_size += RelocAddrSize;
 }
diff --git a/src/IceInstX86BaseImpl.h b/src/IceInstX86BaseImpl.h
index b738a02..8b7fb92 100644
--- a/src/IceInstX86BaseImpl.h
+++ b/src/IceInstX86BaseImpl.h
@@ -1773,8 +1773,7 @@
   Ostream &Str = Func->getContext()->getStrEmit();
   assert(this->getSrcSize() == 3);
   Str << "\t" << this->Opcode
-      << Traits::TypeAttributes[this->getDest()->getType()].SpSdString
-      << "\t";
+      << Traits::TypeAttributes[this->getDest()->getType()].SpSdString << "\t";
   this->getSrc(1)->emit(Func);
   Str << ", ";
   this->getSrc(0)->emit(Func);
diff --git a/src/IceTargetLoweringX8664.cpp b/src/IceTargetLoweringX8664.cpp
index a3602a9..ba72a3b 100644
--- a/src/IceTargetLoweringX8664.cpp
+++ b/src/IceTargetLoweringX8664.cpp
@@ -592,9 +592,11 @@
   std::unique_ptr<AutoBundle> Bundler;
 
   if (!NeedSandboxing) {
-    Variable *T = makeReg(IceType_i64);
-    _movzx(T, JumpTarget);
-    JumpTarget = T;
+    if (JumpTarget->getType() != IceType_i64) {
+      Variable *T = makeReg(IceType_i64);
+      _movzx(T, JumpTarget);
+      JumpTarget = T;
+    }
   } else {
     Variable *T = makeReg(IceType_i32);
     Variable *T64 = makeReg(IceType_i64);
diff --git a/src/IceTargetLoweringX86BaseImpl.h b/src/IceTargetLoweringX86BaseImpl.h
index 3472b00..205d783 100644
--- a/src/IceTargetLoweringX86BaseImpl.h
+++ b/src/IceTargetLoweringX86BaseImpl.h
@@ -6851,6 +6851,7 @@
 
     constexpr RelocOffsetT RelocOffset = 0;
     constexpr Variable *NoBase = nullptr;
+    constexpr Constant *NoOffset = nullptr;
     auto JTName = GlobalString::createWithString(Ctx, JumpTable->getName());
     Constant *Offset = Ctx->getConstantSym(RelocOffset, JTName);
     uint16_t Shift = typeWidthInBytesLog2(PointerType);
@@ -6860,9 +6861,16 @@
     if (Traits::Is64Bit && NeedSandboxing) {
       assert(Index != nullptr && Index->getType() == IceType_i32);
     }
-    auto *TargetInMemory = X86OperandMem::create(Func, PointerType, NoBase,
-                                                 Offset, Index, Shift, Segment);
-    _mov(Target, TargetInMemory);
+
+    if (PointerType == IceType_i32) {
+      _mov(Target, X86OperandMem::create(Func, PointerType, NoBase, Offset,
+                                         Index, Shift, Segment));
+    } else {
+      auto *Base = makeReg(IceType_i64);
+      _lea(Base, X86OperandMem::create(Func, IceType_void, NoBase, Offset));
+      _mov(Target, X86OperandMem::create(Func, PointerType, Base, NoOffset,
+                                         Index, Shift, Segment));
+    }
 
     lowerIndirectJump(Target);
 
@@ -8357,8 +8365,11 @@
   switch (getFlags().getOutFileType()) {
   case FT_Elf: {
     ELFObjectWriter *Writer = Ctx->getObjectWriter();
+    constexpr FixupKind FK_Abs64 = llvm::ELF::R_X86_64_64;
+    const FixupKind RelocationKind =
+        (getPointerType() == IceType_i32) ? Traits::FK_Abs : FK_Abs64;
     for (const JumpTableData &JT : Ctx->getJumpTables())
-      Writer->writeJumpTable(JT, Traits::FK_Abs, IsPIC);
+      Writer->writeJumpTable(JT, RelocationKind, IsPIC);
   } break;
   case FT_Asm:
     // Already emitted from Cfg