Index: src/compiler/ia32/code-generator-ia32.cc |
diff --git a/src/compiler/ia32/code-generator-ia32.cc b/src/compiler/ia32/code-generator-ia32.cc |
index 17d7a8e042bca6842acbce217e5147cdca0a5c73..214d24ae1854fe089049882c3c0ce6c91852f00b 100644 |
--- a/src/compiler/ia32/code-generator-ia32.cc |
+++ b/src/compiler/ia32/code-generator-ia32.cc |
@@ -155,18 +155,111 @@ class IA32OperandConverter : public InstructionOperandConverter { |
return Operand(no_reg, 0); |
} |
- Operand MemoryOperand() { |
- int first_input = 0; |
+ Operand MemoryOperand(int first_input = 0) { |
return MemoryOperand(&first_input); |
} |
}; |
-static bool HasImmediateInput(Instruction* instr, int index) { |
+namespace { |
+ |
+bool HasImmediateInput(Instruction* instr, int index) { |
return instr->InputAt(index)->IsImmediate(); |
} |
+class OutOfLineLoadInteger FINAL : public OutOfLineCode { |
+ public: |
+ OutOfLineLoadInteger(CodeGenerator* gen, Register result) |
+ : OutOfLineCode(gen), result_(result) {} |
+ |
+ void Generate() FINAL { __ xor_(result_, result_); } |
+ |
+ private: |
+ Register const result_; |
+}; |
+ |
+ |
+class OutOfLineLoadFloat FINAL : public OutOfLineCode { |
+ public: |
+ OutOfLineLoadFloat(CodeGenerator* gen, XMMRegister result) |
+ : OutOfLineCode(gen), result_(result) {} |
+ |
+ void Generate() FINAL { __ pcmpeqd(result_, result_); } |
+ |
+ private: |
+ XMMRegister const result_; |
+}; |
+ |
+} // namespace |
+ |
+ |
+#define ASSEMBLE_CHECKED_LOAD_FLOAT(asm_instr) \ |
+ do { \ |
+ auto result = i.OutputDoubleRegister(); \ |
+ auto offset = i.InputRegister(0); \ |
+ if (instr->InputAt(1)->IsRegister()) { \ |
+ __ cmp(offset, i.InputRegister(1)); \ |
+ } else { \ |
+ __ cmp(offset, i.InputImmediate(1)); \ |
+ } \ |
+ OutOfLineCode* ool = new (zone()) OutOfLineLoadFloat(this, result); \ |
+ __ j(above_equal, ool->entry()); \ |
+ __ asm_instr(result, i.MemoryOperand(2)); \ |
+ __ bind(ool->exit()); \ |
+ } while (false) |
+ |
+ |
+#define ASSEMBLE_CHECKED_LOAD_INTEGER(asm_instr) \ |
+ do { \ |
+ auto result = i.OutputRegister(); \ |
+ auto offset = i.InputRegister(0); \ |
+ if (instr->InputAt(1)->IsRegister()) { \ |
+ __ cmp(offset, i.InputRegister(1)); \ |
+ } else { \ |
+ __ cmp(offset, i.InputImmediate(1)); \ |
+ } \ |
+ OutOfLineCode* ool = new (zone()) OutOfLineLoadInteger(this, result); \ |
+ __ j(above_equal, ool->entry()); \ |
+ __ asm_instr(result, i.MemoryOperand(2)); \ |
+ __ bind(ool->exit()); \ |
+ } while (false) |
+ |
+ |
+#define ASSEMBLE_CHECKED_STORE_FLOAT(asm_instr) \ |
+ do { \ |
+ auto offset = i.InputRegister(0); \ |
+ if (instr->InputAt(1)->IsRegister()) { \ |
+ __ cmp(offset, i.InputRegister(1)); \ |
+ } else { \ |
+ __ cmp(offset, i.InputImmediate(1)); \ |
+ } \ |
+ Label done; \ |
+ __ j(above_equal, &done, Label::kNear); \ |
+ __ asm_instr(i.MemoryOperand(3), i.InputDoubleRegister(2)); \ |
+ __ bind(&done); \ |
+ } while (false) |
+ |
+ |
+#define ASSEMBLE_CHECKED_STORE_INTEGER(asm_instr) \ |
+ do { \ |
+ auto offset = i.InputRegister(0); \ |
+ if (instr->InputAt(1)->IsRegister()) { \ |
+ __ cmp(offset, i.InputRegister(1)); \ |
+ } else { \ |
+ __ cmp(offset, i.InputImmediate(1)); \ |
+ } \ |
+ Label done; \ |
+ __ j(above_equal, &done, Label::kNear); \ |
+ if (instr->InputAt(2)->IsRegister()) { \ |
+ __ asm_instr(i.MemoryOperand(3), i.InputRegister(2)); \ |
+ } else { \ |
+ __ asm_instr(i.MemoryOperand(3), i.InputImmediate(2)); \ |
+ } \ |
+ __ bind(&done); \ |
+ } while (false) |
+ |
+ |
// Assembles an instruction after register allocation, producing machine code. |
void CodeGenerator::AssembleArchInstruction(Instruction* instr) { |
IA32OperandConverter i(this, instr); |
@@ -483,6 +576,42 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) { |
__ RecordWrite(object, index, value, mode); |
break; |
} |
+ case kCheckedLoadInt8: |
+ ASSEMBLE_CHECKED_LOAD_INTEGER(movsx_b); |
+ break; |
+ case kCheckedLoadUint8: |
+ ASSEMBLE_CHECKED_LOAD_INTEGER(movzx_b); |
+ break; |
+ case kCheckedLoadInt16: |
+ ASSEMBLE_CHECKED_LOAD_INTEGER(movsx_w); |
+ break; |
+ case kCheckedLoadUint16: |
+ ASSEMBLE_CHECKED_LOAD_INTEGER(movzx_w); |
+ break; |
+ case kCheckedLoadWord32: |
+ ASSEMBLE_CHECKED_LOAD_INTEGER(mov); |
+ break; |
+ case kCheckedLoadFloat32: |
+ ASSEMBLE_CHECKED_LOAD_FLOAT(movss); |
+ break; |
+ case kCheckedLoadFloat64: |
+ ASSEMBLE_CHECKED_LOAD_FLOAT(movsd); |
+ break; |
+ case kCheckedStoreWord8: |
+ ASSEMBLE_CHECKED_STORE_INTEGER(mov_b); |
+ break; |
+ case kCheckedStoreWord16: |
+ ASSEMBLE_CHECKED_STORE_INTEGER(mov_w); |
+ break; |
+ case kCheckedStoreWord32: |
+ ASSEMBLE_CHECKED_STORE_INTEGER(mov); |
+ break; |
+ case kCheckedStoreFloat32: |
+ ASSEMBLE_CHECKED_STORE_FLOAT(movss); |
+ break; |
+ case kCheckedStoreFloat64: |
+ ASSEMBLE_CHECKED_STORE_FLOAT(movsd); |
+ break; |
} |
} |