| Index: src/compiler/mips64/code-generator-mips64.cc
|
| diff --git a/src/compiler/mips64/code-generator-mips64.cc b/src/compiler/mips64/code-generator-mips64.cc
|
| index 45cf340b65e68ab970eb65a26f2e52d2a4e9cf40..ba921e265b2bc6a748b8992fd05f3410c0a7c0af 100644
|
| --- a/src/compiler/mips64/code-generator-mips64.cc
|
| +++ b/src/compiler/mips64/code-generator-mips64.cc
|
| @@ -386,85 +386,108 @@ FPUCondition FlagsConditionToConditionCmpFPU(bool& predicate,
|
| }
|
|
|
| } // namespace
|
| -
|
| -#define ASSEMBLE_CHECKED_LOAD_FLOAT(width, asm_instr) \
|
| +#define ASSEMBLE_BOUNDS_CHECK_REGISTER(offset, length, out_of_bounds) \
|
| do { \
|
| - auto result = i.Output##width##Register(); \
|
| - auto ool = new (zone()) OutOfLineLoad##width(this, result); \
|
| - if (instr->InputAt(0)->IsRegister()) { \
|
| - auto offset = i.InputRegister(0); \
|
| - __ Branch(USE_DELAY_SLOT, ool->entry(), hs, offset, i.InputOperand(1)); \
|
| - __ And(kScratchReg, offset, Operand(0xffffffff)); \
|
| - __ Daddu(kScratchReg, i.InputRegister(2), kScratchReg); \
|
| - __ asm_instr(result, MemOperand(kScratchReg, 0)); \
|
| + if (!length.is_reg() && base::bits::IsPowerOfTwo64(length.immediate())) { \
|
| + __ And(kScratchReg, offset, Operand(~(length.immediate() - 1))); \
|
| + __ Branch(USE_DELAY_SLOT, out_of_bounds, ne, kScratchReg, \
|
| + Operand(zero_reg)); \
|
| } else { \
|
| - int offset = static_cast<int>(i.InputOperand(0).immediate()); \
|
| - __ Branch(ool->entry(), ls, i.InputRegister(1), Operand(offset)); \
|
| - __ asm_instr(result, MemOperand(i.InputRegister(2), offset)); \
|
| + __ Branch(USE_DELAY_SLOT, out_of_bounds, hs, offset, length); \
|
| } \
|
| - __ bind(ool->exit()); \
|
| } while (0)
|
|
|
| -#define ASSEMBLE_CHECKED_LOAD_INTEGER(asm_instr) \
|
| +#define ASSEMBLE_BOUNDS_CHECK_IMMEDIATE(offset, length, out_of_bounds) \
|
| do { \
|
| - auto result = i.OutputRegister(); \
|
| - auto ool = new (zone()) OutOfLineLoadInteger(this, result); \
|
| - if (instr->InputAt(0)->IsRegister()) { \
|
| - auto offset = i.InputRegister(0); \
|
| - __ Branch(USE_DELAY_SLOT, ool->entry(), hs, offset, i.InputOperand(1)); \
|
| - __ And(kScratchReg, offset, Operand(0xffffffff)); \
|
| - __ Daddu(kScratchReg, i.InputRegister(2), kScratchReg); \
|
| - __ asm_instr(result, MemOperand(kScratchReg, 0)); \
|
| + if (!length.is_reg() && base::bits::IsPowerOfTwo64(length.immediate())) { \
|
| + __ Or(kScratchReg, zero_reg, Operand(offset)); \
|
| + __ And(kScratchReg, kScratchReg, Operand(~(length.immediate() - 1))); \
|
| + __ Branch(out_of_bounds, ne, kScratchReg, Operand(zero_reg)); \
|
| } else { \
|
| - int offset = static_cast<int>(i.InputOperand(0).immediate()); \
|
| - __ Branch(ool->entry(), ls, i.InputRegister(1), Operand(offset)); \
|
| - __ asm_instr(result, MemOperand(i.InputRegister(2), offset)); \
|
| + __ Branch(out_of_bounds, ls, length.rm(), Operand(offset)); \
|
| } \
|
| - __ bind(ool->exit()); \
|
| } while (0)
|
|
|
| -#define ASSEMBLE_CHECKED_STORE_FLOAT(width, asm_instr) \
|
| - do { \
|
| - Label done; \
|
| - if (instr->InputAt(0)->IsRegister()) { \
|
| - auto offset = i.InputRegister(0); \
|
| - auto value = i.InputOrZero##width##Register(2); \
|
| - if (value.is(kDoubleRegZero) && !__ IsDoubleZeroRegSet()) { \
|
| - __ Move(kDoubleRegZero, 0.0); \
|
| - } \
|
| - __ Branch(USE_DELAY_SLOT, &done, hs, offset, i.InputOperand(1)); \
|
| - __ And(kScratchReg, offset, Operand(0xffffffff)); \
|
| - __ Daddu(kScratchReg, i.InputRegister(3), kScratchReg); \
|
| - __ asm_instr(value, MemOperand(kScratchReg, 0)); \
|
| - } else { \
|
| - int offset = static_cast<int>(i.InputOperand(0).immediate()); \
|
| - auto value = i.InputOrZero##width##Register(2); \
|
| - if (value.is(kDoubleRegZero) && !__ IsDoubleZeroRegSet()) { \
|
| - __ Move(kDoubleRegZero, 0.0); \
|
| - } \
|
| - __ Branch(&done, ls, i.InputRegister(1), Operand(offset)); \
|
| - __ asm_instr(value, MemOperand(i.InputRegister(3), offset)); \
|
| - } \
|
| - __ bind(&done); \
|
| +#define ASSEMBLE_CHECKED_LOAD_FLOAT(width, asm_instr) \
|
| + do { \
|
| + auto result = i.Output##width##Register(); \
|
| + auto ool = new (zone()) OutOfLineLoad##width(this, result); \
|
| + if (instr->InputAt(0)->IsRegister()) { \
|
| + auto offset = i.InputRegister(0); \
|
| + ASSEMBLE_BOUNDS_CHECK_REGISTER(offset, i.InputOperand(1), ool->entry()); \
|
| + __ And(kScratchReg, offset, Operand(0xffffffff)); \
|
| + __ Daddu(kScratchReg, i.InputRegister(2), kScratchReg); \
|
| + __ asm_instr(result, MemOperand(kScratchReg, 0)); \
|
| + } else { \
|
| + int offset = static_cast<int>(i.InputOperand(0).immediate()); \
|
| + ASSEMBLE_BOUNDS_CHECK_IMMEDIATE(offset, i.InputOperand(1), \
|
| + ool->entry()); \
|
| + __ asm_instr(result, MemOperand(i.InputRegister(2), offset)); \
|
| + } \
|
| + __ bind(ool->exit()); \
|
| + } while (0)
|
| +
|
| +#define ASSEMBLE_CHECKED_LOAD_INTEGER(asm_instr) \
|
| + do { \
|
| + auto result = i.OutputRegister(); \
|
| + auto ool = new (zone()) OutOfLineLoadInteger(this, result); \
|
| + if (instr->InputAt(0)->IsRegister()) { \
|
| + auto offset = i.InputRegister(0); \
|
| + ASSEMBLE_BOUNDS_CHECK_REGISTER(offset, i.InputOperand(1), ool->entry()); \
|
| + __ And(kScratchReg, offset, Operand(0xffffffff)); \
|
| + __ Daddu(kScratchReg, i.InputRegister(2), kScratchReg); \
|
| + __ asm_instr(result, MemOperand(kScratchReg, 0)); \
|
| + } else { \
|
| + int offset = static_cast<int>(i.InputOperand(0).immediate()); \
|
| + ASSEMBLE_BOUNDS_CHECK_IMMEDIATE(offset, i.InputOperand(1), \
|
| + ool->entry()); \
|
| + __ asm_instr(result, MemOperand(i.InputRegister(2), offset)); \
|
| + } \
|
| + __ bind(ool->exit()); \
|
| + } while (0)
|
| +
|
| +#define ASSEMBLE_CHECKED_STORE_FLOAT(width, asm_instr) \
|
| + do { \
|
| + Label done; \
|
| + if (instr->InputAt(0)->IsRegister()) { \
|
| + auto offset = i.InputRegister(0); \
|
| + auto value = i.InputOrZero##width##Register(2); \
|
| + if (value.is(kDoubleRegZero) && !__ IsDoubleZeroRegSet()) { \
|
| + __ Move(kDoubleRegZero, 0.0); \
|
| + } \
|
| + ASSEMBLE_BOUNDS_CHECK_REGISTER(offset, i.InputOperand(1), &done); \
|
| + __ And(kScratchReg, offset, Operand(0xffffffff)); \
|
| + __ Daddu(kScratchReg, i.InputRegister(3), kScratchReg); \
|
| + __ asm_instr(value, MemOperand(kScratchReg, 0)); \
|
| + } else { \
|
| + int offset = static_cast<int>(i.InputOperand(0).immediate()); \
|
| + auto value = i.InputOrZero##width##Register(2); \
|
| + if (value.is(kDoubleRegZero) && !__ IsDoubleZeroRegSet()) { \
|
| + __ Move(kDoubleRegZero, 0.0); \
|
| + } \
|
| + ASSEMBLE_BOUNDS_CHECK_IMMEDIATE(offset, i.InputOperand(1), &done); \
|
| + __ asm_instr(value, MemOperand(i.InputRegister(3), offset)); \
|
| + } \
|
| + __ bind(&done); \
|
| } while (0)
|
|
|
| -#define ASSEMBLE_CHECKED_STORE_INTEGER(asm_instr) \
|
| - do { \
|
| - Label done; \
|
| - if (instr->InputAt(0)->IsRegister()) { \
|
| - auto offset = i.InputRegister(0); \
|
| - auto value = i.InputOrZeroRegister(2); \
|
| - __ Branch(USE_DELAY_SLOT, &done, hs, offset, i.InputOperand(1)); \
|
| - __ And(kScratchReg, offset, Operand(0xffffffff)); \
|
| - __ Daddu(kScratchReg, i.InputRegister(3), kScratchReg); \
|
| - __ asm_instr(value, MemOperand(kScratchReg, 0)); \
|
| - } else { \
|
| - int offset = static_cast<int>(i.InputOperand(0).immediate()); \
|
| - auto value = i.InputOrZeroRegister(2); \
|
| - __ Branch(&done, ls, i.InputRegister(1), Operand(offset)); \
|
| - __ asm_instr(value, MemOperand(i.InputRegister(3), offset)); \
|
| - } \
|
| - __ bind(&done); \
|
| +#define ASSEMBLE_CHECKED_STORE_INTEGER(asm_instr) \
|
| + do { \
|
| + Label done; \
|
| + if (instr->InputAt(0)->IsRegister()) { \
|
| + auto offset = i.InputRegister(0); \
|
| + auto value = i.InputOrZeroRegister(2); \
|
| + ASSEMBLE_BOUNDS_CHECK_REGISTER(offset, i.InputOperand(1), &done); \
|
| + __ And(kScratchReg, offset, Operand(0xffffffff)); \
|
| + __ Daddu(kScratchReg, i.InputRegister(3), kScratchReg); \
|
| + __ asm_instr(value, MemOperand(kScratchReg, 0)); \
|
| + } else { \
|
| + int offset = static_cast<int>(i.InputOperand(0).immediate()); \
|
| + auto value = i.InputOrZeroRegister(2); \
|
| + ASSEMBLE_BOUNDS_CHECK_IMMEDIATE(offset, i.InputOperand(1), &done); \
|
| + __ asm_instr(value, MemOperand(i.InputRegister(3), offset)); \
|
| + } \
|
| + __ bind(&done); \
|
| } while (0)
|
|
|
| #define ASSEMBLE_ROUND_DOUBLE_TO_DOUBLE(mode) \
|
|
|