diff options
author | Ian Rogers <irogers@google.com> | 2014-03-06 01:13:39 -0800 |
---|---|---|
committer | Ian Rogers <irogers@google.com> | 2014-03-06 01:34:07 -0800 |
commit | befbd5731ecca08f08780ee28a913d08ffb14656 (patch) | |
tree | ee359fc38671950afa91d96bf8c29232a799b628 /compiler | |
parent | 97c3d61e46a3678dac848578c686c724ec3397fa (diff) | |
download | android_art-befbd5731ecca08f08780ee28a913d08ffb14656.tar.gz android_art-befbd5731ecca08f08780ee28a913d08ffb14656.tar.bz2 android_art-befbd5731ecca08f08780ee28a913d08ffb14656.zip |
Fix host architecture for 64bit.
Also, hack x86 assembler for use as a x86-64 trampoline compiler's assembler.
Implement missing x86-64 quick resolution trampoline.
Add x86-64 to the quick elf writer.
Change-Id: I08216c67014a83492ada12898ab8000218ba7bb4
Diffstat (limited to 'compiler')
-rw-r--r-- | compiler/compiled_method.cc | 3 | ||||
-rw-r--r-- | compiler/elf_writer_quick.cc | 5 | ||||
-rw-r--r-- | compiler/trampolines/trampoline_compiler.cc | 19 | ||||
-rw-r--r-- | compiler/utils/assembler.cc | 3 | ||||
-rw-r--r-- | compiler/utils/x86/assembler_x86.cc | 7 | ||||
-rw-r--r-- | compiler/utils/x86/assembler_x86.h | 21 |
6 files changed, 49 insertions, 9 deletions
diff --git a/compiler/compiled_method.cc b/compiler/compiled_method.cc index d884bc0ef8..17c2e94652 100644 --- a/compiler/compiled_method.cc +++ b/compiler/compiled_method.cc @@ -88,7 +88,8 @@ uint32_t CompiledCode::AlignCode(uint32_t offset, InstructionSet instruction_set return RoundUp(offset, kArmAlignment); case kMips: return RoundUp(offset, kMipsAlignment); - case kX86: + case kX86: // Fall-through. + case kX86_64: return RoundUp(offset, kX86Alignment); default: LOG(FATAL) << "Unknown InstructionSet: " << instruction_set; diff --git a/compiler/elf_writer_quick.cc b/compiler/elf_writer_quick.cc index 4b823ef5ec..a6daa5d00d 100644 --- a/compiler/elf_writer_quick.cc +++ b/compiler/elf_writer_quick.cc @@ -377,6 +377,11 @@ bool ElfWriterQuick::Write(OatWriter* oat_writer, elf_header.e_flags = 0; break; } + case kX86_64: { + elf_header.e_machine = EM_X86_64; + elf_header.e_flags = 0; + break; + } case kMips: { elf_header.e_machine = EM_MIPS; elf_header.e_flags = (EF_MIPS_NOREORDER | diff --git a/compiler/trampolines/trampoline_compiler.cc b/compiler/trampolines/trampoline_compiler.cc index 32ae5583ac..3e13e44397 100644 --- a/compiler/trampolines/trampoline_compiler.cc +++ b/compiler/trampolines/trampoline_compiler.cc @@ -100,6 +100,23 @@ static const std::vector<uint8_t>* CreateTrampoline(ThreadOffset offset) { } } // 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))); + + // All x86 trampolines call via the Thread* held in gs. + __ gs()->jmp(x86::Address::Absolute(offset, true)); + __ int3(); + + size_t cs = assembler->CodeSize(); + UniquePtr<std::vector<uint8_t> > entry_stub(new std::vector<uint8_t>(cs)); + MemoryRegion code(&(*entry_stub)[0], entry_stub->size()); + assembler->FinalizeInstructions(code); + + return entry_stub.release(); +} +} // namespace x86_64 + const std::vector<uint8_t>* CreateTrampoline(InstructionSet isa, EntryPointCallingConvention abi, ThreadOffset offset) { switch (isa) { @@ -110,6 +127,8 @@ const std::vector<uint8_t>* CreateTrampoline(InstructionSet isa, EntryPointCalli 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; diff --git a/compiler/utils/assembler.cc b/compiler/utils/assembler.cc index 67324764f0..a7cb2784a7 100644 --- a/compiler/utils/assembler.cc +++ b/compiler/utils/assembler.cc @@ -111,7 +111,8 @@ Assembler* Assembler::Create(InstructionSet instruction_set) { return new arm64::Arm64Assembler(); case kMips: return new mips::MipsAssembler(); - case kX86: + case kX86: // Fall-through. + case kX86_64: return new x86::X86Assembler(); default: LOG(FATAL) << "Unknown InstructionSet: " << instruction_set; diff --git a/compiler/utils/x86/assembler_x86.cc b/compiler/utils/x86/assembler_x86.cc index 136d2486df..26300e02e0 100644 --- a/compiler/utils/x86/assembler_x86.cc +++ b/compiler/utils/x86/assembler_x86.cc @@ -1210,6 +1210,13 @@ X86Assembler* X86Assembler::fs() { return this; } +X86Assembler* X86Assembler::gs() { + // TODO: fs is a prefix and not an instruction + AssemblerBuffer::EnsureCapacity ensured(&buffer_); + EmitUint8(0x65); + return this; +} + void X86Assembler::AddImmediate(Register reg, const Immediate& imm) { int value = imm.value(); if (value > 0) { diff --git a/compiler/utils/x86/assembler_x86.h b/compiler/utils/x86/assembler_x86.h index 0fa8e0086c..e284d8c152 100644 --- a/compiler/utils/x86/assembler_x86.h +++ b/compiler/utils/x86/assembler_x86.h @@ -192,15 +192,21 @@ class Address : public Operand { } } - static Address Absolute(uword addr) { + static Address Absolute(uword addr, bool has_rip = false) { Address result; - result.SetModRM(0, EBP); - result.SetDisp32(addr); + if (has_rip) { + result.SetModRM(0, ESP); + result.SetSIB(TIMES_1, ESP, EBP); + result.SetDisp32(addr); + } else { + result.SetModRM(0, EBP); + result.SetDisp32(addr); + } return result; } - static Address Absolute(ThreadOffset addr) { - return Absolute(addr.Int32Value()); + static Address Absolute(ThreadOffset addr, bool has_rip = false) { + return Absolute(addr.Int32Value(), has_rip); } private: @@ -210,9 +216,9 @@ class Address : public Operand { }; -class X86Assembler : public Assembler { +class X86Assembler FINAL : public Assembler { public: - X86Assembler() {} + explicit X86Assembler() {} virtual ~X86Assembler() {} /* @@ -427,6 +433,7 @@ class X86Assembler : public Assembler { void mfence(); X86Assembler* fs(); + X86Assembler* gs(); // // Macros for High-level operations. |