Chromium Code Reviews| 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-intrinsics.h" | 7 #include "src/compiler-intrinsics.h" |
| 8 | 8 |
| 9 namespace v8 { | 9 namespace v8 { |
| 10 namespace internal { | 10 namespace internal { |
| (...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 210 *opcode_return |= AddressingModeField::encode(kMode_Operand2_R_LSR_I); | 210 *opcode_return |= AddressingModeField::encode(kMode_Operand2_R_LSR_I); |
| 211 *shift_return = g.UseImmediate(m.right().node()); | 211 *shift_return = g.UseImmediate(m.right().node()); |
| 212 } else { | 212 } else { |
| 213 *opcode_return |= AddressingModeField::encode(kMode_Operand2_R_LSR_R); | 213 *opcode_return |= AddressingModeField::encode(kMode_Operand2_R_LSR_R); |
| 214 *shift_return = g.UseRegister(m.right().node()); | 214 *shift_return = g.UseRegister(m.right().node()); |
| 215 } | 215 } |
| 216 return true; | 216 return true; |
| 217 } | 217 } |
| 218 | 218 |
| 219 | 219 |
| 220 static inline bool TryMatchShift(InstructionSelector* selector, | |
|
titzer
2014/08/01 11:12:33
s/inline//
| |
| 221 InstructionCode* opcode_return, Node* node, | |
| 222 InstructionOperand** value_return, | |
| 223 InstructionOperand** shift_return) { | |
| 224 return ( | |
| 225 TryMatchASR(selector, opcode_return, node, value_return, shift_return) || | |
| 226 TryMatchLSL(selector, opcode_return, node, value_return, shift_return) || | |
| 227 TryMatchLSR(selector, opcode_return, node, value_return, shift_return) || | |
| 228 TryMatchROR(selector, opcode_return, node, value_return, shift_return)); | |
| 229 } | |
| 230 | |
| 231 | |
| 220 static inline bool TryMatchImmediateOrShift(InstructionSelector* selector, | 232 static inline bool TryMatchImmediateOrShift(InstructionSelector* selector, |
| 221 InstructionCode* opcode_return, | 233 InstructionCode* opcode_return, |
| 222 Node* node, | 234 Node* node, |
| 223 size_t* input_count_return, | 235 size_t* input_count_return, |
| 224 InstructionOperand** inputs) { | 236 InstructionOperand** inputs) { |
| 225 ArmOperandGenerator g(selector); | 237 ArmOperandGenerator g(selector); |
| 226 if (g.CanBeImmediate(node, *opcode_return)) { | 238 if (g.CanBeImmediate(node, *opcode_return)) { |
| 227 *opcode_return |= AddressingModeField::encode(kMode_Operand2_I); | 239 *opcode_return |= AddressingModeField::encode(kMode_Operand2_I); |
| 228 inputs[0] = g.UseImmediate(node); | 240 inputs[0] = g.UseImmediate(node); |
| 229 *input_count_return = 1; | 241 *input_count_return = 1; |
| 230 return true; | 242 return true; |
| 231 } | 243 } |
| 232 if (TryMatchASR(selector, opcode_return, node, &inputs[0], &inputs[1]) || | 244 if (TryMatchShift(selector, opcode_return, node, &inputs[0], &inputs[1])) { |
| 233 TryMatchLSL(selector, opcode_return, node, &inputs[0], &inputs[1]) || | |
| 234 TryMatchLSR(selector, opcode_return, node, &inputs[0], &inputs[1]) || | |
| 235 TryMatchROR(selector, opcode_return, node, &inputs[0], &inputs[1])) { | |
| 236 *input_count_return = 2; | 245 *input_count_return = 2; |
| 237 return true; | 246 return true; |
| 238 } | 247 } |
| 239 return false; | 248 return false; |
| 240 } | 249 } |
| 241 | 250 |
| 242 | 251 |
| 243 // Shared routine for multiple binary operations. | 252 // Shared routine for multiple binary operations. |
| 244 static void VisitBinop(InstructionSelector* selector, Node* node, | 253 static void VisitBinop(InstructionSelector* selector, Node* node, |
| 245 InstructionCode opcode, InstructionCode reverse_opcode) { | 254 InstructionCode opcode, InstructionCode reverse_opcode) { |
| (...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 418 Emit(opcode | AddressingModeField::encode(kMode_Offset_RR), NULL, | 427 Emit(opcode | AddressingModeField::encode(kMode_Offset_RR), NULL, |
| 419 g.UseRegister(base), g.UseRegister(index), val); | 428 g.UseRegister(base), g.UseRegister(index), val); |
| 420 } | 429 } |
| 421 } | 430 } |
| 422 | 431 |
| 423 | 432 |
| 424 static inline void EmitBic(InstructionSelector* selector, Node* node, | 433 static inline void EmitBic(InstructionSelector* selector, Node* node, |
| 425 Node* left, Node* right) { | 434 Node* left, Node* right) { |
| 426 ArmOperandGenerator g(selector); | 435 ArmOperandGenerator g(selector); |
| 427 InstructionCode opcode = kArmBic; | 436 InstructionCode opcode = kArmBic; |
| 428 InstructionOperand* inputs[3]; | 437 InstructionOperand* value_operand; |
| 429 size_t input_count = 0; | 438 InstructionOperand* shift_operand; |
| 430 InstructionOperand* outputs[1] = {g.DefineAsRegister(node)}; | 439 if (TryMatchShift(selector, &opcode, right, &value_operand, &shift_operand)) { |
| 431 const size_t output_count = ARRAY_SIZE(outputs); | 440 selector->Emit(opcode, g.DefineAsRegister(node), g.UseRegister(left), |
| 432 | 441 value_operand, shift_operand); |
| 433 inputs[input_count++] = g.UseRegister(left); | 442 return; |
| 434 if (!TryMatchImmediateOrShift(selector, &opcode, right, &input_count, | |
| 435 &inputs[input_count])) { | |
| 436 opcode |= AddressingModeField::encode(kMode_Operand2_R); | |
| 437 inputs[input_count++] = g.UseRegister(right); | |
| 438 } | 443 } |
| 439 | 444 selector->Emit(opcode | AddressingModeField::encode(kMode_Operand2_R), |
| 440 ASSERT_NE(0, input_count); | 445 g.DefineAsRegister(node), g.UseRegister(left), |
| 441 ASSERT_GE(ARRAY_SIZE(inputs), input_count); | 446 g.UseRegister(right)); |
| 442 ASSERT_NE(kMode_None, AddressingModeField::decode(opcode)); | |
| 443 | |
| 444 selector->Emit(opcode, output_count, outputs, input_count, inputs); | |
| 445 } | 447 } |
| 446 | 448 |
| 447 | 449 |
| 448 void InstructionSelector::VisitWord32And(Node* node) { | 450 void InstructionSelector::VisitWord32And(Node* node) { |
| 449 ArmOperandGenerator g(this); | 451 ArmOperandGenerator g(this); |
| 450 Int32BinopMatcher m(node); | 452 Int32BinopMatcher m(node); |
| 451 if (m.left().IsWord32Xor() && CanCover(node, m.left().node())) { | 453 if (m.left().IsWord32Xor() && CanCover(node, m.left().node())) { |
| 452 Int32BinopMatcher mleft(m.left().node()); | 454 Int32BinopMatcher mleft(m.left().node()); |
| 453 if (mleft.right().Is(-1)) { | 455 if (mleft.right().Is(-1)) { |
| 454 EmitBic(this, node, m.right().node(), mleft.left().node()); | 456 EmitBic(this, node, m.right().node(), mleft.left().node()); |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 505 return; | 507 return; |
| 506 } | 508 } |
| 507 VisitBinop(this, node, kArmOrr, kArmOrr); | 509 VisitBinop(this, node, kArmOrr, kArmOrr); |
| 508 } | 510 } |
| 509 | 511 |
| 510 | 512 |
| 511 void InstructionSelector::VisitWord32Xor(Node* node) { | 513 void InstructionSelector::VisitWord32Xor(Node* node) { |
| 512 ArmOperandGenerator g(this); | 514 ArmOperandGenerator g(this); |
| 513 Int32BinopMatcher m(node); | 515 Int32BinopMatcher m(node); |
| 514 if (m.right().Is(-1)) { | 516 if (m.right().Is(-1)) { |
| 515 Emit(kArmMvn | AddressingModeField::encode(kMode_Operand2_R), | 517 InstructionCode opcode = kArmMvn; |
| 516 g.DefineSameAsFirst(node), g.UseRegister(m.left().node())); | 518 InstructionOperand* value_operand; |
| 517 } else { | 519 InstructionOperand* shift_operand; |
| 518 VisitBinop(this, node, kArmEor, kArmEor); | 520 if (TryMatchShift(this, &opcode, m.left().node(), &value_operand, |
| 521 &shift_operand)) { | |
| 522 Emit(opcode, g.DefineAsRegister(node), value_operand, shift_operand); | |
| 523 return; | |
| 524 } | |
| 525 Emit(opcode | AddressingModeField::encode(kMode_Operand2_R), | |
| 526 g.DefineAsRegister(node), g.UseRegister(m.left().node())); | |
| 527 return; | |
| 519 } | 528 } |
| 529 VisitBinop(this, node, kArmEor, kArmEor); | |
| 520 } | 530 } |
| 521 | 531 |
| 522 | 532 |
| 523 template <typename TryMatchShift> | 533 template <typename TryMatchShift> |
| 524 static inline void VisitShift(InstructionSelector* selector, Node* node, | 534 static inline void VisitShift(InstructionSelector* selector, Node* node, |
| 525 TryMatchShift try_match_shift) { | 535 TryMatchShift try_match_shift) { |
| 526 ArmOperandGenerator g(selector); | 536 ArmOperandGenerator g(selector); |
| 527 InstructionCode opcode = kArmMov; | 537 InstructionCode opcode = kArmMov; |
| 528 InstructionOperand* value_operand = NULL; | 538 InstructionOperand* value_operand = NULL; |
| 529 InstructionOperand* shift_operand = NULL; | 539 InstructionOperand* shift_operand = NULL; |
| (...skipping 417 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 947 ASSERT(cont->IsSet()); | 957 ASSERT(cont->IsSet()); |
| 948 Emit(cont->Encode(kArmVcmpF64), g.DefineAsRegister(cont->result()), | 958 Emit(cont->Encode(kArmVcmpF64), g.DefineAsRegister(cont->result()), |
| 949 g.UseDoubleRegister(m.left().node()), | 959 g.UseDoubleRegister(m.left().node()), |
| 950 g.UseDoubleRegister(m.right().node())); | 960 g.UseDoubleRegister(m.right().node())); |
| 951 } | 961 } |
| 952 } | 962 } |
| 953 | 963 |
| 954 } // namespace compiler | 964 } // namespace compiler |
| 955 } // namespace internal | 965 } // namespace internal |
| 956 } // namespace v8 | 966 } // namespace v8 |
| OLD | NEW |