ad-hack-simple-unops.js (4476B)
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 // Simple unary operators. Place parameter in memory at offset 16, 7 // read the result at offset 0. 8 9 function expandConstantUnopInputs(op, memtype, inputs) { 10 let s = ''; 11 let ident = 0; 12 for ( let a of inputs ) { 13 let constval = `${memtype.layoutName} ${a.map(jsValueToWasmName).join(' ')}`; 14 s += ` 15 (func (export "run_const${ident}") 16 (v128.store (i32.const 0) 17 (${op} (v128.const ${constval})))) 18 `; 19 ident++; 20 } 21 return s; 22 } 23 24 function insAndMemUnop(op, memtype, resultmemtype, inputs) { 25 var ins = wasmEvalText(` 26 (module 27 (memory (export "mem") 1 1) 28 29 (func (export "run") 30 (v128.store (i32.const 0) 31 (call $doit (v128.load (i32.const 16))))) 32 33 (func $doit (param $a v128) (result v128) 34 (${op} (local.get $a))) 35 36 ${expandConstantUnopInputs(op, memtype, inputs)})`); 37 var mem = new memtype(ins.exports.mem.buffer); 38 var resultmem = !resultmemtype || memtype == resultmemtype ? mem : new resultmemtype(ins.exports.mem.buffer); 39 return [ins, mem, resultmem]; 40 } 41 42 function ineg(bits) { return (a) => sign_extend(!a ? a : -a,bits) } 43 function iabs(bits) { return (a) => zero_extend(a < 0 ? -a : a, bits) } 44 function fneg(a) { return -a } 45 function fabs(a) { return Math.abs(a) } 46 function fsqrt(a) { return Math.fround(Math.sqrt(Math.fround(a))) } 47 function dsqrt(a) { return Math.sqrt(a) } 48 function bitnot(a) { return (~a) & 255 } 49 function ffloor(x) { return Math.fround(Math.floor(x)) } 50 function fceil(x) { return Math.fround(Math.ceil(x)) } 51 function ftrunc(x) { return Math.fround(Math.sign(x)*Math.floor(Math.abs(x))) } 52 function fnearest(x) { return Math.fround(Math.round(x)) } 53 function dfloor(x) { return Math.floor(x) } 54 function dceil(x) { return Math.ceil(x) } 55 function dtrunc(x) { return Math.sign(x)*Math.floor(Math.abs(x)) } 56 function dnearest(x) { return Math.round(x) } 57 58 for ( let [op, memtype, rop, resultmemtype] of 59 [['i8x16.neg', Int8Array, ineg(8)], 60 ['i16x8.neg', Int16Array, ineg(16)], 61 ['i32x4.neg', Int32Array, ineg(32)], 62 ['i64x2.neg', BigInt64Array, ineg(64)], 63 ['i8x16.abs', Int8Array, iabs(8), Uint8Array], 64 ['i16x8.abs', Int16Array, iabs(16), Uint16Array], 65 ['i32x4.abs', Int32Array, iabs(32), Uint32Array], 66 ['f32x4.neg', Float32Array, fneg], 67 ['f64x2.neg', Float64Array, fneg], 68 ['f32x4.abs', Float32Array, fabs], 69 ['f64x2.abs', Float64Array, fabs], 70 ['f32x4.sqrt', Float32Array, fsqrt], 71 ['f64x2.sqrt', Float64Array, dsqrt], 72 ['f32x4.ceil', Float32Array, fceil], 73 ['f32x4.floor', Float32Array, ffloor], 74 ['f32x4.trunc', Float32Array, ftrunc], 75 ['f32x4.nearest', Float32Array, fnearest], 76 ['f64x2.ceil', Float64Array, dceil], 77 ['f64x2.floor', Float64Array, dfloor], 78 ['f64x2.trunc', Float64Array, dtrunc], 79 ['f64x2.nearest', Float64Array, dnearest], 80 ['v128.not', Uint8Array, bitnot], 81 ]) 82 { 83 let [ins, mem, resultmem] = insAndMemUnop(op, memtype, resultmemtype, memtype.inputs); 84 let len = 16/memtype.BYTES_PER_ELEMENT; 85 let xs = iota(len); 86 let zero = xs.map(_ => 0); 87 let bitsForF32 = memtype == Float32Array ? new Uint32Array(mem.buffer) : null; 88 let bitsForF64 = memtype == Float64Array ? new BigInt64Array(mem.buffer) : null; 89 90 function testIt(a, r) { 91 set(mem, len, a); 92 ins.exports.run(); 93 assertSame(get(resultmem, 0, len), r); 94 95 // Test signalling NaN superficially by replacing QNaN inputs with SNaN 96 if (bitsForF32 != null && a.some(isNaN)) { 97 a.forEach((x, i) => { if (isNaN(x)) { bitsForF32[len+i] = 0x7FA0_0000; } }); 98 ins.exports.run(); 99 assertSame(get(resultmem, 0, len), r); 100 } 101 if (bitsForF64 != null && a.some(isNaN)) { 102 a.forEach((x, i) => { if (isNaN(x)) { bitsForF64[len+i] = 0x7FF4_0000_0000_0000n; } }); 103 ins.exports.run(); 104 assertSame(get(resultmem, 0, len), r); 105 } 106 } 107 108 function testConstIt(i,r) { 109 set(resultmem, 0, zero); 110 ins.exports["run_const" + i](); 111 assertSame(get(resultmem, 0, len), r); 112 } 113 114 let i = 0; 115 for (let a of memtype.inputs) { 116 let r = xs.map((i) => rop(a[i])); 117 testIt(a, r); 118 testConstIt(i, r); 119 i++; 120 } 121 }