Index: src/compiler/arm64/instruction-selector-arm64.cc |
diff --git a/src/compiler/arm64/instruction-selector-arm64.cc b/src/compiler/arm64/instruction-selector-arm64.cc |
index 1db8a6b65d07e1c51e81993f1854542d2ebc294d..ed4d600d1d5e9c889344854d05a03be4b71840d6 100644 |
--- a/src/compiler/arm64/instruction-selector-arm64.cc |
+++ b/src/compiler/arm64/instruction-selector-arm64.cc |
@@ -398,10 +398,20 @@ void InstructionSelector::VisitStore(Node* node) { |
// TODO(arm64): 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(index); |
+ // OutOfLineRecordWrite uses the index in an arithmetic instruction, so we |
+ // must check kArithmeticImm as well as kLoadStoreImm64. |
+ if (g.CanBeImmediate(index, kArithmeticImm) && |
+ g.CanBeImmediate(index, kLoadStoreImm64)) { |
+ inputs[input_count++] = g.UseImmediate(index); |
+ addressing_mode = kMode_MRI; |
+ } else { |
+ inputs[input_count++] = g.UseUniqueRegister(index); |
+ addressing_mode = kMode_MRR; |
+ } |
inputs[input_count++] = (write_barrier_kind == kMapWriteBarrier) |
? g.UseRegister(value) |
: g.UseUniqueRegister(value); |
@@ -423,6 +433,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 { |