Skip to content
This repository was archived by the owner on Dec 22, 2021. It is now read-only.

Commit 7c37165

Browse files
authored
[interpreter] Implement SIMD extended multiply instructions (#438)
These were accepted into the proposal in #376. There are 12 instructions in total: - i16x8.extmul_{low,high}_i8x16_{s,u} - i32x4.extmul_{low,high}_i16x8_{s,u} - i64x2.extmul_{low,high}_i32x4_{s,u} The implementation is straightforward, widen (using existing operations), then a multiply with the wider shape. The binary opcodes are not decided yet, they currently follow the ones used in V8, when those are finalized, we can change it to match. Added a test generation script that reuses some logic in the generator for arithmetic instructions. Since these instructions have different src and dst shapes, I tweaked the base class to allow for having different shapes.
1 parent 98915d5 commit 7c37165

15 files changed

+1435
-18
lines changed

interpreter/binary/decode.ml

+12
Original file line numberDiff line numberDiff line change
@@ -365,7 +365,11 @@ let simd_prefix s =
365365
| 0x97l -> i16x8_min_u
366366
| 0x98l -> i16x8_max_s
367367
| 0x99l -> i16x8_max_u
368+
| 0x9al -> i16x8_extmul_low_i8x16_s
368369
| 0x9bl -> i16x8_avgr_u
370+
| 0x9dl -> i16x8_extmul_high_i8x16_s
371+
| 0x9el -> i16x8_extmul_low_i8x16_u
372+
| 0x9fl -> i16x8_extmul_high_i8x16_u
369373
| 0xa0l -> i32x4_abs
370374
| 0xa1l -> i32x4_neg
371375
| 0xa3l -> i32x4_all_true
@@ -385,6 +389,10 @@ let simd_prefix s =
385389
| 0xb8l -> i32x4_max_s
386390
| 0xb9l -> i32x4_max_u
387391
| 0xbal -> i32x4_dot_i16x8_s
392+
| 0xbbl -> i32x4_extmul_low_i16x8_s
393+
| 0xbdl -> i32x4_extmul_high_i16x8_s
394+
| 0xbel -> i32x4_extmul_low_i16x8_u
395+
| 0xbfl -> i32x4_extmul_high_i16x8_u
388396
| 0xc0l -> i64x2_eq
389397
| 0xc1l -> i64x2_neg
390398
| 0xcbl -> i64x2_shl
@@ -393,6 +401,10 @@ let simd_prefix s =
393401
| 0xcel -> i64x2_add
394402
| 0xd0l -> i64x2_ne
395403
| 0xd1l -> i64x2_sub
404+
| 0xd2l -> i64x2_extmul_low_i32x4_s
405+
| 0xd3l -> i64x2_extmul_high_i32x4_s
406+
| 0xd6l -> i64x2_extmul_low_i32x4_u
407+
| 0xd7l -> i64x2_extmul_high_i32x4_u
396408
| 0xd5l -> i64x2_mul
397409
| 0xd8l -> f32x4_ceil
398410
| 0xd9l -> f32x4_floor

interpreter/binary/encode.ml

+12
Original file line numberDiff line numberDiff line change
@@ -467,6 +467,10 @@ let encode m =
467467
| Binary (V128 V128Op.(I16x8 MaxS)) -> simd_op 0x98l
468468
| Binary (V128 V128Op.(I16x8 MaxU)) -> simd_op 0x99l
469469
| Binary (V128 V128Op.(I16x8 AvgrU)) -> simd_op 0x9bl
470+
| Binary (V128 V128Op.(I16x8 ExtMulLowS)) -> simd_op 0x9al
471+
| Binary (V128 V128Op.(I16x8 ExtMulHighS)) -> simd_op 0x9dl
472+
| Binary (V128 V128Op.(I16x8 ExtMulLowU)) -> simd_op 0x9el
473+
| Binary (V128 V128Op.(I16x8 ExtMulHighU)) -> simd_op 0x9fl
470474
| Binary (V128 V128Op.(I32x4 Add)) -> simd_op 0xael
471475
| Binary (V128 V128Op.(I32x4 Sub)) -> simd_op 0xb1l
472476
| Binary (V128 V128Op.(I32x4 MinS)) -> simd_op 0xb6l
@@ -485,11 +489,19 @@ let encode m =
485489
| Binary (V128 V128Op.(I32x4 LeU)) -> simd_op 0x3el
486490
| Binary (V128 V128Op.(I32x4 GeS)) -> simd_op 0x3fl
487491
| Binary (V128 V128Op.(I32x4 GeU)) -> simd_op 0x40l
492+
| Binary (V128 V128Op.(I32x4 ExtMulLowS)) -> simd_op 0xbbl
493+
| Binary (V128 V128Op.(I32x4 ExtMulHighS)) -> simd_op 0xbdl
494+
| Binary (V128 V128Op.(I32x4 ExtMulLowU)) -> simd_op 0xbel
495+
| Binary (V128 V128Op.(I32x4 ExtMulHighU)) -> simd_op 0xbfl
488496
| Binary (V128 V128Op.(I64x2 Add)) -> simd_op 0xcel
489497
| Binary (V128 V128Op.(I64x2 Sub)) -> simd_op 0xd1l
490498
| Binary (V128 V128Op.(I64x2 Mul)) -> simd_op 0xd5l
491499
| Binary (V128 V128Op.(I64x2 Eq)) -> simd_op 0xc0l
492500
| Binary (V128 V128Op.(I64x2 Ne)) -> simd_op 0xd0l
501+
| Binary (V128 V128Op.(I64x2 ExtMulLowS)) -> simd_op 0xd2l
502+
| Binary (V128 V128Op.(I64x2 ExtMulHighS)) -> simd_op 0xd3l
503+
| Binary (V128 V128Op.(I64x2 ExtMulLowU)) -> simd_op 0xd6l
504+
| Binary (V128 V128Op.(I64x2 ExtMulHighU)) -> simd_op 0xd7l
493505
| Binary (V128 V128Op.(F32x4 Eq)) -> simd_op 0x41l
494506
| Binary (V128 V128Op.(F32x4 Ne)) -> simd_op 0x42l
495507
| Binary (V128 V128Op.(F32x4 Lt)) -> simd_op 0x43l

interpreter/exec/eval_simd.ml

+12
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,10 @@ module SimdOp (SXX : Simd.S) (Value : ValueType with type t = SXX.t) = struct
101101
| I16x8 MaxS -> SXX.I16x8.max_s
102102
| I16x8 MaxU -> SXX.I16x8.max_u
103103
| I16x8 AvgrU -> SXX.I16x8.avgr_u
104+
| I16x8 ExtMulLowS -> SXX.I16x8_convert.extmul_low_s
105+
| I16x8 ExtMulHighS -> SXX.I16x8_convert.extmul_high_s
106+
| I16x8 ExtMulLowU -> SXX.I16x8_convert.extmul_low_u
107+
| I16x8 ExtMulHighU -> SXX.I16x8_convert.extmul_high_u
104108
| I32x4 Add -> SXX.I32x4.add
105109
| I32x4 Sub -> SXX.I32x4.sub
106110
| I32x4 MinS -> SXX.I32x4.min_s
@@ -121,9 +125,17 @@ module SimdOp (SXX : Simd.S) (Value : ValueType with type t = SXX.t) = struct
121125
| I32x4 DotI16x8S -> SXX.I32x4_convert.dot_i16x8_s
122126
| I64x2 Eq -> SXX.I64x2.eq
123127
| I64x2 Ne -> SXX.I64x2.ne
128+
| I32x4 ExtMulLowS -> SXX.I32x4_convert.extmul_low_s
129+
| I32x4 ExtMulHighS -> SXX.I32x4_convert.extmul_high_s
130+
| I32x4 ExtMulLowU -> SXX.I32x4_convert.extmul_low_u
131+
| I32x4 ExtMulHighU -> SXX.I32x4_convert.extmul_high_u
124132
| I64x2 Add -> SXX.I64x2.add
125133
| I64x2 Sub -> SXX.I64x2.sub
126134
| I64x2 Mul -> SXX.I64x2.mul
135+
| I64x2 ExtMulLowS -> SXX.I64x2_convert.extmul_low_s
136+
| I64x2 ExtMulHighS -> SXX.I64x2_convert.extmul_high_s
137+
| I64x2 ExtMulLowU -> SXX.I64x2_convert.extmul_low_u
138+
| I64x2 ExtMulHighU -> SXX.I64x2_convert.extmul_high_u
127139
| F32x4 Eq -> SXX.F32x4.eq
128140
| F32x4 Ne -> SXX.F32x4.ne
129141
| F32x4 Lt -> SXX.F32x4.lt

interpreter/exec/simd.ml

+34-4
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,10 @@ sig
177177
val widen_high_s : t -> t
178178
val widen_low_u : t -> t
179179
val widen_high_u : t -> t
180+
val extmul_low_s : t -> t -> t
181+
val extmul_high_s : t -> t -> t
182+
val extmul_low_u : t -> t -> t
183+
val extmul_high_u : t -> t -> t
180184
end
181185
module I32x4_convert : sig
182186
val trunc_sat_f32x4_s : t -> t
@@ -186,10 +190,20 @@ sig
186190
val widen_low_u : t -> t
187191
val widen_high_u : t -> t
188192
val dot_i16x8_s : t -> t -> t
193+
val extmul_low_s : t -> t -> t
194+
val extmul_high_s : t -> t -> t
195+
val extmul_low_u : t -> t -> t
196+
val extmul_high_u : t -> t -> t
189197
end
190198
module I64x2_convert : sig
191199
val widen_low_s : t -> t
200+
val widen_high_s : t -> t
192201
val widen_low_u : t -> t
202+
val widen_high_u : t -> t
203+
val extmul_low_s : t -> t -> t
204+
val extmul_high_s : t -> t -> t
205+
val extmul_low_u : t -> t -> t
206+
val extmul_high_u : t -> t -> t
193207
end
194208
module F32x4_convert : sig
195209
val convert_i32x4_s : t -> t
@@ -417,6 +431,10 @@ struct
417431
let widen_low_u = widen Lib.List.take 0xffl
418432
let widen_high_u = widen Lib.List.drop 0xffl
419433

434+
let extmul_low_s x y = I16x8.mul (widen_low_s x) (widen_low_s y)
435+
let extmul_high_s x y = I16x8.mul (widen_high_s x) (widen_high_s y)
436+
let extmul_low_u x y = I16x8.mul (widen_low_u x) (widen_low_u y)
437+
let extmul_high_u x y = I16x8.mul (widen_high_u x) (widen_high_u y)
420438
end
421439

422440
module I32x4_convert = struct
@@ -441,16 +459,28 @@ struct
441459
| [], [] -> []
442460
| _, _ -> assert false
443461
in Rep.of_i32x4 (dot xs ys)
462+
463+
let extmul_low_s x y = I32x4.mul (widen_low_s x) (widen_low_s y)
464+
let extmul_high_s x y = I32x4.mul (widen_high_s x) (widen_high_s y)
465+
let extmul_low_u x y = I32x4.mul (widen_low_u x) (widen_low_u y)
466+
let extmul_high_u x y = I32x4.mul (widen_high_u x) (widen_high_u y)
444467
end
445468

446469
module I64x2_convert = struct
447-
let widen mask x =
470+
let widen take_or_drop mask x =
448471
Rep.of_i64x2
449472
(List.map
450473
(fun i32 -> Int64.(logand mask (of_int32 i32)))
451-
(Lib.List.take 2 (Rep.to_i32x4 x)))
452-
let widen_low_s = widen 0xffffffffffffffffL
453-
let widen_low_u = widen 0xffffffffL
474+
(take_or_drop 2 (Rep.to_i32x4 x)))
475+
let widen_low_s = widen Lib.List.take 0xffffffffffffffffL
476+
let widen_high_s = widen Lib.List.drop 0xffffffffffffffffL
477+
let widen_low_u = widen Lib.List.take 0xffffffffL
478+
let widen_high_u = widen Lib.List.drop 0xffffffffL
479+
480+
let extmul_low_s x y = I64x2.mul (widen_low_s x) (widen_low_s y)
481+
let extmul_high_s x y = I64x2.mul (widen_high_s x) (widen_high_s y)
482+
let extmul_low_u x y = I64x2.mul (widen_low_u x) (widen_low_u y)
483+
let extmul_high_u x y = I64x2.mul (widen_high_u x) (widen_high_u y)
454484
end
455485

