Allow mixing of thread offsets between 32 and 64bit architectures.

Begin a more full implementation x86-64 REX prefixes.
Doesn't implement 64bit thread offset support for the JNI compiler.

Change-Id: If9af2f08a1833c21ddb4b4077f9b03add1a05147
diff --git a/compiler/trampolines/trampoline_compiler.cc b/compiler/trampolines/trampoline_compiler.cc
index 32980cb..fb909a8 100644
--- a/compiler/trampolines/trampoline_compiler.cc
+++ b/compiler/trampolines/trampoline_compiler.cc
@@ -21,6 +21,7 @@
 #include "utils/arm64/assembler_arm64.h"
 #include "utils/mips/assembler_mips.h"
 #include "utils/x86/assembler_x86.h"
+#include "utils/x86_64/assembler_x86_64.h"
 
 #define __ assembler->
 
@@ -28,7 +29,7 @@
 
 namespace arm {
 static const std::vector<uint8_t>* CreateTrampoline(EntryPointCallingConvention abi,
-                                                    ThreadOffset offset) {
+                                                    ThreadOffset<4> offset) {
   UniquePtr<ArmAssembler> assembler(static_cast<ArmAssembler*>(Assembler::Create(kArm)));
 
   switch (abi) {
@@ -56,7 +57,7 @@
 
 namespace arm64 {
 static const std::vector<uint8_t>* CreateTrampoline(EntryPointCallingConvention abi,
-                                                    ThreadOffset offset) {
+                                                    ThreadOffset<8> offset) {
   UniquePtr<Arm64Assembler> assembler(static_cast<Arm64Assembler*>(Assembler::Create(kArm64)));
 
   switch (abi) {
@@ -96,7 +97,7 @@
 
 namespace mips {
 static const std::vector<uint8_t>* CreateTrampoline(EntryPointCallingConvention abi,
-                                                    ThreadOffset offset) {
+                                                    ThreadOffset<4> offset) {
   UniquePtr<MipsAssembler> assembler(static_cast<MipsAssembler*>(Assembler::Create(kMips)));
 
   switch (abi) {
@@ -125,7 +126,7 @@
 }  // namespace mips
 
 namespace x86 {
-static const std::vector<uint8_t>* CreateTrampoline(ThreadOffset offset) {
+static const std::vector<uint8_t>* CreateTrampoline(ThreadOffset<4> offset) {
   UniquePtr<X86Assembler> assembler(static_cast<X86Assembler*>(Assembler::Create(kX86)));
 
   // All x86 trampolines call via the Thread* held in fs.
@@ -142,11 +143,12 @@
 }  // namespace x86
 
 namespace x86_64 {
-static const std::vector<uint8_t>* CreateTrampoline(ThreadOffset offset) {
-  UniquePtr<x86::X86Assembler> assembler(static_cast<x86::X86Assembler*>(Assembler::Create(kX86_64)));
+static const std::vector<uint8_t>* CreateTrampoline(ThreadOffset<8> offset) {
+  UniquePtr<x86_64::X86_64Assembler>
+      assembler(static_cast<x86_64::X86_64Assembler*>(Assembler::Create(kX86_64)));
 
   // All x86 trampolines call via the Thread* held in gs.
-  __ gs()->jmp(x86::Address::Absolute(offset, true));
+  __ gs()->jmp(x86_64::Address::Absolute(offset, true));
   __ int3();
 
   size_t cs = assembler->CodeSize();
@@ -158,23 +160,32 @@
 }
 }  // namespace x86_64
 
-const std::vector<uint8_t>* CreateTrampoline(InstructionSet isa, EntryPointCallingConvention abi,
-                                             ThreadOffset offset) {
+const std::vector<uint8_t>* CreateTrampoline64(InstructionSet isa, EntryPointCallingConvention abi,
+                                               ThreadOffset<8> offset) {
+  switch (isa) {
+    case kArm64:
+      return arm64::CreateTrampoline(abi, offset);
+    case kX86_64:
+      return x86_64::CreateTrampoline(offset);
+    default:
+      LOG(FATAL) << "Unexpected InstructionSet: " << isa;
+      return nullptr;
+  }
+}
+
+const std::vector<uint8_t>* CreateTrampoline32(InstructionSet isa, EntryPointCallingConvention abi,
+                                               ThreadOffset<4> offset) {
   switch (isa) {
     case kArm:
     case kThumb2:
       return arm::CreateTrampoline(abi, offset);
-    case kArm64:
-      return arm64::CreateTrampoline(abi, offset);
     case kMips:
       return mips::CreateTrampoline(abi, offset);
     case kX86:
       return x86::CreateTrampoline(offset);
-    case kX86_64:
-      return x86_64::CreateTrampoline(offset);
     default:
-      LOG(FATAL) << "Unknown InstructionSet: " << isa;
-      return NULL;
+      LOG(FATAL) << "Unexpected InstructionSet: " << isa;
+      return nullptr;
   }
 }
 
diff --git a/compiler/trampolines/trampoline_compiler.h b/compiler/trampolines/trampoline_compiler.h
index cb5aa27..bdab279 100644
--- a/compiler/trampolines/trampoline_compiler.h
+++ b/compiler/trampolines/trampoline_compiler.h
@@ -25,8 +25,11 @@
 namespace art {
 
 // Create code that will invoke the function held in thread local storage.
-const std::vector<uint8_t>* CreateTrampoline(InstructionSet isa, EntryPointCallingConvention abi,
-                                             ThreadOffset entry_point_offset)
+const std::vector<uint8_t>* CreateTrampoline32(InstructionSet isa, EntryPointCallingConvention abi,
+                                               ThreadOffset<4> entry_point_offset)
+    SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+const std::vector<uint8_t>* CreateTrampoline64(InstructionSet isa, EntryPointCallingConvention abi,
+                                               ThreadOffset<8> entry_point_offset)
     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
 
 }  // namespace art