| 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 790 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 801 uint32_t mask = 1 << bit; | 801 uint32_t mask = 1 << bit; |
| 802 StreamBuilder m(this, kMachInt32, kMachInt32); | 802 StreamBuilder m(this, kMachInt32, kMachInt32); |
| 803 MLabel a, b; | 803 MLabel a, b; |
| 804 m.Branch(m.Word32And(m.Parameter(0), m.Int32Constant(mask)), &a, &b); | 804 m.Branch(m.Word32And(m.Parameter(0), m.Int32Constant(mask)), &a, &b); |
| 805 m.Bind(&a); | 805 m.Bind(&a); |
| 806 m.Return(m.Int32Constant(1)); | 806 m.Return(m.Int32Constant(1)); |
| 807 m.Bind(&b); | 807 m.Bind(&b); |
| 808 m.Return(m.Int32Constant(0)); | 808 m.Return(m.Int32Constant(0)); |
| 809 Stream s = m.Build(); | 809 Stream s = m.Build(); |
| 810 ASSERT_EQ(1U, s.size()); | 810 ASSERT_EQ(1U, s.size()); |
| 811 EXPECT_EQ(kArm64Tbnz32, s[0]->arch_opcode()); | 811 EXPECT_EQ(kArm64TestAndBranch32, s[0]->arch_opcode()); |
| 812 EXPECT_EQ(kNotEqual, s[0]->flags_condition()); |
| 812 EXPECT_EQ(4U, s[0]->InputCount()); | 813 EXPECT_EQ(4U, s[0]->InputCount()); |
| 813 EXPECT_EQ(InstructionOperand::IMMEDIATE, s[0]->InputAt(1)->kind()); | 814 EXPECT_EQ(InstructionOperand::IMMEDIATE, s[0]->InputAt(1)->kind()); |
| 814 EXPECT_EQ(bit, s.ToInt32(s[0]->InputAt(1))); | 815 EXPECT_EQ(bit, s.ToInt32(s[0]->InputAt(1))); |
| 815 } | 816 } |
| 816 | 817 |
| 817 TRACED_FORRANGE(int, bit, 0, 31) { | 818 TRACED_FORRANGE(int, bit, 0, 31) { |
| 818 uint32_t mask = 1 << bit; | 819 uint32_t mask = 1 << bit; |
| 819 StreamBuilder m(this, kMachInt32, kMachInt32); | 820 StreamBuilder m(this, kMachInt32, kMachInt32); |
| 820 MLabel a, b; | 821 MLabel a, b; |
| 821 m.Branch( | 822 m.Branch( |
| 822 m.Word32BinaryNot(m.Word32And(m.Parameter(0), m.Int32Constant(mask))), | 823 m.Word32BinaryNot(m.Word32And(m.Parameter(0), m.Int32Constant(mask))), |
| 823 &a, &b); | 824 &a, &b); |
| 824 m.Bind(&a); | 825 m.Bind(&a); |
| 825 m.Return(m.Int32Constant(1)); | 826 m.Return(m.Int32Constant(1)); |
| 826 m.Bind(&b); | 827 m.Bind(&b); |
| 827 m.Return(m.Int32Constant(0)); | 828 m.Return(m.Int32Constant(0)); |
| 828 Stream s = m.Build(); | 829 Stream s = m.Build(); |
| 829 ASSERT_EQ(1U, s.size()); | 830 ASSERT_EQ(1U, s.size()); |
| 830 EXPECT_EQ(kArm64Tbz32, s[0]->arch_opcode()); | 831 EXPECT_EQ(kArm64TestAndBranch32, s[0]->arch_opcode()); |
| 832 EXPECT_EQ(kEqual, s[0]->flags_condition()); |
| 831 EXPECT_EQ(4U, s[0]->InputCount()); | 833 EXPECT_EQ(4U, s[0]->InputCount()); |
| 832 EXPECT_EQ(InstructionOperand::IMMEDIATE, s[0]->InputAt(1)->kind()); | 834 EXPECT_EQ(InstructionOperand::IMMEDIATE, s[0]->InputAt(1)->kind()); |
| 833 EXPECT_EQ(bit, s.ToInt32(s[0]->InputAt(1))); | 835 EXPECT_EQ(bit, s.ToInt32(s[0]->InputAt(1))); |
| 834 } | 836 } |
| 835 } | 837 } |
| 836 | 838 |
| 837 | 839 |
| 838 TEST_F(InstructionSelectorTest, Word32AndBranchWithOneBitMaskOnLeft) { | 840 TEST_F(InstructionSelectorTest, Word32AndBranchWithOneBitMaskOnLeft) { |
| 839 TRACED_FORRANGE(int, bit, 0, 31) { | 841 TRACED_FORRANGE(int, bit, 0, 31) { |
| 840 uint32_t mask = 1 << bit; | 842 uint32_t mask = 1 << bit; |
| 841 StreamBuilder m(this, kMachInt32, kMachInt32); | 843 StreamBuilder m(this, kMachInt32, kMachInt32); |
| 842 MLabel a, b; | 844 MLabel a, b; |
| 843 m.Branch(m.Word32And(m.Int32Constant(mask), m.Parameter(0)), &a, &b); | 845 m.Branch(m.Word32And(m.Int32Constant(mask), m.Parameter(0)), &a, &b); |
| 844 m.Bind(&a); | 846 m.Bind(&a); |
| 845 m.Return(m.Int32Constant(1)); | 847 m.Return(m.Int32Constant(1)); |
| 846 m.Bind(&b); | 848 m.Bind(&b); |
| 847 m.Return(m.Int32Constant(0)); | 849 m.Return(m.Int32Constant(0)); |
| 848 Stream s = m.Build(); | 850 Stream s = m.Build(); |
| 849 ASSERT_EQ(1U, s.size()); | 851 ASSERT_EQ(1U, s.size()); |
| 850 EXPECT_EQ(kArm64Tbnz32, s[0]->arch_opcode()); | 852 EXPECT_EQ(kArm64TestAndBranch32, s[0]->arch_opcode()); |
| 853 EXPECT_EQ(kNotEqual, s[0]->flags_condition()); |
| 851 EXPECT_EQ(4U, s[0]->InputCount()); | 854 EXPECT_EQ(4U, s[0]->InputCount()); |
| 852 EXPECT_EQ(InstructionOperand::IMMEDIATE, s[0]->InputAt(1)->kind()); | 855 EXPECT_EQ(InstructionOperand::IMMEDIATE, s[0]->InputAt(1)->kind()); |
| 853 EXPECT_EQ(bit, s.ToInt32(s[0]->InputAt(1))); | 856 EXPECT_EQ(bit, s.ToInt32(s[0]->InputAt(1))); |
| 854 } | 857 } |
| 855 | 858 |
| 856 TRACED_FORRANGE(int, bit, 0, 31) { | 859 TRACED_FORRANGE(int, bit, 0, 31) { |
| 857 uint32_t mask = 1 << bit; | 860 uint32_t mask = 1 << bit; |
| 858 StreamBuilder m(this, kMachInt32, kMachInt32); | 861 StreamBuilder m(this, kMachInt32, kMachInt32); |
| 859 MLabel a, b; | 862 MLabel a, b; |
| 860 m.Branch( | 863 m.Branch( |
| 861 m.Word32BinaryNot(m.Word32And(m.Int32Constant(mask), m.Parameter(0))), | 864 m.Word32BinaryNot(m.Word32And(m.Int32Constant(mask), m.Parameter(0))), |
| 862 &a, &b); | 865 &a, &b); |
| 863 m.Bind(&a); | 866 m.Bind(&a); |
| 864 m.Return(m.Int32Constant(1)); | 867 m.Return(m.Int32Constant(1)); |
| 865 m.Bind(&b); | 868 m.Bind(&b); |
| 866 m.Return(m.Int32Constant(0)); | 869 m.Return(m.Int32Constant(0)); |
| 867 Stream s = m.Build(); | 870 Stream s = m.Build(); |
| 868 ASSERT_EQ(1U, s.size()); | 871 ASSERT_EQ(1U, s.size()); |
| 869 EXPECT_EQ(kArm64Tbz32, s[0]->arch_opcode()); | 872 EXPECT_EQ(kArm64TestAndBranch32, s[0]->arch_opcode()); |
| 873 EXPECT_EQ(kEqual, s[0]->flags_condition()); |
| 870 EXPECT_EQ(4U, s[0]->InputCount()); | 874 EXPECT_EQ(4U, s[0]->InputCount()); |
| 871 EXPECT_EQ(InstructionOperand::IMMEDIATE, s[0]->InputAt(1)->kind()); | 875 EXPECT_EQ(InstructionOperand::IMMEDIATE, s[0]->InputAt(1)->kind()); |
| 872 EXPECT_EQ(bit, s.ToInt32(s[0]->InputAt(1))); | 876 EXPECT_EQ(bit, s.ToInt32(s[0]->InputAt(1))); |
| 873 } | 877 } |
| 874 } | 878 } |
| 875 | 879 |
| 876 | 880 |
| 877 TEST_F(InstructionSelectorTest, Word64AndBranchWithOneBitMaskOnRight) { | 881 TEST_F(InstructionSelectorTest, Word64AndBranchWithOneBitMaskOnRight) { |
| 878 TRACED_FORRANGE(int, bit, 0, 63) { | 882 TRACED_FORRANGE(int, bit, 0, 63) { |
| 879 uint64_t mask = 1L << bit; | 883 uint64_t mask = 1L << bit; |
| 880 StreamBuilder m(this, kMachInt64, kMachInt64); | 884 StreamBuilder m(this, kMachInt64, kMachInt64); |
| 881 MLabel a, b; | 885 MLabel a, b; |
| 882 m.Branch(m.Word64And(m.Parameter(0), m.Int64Constant(mask)), &a, &b); | 886 m.Branch(m.Word64And(m.Parameter(0), m.Int64Constant(mask)), &a, &b); |
| 883 m.Bind(&a); | 887 m.Bind(&a); |
| 884 m.Return(m.Int32Constant(1)); | 888 m.Return(m.Int32Constant(1)); |
| 885 m.Bind(&b); | 889 m.Bind(&b); |
| 886 m.Return(m.Int32Constant(0)); | 890 m.Return(m.Int32Constant(0)); |
| 887 Stream s = m.Build(); | 891 Stream s = m.Build(); |
| 888 ASSERT_EQ(1U, s.size()); | 892 ASSERT_EQ(1U, s.size()); |
| 889 EXPECT_EQ(kArm64Tbnz, s[0]->arch_opcode()); | 893 EXPECT_EQ(kArm64TestAndBranch, s[0]->arch_opcode()); |
| 894 EXPECT_EQ(kNotEqual, s[0]->flags_condition()); |
| 890 EXPECT_EQ(4U, s[0]->InputCount()); | 895 EXPECT_EQ(4U, s[0]->InputCount()); |
| 891 EXPECT_EQ(InstructionOperand::IMMEDIATE, s[0]->InputAt(1)->kind()); | 896 EXPECT_EQ(InstructionOperand::IMMEDIATE, s[0]->InputAt(1)->kind()); |
| 892 EXPECT_EQ(bit, s.ToInt64(s[0]->InputAt(1))); | 897 EXPECT_EQ(bit, s.ToInt64(s[0]->InputAt(1))); |
| 893 } | 898 } |
| 894 | 899 |
| 895 TRACED_FORRANGE(int, bit, 0, 63) { | 900 TRACED_FORRANGE(int, bit, 0, 63) { |
| 896 uint64_t mask = 1L << bit; | 901 uint64_t mask = 1L << bit; |
| 897 StreamBuilder m(this, kMachInt64, kMachInt64); | 902 StreamBuilder m(this, kMachInt64, kMachInt64); |
| 898 MLabel a, b; | 903 MLabel a, b; |
| 899 m.Branch( | 904 m.Branch( |
| 900 m.Word64BinaryNot(m.Word64And(m.Parameter(0), m.Int64Constant(mask))), | 905 m.Word64BinaryNot(m.Word64And(m.Parameter(0), m.Int64Constant(mask))), |
| 901 &a, &b); | 906 &a, &b); |
| 902 m.Bind(&a); | 907 m.Bind(&a); |
| 903 m.Return(m.Int32Constant(1)); | 908 m.Return(m.Int32Constant(1)); |
| 904 m.Bind(&b); | 909 m.Bind(&b); |
| 905 m.Return(m.Int32Constant(0)); | 910 m.Return(m.Int32Constant(0)); |
| 906 Stream s = m.Build(); | 911 Stream s = m.Build(); |
| 907 ASSERT_EQ(1U, s.size()); | 912 ASSERT_EQ(1U, s.size()); |
| 908 EXPECT_EQ(kArm64Tbz, s[0]->arch_opcode()); | 913 EXPECT_EQ(kArm64TestAndBranch, s[0]->arch_opcode()); |
| 914 EXPECT_EQ(kEqual, s[0]->flags_condition()); |
| 909 EXPECT_EQ(4U, s[0]->InputCount()); | 915 EXPECT_EQ(4U, s[0]->InputCount()); |
| 910 EXPECT_EQ(InstructionOperand::IMMEDIATE, s[0]->InputAt(1)->kind()); | 916 EXPECT_EQ(InstructionOperand::IMMEDIATE, s[0]->InputAt(1)->kind()); |
| 911 EXPECT_EQ(bit, s.ToInt64(s[0]->InputAt(1))); | 917 EXPECT_EQ(bit, s.ToInt64(s[0]->InputAt(1))); |
| 912 } | 918 } |
| 913 } | 919 } |
| 914 | 920 |
| 915 | 921 |
| 916 TEST_F(InstructionSelectorTest, Word64AndBranchWithOneBitMaskOnLeft) { | 922 TEST_F(InstructionSelectorTest, Word64AndBranchWithOneBitMaskOnLeft) { |
| 917 TRACED_FORRANGE(int, bit, 0, 63) { | 923 TRACED_FORRANGE(int, bit, 0, 63) { |
| 918 uint64_t mask = 1L << bit; | 924 uint64_t mask = 1L << bit; |
| 919 StreamBuilder m(this, kMachInt64, kMachInt64); | 925 StreamBuilder m(this, kMachInt64, kMachInt64); |
| 920 MLabel a, b; | 926 MLabel a, b; |
| 921 m.Branch(m.Word64And(m.Int64Constant(mask), m.Parameter(0)), &a, &b); | 927 m.Branch(m.Word64And(m.Int64Constant(mask), m.Parameter(0)), &a, &b); |
| 922 m.Bind(&a); | 928 m.Bind(&a); |
| 923 m.Return(m.Int32Constant(1)); | 929 m.Return(m.Int32Constant(1)); |
| 924 m.Bind(&b); | 930 m.Bind(&b); |
| 925 m.Return(m.Int32Constant(0)); | 931 m.Return(m.Int32Constant(0)); |
| 926 Stream s = m.Build(); | 932 Stream s = m.Build(); |
| 927 ASSERT_EQ(1U, s.size()); | 933 ASSERT_EQ(1U, s.size()); |
| 928 EXPECT_EQ(kArm64Tbnz, s[0]->arch_opcode()); | 934 EXPECT_EQ(kArm64TestAndBranch, s[0]->arch_opcode()); |
| 935 EXPECT_EQ(kNotEqual, s[0]->flags_condition()); |
| 929 EXPECT_EQ(4U, s[0]->InputCount()); | 936 EXPECT_EQ(4U, s[0]->InputCount()); |
| 930 EXPECT_EQ(InstructionOperand::IMMEDIATE, s[0]->InputAt(1)->kind()); | 937 EXPECT_EQ(InstructionOperand::IMMEDIATE, s[0]->InputAt(1)->kind()); |
| 931 EXPECT_EQ(bit, s.ToInt64(s[0]->InputAt(1))); | 938 EXPECT_EQ(bit, s.ToInt64(s[0]->InputAt(1))); |
| 932 } | 939 } |
| 933 | 940 |
| 934 TRACED_FORRANGE(int, bit, 0, 63) { | 941 TRACED_FORRANGE(int, bit, 0, 63) { |
| 935 uint64_t mask = 1L << bit; | 942 uint64_t mask = 1L << bit; |
| 936 StreamBuilder m(this, kMachInt64, kMachInt64); | 943 StreamBuilder m(this, kMachInt64, kMachInt64); |
| 937 MLabel a, b; | 944 MLabel a, b; |
| 938 m.Branch( | 945 m.Branch( |
| 939 m.Word64BinaryNot(m.Word64And(m.Int64Constant(mask), m.Parameter(0))), | 946 m.Word64BinaryNot(m.Word64And(m.Int64Constant(mask), m.Parameter(0))), |
| 940 &a, &b); | 947 &a, &b); |
| 941 m.Bind(&a); | 948 m.Bind(&a); |
| 942 m.Return(m.Int32Constant(1)); | 949 m.Return(m.Int32Constant(1)); |
| 943 m.Bind(&b); | 950 m.Bind(&b); |
| 944 m.Return(m.Int32Constant(0)); | 951 m.Return(m.Int32Constant(0)); |
| 945 Stream s = m.Build(); | 952 Stream s = m.Build(); |
| 946 ASSERT_EQ(1U, s.size()); | 953 ASSERT_EQ(1U, s.size()); |
| 947 EXPECT_EQ(kArm64Tbz, s[0]->arch_opcode()); | 954 EXPECT_EQ(kArm64TestAndBranch, s[0]->arch_opcode()); |
| 955 EXPECT_EQ(kEqual, s[0]->flags_condition()); |
| 948 EXPECT_EQ(4U, s[0]->InputCount()); | 956 EXPECT_EQ(4U, s[0]->InputCount()); |
| 949 EXPECT_EQ(InstructionOperand::IMMEDIATE, s[0]->InputAt(1)->kind()); | 957 EXPECT_EQ(InstructionOperand::IMMEDIATE, s[0]->InputAt(1)->kind()); |
| 950 EXPECT_EQ(bit, s.ToInt64(s[0]->InputAt(1))); | 958 EXPECT_EQ(bit, s.ToInt64(s[0]->InputAt(1))); |
| 951 } | 959 } |
| 952 } | 960 } |
| 953 | 961 |
| 954 | 962 |
| 955 TEST_F(InstructionSelectorTest, CompareAgainstZeroAndBranch) { | 963 TEST_F(InstructionSelectorTest, CompareAgainstZeroAndBranch) { |
| 956 { | 964 { |
| 957 StreamBuilder m(this, kMachInt32, kMachInt32); | 965 StreamBuilder m(this, kMachInt32, kMachInt32); |
| 958 MLabel a, b; | 966 MLabel a, b; |
| 959 Node* p0 = m.Parameter(0); | 967 Node* p0 = m.Parameter(0); |
| 960 m.Branch(p0, &a, &b); | 968 m.Branch(p0, &a, &b); |
| 961 m.Bind(&a); | 969 m.Bind(&a); |
| 962 m.Return(m.Int32Constant(1)); | 970 m.Return(m.Int32Constant(1)); |
| 963 m.Bind(&b); | 971 m.Bind(&b); |
| 964 m.Return(m.Int32Constant(0)); | 972 m.Return(m.Int32Constant(0)); |
| 965 Stream s = m.Build(); | 973 Stream s = m.Build(); |
| 966 ASSERT_EQ(1U, s.size()); | 974 ASSERT_EQ(1U, s.size()); |
| 967 EXPECT_EQ(kArm64Cbnz32, s[0]->arch_opcode()); | 975 EXPECT_EQ(kArm64CompareAndBranch32, s[0]->arch_opcode()); |
| 976 EXPECT_EQ(kNotEqual, s[0]->flags_condition()); |
| 968 EXPECT_EQ(3U, s[0]->InputCount()); | 977 EXPECT_EQ(3U, s[0]->InputCount()); |
| 969 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0))); | 978 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0))); |
| 970 } | 979 } |
| 971 | 980 |
| 972 { | 981 { |
| 973 StreamBuilder m(this, kMachInt32, kMachInt32); | 982 StreamBuilder m(this, kMachInt32, kMachInt32); |
| 974 MLabel a, b; | 983 MLabel a, b; |
| 975 Node* p0 = m.Parameter(0); | 984 Node* p0 = m.Parameter(0); |
| 976 m.Branch(m.Word32BinaryNot(p0), &a, &b); | 985 m.Branch(m.Word32BinaryNot(p0), &a, &b); |
| 977 m.Bind(&a); | 986 m.Bind(&a); |
| 978 m.Return(m.Int32Constant(1)); | 987 m.Return(m.Int32Constant(1)); |
| 979 m.Bind(&b); | 988 m.Bind(&b); |
| 980 m.Return(m.Int32Constant(0)); | 989 m.Return(m.Int32Constant(0)); |
| 981 Stream s = m.Build(); | 990 Stream s = m.Build(); |
| 982 ASSERT_EQ(1U, s.size()); | 991 ASSERT_EQ(1U, s.size()); |
| 983 EXPECT_EQ(kArm64Cbz32, s[0]->arch_opcode()); | 992 EXPECT_EQ(kArm64CompareAndBranch32, s[0]->arch_opcode()); |
| 993 EXPECT_EQ(kEqual, s[0]->flags_condition()); |
| 984 EXPECT_EQ(3U, s[0]->InputCount()); | 994 EXPECT_EQ(3U, s[0]->InputCount()); |
| 985 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0))); | 995 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0))); |
| 986 } | 996 } |
| 987 } | 997 } |
| 988 | 998 |
| 989 | 999 |
| 990 // ----------------------------------------------------------------------------- | 1000 // ----------------------------------------------------------------------------- |
| 991 // Add and subtract instructions with overflow. | 1001 // Add and subtract instructions with overflow. |
| 992 | 1002 |
| 993 | 1003 |
| (...skipping 1163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2157 ASSERT_EQ(1U, s[0]->InputCount()); | 2167 ASSERT_EQ(1U, s[0]->InputCount()); |
| 2158 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0))); | 2168 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0))); |
| 2159 ASSERT_EQ(1U, s[0]->OutputCount()); | 2169 ASSERT_EQ(1U, s[0]->OutputCount()); |
| 2160 EXPECT_EQ(s.ToVreg(r), s.ToVreg(s[0]->Output())); | 2170 EXPECT_EQ(s.ToVreg(r), s.ToVreg(s[0]->Output())); |
| 2161 } | 2171 } |
| 2162 } | 2172 } |
| 2163 | 2173 |
| 2164 } // namespace compiler | 2174 } // namespace compiler |
| 2165 } // namespace internal | 2175 } // namespace internal |
| 2166 } // namespace v8 | 2176 } // namespace v8 |
| OLD | NEW |