Skip to content

Commit 844998f

Browse files
authored
SIMD narrowing and widening operations (#2341)
1 parent 167acc7 commit 844998f

28 files changed

Lines changed: 2874 additions & 1263 deletions

build-js.sh

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -550,6 +550,18 @@ export_function "_BinaryenConvertSVecI32x4ToVecF32x4"
550550
export_function "_BinaryenConvertUVecI32x4ToVecF32x4"
551551
export_function "_BinaryenConvertSVecI64x2ToVecF64x2"
552552
export_function "_BinaryenConvertUVecI64x2ToVecF64x2"
553+
export_function "_BinaryenNarrowSVecI16x8ToVecI8x16"
554+
export_function "_BinaryenNarrowUVecI16x8ToVecI8x16"
555+
export_function "_BinaryenNarrowSVecI32x4ToVecI16x8"
556+
export_function "_BinaryenNarrowUVecI32x4ToVecI16x8"
557+
export_function "_BinaryenWidenLowSVecI8x16ToVecI16x8"
558+
export_function "_BinaryenWidenHighSVecI8x16ToVecI16x8"
559+
export_function "_BinaryenWidenLowUVecI8x16ToVecI16x8"
560+
export_function "_BinaryenWidenHighUVecI8x16ToVecI16x8"
561+
export_function "_BinaryenWidenLowSVecI16x8ToVecI32x4"
562+
export_function "_BinaryenWidenHighSVecI16x8ToVecI32x4"
563+
export_function "_BinaryenWidenLowUVecI16x8ToVecI32x4"
564+
export_function "_BinaryenWidenHighUVecI16x8ToVecI32x4"
553565

554566
# Expression creation
555567
export_function "_BinaryenBlock"

scripts/gen-s-parser.py

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -421,14 +421,26 @@
421421
("f64x2.div", "makeBinary(s, BinaryOp::DivVecF64x2)"),
422422
("f64x2.min", "makeBinary(s, BinaryOp::MinVecF64x2)"),
423423
("f64x2.max", "makeBinary(s, BinaryOp::MaxVecF64x2)"),
424-
("i32x4.trunc_sat_f32x4_s", "makeUnary(s, UnaryOp::TruncSatSVecF32x4ToVecI32x4)"),
425-
("i32x4.trunc_sat_f32x4_u", "makeUnary(s, UnaryOp::TruncSatUVecF32x4ToVecI32x4)"),
426-
("i64x2.trunc_sat_f64x2_s", "makeUnary(s, UnaryOp::TruncSatSVecF64x2ToVecI64x2)"),
427-
("i64x2.trunc_sat_f64x2_u", "makeUnary(s, UnaryOp::TruncSatUVecF64x2ToVecI64x2)"),
428-
("f32x4.convert_i32x4_s", "makeUnary(s, UnaryOp::ConvertSVecI32x4ToVecF32x4)"),
429-
("f32x4.convert_i32x4_u", "makeUnary(s, UnaryOp::ConvertUVecI32x4ToVecF32x4)"),
430-
("f64x2.convert_i64x2_s", "makeUnary(s, UnaryOp::ConvertSVecI64x2ToVecF64x2)"),
431-
("f64x2.convert_i64x2_u", "makeUnary(s, UnaryOp::ConvertUVecI64x2ToVecF64x2)"),
424+
("i32x4.trunc_sat_f32x4_s", "makeUnary(s, UnaryOp::TruncSatSVecF32x4ToVecI32x4)"),
425+
("i32x4.trunc_sat_f32x4_u", "makeUnary(s, UnaryOp::TruncSatUVecF32x4ToVecI32x4)"),
426+
("i64x2.trunc_sat_f64x2_s", "makeUnary(s, UnaryOp::TruncSatSVecF64x2ToVecI64x2)"),
427+
("i64x2.trunc_sat_f64x2_u", "makeUnary(s, UnaryOp::TruncSatUVecF64x2ToVecI64x2)"),
428+
("f32x4.convert_i32x4_s", "makeUnary(s, UnaryOp::ConvertSVecI32x4ToVecF32x4)"),
429+
("f32x4.convert_i32x4_u", "makeUnary(s, UnaryOp::ConvertUVecI32x4ToVecF32x4)"),
430+
("f64x2.convert_i64x2_s", "makeUnary(s, UnaryOp::ConvertSVecI64x2ToVecF64x2)"),
431+
("f64x2.convert_i64x2_u", "makeUnary(s, UnaryOp::ConvertUVecI64x2ToVecF64x2)"),
432+
("i8x16.narrow_i16x8_s", "makeBinary(s, BinaryOp::NarrowSVecI16x8ToVecI8x16)"),
433+
("i8x16.narrow_i16x8_u", "makeBinary(s, BinaryOp::NarrowUVecI16x8ToVecI8x16)"),
434+
("i16x8.narrow_i32x4_s", "makeBinary(s, BinaryOp::NarrowSVecI32x4ToVecI16x8)"),
435+
("i16x8.narrow_i32x4_u", "makeBinary(s, BinaryOp::NarrowUVecI32x4ToVecI16x8)"),
436+
("i16x8.widen_low_i8x16_s", "makeUnary(s, UnaryOp::WidenLowSVecI8x16ToVecI16x8)"),
437+
("i16x8.widen_high_i8x16_s", "makeUnary(s, UnaryOp::WidenHighSVecI8x16ToVecI16x8)"),
438+
("i16x8.widen_low_i8x16_u", "makeUnary(s, UnaryOp::WidenLowUVecI8x16ToVecI16x8)"),
439+
("i16x8.widen_high_i8x16_u", "makeUnary(s, UnaryOp::WidenHighUVecI8x16ToVecI16x8)"),
440+
("i32x4.widen_low_i16x8_s", "makeUnary(s, UnaryOp::WidenLowSVecI16x8ToVecI32x4)"),
441+
("i32x4.widen_high_i16x8_s", "makeUnary(s, UnaryOp::WidenHighSVecI16x8ToVecI32x4)"),
442+
("i32x4.widen_low_i16x8_u", "makeUnary(s, UnaryOp::WidenLowUVecI16x8ToVecI32x4)"),
443+
("i32x4.widen_high_i16x8_u", "makeUnary(s, UnaryOp::WidenHighUVecI16x8ToVecI32x4)"),
432444
# exception handling instructions
433445
("try", "makeTry(s)"),
434446
("throw", "makeThrow(s)"),

src/binaryen-c.cpp

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -880,6 +880,42 @@ BinaryenOp BinaryenConvertSVecI64x2ToVecF64x2(void) {
880880
BinaryenOp BinaryenConvertUVecI64x2ToVecF64x2(void) {
881881
return ConvertUVecI64x2ToVecF64x2;
882882
}
883+
BinaryenOp BinaryenNarrowSVecI16x8ToVecI8x16(void) {
884+
return NarrowSVecI16x8ToVecI8x16;
885+
}
886+
BinaryenOp BinaryenNarrowUVecI16x8ToVecI8x16(void) {
887+
return NarrowUVecI16x8ToVecI8x16;
888+
}
889+
BinaryenOp BinaryenNarrowSVecI32x4ToVecI16x8(void) {
890+
return NarrowSVecI32x4ToVecI16x8;
891+
}
892+
BinaryenOp BinaryenNarrowUVecI32x4ToVecI16x8(void) {
893+
return NarrowUVecI32x4ToVecI16x8;
894+
}
895+
BinaryenOp BinaryenWidenLowSVecI8x16ToVecI16x8(void) {
896+
return WidenLowSVecI8x16ToVecI16x8;
897+
}
898+
BinaryenOp BinaryenWidenHighSVecI8x16ToVecI16x8(void) {
899+
return WidenHighSVecI8x16ToVecI16x8;
900+
}
901+
BinaryenOp BinaryenWidenLowUVecI8x16ToVecI16x8(void) {
902+
return WidenLowUVecI8x16ToVecI16x8;
903+
}
904+
BinaryenOp BinaryenWidenHighUVecI8x16ToVecI16x8(void) {
905+
return WidenHighUVecI8x16ToVecI16x8;
906+
}
907+
BinaryenOp BinaryenWidenLowSVecI16x8ToVecI32x4(void) {
908+
return WidenLowSVecI16x8ToVecI32x4;
909+
}
910+
BinaryenOp BinaryenWidenHighSVecI16x8ToVecI32x4(void) {
911+
return WidenHighSVecI16x8ToVecI32x4;
912+
}
913+
BinaryenOp BinaryenWidenLowUVecI16x8ToVecI32x4(void) {
914+
return WidenLowUVecI16x8ToVecI32x4;
915+
}
916+
BinaryenOp BinaryenWidenHighUVecI16x8ToVecI32x4(void) {
917+
return WidenHighUVecI16x8ToVecI32x4;
918+
}
883919

884920
BinaryenExpressionRef BinaryenBlock(BinaryenModuleRef module,
885921
const char* name,

src/binaryen-c.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -514,6 +514,18 @@ BinaryenOp BinaryenConvertSVecI32x4ToVecF32x4(void);
514514
BinaryenOp BinaryenConvertUVecI32x4ToVecF32x4(void);
515515
BinaryenOp BinaryenConvertSVecI64x2ToVecF64x2(void);
516516
BinaryenOp BinaryenConvertUVecI64x2ToVecF64x2(void);
517+
BinaryenOp BinaryenNarrowSVecI16x8ToVecI8x16(void);
518+
BinaryenOp BinaryenNarrowUVecI16x8ToVecI8x16(void);
519+
BinaryenOp BinaryenNarrowSVecI32x4ToVecI16x8(void);
520+
BinaryenOp BinaryenNarrowUVecI32x4ToVecI16x8(void);
521+
BinaryenOp BinaryenWidenLowSVecI8x16ToVecI16x8(void);
522+
BinaryenOp BinaryenWidenHighSVecI8x16ToVecI16x8(void);
523+
BinaryenOp BinaryenWidenLowUVecI8x16ToVecI16x8(void);
524+
BinaryenOp BinaryenWidenHighUVecI8x16ToVecI16x8(void);
525+
BinaryenOp BinaryenWidenLowSVecI16x8ToVecI32x4(void);
526+
BinaryenOp BinaryenWidenHighSVecI16x8ToVecI32x4(void);
527+
BinaryenOp BinaryenWidenLowUVecI16x8ToVecI32x4(void);
528+
BinaryenOp BinaryenWidenHighUVecI16x8ToVecI32x4(void);
517529

518530
typedef void* BinaryenExpressionRef;
519531

src/gen-s-parser.inc

Lines changed: 100 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -778,13 +778,29 @@ switch (op[0]) {
778778
if (strcmp(op, "i16x8.mul") == 0) { return makeBinary(s, BinaryOp::MulVecI16x8); }
779779
goto parse_error;
780780
case 'n': {
781-
switch (op[8]) {
782-
case '\0':
783-
if (strcmp(op, "i16x8.ne") == 0) { return makeBinary(s, BinaryOp::NeVecI16x8); }
784-
goto parse_error;
785-
case 'g':
786-
if (strcmp(op, "i16x8.neg") == 0) { return makeUnary(s, UnaryOp::NegVecI16x8); }
787-
goto parse_error;
781+
switch (op[7]) {
782+
case 'a': {
783+
switch (op[19]) {
784+
case 's':
785+
if (strcmp(op, "i16x8.narrow_i32x4_s") == 0) { return makeBinary(s, BinaryOp::NarrowSVecI32x4ToVecI16x8); }
786+
goto parse_error;
787+
case 'u':
788+
if (strcmp(op, "i16x8.narrow_i32x4_u") == 0) { return makeBinary(s, BinaryOp::NarrowUVecI32x4ToVecI16x8); }
789+
goto parse_error;
790+
default: goto parse_error;
791+
}
792+
}
793+
case 'e': {
794+
switch (op[8]) {
795+
case '\0':
796+
if (strcmp(op, "i16x8.ne") == 0) { return makeBinary(s, BinaryOp::NeVecI16x8); }
797+
goto parse_error;
798+
case 'g':
799+
if (strcmp(op, "i16x8.neg") == 0) { return makeUnary(s, UnaryOp::NegVecI16x8); }
800+
goto parse_error;
801+
default: goto parse_error;
802+
}
803+
}
788804
default: goto parse_error;
789805
}
790806
}
@@ -837,6 +853,33 @@ switch (op[0]) {
837853
default: goto parse_error;
838854
}
839855
}
856+
case 'w': {
857+
switch (op[12]) {
858+
case 'h': {
859+
switch (op[23]) {
860+
case 's':
861+
if (strcmp(op, "i16x8.widen_high_i8x16_s") == 0) { return makeUnary(s, UnaryOp::WidenHighSVecI8x16ToVecI16x8); }
862+
goto parse_error;
863+
case 'u':
864+
if (strcmp(op, "i16x8.widen_high_i8x16_u") == 0) { return makeUnary(s, UnaryOp::WidenHighUVecI8x16ToVecI16x8); }
865+
goto parse_error;
866+
default: goto parse_error;
867+
}
868+
}
869+
case 'l': {
870+
switch (op[22]) {
871+
case 's':
872+
if (strcmp(op, "i16x8.widen_low_i8x16_s") == 0) { return makeUnary(s, UnaryOp::WidenLowSVecI8x16ToVecI16x8); }
873+
goto parse_error;
874+
case 'u':
875+
if (strcmp(op, "i16x8.widen_low_i8x16_u") == 0) { return makeUnary(s, UnaryOp::WidenLowUVecI8x16ToVecI16x8); }
876+
goto parse_error;
877+
default: goto parse_error;
878+
}
879+
}
880+
default: goto parse_error;
881+
}
882+
}
840883
default: goto parse_error;
841884
}
842885
}
@@ -1443,6 +1486,33 @@ switch (op[0]) {
14431486
default: goto parse_error;
14441487
}
14451488
}
1489+
case 'w': {
1490+
switch (op[12]) {
1491+
case 'h': {
1492+
switch (op[23]) {
1493+
case 's':
1494+
if (strcmp(op, "i32x4.widen_high_i16x8_s") == 0) { return makeUnary(s, UnaryOp::WidenHighSVecI16x8ToVecI32x4); }
1495+
goto parse_error;
1496+
case 'u':
1497+
if (strcmp(op, "i32x4.widen_high_i16x8_u") == 0) { return makeUnary(s, UnaryOp::WidenHighUVecI16x8ToVecI32x4); }
1498+
goto parse_error;
1499+
default: goto parse_error;
1500+
}
1501+
}
1502+
case 'l': {
1503+
switch (op[22]) {
1504+
case 's':
1505+
if (strcmp(op, "i32x4.widen_low_i16x8_s") == 0) { return makeUnary(s, UnaryOp::WidenLowSVecI16x8ToVecI32x4); }
1506+
goto parse_error;
1507+
case 'u':
1508+
if (strcmp(op, "i32x4.widen_low_i16x8_u") == 0) { return makeUnary(s, UnaryOp::WidenLowUVecI16x8ToVecI32x4); }
1509+
goto parse_error;
1510+
default: goto parse_error;
1511+
}
1512+
}
1513+
default: goto parse_error;
1514+
}
1515+
}
14461516
default: goto parse_error;
14471517
}
14481518
}
@@ -2161,13 +2231,29 @@ switch (op[0]) {
21612231
if (strcmp(op, "i8x16.mul") == 0) { return makeBinary(s, BinaryOp::MulVecI8x16); }
21622232
goto parse_error;
21632233
case 'n': {
2164-
switch (op[8]) {
2165-
case '\0':
2166-
if (strcmp(op, "i8x16.ne") == 0) { return makeBinary(s, BinaryOp::NeVecI8x16); }
2167-
goto parse_error;
2168-
case 'g':
2169-
if (strcmp(op, "i8x16.neg") == 0) { return makeUnary(s, UnaryOp::NegVecI8x16); }
2170-
goto parse_error;
2234+
switch (op[7]) {
2235+
case 'a': {
2236+
switch (op[19]) {
2237+
case 's':
2238+
if (strcmp(op, "i8x16.narrow_i16x8_s") == 0) { return makeBinary(s, BinaryOp::NarrowSVecI16x8ToVecI8x16); }
2239+
goto parse_error;
2240+
case 'u':
2241+
if (strcmp(op, "i8x16.narrow_i16x8_u") == 0) { return makeBinary(s, BinaryOp::NarrowUVecI16x8ToVecI8x16); }
2242+
goto parse_error;
2243+
default: goto parse_error;
2244+
}
2245+
}
2246+
case 'e': {
2247+
switch (op[8]) {
2248+
case '\0':
2249+
if (strcmp(op, "i8x16.ne") == 0) { return makeBinary(s, BinaryOp::NeVecI8x16); }
2250+
goto parse_error;
2251+
case 'g':
2252+
if (strcmp(op, "i8x16.neg") == 0) { return makeUnary(s, UnaryOp::NegVecI8x16); }
2253+
goto parse_error;
2254+
default: goto parse_error;
2255+
}
2256+
}
21712257
default: goto parse_error;
21722258
}
21732259
}

src/ir/cost.h

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,14 @@ struct CostAnalyzer : public Visitor<CostAnalyzer, Index> {
178178
case ConvertUVecI32x4ToVecF32x4:
179179
case ConvertSVecI64x2ToVecF64x2:
180180
case ConvertUVecI64x2ToVecF64x2:
181+
case WidenLowSVecI8x16ToVecI16x8:
182+
case WidenHighSVecI8x16ToVecI16x8:
183+
case WidenLowUVecI8x16ToVecI16x8:
184+
case WidenHighUVecI8x16ToVecI16x8:
185+
case WidenLowSVecI16x8ToVecI32x4:
186+
case WidenHighSVecI16x8ToVecI32x4:
187+
case WidenLowUVecI16x8ToVecI32x4:
188+
case WidenHighUVecI16x8ToVecI32x4:
181189
return 1;
182190
case InvalidUnary:
183191
WASM_UNREACHABLE();
@@ -643,6 +651,18 @@ struct CostAnalyzer : public Visitor<CostAnalyzer, Index> {
643651
case MaxVecF64x2:
644652
ret = 1;
645653
break;
654+
case NarrowSVecI16x8ToVecI8x16:
655+
ret = 1;
656+
break;
657+
case NarrowUVecI16x8ToVecI8x16:
658+
ret = 1;
659+
break;
660+
case NarrowSVecI32x4ToVecI16x8:
661+
ret = 1;
662+
break;
663+
case NarrowUVecI32x4ToVecI16x8:
664+
ret = 1;
665+
break;
646666
case InvalidBinary:
647667
WASM_UNREACHABLE();
648668
}

0 commit comments

Comments
 (0)