| OLD | NEW |
| 1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "src/compiler/instruction-selector-impl.h" | 5 #include "src/compiler/instruction-selector-impl.h" |
| 6 #include "src/compiler/node-matchers.h" | 6 #include "src/compiler/node-matchers.h" |
| 7 #include "src/compiler/node-properties.h" | 7 #include "src/compiler/node-properties.h" |
| 8 | 8 |
| 9 namespace v8 { | 9 namespace v8 { |
| 10 namespace internal { | 10 namespace internal { |
| (...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 160 kMode_Operand2_R_LSR_I) || | 160 kMode_Operand2_R_LSR_I) || |
| 161 TryMatchShift<Int64BinopMatcher>(selector, node, opcode, | 161 TryMatchShift<Int64BinopMatcher>(selector, node, opcode, |
| 162 IrOpcode::kWord64Sar, kShift64Imm, | 162 IrOpcode::kWord64Sar, kShift64Imm, |
| 163 kMode_Operand2_R_ASR_I) || | 163 kMode_Operand2_R_ASR_I) || |
| 164 (try_ror && TryMatchShift<Int64BinopMatcher>( | 164 (try_ror && TryMatchShift<Int64BinopMatcher>( |
| 165 selector, node, opcode, IrOpcode::kWord64Ror, | 165 selector, node, opcode, IrOpcode::kWord64Ror, |
| 166 kShift64Imm, kMode_Operand2_R_ROR_I)); | 166 kShift64Imm, kMode_Operand2_R_ROR_I)); |
| 167 } | 167 } |
| 168 | 168 |
| 169 | 169 |
| 170 static bool TryMatchAnyExtend(InstructionSelector* selector, Node* node, |
| 171 InstructionCode* opcode) { |
| 172 NodeMatcher nm(node); |
| 173 if (nm.IsWord32And()) { |
| 174 Int32BinopMatcher m(node); |
| 175 if (m.right().HasValue()) { |
| 176 if (m.right().Value() == 0xff) { |
| 177 *opcode |= AddressingModeField::encode(kMode_Operand2_R_UXTB); |
| 178 return true; |
| 179 } else if (m.right().Value() == 0xffff) { |
| 180 *opcode |= AddressingModeField::encode(kMode_Operand2_R_UXTH); |
| 181 return true; |
| 182 } |
| 183 } |
| 184 } |
| 185 return false; |
| 186 } |
| 187 |
| 188 |
| 170 // Shared routine for multiple binary operations. | 189 // Shared routine for multiple binary operations. |
| 171 template <typename Matcher> | 190 template <typename Matcher> |
| 172 static void VisitBinop(InstructionSelector* selector, Node* node, | 191 static void VisitBinop(InstructionSelector* selector, Node* node, |
| 173 InstructionCode opcode, ImmediateMode operand_mode, | 192 InstructionCode opcode, ImmediateMode operand_mode, |
| 174 FlagsContinuation* cont) { | 193 FlagsContinuation* cont) { |
| 175 Arm64OperandGenerator g(selector); | 194 Arm64OperandGenerator g(selector); |
| 176 Matcher m(node); | 195 Matcher m(node); |
| 177 InstructionOperand inputs[4]; | 196 InstructionOperand inputs[4]; |
| 178 size_t input_count = 0; | 197 size_t input_count = 0; |
| 179 InstructionOperand outputs[2]; | 198 InstructionOperand outputs[2]; |
| 180 size_t output_count = 0; | 199 size_t output_count = 0; |
| 181 bool try_ror_operand = true; | 200 bool is_add_sub = false; |
| 182 | 201 |
| 183 if (m.IsInt32Add() || m.IsInt64Add() || m.IsInt32Sub() || m.IsInt64Sub()) { | 202 if (m.IsInt32Add() || m.IsInt64Add() || m.IsInt32Sub() || m.IsInt64Sub()) { |
| 184 try_ror_operand = false; | 203 is_add_sub = true; |
| 185 } | 204 } |
| 186 | 205 |
| 187 if (g.CanBeImmediate(m.right().node(), operand_mode)) { | 206 if (g.CanBeImmediate(m.right().node(), operand_mode)) { |
| 188 inputs[input_count++] = g.UseRegister(m.left().node()); | 207 inputs[input_count++] = g.UseRegister(m.left().node()); |
| 189 inputs[input_count++] = g.UseImmediate(m.right().node()); | 208 inputs[input_count++] = g.UseImmediate(m.right().node()); |
| 190 } else if (TryMatchAnyShift(selector, m.right().node(), &opcode, | 209 } else if (TryMatchAnyShift(selector, m.right().node(), &opcode, |
| 191 try_ror_operand)) { | 210 !is_add_sub)) { |
| 192 Matcher m_shift(m.right().node()); | 211 Matcher m_shift(m.right().node()); |
| 193 inputs[input_count++] = g.UseRegister(m.left().node()); | 212 inputs[input_count++] = g.UseRegister(m.left().node()); |
| 194 inputs[input_count++] = g.UseRegister(m_shift.left().node()); | 213 inputs[input_count++] = g.UseRegister(m_shift.left().node()); |
| 195 inputs[input_count++] = g.UseImmediate(m_shift.right().node()); | 214 inputs[input_count++] = g.UseImmediate(m_shift.right().node()); |
| 196 } else if (m.HasProperty(Operator::kCommutative) && | 215 } else if (m.HasProperty(Operator::kCommutative) && |
| 197 TryMatchAnyShift(selector, m.left().node(), &opcode, | 216 TryMatchAnyShift(selector, m.left().node(), &opcode, |
| 198 try_ror_operand)) { | 217 !is_add_sub)) { |
| 199 Matcher m_shift(m.left().node()); | 218 Matcher m_shift(m.left().node()); |
| 200 inputs[input_count++] = g.UseRegister(m.right().node()); | 219 inputs[input_count++] = g.UseRegister(m.right().node()); |
| 201 inputs[input_count++] = g.UseRegister(m_shift.left().node()); | 220 inputs[input_count++] = g.UseRegister(m_shift.left().node()); |
| 202 inputs[input_count++] = g.UseImmediate(m_shift.right().node()); | 221 inputs[input_count++] = g.UseImmediate(m_shift.right().node()); |
| 222 } else if (is_add_sub && |
| 223 TryMatchAnyExtend(selector, m.right().node(), &opcode)) { |
| 224 Matcher mright(m.right().node()); |
| 225 inputs[input_count++] = g.UseRegister(m.left().node()); |
| 226 inputs[input_count++] = g.UseRegister(mright.left().node()); |
| 227 } else if (is_add_sub && m.HasProperty(Operator::kCommutative) && |
| 228 TryMatchAnyExtend(selector, m.left().node(), &opcode)) { |
| 229 Matcher mleft(m.left().node()); |
| 230 inputs[input_count++] = g.UseRegister(m.right().node()); |
| 231 inputs[input_count++] = g.UseRegister(mleft.left().node()); |
| 203 } else { | 232 } else { |
| 204 inputs[input_count++] = g.UseRegister(m.left().node()); | 233 inputs[input_count++] = g.UseRegister(m.left().node()); |
| 205 inputs[input_count++] = g.UseRegister(m.right().node()); | 234 inputs[input_count++] = g.UseRegister(m.right().node()); |
| 206 } | 235 } |
| 207 | 236 |
| 208 if (cont->IsBranch()) { | 237 if (cont->IsBranch()) { |
| 209 inputs[input_count++] = g.Label(cont->true_block()); | 238 inputs[input_count++] = g.Label(cont->true_block()); |
| 210 inputs[input_count++] = g.Label(cont->false_block()); | 239 inputs[input_count++] = g.Label(cont->false_block()); |
| 211 } | 240 } |
| 212 | 241 |
| (...skipping 1434 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1647 MachineOperatorBuilder::kFloat64RoundTruncate | | 1676 MachineOperatorBuilder::kFloat64RoundTruncate | |
| 1648 MachineOperatorBuilder::kFloat64RoundTiesAway | | 1677 MachineOperatorBuilder::kFloat64RoundTiesAway | |
| 1649 MachineOperatorBuilder::kWord32ShiftIsSafe | | 1678 MachineOperatorBuilder::kWord32ShiftIsSafe | |
| 1650 MachineOperatorBuilder::kInt32DivIsSafe | | 1679 MachineOperatorBuilder::kInt32DivIsSafe | |
| 1651 MachineOperatorBuilder::kUint32DivIsSafe; | 1680 MachineOperatorBuilder::kUint32DivIsSafe; |
| 1652 } | 1681 } |
| 1653 | 1682 |
| 1654 } // namespace compiler | 1683 } // namespace compiler |
| 1655 } // namespace internal | 1684 } // namespace internal |
| 1656 } // namespace v8 | 1685 } // namespace v8 |
| OLD | NEW |