Skip to content

Commit

Permalink
SIMD integer abs and bitmask instructions (#2703)
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
tlively authored Mar 20, 2020
1 parent 39fda77 commit 03ae7fc
Show file tree
Hide file tree
Showing 26 changed files with 2,355 additions and 1,737 deletions.
6 changes: 6 additions & 0 deletions scripts/gen-s-parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -360,9 +360,11 @@
("v128.xor", "makeBinary(s, BinaryOp::XorVec128)"),
("v128.andnot", "makeBinary(s, BinaryOp::AndNotVec128)"),
("v128.bitselect", "makeSIMDTernary(s, SIMDTernaryOp::Bitselect)"),
("i8x16.abs", "makeUnary(s, UnaryOp::AbsVecI8x16)"),
("i8x16.neg", "makeUnary(s, UnaryOp::NegVecI8x16)"),
("i8x16.any_true", "makeUnary(s, UnaryOp::AnyTrueVecI8x16)"),
("i8x16.all_true", "makeUnary(s, UnaryOp::AllTrueVecI8x16)"),
("i8x16.bitmask", "makeUnary(s, UnaryOp::BitmaskVecI8x16)"),
("i8x16.shl", "makeSIMDShift(s, SIMDShiftOp::ShlVecI8x16)"),
("i8x16.shr_s", "makeSIMDShift(s, SIMDShiftOp::ShrSVecI8x16)"),
("i8x16.shr_u", "makeSIMDShift(s, SIMDShiftOp::ShrUVecI8x16)"),
Expand All @@ -378,9 +380,11 @@
("i8x16.max_s", "makeBinary(s, BinaryOp::MaxSVecI8x16)"),
("i8x16.max_u", "makeBinary(s, BinaryOp::MaxUVecI8x16)"),
("i8x16.avgr_u", "makeBinary(s, BinaryOp::AvgrUVecI8x16)"),
("i16x8.abs", "makeUnary(s, UnaryOp::AbsVecI16x8)"),
("i16x8.neg", "makeUnary(s, UnaryOp::NegVecI16x8)"),
("i16x8.any_true", "makeUnary(s, UnaryOp::AnyTrueVecI16x8)"),
("i16x8.all_true", "makeUnary(s, UnaryOp::AllTrueVecI16x8)"),
("i16x8.bitmask", "makeUnary(s, UnaryOp::BitmaskVecI16x8)"),
("i16x8.shl", "makeSIMDShift(s, SIMDShiftOp::ShlVecI16x8)"),
("i16x8.shr_s", "makeSIMDShift(s, SIMDShiftOp::ShrSVecI16x8)"),
("i16x8.shr_u", "makeSIMDShift(s, SIMDShiftOp::ShrUVecI16x8)"),
Expand All @@ -396,9 +400,11 @@
("i16x8.max_s", "makeBinary(s, BinaryOp::MaxSVecI16x8)"),
("i16x8.max_u", "makeBinary(s, BinaryOp::MaxUVecI16x8)"),
("i16x8.avgr_u", "makeBinary(s, BinaryOp::AvgrUVecI16x8)"),
("i32x4.abs", "makeUnary(s, UnaryOp::AbsVecI32x4)"),
("i32x4.neg", "makeUnary(s, UnaryOp::NegVecI32x4)"),
("i32x4.any_true", "makeUnary(s, UnaryOp::AnyTrueVecI32x4)"),
("i32x4.all_true", "makeUnary(s, UnaryOp::AllTrueVecI32x4)"),
("i32x4.bitmask", "makeUnary(s, UnaryOp::BitmaskVecI32x4)"),
("i32x4.shl", "makeSIMDShift(s, SIMDShiftOp::ShlVecI32x4)"),
("i32x4.shr_s", "makeSIMDShift(s, SIMDShiftOp::ShrSVecI32x4)"),
("i32x4.shr_u", "makeSIMDShift(s, SIMDShiftOp::ShrUVecI32x4)"),
Expand Down
6 changes: 6 additions & 0 deletions src/binaryen-c.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -790,9 +790,11 @@ BinaryenOp BinaryenOrVec128(void) { return OrVec128; }
BinaryenOp BinaryenXorVec128(void) { return XorVec128; }
BinaryenOp BinaryenAndNotVec128(void) { return AndNotVec128; }
BinaryenOp BinaryenBitselectVec128(void) { return Bitselect; }
BinaryenOp BinaryenAbsVecI8x16(void) { return AbsVecI8x16; }
BinaryenOp BinaryenNegVecI8x16(void) { return NegVecI8x16; }
BinaryenOp BinaryenAnyTrueVecI8x16(void) { return AnyTrueVecI8x16; }
BinaryenOp BinaryenAllTrueVecI8x16(void) { return AllTrueVecI8x16; }
BinaryenOp BinaryenBitmaskVecI8x16(void) { return BitmaskVecI8x16; }
BinaryenOp BinaryenShlVecI8x16(void) { return ShlVecI8x16; }
BinaryenOp BinaryenShrSVecI8x16(void) { return ShrSVecI8x16; }
BinaryenOp BinaryenShrUVecI8x16(void) { return ShrUVecI8x16; }
Expand All @@ -808,9 +810,11 @@ BinaryenOp BinaryenMinUVecI8x16(void) { return MinUVecI8x16; }
BinaryenOp BinaryenMaxSVecI8x16(void) { return MaxSVecI8x16; }
BinaryenOp BinaryenMaxUVecI8x16(void) { return MaxUVecI8x16; }
BinaryenOp BinaryenAvgrUVecI8x16(void) { return AvgrUVecI8x16; }
BinaryenOp BinaryenAbsVecI16x8(void) { return AbsVecI16x8; }
BinaryenOp BinaryenNegVecI16x8(void) { return NegVecI16x8; }
BinaryenOp BinaryenAnyTrueVecI16x8(void) { return AnyTrueVecI16x8; }
BinaryenOp BinaryenAllTrueVecI16x8(void) { return AllTrueVecI16x8; }
BinaryenOp BinaryenBitmaskVecI16x8(void) { return BitmaskVecI16x8; }
BinaryenOp BinaryenShlVecI16x8(void) { return ShlVecI16x8; }
BinaryenOp BinaryenShrSVecI16x8(void) { return ShrSVecI16x8; }
BinaryenOp BinaryenShrUVecI16x8(void) { return ShrUVecI16x8; }
Expand All @@ -826,9 +830,11 @@ BinaryenOp BinaryenMinUVecI16x8(void) { return MinUVecI16x8; }
BinaryenOp BinaryenMaxSVecI16x8(void) { return MaxSVecI16x8; }
BinaryenOp BinaryenMaxUVecI16x8(void) { return MaxUVecI16x8; }
BinaryenOp BinaryenAvgrUVecI16x8(void) { return AvgrUVecI16x8; }
BinaryenOp BinaryenAbsVecI32x4(void) { return AbsVecI32x4; }
BinaryenOp BinaryenNegVecI32x4(void) { return NegVecI32x4; }
BinaryenOp BinaryenAnyTrueVecI32x4(void) { return AnyTrueVecI32x4; }
BinaryenOp BinaryenAllTrueVecI32x4(void) { return AllTrueVecI32x4; }
BinaryenOp BinaryenBitmaskVecI32x4(void) { return BitmaskVecI32x4; }
BinaryenOp BinaryenShlVecI32x4(void) { return ShlVecI32x4; }
BinaryenOp BinaryenShrSVecI32x4(void) { return ShrSVecI32x4; }
BinaryenOp BinaryenShrUVecI32x4(void) { return ShrUVecI32x4; }
Expand Down
6 changes: 6 additions & 0 deletions src/binaryen-c.h
Original file line number Diff line number Diff line change
Expand Up @@ -464,9 +464,11 @@ BINARYEN_API BinaryenOp BinaryenOrVec128(void);
BINARYEN_API BinaryenOp BinaryenXorVec128(void);
BINARYEN_API BinaryenOp BinaryenAndNotVec128(void);
BINARYEN_API BinaryenOp BinaryenBitselectVec128(void);
BINARYEN_API BinaryenOp BinaryenAbsVecI8x16(void);
BINARYEN_API BinaryenOp BinaryenNegVecI8x16(void);
BINARYEN_API BinaryenOp BinaryenAnyTrueVecI8x16(void);
BINARYEN_API BinaryenOp BinaryenAllTrueVecI8x16(void);
BINARYEN_API BinaryenOp BinaryenBitmaskVecI8x16(void);
BINARYEN_API BinaryenOp BinaryenShlVecI8x16(void);
BINARYEN_API BinaryenOp BinaryenShrSVecI8x16(void);
BINARYEN_API BinaryenOp BinaryenShrUVecI8x16(void);
Expand All @@ -482,9 +484,11 @@ BINARYEN_API BinaryenOp BinaryenMinUVecI8x16(void);
BINARYEN_API BinaryenOp BinaryenMaxSVecI8x16(void);
BINARYEN_API BinaryenOp BinaryenMaxUVecI8x16(void);
BINARYEN_API BinaryenOp BinaryenAvgrUVecI8x16(void);
BINARYEN_API BinaryenOp BinaryenAbsVecI16x8(void);
BINARYEN_API BinaryenOp BinaryenNegVecI16x8(void);
BINARYEN_API BinaryenOp BinaryenAnyTrueVecI16x8(void);
BINARYEN_API BinaryenOp BinaryenAllTrueVecI16x8(void);
BINARYEN_API BinaryenOp BinaryenBitmaskVecI16x8(void);
BINARYEN_API BinaryenOp BinaryenShlVecI16x8(void);
BINARYEN_API BinaryenOp BinaryenShrSVecI16x8(void);
BINARYEN_API BinaryenOp BinaryenShrUVecI16x8(void);
Expand All @@ -500,9 +504,11 @@ BINARYEN_API BinaryenOp BinaryenMinUVecI16x8(void);
BINARYEN_API BinaryenOp BinaryenMaxSVecI16x8(void);
BINARYEN_API BinaryenOp BinaryenMaxUVecI16x8(void);
BINARYEN_API BinaryenOp BinaryenAvgrUVecI16x8(void);
BINARYEN_API BinaryenOp BinaryenAbsVecI32x4(void);
BINARYEN_API BinaryenOp BinaryenNegVecI32x4(void);
BINARYEN_API BinaryenOp BinaryenAnyTrueVecI32x4(void);
BINARYEN_API BinaryenOp BinaryenAllTrueVecI32x4(void);
BINARYEN_API BinaryenOp BinaryenBitmaskVecI32x4(void);
BINARYEN_API BinaryenOp BinaryenShlVecI32x4(void);
BINARYEN_API BinaryenOp BinaryenShrSVecI32x4(void);
BINARYEN_API BinaryenOp BinaryenShrUVecI32x4(void);
Expand Down
18 changes: 18 additions & 0 deletions src/gen-s-parser.inc
Original file line number Diff line number Diff line change
Expand Up @@ -676,6 +676,9 @@ switch (op[0]) {
switch (op[6]) {
case 'a': {
switch (op[7]) {
case 'b':
if (strcmp(op, "i16x8.abs") == 0) { return makeUnary(s, UnaryOp::AbsVecI16x8); }
goto parse_error;
case 'd': {
switch (op[9]) {
case '\0':
Expand Down Expand Up @@ -707,6 +710,9 @@ switch (op[0]) {
default: goto parse_error;
}
}
case 'b':
if (strcmp(op, "i16x8.bitmask") == 0) { return makeUnary(s, UnaryOp::BitmaskVecI16x8); }
goto parse_error;
case 'e': {
switch (op[7]) {
case 'q':
Expand Down Expand Up @@ -1395,6 +1401,9 @@ switch (op[0]) {
switch (op[6]) {
case 'a': {
switch (op[7]) {
case 'b':
if (strcmp(op, "i32x4.abs") == 0) { return makeUnary(s, UnaryOp::AbsVecI32x4); }
goto parse_error;
case 'd':
if (strcmp(op, "i32x4.add") == 0) { return makeBinary(s, BinaryOp::AddVecI32x4); }
goto parse_error;
Expand All @@ -1407,6 +1416,9 @@ switch (op[0]) {
default: goto parse_error;
}
}
case 'b':
if (strcmp(op, "i32x4.bitmask") == 0) { return makeUnary(s, UnaryOp::BitmaskVecI32x4); }
goto parse_error;
case 'd':
if (strcmp(op, "i32x4.dot_i16x8_s") == 0) { return makeBinary(s, BinaryOp::DotSVecI16x8ToVecI32x4); }
goto parse_error;
Expand Down Expand Up @@ -2222,6 +2234,9 @@ switch (op[0]) {
switch (op[6]) {
case 'a': {
switch (op[7]) {
case 'b':
if (strcmp(op, "i8x16.abs") == 0) { return makeUnary(s, UnaryOp::AbsVecI8x16); }
goto parse_error;
case 'd': {
switch (op[9]) {
case '\0':
Expand Down Expand Up @@ -2253,6 +2268,9 @@ switch (op[0]) {
default: goto parse_error;
}
}
case 'b':
if (strcmp(op, "i8x16.bitmask") == 0) { return makeUnary(s, UnaryOp::BitmaskVecI8x16); }
goto parse_error;
case 'e': {
switch (op[7]) {
case 'q':
Expand Down
6 changes: 6 additions & 0 deletions src/ir/cost.h
Original file line number Diff line number Diff line change
Expand Up @@ -152,15 +152,21 @@ struct CostAnalyzer : public Visitor<CostAnalyzer, Index> {
case SplatVecF32x4:
case SplatVecF64x2:
case NotVec128:
case AbsVecI8x16:
case NegVecI8x16:
case AnyTrueVecI8x16:
case AllTrueVecI8x16:
case BitmaskVecI8x16:
case AbsVecI16x8:
case NegVecI16x8:
case AnyTrueVecI16x8:
case AllTrueVecI16x8:
case BitmaskVecI16x8:
case AbsVecI32x4:
case NegVecI32x4:
case AnyTrueVecI32x4:
case AllTrueVecI32x4:
case BitmaskVecI32x4:
case NegVecI64x2:
case AnyTrueVecI64x2:
case AllTrueVecI64x2:
Expand Down
24 changes: 24 additions & 0 deletions src/js/binaryen.js-post.js
Original file line number Diff line number Diff line change
Expand Up @@ -344,9 +344,11 @@ function initializeConstants() {
'XorVec128',
'AndNotVec128',
'BitselectVec128',
'AbsVecI8x16',
'NegVecI8x16',
'AnyTrueVecI8x16',
'AllTrueVecI8x16',
'BitmaskVecI8x16',
'ShlVecI8x16',
'ShrSVecI8x16',
'ShrUVecI8x16',
Expand All @@ -362,9 +364,11 @@ function initializeConstants() {
'MaxSVecI8x16',
'MaxUVecI8x16',
'AvgrUVecI8x16',
'AbsVecI16x8',
'NegVecI16x8',
'AnyTrueVecI16x8',
'AllTrueVecI16x8',
'BitmaskVecI16x8',
'ShlVecI16x8',
'ShrSVecI16x8',
'ShrUVecI16x8',
Expand All @@ -381,9 +385,11 @@ function initializeConstants() {
'MaxUVecI16x8',
'AvgrUVecI16x8',
'DotSVecI16x8ToVecI32x4',
'AbsVecI32x4',
'NegVecI32x4',
'AnyTrueVecI32x4',
'AllTrueVecI32x4',
'BitmaskVecI32x4',
'ShlVecI32x4',
'ShrSVecI32x4',
'ShrUVecI32x4',
Expand Down Expand Up @@ -1466,6 +1472,9 @@ function wrapModule(module, self) {
'ge_u': function(left, right) {
return Module['_BinaryenBinary'](module, Module['GeUVecI8x16'], left, right);
},
'abs': function(value) {
return Module['_BinaryenUnary'](module, Module['AbsVecI8x16'], value);
},
'neg': function(value) {
return Module['_BinaryenUnary'](module, Module['NegVecI8x16'], value);
},
Expand All @@ -1475,6 +1484,9 @@ function wrapModule(module, self) {
'all_true': function(value) {
return Module['_BinaryenUnary'](module, Module['AllTrueVecI8x16'], value);
},
'bitmask': function(value) {
return Module['_BinaryenUnary'](module, Module['BitmaskVecI8x16'], value);
},
'shl': function(vec, shift) {
return Module['_BinaryenSIMDShift'](module, Module['ShlVecI8x16'], vec, shift);
},
Expand Down Expand Up @@ -1571,6 +1583,9 @@ function wrapModule(module, self) {
'ge_u': function(left, right) {
return Module['_BinaryenBinary'](module, Module['GeUVecI16x8'], left, right);
},
'abs': function(value) {
return Module['_BinaryenUnary'](module, Module['AbsVecI16x8'], value);
},
'neg': function(value) {
return Module['_BinaryenUnary'](module, Module['NegVecI16x8'], value);
},
Expand All @@ -1580,6 +1595,9 @@ function wrapModule(module, self) {
'all_true': function(value) {
return Module['_BinaryenUnary'](module, Module['AllTrueVecI16x8'], value);
},
'bitmask': function(value) {
return Module['_BinaryenUnary'](module, Module['BitmaskVecI16x8'], value);
},
'shl': function(vec, shift) {
return Module['_BinaryenSIMDShift'](module, Module['ShlVecI16x8'], vec, shift);
},
Expand Down Expand Up @@ -1691,6 +1709,9 @@ function wrapModule(module, self) {
'ge_u': function(left, right) {
return Module['_BinaryenBinary'](module, Module['GeUVecI32x4'], left, right);
},
'abs': function(value) {
return Module['_BinaryenUnary'](module, Module['AbsVecI32x4'], value);
},
'neg': function(value) {
return Module['_BinaryenUnary'](module, Module['NegVecI32x4'], value);
},
Expand All @@ -1700,6 +1721,9 @@ function wrapModule(module, self) {
'all_true': function(value) {
return Module['_BinaryenUnary'](module, Module['AllTrueVecI32x4'], value);
},
'bitmask': function(value) {
return Module['_BinaryenUnary'](module, Module['BitmaskVecI32x4'], value);
},
'shl': function(vec, shift) {
return Module['_BinaryenSIMDShift'](module, Module['ShlVecI32x4'], vec, shift);
},
Expand Down
6 changes: 6 additions & 0 deletions src/literal.h
Original file line number Diff line number Diff line change
Expand Up @@ -330,9 +330,11 @@ class Literal {
Literal orV128(const Literal& other) const;
Literal xorV128(const Literal& other) const;
Literal bitselectV128(const Literal& left, const Literal& right) const;
Literal absI8x16() const;
Literal negI8x16() const;
Literal anyTrueI8x16() const;
Literal allTrueI8x16() const;
Literal bitmaskI8x16() const;
Literal shlI8x16(const Literal& other) const;
Literal shrSI8x16(const Literal& other) const;
Literal shrUI8x16(const Literal& other) const;
Expand All @@ -348,9 +350,11 @@ class Literal {
Literal maxSI8x16(const Literal& other) const;
Literal maxUI8x16(const Literal& other) const;
Literal avgrUI8x16(const Literal& other) const;
Literal absI16x8() const;
Literal negI16x8() const;
Literal anyTrueI16x8() const;
Literal allTrueI16x8() const;
Literal bitmaskI16x8() const;
Literal shlI16x8(const Literal& other) const;
Literal shrSI16x8(const Literal& other) const;
Literal shrUI16x8(const Literal& other) const;
Expand All @@ -366,9 +370,11 @@ class Literal {
Literal maxSI16x8(const Literal& other) const;
Literal maxUI16x8(const Literal& other) const;
Literal avgrUI16x8(const Literal& other) const;
Literal absI32x4() const;
Literal negI32x4() const;
Literal anyTrueI32x4() const;
Literal allTrueI32x4() const;
Literal bitmaskI32x4() const;
Literal shlI32x4(const Literal& other) const;
Literal shrSI32x4(const Literal& other) const;
Literal shrUI32x4(const Literal& other) const;
Expand Down
18 changes: 18 additions & 0 deletions src/passes/Print.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -717,6 +717,9 @@ struct PrintExpressionContents
case NotVec128:
o << "v128.not";
break;
case AbsVecI8x16:
o << "i8x16.abs";
break;
case NegVecI8x16:
o << "i8x16.neg";
break;
Expand All @@ -726,6 +729,12 @@ struct PrintExpressionContents
case AllTrueVecI8x16:
o << "i8x16.all_true";
break;
case BitmaskVecI8x16:
o << "i8x16.bitmask";
break;
case AbsVecI16x8:
o << "i16x8.abs";
break;
case NegVecI16x8:
o << "i16x8.neg";
break;
Expand All @@ -735,6 +744,12 @@ struct PrintExpressionContents
case AllTrueVecI16x8:
o << "i16x8.all_true";
break;
case BitmaskVecI16x8:
o << "i16x8.bitmask";
break;
case AbsVecI32x4:
o << "i32x4.abs";
break;
case NegVecI32x4:
o << "i32x4.neg";
break;
Expand All @@ -744,6 +759,9 @@ struct PrintExpressionContents
case AllTrueVecI32x4:
o << "i32x4.all_true";
break;
case BitmaskVecI32x4:
o << "i32x4.bitmask";
break;
case NegVecI64x2:
o << "i64x2.neg";
break;
Expand Down
Loading

0 comments on commit 03ae7fc

Please sign in to comment.