456486
module F32x4_convert = struct

interpreter/syntax/ast.ml

+1
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ struct
5555
| Swizzle | Shuffle of int list | NarrowS | NarrowU
5656
| AddSatS | AddSatU | SubSatS | SubSatU
5757
| DotI16x8S
58+
| ExtMulLowS | ExtMulHighS | ExtMulLowU | ExtMulHighU
5859
type funop = Abs | Neg | Sqrt
5960
| Ceil | Floor | Trunc | Nearest
6061
| ConvertI32x4S | ConvertI32x4U

interpreter/syntax/operators.ml

+12
Original file line numberDiff line numberDiff line change
@@ -340,6 +340,10 @@ let i16x8_min_u = Binary (V128 V128Op.(I16x8 MinU))
340340
let i16x8_max_s = Binary (V128 V128Op.(I16x8 MaxS))
341341
let i16x8_max_u = Binary (V128 V128Op.(I16x8 MaxU))
342342
let i16x8_avgr_u = Binary (V128 V128Op.(I16x8 AvgrU))
343+
let i16x8_extmul_low_i8x16_s = Binary (V128 V128Op.(I16x8 ExtMulLowS))
344+
let i16x8_extmul_high_i8x16_s = Binary (V128 V128Op.(I16x8 ExtMulHighS))
345+
let i16x8_extmul_low_i8x16_u = Binary (V128 V128Op.(I16x8 ExtMulLowU))
346+
let i16x8_extmul_high_i8x16_u = Binary (V128 V128Op.(I16x8 ExtMulHighU))
343347

