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 10cafeedffe2fc1be2918160e300f6ab5f1721c7..fdf63855d59cac64d5f9083657a8688d769c4347 100644 |
--- a/src/compiler/x64/code-generator-x64.cc |
+++ b/src/compiler/x64/code-generator-x64.cc |
@@ -145,22 +145,79 @@ class X64OperandConverter : public InstructionOperandConverter { |
return result; |
} |
- Operand MemoryOperand(int* first_input) { |
- const int offset = *first_input; |
- switch (AddressingModeField::decode(instr_->opcode())) { |
- case kMode_MR1I: { |
- *first_input += 2; |
- Register index = InputRegister(offset + 1); |
- return Operand(InputRegister(offset + 0), index, times_1, |
- 0); // TODO(dcarney): K != 0 |
+ static int NextOffset(int* offset) { |
+ int i = *offset; |
+ (*offset)++; |
+ return i; |
+ } |
+ |
+ static ScaleFactor ScaleFor(AddressingMode one, AddressingMode mode) { |
+ STATIC_ASSERT(0 == static_cast<int>(times_1)); |
+ STATIC_ASSERT(1 == static_cast<int>(times_2)); |
+ STATIC_ASSERT(2 == static_cast<int>(times_4)); |
+ STATIC_ASSERT(3 == static_cast<int>(times_8)); |
+ int scale = static_cast<int>(mode - one); |
+ DCHECK(scale >= 0 && scale < 4); |
+ return static_cast<ScaleFactor>(scale); |
+ } |
+ |
+ Operand MemoryOperand(int* offset) { |
+ AddressingMode mode = AddressingModeField::decode(instr_->opcode()); |
+ switch (mode) { |
+ case kMode_MR: { |
+ Register base = InputRegister(NextOffset(offset)); |
+ int32_t disp = 0; |
+ return Operand(base, disp); |
+ } |
+ case kMode_MRI: { |
+ Register base = InputRegister(NextOffset(offset)); |
+ int32_t disp = InputInt32(NextOffset(offset)); |
+ return Operand(base, disp); |
} |
- case kMode_MRI: |
- *first_input += 2; |
- return Operand(InputRegister(offset + 0), InputInt32(offset + 1)); |
- default: |
+ case kMode_MR1: |
+ case kMode_MR2: |
+ case kMode_MR4: |
+ case kMode_MR8: { |
+ Register base = InputRegister(NextOffset(offset)); |
+ Register index = InputRegister(NextOffset(offset)); |
+ ScaleFactor scale = ScaleFor(kMode_MR1, mode); |
+ int32_t disp = 0; |
+ return Operand(base, index, scale, disp); |
+ } |
+ case kMode_MR1I: |
+ case kMode_MR2I: |
+ case kMode_MR4I: |
+ case kMode_MR8I: { |
+ Register base = InputRegister(NextOffset(offset)); |
+ Register index = InputRegister(NextOffset(offset)); |
+ ScaleFactor scale = ScaleFor(kMode_MR1I, mode); |
+ int32_t disp = InputInt32(NextOffset(offset)); |
+ return Operand(base, index, scale, disp); |
+ } |
+ case kMode_M1: |
+ case kMode_M2: |
+ case kMode_M4: |
+ case kMode_M8: { |
+ Register index = InputRegister(NextOffset(offset)); |
+ ScaleFactor scale = ScaleFor(kMode_M1, mode); |
+ int32_t disp = 0; |
+ return Operand(index, scale, disp); |
+ } |
+ case kMode_M1I: |
+ case kMode_M2I: |
+ case kMode_M4I: |
+ case kMode_M8I: { |
+ Register index = InputRegister(NextOffset(offset)); |
+ ScaleFactor scale = ScaleFor(kMode_M1I, mode); |
+ int32_t disp = InputInt32(NextOffset(offset)); |
+ return Operand(index, scale, disp); |
+ } |
+ case kMode_None: |
UNREACHABLE(); |
return Operand(no_reg, 0); |
} |
+ UNREACHABLE(); |
+ return Operand(no_reg, 0); |
} |
Operand MemoryOperand() { |