Commit 5ca122a1 authored by mbrandy's avatar mbrandy Committed by Commit bot

PPC: Support immediate indices for StoreWriteBarrier.

Port 4eff883b
     c72b49bd

Original commit message:
    Ideally we would not need the StoreWriteBarrier instructions at all,
    but represent the RecordWrite functionality as machine subgraph, but
    that'll take some time to get there. In the mean time we can have a
    shorter instruction sequence by recognizing immediate indices here.

R=bmeurer@chromium.org, joransiu@ca.ibm.com, jyan@ca.ibm.com, michael_dawson@ca.ibm.com
BUG=

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

Cr-Commit-Position: refs/heads/master@{#34006}
parent ea08453c
......@@ -167,6 +167,19 @@ class OutOfLineRecordWrite final : public OutOfLineCode {
: OutOfLineCode(gen),
object_(object),
offset_(offset),
offset_immediate_(0),
value_(value),
scratch0_(scratch0),
scratch1_(scratch1),
mode_(mode) {}
OutOfLineRecordWrite(CodeGenerator* gen, Register object, int32_t offset,
Register value, Register scratch0, Register scratch1,
RecordWriteMode mode)
: OutOfLineCode(gen),
object_(object),
offset_(no_reg),
offset_immediate_(offset),
value_(value),
scratch0_(scratch0),
scratch1_(scratch1),
......@@ -187,13 +200,19 @@ class OutOfLineRecordWrite final : public OutOfLineCode {
// and restore lr properly here if the frame was elided.
RecordWriteStub stub(isolate(), object_, scratch0_, scratch1_,
EMIT_REMEMBERED_SET, save_fp_mode);
__ add(scratch1_, object_, offset_);
if (offset_.is(no_reg)) {
__ addi(scratch1_, object_, Operand(offset_immediate_));
} else {
DCHECK_EQ(0, offset_immediate_);
__ add(scratch1_, object_, offset_);
}
__ CallStub(&stub);
}
private:
Register const object_;
Register const offset_;
int32_t const offset_immediate_; // Valid if offset_.is(no_reg).
Register const value_;
Register const scratch0_;
Register const scratch1_;
......@@ -810,13 +829,25 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
RecordWriteMode mode =
static_cast<RecordWriteMode>(MiscField::decode(instr->opcode()));
Register object = i.InputRegister(0);
Register offset = i.InputRegister(1);
Register value = i.InputRegister(2);
Register scratch0 = i.TempRegister(0);
Register scratch1 = i.TempRegister(1);
auto ool = new (zone()) OutOfLineRecordWrite(this, object, offset, value,
scratch0, scratch1, mode);
__ StorePX(value, MemOperand(object, offset));
OutOfLineRecordWrite* ool;
AddressingMode addressing_mode =
AddressingModeField::decode(instr->opcode());
if (addressing_mode == kMode_MRI) {
int32_t offset = i.InputInt32(1);
ool = new (zone()) OutOfLineRecordWrite(this, object, offset, value,
scratch0, scratch1, mode);
__ StoreP(value, MemOperand(object, offset));
} else {
DCHECK_EQ(kMode_MRR, addressing_mode);
Register offset(i.InputRegister(1));
ool = new (zone()) OutOfLineRecordWrite(this, object, offset, value,
scratch0, scratch1, mode);
__ StorePX(value, MemOperand(object, offset));
}
__ CheckPageFlag(object, scratch0,
MemoryChunk::kPointersFromHereAreInterestingMask, ne,
ool->entry());
......
......@@ -227,13 +227,25 @@ void InstructionSelector::VisitStore(Node* node) {
WriteBarrierKind write_barrier_kind = store_rep.write_barrier_kind();
MachineRepresentation rep = store_rep.representation();
// TODO(ppc): I guess this could be done in a better way.
if (write_barrier_kind != kNoWriteBarrier) {
DCHECK_EQ(MachineRepresentation::kTagged, rep);
AddressingMode addressing_mode;
InstructionOperand inputs[3];
size_t input_count = 0;
inputs[input_count++] = g.UseUniqueRegister(base);
inputs[input_count++] = g.UseUniqueRegister(offset);
// OutOfLineRecordWrite uses the offset in an 'add' instruction as well as
// for the store itself, so we must check compatibility with both.
if (g.CanBeImmediate(offset, kInt16Imm)
#if V8_TARGET_ARCH_PPC64
&& g.CanBeImmediate(offset, kInt16Imm_4ByteAligned)
#endif
) {
inputs[input_count++] = g.UseImmediate(offset);
addressing_mode = kMode_MRI;
} else {
inputs[input_count++] = g.UseUniqueRegister(offset);
addressing_mode = kMode_MRR;
}
inputs[input_count++] = (write_barrier_kind == kMapWriteBarrier)
? g.UseRegister(value)
: g.UseUniqueRegister(value);
......@@ -255,6 +267,7 @@ void InstructionSelector::VisitStore(Node* node) {
InstructionOperand temps[] = {g.TempRegister(), g.TempRegister()};
size_t const temp_count = arraysize(temps);
InstructionCode code = kArchStoreWithWriteBarrier;
code |= AddressingModeField::encode(addressing_mode);
code |= MiscField::encode(static_cast<int>(record_write_mode));
Emit(code, 0, nullptr, input_count, inputs, temp_count, temps);
} else {
......
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