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 "test/unittests/compiler/instruction-selector-unittest.h" | 5 #include "test/unittests/compiler/instruction-selector-unittest.h" |
6 | 6 |
7 namespace v8 { | 7 namespace v8 { |
8 namespace internal { | 8 namespace internal { |
9 namespace compiler { | 9 namespace compiler { |
10 | 10 |
(...skipping 631 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
642 } | 642 } |
643 | 643 |
644 | 644 |
645 INSTANTIATE_TEST_CASE_P(InstructionSelectorTest, | 645 INSTANTIATE_TEST_CASE_P(InstructionSelectorTest, |
646 InstructionSelectorDPFlagSetTest, | 646 InstructionSelectorDPFlagSetTest, |
647 ::testing::ValuesIn(kDPFlagSetInstructions)); | 647 ::testing::ValuesIn(kDPFlagSetInstructions)); |
648 | 648 |
649 | 649 |
650 TEST_F(InstructionSelectorTest, Word32AndBranchWithImmediateOnRight) { | 650 TEST_F(InstructionSelectorTest, Word32AndBranchWithImmediateOnRight) { |
651 TRACED_FOREACH(int32_t, imm, kLogical32Immediates) { | 651 TRACED_FOREACH(int32_t, imm, kLogical32Immediates) { |
| 652 // Skip the cases where the instruction selector would use tbz/tbnz. |
| 653 if (base::bits::CountPopulation32(imm) == 1) continue; |
| 654 |
652 StreamBuilder m(this, kMachInt32, kMachInt32); | 655 StreamBuilder m(this, kMachInt32, kMachInt32); |
653 MLabel a, b; | 656 MLabel a, b; |
654 m.Branch(m.Word32And(m.Parameter(0), m.Int32Constant(imm)), &a, &b); | 657 m.Branch(m.Word32And(m.Parameter(0), m.Int32Constant(imm)), &a, &b); |
655 m.Bind(&a); | 658 m.Bind(&a); |
656 m.Return(m.Int32Constant(1)); | 659 m.Return(m.Int32Constant(1)); |
657 m.Bind(&b); | 660 m.Bind(&b); |
658 m.Return(m.Int32Constant(0)); | 661 m.Return(m.Int32Constant(0)); |
659 Stream s = m.Build(); | 662 Stream s = m.Build(); |
660 ASSERT_EQ(1U, s.size()); | 663 ASSERT_EQ(1U, s.size()); |
661 EXPECT_EQ(kArm64Tst32, s[0]->arch_opcode()); | 664 EXPECT_EQ(kArm64Tst32, s[0]->arch_opcode()); |
662 EXPECT_EQ(4U, s[0]->InputCount()); | 665 EXPECT_EQ(4U, s[0]->InputCount()); |
663 EXPECT_EQ(InstructionOperand::IMMEDIATE, s[0]->InputAt(1)->kind()); | 666 EXPECT_EQ(InstructionOperand::IMMEDIATE, s[0]->InputAt(1)->kind()); |
664 EXPECT_EQ(kFlags_branch, s[0]->flags_mode()); | 667 EXPECT_EQ(kFlags_branch, s[0]->flags_mode()); |
665 EXPECT_EQ(kNotEqual, s[0]->flags_condition()); | 668 EXPECT_EQ(kNotEqual, s[0]->flags_condition()); |
666 } | 669 } |
667 } | 670 } |
668 | 671 |
669 | 672 |
670 TEST_F(InstructionSelectorTest, Word64AndBranchWithImmediateOnRight) { | 673 TEST_F(InstructionSelectorTest, Word64AndBranchWithImmediateOnRight) { |
671 TRACED_FOREACH(int64_t, imm, kLogical64Immediates) { | 674 TRACED_FOREACH(int64_t, imm, kLogical64Immediates) { |
| 675 // Skip the cases where the instruction selector would use tbz/tbnz. |
| 676 if (base::bits::CountPopulation64(imm) == 1) continue; |
| 677 |
672 StreamBuilder m(this, kMachInt64, kMachInt64); | 678 StreamBuilder m(this, kMachInt64, kMachInt64); |
673 MLabel a, b; | 679 MLabel a, b; |
674 m.Branch(m.Word64And(m.Parameter(0), m.Int64Constant(imm)), &a, &b); | 680 m.Branch(m.Word64And(m.Parameter(0), m.Int64Constant(imm)), &a, &b); |
675 m.Bind(&a); | 681 m.Bind(&a); |
676 m.Return(m.Int32Constant(1)); | 682 m.Return(m.Int32Constant(1)); |
677 m.Bind(&b); | 683 m.Bind(&b); |
678 m.Return(m.Int32Constant(0)); | 684 m.Return(m.Int32Constant(0)); |
679 Stream s = m.Build(); | 685 Stream s = m.Build(); |
680 ASSERT_EQ(1U, s.size()); | 686 ASSERT_EQ(1U, s.size()); |
681 EXPECT_EQ(kArm64Tst, s[0]->arch_opcode()); | 687 EXPECT_EQ(kArm64Tst, s[0]->arch_opcode()); |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
718 ASSERT_EQ(1U, s.size()); | 724 ASSERT_EQ(1U, s.size()); |
719 EXPECT_EQ(kArm64Cmp32, s[0]->arch_opcode()); | 725 EXPECT_EQ(kArm64Cmp32, s[0]->arch_opcode()); |
720 EXPECT_EQ(kFlags_branch, s[0]->flags_mode()); | 726 EXPECT_EQ(kFlags_branch, s[0]->flags_mode()); |
721 EXPECT_EQ(kNotEqual, s[0]->flags_condition()); | 727 EXPECT_EQ(kNotEqual, s[0]->flags_condition()); |
722 } | 728 } |
723 } | 729 } |
724 | 730 |
725 | 731 |
726 TEST_F(InstructionSelectorTest, Word32AndBranchWithImmediateOnLeft) { | 732 TEST_F(InstructionSelectorTest, Word32AndBranchWithImmediateOnLeft) { |
727 TRACED_FOREACH(int32_t, imm, kLogical32Immediates) { | 733 TRACED_FOREACH(int32_t, imm, kLogical32Immediates) { |
| 734 // Skip the cases where the instruction selector would use tbz/tbnz. |
| 735 if (base::bits::CountPopulation32(imm) == 1) continue; |
| 736 |
728 StreamBuilder m(this, kMachInt32, kMachInt32); | 737 StreamBuilder m(this, kMachInt32, kMachInt32); |
729 MLabel a, b; | 738 MLabel a, b; |
730 m.Branch(m.Word32And(m.Int32Constant(imm), m.Parameter(0)), &a, &b); | 739 m.Branch(m.Word32And(m.Int32Constant(imm), m.Parameter(0)), &a, &b); |
731 m.Bind(&a); | 740 m.Bind(&a); |
732 m.Return(m.Int32Constant(1)); | 741 m.Return(m.Int32Constant(1)); |
733 m.Bind(&b); | 742 m.Bind(&b); |
734 m.Return(m.Int32Constant(0)); | 743 m.Return(m.Int32Constant(0)); |
735 Stream s = m.Build(); | 744 Stream s = m.Build(); |
736 ASSERT_EQ(1U, s.size()); | 745 ASSERT_EQ(1U, s.size()); |
737 EXPECT_EQ(kArm64Tst32, s[0]->arch_opcode()); | 746 EXPECT_EQ(kArm64Tst32, s[0]->arch_opcode()); |
738 EXPECT_EQ(4U, s[0]->InputCount()); | 747 EXPECT_EQ(4U, s[0]->InputCount()); |
739 EXPECT_EQ(InstructionOperand::IMMEDIATE, s[0]->InputAt(1)->kind()); | 748 EXPECT_EQ(InstructionOperand::IMMEDIATE, s[0]->InputAt(1)->kind()); |
740 ASSERT_LE(1U, s[0]->InputCount()); | 749 ASSERT_LE(1U, s[0]->InputCount()); |
741 EXPECT_EQ(kFlags_branch, s[0]->flags_mode()); | 750 EXPECT_EQ(kFlags_branch, s[0]->flags_mode()); |
742 EXPECT_EQ(kNotEqual, s[0]->flags_condition()); | 751 EXPECT_EQ(kNotEqual, s[0]->flags_condition()); |
743 } | 752 } |
744 } | 753 } |
745 | 754 |
746 | 755 |
747 TEST_F(InstructionSelectorTest, Word64AndBranchWithImmediateOnLeft) { | 756 TEST_F(InstructionSelectorTest, Word64AndBranchWithImmediateOnLeft) { |
748 TRACED_FOREACH(int64_t, imm, kLogical64Immediates) { | 757 TRACED_FOREACH(int64_t, imm, kLogical64Immediates) { |
| 758 // Skip the cases where the instruction selector would use tbz/tbnz. |
| 759 if (base::bits::CountPopulation64(imm) == 1) continue; |
| 760 |
749 StreamBuilder m(this, kMachInt64, kMachInt64); | 761 StreamBuilder m(this, kMachInt64, kMachInt64); |
750 MLabel a, b; | 762 MLabel a, b; |
751 m.Branch(m.Word64And(m.Int64Constant(imm), m.Parameter(0)), &a, &b); | 763 m.Branch(m.Word64And(m.Int64Constant(imm), m.Parameter(0)), &a, &b); |
752 m.Bind(&a); | 764 m.Bind(&a); |
753 m.Return(m.Int32Constant(1)); | 765 m.Return(m.Int32Constant(1)); |
754 m.Bind(&b); | 766 m.Bind(&b); |
755 m.Return(m.Int32Constant(0)); | 767 m.Return(m.Int32Constant(0)); |
756 Stream s = m.Build(); | 768 Stream s = m.Build(); |
757 ASSERT_EQ(1U, s.size()); | 769 ASSERT_EQ(1U, s.size()); |
758 EXPECT_EQ(kArm64Tst, s[0]->arch_opcode()); | 770 EXPECT_EQ(kArm64Tst, s[0]->arch_opcode()); |
(...skipping 18 matching lines...) Expand all Loading... |
777 Stream s = m.Build(); | 789 Stream s = m.Build(); |
778 ASSERT_EQ(1U, s.size()); | 790 ASSERT_EQ(1U, s.size()); |
779 EXPECT_EQ(kArm64Cmn32, s[0]->arch_opcode()); | 791 EXPECT_EQ(kArm64Cmn32, s[0]->arch_opcode()); |
780 ASSERT_LE(1U, s[0]->InputCount()); | 792 ASSERT_LE(1U, s[0]->InputCount()); |
781 EXPECT_EQ(kFlags_branch, s[0]->flags_mode()); | 793 EXPECT_EQ(kFlags_branch, s[0]->flags_mode()); |
782 EXPECT_EQ(kNotEqual, s[0]->flags_condition()); | 794 EXPECT_EQ(kNotEqual, s[0]->flags_condition()); |
783 } | 795 } |
784 } | 796 } |
785 | 797 |
786 | 798 |
| 799 TEST_F(InstructionSelectorTest, Word32AndBranchWithOneBitMaskOnRight) { |
| 800 TRACED_FORRANGE(int, bit, 0, 31) { |
| 801 uint32_t mask = 1 << bit; |
| 802 StreamBuilder m(this, kMachInt32, kMachInt32); |
| 803 MLabel a, b; |
| 804 m.Branch(m.Word32And(m.Parameter(0), m.Int32Constant(mask)), &a, &b); |
| 805 m.Bind(&a); |
| 806 m.Return(m.Int32Constant(1)); |
| 807 m.Bind(&b); |
| 808 m.Return(m.Int32Constant(0)); |
| 809 Stream s = m.Build(); |
| 810 ASSERT_EQ(1U, s.size()); |
| 811 EXPECT_EQ(kArm64Tbnz32, s[0]->arch_opcode()); |
| 812 EXPECT_EQ(4U, s[0]->InputCount()); |
| 813 EXPECT_EQ(InstructionOperand::IMMEDIATE, s[0]->InputAt(1)->kind()); |
| 814 EXPECT_EQ(bit, s.ToInt32(s[0]->InputAt(1))); |
| 815 } |
| 816 |
| 817 TRACED_FORRANGE(int, bit, 0, 31) { |
| 818 uint32_t mask = 1 << bit; |
| 819 StreamBuilder m(this, kMachInt32, kMachInt32); |
| 820 MLabel a, b; |
| 821 m.Branch( |
| 822 m.Word32BinaryNot(m.Word32And(m.Parameter(0), m.Int32Constant(mask))), |
| 823 &a, &b); |
| 824 m.Bind(&a); |
| 825 m.Return(m.Int32Constant(1)); |
| 826 m.Bind(&b); |
| 827 m.Return(m.Int32Constant(0)); |
| 828 Stream s = m.Build(); |
| 829 ASSERT_EQ(1U, s.size()); |
| 830 EXPECT_EQ(kArm64Tbz32, s[0]->arch_opcode()); |
| 831 EXPECT_EQ(4U, s[0]->InputCount()); |
| 832 EXPECT_EQ(InstructionOperand::IMMEDIATE, s[0]->InputAt(1)->kind()); |
| 833 EXPECT_EQ(bit, s.ToInt32(s[0]->InputAt(1))); |
| 834 } |
| 835 } |
| 836 |
| 837 |
| 838 TEST_F(InstructionSelectorTest, Word32AndBranchWithOneBitMaskOnLeft) { |
| 839 TRACED_FORRANGE(int, bit, 0, 31) { |
| 840 uint32_t mask = 1 << bit; |
| 841 StreamBuilder m(this, kMachInt32, kMachInt32); |
| 842 MLabel a, b; |
| 843 m.Branch(m.Word32And(m.Int32Constant(mask), m.Parameter(0)), &a, &b); |
| 844 m.Bind(&a); |
| 845 m.Return(m.Int32Constant(1)); |
| 846 m.Bind(&b); |
| 847 m.Return(m.Int32Constant(0)); |
| 848 Stream s = m.Build(); |
| 849 ASSERT_EQ(1U, s.size()); |
| 850 EXPECT_EQ(kArm64Tbnz32, s[0]->arch_opcode()); |
| 851 EXPECT_EQ(4U, s[0]->InputCount()); |
| 852 EXPECT_EQ(InstructionOperand::IMMEDIATE, s[0]->InputAt(1)->kind()); |
| 853 EXPECT_EQ(bit, s.ToInt32(s[0]->InputAt(1))); |
| 854 } |
| 855 |
| 856 TRACED_FORRANGE(int, bit, 0, 31) { |
| 857 uint32_t mask = 1 << bit; |
| 858 StreamBuilder m(this, kMachInt32, kMachInt32); |
| 859 MLabel a, b; |
| 860 m.Branch( |
| 861 m.Word32BinaryNot(m.Word32And(m.Int32Constant(mask), m.Parameter(0))), |
| 862 &a, &b); |
| 863 m.Bind(&a); |
| 864 m.Return(m.Int32Constant(1)); |
| 865 m.Bind(&b); |
| 866 m.Return(m.Int32Constant(0)); |
| 867 Stream s = m.Build(); |
| 868 ASSERT_EQ(1U, s.size()); |
| 869 EXPECT_EQ(kArm64Tbz32, s[0]->arch_opcode()); |
| 870 EXPECT_EQ(4U, s[0]->InputCount()); |
| 871 EXPECT_EQ(InstructionOperand::IMMEDIATE, s[0]->InputAt(1)->kind()); |
| 872 EXPECT_EQ(bit, s.ToInt32(s[0]->InputAt(1))); |
| 873 } |
| 874 } |
| 875 |
| 876 |
| 877 TEST_F(InstructionSelectorTest, Word64AndBranchWithOneBitMaskOnRight) { |
| 878 TRACED_FORRANGE(int, bit, 0, 63) { |
| 879 uint64_t mask = 1L << bit; |
| 880 StreamBuilder m(this, kMachInt64, kMachInt64); |
| 881 MLabel a, b; |
| 882 m.Branch(m.Word64And(m.Parameter(0), m.Int64Constant(mask)), &a, &b); |
| 883 m.Bind(&a); |
| 884 m.Return(m.Int32Constant(1)); |
| 885 m.Bind(&b); |
| 886 m.Return(m.Int32Constant(0)); |
| 887 Stream s = m.Build(); |
| 888 ASSERT_EQ(1U, s.size()); |
| 889 EXPECT_EQ(kArm64Tbnz, s[0]->arch_opcode()); |
| 890 EXPECT_EQ(4U, s[0]->InputCount()); |
| 891 EXPECT_EQ(InstructionOperand::IMMEDIATE, s[0]->InputAt(1)->kind()); |
| 892 EXPECT_EQ(bit, s.ToInt64(s[0]->InputAt(1))); |
| 893 } |
| 894 |
| 895 TRACED_FORRANGE(int, bit, 0, 63) { |
| 896 uint64_t mask = 1L << bit; |
| 897 StreamBuilder m(this, kMachInt64, kMachInt64); |
| 898 MLabel a, b; |
| 899 m.Branch( |
| 900 m.Word64BinaryNot(m.Word64And(m.Parameter(0), m.Int64Constant(mask))), |
| 901 &a, &b); |
| 902 m.Bind(&a); |
| 903 m.Return(m.Int32Constant(1)); |
| 904 m.Bind(&b); |
| 905 m.Return(m.Int32Constant(0)); |
| 906 Stream s = m.Build(); |
| 907 ASSERT_EQ(1U, s.size()); |
| 908 EXPECT_EQ(kArm64Tbz, s[0]->arch_opcode()); |
| 909 EXPECT_EQ(4U, s[0]->InputCount()); |
| 910 EXPECT_EQ(InstructionOperand::IMMEDIATE, s[0]->InputAt(1)->kind()); |
| 911 EXPECT_EQ(bit, s.ToInt64(s[0]->InputAt(1))); |
| 912 } |
| 913 } |
| 914 |
| 915 |
| 916 TEST_F(InstructionSelectorTest, Word64AndBranchWithOneBitMaskOnLeft) { |
| 917 TRACED_FORRANGE(int, bit, 0, 63) { |
| 918 uint64_t mask = 1L << bit; |
| 919 StreamBuilder m(this, kMachInt64, kMachInt64); |
| 920 MLabel a, b; |
| 921 m.Branch(m.Word64And(m.Int64Constant(mask), m.Parameter(0)), &a, &b); |
| 922 m.Bind(&a); |
| 923 m.Return(m.Int32Constant(1)); |
| 924 m.Bind(&b); |
| 925 m.Return(m.Int32Constant(0)); |
| 926 Stream s = m.Build(); |
| 927 ASSERT_EQ(1U, s.size()); |
| 928 EXPECT_EQ(kArm64Tbnz, s[0]->arch_opcode()); |
| 929 EXPECT_EQ(4U, s[0]->InputCount()); |
| 930 EXPECT_EQ(InstructionOperand::IMMEDIATE, s[0]->InputAt(1)->kind()); |
| 931 EXPECT_EQ(bit, s.ToInt64(s[0]->InputAt(1))); |
| 932 } |
| 933 |
| 934 TRACED_FORRANGE(int, bit, 0, 63) { |
| 935 uint64_t mask = 1L << bit; |
| 936 StreamBuilder m(this, kMachInt64, kMachInt64); |
| 937 MLabel a, b; |
| 938 m.Branch( |
| 939 m.Word64BinaryNot(m.Word64And(m.Int64Constant(mask), m.Parameter(0))), |
| 940 &a, &b); |
| 941 m.Bind(&a); |
| 942 m.Return(m.Int32Constant(1)); |
| 943 m.Bind(&b); |
| 944 m.Return(m.Int32Constant(0)); |
| 945 Stream s = m.Build(); |
| 946 ASSERT_EQ(1U, s.size()); |
| 947 EXPECT_EQ(kArm64Tbz, s[0]->arch_opcode()); |
| 948 EXPECT_EQ(4U, s[0]->InputCount()); |
| 949 EXPECT_EQ(InstructionOperand::IMMEDIATE, s[0]->InputAt(1)->kind()); |
| 950 EXPECT_EQ(bit, s.ToInt64(s[0]->InputAt(1))); |
| 951 } |
| 952 } |
| 953 |
| 954 |
787 // ----------------------------------------------------------------------------- | 955 // ----------------------------------------------------------------------------- |
788 // Add and subtract instructions with overflow. | 956 // Add and subtract instructions with overflow. |
789 | 957 |
790 | 958 |
791 typedef InstructionSelectorTestWithParam<MachInst2> | 959 typedef InstructionSelectorTestWithParam<MachInst2> |
792 InstructionSelectorOvfAddSubTest; | 960 InstructionSelectorOvfAddSubTest; |
793 | 961 |
794 | 962 |
795 TEST_P(InstructionSelectorOvfAddSubTest, OvfParameter) { | 963 TEST_P(InstructionSelectorOvfAddSubTest, OvfParameter) { |
796 const MachInst2 dpi = GetParam(); | 964 const MachInst2 dpi = GetParam(); |
(...skipping 1055 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1852 ASSERT_EQ(2U, s[1]->InputCount()); | 2020 ASSERT_EQ(2U, s[1]->InputCount()); |
1853 EXPECT_EQ(s.ToVreg(s[0]->Output()), s.ToVreg(s[1]->InputAt(0))); | 2021 EXPECT_EQ(s.ToVreg(s[0]->Output()), s.ToVreg(s[1]->InputAt(0))); |
1854 EXPECT_EQ(32, s.ToInt64(s[1]->InputAt(1))); | 2022 EXPECT_EQ(32, s.ToInt64(s[1]->InputAt(1))); |
1855 ASSERT_EQ(1U, s[1]->OutputCount()); | 2023 ASSERT_EQ(1U, s[1]->OutputCount()); |
1856 EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[1]->Output())); | 2024 EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[1]->Output())); |
1857 } | 2025 } |
1858 | 2026 |
1859 } // namespace compiler | 2027 } // namespace compiler |
1860 } // namespace internal | 2028 } // namespace internal |
1861 } // namespace v8 | 2029 } // namespace v8 |
OLD | NEW |