OLD | NEW |
1 // Copyright 2016 the V8 project authors. All rights reserved. | 1 // Copyright 2016 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/wasm/wasm-macro-gen.h" | 5 #include "src/wasm/wasm-macro-gen.h" |
6 | 6 |
7 #include "test/cctest/cctest.h" | 7 #include "test/cctest/cctest.h" |
8 #include "test/cctest/compiler/value-helper.h" | 8 #include "test/cctest/compiler/value-helper.h" |
9 #include "test/cctest/wasm/wasm-run-utils.h" | 9 #include "test/cctest/wasm/wasm-run-utils.h" |
10 | 10 |
11 using namespace v8::base; | 11 using namespace v8::base; |
12 using namespace v8::internal; | 12 using namespace v8::internal; |
13 using namespace v8::internal::compiler; | 13 using namespace v8::internal::compiler; |
14 using namespace v8::internal::wasm; | 14 using namespace v8::internal::wasm; |
15 | 15 |
16 namespace { | 16 namespace { |
17 | 17 |
18 typedef float (*FloatUnOp)(float); | 18 typedef float (*FloatUnOp)(float); |
19 typedef float (*FloatBinOp)(float, float); | 19 typedef float (*FloatBinOp)(float, float); |
20 typedef int32_t (*FloatCompareOp)(float, float); | 20 typedef int32_t (*FloatCompareOp)(float, float); |
21 typedef int32_t (*Int32UnOp)(int32_t); | 21 typedef int32_t (*Int32UnOp)(int32_t); |
22 typedef int32_t (*Int32BinOp)(int32_t, int32_t); | 22 typedef int32_t (*Int32BinOp)(int32_t, int32_t); |
| 23 typedef int32_t (*Int32ShiftOp)(int32_t, int); |
23 typedef int16_t (*Int16UnOp)(int16_t); | 24 typedef int16_t (*Int16UnOp)(int16_t); |
24 typedef int16_t (*Int16BinOp)(int16_t, int16_t); | 25 typedef int16_t (*Int16BinOp)(int16_t, int16_t); |
| 26 typedef int16_t (*Int16ShiftOp)(int16_t, int); |
25 typedef int8_t (*Int8UnOp)(int8_t); | 27 typedef int8_t (*Int8UnOp)(int8_t); |
26 typedef int8_t (*Int8BinOp)(int8_t, int8_t); | 28 typedef int8_t (*Int8BinOp)(int8_t, int8_t); |
| 29 typedef int8_t (*Int8ShiftOp)(int8_t, int); |
27 | 30 |
28 #if V8_TARGET_ARCH_ARM | 31 #if V8_TARGET_ARCH_ARM |
29 // Floating point specific value functions. | 32 // Floating point specific value functions. |
30 int32_t Equal(float a, float b) { return a == b ? -1 : 0; } | 33 int32_t Equal(float a, float b) { return a == b ? -1 : 0; } |
31 | 34 |
32 int32_t NotEqual(float a, float b) { return a != b ? -1 : 0; } | 35 int32_t NotEqual(float a, float b) { return a != b ? -1 : 0; } |
33 #endif // V8_TARGET_ARCH_ARM | 36 #endif // V8_TARGET_ARCH_ARM |
34 | 37 |
35 // Generic expected value functions. | 38 // Generic expected value functions. |
36 template <typename T> | 39 template <typename T> |
(...skipping 10 matching lines...) Expand all Loading... |
47 T Sub(T a, T b) { | 50 T Sub(T a, T b) { |
48 return a - b; | 51 return a - b; |
49 } | 52 } |
50 | 53 |
51 template <typename T> | 54 template <typename T> |
52 T Mul(T a, T b) { | 55 T Mul(T a, T b) { |
53 return a * b; | 56 return a * b; |
54 } | 57 } |
55 | 58 |
56 template <typename T> | 59 template <typename T> |
| 60 T Minimum(T a, T b) { |
| 61 return a <= b ? a : b; |
| 62 } |
| 63 |
| 64 template <typename T> |
| 65 T Maximum(T a, T b) { |
| 66 return a >= b ? a : b; |
| 67 } |
| 68 |
| 69 template <typename T> |
| 70 T UnsignedMinimum(T a, T b) { |
| 71 using UnsignedT = typename std::make_unsigned<T>::type; |
| 72 return static_cast<UnsignedT>(a) <= static_cast<UnsignedT>(b) ? a : b; |
| 73 } |
| 74 |
| 75 template <typename T> |
| 76 T UnsignedMaximum(T a, T b) { |
| 77 using UnsignedT = typename std::make_unsigned<T>::type; |
| 78 return static_cast<UnsignedT>(a) >= static_cast<UnsignedT>(b) ? a : b; |
| 79 } |
| 80 |
| 81 template <typename T> |
57 T Equal(T a, T b) { | 82 T Equal(T a, T b) { |
58 return a == b ? -1 : 0; | 83 return a == b ? -1 : 0; |
59 } | 84 } |
60 | 85 |
61 template <typename T> | 86 template <typename T> |
62 T NotEqual(T a, T b) { | 87 T NotEqual(T a, T b) { |
63 return a != b ? -1 : 0; | 88 return a != b ? -1 : 0; |
64 } | 89 } |
65 | 90 |
66 template <typename T> | 91 template <typename T> |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
100 using UnsignedT = typename std::make_unsigned<T>::type; | 125 using UnsignedT = typename std::make_unsigned<T>::type; |
101 return static_cast<UnsignedT>(a) < static_cast<UnsignedT>(b) ? -1 : 0; | 126 return static_cast<UnsignedT>(a) < static_cast<UnsignedT>(b) ? -1 : 0; |
102 } | 127 } |
103 | 128 |
104 template <typename T> | 129 template <typename T> |
105 T UnsignedLessEqual(T a, T b) { | 130 T UnsignedLessEqual(T a, T b) { |
106 using UnsignedT = typename std::make_unsigned<T>::type; | 131 using UnsignedT = typename std::make_unsigned<T>::type; |
107 return static_cast<UnsignedT>(a) <= static_cast<UnsignedT>(b) ? -1 : 0; | 132 return static_cast<UnsignedT>(a) <= static_cast<UnsignedT>(b) ? -1 : 0; |
108 } | 133 } |
109 | 134 |
| 135 template <typename T> |
| 136 T LogicalShiftLeft(T a, int shift) { |
| 137 return a << shift; |
| 138 } |
| 139 |
| 140 template <typename T> |
| 141 T LogicalShiftRight(T a, int shift) { |
| 142 using UnsignedT = typename std::make_unsigned<T>::type; |
| 143 return static_cast<UnsignedT>(a) >> shift; |
| 144 } |
| 145 |
| 146 template <typename T> |
| 147 int64_t Widen(T value) { |
| 148 static_assert(sizeof(int64_t) > sizeof(T), "T must be int32_t or smaller"); |
| 149 return static_cast<int64_t>(value); |
| 150 } |
| 151 |
| 152 template <typename T> |
| 153 int64_t UnsignedWiden(T value) { |
| 154 static_assert(sizeof(int64_t) > sizeof(T), "T must be int32_t or smaller"); |
| 155 using UnsignedT = typename std::make_unsigned<T>::type; |
| 156 return static_cast<int64_t>(static_cast<UnsignedT>(value)); |
| 157 } |
| 158 |
| 159 template <typename T> |
| 160 T Clamp(int64_t value) { |
| 161 static_assert(sizeof(int64_t) > sizeof(T), "T must be int32_t or smaller"); |
| 162 int64_t min = static_cast<int64_t>(std::numeric_limits<T>::min()); |
| 163 int64_t max = static_cast<int64_t>(std::numeric_limits<T>::max()); |
| 164 int64_t clamped = std::max(min, std::min(max, value)); |
| 165 return static_cast<T>(clamped); |
| 166 } |
| 167 |
| 168 template <typename T> |
| 169 T AddSaturate(T a, T b) { |
| 170 return Clamp<T>(Widen(a) + Widen(b)); |
| 171 } |
| 172 |
| 173 template <typename T> |
| 174 T SubSaturate(T a, T b) { |
| 175 return Clamp<T>(Widen(a) - Widen(b)); |
| 176 } |
| 177 |
| 178 template <typename T> |
| 179 T UnsignedAddSaturate(T a, T b) { |
| 180 using UnsignedT = typename std::make_unsigned<T>::type; |
| 181 return Clamp<UnsignedT>(UnsignedWiden(a) + UnsignedWiden(b)); |
| 182 } |
| 183 |
| 184 template <typename T> |
| 185 T UnsignedSubSaturate(T a, T b) { |
| 186 using UnsignedT = typename std::make_unsigned<T>::type; |
| 187 return Clamp<UnsignedT>(UnsignedWiden(a) - UnsignedWiden(b)); |
| 188 } |
| 189 |
110 } // namespace | 190 } // namespace |
111 | 191 |
112 // TODO(gdeepti): These are tests using sample values to verify functional | 192 // TODO(gdeepti): These are tests using sample values to verify functional |
113 // correctness of opcodes, add more tests for a range of values and macroize | 193 // correctness of opcodes, add more tests for a range of values and macroize |
114 // tests. | 194 // tests. |
115 | 195 |
116 // TODO(bbudge) Figure out how to compare floats in Wasm code that can handle | 196 // TODO(bbudge) Figure out how to compare floats in Wasm code that can handle |
117 // NaNs. For now, our tests avoid using NaNs. | 197 // NaNs. For now, our tests avoid using NaNs. |
118 #define WASM_SIMD_CHECK_LANE(TYPE, value, LANE_TYPE, lane_value, lane_index) \ | 198 #define WASM_SIMD_CHECK_LANE(TYPE, value, LANE_TYPE, lane_value, lane_index) \ |
119 WASM_IF(WASM_##LANE_TYPE##_NE(WASM_GET_LOCAL(lane_value), \ | 199 WASM_IF(WASM_##LANE_TYPE##_NE(WASM_GET_LOCAL(lane_value), \ |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
177 | 257 |
178 #define WASM_SIMD_CHECK4_F32(TYPE, value, lv0, lv1, lv2, lv3) \ | 258 #define WASM_SIMD_CHECK4_F32(TYPE, value, lv0, lv1, lv2, lv3) \ |
179 WASM_SIMD_CHECK_F32_LANE(TYPE, value, lv0, 0) \ | 259 WASM_SIMD_CHECK_F32_LANE(TYPE, value, lv0, 0) \ |
180 , WASM_SIMD_CHECK_F32_LANE(TYPE, value, lv1, 1), \ | 260 , WASM_SIMD_CHECK_F32_LANE(TYPE, value, lv1, 1), \ |
181 WASM_SIMD_CHECK_F32_LANE(TYPE, value, lv2, 2), \ | 261 WASM_SIMD_CHECK_F32_LANE(TYPE, value, lv2, 2), \ |
182 WASM_SIMD_CHECK_F32_LANE(TYPE, value, lv3, 3) | 262 WASM_SIMD_CHECK_F32_LANE(TYPE, value, lv3, 3) |
183 | 263 |
184 #define WASM_SIMD_CHECK_SPLAT4_F32(TYPE, value, lv) \ | 264 #define WASM_SIMD_CHECK_SPLAT4_F32(TYPE, value, lv) \ |
185 WASM_SIMD_CHECK4_F32(TYPE, value, lv, lv, lv, lv) | 265 WASM_SIMD_CHECK4_F32(TYPE, value, lv, lv, lv, lv) |
186 | 266 |
| 267 #define WASM_SIMD_UNOP(opcode, x) x, kSimdPrefix, static_cast<byte>(opcode) |
| 268 #define WASM_SIMD_BINOP(opcode, x, y) \ |
| 269 x, y, kSimdPrefix, static_cast<byte>(opcode) |
| 270 #define WASM_SIMD_SHIFT_OP(opcode, x, shift) \ |
| 271 x, kSimdPrefix, static_cast<byte>(opcode), static_cast<byte>(shift) |
| 272 |
187 #if V8_TARGET_ARCH_ARM | 273 #if V8_TARGET_ARCH_ARM |
188 WASM_EXEC_TEST(F32x4Splat) { | 274 WASM_EXEC_TEST(F32x4Splat) { |
189 FLAG_wasm_simd_prototype = true; | 275 FLAG_wasm_simd_prototype = true; |
190 | 276 |
191 WasmRunner<int32_t, float> r(kExecuteCompiled); | 277 WasmRunner<int32_t, float> r(kExecuteCompiled); |
192 byte lane_val = 0; | 278 byte lane_val = 0; |
193 byte simd = r.AllocateLocal(kWasmS128); | 279 byte simd = r.AllocateLocal(kWasmS128); |
194 BUILD(r, WASM_BLOCK(WASM_SET_LOCAL(simd, WASM_SIMD_F32x4_SPLAT( | 280 BUILD(r, WASM_BLOCK(WASM_SET_LOCAL(simd, WASM_SIMD_F32x4_SPLAT( |
195 WASM_GET_LOCAL(lane_val))), | 281 WASM_GET_LOCAL(lane_val))), |
196 WASM_SIMD_CHECK_SPLAT4_F32(F32x4, simd, lane_val), | 282 WASM_SIMD_CHECK_SPLAT4_F32(F32x4, simd, lane_val), |
(...skipping 550 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
747 } | 833 } |
748 } | 834 } |
749 | 835 |
750 WASM_EXEC_TEST(I32x4Add) { RunI32x4BinOpTest(kExprI32x4Add, Add); } | 836 WASM_EXEC_TEST(I32x4Add) { RunI32x4BinOpTest(kExprI32x4Add, Add); } |
751 | 837 |
752 WASM_EXEC_TEST(I32x4Sub) { RunI32x4BinOpTest(kExprI32x4Sub, Sub); } | 838 WASM_EXEC_TEST(I32x4Sub) { RunI32x4BinOpTest(kExprI32x4Sub, Sub); } |
753 | 839 |
754 #if V8_TARGET_ARCH_ARM | 840 #if V8_TARGET_ARCH_ARM |
755 WASM_EXEC_TEST(I32x4Mul) { RunI32x4BinOpTest(kExprI32x4Mul, Mul); } | 841 WASM_EXEC_TEST(I32x4Mul) { RunI32x4BinOpTest(kExprI32x4Mul, Mul); } |
756 | 842 |
| 843 WASM_EXEC_TEST(I32x4Min) { RunI32x4BinOpTest(kExprI32x4MinS, Minimum); } |
| 844 |
| 845 WASM_EXEC_TEST(I32x4Max) { RunI32x4BinOpTest(kExprI32x4MaxS, Maximum); } |
| 846 |
757 WASM_EXEC_TEST(I32x4Equal) { RunI32x4BinOpTest(kExprI32x4Eq, Equal); } | 847 WASM_EXEC_TEST(I32x4Equal) { RunI32x4BinOpTest(kExprI32x4Eq, Equal); } |
758 | 848 |
759 WASM_EXEC_TEST(I32x4NotEqual) { RunI32x4BinOpTest(kExprI32x4Ne, NotEqual); } | 849 WASM_EXEC_TEST(I32x4NotEqual) { RunI32x4BinOpTest(kExprI32x4Ne, NotEqual); } |
760 | 850 |
761 WASM_EXEC_TEST(I32x4Greater) { RunI32x4BinOpTest(kExprI32x4GtS, Greater); } | 851 WASM_EXEC_TEST(I32x4Greater) { RunI32x4BinOpTest(kExprI32x4GtS, Greater); } |
762 | 852 |
763 WASM_EXEC_TEST(I32x4GreaterEqual) { | 853 WASM_EXEC_TEST(I32x4GreaterEqual) { |
764 RunI32x4BinOpTest(kExprI32x4GeS, GreaterEqual); | 854 RunI32x4BinOpTest(kExprI32x4GeS, GreaterEqual); |
765 } | 855 } |
766 | 856 |
767 WASM_EXEC_TEST(I32x4Less) { RunI32x4BinOpTest(kExprI32x4LtS, Less); } | 857 WASM_EXEC_TEST(I32x4Less) { RunI32x4BinOpTest(kExprI32x4LtS, Less); } |
768 | 858 |
769 WASM_EXEC_TEST(I32x4LessEqual) { RunI32x4BinOpTest(kExprI32x4LeS, LessEqual); } | 859 WASM_EXEC_TEST(I32x4LessEqual) { RunI32x4BinOpTest(kExprI32x4LeS, LessEqual); } |
770 | 860 |
| 861 WASM_EXEC_TEST(Ui32x4Min) { |
| 862 RunI32x4BinOpTest(kExprI32x4MinU, UnsignedMinimum); |
| 863 } |
| 864 |
| 865 WASM_EXEC_TEST(Ui32x4Max) { |
| 866 RunI32x4BinOpTest(kExprI32x4MaxU, UnsignedMaximum); |
| 867 } |
| 868 |
771 WASM_EXEC_TEST(Ui32x4Greater) { | 869 WASM_EXEC_TEST(Ui32x4Greater) { |
772 RunI32x4BinOpTest(kExprI32x4GtU, UnsignedGreater); | 870 RunI32x4BinOpTest(kExprI32x4GtU, UnsignedGreater); |
773 } | 871 } |
774 | 872 |
775 WASM_EXEC_TEST(Ui32x4GreaterEqual) { | 873 WASM_EXEC_TEST(Ui32x4GreaterEqual) { |
776 RunI32x4BinOpTest(kExprI32x4GeU, UnsignedGreaterEqual); | 874 RunI32x4BinOpTest(kExprI32x4GeU, UnsignedGreaterEqual); |
777 } | 875 } |
778 | 876 |
779 WASM_EXEC_TEST(Ui32x4Less) { RunI32x4BinOpTest(kExprI32x4LtU, UnsignedLess); } | 877 WASM_EXEC_TEST(Ui32x4Less) { RunI32x4BinOpTest(kExprI32x4LtU, UnsignedLess); } |
780 | 878 |
781 WASM_EXEC_TEST(Ui32x4LessEqual) { | 879 WASM_EXEC_TEST(Ui32x4LessEqual) { |
782 RunI32x4BinOpTest(kExprI32x4LeU, UnsignedLessEqual); | 880 RunI32x4BinOpTest(kExprI32x4LeU, UnsignedLessEqual); |
783 } | 881 } |
784 | 882 |
| 883 void RunI32x4ShiftOpTest(WasmOpcode simd_op, Int32ShiftOp expected_op, |
| 884 int shift) { |
| 885 FLAG_wasm_simd_prototype = true; |
| 886 WasmRunner<int32_t, int32_t, int32_t> r(kExecuteCompiled); |
| 887 byte a = 0; |
| 888 byte expected = 1; |
| 889 byte simd = r.AllocateLocal(kWasmS128); |
| 890 BUILD(r, WASM_BLOCK( |
| 891 WASM_SET_LOCAL(simd, WASM_SIMD_I32x4_SPLAT(WASM_GET_LOCAL(a))), |
| 892 WASM_SET_LOCAL(simd, WASM_SIMD_SHIFT_OP( |
| 893 simd_op, WASM_GET_LOCAL(simd), shift)), |
| 894 WASM_SIMD_CHECK_SPLAT4(I32x4, simd, I32, expected), |
| 895 WASM_RETURN1(WASM_ONE))); |
| 896 |
| 897 FOR_INT32_INPUTS(i) { CHECK_EQ(1, r.Call(*i, expected_op(*i, shift))); } |
| 898 } |
| 899 |
| 900 WASM_EXEC_TEST(I32x4Shl) { |
| 901 RunI32x4ShiftOpTest(kExprI32x4Shl, LogicalShiftLeft, 1); |
| 902 } |
| 903 |
| 904 WASM_EXEC_TEST(I32x4ShrS) { |
| 905 RunI32x4ShiftOpTest(kExprI32x4ShrS, ArithmeticShiftRight, 1); |
| 906 } |
| 907 |
| 908 WASM_EXEC_TEST(I32x4ShrU) { |
| 909 RunI32x4ShiftOpTest(kExprI32x4ShrU, LogicalShiftRight, 1); |
| 910 } |
| 911 |
785 void RunI16x8UnOpTest(WasmOpcode simd_op, Int16UnOp expected_op) { | 912 void RunI16x8UnOpTest(WasmOpcode simd_op, Int16UnOp expected_op) { |
786 FLAG_wasm_simd_prototype = true; | 913 FLAG_wasm_simd_prototype = true; |
787 WasmRunner<int32_t, int32_t, int32_t> r(kExecuteCompiled); | 914 WasmRunner<int32_t, int32_t, int32_t> r(kExecuteCompiled); |
788 byte a = 0; | 915 byte a = 0; |
789 byte expected = 1; | 916 byte expected = 1; |
790 byte simd = r.AllocateLocal(kWasmS128); | 917 byte simd = r.AllocateLocal(kWasmS128); |
791 BUILD(r, WASM_BLOCK( | 918 BUILD(r, WASM_BLOCK( |
792 WASM_SET_LOCAL(simd, WASM_SIMD_I16x8_SPLAT(WASM_GET_LOCAL(a))), | 919 WASM_SET_LOCAL(simd, WASM_SIMD_I16x8_SPLAT(WASM_GET_LOCAL(a))), |
793 WASM_SET_LOCAL( | 920 WASM_SET_LOCAL( |
794 simd, WASM_SIMD_UNOP(simd_op & 0xffu, WASM_GET_LOCAL(simd))), | 921 simd, WASM_SIMD_UNOP(simd_op & 0xffu, WASM_GET_LOCAL(simd))), |
(...skipping 22 matching lines...) Expand all Loading... |
817 WASM_SIMD_CHECK_SPLAT8(I16x8, simd1, I32, expected), | 944 WASM_SIMD_CHECK_SPLAT8(I16x8, simd1, I32, expected), |
818 WASM_RETURN1(WASM_ONE))); | 945 WASM_RETURN1(WASM_ONE))); |
819 | 946 |
820 FOR_INT16_INPUTS(i) { | 947 FOR_INT16_INPUTS(i) { |
821 FOR_INT16_INPUTS(j) { CHECK_EQ(1, r.Call(*i, *j, expected_op(*i, *j))); } | 948 FOR_INT16_INPUTS(j) { CHECK_EQ(1, r.Call(*i, *j, expected_op(*i, *j))); } |
822 } | 949 } |
823 } | 950 } |
824 | 951 |
825 WASM_EXEC_TEST(I16x8Add) { RunI16x8BinOpTest(kExprI16x8Add, Add); } | 952 WASM_EXEC_TEST(I16x8Add) { RunI16x8BinOpTest(kExprI16x8Add, Add); } |
826 | 953 |
| 954 WASM_EXEC_TEST(I16x8AddSaturate) { |
| 955 RunI16x8BinOpTest(kExprI16x8AddSaturateS, AddSaturate); |
| 956 } |
| 957 |
827 WASM_EXEC_TEST(I16x8Sub) { RunI16x8BinOpTest(kExprI16x8Sub, Sub); } | 958 WASM_EXEC_TEST(I16x8Sub) { RunI16x8BinOpTest(kExprI16x8Sub, Sub); } |
828 | 959 |
| 960 WASM_EXEC_TEST(I16x8SubSaturate) { |
| 961 RunI16x8BinOpTest(kExprI16x8SubSaturateS, SubSaturate); |
| 962 } |
| 963 |
829 WASM_EXEC_TEST(I16x8Mul) { RunI16x8BinOpTest(kExprI16x8Mul, Mul); } | 964 WASM_EXEC_TEST(I16x8Mul) { RunI16x8BinOpTest(kExprI16x8Mul, Mul); } |
830 | 965 |
| 966 WASM_EXEC_TEST(I16x8Min) { RunI16x8BinOpTest(kExprI16x8MinS, Minimum); } |
| 967 |
| 968 WASM_EXEC_TEST(I16x8Max) { RunI16x8BinOpTest(kExprI16x8MaxS, Maximum); } |
| 969 |
831 WASM_EXEC_TEST(I16x8Equal) { RunI16x8BinOpTest(kExprI16x8Eq, Equal); } | 970 WASM_EXEC_TEST(I16x8Equal) { RunI16x8BinOpTest(kExprI16x8Eq, Equal); } |
832 | 971 |
833 WASM_EXEC_TEST(I16x8NotEqual) { RunI16x8BinOpTest(kExprI16x8Ne, NotEqual); } | 972 WASM_EXEC_TEST(I16x8NotEqual) { RunI16x8BinOpTest(kExprI16x8Ne, NotEqual); } |
834 | 973 |
835 WASM_EXEC_TEST(I16x8Greater) { RunI16x8BinOpTest(kExprI16x8GtS, Greater); } | 974 WASM_EXEC_TEST(I16x8Greater) { RunI16x8BinOpTest(kExprI16x8GtS, Greater); } |
836 | 975 |
837 WASM_EXEC_TEST(I16x8GreaterEqual) { | 976 WASM_EXEC_TEST(I16x8GreaterEqual) { |
838 RunI16x8BinOpTest(kExprI16x8GeS, GreaterEqual); | 977 RunI16x8BinOpTest(kExprI16x8GeS, GreaterEqual); |
839 } | 978 } |
840 | 979 |
841 WASM_EXEC_TEST(I16x8Less) { RunI16x8BinOpTest(kExprI16x8LtS, Less); } | 980 WASM_EXEC_TEST(I16x8Less) { RunI16x8BinOpTest(kExprI16x8LtS, Less); } |
842 | 981 |
843 WASM_EXEC_TEST(I16x8LessEqual) { RunI16x8BinOpTest(kExprI16x8LeS, LessEqual); } | 982 WASM_EXEC_TEST(I16x8LessEqual) { RunI16x8BinOpTest(kExprI16x8LeS, LessEqual); } |
844 | 983 |
| 984 WASM_EXEC_TEST(Ui16x8AddSaturate) { |
| 985 RunI16x8BinOpTest(kExprI16x8AddSaturateU, UnsignedAddSaturate); |
| 986 } |
| 987 |
| 988 WASM_EXEC_TEST(Ui16x8SubSaturate) { |
| 989 RunI16x8BinOpTest(kExprI16x8SubSaturateU, UnsignedSubSaturate); |
| 990 } |
| 991 |
| 992 WASM_EXEC_TEST(Ui16x8Min) { |
| 993 RunI16x8BinOpTest(kExprI16x8MinU, UnsignedMinimum); |
| 994 } |
| 995 |
| 996 WASM_EXEC_TEST(Ui16x8Max) { |
| 997 RunI16x8BinOpTest(kExprI16x8MaxU, UnsignedMaximum); |
| 998 } |
| 999 |
845 WASM_EXEC_TEST(Ui16x8Greater) { | 1000 WASM_EXEC_TEST(Ui16x8Greater) { |
846 RunI16x8BinOpTest(kExprI16x8GtU, UnsignedGreater); | 1001 RunI16x8BinOpTest(kExprI16x8GtU, UnsignedGreater); |
847 } | 1002 } |
848 | 1003 |
849 WASM_EXEC_TEST(Ui16x8GreaterEqual) { | 1004 WASM_EXEC_TEST(Ui16x8GreaterEqual) { |
850 RunI16x8BinOpTest(kExprI16x8GeU, UnsignedGreaterEqual); | 1005 RunI16x8BinOpTest(kExprI16x8GeU, UnsignedGreaterEqual); |
851 } | 1006 } |
852 | 1007 |
853 WASM_EXEC_TEST(Ui16x8Less) { RunI16x8BinOpTest(kExprI16x8LtU, UnsignedLess); } | 1008 WASM_EXEC_TEST(Ui16x8Less) { RunI16x8BinOpTest(kExprI16x8LtU, UnsignedLess); } |
854 | 1009 |
855 WASM_EXEC_TEST(Ui16x8LessEqual) { | 1010 WASM_EXEC_TEST(Ui16x8LessEqual) { |
856 RunI16x8BinOpTest(kExprI16x8LeU, UnsignedLessEqual); | 1011 RunI16x8BinOpTest(kExprI16x8LeU, UnsignedLessEqual); |
857 } | 1012 } |
858 | 1013 |
| 1014 void RunI16x8ShiftOpTest(WasmOpcode simd_op, Int16ShiftOp expected_op, |
| 1015 int shift) { |
| 1016 FLAG_wasm_simd_prototype = true; |
| 1017 WasmRunner<int32_t, int32_t, int32_t> r(kExecuteCompiled); |
| 1018 byte a = 0; |
| 1019 byte expected = 1; |
| 1020 byte simd = r.AllocateLocal(kWasmS128); |
| 1021 BUILD(r, WASM_BLOCK( |
| 1022 WASM_SET_LOCAL(simd, WASM_SIMD_I16x8_SPLAT(WASM_GET_LOCAL(a))), |
| 1023 WASM_SET_LOCAL(simd, WASM_SIMD_SHIFT_OP( |
| 1024 simd_op, WASM_GET_LOCAL(simd), shift)), |
| 1025 WASM_SIMD_CHECK_SPLAT8(I16x8, simd, I32, expected), |
| 1026 WASM_RETURN1(WASM_ONE))); |
| 1027 |
| 1028 FOR_INT16_INPUTS(i) { CHECK_EQ(1, r.Call(*i, expected_op(*i, shift))); } |
| 1029 } |
| 1030 |
| 1031 WASM_EXEC_TEST(I16x8Shl) { |
| 1032 RunI16x8ShiftOpTest(kExprI16x8Shl, LogicalShiftLeft, 1); |
| 1033 } |
| 1034 |
| 1035 WASM_EXEC_TEST(I16x8ShrS) { |
| 1036 RunI16x8ShiftOpTest(kExprI16x8ShrS, ArithmeticShiftRight, 1); |
| 1037 } |
| 1038 |
| 1039 WASM_EXEC_TEST(I16x8ShrU) { |
| 1040 RunI16x8ShiftOpTest(kExprI16x8ShrU, LogicalShiftRight, 1); |
| 1041 } |
| 1042 |
859 void RunI8x16UnOpTest(WasmOpcode simd_op, Int8UnOp expected_op) { | 1043 void RunI8x16UnOpTest(WasmOpcode simd_op, Int8UnOp expected_op) { |
860 FLAG_wasm_simd_prototype = true; | 1044 FLAG_wasm_simd_prototype = true; |
861 WasmRunner<int32_t, int32_t, int32_t> r(kExecuteCompiled); | 1045 WasmRunner<int32_t, int32_t, int32_t> r(kExecuteCompiled); |
862 byte a = 0; | 1046 byte a = 0; |
863 byte expected = 1; | 1047 byte expected = 1; |
864 byte simd = r.AllocateLocal(kWasmS128); | 1048 byte simd = r.AllocateLocal(kWasmS128); |
865 BUILD(r, WASM_BLOCK( | 1049 BUILD(r, WASM_BLOCK( |
866 WASM_SET_LOCAL(simd, WASM_SIMD_I8x16_SPLAT(WASM_GET_LOCAL(a))), | 1050 WASM_SET_LOCAL(simd, WASM_SIMD_I8x16_SPLAT(WASM_GET_LOCAL(a))), |
867 WASM_SET_LOCAL( | 1051 WASM_SET_LOCAL( |
868 simd, WASM_SIMD_UNOP(simd_op & 0xffu, WASM_GET_LOCAL(simd))), | 1052 simd, WASM_SIMD_UNOP(simd_op & 0xffu, WASM_GET_LOCAL(simd))), |
(...skipping 22 matching lines...) Expand all Loading... |
891 WASM_SIMD_CHECK_SPLAT16(I8x16, simd1, I32, expected), | 1075 WASM_SIMD_CHECK_SPLAT16(I8x16, simd1, I32, expected), |
892 WASM_RETURN1(WASM_ONE))); | 1076 WASM_RETURN1(WASM_ONE))); |
893 | 1077 |
894 FOR_INT8_INPUTS(i) { | 1078 FOR_INT8_INPUTS(i) { |
895 FOR_INT8_INPUTS(j) { CHECK_EQ(1, r.Call(*i, *j, expected_op(*i, *j))); } | 1079 FOR_INT8_INPUTS(j) { CHECK_EQ(1, r.Call(*i, *j, expected_op(*i, *j))); } |
896 } | 1080 } |
897 } | 1081 } |
898 | 1082 |
899 WASM_EXEC_TEST(I8x16Add) { RunI8x16BinOpTest(kExprI8x16Add, Add); } | 1083 WASM_EXEC_TEST(I8x16Add) { RunI8x16BinOpTest(kExprI8x16Add, Add); } |
900 | 1084 |
| 1085 WASM_EXEC_TEST(I8x16AddSaturate) { |
| 1086 RunI8x16BinOpTest(kExprI8x16AddSaturateS, AddSaturate); |
| 1087 } |
| 1088 |
901 WASM_EXEC_TEST(I8x16Sub) { RunI8x16BinOpTest(kExprI8x16Sub, Sub); } | 1089 WASM_EXEC_TEST(I8x16Sub) { RunI8x16BinOpTest(kExprI8x16Sub, Sub); } |
902 | 1090 |
| 1091 WASM_EXEC_TEST(I8x16SubSaturate) { |
| 1092 RunI8x16BinOpTest(kExprI8x16SubSaturateS, SubSaturate); |
| 1093 } |
| 1094 |
903 WASM_EXEC_TEST(I8x16Mul) { RunI8x16BinOpTest(kExprI8x16Mul, Mul); } | 1095 WASM_EXEC_TEST(I8x16Mul) { RunI8x16BinOpTest(kExprI8x16Mul, Mul); } |
904 | 1096 |
| 1097 WASM_EXEC_TEST(I8x16Min) { RunI8x16BinOpTest(kExprI8x16MinS, Minimum); } |
| 1098 |
| 1099 WASM_EXEC_TEST(I8x16Max) { RunI8x16BinOpTest(kExprI8x16MaxS, Maximum); } |
| 1100 |
905 WASM_EXEC_TEST(I8x16Equal) { RunI8x16BinOpTest(kExprI8x16Eq, Equal); } | 1101 WASM_EXEC_TEST(I8x16Equal) { RunI8x16BinOpTest(kExprI8x16Eq, Equal); } |
906 | 1102 |
907 WASM_EXEC_TEST(I8x16NotEqual) { RunI8x16BinOpTest(kExprI8x16Ne, NotEqual); } | 1103 WASM_EXEC_TEST(I8x16NotEqual) { RunI8x16BinOpTest(kExprI8x16Ne, NotEqual); } |
908 | 1104 |
909 WASM_EXEC_TEST(I8x16Greater) { RunI8x16BinOpTest(kExprI8x16GtS, Greater); } | 1105 WASM_EXEC_TEST(I8x16Greater) { RunI8x16BinOpTest(kExprI8x16GtS, Greater); } |
910 | 1106 |
911 WASM_EXEC_TEST(I8x16GreaterEqual) { | 1107 WASM_EXEC_TEST(I8x16GreaterEqual) { |
912 RunI8x16BinOpTest(kExprI8x16GeS, GreaterEqual); | 1108 RunI8x16BinOpTest(kExprI8x16GeS, GreaterEqual); |
913 } | 1109 } |
914 | 1110 |
915 WASM_EXEC_TEST(I8x16Less) { RunI8x16BinOpTest(kExprI8x16LtS, Less); } | 1111 WASM_EXEC_TEST(I8x16Less) { RunI8x16BinOpTest(kExprI8x16LtS, Less); } |
916 | 1112 |
917 WASM_EXEC_TEST(I8x16LessEqual) { RunI8x16BinOpTest(kExprI8x16LeS, LessEqual); } | 1113 WASM_EXEC_TEST(I8x16LessEqual) { RunI8x16BinOpTest(kExprI8x16LeS, LessEqual); } |
918 | 1114 |
| 1115 WASM_EXEC_TEST(Ui8x16AddSaturate) { |
| 1116 RunI8x16BinOpTest(kExprI8x16AddSaturateU, UnsignedAddSaturate); |
| 1117 } |
| 1118 |
| 1119 WASM_EXEC_TEST(Ui8x16SubSaturate) { |
| 1120 RunI8x16BinOpTest(kExprI8x16SubSaturateU, UnsignedSubSaturate); |
| 1121 } |
| 1122 |
| 1123 WASM_EXEC_TEST(Ui8x16Min) { |
| 1124 RunI8x16BinOpTest(kExprI8x16MinU, UnsignedMinimum); |
| 1125 } |
| 1126 |
| 1127 WASM_EXEC_TEST(Ui8x16Max) { |
| 1128 RunI8x16BinOpTest(kExprI8x16MaxU, UnsignedMaximum); |
| 1129 } |
| 1130 |
919 WASM_EXEC_TEST(Ui8x16Greater) { | 1131 WASM_EXEC_TEST(Ui8x16Greater) { |
920 RunI8x16BinOpTest(kExprI8x16GtU, UnsignedGreater); | 1132 RunI8x16BinOpTest(kExprI8x16GtU, UnsignedGreater); |
921 } | 1133 } |
922 | 1134 |
923 WASM_EXEC_TEST(Ui8x16GreaterEqual) { | 1135 WASM_EXEC_TEST(Ui8x16GreaterEqual) { |
924 RunI8x16BinOpTest(kExprI8x16GeU, UnsignedGreaterEqual); | 1136 RunI8x16BinOpTest(kExprI8x16GeU, UnsignedGreaterEqual); |
925 } | 1137 } |
926 | 1138 |
927 WASM_EXEC_TEST(Ui8x16Less) { RunI8x16BinOpTest(kExprI8x16LtU, UnsignedLess); } | 1139 WASM_EXEC_TEST(Ui8x16Less) { RunI8x16BinOpTest(kExprI8x16LtU, UnsignedLess); } |
928 | 1140 |
929 WASM_EXEC_TEST(Ui8x16LessEqual) { | 1141 WASM_EXEC_TEST(Ui8x16LessEqual) { |
930 RunI8x16BinOpTest(kExprI8x16LeU, UnsignedLessEqual); | 1142 RunI8x16BinOpTest(kExprI8x16LeU, UnsignedLessEqual); |
931 } | 1143 } |
| 1144 |
| 1145 void RunI8x16ShiftOpTest(WasmOpcode simd_op, Int8ShiftOp expected_op, |
| 1146 int shift) { |
| 1147 FLAG_wasm_simd_prototype = true; |
| 1148 WasmRunner<int32_t, int32_t, int32_t> r(kExecuteCompiled); |
| 1149 byte a = 0; |
| 1150 byte expected = 1; |
| 1151 byte simd = r.AllocateLocal(kWasmS128); |
| 1152 BUILD(r, WASM_BLOCK( |
| 1153 WASM_SET_LOCAL(simd, WASM_SIMD_I8x16_SPLAT(WASM_GET_LOCAL(a))), |
| 1154 WASM_SET_LOCAL(simd, WASM_SIMD_SHIFT_OP( |
| 1155 simd_op, WASM_GET_LOCAL(simd), shift)), |
| 1156 WASM_SIMD_CHECK_SPLAT16(I8x16, simd, I32, expected), |
| 1157 WASM_RETURN1(WASM_ONE))); |
| 1158 |
| 1159 FOR_INT8_INPUTS(i) { CHECK_EQ(1, r.Call(*i, expected_op(*i, shift))); } |
| 1160 } |
| 1161 |
| 1162 WASM_EXEC_TEST(I8x16Shl) { |
| 1163 RunI8x16ShiftOpTest(kExprI8x16Shl, LogicalShiftLeft, 1); |
| 1164 } |
| 1165 |
| 1166 WASM_EXEC_TEST(I8x16ShrS) { |
| 1167 RunI8x16ShiftOpTest(kExprI8x16ShrS, ArithmeticShiftRight, 1); |
| 1168 } |
| 1169 |
| 1170 WASM_EXEC_TEST(I8x16ShrU) { |
| 1171 RunI8x16ShiftOpTest(kExprI8x16ShrU, LogicalShiftRight, 1); |
| 1172 } |
932 #endif // V8_TARGET_ARCH_ARM | 1173 #endif // V8_TARGET_ARCH_ARM |
OLD | NEW |