| 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 |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 90 #define WASM_SIMD_CHECK_SPLAT4_F32(TYPE, value, lv) \ | 90 #define WASM_SIMD_CHECK_SPLAT4_F32(TYPE, value, lv) \ |
| 91 WASM_SIMD_CHECK4_F32(TYPE, value, lv, lv, lv, lv) | 91 WASM_SIMD_CHECK4_F32(TYPE, value, lv, lv, lv, lv) |
| 92 | 92 |
| 93 #if V8_TARGET_ARCH_ARM | 93 #if V8_TARGET_ARCH_ARM |
| 94 WASM_EXEC_TEST(F32x4Splat) { | 94 WASM_EXEC_TEST(F32x4Splat) { |
| 95 FLAG_wasm_simd_prototype = true; | 95 FLAG_wasm_simd_prototype = true; |
| 96 | 96 |
| 97 WasmRunner<int32_t, float> r(kExecuteCompiled); | 97 WasmRunner<int32_t, float> r(kExecuteCompiled); |
| 98 byte lane_val = 0; | 98 byte lane_val = 0; |
| 99 byte simd = r.AllocateLocal(kWasmS128); | 99 byte simd = r.AllocateLocal(kWasmS128); |
| 100 BUILD(r, WASM_BLOCK(WASM_SET_LOCAL(simd, WASM_SIMD_F32x4_SPLAT( | 100 BUILD(r, |
| 101 WASM_GET_LOCAL(lane_val))), | 101 WASM_SET_LOCAL(simd, WASM_SIMD_F32x4_SPLAT(WASM_GET_LOCAL(lane_val))), |
| 102 WASM_SIMD_CHECK_SPLAT4_F32(F32x4, simd, lane_val), | 102 WASM_SIMD_CHECK_SPLAT4_F32(F32x4, simd, lane_val), WASM_ONE); |
| 103 WASM_RETURN1(WASM_ONE))); | |
| 104 | 103 |
| 105 FOR_FLOAT32_INPUTS(i) { CHECK_EQ(1, r.Call(*i)); } | 104 FOR_FLOAT32_INPUTS(i) { CHECK_EQ(1, r.Call(*i)); } |
| 106 } | 105 } |
| 107 | 106 |
| 108 WASM_EXEC_TEST(F32x4ReplaceLane) { | 107 WASM_EXEC_TEST(F32x4ReplaceLane) { |
| 109 FLAG_wasm_simd_prototype = true; | 108 FLAG_wasm_simd_prototype = true; |
| 110 WasmRunner<int32_t, float, float> r(kExecuteCompiled); | 109 WasmRunner<int32_t, float, float> r(kExecuteCompiled); |
| 111 byte old_val = 0; | 110 byte old_val = 0; |
| 112 byte new_val = 1; | 111 byte new_val = 1; |
| 113 byte simd = r.AllocateLocal(kWasmS128); | 112 byte simd = r.AllocateLocal(kWasmS128); |
| 114 BUILD(r, WASM_BLOCK( | 113 BUILD(r, WASM_SET_LOCAL(simd, WASM_SIMD_F32x4_SPLAT(WASM_GET_LOCAL(old_val))), |
| 115 WASM_SET_LOCAL(simd, | 114 WASM_SET_LOCAL(simd, |
| 116 WASM_SIMD_F32x4_SPLAT(WASM_GET_LOCAL(old_val))), | 115 WASM_SIMD_F32x4_REPLACE_LANE(0, WASM_GET_LOCAL(simd), |
| 117 WASM_SET_LOCAL( | 116 WASM_GET_LOCAL(new_val))), |
| 118 simd, WASM_SIMD_F32x4_REPLACE_LANE(0, WASM_GET_LOCAL(simd), | 117 WASM_SIMD_CHECK4(F32x4, simd, F32, new_val, old_val, old_val, old_val), |
| 119 WASM_GET_LOCAL(new_val))), | 118 WASM_SET_LOCAL(simd, |
| 120 WASM_SIMD_CHECK4(F32x4, simd, F32, new_val, old_val, old_val, | 119 WASM_SIMD_F32x4_REPLACE_LANE(1, WASM_GET_LOCAL(simd), |
| 121 old_val), | 120 WASM_GET_LOCAL(new_val))), |
| 122 WASM_SET_LOCAL( | 121 WASM_SIMD_CHECK4(F32x4, simd, F32, new_val, new_val, old_val, old_val), |
| 123 simd, WASM_SIMD_F32x4_REPLACE_LANE(1, WASM_GET_LOCAL(simd), | 122 WASM_SET_LOCAL(simd, |
| 124 WASM_GET_LOCAL(new_val))), | 123 WASM_SIMD_F32x4_REPLACE_LANE(2, WASM_GET_LOCAL(simd), |
| 125 WASM_SIMD_CHECK4(F32x4, simd, F32, new_val, new_val, old_val, | 124 WASM_GET_LOCAL(new_val))), |
| 126 old_val), | 125 WASM_SIMD_CHECK4(F32x4, simd, F32, new_val, new_val, new_val, old_val), |
| 127 WASM_SET_LOCAL( | 126 WASM_SET_LOCAL(simd, |
| 128 simd, WASM_SIMD_F32x4_REPLACE_LANE(2, WASM_GET_LOCAL(simd), | 127 WASM_SIMD_F32x4_REPLACE_LANE(3, WASM_GET_LOCAL(simd), |
| 129 WASM_GET_LOCAL(new_val))), | 128 WASM_GET_LOCAL(new_val))), |
| 130 WASM_SIMD_CHECK4(F32x4, simd, F32, new_val, new_val, new_val, | 129 WASM_SIMD_CHECK_SPLAT4(F32x4, simd, F32, new_val), WASM_ONE); |
| 131 old_val), | |
| 132 WASM_SET_LOCAL( | |
| 133 simd, WASM_SIMD_F32x4_REPLACE_LANE(3, WASM_GET_LOCAL(simd), | |
| 134 WASM_GET_LOCAL(new_val))), | |
| 135 WASM_SIMD_CHECK_SPLAT4(F32x4, simd, F32, new_val), | |
| 136 WASM_RETURN1(WASM_ONE))); | |
| 137 | 130 |
| 138 CHECK_EQ(1, r.Call(3.14159, -1.5)); | 131 CHECK_EQ(1, r.Call(3.14159, -1.5)); |
| 139 } | 132 } |
| 140 | 133 |
| 141 // Tests both signed and unsigned conversion. | 134 // Tests both signed and unsigned conversion. |
| 142 WASM_EXEC_TEST(F32x4FromInt32x4) { | 135 WASM_EXEC_TEST(F32x4FromInt32x4) { |
| 143 FLAG_wasm_simd_prototype = true; | 136 FLAG_wasm_simd_prototype = true; |
| 144 WasmRunner<int32_t, int32_t, float, float> r(kExecuteCompiled); | 137 WasmRunner<int32_t, int32_t, float, float> r(kExecuteCompiled); |
| 145 byte a = 0; | 138 byte a = 0; |
| 146 byte expected_signed = 1; | 139 byte expected_signed = 1; |
| 147 byte expected_unsigned = 2; | 140 byte expected_unsigned = 2; |
| 148 byte simd0 = r.AllocateLocal(kWasmS128); | 141 byte simd0 = r.AllocateLocal(kWasmS128); |
| 149 byte simd1 = r.AllocateLocal(kWasmS128); | 142 byte simd1 = r.AllocateLocal(kWasmS128); |
| 150 byte simd2 = r.AllocateLocal(kWasmS128); | 143 byte simd2 = r.AllocateLocal(kWasmS128); |
| 151 BUILD(r, WASM_BLOCK( | 144 BUILD( |
| 152 WASM_SET_LOCAL(simd0, WASM_SIMD_I32x4_SPLAT(WASM_GET_LOCAL(a))), | 145 r, WASM_SET_LOCAL(simd0, WASM_SIMD_I32x4_SPLAT(WASM_GET_LOCAL(a))), |
| 153 WASM_SET_LOCAL( | 146 WASM_SET_LOCAL(simd1, WASM_SIMD_F32x4_FROM_I32x4(WASM_GET_LOCAL(simd0))), |
| 154 simd1, WASM_SIMD_F32x4_FROM_I32x4(WASM_GET_LOCAL(simd0))), | 147 WASM_SIMD_CHECK_SPLAT4_F32(F32x4, simd1, expected_signed), |
| 155 WASM_SIMD_CHECK_SPLAT4_F32(F32x4, simd1, expected_signed), | 148 WASM_SET_LOCAL(simd2, WASM_SIMD_F32x4_FROM_U32x4(WASM_GET_LOCAL(simd0))), |
| 156 WASM_SET_LOCAL( | 149 WASM_SIMD_CHECK_SPLAT4_F32(F32x4, simd2, expected_unsigned), WASM_ONE); |
| 157 simd2, WASM_SIMD_F32x4_FROM_U32x4(WASM_GET_LOCAL(simd0))), | |
| 158 WASM_SIMD_CHECK_SPLAT4_F32(F32x4, simd2, expected_unsigned), | |
| 159 WASM_RETURN1(WASM_ONE))); | |
| 160 | 150 |
| 161 FOR_INT32_INPUTS(i) { | 151 FOR_INT32_INPUTS(i) { |
| 162 CHECK_EQ(1, r.Call(*i, static_cast<float>(*i), | 152 CHECK_EQ(1, r.Call(*i, static_cast<float>(*i), |
| 163 static_cast<float>(static_cast<uint32_t>(*i)))); | 153 static_cast<float>(static_cast<uint32_t>(*i)))); |
| 164 } | 154 } |
| 165 } | 155 } |
| 166 | 156 |
| 167 WASM_EXEC_TEST(S32x4Select) { | 157 WASM_EXEC_TEST(S32x4Select) { |
| 168 FLAG_wasm_simd_prototype = true; | 158 FLAG_wasm_simd_prototype = true; |
| 169 WasmRunner<int32_t, int32_t, int32_t> r(kExecuteCompiled); | 159 WasmRunner<int32_t, int32_t, int32_t> r(kExecuteCompiled); |
| 170 byte val1 = 0; | 160 byte val1 = 0; |
| 171 byte val2 = 1; | 161 byte val2 = 1; |
| 172 byte mask = r.AllocateLocal(kWasmS128); | 162 byte mask = r.AllocateLocal(kWasmS128); |
| 173 byte src1 = r.AllocateLocal(kWasmS128); | 163 byte src1 = r.AllocateLocal(kWasmS128); |
| 174 byte src2 = r.AllocateLocal(kWasmS128); | 164 byte src2 = r.AllocateLocal(kWasmS128); |
| 175 BUILD(r, | 165 BUILD(r, |
| 176 WASM_BLOCK( | 166 |
| 177 WASM_SET_LOCAL(mask, WASM_SIMD_I32x4_SPLAT(WASM_ZERO)), | 167 WASM_SET_LOCAL(mask, WASM_SIMD_I32x4_SPLAT(WASM_ZERO)), |
| 178 WASM_SET_LOCAL(src1, WASM_SIMD_I32x4_SPLAT(WASM_GET_LOCAL(val1))), | 168 WASM_SET_LOCAL(src1, WASM_SIMD_I32x4_SPLAT(WASM_GET_LOCAL(val1))), |
| 179 WASM_SET_LOCAL(src2, WASM_SIMD_I32x4_SPLAT(WASM_GET_LOCAL(val2))), | 169 WASM_SET_LOCAL(src2, WASM_SIMD_I32x4_SPLAT(WASM_GET_LOCAL(val2))), |
| 180 WASM_SET_LOCAL(mask, WASM_SIMD_I32x4_REPLACE_LANE( | 170 WASM_SET_LOCAL(mask, WASM_SIMD_I32x4_REPLACE_LANE( |
| 181 1, WASM_GET_LOCAL(mask), WASM_I32V(-1))), | 171 1, WASM_GET_LOCAL(mask), WASM_I32V(-1))), |
| 182 WASM_SET_LOCAL(mask, WASM_SIMD_I32x4_REPLACE_LANE( | 172 WASM_SET_LOCAL(mask, WASM_SIMD_I32x4_REPLACE_LANE( |
| 183 2, WASM_GET_LOCAL(mask), WASM_I32V(-1))), | 173 2, WASM_GET_LOCAL(mask), WASM_I32V(-1))), |
| 184 WASM_SET_LOCAL(mask, WASM_SIMD_S32x4_SELECT(WASM_GET_LOCAL(mask), | 174 WASM_SET_LOCAL(mask, WASM_SIMD_S32x4_SELECT(WASM_GET_LOCAL(mask), |
| 185 WASM_GET_LOCAL(src1), | 175 WASM_GET_LOCAL(src1), |
| 186 WASM_GET_LOCAL(src2))), | 176 WASM_GET_LOCAL(src2))), |
| 187 WASM_SIMD_CHECK_LANE(I32x4, mask, I32, val2, 0), | 177 WASM_SIMD_CHECK_LANE(I32x4, mask, I32, val2, 0), |
| 188 WASM_SIMD_CHECK_LANE(I32x4, mask, I32, val1, 1), | 178 WASM_SIMD_CHECK_LANE(I32x4, mask, I32, val1, 1), |
| 189 WASM_SIMD_CHECK_LANE(I32x4, mask, I32, val1, 2), | 179 WASM_SIMD_CHECK_LANE(I32x4, mask, I32, val1, 2), |
| 190 WASM_SIMD_CHECK_LANE(I32x4, mask, I32, val2, 3), | 180 WASM_SIMD_CHECK_LANE(I32x4, mask, I32, val2, 3), WASM_ONE); |
| 191 WASM_RETURN1(WASM_ONE))); | |
| 192 | 181 |
| 193 CHECK_EQ(1, r.Call(0x1234, 0x5678)); | 182 CHECK_EQ(1, r.Call(0x1234, 0x5678)); |
| 194 } | 183 } |
| 195 | 184 |
| 196 void RunF32x4UnOpTest(WasmOpcode simd_op, FloatUnOp expected_op) { | 185 void RunF32x4UnOpTest(WasmOpcode simd_op, FloatUnOp expected_op) { |
| 197 FLAG_wasm_simd_prototype = true; | 186 FLAG_wasm_simd_prototype = true; |
| 198 WasmRunner<int32_t, float, float> r(kExecuteCompiled); | 187 WasmRunner<int32_t, float, float> r(kExecuteCompiled); |
| 199 byte a = 0; | 188 byte a = 0; |
| 200 byte expected = 1; | 189 byte expected = 1; |
| 201 byte simd = r.AllocateLocal(kWasmS128); | 190 byte simd = r.AllocateLocal(kWasmS128); |
| 202 BUILD(r, WASM_BLOCK( | 191 BUILD(r, WASM_SET_LOCAL(simd, WASM_SIMD_F32x4_SPLAT(WASM_GET_LOCAL(a))), |
| 203 WASM_SET_LOCAL(simd, WASM_SIMD_F32x4_SPLAT(WASM_GET_LOCAL(a))), | 192 WASM_SET_LOCAL(simd, |
| 204 WASM_SET_LOCAL( | 193 WASM_SIMD_UNOP(simd_op & 0xffu, WASM_GET_LOCAL(simd))), |
| 205 simd, WASM_SIMD_UNOP(simd_op & 0xffu, WASM_GET_LOCAL(simd))), | 194 WASM_SIMD_CHECK_SPLAT4_F32(F32x4, simd, expected), WASM_ONE); |
| 206 WASM_SIMD_CHECK_SPLAT4_F32(F32x4, simd, expected), | |
| 207 WASM_RETURN1(WASM_ONE))); | |
| 208 | 195 |
| 209 FOR_FLOAT32_INPUTS(i) { | 196 FOR_FLOAT32_INPUTS(i) { |
| 210 if (std::isnan(*i)) continue; | 197 if (std::isnan(*i)) continue; |
| 211 CHECK_EQ(1, r.Call(*i, expected_op(*i))); | 198 CHECK_EQ(1, r.Call(*i, expected_op(*i))); |
| 212 } | 199 } |
| 213 } | 200 } |
| 214 | 201 |
| 215 WASM_EXEC_TEST(F32x4Abs) { RunF32x4UnOpTest(kExprF32x4Abs, std::abs); } | 202 WASM_EXEC_TEST(F32x4Abs) { RunF32x4UnOpTest(kExprF32x4Abs, std::abs); } |
| 216 WASM_EXEC_TEST(F32x4Neg) { RunF32x4UnOpTest(kExprF32x4Neg, Negate); } | 203 WASM_EXEC_TEST(F32x4Neg) { RunF32x4UnOpTest(kExprF32x4Neg, Negate); } |
| 217 | 204 |
| 218 void RunF32x4BinOpTest(WasmOpcode simd_op, FloatBinOp expected_op) { | 205 void RunF32x4BinOpTest(WasmOpcode simd_op, FloatBinOp expected_op) { |
| 219 FLAG_wasm_simd_prototype = true; | 206 FLAG_wasm_simd_prototype = true; |
| 220 WasmRunner<int32_t, float, float, float> r(kExecuteCompiled); | 207 WasmRunner<int32_t, float, float, float> r(kExecuteCompiled); |
| 221 byte a = 0; | 208 byte a = 0; |
| 222 byte b = 1; | 209 byte b = 1; |
| 223 byte expected = 2; | 210 byte expected = 2; |
| 224 byte simd0 = r.AllocateLocal(kWasmS128); | 211 byte simd0 = r.AllocateLocal(kWasmS128); |
| 225 byte simd1 = r.AllocateLocal(kWasmS128); | 212 byte simd1 = r.AllocateLocal(kWasmS128); |
| 226 BUILD(r, WASM_BLOCK( | 213 BUILD(r, WASM_SET_LOCAL(simd0, WASM_SIMD_F32x4_SPLAT(WASM_GET_LOCAL(a))), |
| 227 WASM_SET_LOCAL(simd0, WASM_SIMD_F32x4_SPLAT(WASM_GET_LOCAL(a))), | 214 WASM_SET_LOCAL(simd1, WASM_SIMD_F32x4_SPLAT(WASM_GET_LOCAL(b))), |
| 228 WASM_SET_LOCAL(simd1, WASM_SIMD_F32x4_SPLAT(WASM_GET_LOCAL(b))), | 215 WASM_SET_LOCAL(simd1, |
| 229 WASM_SET_LOCAL(simd1, WASM_SIMD_BINOP(simd_op & 0xffu, | 216 WASM_SIMD_BINOP(simd_op & 0xffu, WASM_GET_LOCAL(simd0), |
| 230 WASM_GET_LOCAL(simd0), | 217 WASM_GET_LOCAL(simd1))), |
| 231 WASM_GET_LOCAL(simd1))), | 218 WASM_SIMD_CHECK_SPLAT4_F32(F32x4, simd1, expected), WASM_ONE); |
| 232 WASM_SIMD_CHECK_SPLAT4_F32(F32x4, simd1, expected), | |
| 233 WASM_RETURN1(WASM_ONE))); | |
| 234 | 219 |
| 235 FOR_FLOAT32_INPUTS(i) { | 220 FOR_FLOAT32_INPUTS(i) { |
| 236 if (std::isnan(*i)) continue; | 221 if (std::isnan(*i)) continue; |
| 237 FOR_FLOAT32_INPUTS(j) { | 222 FOR_FLOAT32_INPUTS(j) { |
| 238 if (std::isnan(*j)) continue; | 223 if (std::isnan(*j)) continue; |
| 239 float expected = expected_op(*i, *j); | 224 float expected = expected_op(*i, *j); |
| 240 // SIMD on some platforms may handle denormalized numbers differently. | 225 // SIMD on some platforms may handle denormalized numbers differently. |
| 241 // TODO(bbudge) On platforms that flush denorms to zero, test with | 226 // TODO(bbudge) On platforms that flush denorms to zero, test with |
| 242 // expected == 0. | 227 // expected == 0. |
| 243 if (std::fpclassify(expected) == FP_SUBNORMAL) continue; | 228 if (std::fpclassify(expected) == FP_SUBNORMAL) continue; |
| 244 CHECK_EQ(1, r.Call(*i, *j, expected)); | 229 CHECK_EQ(1, r.Call(*i, *j, expected)); |
| 245 } | 230 } |
| 246 } | 231 } |
| 247 } | 232 } |
| 248 | 233 |
| 249 WASM_EXEC_TEST(F32x4Add) { RunF32x4BinOpTest(kExprF32x4Add, Add); } | 234 WASM_EXEC_TEST(F32x4Add) { RunF32x4BinOpTest(kExprF32x4Add, Add); } |
| 250 WASM_EXEC_TEST(F32x4Sub) { RunF32x4BinOpTest(kExprF32x4Sub, Sub); } | 235 WASM_EXEC_TEST(F32x4Sub) { RunF32x4BinOpTest(kExprF32x4Sub, Sub); } |
| 251 | 236 |
| 252 void RunF32x4CompareOpTest(WasmOpcode simd_op, FloatCompareOp expected_op) { | 237 void RunF32x4CompareOpTest(WasmOpcode simd_op, FloatCompareOp expected_op) { |
| 253 FLAG_wasm_simd_prototype = true; | 238 FLAG_wasm_simd_prototype = true; |
| 254 WasmRunner<int32_t, float, float, int32_t> r(kExecuteCompiled); | 239 WasmRunner<int32_t, float, float, int32_t> r(kExecuteCompiled); |
| 255 byte a = 0; | 240 byte a = 0; |
| 256 byte b = 1; | 241 byte b = 1; |
| 257 byte expected = 2; | 242 byte expected = 2; |
| 258 byte simd0 = r.AllocateLocal(kWasmS128); | 243 byte simd0 = r.AllocateLocal(kWasmS128); |
| 259 byte simd1 = r.AllocateLocal(kWasmS128); | 244 byte simd1 = r.AllocateLocal(kWasmS128); |
| 260 BUILD(r, WASM_BLOCK( | 245 BUILD(r, WASM_SET_LOCAL(simd0, WASM_SIMD_F32x4_SPLAT(WASM_GET_LOCAL(a))), |
| 261 WASM_SET_LOCAL(simd0, WASM_SIMD_F32x4_SPLAT(WASM_GET_LOCAL(a))), | 246 WASM_SET_LOCAL(simd1, WASM_SIMD_F32x4_SPLAT(WASM_GET_LOCAL(b))), |
| 262 WASM_SET_LOCAL(simd1, WASM_SIMD_F32x4_SPLAT(WASM_GET_LOCAL(b))), | 247 WASM_SET_LOCAL(simd1, |
| 263 WASM_SET_LOCAL(simd1, WASM_SIMD_BINOP(simd_op & 0xffu, | 248 WASM_SIMD_BINOP(simd_op & 0xffu, WASM_GET_LOCAL(simd0), |
| 264 WASM_GET_LOCAL(simd0), | 249 WASM_GET_LOCAL(simd1))), |
| 265 WASM_GET_LOCAL(simd1))), | 250 WASM_SIMD_CHECK_SPLAT4(I32x4, simd1, I32, expected), WASM_ONE); |
| 266 WASM_SIMD_CHECK_SPLAT4(I32x4, simd1, I32, expected), | |
| 267 WASM_RETURN1(WASM_ONE))); | |
| 268 | 251 |
| 269 FOR_FLOAT32_INPUTS(i) { | 252 FOR_FLOAT32_INPUTS(i) { |
| 270 if (std::isnan(*i)) continue; | 253 if (std::isnan(*i)) continue; |
| 271 FOR_FLOAT32_INPUTS(j) { | 254 FOR_FLOAT32_INPUTS(j) { |
| 272 if (std::isnan(*j)) continue; | 255 if (std::isnan(*j)) continue; |
| 273 // SIMD on some platforms may handle denormalized numbers differently. | 256 // SIMD on some platforms may handle denormalized numbers differently. |
| 274 // Check for number pairs that are very close together. | 257 // Check for number pairs that are very close together. |
| 275 if (std::fpclassify(*i - *j) == FP_SUBNORMAL) continue; | 258 if (std::fpclassify(*i - *j) == FP_SUBNORMAL) continue; |
| 276 CHECK_EQ(1, r.Call(*i, *j, expected_op(*i, *j))); | 259 CHECK_EQ(1, r.Call(*i, *j, expected_op(*i, *j))); |
| 277 } | 260 } |
| (...skipping 13 matching lines...) Expand all Loading... |
| 291 // | 274 // |
| 292 // SetLocal(1, I32x4Splat(Local(0))); | 275 // SetLocal(1, I32x4Splat(Local(0))); |
| 293 // For each lane index | 276 // For each lane index |
| 294 // if(Local(0) != I32x4ExtractLane(Local(1), index) | 277 // if(Local(0) != I32x4ExtractLane(Local(1), index) |
| 295 // return 0 | 278 // return 0 |
| 296 // | 279 // |
| 297 // return 1 | 280 // return 1 |
| 298 WasmRunner<int32_t, int32_t> r(kExecuteCompiled); | 281 WasmRunner<int32_t, int32_t> r(kExecuteCompiled); |
| 299 byte lane_val = 0; | 282 byte lane_val = 0; |
| 300 byte simd = r.AllocateLocal(kWasmS128); | 283 byte simd = r.AllocateLocal(kWasmS128); |
| 301 BUILD(r, WASM_BLOCK(WASM_SET_LOCAL(simd, WASM_SIMD_I32x4_SPLAT( | 284 BUILD(r, |
| 302 WASM_GET_LOCAL(lane_val))), | 285 WASM_SET_LOCAL(simd, WASM_SIMD_I32x4_SPLAT(WASM_GET_LOCAL(lane_val))), |
| 303 WASM_SIMD_CHECK_SPLAT4(I32x4, simd, I32, lane_val), | 286 WASM_SIMD_CHECK_SPLAT4(I32x4, simd, I32, lane_val), WASM_ONE); |
| 304 WASM_RETURN1(WASM_ONE))); | |
| 305 | 287 |
| 306 FOR_INT32_INPUTS(i) { CHECK_EQ(1, r.Call(*i)); } | 288 FOR_INT32_INPUTS(i) { CHECK_EQ(1, r.Call(*i)); } |
| 307 } | 289 } |
| 308 | 290 |
| 309 WASM_EXEC_TEST(I32x4ReplaceLane) { | 291 WASM_EXEC_TEST(I32x4ReplaceLane) { |
| 310 FLAG_wasm_simd_prototype = true; | 292 FLAG_wasm_simd_prototype = true; |
| 311 WasmRunner<int32_t, int32_t, int32_t> r(kExecuteCompiled); | 293 WasmRunner<int32_t, int32_t, int32_t> r(kExecuteCompiled); |
| 312 byte old_val = 0; | 294 byte old_val = 0; |
| 313 byte new_val = 1; | 295 byte new_val = 1; |
| 314 byte simd = r.AllocateLocal(kWasmS128); | 296 byte simd = r.AllocateLocal(kWasmS128); |
| 315 BUILD(r, WASM_BLOCK( | 297 BUILD(r, WASM_SET_LOCAL(simd, WASM_SIMD_I32x4_SPLAT(WASM_GET_LOCAL(old_val))), |
| 316 WASM_SET_LOCAL(simd, | 298 WASM_SET_LOCAL(simd, |
| 317 WASM_SIMD_I32x4_SPLAT(WASM_GET_LOCAL(old_val))), | 299 WASM_SIMD_I32x4_REPLACE_LANE(0, WASM_GET_LOCAL(simd), |
| 318 WASM_SET_LOCAL( | 300 WASM_GET_LOCAL(new_val))), |
| 319 simd, WASM_SIMD_I32x4_REPLACE_LANE(0, WASM_GET_LOCAL(simd), | 301 WASM_SIMD_CHECK4(I32x4, simd, I32, new_val, old_val, old_val, old_val), |
| 320 WASM_GET_LOCAL(new_val))), | 302 WASM_SET_LOCAL(simd, |
| 321 WASM_SIMD_CHECK4(I32x4, simd, I32, new_val, old_val, old_val, | 303 WASM_SIMD_I32x4_REPLACE_LANE(1, WASM_GET_LOCAL(simd), |
| 322 old_val), | 304 WASM_GET_LOCAL(new_val))), |
| 323 WASM_SET_LOCAL( | 305 WASM_SIMD_CHECK4(I32x4, simd, I32, new_val, new_val, old_val, old_val), |
| 324 simd, WASM_SIMD_I32x4_REPLACE_LANE(1, WASM_GET_LOCAL(simd), | 306 WASM_SET_LOCAL(simd, |
| 325 WASM_GET_LOCAL(new_val))), | 307 WASM_SIMD_I32x4_REPLACE_LANE(2, WASM_GET_LOCAL(simd), |
| 326 WASM_SIMD_CHECK4(I32x4, simd, I32, new_val, new_val, old_val, | 308 WASM_GET_LOCAL(new_val))), |
| 327 old_val), | 309 WASM_SIMD_CHECK4(I32x4, simd, I32, new_val, new_val, new_val, old_val), |
| 328 WASM_SET_LOCAL( | 310 WASM_SET_LOCAL(simd, |
| 329 simd, WASM_SIMD_I32x4_REPLACE_LANE(2, WASM_GET_LOCAL(simd), | 311 WASM_SIMD_I32x4_REPLACE_LANE(3, WASM_GET_LOCAL(simd), |
| 330 WASM_GET_LOCAL(new_val))), | 312 WASM_GET_LOCAL(new_val))), |
| 331 WASM_SIMD_CHECK4(I32x4, simd, I32, new_val, new_val, new_val, | 313 WASM_SIMD_CHECK_SPLAT4(I32x4, simd, I32, new_val), WASM_ONE); |
| 332 old_val), | |
| 333 WASM_SET_LOCAL( | |
| 334 simd, WASM_SIMD_I32x4_REPLACE_LANE(3, WASM_GET_LOCAL(simd), | |
| 335 WASM_GET_LOCAL(new_val))), | |
| 336 WASM_SIMD_CHECK_SPLAT4(I32x4, simd, I32, new_val), | |
| 337 WASM_RETURN1(WASM_ONE))); | |
| 338 | 314 |
| 339 CHECK_EQ(1, r.Call(1, 2)); | 315 CHECK_EQ(1, r.Call(1, 2)); |
| 340 } | 316 } |
| 341 | 317 |
| 342 #if V8_TARGET_ARCH_ARM | 318 #if V8_TARGET_ARCH_ARM |
| 343 | 319 |
| 344 // Determines if conversion from float to int will be valid. | 320 // Determines if conversion from float to int will be valid. |
| 345 bool CanRoundToZeroAndConvert(double val, bool unsigned_integer) { | 321 bool CanRoundToZeroAndConvert(double val, bool unsigned_integer) { |
| 346 const double max_uint = static_cast<double>(0xffffffffu); | 322 const double max_uint = static_cast<double>(0xffffffffu); |
| 347 const double max_int = static_cast<double>(kMaxInt); | 323 const double max_int = static_cast<double>(kMaxInt); |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 384 // Tests both signed and unsigned conversion. | 360 // Tests both signed and unsigned conversion. |
| 385 WASM_EXEC_TEST(I32x4FromFloat32x4) { | 361 WASM_EXEC_TEST(I32x4FromFloat32x4) { |
| 386 FLAG_wasm_simd_prototype = true; | 362 FLAG_wasm_simd_prototype = true; |
| 387 WasmRunner<int32_t, float, int32_t, int32_t> r(kExecuteCompiled); | 363 WasmRunner<int32_t, float, int32_t, int32_t> r(kExecuteCompiled); |
| 388 byte a = 0; | 364 byte a = 0; |
| 389 byte expected_signed = 1; | 365 byte expected_signed = 1; |
| 390 byte expected_unsigned = 2; | 366 byte expected_unsigned = 2; |
| 391 byte simd0 = r.AllocateLocal(kWasmS128); | 367 byte simd0 = r.AllocateLocal(kWasmS128); |
| 392 byte simd1 = r.AllocateLocal(kWasmS128); | 368 byte simd1 = r.AllocateLocal(kWasmS128); |
| 393 byte simd2 = r.AllocateLocal(kWasmS128); | 369 byte simd2 = r.AllocateLocal(kWasmS128); |
| 394 BUILD(r, WASM_BLOCK( | 370 BUILD( |
| 395 WASM_SET_LOCAL(simd0, WASM_SIMD_F32x4_SPLAT(WASM_GET_LOCAL(a))), | 371 r, WASM_SET_LOCAL(simd0, WASM_SIMD_F32x4_SPLAT(WASM_GET_LOCAL(a))), |
| 396 WASM_SET_LOCAL( | 372 WASM_SET_LOCAL(simd1, WASM_SIMD_I32x4_FROM_F32x4(WASM_GET_LOCAL(simd0))), |
| 397 simd1, WASM_SIMD_I32x4_FROM_F32x4(WASM_GET_LOCAL(simd0))), | 373 WASM_SIMD_CHECK_SPLAT4(I32x4, simd1, I32, expected_signed), |
| 398 WASM_SIMD_CHECK_SPLAT4(I32x4, simd1, I32, expected_signed), | 374 WASM_SET_LOCAL(simd2, WASM_SIMD_U32x4_FROM_F32x4(WASM_GET_LOCAL(simd0))), |
| 399 WASM_SET_LOCAL( | 375 WASM_SIMD_CHECK_SPLAT4(I32x4, simd2, I32, expected_unsigned), WASM_ONE); |
| 400 simd2, WASM_SIMD_U32x4_FROM_F32x4(WASM_GET_LOCAL(simd0))), | |
| 401 WASM_SIMD_CHECK_SPLAT4(I32x4, simd2, I32, expected_unsigned), | |
| 402 WASM_RETURN1(WASM_ONE))); | |
| 403 | 376 |
| 404 FOR_FLOAT32_INPUTS(i) { | 377 FOR_FLOAT32_INPUTS(i) { |
| 405 int32_t signed_value = ConvertToInt(*i, false); | 378 int32_t signed_value = ConvertToInt(*i, false); |
| 406 int32_t unsigned_value = ConvertToInt(*i, true); | 379 int32_t unsigned_value = ConvertToInt(*i, true); |
| 407 CHECK_EQ(1, r.Call(*i, signed_value, unsigned_value)); | 380 CHECK_EQ(1, r.Call(*i, signed_value, unsigned_value)); |
| 408 } | 381 } |
| 409 } | 382 } |
| 410 #endif // V8_TARGET_ARCH_ARM | 383 #endif // V8_TARGET_ARCH_ARM |
| 411 | 384 |
| 412 void RunI32x4BinOpTest(WasmOpcode simd_op, Int32BinOp expected_op) { | 385 void RunI32x4BinOpTest(WasmOpcode simd_op, Int32BinOp expected_op) { |
| 413 FLAG_wasm_simd_prototype = true; | 386 FLAG_wasm_simd_prototype = true; |
| 414 WasmRunner<int32_t, int32_t, int32_t, int32_t> r(kExecuteCompiled); | 387 WasmRunner<int32_t, int32_t, int32_t, int32_t> r(kExecuteCompiled); |
| 415 byte a = 0; | 388 byte a = 0; |
| 416 byte b = 1; | 389 byte b = 1; |
| 417 byte expected = 2; | 390 byte expected = 2; |
| 418 byte simd0 = r.AllocateLocal(kWasmS128); | 391 byte simd0 = r.AllocateLocal(kWasmS128); |
| 419 byte simd1 = r.AllocateLocal(kWasmS128); | 392 byte simd1 = r.AllocateLocal(kWasmS128); |
| 420 BUILD(r, WASM_BLOCK( | 393 BUILD(r, WASM_SET_LOCAL(simd0, WASM_SIMD_I32x4_SPLAT(WASM_GET_LOCAL(a))), |
| 421 WASM_SET_LOCAL(simd0, WASM_SIMD_I32x4_SPLAT(WASM_GET_LOCAL(a))), | 394 WASM_SET_LOCAL(simd1, WASM_SIMD_I32x4_SPLAT(WASM_GET_LOCAL(b))), |
| 422 WASM_SET_LOCAL(simd1, WASM_SIMD_I32x4_SPLAT(WASM_GET_LOCAL(b))), | 395 WASM_SET_LOCAL(simd1, |
| 423 WASM_SET_LOCAL(simd1, WASM_SIMD_BINOP(simd_op & 0xffu, | 396 WASM_SIMD_BINOP(simd_op & 0xffu, WASM_GET_LOCAL(simd0), |
| 424 WASM_GET_LOCAL(simd0), | 397 WASM_GET_LOCAL(simd1))), |
| 425 WASM_GET_LOCAL(simd1))), | 398 WASM_SIMD_CHECK_SPLAT4(I32x4, simd1, I32, expected), WASM_ONE); |
| 426 WASM_SIMD_CHECK_SPLAT4(I32x4, simd1, I32, expected), | |
| 427 WASM_RETURN1(WASM_ONE))); | |
| 428 | 399 |
| 429 FOR_INT32_INPUTS(i) { | 400 FOR_INT32_INPUTS(i) { |
| 430 FOR_INT32_INPUTS(j) { CHECK_EQ(1, r.Call(*i, *j, expected_op(*i, *j))); } | 401 FOR_INT32_INPUTS(j) { CHECK_EQ(1, r.Call(*i, *j, expected_op(*i, *j))); } |
| 431 } | 402 } |
| 432 } | 403 } |
| 433 | 404 |
| 434 WASM_EXEC_TEST(I32x4Add) { RunI32x4BinOpTest(kExprI32x4Add, Add); } | 405 WASM_EXEC_TEST(I32x4Add) { RunI32x4BinOpTest(kExprI32x4Add, Add); } |
| 435 | 406 |
| 436 WASM_EXEC_TEST(I32x4Sub) { RunI32x4BinOpTest(kExprI32x4Sub, Sub); } | 407 WASM_EXEC_TEST(I32x4Sub) { RunI32x4BinOpTest(kExprI32x4Sub, Sub); } |
| 437 | 408 |
| 438 #if V8_TARGET_ARCH_ARM | 409 #if V8_TARGET_ARCH_ARM |
| 439 WASM_EXEC_TEST(I32x4Equal) { RunI32x4BinOpTest(kExprI32x4Eq, Equal); } | 410 WASM_EXEC_TEST(I32x4Equal) { RunI32x4BinOpTest(kExprI32x4Eq, Equal); } |
| 440 | 411 |
| 441 WASM_EXEC_TEST(I32x4NotEqual) { RunI32x4BinOpTest(kExprI32x4Ne, NotEqual); } | 412 WASM_EXEC_TEST(I32x4NotEqual) { RunI32x4BinOpTest(kExprI32x4Ne, NotEqual); } |
| 442 #endif // V8_TARGET_ARCH_ARM | 413 #endif // V8_TARGET_ARCH_ARM |
| OLD | NEW |