summaryrefslogtreecommitdiffstats
path: root/js/src/jit-test/tests/wasm/simd/pmaddubsw-x64-ion-codegen.js
blob: 17125e3dc3b2c2eee8feb37b6fe35a48f94a9aad (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
// |jit-test| skip-if: !wasmSimdEnabled() || wasmCompileMode() != "ion"

// Testing _mm_maddubs_epi16 / vpmaddubsw behavoir for all platforms.
//
// Bug 1762413 adds specialization for emscripten's pattern to directly
// emit PMADDUBSW machine code.

const isX64 = getBuildConfiguration("x64") && !getBuildConfiguration("simulator");

// Simple test.
const simple = wasmTextToBinary(`(module 
  (memory (export "memory") 1 1)
  (func $_mm_maddubs_epi16 (export "t") (param v128 v128) (result v128)
    local.get 1
    i32.const 8
    i16x8.shl
    i32.const 8
    i16x8.shr_s
    local.get 0
    v128.const i32x4 0x00ff00ff 0x00ff00ff 0x00ff00ff 0x00ff00ff
    v128.and
    i16x8.mul
    local.get 1
    i32.const 8
    i16x8.shr_s
    local.get 0
    i32.const 8
    i16x8.shr_u
    i16x8.mul
    i16x8.add_sat_s)
  (func (export "run")
    i32.const 0
    v128.const i8x16 0 2 1 2 1  2  -1   1    255 255 255 255   0 0 255 255 
    v128.const i8x16 1 0 3 4 -3 -4 -128 127  127 127 -128 -128 0 0 -128 127 
    call $_mm_maddubs_epi16
    v128.store
  )
)`);
var ins = new WebAssembly.Instance(new WebAssembly.Module(simple));
ins.exports.run();
var mem16 = new Int16Array(ins.exports.memory.buffer, 0, 8);
assertSame(mem16, [0, 11, -11, -32513, 32767, -32768, 0, -255]);

if (hasDisassembler() && isX64) {
  assertEq(wasmDis(ins.exports.t, {tier:"ion", asString:true}).includes('pmaddubsw'), true);
}

if (hasDisassembler() && isX64) {
  // Two pmaddubsw has common operand, and code was optimized.
  const realWorldOutput = wasmTextToBinary(`(module
     (memory 1 1)
     (func (export "test")
         (local i32 i32 i32 i32 v128 v128 v128 v128 v128 v128)
         local.get 0
         local.get 1
         i32.add
         local.set 2
         local.get 0
         i32.const 16
         i32.add
         local.set 0
         local.get 3
         local.set 1
         loop
             local.get 5
             local.get 0
             v128.load
             local.tee 5
             i32.const 7
             i8x16.shr_s
             local.tee 8
             local.get 1
             v128.load offset=240
             local.get 5
             v128.const i32x4 0x00000000 0x00000000 0x00000000 0x00000000
             i8x16.eq
             local.tee 7
             v128.andnot
             i8x16.add
             local.get 8
             v128.xor
             local.tee 4
             i32.const 8
             i16x8.shl
             i32.const 8
             i16x8.shr_s
             local.get 5
             i8x16.abs
             local.tee 5
             v128.const i32x4 0x00ff00ff 0x00ff00ff 0x00ff00ff 0x00ff00ff
             v128.and
             local.tee 9
             i16x8.mul
             local.get 4
             i32.const 8
             i16x8.shr_s
             local.get 5
             i32.const 8
             i16x8.shr_u
             local.tee 4
             i16x8.mul
             i16x8.add_sat_s
             i16x8.add_sat_s
             local.set 5
 
             local.get 6
             local.get 8
             local.get 1
             v128.load offset=224
             local.get 7
             v128.andnot
             i8x16.add
             local.get 8
             v128.xor
             local.tee 6
             i32.const 8
             i16x8.shl
             i32.const 8
             i16x8.shr_s
             local.get 9
             i16x8.mul
             local.get 6
             i32.const 8
             i16x8.shr_s
             local.get 4
             i16x8.mul
             i16x8.add_sat_s
             i16x8.add_sat_s
             local.set 6
 
             local.get 1
             i32.const 128
             i32.add
             local.set 1
             local.get 0
             i32.const 16
             i32.add
             local.tee 0
             local.get 2
             i32.ne
             br_if 0
         end
))`);
 
  var ins = new WebAssembly.Instance(new WebAssembly.Module(realWorldOutput));
  const output = wasmDis(ins.exports.test, {tier:"ion", asString:true}).replace(/^[0-9a-f]{8}  (?:[0-9a-f]{2} )+\n?\s+/gmi, "");
  // Find two pmaddubsw+paddsw.
  const re = /\bv?pmaddubsw[^\n]+\nv?paddsw /g;
  assertEq(re.exec(output) != null, true);
  assertEq(re.exec(output) != null, true);
  assertEq(re.exec(output) == null, true);
  // No leftover PMULL, PSLLW, or PSRAW.
  assertEq(/pmullw|psllw|psraw/.test(output), false);
}