v8
V8 is Google’s open source high-performance JavaScript and WebAssembly engine, written in C++.
Loading...
Searching...
No Matches
wasm-interpreter-simd.cc
Go to the documentation of this file.
1// Copyright 2024 the V8 project authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "src/wasm/decoder.h"
10
11namespace v8 {
12namespace internal {
13namespace wasm {
14
16
19 Decoder* decoder,
20 InterpreterCode* code, pc_t pc,
21 int* const len) {
22 static const bool kIsReservedSimdOpcode[256] = {
23 // simdop Instruction Immediate operands
24 // --------------------------------------------------------
25 false, // 0x00 v128.load m:memarg
26 false, // 0x01 v128.load8x8_s m:memarg
27 false, // 0x02 v128.load8x8_u m:memarg
28 false, // 0x03 v128.load16x4_s m:memarg
29 false, // 0x04 v128.load16x4_u m:memarg
30 false, // 0x05 v128.load32x2_s m:memarg
31 false, // 0x06 v128.load32x2_u m:memarg
32 false, // 0x07 v128.load8_splat m:memarg
33 false, // 0x08 v128.load16_splat m:memarg
34 false, // 0x09 v128.load32_splat m:memarg
35 false, // 0x0a v128.load64_splat m:memarg
36 false, // 0x0b v128.store m:memarg
37 false, // 0x0c v128.const i:ImmByte[16]
38 false, // 0x0d i8x16.shuffle s:ImmLaneIdx32[16]
39 false, // 0x0e i8x16.swizzle -
40 false, // 0x0f i8x16.splat -
41 false, // 0x10 i16x8.splat -
42 false, // 0x11 i32x4.splat -
43 false, // 0x12 i64x2.splat -
44 false, // 0x13 f32x4.splat -
45 false, // 0x14 f64x2.splat -
46 false, // 0x15 i8x16.extract_lane_s i:ImmLaneIdx16
47 false, // 0x16 i8x16.extract_lane_u i:ImmLaneIdx16
48 false, // 0x17 i8x16.replace_lane i:ImmLaneIdx16
49 false, // 0x18 i16x8.extract_lane_s i:ImmLaneIdx8
50 false, // 0x19 i16x8.extract_lane_u i:ImmLaneIdx8
51 false, // 0x1a i16x8.replace_lane i:ImmLaneIdx8
52 false, // 0x1b i32x4.extract_lane i:ImmLaneIdx4
53 false, // 0x1c i32x4.replace_lane i:ImmLaneIdx4
54 false, // 0x1d i64x2.extract_lane i:ImmLaneIdx2
55 false, // 0x1e i64x2.replace_lane i:ImmLaneIdx2
56 false, // 0x1f f32x4.extract_lane i:ImmLaneIdx4
57 false, // 0x20 f32x4.replace_lane i:ImmLaneIdx4
58 false, // 0x21 f64x2.extract_lane i:ImmLaneIdx2
59 false, // 0x22 f64x2.replace_lane i:ImmLaneIdx2
60 false, // 0x23 i8x16.eq -
61 false, // 0x24 i8x16.ne -
62 false, // 0x25 i8x16.lt_s -
63 false, // 0x26 i8x16.lt_u -
64 false, // 0x27 i8x16.gt_s -
65 false, // 0x28 i8x16.gt_u -
66 false, // 0x29 i8x16.le_s -
67 false, // 0x2a i8x16.le_u -
68 false, // 0x2b i8x16.ge_s -
69 false, // 0x2c i8x16.ge_u -
70 false, // 0x2d i16x8.eq -
71 false, // 0x2e i16x8.ne -
72 false, // 0x2f i16x8.lt_s -
73 false, // 0x30 i16x8.lt_u -
74 false, // 0x31 i16x8.gt_s -
75 false, // 0x32 i16x8.gt_u -
76 false, // 0x33 i16x8.le_s -
77 false, // 0x34 i16x8.le_u -
78 false, // 0x35 i16x8.ge_s -
79 false, // 0x36 i16x8.ge_u -
80 false, // 0x37 i32x4.eq -
81 false, // 0x38 i32x4.ne -
82 false, // 0x39 i32x4.lt_s -
83 false, // 0x3a i32x4.lt_u -
84 false, // 0x3b i32x4.gt_s -
85 false, // 0x3c i32x4.gt_u -
86 false, // 0x3d i32x4.le_s -
87 false, // 0x3e i32x4.le_u -
88 false, // 0x3f i32x4.ge_s -
89 false, // 0x40 i32x4.ge_u -
90 false, // 0x41 f32x4.eq -
91 false, // 0x42 f32x4.ne -
92 false, // 0x43 f32x4.lt -
93 false, // 0x44 f32x4.gt -
94 false, // 0x45 f32x4.le -
95 false, // 0x46 f32x4.ge -
96 false, // 0x47 f64x2.eq -
97 false, // 0x48 f64x2.ne -
98 false, // 0x49 f64x2.lt -
99 false, // 0x4a f64x2.gt -
100 false, // 0x4b f64x2.le -
101 false, // 0x4c f64x2.ge -
102 false, // 0x4d v128.not -
103 false, // 0x4e v128.and -
104 false, // 0x4f v128.andnot -
105 false, // 0x50 v128.or -
106 false, // 0x51 v128.xor -
107 false, // 0x52 v128.bitselect -
108 false, // 0x53 v128.any_true -
109 false, // 0x54 v128.load8_lane m:memarg, i:ImmLaneIdx16
110 false, // 0x55 v128.load16_lane m:memarg, i:ImmLaneIdx8
111 false, // 0x56 v128.load32_lane m:memarg, i:ImmLaneIdx4
112 false, // 0x57 v128.load64_lane m:memarg, i:ImmLaneIdx2
113 false, // 0x58 v128.store8_lane m:memarg, i:ImmLaneIdx16
114 false, // 0x59 v128.store16_lane m:memarg, i:ImmLaneIdx8
115 false, // 0x5a v128.store32_lane m:memarg, i:ImmLaneIdx4
116 false, // 0x5b v128.store64_lane m:memarg, i:ImmLaneIdx2
117 false, // 0x5c v128.load32_zero m:memarg
118 false, // 0x5d v128.load64_zero m:memarg
119 false, // 0x5e f32x4.demote_f64x2_zero -
120 false, // 0x5f f64x2.promote_low_f32x4 -
121 false, // 0x60 i8x16.abs -
122 false, // 0x61 i8x16.neg -
123 false, // 0x62 i8x16.popcnt -
124 false, // 0x63 i8x16.all_true -
125 false, // 0x64 i8x16.bitmask -
126 false, // 0x65 i8x16.narrow_i16x8_s -
127 false, // 0x66 i8x16.narrow_i16x8_u -
128 false, // 0x67 f32x4.ceil -
129 false, // 0x68 f32x4.floor -
130 false, // 0x69 f32x4.trunc -
131 false, // 0x6a f32x4.nearest -
132 false, // 0x6b i8x16.shl -
133 false, // 0x6c i8x16.shr_s -
134 false, // 0x6d i8x16.shr_u -
135 false, // 0x6e i8x16.add -
136 false, // 0x6f i8x16.add_sat_s -
137 false, // 0x70 i8x16.add_sat_u -
138 false, // 0x71 i8x16.sub -
139 false, // 0x72 i8x16.sub_sat_s -
140 false, // 0x73 i8x16.sub_sat_u -
141 false, // 0x74 f64x2.ceil -
142 false, // 0x75 f64x2.floor -
143 false, // 0x76 i8x16.min_s -
144 false, // 0x77 i8x16.min_u -
145 false, // 0x78 i8x16.max_s -
146 false, // 0x79 i8x16.max_u -
147 false, // 0x7a f64x2.trunc -
148 false, // 0x7b i8x16.avgr_u -
149 false, // 0x7c i16x8.extadd_pairwise_i8x16_s -
150 false, // 0x7d i16x8.extadd_pairwise_i8x16_u -
151 false, // 0x7e i32x4.extadd_pairwise_i16x8_s -
152 false, // 0x7f i32x4.extadd_pairwise_i16x8_u -
153 false, // 0x80 i16x8.abs -
154 false, // 0x81 i16x8.neg -
155 false, // 0x82 i16x8.q15mulr_sat_s -
156 false, // 0x83 i16x8.all_true -
157 false, // 0x84 i16x8.bitmask -
158 false, // 0x85 i16x8.narrow_i32x4_s -
159 false, // 0x86 i16x8.narrow_i32x4_u -
160 false, // 0x87 i16x8.extend_low_i8x16_s -
161 false, // 0x88 i16x8.extend_high_i8x16_s -
162 false, // 0x89 i16x8.extend_low_i8x16_u -
163 false, // 0x8a i16x8.extend_high_i8x16_u -
164 false, // 0x8b i16x8.shl -
165 false, // 0x8c i16x8.shr_s -
166 false, // 0x8d i16x8.shr_u -
167 false, // 0x8e i16x8.add -
168 false, // 0x8f i16x8.add_sat_s -
169 false, // 0x90 i16x8.add_sat_u -
170 false, // 0x91 i16x8.sub -
171 false, // 0x92 i16x8.sub_sat_s -
172 false, // 0x93 i16x8.sub_sat_u -
173 false, // 0x94 f64x2.nearest -
174 false, // 0x95 i16x8.mul -
175 false, // 0x96 i16x8.min_s -
176 false, // 0x97 i16x8.min_u -
177 false, // 0x98 i16x8.max_s -
178 false, // 0x99 i16x8.max_u -
179 true, // 0x9a (reserved)
180 false, // 0x9b i16x8.avgr_u -
181 false, // 0x9c i16x8.extmul_low_i8x16_s -
182 false, // 0x9d i16x8.extmul_high_i8x16_s -
183 false, // 0x9e i16x8.extmul_low_i8x16_u -
184 false, // 0x9f i16x8.extmul_high_i8x16_u -
185 false, // 0xa0 i32x4.abs -
186 false, // 0xa1 i32x4.neg -
187 true, // 0xa2 (reserved)
188 false, // 0xa3 i32x4.all_true -
189 false, // 0xa4 i32x4.bitmask -
190 true, // 0xa5 (reserved)
191 true, // 0xa6 (reserved)
192 false, // 0xa7 i32x4.extend_low_i16x8_s -
193 false, // 0xa8 i32x4.extend_high_i16x8_s -
194 false, // 0xa9 i32x4.extend_low_i16x8_u -
195 false, // 0xaa i32x4.extend_high_i16x8_u -
196 false, // 0xab i32x4.shl -
197 false, // 0xac i32x4.shr_s -
198 false, // 0xad i32x4.shr_u -
199 false, // 0xae i32x4.add -
200 true, // 0xaf (reserved)
201 true, // 0xb0 (reserved)
202 false, // 0xb1 i32x4.sub -
203 true, // 0xb2 (reserved)
204 true, // 0xb3 (reserved)
205 true, // 0xb4 (reserved)
206 false, // 0xb5 i32x4.mul -
207 false, // 0xb6 i32x4.min_s -
208 false, // 0xb7 i32x4.min_u -
209 false, // 0xb8 i32x4.max_s -
210 false, // 0xb9 i32x4.max_u -
211 false, // 0xba i32x4.dot_i16x8_s -
212 true, // 0xbb (reserved)
213 false, // 0xbc i32x4.extmul_low_i16x8_s -
214 false, // 0xbd i32x4.extmul_high_i16x8_s -
215 false, // 0xbe i32x4.extmul_low_i16x8_u -
216 false, // 0xbf i32x4.extmul_high_i16x8_u -
217 false, // 0xc0 i64x2.abs -
218 false, // 0xc1 i64x2.neg -
219 true, // 0xc2 (reserved)
220 false, // 0xc3 i64x2.all_true -
221 false, // 0xc4 i64x2.bitmask -
222 true, // 0xc5 (reserved)
223 true, // 0xc6 (reserved)
224 false, // 0xc7 i64x2.extend_low_i32x4_s -
225 false, // 0xc8 i64x2.extend_high_i32x4_s -
226 false, // 0xc9 i64x2.extend_low_i32x4_u -
227 false, // 0xca i64x2.extend_high_i32x4_u -
228 false, // 0xcb i64x2.shl -
229 false, // 0xcc i64x2.shr_s -
230 false, // 0xcd i64x2.shr_u -
231 false, // 0xce i64x2.add -
232 true, // 0xcf (reserved)
233 true, // 0xd0 (reserved)
234 false, // 0xd1 i64x2.sub -
235 true, // 0xd2 (reserved)
236 true, // 0xd3 (reserved)
237 true, // 0xd4 (reserved)
238 false, // 0xd5 i64x2.mul -
239 false, // 0xd6 i64x2.eq -
240 false, // 0xd7 i64x2.ne -
241 false, // 0xd8 i64x2.lt_s -
242 false, // 0xd9 i64x2.gt_s -
243 false, // 0xda i64x2.le_s -
244 false, // 0xdb i64x2.ge_s -
245 false, // 0xdc i64x2.extmul_low_i32x4_s -
246 false, // 0xdd i64x2.extmul_high_i32x4_s -
247 false, // 0xde i64x2.extmul_low_i32x4_u -
248 false, // 0xdf i64x2.extmul_high_i32x4_u -
249 false, // 0xe0 f32x4.abs -
250 false, // 0xe1 f32x4.neg -
251 true, // 0xe2 (reserved)
252 false, // 0xe3 f32x4.sqrt -
253 false, // 0xe4 f32x4.add -
254 false, // 0xe5 f32x4.sub -
255 false, // 0xe6 f32x4.mul -
256 false, // 0xe7 f32x4.div -
257 false, // 0xe8 f32x4.min -
258 false, // 0xe9 f32x4.max -
259 false, // 0xea f32x4.pmin -
260 false, // 0xeb f32x4.pmax -
261 false, // 0xec f64x2.abs -
262 false, // 0xed f64x2.neg -
263 false, // 0xef f64x2.sqrt -
264 false, // 0xf0 f64x2.add -
265 false, // 0xf1 f64x2.sub -
266 false, // 0xf2 f64x2.mul -
267 false, // 0xf3 f64x2.div -
268 false, // 0xf4 f64x2.min -
269 false, // 0xf5 f64x2.max -
270 false, // 0xf6 f64x2.pmin -
271 false, // 0xf7 f64x2.pmax -
272 false, // 0xf8 i32x4.trunc_sat_f32x4_s -
273 false, // 0xf9 i32x4.trunc_sat_f32x4_u -
274 false, // 0xfa f32x4.convert_i32x4_s -
275 false, // 0xfb f32x4.convert_i32x4_u -
276 false, // 0xfc i32x4.trunc_sat_f64x2_s_zero -
277 false, // 0xfd i32x4.trunc_sat_f64x2_u_zero -
278 false, // 0xfe f64x2.convert_low_i32x4_s -
279 false // 0xff f64x2.convert_low_i32x4_u -
280 };
281
282 if ((opcode >= kExprS128LoadMem && opcode <= kExprS128StoreMem) ||
283 opcode == kExprS128Load32Zero || opcode == kExprS128Load64Zero) {
284 MemoryAccessImmediate imm(decoder, code->at(pc + *len), 64,
286 optional->offset = imm.offset;
287 *len += imm.length;
288 } else if (opcode == kExprS128Const) {
289 Simd128Immediate imm(decoder, code->at(pc + *len), kNoValidate);
290 optional->simd_immediate_index = simd_immediates_.size();
291 simd_immediates_.push_back(
292 Simd128(imm.value)); // TODO(paolosev@microsoft.com): avoid duplicates?
293 *len += 16;
294 } else if (opcode == kExprI8x16Shuffle) {
295 Simd128Immediate imm(decoder, code->at(pc + *len), kNoValidate);
296 optional->simd_immediate_index = simd_immediates_.size();
297 simd_immediates_.push_back(
298 Simd128(imm.value)); // TODO(paolosev@microsoft.com): avoid duplicates?
299 *len += 16;
300 } else if ((opcode >= kExprI8x16ExtractLaneS) &&
301 (opcode <= kExprF64x2ReplaceLane)) {
302 SimdLaneImmediate imm(decoder, code->at(pc + *len), kNoValidate);
303 if (imm.lane >= kSimd128Size) {
304 return false;
305 }
306 optional->simd_lane = imm.lane;
307 *len += 1;
308 } else if ((opcode >= kExprS128Load8Lane) &&
309 (opcode <= kExprS128Store64Lane)) {
310 MemoryAccessImmediate mem_imm(decoder, code->at(pc + *len), 64,
312 if (mem_imm.offset >= ((uint64_t)1 << 48)) {
313 return false;
314 }
315 *len += mem_imm.length;
316
317 SimdLaneImmediate lane_imm(decoder, code->at(pc + *len), kNoValidate);
318 if (lane_imm.lane >= kSimd128Size) {
319 return false;
320 }
321
322 optional->simd_loadstore_lane.offset = mem_imm.offset;
323 optional->simd_loadstore_lane.lane = lane_imm.lane;
324 *len += lane_imm.length;
325 } else if (WasmOpcodes::IsRelaxedSimdOpcode(opcode)) {
326 // Relaxed SIMD opcodes:
327 // 0x100 i8x16.relaxed_swizzle -
328 // 0x101 i32x4.relaxed_trunc_f32x4_s -
329 // 0x102 i32x4.relaxed_trunc_f32x4_u -
330 // 0x103 i32x4.relaxed_trunc_f64x2_s_zero -
331 // 0x104 i32x4.relaxed_trunc_f64x2_u_zero -
332 // 0x105 f32x4.relaxed_madd -
333 // 0x106 f32x4.relaxed_nmadd -
334 // 0x107 f64x2.relaxed_madd -
335 // 0x108 f64x2.relaxed_nmadd -
336 // 0x109 i8x16.relaxed_laneselect -
337 // 0x10a i16x8.relaxed_laneselect -
338 // 0x10b i32x4.relaxed_laneselect -
339 // 0x10c i64x2.relaxed_laneselect -
340 // 0x10d f32x4.relaxed_min -
341 // 0x10e f32x4.relaxed_max -
342 // 0x10f f64x2.relaxed_min -
343 // 0x110 f64x2.relaxed_max -
344 // 0x111 i16x8.relaxed_q15mulr_s -
345 // 0x112 i16x8.relaxed_dot_i8x16_i7x16_s -
346 // 0x113 i32x4.relaxed_dot_i8x16_i7x16_add_s -
347 return opcode <= 0xfd113;
348 // Handle relaxed SIMD opcodes (in [0xfd100, 0xfd1ff]).
349 } else if (opcode >= 0xfd200 || kIsReservedSimdOpcode[opcode & 0xff]) {
350 FATAL("Unknown or unimplemented opcode #%d:%s", code->start[pc],
351 WasmOpcodes::OpcodeName(static_cast<WasmOpcode>(code->start[pc])));
352 UNREACHABLE();
353 } else {
354 // No immediate operands.
355 }
356 return true;
357}
358
359} // namespace wasm
360} // namespace internal
361} // namespace v8
static constexpr struct v8::internal::wasm::Decoder::NoValidationTag kNoValidation
bool DecodeSimdOp(WasmOpcode opcode, WasmInstruction::Optional *optional, Decoder *decoder, InterpreterCode *code, pc_t pc, int *const len)
static constexpr bool IsRelaxedSimdOpcode(WasmOpcode)
static constexpr const char * OpcodeName(WasmOpcode)
WordWithBits< 128 > Simd128
Definition index.h:236
constexpr Decoder::NoValidationTag kNoValidate
constexpr int kSimd128Size
Definition globals.h:706
Definition c-api.cc:87
#define FATAL(...)
Definition logging.h:47
struct v8::internal::wasm::WasmInstruction::Optional::SimdLaneLoad simd_loadstore_lane