From 5192cbb12856b12620dc346758605baaa1469ced Mon Sep 17 00:00:00 2001 From: Yixin Shou Date: Tue, 1 Jul 2014 13:48:17 -0400 Subject: Load 64 bit constant into GPR by single instruction for 64bit mode This patch load 64 bit constant into a register by a single movabsq instruction on 64 bit bit instead of previous mov, shift, add instruction sequences. Change-Id: I9d013c4f6c0b5c2e43bd125f91436263c7e6028c Signed-off-by: Yixin Shou --- compiler/dex/quick/x86/assemble_x86.cc | 10 +++++++++- compiler/dex/quick/x86/target_x86.cc | 5 +++++ compiler/dex/quick/x86/utility_x86.cc | 16 +++++----------- compiler/dex/quick/x86/x86_lir.h | 3 ++- 4 files changed, 21 insertions(+), 13 deletions(-) (limited to 'compiler') diff --git a/compiler/dex/quick/x86/assemble_x86.cc b/compiler/dex/quick/x86/assemble_x86.cc index 3f362f263e..84dc659bdc 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<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(static_cast(lir->operands[1]) << 32 | + static_cast(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 4169005bed..04a7a8e1f4 100644 --- a/compiler/dex/quick/x86/target_x86.cc +++ b/compiler/dex/quick/x86/target_x86.cc @@ -330,6 +330,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(static_cast(operand) << 32 | + static_cast(lir->operands[operand_number+1])); + buf +=StringPrintf("%" PRId64, value); + } case 'p': { EmbeddedData *tab_rec = reinterpret_cast(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 0352808a7c..03c57de030 100644 --- a/compiler/dex/quick/x86/utility_x86.cc +++ b/compiler/dex/quick/x86/utility_x86.cc @@ -607,18 +607,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. -- cgit v1.2.3-59-g8ed1b