| 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 419 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 430 return; | 430 return; |
| 431 } | 431 } |
| 432 } | 432 } |
| 433 if (m.right().IsWord32Xor() && CanCover(node, m.right().node())) { | 433 if (m.right().IsWord32Xor() && CanCover(node, m.right().node())) { |
| 434 Int32BinopMatcher mright(m.right().node()); | 434 Int32BinopMatcher mright(m.right().node()); |
| 435 if (mright.right().Is(-1)) { | 435 if (mright.right().Is(-1)) { |
| 436 EmitBic(this, node, m.left().node(), mright.left().node()); | 436 EmitBic(this, node, m.left().node(), mright.left().node()); |
| 437 return; | 437 return; |
| 438 } | 438 } |
| 439 } | 439 } |
| 440 if (CpuFeatures::IsSupported(ARMv7) && m.right().HasValue()) { | 440 if (IsSupported(ARMv7) && m.right().HasValue()) { |
| 441 uint32_t value = m.right().Value(); | 441 uint32_t value = m.right().Value(); |
| 442 uint32_t width = CompilerIntrinsics::CountSetBits(value); | 442 uint32_t width = CompilerIntrinsics::CountSetBits(value); |
| 443 uint32_t msb = CompilerIntrinsics::CountLeadingZeros(value); | 443 uint32_t msb = CompilerIntrinsics::CountLeadingZeros(value); |
| 444 if (width != 0 && msb + width == 32) { | 444 if (width != 0 && msb + width == 32) { |
| 445 DCHECK_EQ(0, CompilerIntrinsics::CountTrailingZeros(value)); | 445 DCHECK_EQ(0, CompilerIntrinsics::CountTrailingZeros(value)); |
| 446 if (m.left().IsWord32Shr()) { | 446 if (m.left().IsWord32Shr()) { |
| 447 Int32BinopMatcher mleft(m.left().node()); | 447 Int32BinopMatcher mleft(m.left().node()); |
| 448 if (mleft.right().IsInRange(0, 31)) { | 448 if (mleft.right().IsInRange(0, 31)) { |
| 449 Emit(kArmUbfx, g.DefineAsRegister(node), | 449 Emit(kArmUbfx, g.DefineAsRegister(node), |
| 450 g.UseRegister(mleft.left().node()), | 450 g.UseRegister(mleft.left().node()), |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 518 | 518 |
| 519 | 519 |
| 520 void InstructionSelector::VisitWord32Shl(Node* node) { | 520 void InstructionSelector::VisitWord32Shl(Node* node) { |
| 521 VisitShift(this, node, TryMatchLSL); | 521 VisitShift(this, node, TryMatchLSL); |
| 522 } | 522 } |
| 523 | 523 |
| 524 | 524 |
| 525 void InstructionSelector::VisitWord32Shr(Node* node) { | 525 void InstructionSelector::VisitWord32Shr(Node* node) { |
| 526 ArmOperandGenerator g(this); | 526 ArmOperandGenerator g(this); |
| 527 Int32BinopMatcher m(node); | 527 Int32BinopMatcher m(node); |
| 528 if (CpuFeatures::IsSupported(ARMv7) && m.left().IsWord32And() && | 528 if (IsSupported(ARMv7) && m.left().IsWord32And() && |
| 529 m.right().IsInRange(0, 31)) { | 529 m.right().IsInRange(0, 31)) { |
| 530 int32_t lsb = m.right().Value(); | 530 int32_t lsb = m.right().Value(); |
| 531 Int32BinopMatcher mleft(m.left().node()); | 531 Int32BinopMatcher mleft(m.left().node()); |
| 532 if (mleft.right().HasValue()) { | 532 if (mleft.right().HasValue()) { |
| 533 uint32_t value = (mleft.right().Value() >> lsb) << lsb; | 533 uint32_t value = (mleft.right().Value() >> lsb) << lsb; |
| 534 uint32_t width = CompilerIntrinsics::CountSetBits(value); | 534 uint32_t width = CompilerIntrinsics::CountSetBits(value); |
| 535 uint32_t msb = CompilerIntrinsics::CountLeadingZeros(value); | 535 uint32_t msb = CompilerIntrinsics::CountLeadingZeros(value); |
| 536 if (msb + width + lsb == 32) { | 536 if (msb + width + lsb == 32) { |
| 537 DCHECK_EQ(lsb, CompilerIntrinsics::CountTrailingZeros(value)); | 537 DCHECK_EQ(lsb, CompilerIntrinsics::CountTrailingZeros(value)); |
| 538 Emit(kArmUbfx, g.DefineAsRegister(node), | 538 Emit(kArmUbfx, g.DefineAsRegister(node), |
| (...skipping 27 matching lines...) Expand all Loading... |
| 566 g.UseRegister(mright.right().node()), g.UseRegister(m.left().node())); | 566 g.UseRegister(mright.right().node()), g.UseRegister(m.left().node())); |
| 567 return; | 567 return; |
| 568 } | 568 } |
| 569 VisitBinop(this, node, kArmAdd, kArmAdd); | 569 VisitBinop(this, node, kArmAdd, kArmAdd); |
| 570 } | 570 } |
| 571 | 571 |
| 572 | 572 |
| 573 void InstructionSelector::VisitInt32Sub(Node* node) { | 573 void InstructionSelector::VisitInt32Sub(Node* node) { |
| 574 ArmOperandGenerator g(this); | 574 ArmOperandGenerator g(this); |
| 575 Int32BinopMatcher m(node); | 575 Int32BinopMatcher m(node); |
| 576 if (CpuFeatures::IsSupported(MLS) && m.right().IsInt32Mul() && | 576 if (IsSupported(MLS) && m.right().IsInt32Mul() && |
| 577 CanCover(node, m.right().node())) { | 577 CanCover(node, m.right().node())) { |
| 578 Int32BinopMatcher mright(m.right().node()); | 578 Int32BinopMatcher mright(m.right().node()); |
| 579 Emit(kArmMls, g.DefineAsRegister(node), g.UseRegister(mright.left().node()), | 579 Emit(kArmMls, g.DefineAsRegister(node), g.UseRegister(mright.left().node()), |
| 580 g.UseRegister(mright.right().node()), g.UseRegister(m.left().node())); | 580 g.UseRegister(mright.right().node()), g.UseRegister(m.left().node())); |
| 581 return; | 581 return; |
| 582 } | 582 } |
| 583 VisitBinop(this, node, kArmSub, kArmRsb); | 583 VisitBinop(this, node, kArmSub, kArmRsb); |
| 584 } | 584 } |
| 585 | 585 |
| 586 | 586 |
| (...skipping 21 matching lines...) Expand all Loading... |
| 608 g.UseRegister(m.right().node())); | 608 g.UseRegister(m.right().node())); |
| 609 } | 609 } |
| 610 | 610 |
| 611 | 611 |
| 612 static void EmitDiv(InstructionSelector* selector, ArchOpcode div_opcode, | 612 static void EmitDiv(InstructionSelector* selector, ArchOpcode div_opcode, |
| 613 ArchOpcode f64i32_opcode, ArchOpcode i32f64_opcode, | 613 ArchOpcode f64i32_opcode, ArchOpcode i32f64_opcode, |
| 614 InstructionOperand* result_operand, | 614 InstructionOperand* result_operand, |
| 615 InstructionOperand* left_operand, | 615 InstructionOperand* left_operand, |
| 616 InstructionOperand* right_operand) { | 616 InstructionOperand* right_operand) { |
| 617 ArmOperandGenerator g(selector); | 617 ArmOperandGenerator g(selector); |
| 618 if (CpuFeatures::IsSupported(SUDIV)) { | 618 if (selector->IsSupported(SUDIV)) { |
| 619 selector->Emit(div_opcode, result_operand, left_operand, right_operand); | 619 selector->Emit(div_opcode, result_operand, left_operand, right_operand); |
| 620 return; | 620 return; |
| 621 } | 621 } |
| 622 InstructionOperand* left_double_operand = g.TempDoubleRegister(); | 622 InstructionOperand* left_double_operand = g.TempDoubleRegister(); |
| 623 InstructionOperand* right_double_operand = g.TempDoubleRegister(); | 623 InstructionOperand* right_double_operand = g.TempDoubleRegister(); |
| 624 InstructionOperand* result_double_operand = g.TempDoubleRegister(); | 624 InstructionOperand* result_double_operand = g.TempDoubleRegister(); |
| 625 selector->Emit(f64i32_opcode, left_double_operand, left_operand); | 625 selector->Emit(f64i32_opcode, left_double_operand, left_operand); |
| 626 selector->Emit(f64i32_opcode, right_double_operand, right_operand); | 626 selector->Emit(f64i32_opcode, right_double_operand, right_operand); |
| 627 selector->Emit(kArmVdivF64, result_double_operand, left_double_operand, | 627 selector->Emit(kArmVdivF64, result_double_operand, left_double_operand, |
| 628 right_double_operand); | 628 right_double_operand); |
| (...skipping 26 matching lines...) Expand all Loading... |
| 655 ArchOpcode div_opcode, ArchOpcode f64i32_opcode, | 655 ArchOpcode div_opcode, ArchOpcode f64i32_opcode, |
| 656 ArchOpcode i32f64_opcode) { | 656 ArchOpcode i32f64_opcode) { |
| 657 ArmOperandGenerator g(selector); | 657 ArmOperandGenerator g(selector); |
| 658 Int32BinopMatcher m(node); | 658 Int32BinopMatcher m(node); |
| 659 InstructionOperand* div_operand = g.TempRegister(); | 659 InstructionOperand* div_operand = g.TempRegister(); |
| 660 InstructionOperand* result_operand = g.DefineAsRegister(node); | 660 InstructionOperand* result_operand = g.DefineAsRegister(node); |
| 661 InstructionOperand* left_operand = g.UseRegister(m.left().node()); | 661 InstructionOperand* left_operand = g.UseRegister(m.left().node()); |
| 662 InstructionOperand* right_operand = g.UseRegister(m.right().node()); | 662 InstructionOperand* right_operand = g.UseRegister(m.right().node()); |
| 663 EmitDiv(selector, div_opcode, f64i32_opcode, i32f64_opcode, div_operand, | 663 EmitDiv(selector, div_opcode, f64i32_opcode, i32f64_opcode, div_operand, |
| 664 left_operand, right_operand); | 664 left_operand, right_operand); |
| 665 if (CpuFeatures::IsSupported(MLS)) { | 665 if (selector->IsSupported(MLS)) { |
| 666 selector->Emit(kArmMls, result_operand, div_operand, right_operand, | 666 selector->Emit(kArmMls, result_operand, div_operand, right_operand, |
| 667 left_operand); | 667 left_operand); |
| 668 return; | 668 return; |
| 669 } | 669 } |
| 670 InstructionOperand* mul_operand = g.TempRegister(); | 670 InstructionOperand* mul_operand = g.TempRegister(); |
| 671 selector->Emit(kArmMul, mul_operand, div_operand, right_operand); | 671 selector->Emit(kArmMul, mul_operand, div_operand, right_operand); |
| 672 selector->Emit(kArmSub, result_operand, left_operand, mul_operand); | 672 selector->Emit(kArmSub, result_operand, left_operand, mul_operand); |
| 673 } | 673 } |
| 674 | 674 |
| 675 | 675 |
| (...skipping 258 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 934 DCHECK(cont->IsSet()); | 934 DCHECK(cont->IsSet()); |
| 935 Emit(cont->Encode(kArmVcmpF64), g.DefineAsRegister(cont->result()), | 935 Emit(cont->Encode(kArmVcmpF64), g.DefineAsRegister(cont->result()), |
| 936 g.UseDoubleRegister(m.left().node()), | 936 g.UseDoubleRegister(m.left().node()), |
| 937 g.UseDoubleRegister(m.right().node())); | 937 g.UseDoubleRegister(m.right().node())); |
| 938 } | 938 } |
| 939 } | 939 } |
| 940 | 940 |
| 941 } // namespace compiler | 941 } // namespace compiler |
| 942 } // namespace internal | 942 } // namespace internal |
| 943 } // namespace v8 | 943 } // namespace v8 |
| OLD | NEW |