Skip to content

Commit 037d7a5

Browse files
authored
Add prototype SIMD rounding instructions (#2895)
As specified in WebAssembly/simd#232.
1 parent 0c58de1 commit 037d7a5

25 files changed

+669
-60
lines changed

scripts/gen-s-parser.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -437,6 +437,10 @@
437437
("f32x4.max", "makeBinary(s, BinaryOp::MaxVecF32x4)"),
438438
("f32x4.pmin", "makeBinary(s, BinaryOp::PMinVecF32x4)"),
439439
("f32x4.pmax", "makeBinary(s, BinaryOp::PMaxVecF32x4)"),
440+
("f32x4.ceil", "makeUnary(s, UnaryOp::CeilVecF32x4)"),
441+
("f32x4.floor", "makeUnary(s, UnaryOp::FloorVecF32x4)"),
442+
("f32x4.trunc", "makeUnary(s, UnaryOp::TruncVecF32x4)"),
443+
("f32x4.nearest", "makeUnary(s, UnaryOp::NearestVecF32x4)"),
440444
("f64x2.abs", "makeUnary(s, UnaryOp::AbsVecF64x2)"),
441445
("f64x2.neg", "makeUnary(s, UnaryOp::NegVecF64x2)"),
442446
("f64x2.sqrt", "makeUnary(s, UnaryOp::SqrtVecF64x2)"),
@@ -450,6 +454,10 @@
450454
("f64x2.max", "makeBinary(s, BinaryOp::MaxVecF64x2)"),
451455
("f64x2.pmin", "makeBinary(s, BinaryOp::PMinVecF64x2)"),
452456
("f64x2.pmax", "makeBinary(s, BinaryOp::PMaxVecF64x2)"),
457+
("f64x2.ceil", "makeUnary(s, UnaryOp::CeilVecF64x2)"),
458+
("f64x2.floor", "makeUnary(s, UnaryOp::FloorVecF64x2)"),
459+
("f64x2.trunc", "makeUnary(s, UnaryOp::TruncVecF64x2)"),
460+
("f64x2.nearest", "makeUnary(s, UnaryOp::NearestVecF64x2)"),
453461
("i32x4.trunc_sat_f32x4_s", "makeUnary(s, UnaryOp::TruncSatSVecF32x4ToVecI32x4)"),
454462
("i32x4.trunc_sat_f32x4_u", "makeUnary(s, UnaryOp::TruncSatUVecF32x4ToVecI32x4)"),
455463
("i64x2.trunc_sat_f64x2_s", "makeUnary(s, UnaryOp::TruncSatSVecF64x2ToVecI64x2)"),

src/binaryen-c.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -682,6 +682,10 @@ BinaryenOp BinaryenDivVecF32x4(void) { return DivVecF32x4; }
682682
BinaryenOp BinaryenMinVecF32x4(void) { return MinVecF32x4; }
683683
BinaryenOp BinaryenMaxVecF32x4(void) { return MaxVecF32x4; }
684684
BinaryenOp BinaryenPMinVecF32x4(void) { return PMinVecF32x4; }
685+
BinaryenOp BinaryenCeilVecF32x4(void) { return CeilVecF32x4; }
686+
BinaryenOp BinaryenFloorVecF32x4(void) { return FloorVecF32x4; }
687+
BinaryenOp BinaryenTruncVecF32x4(void) { return TruncVecF32x4; }
688+
BinaryenOp BinaryenNearestVecF32x4(void) { return NearestVecF32x4; }
685689
BinaryenOp BinaryenPMaxVecF32x4(void) { return PMaxVecF32x4; }
686690
BinaryenOp BinaryenAbsVecF64x2(void) { return AbsVecF64x2; }
687691
BinaryenOp BinaryenNegVecF64x2(void) { return NegVecF64x2; }
@@ -696,6 +700,10 @@ BinaryenOp BinaryenMinVecF64x2(void) { return MinVecF64x2; }
696700
BinaryenOp BinaryenMaxVecF64x2(void) { return MaxVecF64x2; }
697701
BinaryenOp BinaryenPMinVecF64x2(void) { return PMinVecF64x2; }
698702
BinaryenOp BinaryenPMaxVecF64x2(void) { return PMaxVecF64x2; }
703+
BinaryenOp BinaryenCeilVecF64x2(void) { return CeilVecF64x2; }
704+
BinaryenOp BinaryenFloorVecF64x2(void) { return FloorVecF64x2; }
705+
BinaryenOp BinaryenTruncVecF64x2(void) { return TruncVecF64x2; }
706+
BinaryenOp BinaryenNearestVecF64x2(void) { return NearestVecF64x2; }
699707
BinaryenOp BinaryenTruncSatSVecF32x4ToVecI32x4(void) {
700708
return TruncSatSVecF32x4ToVecI32x4;
701709
}

src/binaryen-c.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -543,6 +543,10 @@ BINARYEN_API BinaryenOp BinaryenMinVecF32x4(void);
543543
BINARYEN_API BinaryenOp BinaryenMaxVecF32x4(void);
544544
BINARYEN_API BinaryenOp BinaryenPMinVecF32x4(void);
545545
BINARYEN_API BinaryenOp BinaryenPMaxVecF32x4(void);
546+
BINARYEN_API BinaryenOp BinaryenCeilVecF32x4(void);
547+
BINARYEN_API BinaryenOp BinaryenFloorVecF32x4(void);
548+
BINARYEN_API BinaryenOp BinaryenTruncVecF32x4(void);
549+
BINARYEN_API BinaryenOp BinaryenNearestVecF32x4(void);
546550
BINARYEN_API BinaryenOp BinaryenAbsVecF64x2(void);
547551
BINARYEN_API BinaryenOp BinaryenNegVecF64x2(void);
548552
BINARYEN_API BinaryenOp BinaryenSqrtVecF64x2(void);
@@ -556,6 +560,10 @@ BINARYEN_API BinaryenOp BinaryenMinVecF64x2(void);
556560
BINARYEN_API BinaryenOp BinaryenMaxVecF64x2(void);
557561
BINARYEN_API BinaryenOp BinaryenPMinVecF64x2(void);
558562
BINARYEN_API BinaryenOp BinaryenPMaxVecF64x2(void);
563+
BINARYEN_API BinaryenOp BinaryenCeilVecF64x2(void);
564+
BINARYEN_API BinaryenOp BinaryenFloorVecF64x2(void);
565+
BINARYEN_API BinaryenOp BinaryenTruncVecF64x2(void);
566+
BINARYEN_API BinaryenOp BinaryenNearestVecF64x2(void);
559567
BINARYEN_API BinaryenOp BinaryenTruncSatSVecF32x4ToVecI32x4(void);
560568
BINARYEN_API BinaryenOp BinaryenTruncSatUVecF32x4ToVecI32x4(void);
561569
BINARYEN_API BinaryenOp BinaryenTruncSatSVecF64x2ToVecI64x2(void);

src/gen-s-parser.inc

Lines changed: 46 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -267,13 +267,21 @@ switch (op[0]) {
267267
}
268268
}
269269
case 'c': {
270-
switch (op[20]) {
271-
case 's':
272-
if (strcmp(op, "f32x4.convert_i32x4_s") == 0) { return makeUnary(s, UnaryOp::ConvertSVecI32x4ToVecF32x4); }
273-
goto parse_error;
274-
case 'u':
275-
if (strcmp(op, "f32x4.convert_i32x4_u") == 0) { return makeUnary(s, UnaryOp::ConvertUVecI32x4ToVecF32x4); }
270+
switch (op[7]) {
271+
case 'e':
272+
if (strcmp(op, "f32x4.ceil") == 0) { return makeUnary(s, UnaryOp::CeilVecF32x4); }
276273
goto parse_error;
274+
case 'o': {
275+
switch (op[20]) {
276+
case 's':
277+
if (strcmp(op, "f32x4.convert_i32x4_s") == 0) { return makeUnary(s, UnaryOp::ConvertSVecI32x4ToVecF32x4); }
278+
goto parse_error;
279+
case 'u':
280+
if (strcmp(op, "f32x4.convert_i32x4_u") == 0) { return makeUnary(s, UnaryOp::ConvertUVecI32x4ToVecF32x4); }
281+
goto parse_error;
282+
default: goto parse_error;
283+
}
284+
}
277285
default: goto parse_error;
278286
}
279287
}
@@ -291,6 +299,9 @@ switch (op[0]) {
291299
default: goto parse_error;
292300
}
293301
}
302+
case 'f':
303+
if (strcmp(op, "f32x4.floor") == 0) { return makeUnary(s, UnaryOp::FloorVecF32x4); }
304+
goto parse_error;
294305
case 'g': {
295306
switch (op[7]) {
296307
case 'e':
@@ -332,6 +343,9 @@ switch (op[0]) {
332343
case '\0':
333344
if (strcmp(op, "f32x4.ne") == 0) { return makeBinary(s, BinaryOp::NeVecF32x4); }
334345
goto parse_error;
346+
case 'a':
347+
if (strcmp(op, "f32x4.nearest") == 0) { return makeUnary(s, UnaryOp::NearestVecF32x4); }
348+
goto parse_error;
335349
case 'g':
336350
if (strcmp(op, "f32x4.neg") == 0) { return makeUnary(s, UnaryOp::NegVecF32x4); }
337351
goto parse_error;
@@ -377,6 +391,9 @@ switch (op[0]) {
377391
default: goto parse_error;
378392
}
379393
}
394+
case 't':
395+
if (strcmp(op, "f32x4.trunc") == 0) { return makeUnary(s, UnaryOp::TruncVecF32x4); }
396+
goto parse_error;
380397
default: goto parse_error;
381398
}
382399
}
@@ -559,13 +576,21 @@ switch (op[0]) {
559576
}
560577
}
561578
case 'c': {
562-
switch (op[20]) {
563-
case 's':
564-
if (strcmp(op, "f64x2.convert_i64x2_s") == 0) { return makeUnary(s, UnaryOp::ConvertSVecI64x2ToVecF64x2); }
565-
goto parse_error;
566-
case 'u':
567-
if (strcmp(op, "f64x2.convert_i64x2_u") == 0) { return makeUnary(s, UnaryOp::ConvertUVecI64x2ToVecF64x2); }
579+
switch (op[7]) {
580+
case 'e':
581+
if (strcmp(op, "f64x2.ceil") == 0) { return makeUnary(s, UnaryOp::CeilVecF64x2); }
568582
goto parse_error;
583+
case 'o': {
584+
switch (op[20]) {
585+
case 's':
586+
if (strcmp(op, "f64x2.convert_i64x2_s") == 0) { return makeUnary(s, UnaryOp::ConvertSVecI64x2ToVecF64x2); }
587+
goto parse_error;
588+
case 'u':
589+
if (strcmp(op, "f64x2.convert_i64x2_u") == 0) { return makeUnary(s, UnaryOp::ConvertUVecI64x2ToVecF64x2); }
590+
goto parse_error;
591+
default: goto parse_error;
592+
}
593+
}
569594
default: goto parse_error;
570595
}
571596
}
@@ -583,6 +608,9 @@ switch (op[0]) {
583608
default: goto parse_error;
584609
}
585610
}
611+
case 'f':
612+
if (strcmp(op, "f64x2.floor") == 0) { return makeUnary(s, UnaryOp::FloorVecF64x2); }
613+
goto parse_error;
586614
case 'g': {
587615
switch (op[7]) {
588616
case 'e':
@@ -624,6 +652,9 @@ switch (op[0]) {
624652
case '\0':
625653
if (strcmp(op, "f64x2.ne") == 0) { return makeBinary(s, BinaryOp::NeVecF64x2); }
626654
goto parse_error;
655+
case 'a':
656+
if (strcmp(op, "f64x2.nearest") == 0) { return makeUnary(s, UnaryOp::NearestVecF64x2); }
657+
goto parse_error;
627658
case 'g':
628659
if (strcmp(op, "f64x2.neg") == 0) { return makeUnary(s, UnaryOp::NegVecF64x2); }
629660
goto parse_error;
@@ -669,6 +700,9 @@ switch (op[0]) {
669700
default: goto parse_error;
670701
}
671702
}
703+
case 't':
704+
if (strcmp(op, "f64x2.trunc") == 0) { return makeUnary(s, UnaryOp::TruncVecF64x2); }
705+
goto parse_error;
672706
default: goto parse_error;
673707
}
674708
}