344348
let i32x4_splat = Convert (V128 V128Op.(I32x4 Splat))
345349
let i32x4_extract_lane imm = SimdExtract (V128Op.I32x4 (ZX, imm))
@@ -375,6 +379,10 @@ let i32x4_mul = Binary (V128 V128Op.(I32x4 Mul))
375379
let i32x4_trunc_sat_f32x4_s = Unary (V128 V128Op.(I32x4 TruncSatF32x4S))
376380
let i32x4_trunc_sat_f32x4_u = Unary (V128 V128Op.(I32x4 TruncSatF32x4U))
377381
let i32x4_dot_i16x8_s = Binary (V128 V128Op.(I32x4 DotI16x8S))
382+
let i32x4_extmul_low_i16x8_s = Binary (V128 V128Op.(I32x4 ExtMulLowS))
383+
let i32x4_extmul_high_i16x8_s = Binary (V128 V128Op.(I32x4 ExtMulHighS))
384+
let i32x4_extmul_low_i16x8_u = Binary (V128 V128Op.(I32x4 ExtMulLowU))
385+
let i32x4_extmul_high_i16x8_u = Binary (V128 V128Op.(I32x4 ExtMulHighU))
378386

379387
let i64x2_splat = Convert (V128 V128Op.(I64x2 Splat))
380388
let i64x2_extract_lane imm = SimdExtract (V128Op.I64x2 (ZX, imm))
@@ -388,6 +396,10 @@ let i64x2_mul = Binary (V128 V128Op.(I64x2 Mul))
388396
let i64x2_shl = SimdShift V128Op.(I64x2 Shl)
389397
let i64x2_shr_s = SimdShift V128Op.(I64x2 ShrS)
390398
let i64x2_shr_u = SimdShift V128Op.(I64x2 ShrU)
399+
let i64x2_extmul_low_i32x4_s = Binary (V128 V128Op.(I64x2 ExtMulLowS))
400+
let i64x2_extmul_high_i32x4_s = Binary (V128 V128Op.(I64x2 ExtMulHighS))
401+
let i64x2_extmul_low_i32x4_u = Binary (V128 V128Op.(I64x2 ExtMulLowU))
402+
let i64x2_extmul_high_i32x4_u = Binary (V128 V128Op.(I64x2 ExtMulHighU))
391403

