ad-hack-extra.js (26792B)
1 // |jit-test| skip-if: !wasmSimdEnabled() 2 3 // Do not include this in the preamble, it must be loaded after lib/wasm.js 4 load(scriptdir + "ad-hack-preamble.js") 5 6 // Widening multiplication. 7 // This is to be moved into ad-hack.js 8 // 9 // (iMxN.extmul_{high,low}_iKxL_{s,u} A B) 10 // 11 // is equivalent to 12 // 13 // (iMxN.mul (iMxN.extend_{high,low}_iKxL_{s,u} A) 14 // (iMxN.extend_{high,low}_iKxL_{s,u} B)) 15 // 16 // It doesn't really matter what the inputs are, we can test this almost 17 // blindly. 18 // 19 // Unfortunately, we do not yet have i64x2.extend_* so we introduce a helper 20 // function to compute that. 21 22 function makeExtMulTest(wide, narrow, part, signed) { 23 let widener = (wide == 'i64x2') ? 24 `call $${wide}_extend_${part}_${narrow}_${signed}` : 25 `${wide}.extend_${part}_${narrow}_${signed}`; 26 return ` 27 (func (export "${wide}_extmul_${part}_${narrow}_${signed}") 28 (v128.store (i32.const 0) 29 (${wide}.extmul_${part}_${narrow}_${signed} (v128.load (i32.const 16)) 30 (v128.load (i32.const 32)))) 31 (v128.store (i32.const 48) 32 (${wide}.mul (${widener} (v128.load (i32.const 16))) 33 (${widener} (v128.load (i32.const 32)))))) 34 `; 35 } 36 37 var ins = wasmEvalText(` 38 (module 39 (memory (export "mem") 1 1) 40 (func $i64x2_extend_low_i32x4_s (param v128) (result v128) 41 (i64x2.shr_s (i8x16.shuffle 16 16 16 16 0 1 2 3 16 16 16 16 4 5 6 7 42 (local.get 0) 43 (v128.const i32x4 0 0 0 0)) 44 (i32.const 32))) 45 (func $i64x2_extend_high_i32x4_s (param v128) (result v128) 46 (i64x2.shr_s (i8x16.shuffle 16 16 16 16 8 9 10 11 16 16 16 16 12 13 14 15 47 (local.get 0) 48 (v128.const i32x4 0 0 0 0)) 49 (i32.const 32))) 50 (func $i64x2_extend_low_i32x4_u (param v128) (result v128) 51 (i8x16.shuffle 0 1 2 3 16 16 16 16 4 5 6 7 16 16 16 16 52 (local.get 0) 53 (v128.const i32x4 0 0 0 0))) 54 (func $i64x2_extend_high_i32x4_u (param v128) (result v128) 55 (i8x16.shuffle 8 9 10 11 16 16 16 16 12 13 14 15 16 16 16 16 56 (local.get 0) 57 (v128.const i32x4 0 0 0 0))) 58 ${makeExtMulTest('i64x2','i32x4','low','s')} 59 ${makeExtMulTest('i64x2','i32x4','high','s')} 60 ${makeExtMulTest('i64x2','i32x4','low','u')} 61 ${makeExtMulTest('i64x2','i32x4','high','u')} 62 ${makeExtMulTest('i32x4','i16x8','low','s')} 63 ${makeExtMulTest('i32x4','i16x8','high','s')} 64 ${makeExtMulTest('i32x4','i16x8','low','u')} 65 ${makeExtMulTest('i32x4','i16x8','high','u')} 66 ${makeExtMulTest('i16x8','i8x16','low','s')} 67 ${makeExtMulTest('i16x8','i8x16','high','s')} 68 ${makeExtMulTest('i16x8','i8x16','low','u')} 69 ${makeExtMulTest('i16x8','i8x16','high','u')})`); 70 71 for ( let [ WideArray, NarrowArray ] of 72 [ [ Int16Array, Int8Array ], 73 [ Int32Array, Int16Array ], 74 [ BigInt64Array, Int32Array ] ] ) { 75 let narrowMem = new NarrowArray(ins.exports.mem.buffer); 76 let narrowSrc0 = 16/NarrowArray.BYTES_PER_ELEMENT; 77 let narrowSrc1 = 32/NarrowArray.BYTES_PER_ELEMENT; 78 let wideMem = new WideArray(ins.exports.mem.buffer); 79 let wideElems = 16/WideArray.BYTES_PER_ELEMENT; 80 let wideRes0 = 0; 81 let wideRes1 = 48/WideArray.BYTES_PER_ELEMENT; 82 let zero = iota(wideElems).map(_ => 0); 83 for ( let part of [ 'low', 'high' ] ) { 84 for ( let signed of [ 's', 'u' ] ) { 85 for ( let [a, b] of cross(NarrowArray.inputs) ) { 86 set(wideMem, wideRes0, zero); 87 set(wideMem, wideRes1, zero); 88 set(narrowMem, narrowSrc0, a); 89 set(narrowMem, narrowSrc1, b); 90 let test = `${WideArray.layoutName}_extmul_${part}_${NarrowArray.layoutName}_${signed}`; 91 ins.exports[test](); 92 assertSame(get(wideMem, wideRes0, wideElems), 93 get(wideMem, wideRes1, wideElems)); 94 } 95 } 96 } 97 } 98 99 // Bitmask. Ion constant folds, so test that too. 100 // This is to be merged into the existing bitmask tests in ad-hack.js. 101 102 var ins = wasmEvalText(` 103 (module 104 (memory (export "mem") 1 1) 105 (func (export "bitmask_i64x2") (result i32) 106 (i64x2.bitmask (v128.load (i32.const 16)))) 107 (func (export "const_bitmask_i64x2") (result i32) 108 (i64x2.bitmask (v128.const i64x2 0xff337f8012345678 0x0001984212345678))))`); 109 110 var mem8 = new Uint8Array(ins.exports.mem.buffer); 111 var mem64 = new BigUint64Array(ins.exports.mem.buffer); 112 113 set(mem8, 16, iota(16).map((_) => 0)); 114 assertEq(ins.exports.bitmask_i64x2(), 0); 115 116 set(mem64, 2, [0x8000000000000000n, 0x8000000000000000n]); 117 assertEq(ins.exports.bitmask_i64x2(), 3); 118 119 set(mem64, 2, [0x7FFFFFFFFFFFFFFFn, 0x7FFFFFFFFFFFFFFFn]); 120 assertEq(ins.exports.bitmask_i64x2(), 0); 121 122 set(mem64, 2, [0n, 0x8000000000000000n]); 123 assertEq(ins.exports.bitmask_i64x2(), 2); 124 125 set(mem64, 2, [0x8000000000000000n, 0n]); 126 assertEq(ins.exports.bitmask_i64x2(), 1); 127 128 assertEq(ins.exports.const_bitmask_i64x2(), 1); 129 130 // Widen low/high. 131 // This is to be merged into the existing widening tests in ad-hack.js. 132 133 var ins = wasmEvalText(` 134 (module 135 (memory (export "mem") 1 1) 136 (func (export "extend_low_i32x4_s") 137 (v128.store (i32.const 0) (i64x2.extend_low_i32x4_s (v128.load (i32.const 16))))) 138 (func (export "extend_high_i32x4_s") 139 (v128.store (i32.const 0) (i64x2.extend_high_i32x4_s (v128.load (i32.const 16))))) 140 (func (export "extend_low_i32x4_u") 141 (v128.store (i32.const 0) (i64x2.extend_low_i32x4_u (v128.load (i32.const 16))))) 142 (func (export "extend_high_i32x4_u") 143 (v128.store (i32.const 0) (i64x2.extend_high_i32x4_u (v128.load (i32.const 16))))))`); 144 145 var mem32 = new Int32Array(ins.exports.mem.buffer); 146 var mem64 = new BigInt64Array(ins.exports.mem.buffer); 147 var mem64u = new BigUint64Array(ins.exports.mem.buffer); 148 149 var as = [205, 1, 192, 3].map((x) => x << 24); 150 set(mem32, 4, as); 151 152 ins.exports.extend_low_i32x4_s(); 153 assertSame(get(mem64, 0, 2), iota(2).map((n) => BigInt(as[n]))) 154 155 ins.exports.extend_high_i32x4_s(); 156 assertSame(get(mem64, 0, 2), iota(2).map((n) => BigInt(as[n+2]))); 157 158 ins.exports.extend_low_i32x4_u(); 159 assertSame(get(mem64u, 0, 2), iota(2).map((n) => BigInt(as[n] >>> 0))); 160 161 ins.exports.extend_high_i32x4_u(); 162 assertSame(get(mem64u, 0, 2), iota(2).map((n) => BigInt(as[n+2] >>> 0))); 163 164 // Saturating rounding q-format multiplication. 165 // This is to be moved into ad-hack.js 166 167 var ins = wasmEvalText(` 168 (module 169 (memory (export "mem") 1 1) 170 (func (export "q15mulr_sat_s") 171 (v128.store (i32.const 0) (i16x8.q15mulr_sat_s (v128.load (i32.const 16)) (v128.load (i32.const 32))))))`); 172 173 var mem16 = new Int16Array(ins.exports.mem.buffer); 174 for ( let [as, bs] of cross(Int16Array.inputs) ) { 175 set(mem16, 8, as); 176 set(mem16, 16, bs); 177 ins.exports.q15mulr_sat_s(); 178 assertSame(get(mem16, 0, 8), 179 iota(8).map((i) => signed_saturate((as[i] * bs[i] + 0x4000) >> 15, 16))); 180 } 181 182 183 // i64.all_true 184 185 var ins = wasmEvalText(` 186 (module 187 (memory (export "mem") 1 1) 188 (func (export "i64_all_true") (result i32) 189 (i64x2.all_true (v128.load (i32.const 16)) ) ) )`); 190 191 var mem32 = new Int32Array(ins.exports.mem.buffer); 192 193 set(mem32, 4, [0, 0, 0, 0]); 194 assertEq(0, ins.exports.i64_all_true()); 195 set(mem32, 4, [1, 0, 0, 0]); 196 assertEq(0, ins.exports.i64_all_true()); 197 set(mem32, 4, [1, 0, 0, 1]); 198 assertEq(1, ins.exports.i64_all_true()); 199 set(mem32, 4, [0, 0, 10, 0]); 200 assertEq(0, ins.exports.i64_all_true()); 201 set(mem32, 4, [0, -250, 1, 0]); 202 assertEq(1, ins.exports.i64_all_true()); 203 set(mem32, 4, [-1, -1, -1, -1]); 204 assertEq(1, ins.exports.i64_all_true()); 205 206 if (this.wasmSimdAnalysis && wasmCompileMode() == "ion") { 207 const positive = 208 wasmCompile( 209 `(module 210 (memory (export "mem") 1 1) 211 (func $f (param v128) (result i32) 212 (if (result i32) (i64x2.all_true (local.get 0)) 213 (then (i32.const 42)) 214 (else (i32.const 37)))) 215 (func (export "run") (result i32) 216 (call $f (v128.load (i32.const 16)))))`); 217 assertEq(wasmSimdAnalysis(), "simd128-to-scalar-and-branch -> folded"); 218 219 const negative = 220 wasmCompile( 221 `(module 222 (memory (export "mem") 1 1) 223 (func $f (param v128) (result i32) 224 (if (result i32) (i32.eqz (i64x2.all_true (local.get 0))) 225 (then (i32.const 42)) 226 (else (i32.const 37)))) 227 (func (export "run") (result i32) 228 (call $f (v128.load (i32.const 16)))))`); 229 assertEq(wasmSimdAnalysis(), "simd128-to-scalar-and-branch -> folded"); 230 231 for ( let inp of [[1n, 2n], [4n, 0n], [0n, 0n]]) { 232 const all_true = inp.every(v => v != 0n) 233 let mem = new BigInt64Array(positive.exports.mem.buffer); 234 set(mem, 2, inp); 235 assertEq(positive.exports.run(), all_true ? 42 : 37); 236 237 mem = new BigInt64Array(negative.exports.mem.buffer); 238 set(mem, 2, inp); 239 assertEq(negative.exports.run(), all_true ? 37 : 42); 240 } 241 242 wasmCompile(`(module (func (result i32) (i64x2.all_true (v128.const i64x2 0 0))))`); 243 assertEq(wasmSimdAnalysis(), "simd128-to-scalar -> constant folded"); 244 } 245 246 247 // i64x2.eq and i64x2.ne 248 249 var ins = wasmEvalText(` 250 (module 251 (memory (export "mem") 1 1) 252 (func (export "i64_eq") 253 (v128.store (i32.const 0) 254 (i64x2.eq (v128.load (i32.const 16)) (v128.load (i32.const 32))) )) 255 (func (export "i64_ne") 256 (v128.store (i32.const 0) 257 (i64x2.ne (v128.load (i32.const 16)) (v128.load (i32.const 32))) )) )`); 258 259 var mem64 = new BigInt64Array(ins.exports.mem.buffer); 260 261 set(mem64, 2, [0n, 1n, 0n, 1n]); 262 ins.exports.i64_eq(); 263 assertSame(get(mem64, 0, 2), [-1n, -1n]); 264 ins.exports.i64_ne(); 265 assertSame(get(mem64, 0, 2), [0n, 0n]); 266 set(mem64, 2, [0x0n, -1n, 0x100000000n, -1n]); 267 ins.exports.i64_eq(); 268 assertSame(get(mem64, 0, 2), [0n, -1n]); 269 set(mem64, 2, [-1n, 0x0n, -1n, 0x100000000n]); 270 ins.exports.i64_ne(); 271 assertSame(get(mem64, 0, 2), [0n, -1n]); 272 273 274 // i64x2.lt, i64x2.gt, i64x2.le, and i64.ge 275 276 var ins = wasmEvalText(` 277 (module 278 (memory (export "mem") 1 1) 279 (func (export "i64_lt_s") 280 (v128.store (i32.const 0) 281 (i64x2.lt_s (v128.load (i32.const 16)) (v128.load (i32.const 32))) )) 282 (func (export "i64_gt_s") 283 (v128.store (i32.const 0) 284 (i64x2.gt_s (v128.load (i32.const 16)) (v128.load (i32.const 32))) )) 285 (func (export "i64_le_s") 286 (v128.store (i32.const 0) 287 (i64x2.le_s (v128.load (i32.const 16)) (v128.load (i32.const 32))) )) 288 (func (export "i64_ge_s") 289 (v128.store (i32.const 0) 290 (i64x2.ge_s (v128.load (i32.const 16)) (v128.load (i32.const 32))) )) )`); 291 292 var mem64 = new BigInt64Array(ins.exports.mem.buffer); 293 294 set(mem64, 2, [0n, 1n, 1n, 0n]); 295 ins.exports.i64_lt_s(); 296 assertSame(get(mem64, 0, 2), [-1n, 0n]); 297 ins.exports.i64_gt_s(); 298 assertSame(get(mem64, 0, 2), [0n, -1n]); 299 ins.exports.i64_le_s(); 300 assertSame(get(mem64, 0, 2), [-1n, 0n]); 301 ins.exports.i64_ge_s(); 302 assertSame(get(mem64, 0, 2), [0n, -1n]); 303 304 set(mem64, 2, [0n, -1n, -1n, 0n]); 305 ins.exports.i64_lt_s(); 306 assertSame(get(mem64, 0, 2), [0n, -1n]); 307 ins.exports.i64_gt_s(); 308 assertSame(get(mem64, 0, 2), [-1n, 0n]); 309 ins.exports.i64_le_s(); 310 assertSame(get(mem64, 0, 2), [0n, -1n]); 311 ins.exports.i64_ge_s(); 312 assertSame(get(mem64, 0, 2), [-1n, 0n]); 313 314 set(mem64, 2, [-2n, 2n, -1n, 1n]); 315 ins.exports.i64_lt_s(); 316 assertSame(get(mem64, 0, 2), [-1n, 0n]); 317 ins.exports.i64_gt_s(); 318 assertSame(get(mem64, 0, 2), [0n, -1n]); 319 ins.exports.i64_le_s(); 320 assertSame(get(mem64, 0, 2), [-1n, 0n]); 321 ins.exports.i64_ge_s(); 322 assertSame(get(mem64, 0, 2), [0n, -1n]); 323 324 set(mem64, 2, [-2n, 1n, -2n, 1n]); 325 ins.exports.i64_lt_s(); 326 assertSame(get(mem64, 0, 2), [0n, 0n]); 327 ins.exports.i64_gt_s(); 328 assertSame(get(mem64, 0, 2), [0n, 0n]); 329 ins.exports.i64_le_s(); 330 assertSame(get(mem64, 0, 2), [-1n, -1n]); 331 ins.exports.i64_ge_s(); 332 assertSame(get(mem64, 0, 2), [-1n, -1n]); 333 334 335 function wasmCompile(text) { 336 return new WebAssembly.Instance(new WebAssembly.Module(wasmTextToBinary(text))) 337 } 338 339 340 // i64x2.abs 341 342 var ins = wasmEvalText(` 343 (module 344 (memory (export "mem") 1 1) 345 (func (export "i64_abs") 346 (v128.store (i32.const 0) 347 (i64x2.abs (v128.load (i32.const 16))) )) )`); 348 349 var mem64 = new BigInt64Array(ins.exports.mem.buffer); 350 351 set(mem64, 2, [-3n, 42n]); 352 ins.exports.i64_abs(); 353 assertSame(get(mem64, 0, 2), [3n, 42n]); 354 set(mem64, 2, [0n, -0x8000000000000000n]); 355 ins.exports.i64_abs(); 356 assertSame(get(mem64, 0, 2), [0n, -0x8000000000000000n]); 357 358 359 // Load lane 360 361 var ins = wasmEvalText(` 362 (module 363 (memory (export "mem") 1 1) 364 ${iota(16).map(i => `(func (export "load8_lane_${i}") (param i32) 365 (v128.store (i32.const 0) 366 (v128.load8_lane offset=0 ${i} (local.get 0) (v128.load (i32.const 16))))) 367 `).join('')} 368 ${iota(8).map(i => `(func (export "load16_lane_${i}") (param i32) 369 (v128.store (i32.const 0) 370 (v128.load16_lane offset=0 ${i} (local.get 0) (v128.load (i32.const 16))))) 371 `).join('')} 372 ${iota(4).map(i => `(func (export "load32_lane_${i}") (param i32) 373 (v128.store (i32.const 0) 374 (v128.load32_lane offset=0 ${i} (local.get 0) (v128.load (i32.const 16))))) 375 `).join('')} 376 ${iota(2).map(i => `(func (export "load64_lane_${i}") (param i32) 377 (v128.store (i32.const 0) 378 (v128.load64_lane offset=0 ${i} (local.get 0) (v128.load (i32.const 16))))) 379 `).join('')} 380 (func (export "load_lane_const_and_align") 381 (v128.store (i32.const 0) 382 (v128.load64_lane offset=32 1 (i32.const 1) 383 (v128.load32_lane offset=32 1 (i32.const 3) 384 (v128.load16_lane offset=32 0 (i32.const 5) 385 (v128.load (i32.const 16))))) 386 )) 387 )`); 388 389 var mem8 = new Int8Array(ins.exports.mem.buffer); 390 var mem32 = new Int32Array(ins.exports.mem.buffer); 391 var mem64 = new BigInt64Array(ins.exports.mem.buffer); 392 393 var as = [0x12345678, 0x23456789, 0x3456789A, 0x456789AB]; 394 set(mem32, 4, as); set(mem8, 32, [0xC2]); 395 396 ins.exports["load8_lane_0"](32); 397 assertSame(get(mem32, 0, 4), [0x123456C2, 0x23456789, 0x3456789A, 0x456789AB]); 398 ins.exports["load8_lane_1"](32); 399 assertSame(get(mem32, 0, 4), [0x1234C278, 0x23456789, 0x3456789A, 0x456789AB]); 400 ins.exports["load8_lane_2"](32); 401 assertSame(get(mem32, 0, 4), [0x12C25678, 0x23456789, 0x3456789A, 0x456789AB]); 402 ins.exports["load8_lane_3"](32); 403 assertSame(get(mem32, 0, 4), [0xC2345678|0, 0x23456789, 0x3456789A, 0x456789AB]); 404 ins.exports["load8_lane_4"](32); 405 assertSame(get(mem32, 0, 4), [0x12345678, 0x234567C2, 0x3456789A, 0x456789AB]); 406 ins.exports["load8_lane_6"](32); 407 assertSame(get(mem32, 0, 4), [0x12345678, 0x23C26789, 0x3456789A, 0x456789AB]); 408 ins.exports["load8_lane_9"](32); 409 assertSame(get(mem32, 0, 4), [0x12345678, 0x23456789, 0x3456C29A, 0x456789AB]); 410 ins.exports["load8_lane_14"](32); 411 assertSame(get(mem32, 0, 4), [0x12345678, 0x23456789, 0x3456789A, 0x45C289AB]); 412 413 set(mem8, 32, [0xC2, 0xD1]); 414 415 ins.exports["load16_lane_0"](32); 416 assertSame(get(mem32, 0, 4), [0x1234D1C2, 0x23456789, 0x3456789A, 0x456789AB]); 417 ins.exports["load16_lane_1"](32); 418 assertSame(get(mem32, 0, 4), [0xD1C25678|0, 0x23456789, 0x3456789A, 0x456789AB]); 419 ins.exports["load16_lane_2"](32); 420 assertSame(get(mem32, 0, 4), [0x12345678, 0x2345D1C2, 0x3456789A, 0x456789AB]); 421 ins.exports["load16_lane_5"](32); 422 assertSame(get(mem32, 0, 4), [0x12345678, 0x23456789, 0xD1C2789A|0, 0x456789AB]); 423 ins.exports["load16_lane_7"](32); 424 assertSame(get(mem32, 0, 4), [0x12345678, 0x23456789, 0x3456789A, 0xD1C289AB|0]); 425 426 set(mem32, 8, [0x16B5C3D0]); 427 428 ins.exports["load32_lane_0"](32); 429 assertSame(get(mem32, 0, 4), [0x16B5C3D0, 0x23456789, 0x3456789A, 0x456789AB]); 430 ins.exports["load32_lane_1"](32); 431 assertSame(get(mem32, 0, 4), [0x12345678, 0x16B5C3D0, 0x3456789A, 0x456789AB]); 432 ins.exports["load32_lane_2"](32); 433 assertSame(get(mem32, 0, 4), [0x12345678, 0x23456789, 0x16B5C3D0, 0x456789AB]); 434 ins.exports["load32_lane_3"](32); 435 assertSame(get(mem32, 0, 4), [0x12345678, 0x23456789, 0x3456789A, 0x16B5C3D0]); 436 437 set(mem64, 4, [0x3300AA4416B5C3D0n]); 438 439 ins.exports["load64_lane_0"](32); 440 assertSame(get(mem64, 0, 2), [0x3300AA4416B5C3D0n, 0x456789AB3456789An]); 441 ins.exports["load64_lane_1"](32); 442 assertSame(get(mem64, 0, 2), [0x2345678912345678n, 0x3300AA4416B5C3D0n]); 443 444 // .. (mis)align load lane 445 446 var as = [0x12345678, 0x23456789, 0x3456789A, 0x456789AB]; 447 set(mem32, 4, as); set(mem64, 4, [0x3300AA4416B5C3D0n, 0x300AA4416B5C3D03n]); 448 449 ins.exports["load16_lane_5"](33); 450 assertSame(get(mem32, 0, 4), [0x12345678,0x23456789,0xb5c3789a|0,0x456789ab]); 451 ins.exports["load32_lane_1"](34); 452 assertSame(get(mem32, 0, 4), [0x12345678, 0xaa4416b5|0,0x3456789a,0x456789ab]); 453 ins.exports["load64_lane_0"](35); 454 assertSame(get(mem64, 0, 2), [0x5c3d033300aa4416n, 0x456789ab3456789an]); 455 456 ins.exports["load_lane_const_and_align"](); 457 assertSame(get(mem32, 0, 4), [0x123400aa,0x00AA4416,0x4416b5c3,0x033300aa]); 458 459 // Store lane 460 461 var ins = wasmEvalText(` 462 (module 463 (memory (export "mem") 1 1) 464 ${iota(16).map(i => `(func (export "store8_lane_${i}") (param i32) (param i32) 465 (v128.store8_lane ${i} (local.get 1) (v128.load (local.get 0)))) 466 `).join('')} 467 ${iota(8).map(i => `(func (export "store16_lane_${i}") (param i32) (param i32) 468 (v128.store16_lane ${i} (local.get 1) (v128.load (local.get 0)))) 469 `).join('')} 470 ${iota(4).map(i => `(func (export "store32_lane_${i}") (param i32) (param i32) 471 (v128.store32_lane ${i} (local.get 1) (v128.load (local.get 0)))) 472 `).join('')} 473 ${iota(2).map(i => `(func (export "store64_lane_${i}") (param i32) (param i32) 474 (v128.store64_lane ${i} (local.get 1) (v128.load (local.get 0)))) 475 `).join('')} 476 (func (export "store_lane_const_and_align") 477 (v128.store16_lane 1 (i32.const 33) (v128.load (i32.const 16))) 478 (v128.store32_lane 2 (i32.const 37) (v128.load (i32.const 16))) 479 (v128.store64_lane 0 (i32.const 47) (v128.load (i32.const 16))) 480 ))`); 481 482 483 var mem8 = new Int8Array(ins.exports.mem.buffer); 484 var mem32 = new Int32Array(ins.exports.mem.buffer); 485 var mem64 = new BigInt64Array(ins.exports.mem.buffer); 486 487 var as = [0x12345678, 0x23456789, 0x3456789A, 0x456789AB]; 488 set(mem32, 4, as); set(mem32, 0, [0x7799AA00, 42, 3, 0]); 489 490 ins.exports["store8_lane_0"](16, 0); assertSame(get(mem32, 0, 1), [0x7799AA78]); 491 ins.exports["store8_lane_1"](16, 0); assertSame(get(mem32, 0, 1), [0x7799AA56]); 492 ins.exports["store8_lane_2"](16, 0); assertSame(get(mem32, 0, 1), [0x7799AA34]); 493 ins.exports["store8_lane_3"](16, 0); assertSame(get(mem32, 0, 1), [0x7799AA12]); 494 ins.exports["store8_lane_5"](16, 0); assertSame(get(mem32, 0, 1), [0x7799AA67]); 495 ins.exports["store8_lane_7"](16, 0); assertSame(get(mem32, 0, 1), [0x7799AA23]); 496 ins.exports["store8_lane_8"](16, 0); assertSame(get(mem32, 0, 1), [0x7799AA9A]); 497 ins.exports["store8_lane_15"](16, 0); assertSame(get(mem32, 0, 1), [0x7799AA45]); 498 499 ins.exports["store16_lane_0"](16, 0); assertSame(get(mem32, 0, 1), [0x77995678]); 500 ins.exports["store16_lane_1"](16, 0); assertSame(get(mem32, 0, 1), [0x77991234]); 501 ins.exports["store16_lane_2"](16, 0); assertSame(get(mem32, 0, 1), [0x77996789]); 502 ins.exports["store16_lane_5"](16, 0); assertSame(get(mem32, 0, 1), [0x77993456]); 503 ins.exports["store16_lane_7"](16, 0); assertSame(get(mem32, 0, 1), [0x77994567]); 504 505 ins.exports["store32_lane_0"](16, 0); assertSame(get(mem32, 0, 2), [0x12345678, 42]); 506 ins.exports["store32_lane_1"](16, 0); assertSame(get(mem32, 0, 2), [0x23456789, 42]); 507 ins.exports["store32_lane_2"](16, 0); assertSame(get(mem32, 0, 2), [0x3456789A, 42]); 508 ins.exports["store32_lane_3"](16, 0); assertSame(get(mem32, 0, 2), [0x456789AB, 42]); 509 510 ins.exports["store64_lane_0"](16, 0); assertSame(get(mem64, 0, 2), [0x2345678912345678n, 3]); 511 ins.exports["store64_lane_1"](16, 0); assertSame(get(mem64, 0, 2), [0x456789AB3456789An, 3]); 512 513 // .. (mis)align store lane 514 515 var as = [0x12345678, 0x23456789, 0x3456789A, 0x456789AB]; 516 set(mem32, 4, as); set(mem32, 0, [0x7799AA01, 42, 3, 0]); 517 ins.exports["store16_lane_1"](16, 1); assertSame(get(mem32, 0, 2), [0x77123401, 42]); 518 set(mem32, 0, [0x7799AA01, 42, 3, 0]); 519 ins.exports["store32_lane_1"](16, 2); assertSame(get(mem32, 0, 2), [0x6789AA01, 0x2345]); 520 set(mem32, 0, [0x7799AA01, 42, 5, 3]); 521 ins.exports["store64_lane_0"](16, 1); 522 assertSame(get(mem64, 0, 2), [0x4567891234567801n, 0x0300000023]); 523 524 set(mem32, 4, [ 525 0x12345678, 0x23456789, 0x3456789A, 0x456789AB, 526 0x55AA55AA, 0xCC44CC44, 0x55AA55AA, 0xCC44CC44, 527 0x55AA55AA, 0xCC44CC44, 0x55AA55AA, 0xCC44CC44, 528 ]); 529 ins.exports["store_lane_const_and_align"](); 530 assertSame(get(mem32, 8, 8), [ 531 0x551234aa, 0x56789a44, 0x55aa5534, 0x7844cc44, 532 0x89123456|0, 0xcc234567|0, 0x55aa55aa, 0xcc44cc44|0, 533 ]); 534 535 536 // i8x16.popcnt 537 538 var ins = wasmEvalText(` 539 (module 540 (memory (export "mem") 1 1) 541 (func (export "i8x16_popcnt") 542 (v128.store (i32.const 0) (i8x16.popcnt (v128.load (i32.const 16)) ))) 543 )`); 544 545 var mem8 = new Int8Array(ins.exports.mem.buffer); 546 547 set(mem8, 16, [0, 1, 2, 4, 8, 0x10, 0x20, 0x40, 0x80, 3, -1, 0xF0, 0x11, 0xFE, 0x0F, 0xE]); 548 ins.exports.i8x16_popcnt(); 549 assertSame(get(mem8, 0, 16), [0,1,1,1,1,1,1,1,1,2,8,4,2,7,4,3]); 550 551 552 /// Double-precision conversion instructions. 553 /// f64x2.convert_low_i32x4_{u,s} / i32x4.trunc_sat_f64x2_{u,s}_zero 554 /// f32x4.demote_f64x2_zero / f64x2.promote_low_f32x4 555 556 var ins = wasmEvalText(` 557 (module 558 (memory (export "mem") 1 1) 559 (func (export "f64x2_convert_low_i32x4_s") 560 (v128.store (i32.const 0) (f64x2.convert_low_i32x4_s (v128.load (i32.const 16)) ))) 561 (func (export "f64x2_convert_low_i32x4_u") 562 (v128.store (i32.const 0) (f64x2.convert_low_i32x4_u (v128.load (i32.const 16)) ))) 563 564 (func (export "i32x4_trunc_sat_f64x2_s_zero") 565 (v128.store (i32.const 0) (i32x4.trunc_sat_f64x2_s_zero (v128.load (i32.const 16)) ))) 566 (func (export "i32x4_trunc_sat_f64x2_u_zero") 567 (v128.store (i32.const 0) (i32x4.trunc_sat_f64x2_u_zero (v128.load (i32.const 16)) ))) 568 569 (func (export "f32x4_demote_f64x2") 570 (v128.store (i32.const 0) (f32x4.demote_f64x2_zero (v128.load (i32.const 16)) ))) 571 (func (export "f64x2_protomote_f32x4") 572 (v128.store (i32.const 0) (f64x2.promote_low_f32x4 (v128.load (i32.const 16)) ))) 573 )`); 574 575 var mem32 = new Int32Array(ins.exports.mem.buffer); 576 var memU32 = new Uint32Array(ins.exports.mem.buffer); 577 var memF32 = new Float32Array(ins.exports.mem.buffer); 578 var memF64 = new Float64Array(ins.exports.mem.buffer); 579 580 // f64x2.convert_low_i32x4_u / f64x2.convert_low_i32x4_s 581 582 set(mem32, 4, [1, -2, 0, -2]); 583 ins.exports.f64x2_convert_low_i32x4_s(); 584 assertSame(get(memF64, 0, 2), [1, -2]); 585 set(mem32, 4, [-1, 0, 5, -212312312]); 586 ins.exports.f64x2_convert_low_i32x4_s(); 587 assertSame(get(memF64, 0, 2), [-1, 0]); 588 589 set(memU32, 4, [1, 4045646797, 4, 0]); 590 ins.exports.f64x2_convert_low_i32x4_u(); 591 assertSame(get(memF64, 0, 2), [1, 4045646797]); 592 set(memU32, 4, [0, 2, 4, 3]); 593 ins.exports.f64x2_convert_low_i32x4_u(); 594 assertSame(get(memF64, 0, 2), [0, 2]); 595 596 // i32x4.trunc_sat_f64x2_u_zero / i32x4.trunc_sat_f64x2_s_zero 597 598 set(memF64, 2, [0,0]) 599 ins.exports.i32x4_trunc_sat_f64x2_s_zero(); 600 assertSame(get(mem32, 0, 4), [0,0,0,0]); 601 ins.exports.i32x4_trunc_sat_f64x2_u_zero(); 602 assertSame(get(memU32, 0, 4), [0,0,0,0]); 603 604 set(memF64, 2, [-1.23,65535.12]) 605 ins.exports.i32x4_trunc_sat_f64x2_s_zero(); 606 assertSame(get(mem32, 0, 4), [-1,65535,0,0]); 607 set(memF64, 2, [1.99,65535.12]) 608 ins.exports.i32x4_trunc_sat_f64x2_u_zero(); 609 assertSame(get(memU32, 0, 4), [1,65535,0,0]); 610 611 set(memF64, 2, [10e+100,-10e+100]) 612 ins.exports.i32x4_trunc_sat_f64x2_s_zero(); 613 assertSame(get(mem32, 0, 4), [0x7fffffff,-0x80000000,0,0]); 614 ins.exports.i32x4_trunc_sat_f64x2_u_zero(); 615 assertSame(get(memU32, 0, 4), [0xffffffff,0,0,0]); 616 617 // f32x4.demote_f64x2_zero 618 619 set(memF64, 2, [1, 2]) 620 ins.exports.f32x4_demote_f64x2(); 621 assertSame(get(memF32, 0, 4), [1,2,0,0]); 622 623 set(memF64, 2, [-4e38, 4e38]) 624 ins.exports.f32x4_demote_f64x2(); 625 assertSame(get(memF32, 0, 4), [-Infinity,Infinity,0,0]); 626 627 set(memF64, 2, [-1e-46, 1e-46]) 628 ins.exports.f32x4_demote_f64x2(); 629 assertSame(get(memF32, 0, 4), [1/-Infinity,0,0,0]); 630 631 set(memF64, 2, [0, NaN]) 632 ins.exports.f32x4_demote_f64x2(); 633 assertSame(get(memF32, 0, 4), [0, NaN,0,0]); 634 635 set(memF64, 2, [Infinity, -Infinity]) 636 ins.exports.f32x4_demote_f64x2(); 637 assertSame(get(memF32, 0, 4), [Infinity, -Infinity,0,0]); 638 639 // f64x2.promote_low_f32x4 640 641 set(memF32, 4, [4, 3, 1, 2]) 642 ins.exports.f64x2_protomote_f32x4(); 643 assertSame(get(memF64, 0, 2), [4, 3]); 644 645 set(memF32, 4, [NaN, 0, 0, 0]) 646 ins.exports.f64x2_protomote_f32x4(); 647 assertSame(get(memF64, 0, 2), [NaN, 0]); 648 649 set(memF32, 4, [Infinity, -Infinity, 0, 0]) 650 ins.exports.f64x2_protomote_f32x4(); 651 assertSame(get(memF64, 0, 2), [Infinity, -Infinity]); 652 653 654 // i16x8.extadd_pairwise_i8x16_{s,u} / i32x4.extadd_pairwise_i16x8_{s,u} 655 656 var ins = wasmEvalText(` 657 (module 658 (memory (export "mem") 1 1) 659 (func (export "i16x8_extadd_pairwise_i8x16_s") 660 (v128.store (i32.const 0) (i16x8.extadd_pairwise_i8x16_s (v128.load (i32.const 16)) ))) 661 (func (export "i16x8_extadd_pairwise_i8x16_u") 662 (v128.store (i32.const 0) (i16x8.extadd_pairwise_i8x16_u (v128.load (i32.const 16)) ))) 663 664 (func (export "i32x4_extadd_pairwise_i16x8_s") 665 (v128.store (i32.const 0) (i32x4.extadd_pairwise_i16x8_s (v128.load (i32.const 16)) ))) 666 (func (export "i32x4_extadd_pairwise_i16x8_u") 667 (v128.store (i32.const 0) (i32x4.extadd_pairwise_i16x8_u (v128.load (i32.const 16)) ))) 668 )`); 669 670 var mem8 = new Int8Array(ins.exports.mem.buffer); 671 var memU8 = new Uint8Array(ins.exports.mem.buffer); 672 var mem16 = new Int16Array(ins.exports.mem.buffer); 673 var memU16 = new Uint16Array(ins.exports.mem.buffer); 674 var mem32 = new Int32Array(ins.exports.mem.buffer); 675 var memU32 = new Uint32Array(ins.exports.mem.buffer); 676 677 set(mem8, 16, [0, 0, 1, 1, 2, -2, 0, 42, 1, -101, 101, -1, 127, 125, -1, -2]); 678 ins.exports.i16x8_extadd_pairwise_i8x16_s(); 679 assertSame(get(mem16, 0, 8), [0, 2, 0, 42, -100, 100, 252, -3]); 680 681 set(memU8, 16, [0, 0, 1, 1, 2, 255, 0, 42, 0, 255, 254, 0, 127, 125, 255, 255]); 682 ins.exports.i16x8_extadd_pairwise_i8x16_u(); 683 assertSame(get(memU16, 0, 8), [0, 2, 257, 42, 255, 254, 252, 510]); 684 685 set(mem16, 8, [0, 0, 1, 1, 2, -2, -1, -2]); 686 ins.exports.i32x4_extadd_pairwise_i16x8_s(); 687 assertSame(get(mem32, 0, 4), [0, 2, 0, -3]); 688 set(mem16, 8, [0, 42, 1, -32760, 32766, -1, 32761, 32762]); 689 ins.exports.i32x4_extadd_pairwise_i16x8_s(); 690 assertSame(get(mem32, 0, 4), [42, -32759, 32765, 65523]); 691 692 set(memU16, 8, [0, 0, 1, 1, 2, 65535, 65535, 65535]); 693 ins.exports.i32x4_extadd_pairwise_i16x8_u(); 694 assertSame(get(memU32, 0, 4), [0, 2, 65537, 131070]); 695 set(memU16, 8, [0, 42, 0, 65535, 65534, 0, 32768, 32765]); 696 ins.exports.i32x4_extadd_pairwise_i16x8_u(); 697 assertSame(get(memU32, 0, 4), [42, 65535, 65534, 65533]);