diff options
| author | 2014-07-03 20:48:11 +0000 | |
|---|---|---|
| committer | 2014-07-02 20:50:08 +0000 | |
| commit | 3ee86bcbbc29f17b0243954a52dcda96b09411e0 (patch) | |
| tree | 4e469788e93abd12b89e50a79582e6b16c2d1498 | |
| parent | aa079560f65a89ec83591f61ae3a39341f00509e (diff) | |
| parent | 5192cbb12856b12620dc346758605baaa1469ced (diff) | |
Merge "Load 64 bit constant into GPR by single instruction for 64bit mode"
| -rw-r--r-- | compiler/dex/quick/x86/assemble_x86.cc | 10 | ||||
| -rw-r--r-- | compiler/dex/quick/x86/target_x86.cc | 5 | ||||
| -rw-r--r-- | compiler/dex/quick/x86/utility_x86.cc | 16 | ||||
| -rw-r--r-- | compiler/dex/quick/x86/x86_lir.h | 3 | ||||
| -rw-r--r-- | disassembler/disassembler_x86.cc | 14 |
5 files changed, 33 insertions, 15 deletions
diff --git a/compiler/dex/quick/x86/assemble_x86.cc b/compiler/dex/quick/x86/assemble_x86.cc index a491873c2c..737b8b9ea8 100644 --- a/compiler/dex/quick/x86/assemble_x86.cc +++ b/compiler/dex/quick/x86/assemble_x86.cc @@ -208,7 +208,8 @@ ENCODING_MAP(Cmp, IS_LOAD, 0, 0, { kX86Mov64RM, kRegMem, IS_LOAD | IS_TERTIARY_OP | REG_DEF0_USE1, { REX_W, 0, 0x8B, 0, 0, 0, 0, 0, false }, "Mov64RM", "!0r,[!1r+!2d]" }, { kX86Mov64RA, kRegArray, IS_LOAD | IS_QUIN_OP | REG_DEF0_USE12, { REX_W, 0, 0x8B, 0, 0, 0, 0, 0, false }, "Mov64RA", "!0r,[!1r+!2r<<!3d+!4d]" }, { kX86Mov64RT, kRegThread, IS_LOAD | IS_BINARY_OP | REG_DEF0, { THREAD_PREFIX, REX_W, 0x8B, 0, 0, 0, 0, 0, false }, "Mov64RT", "!0r,fs:[!1d]" }, - { kX86Mov64RI, kMovRegImm, IS_BINARY_OP | REG_DEF0, { REX_W, 0, 0xB8, 0, 0, 0, 0, 8, false }, "Mov64RI", "!0r,!1d" }, + { kX86Mov64RI32, kRegImm, IS_BINARY_OP | REG_DEF0, { REX_W, 0, 0xC7, 0, 0, 0, 0, 4, false }, "Mov64RI32", "!0r,!1d" }, + { kX86Mov64RI64, kMovRegQuadImm, IS_TERTIARY_OP | REG_DEF0, { REX_W, 0, 0xB8, 0, 0, 0, 0, 8, false }, "Mov64RI64", "!0r,!1q" }, { kX86Mov64MI, kMemImm, IS_STORE | IS_TERTIARY_OP | REG_USE0, { REX_W, 0, 0xC7, 0, 0, 0, 0, 4, false }, "Mov64MI", "[!0r+!1d],!2d" }, { kX86Mov64AI, kArrayImm, IS_STORE | IS_QUIN_OP | REG_USE01, { REX_W, 0, 0xC7, 0, 0, 0, 0, 4, false }, "Mov64AI", "[!0r+!1r<<!2d+!3d],!4d" }, { kX86Mov64TI, kThreadImm, IS_STORE | IS_BINARY_OP, { THREAD_PREFIX, REX_W, 0xC7, 0, 0, 0, 0, 4, false }, "Mov64TI", "fs:[!0d],!1d" }, @@ -723,6 +724,7 @@ size_t X86Mir2Lir::GetInsnSize(LIR* lir) { return ComputeSize(entry, lir->operands[0], lir->operands[2], lir->operands[1], lir->operands[4]); case kMovRegImm: // lir operands - 0: reg, 1: immediate + case kMovRegQuadImm: return ((entry->skeleton.prefix1 != 0 || NeedsRex(lir->operands[0])) ? 1 : 0) + 1 + entry->skeleton.immediate_bytes; case kShiftRegImm: // lir operands - 0: reg, 1: immediate @@ -1787,6 +1789,12 @@ AssemblerStatus X86Mir2Lir::AssembleInstructions(CodeOffset start_addr) { case kMovRegImm: // lir operands - 0: reg, 1: immediate EmitMovRegImm(entry, lir->operands[0], lir->operands[1]); break; + case kMovRegQuadImm: { + int64_t value = static_cast<int64_t>(static_cast<int64_t>(lir->operands[1]) << 32 | + static_cast<uint32_t>(lir->operands[2])); + EmitMovRegImm(entry, lir->operands[0], value); + } + break; case kShiftRegImm: // lir operands - 0: reg, 1: immediate EmitShiftRegImm(entry, lir->operands[0], lir->operands[1]); break; diff --git a/compiler/dex/quick/x86/target_x86.cc b/compiler/dex/quick/x86/target_x86.cc index 72b2cea7fc..730a271737 100644 --- a/compiler/dex/quick/x86/target_x86.cc +++ b/compiler/dex/quick/x86/target_x86.cc @@ -331,6 +331,11 @@ std::string X86Mir2Lir::BuildInsnString(const char *fmt, LIR *lir, unsigned char case 'd': buf += StringPrintf("%d", operand); break; + case 'q': { + int64_t value = static_cast<int64_t>(static_cast<int64_t>(operand) << 32 | + static_cast<uint32_t>(lir->operands[operand_number+1])); + buf +=StringPrintf("%" PRId64, value); + } case 'p': { EmbeddedData *tab_rec = reinterpret_cast<EmbeddedData*>(UnwrapPointer(operand)); buf += StringPrintf("0x%08x", tab_rec->offset); diff --git a/compiler/dex/quick/x86/utility_x86.cc b/compiler/dex/quick/x86/utility_x86.cc index d835b2215f..4770adecad 100644 --- a/compiler/dex/quick/x86/utility_x86.cc +++ b/compiler/dex/quick/x86/utility_x86.cc @@ -608,18 +608,12 @@ LIR* X86Mir2Lir::LoadConstantWide(RegStorage r_dest, int64_t value) { res = LoadConstantNoClobber(r_dest.GetLow(), val_lo); LoadConstantNoClobber(r_dest.GetHigh(), val_hi); } else { - // TODO(64) make int64_t value parameter of LoadConstantNoClobber - if (val_lo < 0) { - val_hi += 1; - } - if (val_hi != 0) { - res = LoadConstantNoClobber(RegStorage::Solo32(r_dest.GetReg()), val_hi); - NewLIR2(kX86Sal64RI, r_dest.GetReg(), 32); - } else { + if (value == 0) { res = NewLIR2(kX86Xor64RR, r_dest.GetReg(), r_dest.GetReg()); - } - if (val_lo != 0) { - NewLIR2(kX86Add64RI, r_dest.GetReg(), val_lo); + } else if (value >= INT_MIN && value <= INT_MAX) { + res = NewLIR2(kX86Mov64RI32, r_dest.GetReg(), val_lo); + } else { + res = NewLIR3(kX86Mov64RI64, r_dest.GetReg(), val_hi, val_lo); } } } diff --git a/compiler/dex/quick/x86/x86_lir.h b/compiler/dex/quick/x86/x86_lir.h index 17c44bc2c7..7ff4f725d1 100644 --- a/compiler/dex/quick/x86/x86_lir.h +++ b/compiler/dex/quick/x86/x86_lir.h @@ -439,7 +439,7 @@ enum X86OpCode { kX86Lea32RA, kX86Mov64MR, kX86Mov64AR, kX86Mov64TR, kX86Mov64RR, kX86Mov64RM, kX86Mov64RA, kX86Mov64RT, - kX86Mov64RI, kX86Mov64MI, kX86Mov64AI, kX86Mov64TI, + kX86Mov64RI32, kX86Mov64RI64, kX86Mov64MI, kX86Mov64AI, kX86Mov64TI, kX86Lea64RM, kX86Lea64RA, // RRC - Register Register ConditionCode - cond_opcode reg1, reg2 @@ -649,6 +649,7 @@ enum X86EncodingKind { kRegImm, kMemImm, kArrayImm, kThreadImm, // RI, MI, AI and TI instruction kinds. kRegRegImm, kRegMemImm, kRegArrayImm, // RRI, RMI and RAI instruction kinds. kMovRegImm, // Shorter form move RI. + kMovRegQuadImm, // 64 bit move RI kRegRegImmStore, // RRI following the store modrm reg-reg encoding rather than the load. kMemRegImm, // MRI instruction kinds. kShiftRegImm, kShiftMemImm, kShiftArrayImm, // Shift opcode with immediate. diff --git a/disassembler/disassembler_x86.cc b/disassembler/disassembler_x86.cc index 1d8cf9b4cd..1021789908 100644 --- a/disassembler/disassembler_x86.cc +++ b/disassembler/disassembler_x86.cc @@ -21,6 +21,7 @@ #include "base/logging.h" #include "base/stringprintf.h" #include "thread.h" +#include <inttypes.h> namespace art { namespace x86 { @@ -914,6 +915,12 @@ DISASSEMBLER_ENTRY(cmp, reg_in_opcode = true; break; case 0xB8: case 0xB9: case 0xBA: case 0xBB: case 0xBC: case 0xBD: case 0xBE: case 0xBF: + if (rex == 0x48) { + opcode << "movabsq"; + immediate_bytes = 8; + reg_in_opcode = true; + break; + } opcode << "mov"; immediate_bytes = 4; reg_in_opcode = true; @@ -1144,8 +1151,7 @@ DISASSEMBLER_ENTRY(cmp, if (immediate_bytes == 1) { args << StringPrintf("%d", *reinterpret_cast<const int8_t*>(instr)); instr++; - } else { - CHECK_EQ(immediate_bytes, 4u); + } else if (immediate_bytes == 4) { if (prefix[2] == 0x66) { // Operand size override from 32-bit to 16-bit. args << StringPrintf("%d", *reinterpret_cast<const int16_t*>(instr)); instr += 2; @@ -1153,6 +1159,10 @@ DISASSEMBLER_ENTRY(cmp, args << StringPrintf("%d", *reinterpret_cast<const int32_t*>(instr)); instr += 4; } + } else { + CHECK_EQ(immediate_bytes, 8u); + args << StringPrintf("%" PRId64, *reinterpret_cast<const int64_t*>(instr)); + instr += 8; } } else if (branch_bytes > 0) { DCHECK(!has_modrm); |