Index: src/compiler/arm64/code-generator-arm64.cc |
diff --git a/src/compiler/arm64/code-generator-arm64.cc b/src/compiler/arm64/code-generator-arm64.cc |
index d1d6a6d087eed7abe11bc14eb409be95935cdf5f..62145cb445ac56e5758e8a75d05c2a2801904af7 100644 |
--- a/src/compiler/arm64/code-generator-arm64.cc |
+++ b/src/compiler/arm64/code-generator-arm64.cc |
@@ -24,6 +24,18 @@ class Arm64OperandConverter FINAL : public InstructionOperandConverter { |
Arm64OperandConverter(CodeGenerator* gen, Instruction* instr) |
: InstructionOperandConverter(gen, instr) {} |
+ DoubleRegister InputFloat32Register(int index) { |
+ return InputDoubleRegister(index).S(); |
+ } |
+ |
+ DoubleRegister InputFloat64Register(int index) { |
+ return InputDoubleRegister(index); |
+ } |
+ |
+ DoubleRegister OutputFloat32Register() { return OutputDoubleRegister().S(); } |
+ |
+ DoubleRegister OutputFloat64Register() { return OutputDoubleRegister(); } |
+ |
Register InputRegister32(int index) { |
return ToRegister(instr_->InputAt(index)).W(); |
} |
@@ -106,9 +118,8 @@ class Arm64OperandConverter FINAL : public InstructionOperandConverter { |
return MemOperand(no_reg); |
} |
- MemOperand MemoryOperand() { |
- int index = 0; |
- return MemoryOperand(&index); |
+ MemOperand MemoryOperand(int first_index = 0) { |
+ return MemoryOperand(&first_index); |
} |
Operand ToOperand(InstructionOperand* op) { |
@@ -163,6 +174,100 @@ class Arm64OperandConverter FINAL : public InstructionOperandConverter { |
}; |
+namespace { |
+ |
+class OutOfLineLoadFloat32 FINAL : public OutOfLineCode { |
+ public: |
+ OutOfLineLoadFloat32(CodeGenerator* gen, DoubleRegister result) |
+ : OutOfLineCode(gen), result_(result) {} |
+ |
+ void Generate() FINAL { |
+ __ Fmov(result_, std::numeric_limits<float>::quiet_NaN()); |
+ } |
+ |
+ private: |
+ DoubleRegister const result_; |
+}; |
+ |
+ |
+class OutOfLineLoadFloat64 FINAL : public OutOfLineCode { |
+ public: |
+ OutOfLineLoadFloat64(CodeGenerator* gen, DoubleRegister result) |
+ : OutOfLineCode(gen), result_(result) {} |
+ |
+ void Generate() FINAL { |
+ __ Fmov(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_, 0); } |
+ |
+ private: |
+ Register const result_; |
+}; |
+ |
+} // namespace |
+ |
+ |
+#define ASSEMBLE_CHECKED_LOAD_FLOAT(width) \ |
+ do { \ |
+ auto result = i.OutputFloat##width##Register(); \ |
+ auto offset = i.InputRegister32(0); \ |
+ auto length = i.InputOperand32(1); \ |
+ __ Cmp(offset, length); \ |
+ auto ool = new (zone()) OutOfLineLoadFloat##width(this, result); \ |
+ __ B(hs, ool->entry()); \ |
+ __ Ldr(result, i.MemoryOperand(2)); \ |
+ __ Bind(ool->exit()); \ |
+ } while (0) |
+ |
+ |
+#define ASSEMBLE_CHECKED_LOAD_INTEGER(asm_instr) \ |
+ do { \ |
+ auto result = i.OutputRegister32(); \ |
+ auto offset = i.InputRegister32(0); \ |
+ auto length = i.InputOperand32(1); \ |
+ __ Cmp(offset, length); \ |
+ auto ool = new (zone()) OutOfLineLoadInteger(this, result); \ |
+ __ B(hs, ool->entry()); \ |
+ __ asm_instr(result, i.MemoryOperand(2)); \ |
+ __ Bind(ool->exit()); \ |
+ } while (0) |
+ |
+ |
+#define ASSEMBLE_CHECKED_STORE_FLOAT(width) \ |
+ do { \ |
+ auto offset = i.InputRegister32(0); \ |
+ auto length = i.InputOperand32(1); \ |
+ __ Cmp(offset, length); \ |
+ Label done; \ |
+ __ B(hs, &done); \ |
+ __ Str(i.InputFloat##width##Register(2), i.MemoryOperand(3)); \ |
+ __ Bind(&done); \ |
+ } while (0) |
+ |
+ |
+#define ASSEMBLE_CHECKED_STORE_INTEGER(asm_instr) \ |
+ do { \ |
+ auto offset = i.InputRegister32(0); \ |
+ auto length = i.InputOperand32(1); \ |
+ __ Cmp(offset, length); \ |
+ Label done; \ |
+ __ B(hs, &done); \ |
+ __ asm_instr(i.InputRegister32(2), i.MemoryOperand(3)); \ |
+ __ Bind(&done); \ |
+ } while (0) |
+ |
+ |
#define ASSEMBLE_SHIFT(asm_instr, width) \ |
do { \ |
if (instr->InputAt(1)->IsRegister()) { \ |
@@ -616,6 +721,42 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) { |
} |
break; |
} |
+ case kCheckedLoadInt8: |
+ ASSEMBLE_CHECKED_LOAD_INTEGER(Ldrsb); |
+ break; |
+ case kCheckedLoadUint8: |
+ ASSEMBLE_CHECKED_LOAD_INTEGER(Ldrb); |
+ break; |
+ case kCheckedLoadInt16: |
+ ASSEMBLE_CHECKED_LOAD_INTEGER(Ldrsh); |
+ break; |
+ case kCheckedLoadUint16: |
+ ASSEMBLE_CHECKED_LOAD_INTEGER(Ldrh); |
+ break; |
+ case kCheckedLoadWord32: |
+ ASSEMBLE_CHECKED_LOAD_INTEGER(Ldr); |
+ break; |
+ case kCheckedLoadFloat32: |
+ ASSEMBLE_CHECKED_LOAD_FLOAT(32); |
+ break; |
+ case kCheckedLoadFloat64: |
+ ASSEMBLE_CHECKED_LOAD_FLOAT(64); |
+ break; |
+ case kCheckedStoreWord8: |
+ ASSEMBLE_CHECKED_STORE_INTEGER(Strb); |
+ break; |
+ case kCheckedStoreWord16: |
+ ASSEMBLE_CHECKED_STORE_INTEGER(Strh); |
+ break; |
+ case kCheckedStoreWord32: |
+ ASSEMBLE_CHECKED_STORE_INTEGER(Str); |
+ break; |
+ case kCheckedStoreFloat32: |
+ ASSEMBLE_CHECKED_STORE_FLOAT(32); |
+ break; |
+ case kCheckedStoreFloat64: |
+ ASSEMBLE_CHECKED_STORE_FLOAT(64); |
+ break; |
} |
} |
@@ -770,7 +911,7 @@ void CodeGenerator::AssembleArchBoolean(Instruction* instr, |
cc = vc; |
break; |
} |
- __ bind(&check); |
+ __ Bind(&check); |
__ Cset(reg, cc); |
__ Bind(&done); |
} |