392404
let f32x4_splat = Convert (V128 V128Op.(F32x4 Splat))
393405
let f32x4_extract_lane imm = SimdExtract (V128Op.F32x4 (ZX, imm))

interpreter/text/arrange.ml

+12
Original file line numberDiff line numberDiff line change
@@ -298,6 +298,10 @@ struct
298298
| I16x8 MaxS -> "i16x8.max_s"
299299
| I16x8 MaxU -> "i16x8.max_u"
300300
| I16x8 AvgrU -> "i16x8.avgr_u"
301+
| I16x8 ExtMulLowS -> "i16x8.extmul_low_i8x16_s"
302+
| I16x8 ExtMulHighS -> "i16x8.extmul_high_i8x16_s"
303+
| I16x8 ExtMulLowU -> "i16x8.extmul_low_i8x16_u"
304+
| I16x8 ExtMulHighU -> "i16x8.extmul_high_i8x16_u"
301305
| I32x4 Add -> "i32x4.add"
302306
| I32x4 Sub -> "i32x4.sub"
303307
| I32x4 Mul -> "i32x4.mul"
@@ -306,9 +310,17 @@ struct
306310
| I32x4 MaxS -> "i32x4.max_s"
307311
| I32x4 MaxU -> "i32x4.max_u"
308312
| I32x4 DotI16x8S -> "i32x4.dot_i16x8_s"
313+
| I32x4 ExtMulLowS -> "i32x4.extmul_low_i16x8_s"
314+
| I32x4 ExtMulHighS -> "i32x4.extmul_high_i16x8_s"
315+
| I32x4 ExtMulLowU -> "i32x4.extmul_low_i16x8_u"
316+
| I32x4 ExtMulHighU -> "i32x4.extmul_high_i16x8_u"
309317
| I64x2 Add -> "i64x2.add"
310318
| I64x2 Sub -> "i64x2.sub"
311319
| I64x2 Mul -> "i64x2.mul"
320+
| I64x2 ExtMulLowS -> "i64x2.extmul_low_i32x4_s"
321+
| I64x2 ExtMulHighS -> "i64x2.extmul_high_i32x4_s"
322+
| I64x2 ExtMulLowU -> "i64x2.extmul_low_i32x4_u"
323+
| I64x2 ExtMulHighU -> "i64x2.extmul_high_i32x4_u"
312324
| F32x4 Eq -> "f32x4.eq"
313325
| F32x4 Ne -> "f32x4.ne"
314326
| F32x4 Lt -> "f32x4.lt"