src/ir/cost.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,9 +173,17 @@ struct CostAnalyzer : public Visitor<CostAnalyzer, Index> {
173173
case AbsVecF32x4:
174174
case NegVecF32x4:
175175
case SqrtVecF32x4:
176+
case CeilVecF32x4:
177+
case FloorVecF32x4:
178+
case TruncVecF32x4:
179+
case NearestVecF32x4:
176180
case AbsVecF64x2:
177181
case NegVecF64x2:
178182
case SqrtVecF64x2:
183+
case CeilVecF64x2:
184+
case FloorVecF64x2:
185+
case TruncVecF64x2:
186+
case NearestVecF64x2:
179187
case TruncSatSVecF32x4ToVecI32x4:
180188
case TruncSatUVecF32x4ToVecI32x4:
181189
case TruncSatSVecF64x2ToVecI64x2:

src/js/binaryen.js-post.js

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -423,6 +423,10 @@ function initializeConstants() {
423423
'MaxVecF32x4',
424424
'PMinVecF32x4',
425425
'PMaxVecF32x4',
426+
'CeilVecF32x4',
427+
'FloorVecF32x4',
428+
'TruncVecF32x4',
429+
'NearestVecF32x4',
426430
'AbsVecF64x2',
427431
'NegVecF64x2',
428432
'SqrtVecF64x2',
@@ -436,6 +440,10 @@ function initializeConstants() {
436440
'MaxVecF64x2',
437441
'PMinVecF64x2',
438442
'PMaxVecF64x2',
443+
'CeilVecF64x2',
444+
'FloorVecF64x2',
445+
'TruncVecF64x2',
446+
'NearestVecF64x2',
439447
'TruncSatSVecF32x4ToVecI32x4',
440448
'TruncSatUVecF32x4ToVecI32x4',
441449
'TruncSatSVecF64x2ToVecI64x2',
@@ -1918,6 +1926,18 @@ function wrapModule(module, self) {
19181926
'pmax': function(left, right) {
19191927
return Module['_BinaryenBinary'](module, Module['PMaxVecF32x4'], left, right);
19201928
},
1929+
'ceil': function(value) {
1930+
return Module['_BinaryenUnary'](module, Module['CeilVecF32x4'], value);
1931+
},
1932+
'floor': function(value) {
1933+
return Module['_BinaryenUnary'](module, Module['FloorVecF32x4'], value);
1934+
},
1935+
'trunc': function(value) {
1936+
return Module['_BinaryenUnary'](module, Module['TruncVecF32x4'], value);
1937+
},
1938+
'nearest': function(value) {
1939+
return Module['_BinaryenUnary'](module, Module['NearestVecF32x4'], value);
1940+
},
19211941
'convert_i32x4_s': function(value) {
19221942
return Module['_BinaryenUnary'](module, Module['ConvertSVecI32x4ToVecF32x4'], value);
19231943
},
@@ -1993,6 +2013,18 @@ function wrapModule(module, self) {
19932013
'pmax': function(left, right) {
19942014
return Module['_BinaryenBinary'](module, Module['PMaxVecF64x2'], left, right);
19952015
},
2016+
'ceil': function(value) {
2017+
return Module['_BinaryenUnary'](module, Module['CeilVecF64x2'], value);
2018+
},
2019+
'floor': function(value) {
2020+
return Module['_BinaryenUnary'](module, Module['FloorVecF64x2'], value);
2021+
},
2022+
'trunc': function(value) {
2023+
return Module['_BinaryenUnary'](module, Module['TruncVecF64x2'], value);
2024+
},
2025+
'nearest': function(value) {
2026+
return Module['_BinaryenUnary'](module, Module['NearestVecF64x2'], value);
2027+
},
19962028
'convert_i64x2_s': function(value) {
19972029
return Module['_BinaryenUnary'](module, Module['ConvertSVecI64x2ToVecF64x2'], value);
19982030
},

src/literal.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -429,6 +429,10 @@ class Literal {
429429
Literal maxF32x4(const Literal& other) const;
430430
Literal pminF32x4(const Literal& other) const;
431431
Literal pmaxF32x4(const Literal& other) const;
432+
Literal ceilF32x4() const;
433+
Literal floorF32x4() const;
434+
Literal truncF32x4() const;
435+
Literal nearestF32x4() const;
432436
Literal absF64x2() const;
433437
Literal negF64x2() const;
434438
Literal sqrtF64x2() const;
@@ -440,6 +444,10 @@ class Literal {
440444
Literal maxF64x2(const Literal& other) const;
441445
Literal pminF64x2(const Literal& other) const;
442446
Literal pmaxF64x2(const Literal& other) const;
447+
Literal ceilF64x2() const;
448+
Literal floorF64x2() const;
449+
Literal truncF64x2() const;
450+
Literal nearestF64x2() const;
443451
Literal truncSatToSI32x4() const;
444452
Literal truncSatToUI32x4() const;
445453
Literal truncSatToSI64x2() const;

src/passes/Print.cpp

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -780,6 +780,18 @@ struct PrintExpressionContents
780780
case SqrtVecF32x4:
781781
o << "f32x4.sqrt";
782782
break;
783+
case CeilVecF32x4:
784+
o << "f32x4.ceil";
785+
break;
786+
case FloorVecF32x4:
787+
o << "f32x4.floor";
788+
break;
789+
case TruncVecF32x4:
790+
o << "f32x4.trunc";
791+
break;
792+
case NearestVecF32x4:
793+
o << "f32x4.nearest";
794+
break;
783795
case AbsVecF64x2:
784796
o << "f64x2.abs";
785797
break;
@@ -789,6 +801,18 @@ struct PrintExpressionContents
789801
case SqrtVecF64x2:
790802
o << "f64x2.sqrt";
791803
break;
804+
case CeilVecF64x2:
805+
o << "f64x2.ceil";
806+
break;
807+
case FloorVecF64x2:
808+
o << "f64x2.floor";
809+
break;
810+
case TruncVecF64x2:
811+
o << "f64x2.trunc";
812+
break;
813+
case NearestVecF64x2:
814+
o << "f64x2.nearest";
815+
break;
792816
case TruncSatSVecF32x4ToVecI32x4:
793817
o << "i32x4.trunc_sat_f32x4_s";
794818
break;

src/wasm-binary.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -862,6 +862,15 @@ enum ASTNodes {
862862
F32x4PMin = 0xea,
863863
F32x4PMax = 0xeb,
864864

865+
F32x4Ceil = 0xd8,
866+
F32x4Floor = 0xd9,
867+
F32x4Trunc = 0xda,
868+
F32x4Nearest = 0xdb,
869+
F64x2Ceil = 0xdc,
870+
F64x2Floor = 0xdd,
871+
F64x2Trunc = 0xde,
872+
F64x2Nearest = 0xdf,
873+
865874
F64x2Abs = 0xec,
866875
F64x2Neg = 0xed,
867876
F64x2Sqrt = 0xef,

src/wasm-interpreter.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -495,12 +495,28 @@ class ExpressionRunner : public OverriddenVisitor<SubType, Flow> {
495495
return value.negF32x4();
496496
case SqrtVecF32x4:
497497
return value.sqrtF32x4();
498+
case CeilVecF32x4:
499+
return value.ceilF32x4();
500+
case FloorVecF32x4:
501+
return value.floorF32x4();
502+
case TruncVecF32x4:
503+
return value.truncF32x4();
504+
case NearestVecF32x4:
505+
return value.nearestF32x4();
498506
case AbsVecF64x2:
499507
return value.absF64x2();
500508
case NegVecF64x2:
501509
return value.negF64x2();
502510
case SqrtVecF64x2:
503511
return value.sqrtF64x2();
512+
case CeilVecF64x2:
513+
return value.ceilF64x2();
514+
case FloorVecF64x2:
515+
return value.floorF64x2();
516+
case TruncVecF64x2:
517+
return value.truncF64x2();
518+
case NearestVecF64x2:
519+
return value.nearestF64x2();
504520
case TruncSatSVecF32x4ToVecI32x4:
505521
return value.truncSatToSI32x4();
506522
case TruncSatUVecF32x4ToVecI32x4:

0 commit comments

Comments
 (0)