Commit f62ab8d0 authored by Dusan Milosavljevic's avatar Dusan Milosavljevic

MIPS; Improve checked load/store operators for constant offset and length.

TEST=
BUG=
R=balazs.kilvady@imgtec.com, paul.lind@imgtec.com

Review URL: https://codereview.chromium.org/782493002

Cr-Commit-Position: refs/heads/master@{#25664}
parent 0197a15f
......@@ -165,51 +165,77 @@ class OutOfLineLoadInteger FINAL : public OutOfLineCode {
} // 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()); \
#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); \
__ Branch(USE_DELAY_SLOT, ool->entry(), hs, offset, i.InputOperand(1)); \
__ addu(at, i.InputRegister(2), offset); \
__ asm_instr(result, MemOperand(at, 0)); \
} else { \
auto offset = i.InputOperand(0).immediate(); \
__ Branch(ool->entry(), ls, i.InputRegister(1), Operand(offset)); \
__ 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 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()); \
#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); \
__ Branch(USE_DELAY_SLOT, ool->entry(), hs, offset, i.InputOperand(1)); \
__ addu(at, i.InputRegister(2), offset); \
__ asm_instr(result, MemOperand(at, 0)); \
} else { \
auto offset = i.InputOperand(0).immediate(); \
__ Branch(ool->entry(), ls, i.InputRegister(1), Operand(offset)); \
__ asm_instr(result, MemOperand(i.InputRegister(2), offset)); \
} \
__ 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); \
#define ASSEMBLE_CHECKED_STORE_FLOAT(width, asm_instr) \
do { \
Label done; \
if (instr->InputAt(0)->IsRegister()) { \
auto offset = i.InputRegister(0); \
auto value = i.Input##width##Register(2); \
__ Branch(USE_DELAY_SLOT, &done, hs, offset, i.InputOperand(1)); \
__ addu(at, i.InputRegister(3), offset); \
__ asm_instr(value, MemOperand(at, 0)); \
} else { \
auto offset = i.InputOperand(0).immediate(); \
auto value = i.Input##width##Register(2); \
__ Branch(&done, ls, i.InputRegister(1), Operand(offset)); \
__ asm_instr(value, MemOperand(i.InputRegister(3), offset)); \
} \
__ 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); \
#define ASSEMBLE_CHECKED_STORE_INTEGER(asm_instr) \
do { \
Label done; \
if (instr->InputAt(0)->IsRegister()) { \
auto offset = i.InputRegister(0); \
auto value = i.InputRegister(2); \
__ Branch(USE_DELAY_SLOT, &done, hs, offset, i.InputOperand(1)); \
__ addu(at, i.InputRegister(3), offset); \
__ asm_instr(value, MemOperand(at, 0)); \
} else { \
auto offset = i.InputOperand(0).immediate(); \
auto value = i.InputRegister(2); \
__ Branch(&done, ls, i.InputRegister(1), Operand(offset)); \
__ asm_instr(value, MemOperand(i.InputRegister(3), offset)); \
} \
__ bind(&done); \
} while (0)
......
......@@ -42,6 +42,10 @@ class MipsOperandGenerator FINAL : public OperandGenerator {
return is_uint16(value);
case kMipsLdc1:
case kMipsSdc1:
case kCheckedLoadFloat32:
case kCheckedLoadFloat64:
case kCheckedStoreFloat32:
case kCheckedStoreFloat64:
return is_int16(value + kIntSize);
default:
return is_int16(value);
......@@ -513,9 +517,18 @@ void InstructionSelector::VisitCheckedLoad(Node* node) {
UNREACHABLE();
return;
}
InstructionOperand* offset_operand = g.UseRegister(offset);
InstructionOperand* offset_operand = g.CanBeImmediate(offset, opcode)
? g.UseImmediate(offset)
: g.UseRegister(offset);
InstructionOperand* length_operand =
(!g.CanBeImmediate(offset, opcode)) ? g.CanBeImmediate(length, opcode)
? g.UseImmediate(length)
: g.UseRegister(length)
: g.UseRegister(length);
Emit(opcode | AddressingModeField::encode(kMode_MRI),
g.DefineAsRegister(node), offset_operand, g.UseRegister(length),
g.DefineAsRegister(node), offset_operand, length_operand,
g.UseRegister(buffer));
}
......@@ -548,9 +561,18 @@ void InstructionSelector::VisitCheckedStore(Node* node) {
UNREACHABLE();
return;
}
InstructionOperand* offset_operand = g.UseRegister(offset);
InstructionOperand* offset_operand = g.CanBeImmediate(offset, opcode)
? g.UseImmediate(offset)
: g.UseRegister(offset);
InstructionOperand* length_operand =
(!g.CanBeImmediate(offset, opcode)) ? g.CanBeImmediate(length, opcode)
? g.UseImmediate(length)
: g.UseRegister(length)
: g.UseRegister(length);
Emit(opcode | AddressingModeField::encode(kMode_MRI), nullptr, offset_operand,
g.UseRegister(length), g.UseRegister(value), g.UseRegister(buffer));
length_operand, g.UseRegister(value), g.UseRegister(buffer));
}
......
......@@ -166,51 +166,77 @@ class OutOfLineLoadInteger FINAL : public OutOfLineCode {
} // 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))); \
__ Daddu(at, i.InputRegister(2), offset); \
__ asm_instr(result, MemOperand(at, 0)); \
__ bind(ool->exit()); \
#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); \
__ Branch(USE_DELAY_SLOT, ool->entry(), hs, offset, i.InputOperand(1)); \
__ Daddu(at, i.InputRegister(2), offset); \
__ asm_instr(result, MemOperand(at, 0)); \
} else { \
auto offset = i.InputOperand(0).immediate(); \
__ Branch(ool->entry(), ls, i.InputRegister(1), Operand(offset)); \
__ 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 offset = i.InputRegister(0); \
auto ool = new (zone()) OutOfLineLoadInteger(this, result); \
__ Branch(ool->entry(), hs, offset, Operand(i.InputRegister(1))); \
__ Daddu(at, i.InputRegister(2), offset); \
__ asm_instr(result, MemOperand(at, 0)); \
__ bind(ool->exit()); \
#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); \
__ Branch(USE_DELAY_SLOT, ool->entry(), hs, offset, i.InputOperand(1)); \
__ Daddu(at, i.InputRegister(2), offset); \
__ asm_instr(result, MemOperand(at, 0)); \
} else { \
auto offset = i.InputOperand(0).immediate(); \
__ Branch(ool->entry(), ls, i.InputRegister(1), Operand(offset)); \
__ asm_instr(result, MemOperand(i.InputRegister(2), offset)); \
} \
__ 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); \
__ Daddu(at, i.InputRegister(3), offset); \
__ asm_instr(value, MemOperand(at, 0)); \
__ bind(&done); \
#define ASSEMBLE_CHECKED_STORE_FLOAT(width, asm_instr) \
do { \
Label done; \
if (instr->InputAt(0)->IsRegister()) { \
auto offset = i.InputRegister(0); \
auto value = i.Input##width##Register(2); \
__ Branch(USE_DELAY_SLOT, &done, hs, offset, i.InputOperand(1)); \
__ Daddu(at, i.InputRegister(3), offset); \
__ asm_instr(value, MemOperand(at, 0)); \
} else { \
auto offset = i.InputOperand(0).immediate(); \
auto value = i.Input##width##Register(2); \
__ Branch(&done, ls, i.InputRegister(1), Operand(offset)); \
__ asm_instr(value, MemOperand(i.InputRegister(3), offset)); \
} \
__ 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); \
__ Daddu(at, i.InputRegister(3), offset); \
__ asm_instr(value, MemOperand(at, 0)); \
__ 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.InputRegister(2); \
__ Branch(USE_DELAY_SLOT, &done, hs, offset, i.InputOperand(1)); \
__ Daddu(at, i.InputRegister(3), offset); \
__ asm_instr(value, MemOperand(at, 0)); \
} else { \
auto offset = i.InputOperand(0).immediate(); \
auto value = i.InputRegister(2); \
__ Branch(&done, ls, i.InputRegister(1), Operand(offset)); \
__ asm_instr(value, MemOperand(i.InputRegister(3), offset)); \
} \
__ bind(&done); \
} while (0)
......
......@@ -708,9 +708,18 @@ void InstructionSelector::VisitCheckedLoad(Node* node) {
UNREACHABLE();
return;
}
InstructionOperand* offset_operand = g.UseRegister(offset);
InstructionOperand* offset_operand = g.CanBeImmediate(offset, opcode)
? g.UseImmediate(offset)
: g.UseRegister(offset);
InstructionOperand* length_operand =
(!g.CanBeImmediate(offset, opcode)) ? g.CanBeImmediate(length, opcode)
? g.UseImmediate(length)
: g.UseRegister(length)
: g.UseRegister(length);
Emit(opcode | AddressingModeField::encode(kMode_MRI),
g.DefineAsRegister(node), offset_operand, g.UseRegister(length),
g.DefineAsRegister(node), offset_operand, length_operand,
g.UseRegister(buffer));
}
......@@ -743,9 +752,18 @@ void InstructionSelector::VisitCheckedStore(Node* node) {
UNREACHABLE();
return;
}
InstructionOperand* offset_operand = g.UseRegister(offset);
InstructionOperand* offset_operand = g.CanBeImmediate(offset, opcode)
? g.UseImmediate(offset)
: g.UseRegister(offset);
InstructionOperand* length_operand =
(!g.CanBeImmediate(offset, opcode)) ? g.CanBeImmediate(length, opcode)
? g.UseImmediate(length)
: g.UseRegister(length)
: g.UseRegister(length);
Emit(opcode | AddressingModeField::encode(kMode_MRI), nullptr, offset_operand,
g.UseRegister(length), g.UseRegister(value), g.UseRegister(buffer));
length_operand, g.UseRegister(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