Index: src/compiler/ppc/instruction-selector-ppc.cc |
diff --git a/src/compiler/ppc/instruction-selector-ppc.cc b/src/compiler/ppc/instruction-selector-ppc.cc |
index d3de14bf55d76c7fec6b9b3e0eaf7a6cfc10a1e5..ba6e2372bb679a76e949bfb64c53196b34fa23f2 100644 |
--- a/src/compiler/ppc/instruction-selector-ppc.cc |
+++ b/src/compiler/ppc/instruction-selector-ppc.cc |
@@ -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 { |