 Chromium Code Reviews
 Chromium Code Reviews Issue 763963002:
  [turbofan] Add checked load/store operators.  (Closed) 
  Base URL: https://chromium.googlesource.com/v8/v8.git@master
    
  
    Issue 763963002:
  [turbofan] Add checked load/store operators.  (Closed) 
  Base URL: https://chromium.googlesource.com/v8/v8.git@master| 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..8f98cad17a9d35c716018afdc938ef1242c83b1a 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()); | 
| 
Rodolph Perfetta
2014/12/01 15:16:34
This won't do what you expect. Since result is a d
 
Benedikt Meurer
2014/12/01 17:58:39
Yeah the arm64 macro assembler can be quite confus
 | 
| + } | 
| + | 
| + 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()); \ | 
| 
Rodolph Perfetta
2014/12/01 15:16:34
nit, use the upper case variant: Bind. Same below.
 
Benedikt Meurer
2014/12/01 17:58:39
Done.
 | 
| + } 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; | 
| } | 
| } |