tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

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 }