interpreter/text/lexer.mll

+13
Original file line numberDiff line numberDiff line change
@@ -576,6 +576,19 @@ rule token = parse
576576
| "i32x4.dot_i16x8_s"
577577
{ BINARY i32x4_dot_i16x8_s }
578578

579+
| "i16x8.extmul_low_i8x16_"(sign as s)
580+
{ BINARY (ext s i16x8_extmul_low_i8x16_s i16x8_extmul_low_i8x16_u) }
581+
| "i16x8.extmul_high_i8x16_"(sign as s)
582+
{ BINARY (ext s i16x8_extmul_high_i8x16_s i16x8_extmul_high_i8x16_u) }
583+
| "i32x4.extmul_low_i16x8_"(sign as s)
584+
{ BINARY (ext s i32x4_extmul_low_i16x8_s i32x4_extmul_low_i16x8_u) }
585+
| "i32x4.extmul_high_i16x8_"(sign as s)
586+
{ BINARY (ext s i32x4_extmul_high_i16x8_s i32x4_extmul_high_i16x8_u) }
587+
| "i64x2.extmul_low_i32x4_"(sign as s)
588+
{ BINARY (ext s i64x2_extmul_low_i32x4_s i64x2_extmul_low_i32x4_u) }
589+
| "i64x2.extmul_high_i32x4_"(sign as s)
590+
{ BINARY (ext s i64x2_extmul_high_i32x4_s i64x2_extmul_high_i32x4_u) }
591+
579592
| (simd_shape as s) { SIMD_SHAPE (simd_shape s) }
580593

581594
| name as s { VAR s }

test/core/simd/meta/gen_tests.py

+1
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
'simd_f64x2_pmin_pmax',
3434
'simd_i32x4_dot_i16x8',
3535
'simd_load_lane',
36+
'simd_ext_mul',
3637
)
3738

3839

test/core/simd/meta/simd_arithmetic.py

+17-4
Original file line numberDiff line numberDiff line change
@@ -35,14 +35,27 @@ def __str__(self):
3535
def lane(self):
3636
return self.LANE_VALUE.get(self.LANE_TYPE)
3737

38+
@property
39+
def dst_lane(self):
40+
return self.lane
41+
42+
@property
43+
def src_lane(self):
44+
# Used for arithmetic that extends the lane, e.g. i16x8 lanes, which
45+
# are extended multiply to i32x4.
46+
if hasattr(self, 'SRC_LANE_TYPE'):
47+
return self.LANE_VALUE.get(self.SRC_LANE_TYPE)
48+
else:
49+
return self.lane
50+
3851
@property
3952
def normal_unary_op_test_data(self):
40-
lane = self.lane
53+
lane = self.src_lane
4154
return [0, 1, -1, lane.max - 1, lane.min + 1, lane.min, lane.max, lane.mask]
4255

