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 |