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 |