Index: src/compiler/x64/instruction-selector-x64.cc |
diff --git a/src/compiler/x64/instruction-selector-x64.cc b/src/compiler/x64/instruction-selector-x64.cc |
index 95ba8973ea1aa62cac352760b5013d2e7cfbe4d0..7a49774da4d56f7150d04ed6f3a5899cf76af40e 100644 |
--- a/src/compiler/x64/instruction-selector-x64.cc |
+++ b/src/compiler/x64/instruction-selector-x64.cc |
@@ -67,11 +67,11 @@ class X64OperandGenerator FINAL : public OperandGenerator { |
inputs[(*input_count)++] = UseRegister(index); |
if (displacement != NULL) { |
inputs[(*input_count)++] = UseImmediate(displacement); |
- static const AddressingMode kMnI_modes[] = {kMode_M1I, kMode_M2I, |
+ static const AddressingMode kMnI_modes[] = {kMode_MRI, kMode_M2I, |
kMode_M4I, kMode_M8I}; |
mode = kMnI_modes[scale_exponent]; |
} else { |
- static const AddressingMode kMn_modes[] = {kMode_M1, kMode_MR1, |
+ static const AddressingMode kMn_modes[] = {kMode_MR, kMode_MR1, |
kMode_M4, kMode_M8}; |
mode = kMn_modes[scale_exponent]; |
if (mode == kMode_MR1) { |
@@ -83,6 +83,21 @@ class X64OperandGenerator FINAL : public OperandGenerator { |
return mode; |
} |
+ AddressingMode GetEffectiveAddressMemoryOperand(Node* operand, |
+ InstructionOperand* inputs[], |
+ size_t* input_count) { |
+ BaseWithIndexAndDisplacement64Matcher m(operand, true); |
+ DCHECK(m.matches()); |
+ if ((m.displacement() == NULL || CanBeImmediate(m.displacement()))) { |
+ return GenerateMemoryOperandInputs(m.index(), m.scale(), m.base(), |
+ m.displacement(), inputs, input_count); |
+ } else { |
+ inputs[(*input_count)++] = UseRegister(operand->InputAt(0)); |
+ inputs[(*input_count)++] = UseRegister(operand->InputAt(1)); |
+ return kMode_MR1; |
+ } |
+ } |
+ |
bool CanBeBetterLeftOperand(Node* node) const { |
return !selector()->IsLive(node); |
} |
@@ -93,8 +108,6 @@ void InstructionSelector::VisitLoad(Node* node) { |
MachineType rep = RepresentationOf(OpParameter<LoadRepresentation>(node)); |
MachineType typ = TypeOf(OpParameter<LoadRepresentation>(node)); |
X64OperandGenerator g(this); |
- Node* const base = node->InputAt(0); |
- Node* const index = node->InputAt(1); |
ArchOpcode opcode; |
switch (rep) { |
@@ -122,19 +135,15 @@ void InstructionSelector::VisitLoad(Node* node) { |
UNREACHABLE(); |
return; |
} |
- if (g.CanBeImmediate(index)) { |
- // load [%base + #index] |
- Emit(opcode | AddressingModeField::encode(kMode_MRI), |
- g.DefineAsRegister(node), g.UseRegister(base), g.UseImmediate(index)); |
- } else if (g.CanBeImmediate(base)) { |
- // load [#base + %index] |
- Emit(opcode | AddressingModeField::encode(kMode_MRI), |
- g.DefineAsRegister(node), g.UseRegister(index), g.UseImmediate(base)); |
- } else { |
- // load [%base + %index*1] |
- Emit(opcode | AddressingModeField::encode(kMode_MR1), |
- g.DefineAsRegister(node), g.UseRegister(base), g.UseRegister(index)); |
- } |
+ |
+ InstructionOperand* outputs[1]; |
+ outputs[0] = g.DefineAsRegister(node); |
+ InstructionOperand* inputs[3]; |
+ size_t input_count = 0; |
+ AddressingMode mode = |
+ g.GetEffectiveAddressMemoryOperand(node, inputs, &input_count); |
+ InstructionCode code = opcode | AddressingModeField::encode(mode); |
+ Emit(code, 1, outputs, input_count, inputs); |
} |
@@ -184,21 +193,15 @@ void InstructionSelector::VisitStore(Node* node) { |
UNREACHABLE(); |
return; |
} |
+ InstructionOperand* inputs[4]; |
+ size_t input_count = 0; |
+ AddressingMode mode = |
+ g.GetEffectiveAddressMemoryOperand(node, inputs, &input_count); |
+ InstructionCode code = opcode | AddressingModeField::encode(mode); |
InstructionOperand* value_operand = |
g.CanBeImmediate(value) ? g.UseImmediate(value) : g.UseRegister(value); |
- if (g.CanBeImmediate(index)) { |
- // store [%base + #index], %|#value |
- Emit(opcode | AddressingModeField::encode(kMode_MRI), nullptr, |
- g.UseRegister(base), g.UseImmediate(index), value_operand); |
- } else if (g.CanBeImmediate(base)) { |
- // store [#base + %index], %|#value |
- Emit(opcode | AddressingModeField::encode(kMode_MRI), nullptr, |
- g.UseRegister(index), g.UseImmediate(base), value_operand); |
- } else { |
- // store [%base + %index*1], %|#value |
- Emit(opcode | AddressingModeField::encode(kMode_MR1), nullptr, |
- g.UseRegister(base), g.UseRegister(index), value_operand); |
- } |
+ inputs[input_count++] = value_operand; |
+ Emit(code, 0, static_cast<InstructionOperand**>(NULL), input_count, inputs); |
} |