| Index: src/compiler/arm/instruction-selector-arm.cc
|
| diff --git a/src/compiler/arm/instruction-selector-arm.cc b/src/compiler/arm/instruction-selector-arm.cc
|
| index b2b1a7049d1e5bb2fc7237f3316dd648d5260352..351d21147771e29fd644a5908deee44a29bdae0f 100644
|
| --- a/src/compiler/arm/instruction-selector-arm.cc
|
| +++ b/src/compiler/arm/instruction-selector-arm.cc
|
| @@ -115,6 +115,24 @@ bool TryMatchShift(InstructionSelector* selector,
|
| return false;
|
| }
|
|
|
| +template <IrOpcode::Value kOpcode, int kImmMin, int kImmMax,
|
| + AddressingMode kImmMode>
|
| +bool TryMatchShiftImmediate(InstructionSelector* selector,
|
| + InstructionCode* opcode_return, Node* node,
|
| + InstructionOperand* value_return,
|
| + InstructionOperand* shift_return) {
|
| + ArmOperandGenerator g(selector);
|
| + if (node->opcode() == kOpcode) {
|
| + Int32BinopMatcher m(node);
|
| + if (m.right().IsInRange(kImmMin, kImmMax)) {
|
| + *opcode_return |= AddressingModeField::encode(kImmMode);
|
| + *value_return = g.UseRegister(m.left().node());
|
| + *shift_return = g.UseImmediate(m.right().node());
|
| + return true;
|
| + }
|
| + }
|
| + return false;
|
| +}
|
|
|
| bool TryMatchROR(InstructionSelector* selector, InstructionCode* opcode_return,
|
| Node* node, InstructionOperand* value_return,
|
| @@ -142,6 +160,14 @@ bool TryMatchLSL(InstructionSelector* selector, InstructionCode* opcode_return,
|
| value_return, shift_return);
|
| }
|
|
|
| +bool TryMatchLSLImmediate(InstructionSelector* selector,
|
| + InstructionCode* opcode_return, Node* node,
|
| + InstructionOperand* value_return,
|
| + InstructionOperand* shift_return) {
|
| + return TryMatchShiftImmediate<IrOpcode::kWord32Shl, 0, 31,
|
| + kMode_Operand2_R_LSL_I>(
|
| + selector, opcode_return, node, value_return, shift_return);
|
| +}
|
|
|
| bool TryMatchLSR(InstructionSelector* selector, InstructionCode* opcode_return,
|
| Node* node, InstructionOperand* value_return,
|
| @@ -312,8 +338,11 @@ void InstructionSelector::VisitLoad(Node* node) {
|
| ArmOperandGenerator g(this);
|
| Node* base = node->InputAt(0);
|
| Node* index = node->InputAt(1);
|
| + InstructionOperand inputs[3];
|
| + size_t input_count = 0;
|
| + InstructionOperand outputs[1];
|
|
|
| - ArchOpcode opcode = kArchNop;
|
| + InstructionCode opcode = kArchNop;
|
| switch (load_rep.representation()) {
|
| case MachineRepresentation::kFloat32:
|
| opcode = kArmVldrF32;
|
| @@ -339,13 +368,24 @@ void InstructionSelector::VisitLoad(Node* node) {
|
| return;
|
| }
|
|
|
| + outputs[0] = g.DefineAsRegister(node);
|
| + inputs[0] = g.UseRegister(base);
|
| +
|
| if (g.CanBeImmediate(index, opcode)) {
|
| - Emit(opcode | AddressingModeField::encode(kMode_Offset_RI),
|
| - g.DefineAsRegister(node), g.UseRegister(base), g.UseImmediate(index));
|
| + input_count = 2;
|
| + inputs[1] = g.UseImmediate(index);
|
| + opcode |= AddressingModeField::encode(kMode_Offset_RI);
|
| + } else if ((opcode == kArmLdr) &&
|
| + TryMatchLSLImmediate(this, &opcode, index, &inputs[1],
|
| + &inputs[2])) {
|
| + input_count = 3;
|
| } else {
|
| - Emit(opcode | AddressingModeField::encode(kMode_Offset_RR),
|
| - g.DefineAsRegister(node), g.UseRegister(base), g.UseRegister(index));
|
| + input_count = 2;
|
| + inputs[1] = g.UseRegister(index);
|
| + opcode |= AddressingModeField::encode(kMode_Offset_RR);
|
| }
|
| +
|
| + Emit(opcode, arraysize(outputs), outputs, input_count, inputs);
|
| }
|
|
|
|
|
| @@ -397,7 +437,10 @@ void InstructionSelector::VisitStore(Node* node) {
|
| code |= MiscField::encode(static_cast<int>(record_write_mode));
|
| Emit(code, 0, nullptr, input_count, inputs, temp_count, temps);
|
| } else {
|
| - ArchOpcode opcode = kArchNop;
|
| + InstructionOperand inputs[4];
|
| + size_t input_count = 0;
|
| +
|
| + InstructionCode opcode = kArchNop;
|
| switch (rep) {
|
| case MachineRepresentation::kFloat32:
|
| opcode = kArmVstrF32;
|
| @@ -423,13 +466,23 @@ void InstructionSelector::VisitStore(Node* node) {
|
| return;
|
| }
|
|
|
| + inputs[0] = g.UseRegister(value);
|
| + inputs[1] = g.UseRegister(base);
|
| +
|
| if (g.CanBeImmediate(index, opcode)) {
|
| - Emit(opcode | AddressingModeField::encode(kMode_Offset_RI), g.NoOutput(),
|
| - g.UseRegister(base), g.UseImmediate(index), g.UseRegister(value));
|
| + input_count = 3;
|
| + inputs[2] = g.UseImmediate(index);
|
| + opcode |= AddressingModeField::encode(kMode_Offset_RI);
|
| + } else if ((opcode == kArmStr) &&
|
| + TryMatchLSLImmediate(this, &opcode, index, &inputs[2],
|
| + &inputs[3])) {
|
| + input_count = 4;
|
| } else {
|
| - Emit(opcode | AddressingModeField::encode(kMode_Offset_RR), g.NoOutput(),
|
| - g.UseRegister(base), g.UseRegister(index), g.UseRegister(value));
|
| + input_count = 3;
|
| + inputs[2] = g.UseRegister(index);
|
| + opcode |= AddressingModeField::encode(kMode_Offset_RR);
|
| }
|
| + Emit(opcode, 0, nullptr, input_count, inputs);
|
| }
|
| }
|
|
|
|
|