Skip to content

Commit 03ae7fc

Browse files
authored
SIMD integer abs and bitmask instructions (#2703)
Adds full support for the {i8x16,i16x8,i32x4}.abs instructions merged to the SIMD proposal in WebAssembly/simd#128 as well as the {i8x16,i16x8,i32x4}.bitmask instructions proposed in WebAssembly/simd#201.
1 parent 39fda77 commit 03ae7fc

26 files changed

+2355
-1737
lines changed

scripts/gen-s-parser.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -360,9 +360,11 @@
360360
("v128.xor", "makeBinary(s, BinaryOp::XorVec128)"),
361361
("v128.andnot", "makeBinary(s, BinaryOp::AndNotVec128)"),
362362
("v128.bitselect", "makeSIMDTernary(s, SIMDTernaryOp::Bitselect)"),
363+
("i8x16.abs", "makeUnary(s, UnaryOp::AbsVecI8x16)"),
363364
("i8x16.neg", "makeUnary(s, UnaryOp::NegVecI8x16)"),
364365
("i8x16.any_true", "makeUnary(s, UnaryOp::AnyTrueVecI8x16)"),
365366
("i8x16.all_true", "makeUnary(s, UnaryOp::AllTrueVecI8x16)"),
367+
("i8x16.bitmask", "makeUnary(s, UnaryOp::BitmaskVecI8x16)"),
366368
("i8x16.shl", "makeSIMDShift(s, SIMDShiftOp::ShlVecI8x16)"),
367369
("i8x16.shr_s", "makeSIMDShift(s, SIMDShiftOp::ShrSVecI8x16)"),
368370
("i8x16.shr_u", "makeSIMDShift(s, SIMDShiftOp::ShrUVecI8x16)"),
@@ -378,9 +380,11 @@
378380
("i8x16.max_s", "makeBinary(s, BinaryOp::MaxSVecI8x16)"),
379381
("i8x16.max_u", "makeBinary(s, BinaryOp::MaxUVecI8x16)"),
380382
("i8x16.avgr_u", "makeBinary(s, BinaryOp::AvgrUVecI8x16)"),
383+
("i16x8.abs", "makeUnary(s, UnaryOp::AbsVecI16x8)"),
381384
("i16x8.neg", "makeUnary(s, UnaryOp::NegVecI16x8)"),
382385
("i16x8.any_true", "makeUnary(s, UnaryOp::AnyTrueVecI16x8)"),
383386
("i16x8.all_true", "makeUnary(s, UnaryOp::AllTrueVecI16x8)"),
387+
("i16x8.bitmask", "makeUnary(s, UnaryOp::BitmaskVecI16x8)"),
384388
("i16x8.shl", "makeSIMDShift(s, SIMDShiftOp::ShlVecI16x8)"),
385389
("i16x8.shr_s", "makeSIMDShift(s, SIMDShiftOp::ShrSVecI16x8)"),
386390
("i16x8.shr_u", "makeSIMDShift(s, SIMDShiftOp::ShrUVecI16x8)"),
@@ -396,9 +400,11 @@
396400
("i16x8.max_s", "makeBinary(s, BinaryOp::MaxSVecI16x8)"),
397401
("i16x8.max_u", "makeBinary(s, BinaryOp::MaxUVecI16x8)"),
398402
("i16x8.avgr_u", "makeBinary(s, BinaryOp::AvgrUVecI16x8)"),
403+
("i32x4.abs", "makeUnary(s, UnaryOp::AbsVecI32x4)"),
399404
("i32x4.neg", "makeUnary(s, UnaryOp::NegVecI32x4)"),
400405
("i32x4.any_true", "makeUnary(s, UnaryOp::AnyTrueVecI32x4)"),
401406
("i32x4.all_true", "makeUnary(s, UnaryOp::AllTrueVecI32x4)"),
407+
("i32x4.bitmask", "makeUnary(s, UnaryOp::BitmaskVecI32x4)"),
402408
("i32x4.shl", "makeSIMDShift(s, SIMDShiftOp::ShlVecI32x4)"),
403409
("i32x4.shr_s", "makeSIMDShift(s, SIMDShiftOp::ShrSVecI32x4)"),
404410
("i32x4.shr_u", "makeSIMDShift(s, SIMDShiftOp::ShrUVecI32x4)"),

src/binaryen-c.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -790,9 +790,11 @@ BinaryenOp BinaryenOrVec128(void) { return OrVec128; }
790790
BinaryenOp BinaryenXorVec128(void) { return XorVec128; }
791791
BinaryenOp BinaryenAndNotVec128(void) { return AndNotVec128; }
792792
BinaryenOp BinaryenBitselectVec128(void) { return Bitselect; }
793+
BinaryenOp BinaryenAbsVecI8x16(void) { return AbsVecI8x16; }
793794
BinaryenOp BinaryenNegVecI8x16(void) { return NegVecI8x16; }
794795
BinaryenOp BinaryenAnyTrueVecI8x16(void) { return AnyTrueVecI8x16; }
795796
BinaryenOp BinaryenAllTrueVecI8x16(void) { return AllTrueVecI8x16; }
797+
BinaryenOp BinaryenBitmaskVecI8x16(void) { return BitmaskVecI8x16; }
796798
BinaryenOp BinaryenShlVecI8x16(void) { return ShlVecI8x16; }
797799
BinaryenOp BinaryenShrSVecI8x16(void) { return ShrSVecI8x16; }
798800
BinaryenOp BinaryenShrUVecI8x16(void) { return ShrUVecI8x16; }
@@ -808,9 +810,11 @@ BinaryenOp BinaryenMinUVecI8x16(void) { return MinUVecI8x16; }
808810
BinaryenOp BinaryenMaxSVecI8x16(void) { return MaxSVecI8x16; }
809811
BinaryenOp BinaryenMaxUVecI8x16(void) { return MaxUVecI8x16; }
810812
BinaryenOp BinaryenAvgrUVecI8x16(void) { return AvgrUVecI8x16; }
813+
BinaryenOp BinaryenAbsVecI16x8(void) { return AbsVecI16x8; }
811814
BinaryenOp BinaryenNegVecI16x8(void) { return NegVecI16x8; }
812815
BinaryenOp BinaryenAnyTrueVecI16x8(void) { return AnyTrueVecI16x8; }
813816
BinaryenOp BinaryenAllTrueVecI16x8(void) { return AllTrueVecI16x8; }
817+
BinaryenOp BinaryenBitmaskVecI16x8(void) { return BitmaskVecI16x8; }
814818
BinaryenOp BinaryenShlVecI16x8(void) { return ShlVecI16x8; }
815819
BinaryenOp BinaryenShrSVecI16x8(void) { return ShrSVecI16x8; }
816820
BinaryenOp BinaryenShrUVecI16x8(void) { return ShrUVecI16x8; }
@@ -826,9 +830,11 @@ BinaryenOp BinaryenMinUVecI16x8(void) { return MinUVecI16x8; }
826830
BinaryenOp BinaryenMaxSVecI16x8(void) { return MaxSVecI16x8; }
827831
BinaryenOp BinaryenMaxUVecI16x8(void) { return MaxUVecI16x8; }
828832
BinaryenOp BinaryenAvgrUVecI16x8(void) { return AvgrUVecI16x8; }
833+
BinaryenOp BinaryenAbsVecI32x4(void) { return AbsVecI32x4; }
829834
BinaryenOp BinaryenNegVecI32x4(void) { return NegVecI32x4; }
830835
BinaryenOp BinaryenAnyTrueVecI32x4(void) { return AnyTrueVecI32x4; }
831836
BinaryenOp BinaryenAllTrueVecI32x4(void) { return AllTrueVecI32x4; }
837+
BinaryenOp BinaryenBitmaskVecI32x4(void) { return BitmaskVecI32x4; }
832838
BinaryenOp BinaryenShlVecI32x4(void) { return ShlVecI32x4; }
833839
BinaryenOp BinaryenShrSVecI32x4(void) { return ShrSVecI32x4; }
834840
BinaryenOp BinaryenShrUVecI32x4(void) { return ShrUVecI32x4; }

src/binaryen-c.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -464,9 +464,11 @@ BINARYEN_API BinaryenOp BinaryenOrVec128(void);
464464
BINARYEN_API BinaryenOp BinaryenXorVec128(void);
465465
BINARYEN_API BinaryenOp BinaryenAndNotVec128(void);
466466
BINARYEN_API BinaryenOp BinaryenBitselectVec128(void);
467+
BINARYEN_API BinaryenOp BinaryenAbsVecI8x16(void);
467468
BINARYEN_API BinaryenOp BinaryenNegVecI8x16(void);
468469
BINARYEN_API BinaryenOp BinaryenAnyTrueVecI8x16(void);
469470
BINARYEN_API BinaryenOp BinaryenAllTrueVecI8x16(void);
471+
BINARYEN_API BinaryenOp BinaryenBitmaskVecI8x16(void);
470472
BINARYEN_API BinaryenOp BinaryenShlVecI8x16(void);
471473
BINARYEN_API BinaryenOp BinaryenShrSVecI8x16(void);
472474
BINARYEN_API BinaryenOp BinaryenShrUVecI8x16(void);
@@ -482,9 +484,11 @@ BINARYEN_API BinaryenOp BinaryenMinUVecI8x16(void);
482484
BINARYEN_API BinaryenOp BinaryenMaxSVecI8x16(void);
483485
BINARYEN_API BinaryenOp BinaryenMaxUVecI8x16(void);
484486
BINARYEN_API BinaryenOp BinaryenAvgrUVecI8x16(void);
487+
BINARYEN_API BinaryenOp BinaryenAbsVecI16x8(void);
485488
BINARYEN_API BinaryenOp BinaryenNegVecI16x8(void);
486489
BINARYEN_API BinaryenOp BinaryenAnyTrueVecI16x8(void);
487490
BINARYEN_API BinaryenOp BinaryenAllTrueVecI16x8(void);
491+
BINARYEN_API BinaryenOp BinaryenBitmaskVecI16x8(void);
488492
BINARYEN_API BinaryenOp BinaryenShlVecI16x8(void);
489493
BINARYEN_API BinaryenOp BinaryenShrSVecI16x8(void);
490494
BINARYEN_API BinaryenOp BinaryenShrUVecI16x8(void);
@@ -500,9 +504,11 @@ BINARYEN_API BinaryenOp BinaryenMinUVecI16x8(void);
500504
BINARYEN_API BinaryenOp BinaryenMaxSVecI16x8(void);
501505
BINARYEN_API BinaryenOp BinaryenMaxUVecI16x8(void);
502506
BINARYEN_API BinaryenOp BinaryenAvgrUVecI16x8(void);
507+
BINARYEN_API BinaryenOp BinaryenAbsVecI32x4(void);
503508
BINARYEN_API BinaryenOp BinaryenNegVecI32x4(void);
504509
BINARYEN_API BinaryenOp BinaryenAnyTrueVecI32x4(void);
505510
BINARYEN_API BinaryenOp BinaryenAllTrueVecI32x4(void);
511+
BINARYEN_API BinaryenOp BinaryenBitmaskVecI32x4(void);
506512
BINARYEN_API BinaryenOp BinaryenShlVecI32x4(void);
507513
BINARYEN_API BinaryenOp BinaryenShrSVecI32x4(void);
508514
BINARYEN_API BinaryenOp BinaryenShrUVecI32x4(void);

src/gen-s-parser.inc

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -676,6 +676,9 @@ switch (op[0]) {
676676
switch (op[6]) {
677677
case 'a': {
678678
switch (op[7]) {
679+
case 'b':
680+
if (strcmp(op, "i16x8.abs") == 0) { return makeUnary(s, UnaryOp::AbsVecI16x8); }
681+
goto parse_error;
679682
case 'd': {
680683
switch (op[9]) {
681684
case '\0':
@@ -707,6 +710,9 @@ switch (op[0]) {
707710
default: goto parse_error;
708711
}
709712
}
713+
case 'b':
714+
if (strcmp(op, "i16x8.bitmask") == 0) { return makeUnary(s, UnaryOp::BitmaskVecI16x8); }
715+
goto parse_error;
710716
case 'e': {
711717
switch (op[7]) {
712718
case 'q':
@@ -1395,6 +1401,9 @@ switch (op[0]) {
13951401
switch (op[6]) {
13961402
case 'a': {
13971403
switch (op[7]) {
1404+
case 'b':
1405+
if (strcmp(op, "i32x4.abs") == 0) { return makeUnary(s, UnaryOp::AbsVecI32x4); }
1406+
goto parse_error;
13981407
case 'd':
13991408
if (strcmp(op, "i32x4.add") == 0) { return makeBinary(s, BinaryOp::AddVecI32x4); }
14001409
goto parse_error;
@@ -1407,6 +1416,9 @@ switch (op[0]) {
14071416
default: goto parse_error;
14081417
}
14091418
}
1419+
case 'b':
1420+
if (strcmp(op, "i32x4.bitmask") == 0) { return makeUnary(s, UnaryOp::BitmaskVecI32x4); }
1421+
goto parse_error;
14101422
case 'd':
14111423
if (strcmp(op, "i32x4.dot_i16x8_s") == 0) { return makeBinary(s, BinaryOp::DotSVecI16x8ToVecI32x4); }
14121424
goto parse_error;
@@ -2222,6 +2234,9 @@ switch (op[0]) {
22222234
switch (op[6]) {
22232235
case 'a': {
22242236
switch (op[7]) {
2237+
case 'b':
2238+
if (strcmp(op, "i8x16.abs") == 0) { return makeUnary(s, UnaryOp::AbsVecI8x16); }
2239+
goto parse_error;
22252240
case 'd': {
22262241
switch (op[9]) {
22272242
case '\0':
@@ -2253,6 +2268,9 @@ switch (op[0]) {
22532268
default: goto parse_error;
22542269
}
22552270
}
2271+
case 'b':
2272+
if (strcmp(op, "i8x16.bitmask") == 0) { return makeUnary(s, UnaryOp::BitmaskVecI8x16); }
2273+
goto parse_error;
22562274
case 'e': {
22572275
switch (op[7]) {
22582276
case 'q':

src/ir/cost.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,15 +152,21 @@ struct CostAnalyzer : public Visitor<CostAnalyzer, Index> {
152152
case SplatVecF32x4:
153153
case SplatVecF64x2:
154154
case NotVec128:
155+
case AbsVecI8x16:
155156
case NegVecI8x16:
156157
case AnyTrueVecI8x16:
157158
case AllTrueVecI8x16:
159+
case BitmaskVecI8x16:
160+
case AbsVecI16x8:
158161
case NegVecI16x8:
159162
case AnyTrueVecI16x8:
160163
case AllTrueVecI16x8:
164+
case BitmaskVecI16x8:
165+
case AbsVecI32x4:
161166
case NegVecI32x4:
162167
case AnyTrueVecI32x4:
163168
case AllTrueVecI32x4:
169+
case BitmaskVecI32x4:
164170
case NegVecI64x2:
165171
case AnyTrueVecI64x2:
166172
case AllTrueVecI64x2:

src/js/binaryen.js-post.js

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -344,9 +344,11 @@ function initializeConstants() {
344344
'XorVec128',
345345
'AndNotVec128',
346346
'BitselectVec128',
347+
'AbsVecI8x16',
347348
'NegVecI8x16',
348349
'AnyTrueVecI8x16',
349350
'AllTrueVecI8x16',
351+
'BitmaskVecI8x16',
350352
'ShlVecI8x16',
351353
'ShrSVecI8x16',
352354
'ShrUVecI8x16',
@@ -362,9 +364,11 @@ function initializeConstants() {
362364
'MaxSVecI8x16',
363365
'MaxUVecI8x16',
364366
'AvgrUVecI8x16',
367+
'AbsVecI16x8',
365368
'NegVecI16x8',
366369
'AnyTrueVecI16x8',
367370
'AllTrueVecI16x8',
371+
'BitmaskVecI16x8',
368372
'ShlVecI16x8',
369373
'ShrSVecI16x8',
370374
'ShrUVecI16x8',
@@ -381,9 +385,11 @@ function initializeConstants() {
381385
'MaxUVecI16x8',
382386
'AvgrUVecI16x8',
383387
'DotSVecI16x8ToVecI32x4',
388+
'AbsVecI32x4',
384389
'NegVecI32x4',
385390
'AnyTrueVecI32x4',
386391
'AllTrueVecI32x4',
392+
'BitmaskVecI32x4',
387393
'ShlVecI32x4',
388394
'ShrSVecI32x4',
389395
'ShrUVecI32x4',
@@ -1466,6 +1472,9 @@ function wrapModule(module, self) {
14661472
'ge_u': function(left, right) {
14671473
return Module['_BinaryenBinary'](module, Module['GeUVecI8x16'], left, right);
14681474
},
1475+
'abs': function(value) {
1476+
return Module['_BinaryenUnary'](module, Module['AbsVecI8x16'], value);
1477+
},
14691478
'neg': function(value) {
14701479
return Module['_BinaryenUnary'](module, Module['NegVecI8x16'], value);
14711480
},
@@ -1475,6 +1484,9 @@ function wrapModule(module, self) {
14751484
'all_true': function(value) {
14761485
return Module['_BinaryenUnary'](module, Module['AllTrueVecI8x16'], value);
14771486
},
1487+
'bitmask': function(value) {
1488+
return Module['_BinaryenUnary'](module, Module['BitmaskVecI8x16'], value);
1489+
},
14781490
'shl': function(vec, shift) {
14791491
return Module['_BinaryenSIMDShift'](module, Module['ShlVecI8x16'], vec, shift);
14801492
},
@@ -1571,6 +1583,9 @@ function wrapModule(module, self) {
15711583
'ge_u': function(left, right) {
15721584
return Module['_BinaryenBinary'](module, Module['GeUVecI16x8'], left, right);
15731585
},
1586+
'abs': function(value) {
1587+
return Module['_BinaryenUnary'](module, Module['AbsVecI16x8'], value);
1588+
},
15741589
'neg': function(value) {
15751590
return Module['_BinaryenUnary'](module, Module['NegVecI16x8'], value);
15761591
},
@@ -1580,6 +1595,9 @@ function wrapModule(module, self) {
15801595
'all_true': function(value) {
15811596
return Module['_BinaryenUnary'](module, Module['AllTrueVecI16x8'], value);
15821597
},
1598+
'bitmask': function(value) {
1599+
return Module['_BinaryenUnary'](module, Module['BitmaskVecI16x8'], value);
1600+
},
15831601
'shl': function(vec, shift) {
15841602
return Module['_BinaryenSIMDShift'](module, Module['ShlVecI16x8'], vec, shift);
15851603
},
@@ -1691,6 +1709,9 @@ function wrapModule(module, self) {
16911709
'ge_u': function(left, right) {
16921710
return Module['_BinaryenBinary'](module, Module['GeUVecI32x4'], left, right);
16931711
},
1712+
'abs': function(value) {
1713+
return Module['_BinaryenUnary'](module, Module['AbsVecI32x4'], value);
1714+
},
16941715
'neg': function(value) {
16951716
return Module['_BinaryenUnary'](module, Module['NegVecI32x4'], value);
16961717
},
@@ -1700,6 +1721,9 @@ function wrapModule(module, self) {
17001721
'all_true': function(value) {
17011722
return Module['_BinaryenUnary'](module, Module['AllTrueVecI32x4'], value);
17021723
},
1724+
'bitmask': function(value) {
1725+
return Module['_BinaryenUnary'](module, Module['BitmaskVecI32x4'], value);
1726+
},
17031727
'shl': function(vec, shift) {
17041728
return Module['_BinaryenSIMDShift'](module, Module['ShlVecI32x4'], vec, shift);
17051729
},

src/literal.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -330,9 +330,11 @@ class Literal {
330330
Literal orV128(const Literal& other) const;
331331
Literal xorV128(const Literal& other) const;
332332
Literal bitselectV128(const Literal& left, const Literal& right) const;
333+
Literal absI8x16() const;
333334
Literal negI8x16() const;
334335
Literal anyTrueI8x16() const;
335336
Literal allTrueI8x16() const;
337+
Literal bitmaskI8x16() const;
336338
Literal shlI8x16(const Literal& other) const;
337339
Literal shrSI8x16(const Literal& other) const;
338340
Literal shrUI8x16(const Literal& other) const;
@@ -348,9 +350,11 @@ class Literal {
348350
Literal maxSI8x16(const Literal& other) const;
349351
Literal maxUI8x16(const Literal& other) const;
350352
Literal avgrUI8x16(const Literal& other) const;
353+
Literal absI16x8() const;
351354
Literal negI16x8() const;
352355
Literal anyTrueI16x8() const;
353356
Literal allTrueI16x8() const;
357+
Literal bitmaskI16x8() const;
354358
Literal shlI16x8(const Literal& other) const;
355359
Literal shrSI16x8(const Literal& other) const;
356360
Literal shrUI16x8(const Literal& other) const;
@@ -366,9 +370,11 @@ class Literal {
366370
Literal maxSI16x8(const Literal& other) const;
367371
Literal maxUI16x8(const Literal& other) const;
368372
Literal avgrUI16x8(const Literal& other) const;
373+
Literal absI32x4() const;
369374
Literal negI32x4() const;
370375
Literal anyTrueI32x4() const;
371376
Literal allTrueI32x4() const;
377+
Literal bitmaskI32x4() const;
372378
Literal shlI32x4(const Literal& other) const;
373379
Literal shrSI32x4(const Literal& other) const;
374380
Literal shrUI32x4(const Literal& other) const;

src/passes/Print.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -717,6 +717,9 @@ struct PrintExpressionContents
717717
case NotVec128:
718718
o << "v128.not";
719719
break;
720+
case AbsVecI8x16:
721+
o << "i8x16.abs";
722+
break;
720723
case NegVecI8x16:
721724
o << "i8x16.neg";
722725
break;
@@ -726,6 +729,12 @@ struct PrintExpressionContents
726729
case AllTrueVecI8x16:
727730
o << "i8x16.all_true";
728731
break;
732+
case BitmaskVecI8x16:
733+
o << "i8x16.bitmask";
734+
break;
735+
case AbsVecI16x8:
736+
o << "i16x8.abs";
737+
break;
729738
case NegVecI16x8:
730739
o << "i16x8.neg";
731740
break;
@@ -735,6 +744,12 @@ struct PrintExpressionContents
735744
case AllTrueVecI16x8:
736745
o << "i16x8.all_true";
737746
break;
747+
case BitmaskVecI16x8:
748+
o << "i16x8.bitmask";
749+
break;
750+
case AbsVecI32x4:
751+
o << "i32x4.abs";
752+
break;
738753
case NegVecI32x4:
739754
o << "i32x4.neg";
740755
break;
@@ -744,6 +759,9 @@ struct PrintExpressionContents
744759
case AllTrueVecI32x4:
745760
o << "i32x4.all_true";
746761
break;
762+
case BitmaskVecI32x4:
763+
o << "i32x4.bitmask";
764+
break;
747765
case NegVecI64x2:
748766
o << "i64x2.neg";
749767
break;

0 commit comments

Comments
 (0)