Commit 6c389cef authored by sreten.kovacevic's avatar sreten.kovacevic Committed by Commit bot

MIPS64: Port `[turbofan] ARM64: Faster checked ops for PoT arrays`

Port 95f210d5

Original commit message:
Improve CheckedLoad and Store bounds checking for arrays with power of two
length.

BUG=

Review-Url: https://codereview.chromium.org/2632213002
Cr-Commit-Position: refs/heads/master@{#42414}
parent f12661a1
......@@ -386,6 +386,27 @@ FPUCondition FlagsConditionToConditionCmpFPU(bool& predicate,
}
} // namespace
#define ASSEMBLE_BOUNDS_CHECK_REGISTER(offset, length, out_of_bounds) \
do { \
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 { \
__ Branch(USE_DELAY_SLOT, out_of_bounds, hs, offset, length); \
} \
} while (0)
#define ASSEMBLE_BOUNDS_CHECK_IMMEDIATE(offset, length, out_of_bounds) \
do { \
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 { \
__ Branch(out_of_bounds, ls, length.rm(), Operand(offset)); \
} \
} while (0)
#define ASSEMBLE_CHECKED_LOAD_FLOAT(width, asm_instr) \
do { \
......@@ -393,13 +414,14 @@ FPUCondition FlagsConditionToConditionCmpFPU(bool& predicate,
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)); \
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()); \
__ Branch(ool->entry(), ls, i.InputRegister(1), Operand(offset)); \
ASSEMBLE_BOUNDS_CHECK_IMMEDIATE(offset, i.InputOperand(1), \
ool->entry()); \
__ asm_instr(result, MemOperand(i.InputRegister(2), offset)); \
} \
__ bind(ool->exit()); \
......@@ -411,13 +433,14 @@ FPUCondition FlagsConditionToConditionCmpFPU(bool& predicate,
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)); \
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()); \
__ Branch(ool->entry(), ls, i.InputRegister(1), Operand(offset)); \
ASSEMBLE_BOUNDS_CHECK_IMMEDIATE(offset, i.InputOperand(1), \
ool->entry()); \
__ asm_instr(result, MemOperand(i.InputRegister(2), offset)); \
} \
__ bind(ool->exit()); \
......@@ -432,7 +455,7 @@ FPUCondition FlagsConditionToConditionCmpFPU(bool& predicate,
if (value.is(kDoubleRegZero) && !__ IsDoubleZeroRegSet()) { \
__ Move(kDoubleRegZero, 0.0); \
} \
__ Branch(USE_DELAY_SLOT, &done, hs, offset, i.InputOperand(1)); \
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)); \
......@@ -442,7 +465,7 @@ FPUCondition FlagsConditionToConditionCmpFPU(bool& predicate,
if (value.is(kDoubleRegZero) && !__ IsDoubleZeroRegSet()) { \
__ Move(kDoubleRegZero, 0.0); \
} \
__ Branch(&done, ls, i.InputRegister(1), Operand(offset)); \
ASSEMBLE_BOUNDS_CHECK_IMMEDIATE(offset, i.InputOperand(1), &done); \
__ asm_instr(value, MemOperand(i.InputRegister(3), offset)); \
} \
__ bind(&done); \
......@@ -454,14 +477,14 @@ FPUCondition FlagsConditionToConditionCmpFPU(bool& predicate,
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)); \
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); \
__ Branch(&done, ls, i.InputRegister(1), Operand(offset)); \
ASSEMBLE_BOUNDS_CHECK_IMMEDIATE(offset, i.InputOperand(1), &done); \
__ asm_instr(value, MemOperand(i.InputRegister(3), offset)); \
} \
__ bind(&done); \
......
......@@ -1854,6 +1854,15 @@ void InstructionSelector::VisitCheckedLoad(Node* node) {
: g.UseRegister(length)
: g.UseRegister(length);
if (length->opcode() == IrOpcode::kInt32Constant) {
Int32Matcher m(length);
if (m.IsPowerOf2()) {
Emit(opcode, g.DefineAsRegister(node), offset_operand,
g.UseImmediate(length), g.UseRegister(buffer));
return;
}
}
Emit(opcode | AddressingModeField::encode(kMode_MRI),
g.DefineAsRegister(node), offset_operand, length_operand,
g.UseRegister(buffer));
......@@ -1906,6 +1915,15 @@ void InstructionSelector::VisitCheckedStore(Node* node) {
: g.UseRegister(length)
: g.UseRegister(length);
if (length->opcode() == IrOpcode::kInt32Constant) {
Int32Matcher m(length);
if (m.IsPowerOf2()) {
Emit(opcode, g.NoOutput(), offset_operand, g.UseImmediate(length),
g.UseRegisterOrImmediateZero(value), g.UseRegister(buffer));
return;
}
}
Emit(opcode | AddressingModeField::encode(kMode_MRI), g.NoOutput(),
offset_operand, length_operand, g.UseRegisterOrImmediateZero(value),
g.UseRegister(buffer));
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment