Skip to content

Commit 74c6c69

Browse files
committed
Implement pseudo-min/max SIMD instructions
As specified in WebAssembly/simd#122.
1 parent 655fd6b commit 74c6c69

24 files changed

+389
-47
lines changed

scripts/gen-s-parser.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -435,6 +435,8 @@
435435
("f32x4.div", "makeBinary(s, BinaryOp::DivVecF32x4)"),
436436
("f32x4.min", "makeBinary(s, BinaryOp::MinVecF32x4)"),
437437
("f32x4.max", "makeBinary(s, BinaryOp::MaxVecF32x4)"),
438+
("f32x4.pmin", "makeBinary(s, BinaryOp::PMinVecF32x4)"),
439+
("f32x4.pmax", "makeBinary(s, BinaryOp::PMaxVecF32x4)"),
438440
("f64x2.abs", "makeUnary(s, UnaryOp::AbsVecF64x2)"),
439441
("f64x2.neg", "makeUnary(s, UnaryOp::NegVecF64x2)"),
440442
("f64x2.sqrt", "makeUnary(s, UnaryOp::SqrtVecF64x2)"),
@@ -446,6 +448,8 @@
446448
("f64x2.div", "makeBinary(s, BinaryOp::DivVecF64x2)"),
447449
("f64x2.min", "makeBinary(s, BinaryOp::MinVecF64x2)"),
448450
("f64x2.max", "makeBinary(s, BinaryOp::MaxVecF64x2)"),
451+
("f64x2.pmin", "makeBinary(s, BinaryOp::PMinVecF64x2)"),
452+
("f64x2.pmax", "makeBinary(s, BinaryOp::PMaxVecF64x2)"),
449453
("i32x4.trunc_sat_f32x4_s", "makeUnary(s, UnaryOp::TruncSatSVecF32x4ToVecI32x4)"),
450454
("i32x4.trunc_sat_f32x4_u", "makeUnary(s, UnaryOp::TruncSatUVecF32x4ToVecI32x4)"),
451455
("i64x2.trunc_sat_f64x2_s", "makeUnary(s, UnaryOp::TruncSatSVecF64x2ToVecI64x2)"),

src/binaryen-c.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -681,6 +681,8 @@ BinaryenOp BinaryenMulVecF32x4(void) { return MulVecF32x4; }
681681
BinaryenOp BinaryenDivVecF32x4(void) { return DivVecF32x4; }
682682
BinaryenOp BinaryenMinVecF32x4(void) { return MinVecF32x4; }
683683
BinaryenOp BinaryenMaxVecF32x4(void) { return MaxVecF32x4; }
684+
BinaryenOp BinaryenPMinVecF32x4(void) { return PMinVecF32x4; }
685+
BinaryenOp BinaryenPMaxVecF32x4(void) { return PMaxVecF32x4; }
684686
BinaryenOp BinaryenAbsVecF64x2(void) { return AbsVecF64x2; }
685687
BinaryenOp BinaryenNegVecF64x2(void) { return NegVecF64x2; }
686688
BinaryenOp BinaryenSqrtVecF64x2(void) { return SqrtVecF64x2; }
@@ -692,6 +694,8 @@ BinaryenOp BinaryenMulVecF64x2(void) { return MulVecF64x2; }
692694
BinaryenOp BinaryenDivVecF64x2(void) { return DivVecF64x2; }
693695
BinaryenOp BinaryenMinVecF64x2(void) { return MinVecF64x2; }
694696
BinaryenOp BinaryenMaxVecF64x2(void) { return MaxVecF64x2; }
697+
BinaryenOp BinaryenPMinVecF64x2(void) { return PMinVecF64x2; }
698+
BinaryenOp BinaryenPMaxVecF64x2(void) { return PMaxVecF64x2; }
695699
BinaryenOp BinaryenTruncSatSVecF32x4ToVecI32x4(void) {
696700
return TruncSatSVecF32x4ToVecI32x4;
697701
}

src/binaryen-c.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -541,6 +541,8 @@ BINARYEN_API BinaryenOp BinaryenMulVecF32x4(void);
541541
BINARYEN_API BinaryenOp BinaryenDivVecF32x4(void);
542542
BINARYEN_API BinaryenOp BinaryenMinVecF32x4(void);
543543
BINARYEN_API BinaryenOp BinaryenMaxVecF32x4(void);
544+
BINARYEN_API BinaryenOp BinaryenPMinVecF32x4(void);
545+
BINARYEN_API BinaryenOp BinaryenPMaxVecF32x4(void);
544546
BINARYEN_API BinaryenOp BinaryenAbsVecF64x2(void);
545547
BINARYEN_API BinaryenOp BinaryenNegVecF64x2(void);
546548
BINARYEN_API BinaryenOp BinaryenSqrtVecF64x2(void);
@@ -552,6 +554,8 @@ BINARYEN_API BinaryenOp BinaryenMulVecF64x2(void);
552554
BINARYEN_API BinaryenOp BinaryenDivVecF64x2(void);
553555
BINARYEN_API BinaryenOp BinaryenMinVecF64x2(void);
554556
BINARYEN_API BinaryenOp BinaryenMaxVecF64x2(void);
557+
BINARYEN_API BinaryenOp BinaryenPMinVecF64x2(void);
558+
BINARYEN_API BinaryenOp BinaryenPMaxVecF64x2(void);
555559
BINARYEN_API BinaryenOp BinaryenTruncSatSVecF32x4ToVecI32x4(void);
556560
BINARYEN_API BinaryenOp BinaryenTruncSatUVecF32x4ToVecI32x4(void);
557561
BINARYEN_API BinaryenOp BinaryenTruncSatSVecF64x2ToVecI64x2(void);

src/gen-s-parser.inc

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -338,6 +338,17 @@ switch (op[0]) {
338338
default: goto parse_error;
339339
}
340340
}
341+
case 'p': {
342+
switch (op[8]) {
343+
case 'a':
344+
if (strcmp(op, "f32x4.pmax") == 0) { return makeBinary(s, BinaryOp::PMaxVecF32x4); }
345+
goto parse_error;
346+
case 'i':
347+
if (strcmp(op, "f32x4.pmin") == 0) { return makeBinary(s, BinaryOp::PMinVecF32x4); }
348+
goto parse_error;
349+
default: goto parse_error;
350+
}
351+
}
341352
case 'q': {
342353
switch (op[9]) {
343354
case 'a':
@@ -619,6 +630,17 @@ switch (op[0]) {
619630
default: goto parse_error;
620631
}
621632
}
633+
case 'p': {
634+
switch (op[8]) {
635+
case 'a':
636+
if (strcmp(op, "f64x2.pmax") == 0) { return makeBinary(s, BinaryOp::PMaxVecF64x2); }
637+
goto parse_error;
638+
case 'i':
639+
if (strcmp(op, "f64x2.pmin") == 0) { return makeBinary(s, BinaryOp::PMinVecF64x2); }
640+
goto parse_error;
641+
default: goto parse_error;
642+
}
643+
}
622644
case 'q': {
623645
switch (op[9]) {
624646
case 'a':

src/ir/cost.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -687,6 +687,12 @@ struct CostAnalyzer : public Visitor<CostAnalyzer, Index> {
687687
case MaxVecF32x4:
688688
ret = 1;
689689
break;
690+
case PMinVecF32x4:
691+
ret = 1;
692+
break;
693+
case PMaxVecF32x4:
694+
ret = 1;
695+
break;
690696
case AddVecF64x2:
691697
ret = 1;
692698
break;
@@ -705,6 +711,12 @@ struct CostAnalyzer : public Visitor<CostAnalyzer, Index> {
705711
case MaxVecF64x2:
706712
ret = 1;
707713
break;
714+
case PMinVecF64x2:
715+
ret = 1;
716+
break;
717+
case PMaxVecF64x2:
718+
ret = 1;
719+
break;
708720
case NarrowSVecI16x8ToVecI8x16:
709721
ret = 1;
710722
break;

src/js/binaryen.js-post.js

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -421,6 +421,8 @@ function initializeConstants() {
421421
'DivVecF32x4',
422422
'MinVecF32x4',
423423
'MaxVecF32x4',
424+
'PMinVecF32x4',
425+
'PMaxVecF32x4',
424426
'AbsVecF64x2',
425427
'NegVecF64x2',
426428
'SqrtVecF64x2',
@@ -432,6 +434,8 @@ function initializeConstants() {
432434
'DivVecF64x2',
433435
'MinVecF64x2',
434436
'MaxVecF64x2',
437+
'PMinVecF64x2',
438+
'PMaxVecF64x2',
435439
'TruncSatSVecF32x4ToVecI32x4',
436440
'TruncSatUVecF32x4ToVecI32x4',
437441
'TruncSatSVecF64x2ToVecI64x2',
@@ -1904,6 +1908,12 @@ function wrapModule(module, self) {
19041908
'max': function(left, right) {
19051909
return Module['_BinaryenBinary'](module, Module['MaxVecF32x4'], left, right);
19061910
},
1911+
'pmin': function(left, right) {
1912+
return Module['_BinaryenBinary'](module, Module['PMinVecF32x4'], left, right);
1913+
},
1914+
'pmax': function(left, right) {
1915+
return Module['_BinaryenBinary'](module, Module['PMaxVecF32x4'], left, right);
1916+
},
19071917
'convert_i32x4_s': function(value) {
19081918
return Module['_BinaryenUnary'](module, Module['ConvertSVecI32x4ToVecF32x4'], value);
19091919
},
@@ -1973,6 +1983,12 @@ function wrapModule(module, self) {
19731983
'max': function(left, right) {
19741984
return Module['_BinaryenBinary'](module, Module['MaxVecF64x2'], left, right);
19751985
},
1986+
'pmin': function(left, right) {
1987+
return Module['_BinaryenBinary'](module, Module['PMinVecF64x2'], left, right);
1988+
},
1989+
'pmax': function(left, right) {
1990+
return Module['_BinaryenBinary'](module, Module['PMaxVecF64x2'], left, right);
1991+
},
19761992
'convert_i64x2_s': function(value) {
19771993
return Module['_BinaryenUnary'](module, Module['ConvertSVecI64x2ToVecF64x2'], value);
19781994
},

src/literal.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -271,6 +271,8 @@ class Literal {
271271

272272
Literal min(const Literal& other) const;
273273
Literal max(const Literal& other) const;
274+
Literal pmin(const Literal& other) const;
275+
Literal pmax(const Literal& other) const;
274276
Literal copysign(const Literal& other) const;
275277

276278
std::array<Literal, 16> getLanesSI8x16() const;
@@ -424,6 +426,8 @@ class Literal {
424426
Literal divF32x4(const Literal& other) const;
425427
Literal minF32x4(const Literal& other) const;
426428
Literal maxF32x4(const Literal& other) const;
429+
Literal pminF32x4(const Literal& other) const;
430+
Literal pmaxF32x4(const Literal& other) const;
427431
Literal absF64x2() const;
428432
Literal negF64x2() const;
429433
Literal sqrtF64x2() const;
@@ -433,6 +437,8 @@ class Literal {
433437
Literal divF64x2(const Literal& other) const;
434438
Literal minF64x2(const Literal& other) const;
435439
Literal maxF64x2(const Literal& other) const;
440+
Literal pminF64x2(const Literal& other) const;
441+
Literal pmaxF64x2(const Literal& other) const;
436442
Literal truncSatToSI32x4() const;
437443
Literal truncSatToUI32x4() const;
438444
Literal truncSatToSI64x2() const;

src/passes/Print.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1337,6 +1337,12 @@ struct PrintExpressionContents
13371337
case MaxVecF32x4:
13381338
o << "f32x4.max";
13391339
break;
1340+
case PMinVecF32x4:
1341+
o << "f32x4.pmin";
1342+
break;
1343+
case PMaxVecF32x4:
1344+
o << "f32x4.pmax";
1345+
break;
13401346
case AddVecF64x2:
13411347
o << "f64x2.add";
13421348
break;
@@ -1355,6 +1361,12 @@ struct PrintExpressionContents
13551361
case MaxVecF64x2:
13561362
o << "f64x2.max";
13571363
break;
1364+
case PMinVecF64x2:
1365+
o << "f64x2.pmin";
1366+
break;
1367+
case PMaxVecF64x2:
1368+
o << "f64x2.pmax";
1369+
break;
13581370

13591371
case NarrowSVecI16x8ToVecI8x16:
13601372
o << "i8x16.narrow_i16x8_s";

src/wasm-binary.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -859,6 +859,8 @@ enum ASTNodes {
859859
F32x4Div = 0xe7,
860860
F32x4Min = 0xe8,
861861
F32x4Max = 0xe9,
862+
F32x4PMin = 0xea,
863+
F32x4PMax = 0xeb,
862864

863865
F64x2Abs = 0xec,
864866
F64x2Neg = 0xed,
@@ -869,6 +871,8 @@ enum ASTNodes {
869871
F64x2Div = 0xf3,
870872
F64x2Min = 0xf4,
871873
F64x2Max = 0xf5,
874+
F64x2PMin = 0xf6,
875+
F64x2PMax = 0xf7,
872876

873877
I32x4TruncSatSF32x4 = 0xf8,
874878
I32x4TruncSatUF32x4 = 0xf9,

src/wasm-interpreter.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -893,6 +893,10 @@ class ExpressionRunner : public OverriddenVisitor<SubType, Flow> {
893893
return left.minF32x4(right);
894894
case MaxVecF32x4:
895895
return left.maxF32x4(right);
896+
case PMinVecF32x4:
897+
return left.pminF32x4(right);
898+
case PMaxVecF32x4:
899+
return right.pmaxF32x4(right);
896900
case AddVecF64x2:
897901
return left.addF64x2(right);
898902
case SubVecF64x2:
@@ -905,6 +909,10 @@ class ExpressionRunner : public OverriddenVisitor<SubType, Flow> {
905909
return left.minF64x2(right);
906910
case MaxVecF64x2:
907911
return left.maxF64x2(right);
912+
case PMinVecF64x2:
913+
return left.pminF64x2(right);
914+
case PMaxVecF64x2:
915+
return left.pmaxF64x2(right);
908916

909917
case NarrowSVecI16x8ToVecI8x16:
910918
return left.narrowSToVecI8x16(right);

0 commit comments

Comments
 (0)