Index: src/compiler/mips/code-generator-mips.cc |
diff --git a/src/compiler/mips/code-generator-mips.cc b/src/compiler/mips/code-generator-mips.cc |
index 6fb0a30edd41a2261f73140a882eda1e376af8e2..1b004e51e3f24f4782a5e8d227b842b59e2586bc 100644 |
--- a/src/compiler/mips/code-generator-mips.cc |
+++ b/src/compiler/mips/code-generator-mips.cc |
@@ -102,10 +102,7 @@ class MipsOperandConverter FINAL : public InstructionOperandConverter { |
return MemOperand(no_reg); |
} |
- MemOperand MemoryOperand() { |
- int index = 0; |
- return MemoryOperand(&index); |
- } |
+ MemOperand MemoryOperand(int index = 0) { return MemoryOperand(&index); } |
MemOperand ToMemOperand(InstructionOperand* op) const { |
DCHECK(op != NULL); |
@@ -124,6 +121,98 @@ static inline bool HasRegisterInput(Instruction* instr, int index) { |
} |
+namespace { |
+ |
+class OutOfLineLoadSingle FINAL : public OutOfLineCode { |
+ public: |
+ OutOfLineLoadSingle(CodeGenerator* gen, FloatRegister result) |
+ : OutOfLineCode(gen), result_(result) {} |
+ |
+ void Generate() FINAL { |
+ __ Move(result_, std::numeric_limits<float>::quiet_NaN()); |
+ } |
+ |
+ private: |
+ FloatRegister const result_; |
+}; |
+ |
+ |
+class OutOfLineLoadDouble FINAL : public OutOfLineCode { |
+ public: |
+ OutOfLineLoadDouble(CodeGenerator* gen, DoubleRegister result) |
+ : OutOfLineCode(gen), result_(result) {} |
+ |
+ void Generate() FINAL { |
+ __ Move(result_, std::numeric_limits<double>::quiet_NaN()); |
+ } |
+ |
+ private: |
+ DoubleRegister const result_; |
+}; |
+ |
+ |
+class OutOfLineLoadInteger FINAL : public OutOfLineCode { |
+ public: |
+ OutOfLineLoadInteger(CodeGenerator* gen, Register result) |
+ : OutOfLineCode(gen), result_(result) {} |
+ |
+ void Generate() FINAL { __ mov(result_, zero_reg); } |
+ |
+ private: |
+ Register const result_; |
+}; |
+ |
+} // namespace |
+ |
+ |
+#define ASSEMBLE_CHECKED_LOAD_FLOAT(width, asm_instr) \ |
+ do { \ |
+ auto result = i.Output##width##Register(); \ |
+ auto offset = i.InputRegister(0); \ |
+ auto ool = new (zone()) OutOfLineLoad##width(this, result); \ |
+ __ Branch(ool->entry(), hs, offset, Operand(i.InputRegister(1))); \ |
+ __ addu(at, i.InputRegister(2), offset); \ |
+ __ asm_instr(result, MemOperand(at, 0)); \ |
+ __ bind(ool->exit()); \ |
+ } while (0) |
+ |
+ |
+#define ASSEMBLE_CHECKED_LOAD_INTEGER(asm_instr) \ |
+ do { \ |
+ auto result = i.OutputRegister(); \ |
+ auto offset = i.InputRegister(0); \ |
+ auto ool = new (zone()) OutOfLineLoadInteger(this, result); \ |
+ __ Branch(ool->entry(), hs, offset, Operand(i.InputRegister(1))); \ |
+ __ addu(at, i.InputRegister(2), offset); \ |
+ __ asm_instr(result, MemOperand(at, 0)); \ |
+ __ bind(ool->exit()); \ |
+ } while (0) |
+ |
+ |
+#define ASSEMBLE_CHECKED_STORE_FLOAT(width, asm_instr) \ |
+ do { \ |
+ auto offset = i.InputRegister(0); \ |
+ Label done; \ |
+ __ Branch(&done, hs, offset, Operand(i.InputRegister(1))); \ |
+ auto value = i.Input##width##Register(2); \ |
+ __ addu(at, i.InputRegister(3), offset); \ |
+ __ asm_instr(value, MemOperand(at, 0)); \ |
+ __ bind(&done); \ |
+ } while (0) |
+ |
+ |
+#define ASSEMBLE_CHECKED_STORE_INTEGER(asm_instr) \ |
+ do { \ |
+ auto offset = i.InputRegister(0); \ |
+ Label done; \ |
+ __ Branch(&done, hs, offset, Operand(i.InputRegister(1))); \ |
+ auto value = i.InputRegister(2); \ |
+ __ addu(at, i.InputRegister(3), offset); \ |
+ __ asm_instr(value, MemOperand(at, 0)); \ |
+ __ bind(&done); \ |
+ } while (0) |
+ |
+ |
// Assembles an instruction after register allocation, producing machine code. |
void CodeGenerator::AssembleArchInstruction(Instruction* instr) { |
MipsOperandConverter i(this, instr); |
@@ -373,7 +462,7 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) { |
case kMipsPush: |
__ Push(i.InputRegister(0)); |
break; |
- case kMipsStoreWriteBarrier: |
+ case kMipsStoreWriteBarrier: { |
Register object = i.InputRegister(0); |
Register index = i.InputRegister(1); |
Register value = i.InputRegister(2); |
@@ -384,6 +473,43 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) { |
RAStatus ra_status = kRAHasNotBeenSaved; |
__ RecordWrite(object, index, value, ra_status, mode); |
break; |
+ } |
+ case kCheckedLoadInt8: |
+ ASSEMBLE_CHECKED_LOAD_INTEGER(lb); |
+ break; |
+ case kCheckedLoadUint8: |
+ ASSEMBLE_CHECKED_LOAD_INTEGER(lbu); |
+ break; |
+ case kCheckedLoadInt16: |
+ ASSEMBLE_CHECKED_LOAD_INTEGER(lh); |
+ break; |
+ case kCheckedLoadUint16: |
+ ASSEMBLE_CHECKED_LOAD_INTEGER(lhu); |
+ break; |
+ case kCheckedLoadWord32: |
+ ASSEMBLE_CHECKED_LOAD_INTEGER(lw); |
+ break; |
+ case kCheckedLoadFloat32: |
+ ASSEMBLE_CHECKED_LOAD_FLOAT(Single, lwc1); |
+ break; |
+ case kCheckedLoadFloat64: |
+ ASSEMBLE_CHECKED_LOAD_FLOAT(Double, ldc1); |
+ break; |
+ case kCheckedStoreWord8: |
+ ASSEMBLE_CHECKED_STORE_INTEGER(sb); |
+ break; |
+ case kCheckedStoreWord16: |
+ ASSEMBLE_CHECKED_STORE_INTEGER(sh); |
+ break; |
+ case kCheckedStoreWord32: |
+ ASSEMBLE_CHECKED_STORE_INTEGER(sw); |
+ break; |
+ case kCheckedStoreFloat32: |
+ ASSEMBLE_CHECKED_STORE_FLOAT(Single, swc1); |
+ break; |
+ case kCheckedStoreFloat64: |
+ ASSEMBLE_CHECKED_STORE_FLOAT(Double, sdc1); |
+ break; |
} |
} |
@@ -805,14 +931,13 @@ void CodeGenerator::AssembleMove(InstructionOperand* source, |
} |
if (destination->IsStackSlot()) __ sw(dst, g.ToMemOperand(destination)); |
} else if (src.type() == Constant::kFloat32) { |
- FPURegister dst = destination->IsDoubleRegister() |
- ? g.ToDoubleRegister(destination) |
- : kScratchDoubleReg.low(); |
- // TODO(turbofan): Can we do better here? |
- __ li(at, Operand(bit_cast<int32_t>(src.ToFloat32()))); |
- __ mtc1(at, dst); |
if (destination->IsDoubleStackSlot()) { |
- __ swc1(dst, g.ToMemOperand(destination)); |
+ MemOperand dst = g.ToMemOperand(destination); |
+ __ li(at, Operand(bit_cast<int32_t>(src.ToFloat32()))); |
+ __ sw(at, dst); |
+ } else { |
+ FloatRegister dst = g.ToSingleRegister(destination); |
+ __ Move(dst, src.ToFloat32()); |
} |
} else { |
DCHECK_EQ(Constant::kFloat64, src.type()); |