| Index: src/compiler/x64/code-generator-x64.cc
|
| diff --git a/src/compiler/x64/code-generator-x64.cc b/src/compiler/x64/code-generator-x64.cc
|
| index 4a96fe866bf2b1ee442f33d6ffab8ef294a4391a..34ddc837a6b5f30fe0048667ed69eb571bc16c63 100644
|
| --- a/src/compiler/x64/code-generator-x64.cc
|
| +++ b/src/compiler/x64/code-generator-x64.cc
|
| @@ -93,8 +93,14 @@ class X64OperandConverter : public InstructionOperandConverter {
|
| int32_t disp = InputInt32(NextOffset(offset));
|
| return Operand(base, index, scale, disp);
|
| }
|
| - case kMode_M1:
|
| + case kMode_M1: {
|
| + Register base = InputRegister(NextOffset(offset));
|
| + int32_t disp = 0;
|
| + return Operand(base, disp);
|
| + }
|
| case kMode_M2:
|
| + UNREACHABLE(); // Should use kModeMR with more compact encoding instead
|
| + return Operand(no_reg, 0);
|
| case kMode_M4:
|
| case kMode_M8: {
|
| Register index = InputRegister(NextOffset(offset));
|
| @@ -711,17 +717,26 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
|
| break;
|
| case kX64Lea32: {
|
| AddressingMode mode = AddressingModeField::decode(instr->opcode());
|
| - // Shorten "leal" to "addl" or "subl" if the register allocation just
|
| - // happens to work out for operations with immediate operands where the
|
| - // non-constant input register is the same as output register. The
|
| - // "addl"/"subl" forms in these cases are faster based on empirical
|
| - // measurements.
|
| - if (mode == kMode_MRI && i.InputRegister(0).is(i.OutputRegister())) {
|
| - int32_t constant_summand = i.InputInt32(1);
|
| - if (constant_summand > 0) {
|
| - __ addl(i.OutputRegister(), Immediate(constant_summand));
|
| - } else if (constant_summand < 0) {
|
| - __ subl(i.OutputRegister(), Immediate(-constant_summand));
|
| + // Shorten "leal" to "addl", "subl" or "shll" if the register allocation
|
| + // and addressing mode just happens to work out. The "addl"/"subl" forms
|
| + // in these cases are faster based on measurements.
|
| + if (i.InputRegister(0).is(i.OutputRegister())) {
|
| + if (mode == kMode_MRI) {
|
| + int32_t constant_summand = i.InputInt32(1);
|
| + if (constant_summand > 0) {
|
| + __ addl(i.OutputRegister(), Immediate(constant_summand));
|
| + } else if (constant_summand < 0) {
|
| + __ subl(i.OutputRegister(), Immediate(-constant_summand));
|
| + }
|
| + } else if (mode == kMode_MR1 || mode == kMode_M2) {
|
| + // Using "addl %r1, %r1" is generally faster than "shll %r1, 1"
|
| + __ addl(i.OutputRegister(), i.InputRegister(1));
|
| + } else if (mode == kMode_M4) {
|
| + __ shll(i.OutputRegister(), Immediate(2));
|
| + } else if (mode == kMode_M8) {
|
| + __ shll(i.OutputRegister(), Immediate(3));
|
| + } else {
|
| + __ leal(i.OutputRegister(), i.MemoryOperand());
|
| }
|
| } else {
|
| __ leal(i.OutputRegister(), i.MemoryOperand());
|
|
|