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 <limits> | 5 #include <limits> |
6 | 6 |
7 #include "test/unittests/compiler/instruction-selector-unittest.h" | 7 #include "test/unittests/compiler/instruction-selector-unittest.h" |
8 | 8 |
9 namespace v8 { | 9 namespace v8 { |
10 namespace internal { | 10 namespace internal { |
(...skipping 2527 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2538 EXPECT_EQ(kArmMls, s[1]->arch_opcode()); | 2538 EXPECT_EQ(kArmMls, s[1]->arch_opcode()); |
2539 ASSERT_EQ(1U, s[1]->OutputCount()); | 2539 ASSERT_EQ(1U, s[1]->OutputCount()); |
2540 ASSERT_EQ(3U, s[1]->InputCount()); | 2540 ASSERT_EQ(3U, s[1]->InputCount()); |
2541 EXPECT_EQ(s.ToVreg(s[0]->Output()), s.ToVreg(s[1]->InputAt(0))); | 2541 EXPECT_EQ(s.ToVreg(s[0]->Output()), s.ToVreg(s[1]->InputAt(0))); |
2542 EXPECT_EQ(s.ToVreg(s[0]->InputAt(1)), s.ToVreg(s[1]->InputAt(1))); | 2542 EXPECT_EQ(s.ToVreg(s[0]->InputAt(1)), s.ToVreg(s[1]->InputAt(1))); |
2543 EXPECT_EQ(s.ToVreg(s[0]->InputAt(0)), s.ToVreg(s[1]->InputAt(2))); | 2543 EXPECT_EQ(s.ToVreg(s[0]->InputAt(0)), s.ToVreg(s[1]->InputAt(2))); |
2544 } | 2544 } |
2545 | 2545 |
2546 | 2546 |
2547 TEST_F(InstructionSelectorTest, Word32AndWithUbfxImmediateForARMv7) { | 2547 TEST_F(InstructionSelectorTest, Word32AndWithUbfxImmediateForARMv7) { |
2548 TRACED_FORRANGE(int32_t, width, 9, 23) { | 2548 TRACED_FORRANGE(int32_t, width, 1, 32) { |
2549 if (width == 16) continue; // Uxth. | |
2550 StreamBuilder m(this, MachineType::Int32(), MachineType::Int32()); | 2549 StreamBuilder m(this, MachineType::Int32(), MachineType::Int32()); |
2551 m.Return(m.Word32And(m.Parameter(0), | 2550 m.Return(m.Word32And(m.Parameter(0), |
2552 m.Int32Constant(0xffffffffu >> (32 - width)))); | 2551 m.Int32Constant(0xffffffffu >> (32 - width)))); |
2553 Stream s = m.Build(ARMv7); | 2552 Stream s = m.Build(ARMv7); |
2554 ASSERT_EQ(1U, s.size()); | 2553 ASSERT_EQ(1U, s.size()); |
2555 EXPECT_EQ(kArmUbfx, s[0]->arch_opcode()); | 2554 EXPECT_EQ(kArmUbfx, s[0]->arch_opcode()); |
2556 ASSERT_EQ(3U, s[0]->InputCount()); | 2555 ASSERT_EQ(3U, s[0]->InputCount()); |
2557 EXPECT_EQ(0, s.ToInt32(s[0]->InputAt(1))); | 2556 EXPECT_EQ(0, s.ToInt32(s[0]->InputAt(1))); |
2558 EXPECT_EQ(width, s.ToInt32(s[0]->InputAt(2))); | 2557 EXPECT_EQ(width, s.ToInt32(s[0]->InputAt(2))); |
2559 } | 2558 } |
2560 TRACED_FORRANGE(int32_t, width, 9, 23) { | 2559 TRACED_FORRANGE(int32_t, width, 1, 32) { |
2561 if (width == 16) continue; // Uxth. | |
2562 StreamBuilder m(this, MachineType::Int32(), MachineType::Int32()); | 2560 StreamBuilder m(this, MachineType::Int32(), MachineType::Int32()); |
2563 m.Return(m.Word32And(m.Int32Constant(0xffffffffu >> (32 - width)), | 2561 m.Return(m.Word32And(m.Int32Constant(0xffffffffu >> (32 - width)), |
2564 m.Parameter(0))); | 2562 m.Parameter(0))); |
2565 Stream s = m.Build(ARMv7); | 2563 Stream s = m.Build(ARMv7); |
2566 ASSERT_EQ(1U, s.size()); | 2564 ASSERT_EQ(1U, s.size()); |
2567 EXPECT_EQ(kArmUbfx, s[0]->arch_opcode()); | 2565 EXPECT_EQ(kArmUbfx, s[0]->arch_opcode()); |
2568 ASSERT_EQ(3U, s[0]->InputCount()); | 2566 ASSERT_EQ(3U, s[0]->InputCount()); |
2569 EXPECT_EQ(0, s.ToInt32(s[0]->InputAt(1))); | 2567 EXPECT_EQ(0, s.ToInt32(s[0]->InputAt(1))); |
2570 EXPECT_EQ(width, s.ToInt32(s[0]->InputAt(2))); | 2568 EXPECT_EQ(width, s.ToInt32(s[0]->InputAt(2))); |
2571 } | 2569 } |
2572 } | 2570 } |
2573 | 2571 |
2574 | 2572 |
2575 TEST_F(InstructionSelectorTest, Word32AndWithBfcImmediateForARMv7) { | 2573 TEST_F(InstructionSelectorTest, Word32AndWithBfcImmediateForARMv7) { |
2576 TRACED_FORRANGE(int32_t, lsb, 0, 31) { | 2574 TRACED_FORRANGE(int32_t, lsb, 0, 31) { |
2577 TRACED_FORRANGE(int32_t, width, 9, (24 - lsb) - 1) { | 2575 TRACED_FORRANGE(int32_t, width, 9, (32 - lsb) - 1) { |
2578 StreamBuilder m(this, MachineType::Int32(), MachineType::Int32()); | 2576 StreamBuilder m(this, MachineType::Int32(), MachineType::Int32()); |
2579 m.Return(m.Word32And( | 2577 m.Return(m.Word32And( |
2580 m.Parameter(0), | 2578 m.Parameter(0), |
2581 m.Int32Constant(~((0xffffffffu >> (32 - width)) << lsb)))); | 2579 m.Int32Constant(~((0xffffffffu >> (32 - width)) << lsb)))); |
2582 Stream s = m.Build(ARMv7); | 2580 Stream s = m.Build(ARMv7); |
2583 ASSERT_EQ(1U, s.size()); | 2581 ASSERT_EQ(1U, s.size()); |
2584 EXPECT_EQ(kArmBfc, s[0]->arch_opcode()); | 2582 EXPECT_EQ(kArmBfc, s[0]->arch_opcode()); |
2585 ASSERT_EQ(1U, s[0]->OutputCount()); | 2583 ASSERT_EQ(1U, s[0]->OutputCount()); |
2586 EXPECT_TRUE( | 2584 EXPECT_TRUE( |
2587 UnallocatedOperand::cast(s[0]->Output())->HasSameAsInputPolicy()); | 2585 UnallocatedOperand::cast(s[0]->Output())->HasSameAsInputPolicy()); |
2588 ASSERT_EQ(3U, s[0]->InputCount()); | 2586 ASSERT_EQ(3U, s[0]->InputCount()); |
2589 EXPECT_EQ(lsb, s.ToInt32(s[0]->InputAt(1))); | 2587 EXPECT_EQ(lsb, s.ToInt32(s[0]->InputAt(1))); |
2590 EXPECT_EQ(width, s.ToInt32(s[0]->InputAt(2))); | 2588 EXPECT_EQ(width, s.ToInt32(s[0]->InputAt(2))); |
2591 } | 2589 } |
2592 } | 2590 } |
2593 TRACED_FORRANGE(int32_t, lsb, 0, 31) { | 2591 TRACED_FORRANGE(int32_t, lsb, 0, 31) { |
2594 TRACED_FORRANGE(int32_t, width, 9, (24 - lsb) - 1) { | 2592 TRACED_FORRANGE(int32_t, width, 9, (32 - lsb) - 1) { |
2595 StreamBuilder m(this, MachineType::Int32(), MachineType::Int32()); | 2593 StreamBuilder m(this, MachineType::Int32(), MachineType::Int32()); |
2596 m.Return( | 2594 m.Return( |
2597 m.Word32And(m.Int32Constant(~((0xffffffffu >> (32 - width)) << lsb)), | 2595 m.Word32And(m.Int32Constant(~((0xffffffffu >> (32 - width)) << lsb)), |
2598 m.Parameter(0))); | 2596 m.Parameter(0))); |
2599 Stream s = m.Build(ARMv7); | 2597 Stream s = m.Build(ARMv7); |
2600 ASSERT_EQ(1U, s.size()); | 2598 ASSERT_EQ(1U, s.size()); |
2601 EXPECT_EQ(kArmBfc, s[0]->arch_opcode()); | 2599 EXPECT_EQ(kArmBfc, s[0]->arch_opcode()); |
2602 ASSERT_EQ(1U, s[0]->OutputCount()); | 2600 ASSERT_EQ(1U, s[0]->OutputCount()); |
2603 EXPECT_TRUE( | 2601 EXPECT_TRUE( |
2604 UnallocatedOperand::cast(s[0]->Output())->HasSameAsInputPolicy()); | 2602 UnallocatedOperand::cast(s[0]->Output())->HasSameAsInputPolicy()); |
(...skipping 218 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2823 Stream s = m.Build(); | 2821 Stream s = m.Build(); |
2824 ASSERT_EQ(1U, s.size()); | 2822 ASSERT_EQ(1U, s.size()); |
2825 EXPECT_EQ(kArmMvn, s[0]->arch_opcode()); | 2823 EXPECT_EQ(kArmMvn, s[0]->arch_opcode()); |
2826 EXPECT_EQ(kMode_Operand2_R, s[0]->addressing_mode()); | 2824 EXPECT_EQ(kMode_Operand2_R, s[0]->addressing_mode()); |
2827 EXPECT_EQ(1U, s[0]->InputCount()); | 2825 EXPECT_EQ(1U, s[0]->InputCount()); |
2828 EXPECT_EQ(1U, s[0]->OutputCount()); | 2826 EXPECT_EQ(1U, s[0]->OutputCount()); |
2829 } | 2827 } |
2830 | 2828 |
2831 | 2829 |
2832 TEST_F(InstructionSelectorTest, Word32AndWithWord32ShrWithImmediateForARMv7) { | 2830 TEST_F(InstructionSelectorTest, Word32AndWithWord32ShrWithImmediateForARMv7) { |
2833 TRACED_FORRANGE(int32_t, lsb, 1, 31) { | 2831 TRACED_FORRANGE(int32_t, lsb, 0, 31) { |
2834 TRACED_FORRANGE(int32_t, width, 1, 32 - lsb) { | 2832 TRACED_FORRANGE(int32_t, width, 1, 32 - lsb) { |
2835 if (((width == 8) || (width == 16)) && | |
2836 ((lsb == 8) || (lsb == 16) || (lsb == 24))) | |
2837 continue; // Uxtb/h ror. | |
2838 StreamBuilder m(this, MachineType::Int32(), MachineType::Int32()); | 2833 StreamBuilder m(this, MachineType::Int32(), MachineType::Int32()); |
2839 m.Return(m.Word32And(m.Word32Shr(m.Parameter(0), m.Int32Constant(lsb)), | 2834 m.Return(m.Word32And(m.Word32Shr(m.Parameter(0), m.Int32Constant(lsb)), |
2840 m.Int32Constant(0xffffffffu >> (32 - width)))); | 2835 m.Int32Constant(0xffffffffu >> (32 - width)))); |
2841 Stream s = m.Build(ARMv7); | 2836 Stream s = m.Build(ARMv7); |
2842 ASSERT_EQ(1U, s.size()); | 2837 ASSERT_EQ(1U, s.size()); |
2843 EXPECT_EQ(kArmUbfx, s[0]->arch_opcode()); | 2838 EXPECT_EQ(kArmUbfx, s[0]->arch_opcode()); |
2844 ASSERT_EQ(3U, s[0]->InputCount()); | 2839 ASSERT_EQ(3U, s[0]->InputCount()); |
2845 EXPECT_EQ(lsb, s.ToInt32(s[0]->InputAt(1))); | 2840 EXPECT_EQ(lsb, s.ToInt32(s[0]->InputAt(1))); |
2846 EXPECT_EQ(width, s.ToInt32(s[0]->InputAt(2))); | 2841 EXPECT_EQ(width, s.ToInt32(s[0]->InputAt(2))); |
2847 } | 2842 } |
2848 } | 2843 } |
2849 TRACED_FORRANGE(int32_t, lsb, 1, 31) { | 2844 TRACED_FORRANGE(int32_t, lsb, 0, 31) { |
2850 TRACED_FORRANGE(int32_t, width, 1, 32 - lsb) { | 2845 TRACED_FORRANGE(int32_t, width, 1, 32 - lsb) { |
2851 if (((width == 8) || (width == 16)) && | |
2852 ((lsb == 8) || (lsb == 16) || (lsb == 24))) | |
2853 continue; // Uxtb/h ror. | |
2854 StreamBuilder m(this, MachineType::Int32(), MachineType::Int32()); | 2846 StreamBuilder m(this, MachineType::Int32(), MachineType::Int32()); |
2855 m.Return(m.Word32And(m.Int32Constant(0xffffffffu >> (32 - width)), | 2847 m.Return(m.Word32And(m.Int32Constant(0xffffffffu >> (32 - width)), |
2856 m.Word32Shr(m.Parameter(0), m.Int32Constant(lsb)))); | 2848 m.Word32Shr(m.Parameter(0), m.Int32Constant(lsb)))); |
2857 Stream s = m.Build(ARMv7); | 2849 Stream s = m.Build(ARMv7); |
2858 ASSERT_EQ(1U, s.size()); | 2850 ASSERT_EQ(1U, s.size()); |
2859 EXPECT_EQ(kArmUbfx, s[0]->arch_opcode()); | 2851 EXPECT_EQ(kArmUbfx, s[0]->arch_opcode()); |
2860 ASSERT_EQ(3U, s[0]->InputCount()); | 2852 ASSERT_EQ(3U, s[0]->InputCount()); |
2861 EXPECT_EQ(lsb, s.ToInt32(s[0]->InputAt(1))); | 2853 EXPECT_EQ(lsb, s.ToInt32(s[0]->InputAt(1))); |
2862 EXPECT_EQ(width, s.ToInt32(s[0]->InputAt(2))); | 2854 EXPECT_EQ(width, s.ToInt32(s[0]->InputAt(2))); |
2863 } | 2855 } |
2864 } | 2856 } |
2865 } | 2857 } |
2866 | 2858 |
2867 | 2859 |
2868 TEST_F(InstructionSelectorTest, Word32AndWithWord32ShrAnd0xff) { | |
2869 TRACED_FORRANGE(int32_t, shr, 1, 3) { | |
2870 StreamBuilder m(this, MachineType::Int32(), MachineType::Int32()); | |
2871 Node* const p0 = m.Parameter(0); | |
2872 Node* const r = m.Word32And(m.Word32Shr(p0, m.Int32Constant(shr * 8)), | |
2873 m.Int32Constant(0xff)); | |
2874 m.Return(r); | |
2875 Stream s = m.Build(); | |
2876 ASSERT_EQ(1U, s.size()); | |
2877 EXPECT_EQ(kArmUxtb, s[0]->arch_opcode()); | |
2878 ASSERT_EQ(2U, s[0]->InputCount()); | |
2879 EXPECT_EQ(shr * 8, s.ToInt32(s[0]->InputAt(1))); | |
2880 } | |
2881 TRACED_FORRANGE(int32_t, shr, 1, 3) { | |
2882 StreamBuilder m(this, MachineType::Int32(), MachineType::Int32()); | |
2883 Node* const p0 = m.Parameter(0); | |
2884 Node* const r = m.Word32And(m.Int32Constant(0xff), | |
2885 m.Word32Shr(p0, m.Int32Constant(shr * 8))); | |
2886 m.Return(r); | |
2887 Stream s = m.Build(); | |
2888 ASSERT_EQ(1U, s.size()); | |
2889 EXPECT_EQ(kArmUxtb, s[0]->arch_opcode()); | |
2890 ASSERT_EQ(2U, s[0]->InputCount()); | |
2891 EXPECT_EQ(shr * 8, s.ToInt32(s[0]->InputAt(1))); | |
2892 } | |
2893 } | |
2894 | |
2895 | |
2896 TEST_F(InstructionSelectorTest, Word32AndWithWord32ShrAnd0xffff) { | |
2897 TRACED_FORRANGE(int32_t, shr, 1, 3) { | |
2898 StreamBuilder m(this, MachineType::Int32(), MachineType::Int32()); | |
2899 Node* const p0 = m.Parameter(0); | |
2900 Node* const r = m.Word32And(m.Word32Shr(p0, m.Int32Constant(shr * 8)), | |
2901 m.Int32Constant(0xffff)); | |
2902 m.Return(r); | |
2903 Stream s = m.Build(); | |
2904 ASSERT_EQ(1U, s.size()); | |
2905 EXPECT_EQ(kArmUxth, s[0]->arch_opcode()); | |
2906 ASSERT_EQ(2U, s[0]->InputCount()); | |
2907 EXPECT_EQ(shr * 8, s.ToInt32(s[0]->InputAt(1))); | |
2908 } | |
2909 TRACED_FORRANGE(int32_t, shr, 1, 3) { | |
2910 StreamBuilder m(this, MachineType::Int32(), MachineType::Int32()); | |
2911 Node* const p0 = m.Parameter(0); | |
2912 Node* const r = m.Word32And(m.Int32Constant(0xffff), | |
2913 m.Word32Shr(p0, m.Int32Constant(shr * 8))); | |
2914 m.Return(r); | |
2915 Stream s = m.Build(); | |
2916 ASSERT_EQ(1U, s.size()); | |
2917 EXPECT_EQ(kArmUxth, s[0]->arch_opcode()); | |
2918 ASSERT_EQ(2U, s[0]->InputCount()); | |
2919 EXPECT_EQ(shr * 8, s.ToInt32(s[0]->InputAt(1))); | |
2920 } | |
2921 } | |
2922 | |
2923 | |
2924 TEST_F(InstructionSelectorTest, Word32Clz) { | 2860 TEST_F(InstructionSelectorTest, Word32Clz) { |
2925 StreamBuilder m(this, MachineType::Uint32(), MachineType::Uint32()); | 2861 StreamBuilder m(this, MachineType::Uint32(), MachineType::Uint32()); |
2926 Node* const p0 = m.Parameter(0); | 2862 Node* const p0 = m.Parameter(0); |
2927 Node* const n = m.Word32Clz(p0); | 2863 Node* const n = m.Word32Clz(p0); |
2928 m.Return(n); | 2864 m.Return(n); |
2929 Stream s = m.Build(); | 2865 Stream s = m.Build(); |
2930 ASSERT_EQ(1U, s.size()); | 2866 ASSERT_EQ(1U, s.size()); |
2931 EXPECT_EQ(kArmClz, s[0]->arch_opcode()); | 2867 EXPECT_EQ(kArmClz, s[0]->arch_opcode()); |
2932 ASSERT_EQ(1U, s[0]->InputCount()); | 2868 ASSERT_EQ(1U, s[0]->InputCount()); |
2933 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0))); | 2869 EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0))); |
2934 ASSERT_EQ(1U, s[0]->OutputCount()); | 2870 ASSERT_EQ(1U, s[0]->OutputCount()); |
2935 EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output())); | 2871 EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output())); |
2936 } | 2872 } |
2937 | 2873 |
2938 } // namespace compiler | 2874 } // namespace compiler |
2939 } // namespace internal | 2875 } // namespace internal |
2940 } // namespace v8 | 2876 } // namespace v8 |
OLD | NEW |