4356
@property
4457
def normal_binary_op_test_data(self):
45-
lane = self.lane
58+
lane = self.src_lane
4659
return [
4760
(0, 0),
4861
(0, 1),
@@ -170,7 +183,7 @@ def get_case_data(self):
170183
for data_group, v128_forms in self.bin_test_data:
171184
for data in data_group:
172185
case_data.append([op_name, [str(data[0]), str(data[1])],
173-
str(o.binary_op(data[0], data[1], self.lane)),
186+
str(o.binary_op(data[0], data[1], self.src_lane, self.dst_lane)),
174187
v128_forms])
175188
for data_group in self.full_bin_test_data:
176189
for data in data_group.get(op_name):
@@ -183,7 +196,7 @@ def get_case_data(self):
183196
for data_group, v128_forms in self.unary_test_data:
184197
for data in data_group:
185198
case_data.append([op_name, [str(data)],
186-
str(o.unary_op(data, self.lane)),
199+
str(o.unary_op(data, self.dst_lane)),
187200
v128_forms])
188201

189202
return case_data

test/core/simd/meta/simd_ext_mul.py

+75
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
#!/usr/bin/env python3
2+
3+
""" Base class for generating extended multiply instructions. These
4+
instructions 2 inputs of the same (narrower) lane shape, multiplies
5+
corresponding lanes with extension (no overflow/wraparound), producing 1 output
6+
of a (wider) shape. These instructions can choose to work on the low or high
7+
halves of the inputs, and perform signed or unsigned multiply.
8+
9+
Subclasses need to define 3 attributes:
10+
- LANE_TYPE (this is the output shape)
11+
- SRC_LANE_TYPE (this is the input (narrower) shape)
12+
- BINARY_OPS (list of operations)
13+
"""
14+
15+
from simd_arithmetic import SimdArithmeticCase
16+
17+
18+
class SimdExtMulCase(SimdArithmeticCase):
19+
UNARY_OPS = ()
20+
21+
@property
22+
def full_bin_test_data(self):
23+
return []
24+
25+
def get_combine_cases(self):
26+
return ''
27+
28+
@property
29+
def bin_test_data(self):
30+
lane_forms = [self.SRC_LANE_TYPE, self.SRC_LANE_TYPE, self.LANE_TYPE]
31+
return [(self.normal_binary_op_test_data, lane_forms)]
32+
33+
@property
34+
def hex_binary_op_test_data(self):
35+
return []
36+
37+
def gen_test_cases(self):
38+
wast_filename = '../simd_{wide}_extmul_{narrow}.wast'.format(
39+
wide=self.LANE_TYPE, narrow=self.SRC_LANE_TYPE)
40+
with open(wast_filename, 'w') as fp:
41+
fp.write(self.get_all_cases())
42+
43+
44+
class SimdI16x8ExtMulCase(SimdExtMulCase):
45+
LANE_TYPE = 'i16x8'
46+
SRC_LANE_TYPE = 'i8x16'
47+
BINARY_OPS = ('extmul_low_i8x16_s', 'extmul_high_i8x16_s',
48+
'extmul_low_i8x16_u', 'extmul_high_i8x16_u')
49+
50+
51+
class SimdI32x4ExtMulCase(SimdExtMulCase):
52+
LANE_TYPE = 'i32x4'
53+
SRC_LANE_TYPE = 'i16x8'
54+
BINARY_OPS = ('extmul_low_i16x8_s', 'extmul_high_i16x8_s',
55+
'extmul_low_i16x8_u', 'extmul_high_i16x8_u')
56+
57+
58+
class SimdI64x2ExtMulCase(SimdExtMulCase):
59+
LANE_TYPE = 'i64x2'
60+
SRC_LANE_TYPE = 'i32x4'
61+
BINARY_OPS = ('extmul_low_i32x4_s', 'extmul_high_i32x4_s',
62+
'extmul_low_i32x4_u', 'extmul_high_i32x4_u')
63+
64+
65+
def gen_test_cases():
66+
simd_i16x8_ext_mul_case = SimdI16x8ExtMulCase()
67+
simd_i16x8_ext_mul_case.gen_test_cases()
68+
simd_i32x4_ext_mul_case = SimdI32x4ExtMulCase()
69+
simd_i32x4_ext_mul_case.gen_test_cases()
70+
simd_i64x2_ext_mul_case = SimdI64x2ExtMulCase()
71+
simd_i64x2_ext_mul_case.gen_test_cases()
72+
73+
74+
if __name__ == '__main__':
75+
gen_test_cases()

0 commit comments

Comments
 (0)