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 baebb1700d1e23a8ccc7d338067f28554480c4a6..053ae8f53da9183022e246f1bf33c39c7b635df8 100644 |
--- a/src/compiler/arm64/instruction-selector-arm64.cc |
+++ b/src/compiler/arm64/instruction-selector-arm64.cc |
@@ -157,17 +157,34 @@ bool TryMatchAnyShift(InstructionSelector* selector, Node* node, |
} |
-bool TryMatchAnyExtend(InstructionSelector* selector, Node* node, |
- InstructionCode* opcode) { |
- NodeMatcher nm(node); |
+bool TryMatchAnyExtend(Arm64OperandGenerator* g, InstructionSelector* selector, |
+ Node* left_node, Node* right_node, |
+ InstructionOperand* left_op, |
+ InstructionOperand* right_op, InstructionCode* opcode) { |
+ NodeMatcher nm(right_node); |
+ |
if (nm.IsWord32And()) { |
- Int32BinopMatcher m(node); |
- if (m.right().HasValue()) { |
- if (m.right().Value() == 0xff) { |
- *opcode |= AddressingModeField::encode(kMode_Operand2_R_UXTB); |
- return true; |
- } else if (m.right().Value() == 0xffff) { |
- *opcode |= AddressingModeField::encode(kMode_Operand2_R_UXTH); |
+ Int32BinopMatcher mright(right_node); |
+ if (mright.right().Is(0xff) || mright.right().Is(0xffff)) { |
+ int32_t mask = mright.right().Value(); |
+ *left_op = g->UseRegister(left_node); |
+ *right_op = g->UseRegister(mright.left().node()); |
+ *opcode |= AddressingModeField::encode( |
+ (mask == 0xff) ? kMode_Operand2_R_UXTB : kMode_Operand2_R_UXTH); |
+ return true; |
+ } |
+ } else if (nm.IsWord32Sar()) { |
+ Int32BinopMatcher mright(right_node); |
+ if (selector->CanCover(mright.node(), mright.left().node()) && |
+ mright.left().IsWord32Shl()) { |
+ Int32BinopMatcher mleft_of_right(mright.left().node()); |
+ if ((mright.right().Is(16) && mleft_of_right.right().Is(16)) || |
+ (mright.right().Is(24) && mleft_of_right.right().Is(24))) { |
+ int32_t shift = mright.right().Value(); |
+ *left_op = g->UseRegister(left_node); |
+ *right_op = g->UseRegister(mleft_of_right.left().node()); |
+ *opcode |= AddressingModeField::encode( |
+ (shift == 24) ? kMode_Operand2_R_SXTB : kMode_Operand2_R_SXTH); |
return true; |
} |
} |
@@ -193,35 +210,34 @@ void VisitBinop(InstructionSelector* selector, Node* node, |
is_add_sub = true; |
} |
- if (g.CanBeImmediate(m.right().node(), operand_mode)) { |
- inputs[input_count++] = g.UseRegister(m.left().node()); |
- inputs[input_count++] = g.UseImmediate(m.right().node()); |
- } else if (TryMatchAnyShift(selector, m.right().node(), &opcode, |
- !is_add_sub)) { |
- Matcher m_shift(m.right().node()); |
- inputs[input_count++] = g.UseRegister(m.left().node()); |
+ Node* left_node = m.left().node(); |
+ Node* right_node = m.right().node(); |
+ |
+ if (g.CanBeImmediate(right_node, operand_mode)) { |
+ inputs[input_count++] = g.UseRegister(left_node); |
+ inputs[input_count++] = g.UseImmediate(right_node); |
+ } else if (is_add_sub && |
+ TryMatchAnyExtend(&g, selector, left_node, right_node, &inputs[0], |
+ &inputs[1], &opcode)) { |
+ input_count += 2; |
+ } else if (is_add_sub && m.HasProperty(Operator::kCommutative) && |
+ TryMatchAnyExtend(&g, selector, right_node, left_node, &inputs[0], |
+ &inputs[1], &opcode)) { |
+ input_count += 2; |
+ } else if (TryMatchAnyShift(selector, right_node, &opcode, !is_add_sub)) { |
+ Matcher m_shift(right_node); |
+ inputs[input_count++] = g.UseRegister(left_node); |
inputs[input_count++] = g.UseRegister(m_shift.left().node()); |
inputs[input_count++] = g.UseImmediate(m_shift.right().node()); |
} else if (m.HasProperty(Operator::kCommutative) && |
- TryMatchAnyShift(selector, m.left().node(), &opcode, |
- !is_add_sub)) { |
- Matcher m_shift(m.left().node()); |
- inputs[input_count++] = g.UseRegister(m.right().node()); |
+ TryMatchAnyShift(selector, left_node, &opcode, !is_add_sub)) { |
+ Matcher m_shift(left_node); |
+ inputs[input_count++] = g.UseRegister(right_node); |
inputs[input_count++] = g.UseRegister(m_shift.left().node()); |
inputs[input_count++] = g.UseImmediate(m_shift.right().node()); |
- } else if (is_add_sub && |
- TryMatchAnyExtend(selector, m.right().node(), &opcode)) { |
- Matcher mright(m.right().node()); |
- inputs[input_count++] = g.UseRegister(m.left().node()); |
- inputs[input_count++] = g.UseRegister(mright.left().node()); |
- } else if (is_add_sub && m.HasProperty(Operator::kCommutative) && |
- TryMatchAnyExtend(selector, m.left().node(), &opcode)) { |
- Matcher mleft(m.left().node()); |
- inputs[input_count++] = g.UseRegister(m.right().node()); |
- inputs[input_count++] = g.UseRegister(mleft.left().node()); |
} else { |
- inputs[input_count++] = g.UseRegister(m.left().node()); |
- inputs[input_count++] = g.UseRegister(m.right().node()); |
+ inputs[input_count++] = g.UseRegister(left_node); |
+ inputs[input_count++] = g.UseRegister(right_node); |
} |
if (cont->IsBranch()) { |