tor-browser

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

ion-adhoc-multiplatform.js (17771B)


      1 // |jit-test| skip-if: !hasDisassembler() || wasmCompileMode() != "ion" || getBuildConfiguration("windows") || (!getBuildConfiguration("x64") && !getBuildConfiguration("x86") && !getBuildConfiguration("arm64") && !getBuildConfiguration("arm")); include:adhoc-multiplatform-test.js
      2 //
      3 // These tests push wasm functions through the ion pipe and specify an expected
      4 // disassembly output on all 4 primary targets, x64 / x86 / arm64 / arm(32).
      5 // Results must be provided for the first 3, but can optionally be skipped
      6 // for arm(32).
      7 //
      8 // Hence: disassembler is needed, compiler must be ion.
      9 //
     10 // Windows is disallowed because the argument registers are different from on
     11 // Linux, and matching both is both difficult and not of much value.
     12 
     13 // Tests are "end-to-end" in the sense that we don't care whether the
     14 // tested-for code improvement is done by MIR optimisation, or later in the
     15 // pipe.  Observed defects are marked with FIXMEs for future easy finding.
     16 
     17 
     18 // Note that identities involving AND, OR and XOR are tested by
     19 // binop-x64-ion-folding.js
     20 
     21 // Multiplication with magic constant on the left
     22 //
     23 //    0 * x =>  0
     24 //    1 * x =>  x
     25 //   -1 * x =>  -x
     26 //    2 * x =>  x + x
     27 //    4 * x =>  x << 2
     28 
     29 codegenTestMultiplatform_adhoc(
     30    `(module (func (export "mul32_zeroL") (param $p1 i32) (result i32)
     31       (i32.mul (i32.const 0) (local.get $p1))))`,
     32    "mul32_zeroL",
     33    {x64:   `xor %eax, %eax`,
     34     x86:   `xor %eax, %eax`,
     35     arm64: `mov w0, wzr`,
     36     arm:   `mov r0, #0`},
     37    {x86: {no_prefix:true}}
     38 );
     39 codegenTestMultiplatform_adhoc(
     40    `(module (func (export "mul64_zeroL") (param $p1 i64) (result i64)
     41       (i64.mul (i64.const 0) (local.get $p1))))`,
     42    "mul64_zeroL",
     43    // FIXME zero-creation insns could be improved
     44    {x64:   `xor %rax, %rax`,     // REX.W is redundant
     45     x86:   `xor %eax, %eax
     46             xor %edx, %edx`,
     47     arm64: `mov x0, xzr`,
     48     arm:   `mov r0, #0
     49             mov r1, #0` },
     50    {x86: {no_prefix:true}}
     51 );
     52 
     53 codegenTestMultiplatform_adhoc(
     54    `(module (func (export "mul32_oneL") (param $p1 i32) (result i32)
     55       (i32.mul (i32.const 1) (local.get $p1))))`,
     56    "mul32_oneL",
     57    {x64:   // We move edi to eax unnecessarily via ecx (bug 1752520).
     58            // Presumably because the folding 1 * x => x is done at the LIR
     59            // level, not the MIR level, hence the now-pointless WasmParameter
     60            // node is not DCE'd away, since DCE only happens at the MIR level.
     61            // In fact all targets suffer from the latter problem, but on x86
     62            // no_prefix_x86:true hides it, and on arm32/64 the pointless move
     63            // is correctly transformed by RA into a no-op.
     64            `mov %edi, %ecx
     65             mov %ecx, %eax`,
     66     x86:   `movl 0x10\\(%rbp\\), %eax`,
     67     arm64: ``,
     68     arm:   ``},
     69    {x86: {no_prefix:true}}
     70 );
     71 codegenTestMultiplatform_adhoc(
     72    `(module (func (export "mul64_oneL") (param $p1 i64) (result i64)
     73       (i64.mul (i64.const 1) (local.get $p1))))`,
     74    "mul64_oneL",
     75    {x64:   `mov %rdi, %rcx
     76             mov %rcx, %rax`,
     77     x86:   `movl 0x14\\(%rbp\\), %edx
     78             movl 0x10\\(%rbp\\), %eax`,
     79     arm64: ``,
     80     arm:   ``},
     81    {x86: {no_prefix:true}}
     82 );
     83 
     84 codegenTestMultiplatform_adhoc(
     85    `(module (func (export "mul32_minusOneL") (param $p1 i32) (result i32)
     86       (i32.mul (i32.const -1) (local.get $p1))))`,
     87    "mul32_minusOneL",
     88    {x64:   `neg %eax`,
     89     x86:   `neg %eax`,
     90     arm64: `neg w0, w0`,
     91     arm:   `rsb r0, r0, #0`},
     92    {x86: {no_prefix:true}, x64: {no_prefix:true}}
     93 );
     94 codegenTestMultiplatform_adhoc(
     95    `(module (func (export "mul64_minusOneL") (param $p1 i64) (result i64)
     96       (i64.mul (i64.const -1) (local.get $p1))))`,
     97    "mul64_minusOneL",
     98    {x64:   `mov %rdi, %rcx
     99             mov %rcx, %rax
    100             neg %rax`,
    101     x86:   `neg %eax
    102             adc \\$0x00, %edx
    103             neg %edx`,
    104     arm64: `neg  x0, x0`,
    105     arm:   `rsbs r0, r0, #0
    106             rsc  r1, r1, #0`},
    107    {x86: {no_prefix:true}}
    108 );
    109 
    110 codegenTestMultiplatform_adhoc(
    111    `(module (func (export "mul32_twoL") (param $p1 i32) (result i32)
    112       (i32.mul (i32.const 2) (local.get $p1))))`,
    113    "mul32_twoL",
    114    {x64:   `lea \\(%rdi,%rdi,1\\), %eax`,
    115     x86:   `movl 0x10\\(%rbp\\), %eax
    116             add %eax, %eax`,
    117     arm64: `add w0, w0, w0`,
    118     arm:   `adds r0, r0, r0`},
    119    {x86: {no_prefix:true}}
    120 );
    121 codegenTestMultiplatform_adhoc(
    122    `(module (func (export "mul64_twoL") (param $p1 i64) (result i64)
    123       (i64.mul (i64.const 2) (local.get $p1))))`,
    124    "mul64_twoL",
    125    {x64:   `lea \\(%rdi,%rdi,1\\), %rax`,
    126     x86:   `movl 0x14\\(%rbp\\), %edx
    127             movl 0x10\\(%rbp\\), %eax
    128             add %eax, %eax
    129             adc %edx, %edx`,
    130     arm64: `add  x0, x0, x0`,
    131     arm:   `adds r0, r0, r0
    132             adc  r1, r1, r1`},
    133    {x86: {no_prefix:true}}
    134 );
    135 
    136 codegenTestMultiplatform_adhoc(
    137    `(module (func (export "mul32_fourL") (param $p1 i32) (result i32)
    138       (i32.mul (i32.const 4) (local.get $p1))))`,
    139    "mul32_fourL",
    140    {x64:   `lea \\(,%rdi,4\\), %eax`,
    141     x86:   `movl 0x10\\(%rbp\\), %eax
    142             shl \\$0x02, %eax`,
    143     arm64: `lsl w0, w0, #2`,
    144     arm:   `mov r0, r0, lsl #2`},
    145    {x86: {no_prefix:true}}
    146 );
    147 codegenTestMultiplatform_adhoc(
    148    `(module (func (export "mul64_fourL") (param $p1 i64) (result i64)
    149       (i64.mul (i64.const 4) (local.get $p1))))`,
    150    "mul64_fourL",
    151    {x64:   `lea \\(,%rdi,4\\), %rax`,
    152     x86:   `movl 0x14\\(%rbp\\), %edx
    153             movl 0x10\\(%rbp\\), %eax
    154             shld \\$0x02, %eax, %edx
    155             shl \\$0x02, %eax`,
    156     arm64: `lsl x0, x0, #2`,
    157     arm:   `mov r1, r1, lsl #2
    158             orr r1, r1, r0, lsr #30
    159             mov r0, r0, lsl #2`},
    160    {x86: {no_prefix:true}}
    161 );
    162 
    163 // Multiplication with magic constant on the right
    164 //
    165 //  x * 0  =>  0
    166 //  x * 1  =>  x
    167 //  x * -1 =>  -x
    168 //  x * 2  =>  x + x
    169 //  x * 4  =>  x << 2
    170 
    171 codegenTestMultiplatform_adhoc(
    172    `(module (func (export "mul32_zeroR") (param $p1 i32) (result i32)
    173       (i32.mul (local.get $p1) (i32.const 0))))`,
    174    "mul32_zeroR",
    175    {x64:   `xor %eax, %eax`,
    176     x86:   `xor %eax, %eax`,
    177     arm64: `mov w0, wzr`,
    178     arm:   `mov r0, #0`},
    179    {x86: {no_prefix:true}}
    180 );
    181 codegenTestMultiplatform_adhoc(
    182    `(module (func (export "mul64_zeroR") (param $p1 i64) (result i64)
    183       (i64.mul (local.get $p1) (i64.const 0))))`,
    184    "mul64_zeroR",
    185    {x64:   `xor %rax, %rax`,     // REX.W is redundant
    186     x86:   `xor %eax, %eax
    187             xor %edx, %edx`,
    188     arm64: `mov x0, xzr`,
    189     arm:   `mov r0, #0
    190             mov r1, #0` },
    191    {x86: {no_prefix:true}}
    192 );
    193 
    194 codegenTestMultiplatform_adhoc(
    195    `(module (func (export "mul32_oneR") (param $p1 i32) (result i32)
    196       (i32.mul (local.get $p1) (i32.const 1))))`,
    197    "mul32_oneR",
    198    {x64:   `mov %edi, %ecx
    199             mov %ecx, %eax`,
    200     x86:   `movl 0x10\\(%rbp\\), %eax`,
    201     arm64: ``,
    202     arm:   ``},
    203    {x86: {no_prefix:true}}
    204 );
    205 codegenTestMultiplatform_adhoc(
    206    `(module (func (export "mul64_oneR") (param $p1 i64) (result i64)
    207       (i64.mul (local.get $p1) (i64.const 1))))`,
    208    "mul64_oneR",
    209    {x64:   `mov %rdi, %rcx
    210             mov %rcx, %rax`,
    211     x86:   `movl 0x14\\(%rbp\\), %edx
    212             movl 0x10\\(%rbp\\), %eax`,
    213     arm64: ``,
    214     arm:   ``},
    215    {x86: {no_prefix:true}}
    216 );
    217 
    218 codegenTestMultiplatform_adhoc(
    219    `(module (func (export "mul32_minusOneR") (param $p1 i32) (result i32)
    220       (i32.mul (local.get $p1) (i32.const -1))))`,
    221    "mul32_minusOneR",
    222    {x64:   `neg %eax`,
    223     x86:   `neg %eax`,
    224     arm64: `neg w0, w0`,
    225     arm:   `rsb r0, r0, #0`},
    226    {x86: {no_prefix:true}, x64: {no_prefix:true}}
    227 );
    228 codegenTestMultiplatform_adhoc(
    229    `(module (func (export "mul64_minusOneR") (param $p1 i64) (result i64)
    230       (i64.mul (local.get $p1) (i64.const -1))))`,
    231    "mul64_minusOneR",
    232    {x64:   `mov %rdi, %rcx
    233             mov %rcx, %rax
    234             neg %rax`,
    235     x86:   `neg %eax
    236             adc \\$0x00, %edx
    237             neg %edx`,
    238     arm64: `neg  x0, x0`,
    239     arm:   `rsbs r0, r0, #0
    240             rsc  r1, r1, #0`},
    241    {x86: {no_prefix:true}}
    242 );
    243 
    244 codegenTestMultiplatform_adhoc(
    245    `(module (func (export "mul32_twoR") (param $p1 i32) (result i32)
    246       (i32.mul (local.get $p1) (i32.const 2))))`,
    247    "mul32_twoR",
    248    {x64:   `lea \\(%rdi,%rdi,1\\), %eax`,
    249     x86:   `movl 0x10\\(%rbp\\), %eax
    250             add %eax, %eax`,
    251     arm64: `add w0, w0, w0`,
    252     arm:   `adds r0, r0, r0`},
    253    {x86: {no_prefix:true}}
    254 );
    255 codegenTestMultiplatform_adhoc(
    256    `(module (func (export "mul64_twoR") (param $p1 i64) (result i64)
    257       (i64.mul (local.get $p1) (i64.const 2))))`,
    258    "mul64_twoR",
    259    {x64:   `lea \\(%rdi,%rdi,1\\), %rax`,
    260     x86:   `movl 0x14\\(%rbp\\), %edx
    261             movl 0x10\\(%rbp\\), %eax
    262             add %eax, %eax
    263             adc %edx, %edx`,
    264     arm64: `add  x0, x0, x0`,
    265     arm:   `adds r0, r0, r0
    266             adc  r1, r1, r1`},
    267    {x86: {no_prefix:true}}
    268 );
    269 
    270 codegenTestMultiplatform_adhoc(
    271    `(module (func (export "mul32_fourR") (param $p1 i32) (result i32)
    272       (i32.mul (local.get $p1) (i32.const 4))))`,
    273    "mul32_fourR",
    274    {x64:   `lea \\(,%rdi,4\\), %eax`,
    275     x86:   `movl 0x10\\(%rbp\\), %eax
    276             shl \\$0x02, %eax`,
    277     arm64: `lsl w0, w0, #2`,
    278     arm:   `mov r0, r0, lsl #2`},
    279    {x86: {no_prefix:true}}
    280 );
    281 codegenTestMultiplatform_adhoc(
    282    `(module (func (export "mul64_fourR") (param $p1 i64) (result i64)
    283       (i64.mul (local.get $p1) (i64.const 4))))`,
    284    "mul64_fourR",
    285    {x64:   `lea \\(,%rdi,4\\), %rax`,
    286     x86:   `movl 0x14\\(%rbp\\), %edx
    287             movl 0x10\\(%rbp\\), %eax
    288             shld \\$0x02, %eax, %edx
    289             shl \\$0x02, %eax`,
    290     arm64: `lsl x0, x0, #2`,
    291     arm:   `mov r1, r1, lsl #2
    292             orr r1, r1, r0, lsr #30
    293             mov r0, r0, lsl #2`
    294    },
    295    {x86: {no_prefix:true}}
    296 );
    297 
    298 // Shifts by zero (the right arg is zero)
    299 //
    300 // x >> 0  =>  x  (any shift kind: shl, shrU, shrS)
    301 
    302 codegenTestMultiplatform_adhoc(
    303    `(module (func (export "shl32_zeroR") (param $p1 i32) (result i32)
    304       (i32.shl (local.get $p1) (i32.const 0))))`,
    305    "shl32_zeroR",
    306    // FIXME check these are consistently folded out at the MIR level
    307    {x64:   `mov %edi, %ecx
    308             mov %ecx, %eax`,
    309     x86:   `movl 0x10\\(%rbp\\), %eax`,
    310     arm64: `mov w0, w0`,
    311     arm:   `` // no-op 
    312    },
    313    {x86: {no_prefix:true}}
    314 );
    315 codegenTestMultiplatform_adhoc(
    316    `(module (func (export "shl64_zeroR") (param $p1 i64) (result i64)
    317       (i64.shl (local.get $p1) (i64.const 0))))`,
    318    "shl64_zeroR",
    319    // FIXME why is this code so much better than the 32-bit case?
    320    {x64:   `mov %rdi, %rcx
    321             mov %rcx, %rax`,
    322     x86:   `movl 0x14\\(%rbp\\), %edx
    323             movl 0x10\\(%rbp\\), %eax`,
    324     arm64: ``, // no-op
    325     arm:   ``  // no-op
    326    },
    327    {x86: {no_prefix:true}}
    328 );
    329 
    330 codegenTestMultiplatform_adhoc(
    331    `(module (func (export "shrU32_zeroR") (param $p1 i32) (result i32)
    332       (i32.shr_u (local.get $p1) (i32.const 0))))`,
    333    "shrU32_zeroR",
    334    {x64:   `mov %edi, %ecx
    335             mov %ecx, %eax`,
    336     x86:   `movl 0x10\\(%rbp\\), %eax`,
    337     arm64: `mov w0, w0`,
    338     arm:   ``
    339    },
    340    {x86: {no_prefix:true}}
    341 );
    342 codegenTestMultiplatform_adhoc(
    343    `(module (func (export "shrU64_zeroR") (param $p1 i64) (result i64)
    344       (i64.shr_u (local.get $p1) (i64.const 0))))`,
    345    "shrU64_zeroR",
    346    {x64:   `mov %rdi, %rcx
    347             mov %rcx, %rax`,
    348     x86:   `movl 0x14\\(%rbp\\), %edx
    349             movl 0x10\\(%rbp\\), %eax`,
    350     arm64: ``,
    351     arm:   ``
    352    },
    353    {x86: {no_prefix:true}}
    354 );
    355 
    356 codegenTestMultiplatform_adhoc(
    357    `(module (func (export "shrS32_zeroR") (param $p1 i32) (result i32)
    358       (i32.shr_s (local.get $p1) (i32.const 0))))`,
    359    "shrS32_zeroR",
    360    {x64:   `mov %edi, %ecx
    361             mov %ecx, %eax`,
    362     x86:   `movl 0x10\\(%rbp\\), %eax`,
    363     arm64: `mov w0, w0`,
    364     arm:   ``
    365    },
    366    {x86: {no_prefix:true}}
    367 );
    368 codegenTestMultiplatform_adhoc(
    369    `(module (func (export "shrS64_zeroR") (param $p1 i64) (result i64)
    370       (i64.shr_s (local.get $p1) (i64.const 0))))`,
    371    "shrS64_zeroR",
    372    {x64:   `mov %rdi, %rcx
    373             mov %rcx, %rax`,
    374     x86:   `movl 0x14\\(%rbp\\), %edx
    375             movl 0x10\\(%rbp\\), %eax`,
    376     arm64: ``,
    377     arm:   ``
    378    },
    379    {x86: {no_prefix:true}}
    380 );
    381 
    382 // Identities involving addition
    383 //
    384 //  x + 0   =>  x
    385 //  0 + x   =>  x
    386 //  x + x   =>  x << 1
    387 
    388 codegenTestMultiplatform_adhoc(
    389    `(module (func (export "add32_zeroR") (param $p1 i32) (result i32)
    390       (i32.add (local.get $p1) (i32.const 0))))`,
    391    "add32_zeroR",
    392    {x64:   `mov %edi, %ecx
    393             mov %ecx, %eax`,
    394     x86:   `movl 0x10\\(%rbp\\), %eax`,
    395     arm64: ``,
    396     arm:   ``
    397    },
    398    {x86: {no_prefix:true}}
    399 );
    400 codegenTestMultiplatform_adhoc(
    401    `(module (func (export "add64_zeroR") (param $p1 i64) (result i64)
    402       (i64.add (local.get $p1) (i64.const 0))))`,
    403    "add64_zeroR",
    404    {x64:   `mov %rdi, %rcx
    405             mov %rcx, %rax`,
    406     x86:   `movl 0x14\\(%rbp\\), %edx
    407             movl 0x10\\(%rbp\\), %eax`,
    408     arm64: ``,
    409     arm:   ``
    410    },
    411    {x86: {no_prefix:true}}
    412 );
    413 
    414 codegenTestMultiplatform_adhoc(
    415    `(module (func (export "add32_zeroL") (param $p1 i32) (result i32)
    416       (i32.add (i32.const 0) (local.get $p1))))`,
    417    "add32_zeroL",
    418    {x64:   `mov %edi, %ecx
    419             mov %ecx, %eax`,
    420     x86:   `movl 0x10\\(%rbp\\), %eax`,
    421     arm64: ``,
    422     arm:   ``
    423    },
    424    {x86: {no_prefix:true}}
    425 );
    426 codegenTestMultiplatform_adhoc(
    427    `(module (func (export "add64_zeroL") (param $p1 i64) (result i64)
    428       (i64.add (i64.const 0) (local.get $p1))))`,
    429    "add64_zeroL",
    430    {x64:   `mov %rdi, %rcx
    431             mov %rcx, %rax`,
    432     x86:   `movl 0x14\\(%rbp\\), %edx
    433             movl 0x10\\(%rbp\\), %eax`,
    434     arm64: ``,
    435     arm:   ``
    436    },
    437    {x86: {no_prefix:true}}
    438 );
    439 
    440 codegenTestMultiplatform_adhoc(
    441    `(module (func (export "add32_self") (param $p1 i32) (result i32)
    442       (i32.add (local.get $p1) (local.get $p1))))`,
    443    "add32_self",
    444    {x64:   `mov  %edi, %ecx
    445             mov  %ecx, %eax
    446             add  %ecx, %eax`,
    447     x86:   `movl 0x10\\(%rbp\\), %eax
    448             addl 0x10\\(%rbp\\), %eax`,
    449     arm64: `add  w0, w0, w0`,
    450     arm:   `adds r0, r0, r0 `
    451    },
    452    {x86: {no_prefix:true}}
    453 );
    454 codegenTestMultiplatform_adhoc(
    455    `(module (func (export "add64_self") (param $p1 i64) (result i64)
    456       (i64.add (local.get $p1) (local.get $p1))))`,
    457    "add64_self",
    458    // FIXME outstandingly bad 32-bit sequences, probably due to the RA
    459    {x64:   `mov %rdi, %rcx
    460             mov %rcx, %rax
    461             add %rcx, %rax`,
    462     x86:   // -0x21524111 is 0xDEADBEEF
    463            `movl 0x14\\(%rbp\\), %ebx
    464             movl 0x10\\(%rbp\\), %ecx
    465             mov \\$-0x21524111, %edi
    466             movl 0x14\\(%rbp\\), %edx
    467             movl 0x10\\(%rbp\\), %eax
    468             add %ecx, %eax
    469             adc %ebx, %edx`,
    470     arm64: `add  x0, x0, x0`,
    471     arm:   // play Musical Chairs for a while
    472            `mov  r3, r1
    473             mov  r2, r0
    474             mov  r5, r3
    475             mov  r4, r2
    476             mov  r1, r3
    477             mov  r0, r2
    478             adds r0, r0, r4
    479             adc  r1, r1, r5`
    480    },
    481    {x86: {no_prefix:true}}
    482 );
    483 
    484 // Identities involving subtraction
    485 //
    486 //  x - 0   =>  x
    487 //  0 - x   =>  -x
    488 //  x - x   =>  0
    489 
    490 codegenTestMultiplatform_adhoc(
    491    `(module (func (export "sub32_zeroR") (param $p1 i32) (result i32)
    492       (i32.sub (local.get $p1) (i32.const 0))))`,
    493    "sub32_zeroR",
    494    {x64:   `mov %edi, %ecx
    495             mov %ecx, %eax`,
    496     x86:   `movl 0x10\\(%rbp\\), %eax`,
    497     arm64: ``,
    498     arm:   ``
    499    },
    500    {x86: {no_prefix:true}}
    501 );
    502 codegenTestMultiplatform_adhoc(
    503    `(module (func (export "sub64_zeroR") (param $p1 i64) (result i64)
    504       (i64.sub (local.get $p1) (i64.const 0))))`,
    505    "sub64_zeroR",
    506    {x64:   `mov %rdi, %rcx
    507             mov %rcx, %rax`,
    508     x86:   `movl 0x14\\(%rbp\\), %edx
    509             movl 0x10\\(%rbp\\), %eax`,
    510     arm64: ``,
    511     arm:   ``
    512    },
    513    {x86: {no_prefix:true}}
    514 );
    515 
    516 codegenTestMultiplatform_adhoc(
    517    `(module (func (export "sub32_zeroL") (param $p1 i32) (result i32)
    518       (i32.sub (i32.const 0) (local.get $p1))))`,
    519    "sub32_zeroL",
    520    {x64:   `mov %edi, %ecx
    521             mov %ecx, %eax
    522             neg %eax`,
    523     x86:   `movl 0x10\\(%rbp\\), %eax
    524             neg %eax`,
    525     arm64: `neg w0, w0 `,
    526     arm:   `rsb r0, r0, #0`
    527    },
    528    {x86: {no_prefix:true}}
    529 );
    530 codegenTestMultiplatform_adhoc(
    531    `(module (func (export "sub64_zeroL") (param $p1 i64) (result i64)
    532       (i64.sub (i64.const 0) (local.get $p1))))`,
    533    "sub64_zeroL",
    534    {x64:   `mov %rdi, %rcx
    535             mov %rcx, %rax
    536             neg %rax`,
    537     x86:   `movl 0x14\\(%rbp\\), %edx
    538             movl 0x10\\(%rbp\\), %eax
    539             neg %eax
    540             adc \\$0x00, %edx
    541             neg %edx`,
    542     arm64: `neg  x0, x0`,
    543     arm:   `rsbs r0, r0, #0
    544             rsc  r1, r1, #0`
    545    },
    546    {x86: {no_prefix:true}}
    547 );
    548 
    549 codegenTestMultiplatform_adhoc(
    550    `(module (func (export "sub32_self") (param $p1 i32) (result i32)
    551       (i32.sub (local.get $p1) (local.get $p1))))`,
    552    "sub32_self",
    553    {x64:   `xor %eax, %eax`,
    554     x86:   `xor %eax, %eax`,
    555     arm64: `mov w0, #0x0`,
    556     arm:   `mov r0, #0`
    557    },
    558    {x86: {no_prefix:true}}
    559 );
    560 codegenTestMultiplatform_adhoc(
    561    `(module (func (export "sub64_self") (param $p1 i64) (result i64)
    562       (i64.sub (local.get $p1) (local.get $p1))))`,
    563    "sub64_self",
    564    {x64:   `xor %eax, %eax`,
    565     x86:   `xor %eax, %eax
    566             xor %edx, %edx`,
    567     arm64: `mov x0, #0x0`,
    568     arm:   `mov r0, #0
    569             mov r1, #0`
    570    },
    571    {x86: {no_prefix:true}}
    572 );