tor-browser

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

const-arm64-vixl-codegen.js (3298B)


      1 // |jit-test| skip-if: !wasmSimdEnabled() || !hasDisassembler() || wasmCompileMode() != "baseline" || !getBuildConfiguration("arm64")
      2 
      3 // Test that the vixl logic for v128 constant loads is at least somewhat
      4 // reasonable.
      5 
      6 var lead = `0x[0-9a-f]+ +[0-9a-f]{8} +`;
      7 
      8 var prefix = `${lead}sub     sp, sp, #0x.. \\(..\\)
      9 ${lead}str     x23, \\[sp, #..\\]`;
     10 
     11 var suffix =
     12 `${lead}b       #\\+0x18 \\(addr 0x.*\\)
     13 ${lead}brk     #0xf000`;
     14 
     15 for ( let [bits, expected, values] of [
     16    // If high == low and the byte is 0 or ff then a single movi is sufficient.
     17    ['i8x16 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00', `
     18 ${prefix}
     19 ${lead}movi    v0\\.2d, #0x0
     20 ${suffix}
     21 `,
     22     [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]],
     23 
     24    ['i8x16 -1 0 -1 0 -1 0 -1 0 -1 0 -1 0 -1 0 -1 0', `
     25 ${prefix}
     26 ${lead}movi    v0\\.2d, #0xff00ff00ff00ff
     27 ${suffix}
     28 `,
     29     [-1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0]],
     30 
     31    // Splattable small things (up to a byte, at a byte location)
     32    // can also use just one instruction
     33    ['i32x4 1 1 1 1', `
     34 ${prefix}
     35 ${lead}movi    v0\\.4s, #0x1, lsl #0
     36 ${suffix}
     37 `,
     38     [1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0]],
     39 
     40    ['i32x4 0x300 0x300 0x300 0x300', `
     41 ${prefix}
     42 ${lead}movi    v0\\.4s, #0x3, lsl #8
     43 ${suffix}
     44 `,
     45     [0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0]],
     46 
     47    // If high == low but the value is more complex then a constant load
     48    // plus a dup is sufficient.  x16 is the designated temp.
     49    ['i32x4 1 2 1 2', `
     50 ${prefix}
     51 ${lead}mov     x16, #0x1
     52 ${lead}movk    x16, #0x2, lsl #32
     53 ${lead}dup     v0\\.2d, x16
     54 ${suffix}
     55 `,
     56     [1, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0]],
     57 
     58    // If high != low then we degenerate to a more complicated pattern: dup the low value
     59    // and then overwrite the high part with the high value.
     60    ['i32x4 1 2 2 1', `
     61 ${prefix}
     62 ${lead}mov     x16, #0x1
     63 ${lead}movk    x16, #0x2, lsl #32
     64 ${lead}dup     v0\\.2d, x16
     65 ${lead}mov     x16, #0x2
     66 ${lead}movk    x16, #0x1, lsl #32
     67 ${lead}mov     v0\\.d\\[1\\], x16
     68 ${suffix}
     69 `,
     70     [1, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0]],
     71 
     72    // Things are not always bleak, and vixl finds a way.
     73    ['i32x4 1 1 2 2', `
     74 ${prefix}
     75 ${lead}movi    v0\\.4s, #0x1, lsl #0
     76 ${lead}mov     x16, #0x200000002
     77 ${lead}mov     v0\\.d\\[1\\], x16
     78 ${suffix}
     79 `,
     80     [1, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0]],
     81 ] ) {
     82    let ins = wasmEvalText(`
     83  (module
     84    (memory (export "mem") 1)
     85    (func (export "run")
     86       (v128.store (i32.const 0) (call $f)))
     87    (func $f (export "f") (result v128)
     88      (v128.const ${bits})))`);
     89    let output = wasmDis(ins.exports.f, {tier:"baseline", asString:true});
     90    let pass = output.match(new RegExp(expected)) != null;
     91    if (!pass) {
     92        // Debugging output in case of failure.
     93        console.log("expected:\n", expected,
     94                    "\n\noutput:\n", output);
     95    }
     96    assertEq(pass, true);
     97    let mem = new Int8Array(ins.exports.mem.buffer);
     98    set(mem, 0, iota(16).map(x => -1-x));
     99    ins.exports.run();
    100    assertSame(get(mem, 0, 16), values);
    101 }
    102 
    103 function get(arr, loc, len) {
    104    let res = [];
    105    for ( let i=0; i < len; i++ ) {
    106        res.push(arr[loc+i]);
    107    }
    108    return res;
    109 }
    110 
    111 function set(arr, loc, vals) {
    112    for ( let i=0; i < vals.length; i++ ) {
    113        arr[loc+i] = vals[i];
    114    }
    115 }