Skip to content

Commit 8b15cee

Browse files
authored
SIMD {i8x16,i16x8}.avgr_u instructions (#2539)
As specified in WebAssembly/simd#126.
1 parent 323e475 commit 8b15cee

25 files changed

+1144
-885
lines changed

scripts/gen-s-parser.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -375,6 +375,7 @@
375375
("i8x16.min_u", "makeBinary(s, BinaryOp::MinUVecI8x16)"),
376376
("i8x16.max_s", "makeBinary(s, BinaryOp::MaxSVecI8x16)"),
377377
("i8x16.max_u", "makeBinary(s, BinaryOp::MaxUVecI8x16)"),
378+
("i8x16.avgr_u", "makeBinary(s, BinaryOp::AvgrUVecI8x16)"),
378379
("i16x8.neg", "makeUnary(s, UnaryOp::NegVecI16x8)"),
379380
("i16x8.any_true", "makeUnary(s, UnaryOp::AnyTrueVecI16x8)"),
380381
("i16x8.all_true", "makeUnary(s, UnaryOp::AllTrueVecI16x8)"),
@@ -392,6 +393,7 @@
392393
("i16x8.min_u", "makeBinary(s, BinaryOp::MinUVecI16x8)"),
393394
("i16x8.max_s", "makeBinary(s, BinaryOp::MaxSVecI16x8)"),
394395
("i16x8.max_u", "makeBinary(s, BinaryOp::MaxUVecI16x8)"),
396+
("i16x8.avgr_u", "makeBinary(s, BinaryOp::AvgrUVecI16x8)"),
395397
("i32x4.neg", "makeUnary(s, UnaryOp::NegVecI32x4)"),
396398
("i32x4.any_true", "makeUnary(s, UnaryOp::AnyTrueVecI32x4)"),
397399
("i32x4.all_true", "makeUnary(s, UnaryOp::AllTrueVecI32x4)"),

src/binaryen-c.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -780,6 +780,7 @@ BinaryenOp BinaryenMinSVecI8x16(void) { return MinSVecI8x16; }
780780
BinaryenOp BinaryenMinUVecI8x16(void) { return MinUVecI8x16; }
781781
BinaryenOp BinaryenMaxSVecI8x16(void) { return MaxSVecI8x16; }
782782
BinaryenOp BinaryenMaxUVecI8x16(void) { return MaxUVecI8x16; }
783+
BinaryenOp BinaryenAvgrUVecI8x16(void) { return AvgrUVecI8x16; }
783784
BinaryenOp BinaryenNegVecI16x8(void) { return NegVecI16x8; }
784785
BinaryenOp BinaryenAnyTrueVecI16x8(void) { return AnyTrueVecI16x8; }
785786
BinaryenOp BinaryenAllTrueVecI16x8(void) { return AllTrueVecI16x8; }
@@ -797,6 +798,7 @@ BinaryenOp BinaryenMinSVecI16x8(void) { return MinSVecI16x8; }
797798
BinaryenOp BinaryenMinUVecI16x8(void) { return MinUVecI16x8; }
798799
BinaryenOp BinaryenMaxSVecI16x8(void) { return MaxSVecI16x8; }
799800
BinaryenOp BinaryenMaxUVecI16x8(void) { return MaxUVecI16x8; }
801+
BinaryenOp BinaryenAvgrUVecI16x8(void) { return AvgrUVecI16x8; }
800802
BinaryenOp BinaryenNegVecI32x4(void) { return NegVecI32x4; }
801803
BinaryenOp BinaryenAnyTrueVecI32x4(void) { return AnyTrueVecI32x4; }
802804
BinaryenOp BinaryenAllTrueVecI32x4(void) { return AllTrueVecI32x4; }

src/binaryen-c.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -474,6 +474,7 @@ BINARYEN_API BinaryenOp BinaryenMinSVecI8x16(void);
474474
BINARYEN_API BinaryenOp BinaryenMinUVecI8x16(void);
475475
BINARYEN_API BinaryenOp BinaryenMaxSVecI8x16(void);
476476
BINARYEN_API BinaryenOp BinaryenMaxUVecI8x16(void);
477+
BINARYEN_API BinaryenOp BinaryenAvgrUVecI8x16(void);
477478
BINARYEN_API BinaryenOp BinaryenNegVecI16x8(void);
478479
BINARYEN_API BinaryenOp BinaryenAnyTrueVecI16x8(void);
479480
BINARYEN_API BinaryenOp BinaryenAllTrueVecI16x8(void);
@@ -491,6 +492,7 @@ BINARYEN_API BinaryenOp BinaryenMinSVecI16x8(void);
491492
BINARYEN_API BinaryenOp BinaryenMinUVecI16x8(void);
492493
BINARYEN_API BinaryenOp BinaryenMaxSVecI16x8(void);
493494
BINARYEN_API BinaryenOp BinaryenMaxUVecI16x8(void);
495+
BINARYEN_API BinaryenOp BinaryenAvgrUVecI16x8(void);
494496
BINARYEN_API BinaryenOp BinaryenNegVecI32x4(void);
495497
BINARYEN_API BinaryenOp BinaryenAnyTrueVecI32x4(void);
496498
BINARYEN_API BinaryenOp BinaryenAllTrueVecI32x4(void);

src/gen-s-parser.inc

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -698,6 +698,9 @@ switch (op[0]) {
698698
case 'n':
699699
if (strcmp(op, "i16x8.any_true") == 0) { return makeUnary(s, UnaryOp::AnyTrueVecI16x8); }
700700
goto parse_error;
701+
case 'v':
702+
if (strcmp(op, "i16x8.avgr_u") == 0) { return makeBinary(s, BinaryOp::AvgrUVecI16x8); }
703+
goto parse_error;
701704
default: goto parse_error;
702705
}
703706
}
@@ -2241,6 +2244,9 @@ switch (op[0]) {
22412244
case 'n':
22422245
if (strcmp(op, "i8x16.any_true") == 0) { return makeUnary(s, UnaryOp::AnyTrueVecI8x16); }
22432246
goto parse_error;
2247+
case 'v':
2248+
if (strcmp(op, "i8x16.avgr_u") == 0) { return makeBinary(s, BinaryOp::AvgrUVecI8x16); }
2249+
goto parse_error;
22442250
default: goto parse_error;
22452251
}
22462252
}

src/ir/cost.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -594,6 +594,9 @@ struct CostAnalyzer : public Visitor<CostAnalyzer, Index> {
594594
case MaxUVecI8x16:
595595
ret = 1;
596596
break;
597+
case AvgrUVecI8x16:
598+
ret = 1;
599+
break;
597600
case AddVecI16x8:
598601
ret = 1;
599602
break;
@@ -627,6 +630,9 @@ struct CostAnalyzer : public Visitor<CostAnalyzer, Index> {
627630
case MaxUVecI16x8:
628631
ret = 1;
629632
break;
633+
case AvgrUVecI16x8:
634+
ret = 1;
635+
break;
630636
case AddVecI32x4:
631637
ret = 1;
632638
break;

src/js/binaryen.js-post.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -359,6 +359,7 @@ Module['MinSVecI8x16'] = Module['_BinaryenMinSVecI8x16']();
359359
Module['MinUVecI8x16'] = Module['_BinaryenMinUVecI8x16']();
360360
Module['MaxSVecI8x16'] = Module['_BinaryenMaxSVecI8x16']();
361361
Module['MaxUVecI8x16'] = Module['_BinaryenMaxUVecI8x16']();
362+
Module['AvgrUVecI8x16'] = Module['_BinaryenAvgrUVecI8x16']();
362363
Module['NegVecI16x8'] = Module['_BinaryenNegVecI16x8']();
363364
Module['AnyTrueVecI16x8'] = Module['_BinaryenAnyTrueVecI16x8']();
364365
Module['AllTrueVecI16x8'] = Module['_BinaryenAllTrueVecI16x8']();
@@ -376,6 +377,7 @@ Module['MinSVecI16x8'] = Module['_BinaryenMinSVecI16x8']();
376377
Module['MinUVecI16x8'] = Module['_BinaryenMinUVecI16x8']();
377378
Module['MaxSVecI16x8'] = Module['_BinaryenMaxSVecI16x8']();
378379
Module['MaxUVecI16x8'] = Module['_BinaryenMaxUVecI16x8']();
380+
Module['AvgrUVecI16x8'] = Module['_BinaryenAvgrUVecI16x8']();
379381
Module['DotSVecI16x8ToVecI32x4'] = Module['_BinaryenDotSVecI16x8ToVecI32x4']();
380382
Module['NegVecI32x4'] = Module['_BinaryenNegVecI32x4']();
381383
Module['AnyTrueVecI32x4'] = Module['_BinaryenAnyTrueVecI32x4']();
@@ -1492,6 +1494,9 @@ function wrapModule(module, self) {
14921494
'max_u': function(left, right) {
14931495
return Module['_BinaryenBinary'](module, Module['MaxUVecI8x16'], left, right);
14941496
},
1497+
'avgr_u': function(left, right) {
1498+
return Module['_BinaryenBinary'](module, Module['AvgrUVecI8x16'], left, right);
1499+
},
14951500
'narrow_i16x8_s': function(left, right) {
14961501
return Module['_BinaryenBinary'](module, Module['NarrowSVecI16x8ToVecI8x16'], left, right);
14971502
},
@@ -1594,6 +1599,9 @@ function wrapModule(module, self) {
15941599
'max_u': function(left, right) {
15951600
return Module['_BinaryenBinary'](module, Module['MaxUVecI16x8'], left, right);
15961601
},
1602+
'avgr_u': function(left, right) {
1603+
return Module['_BinaryenBinary'](module, Module['AvgrUVecI16x8'], left, right);
1604+
},
15971605
'narrow_i32x4_s': function(left, right) {
15981606
return Module['_BinaryenBinary'](module, Module['NarrowSVecI32x4ToVecI16x8'], left, right);
15991607
},

src/literal.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -334,6 +334,7 @@ class Literal {
334334
Literal minUI8x16(const Literal& other) const;
335335
Literal maxSI8x16(const Literal& other) const;
336336
Literal maxUI8x16(const Literal& other) const;
337+
Literal avgrUI8x16(const Literal& other) const;
337338
Literal negI16x8() const;
338339
Literal anyTrueI16x8() const;
339340
Literal allTrueI16x8() const;
@@ -351,6 +352,7 @@ class Literal {
351352
Literal minUI16x8(const Literal& other) const;
352353
Literal maxSI16x8(const Literal& other) const;
353354
Literal maxUI16x8(const Literal& other) const;
355+
Literal avgrUI16x8(const Literal& other) const;
354356
Literal negI32x4() const;
355357
Literal anyTrueI32x4() const;
356358
Literal allTrueI32x4() const;
@@ -426,6 +428,7 @@ class Literal {
426428
Literal maxInt(const Literal& other) const;
427429
Literal minUInt(const Literal& other) const;
428430
Literal maxUInt(const Literal& other) const;
431+
Literal avgrUInt(const Literal& other) const;
429432
};
430433

431434
} // namespace wasm

src/passes/Print.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1204,6 +1204,9 @@ struct PrintExpressionContents
12041204
case MaxUVecI8x16:
12051205
o << "i8x16.max_u";
12061206
break;
1207+
case AvgrUVecI8x16:
1208+
o << "i8x16.avgr_u";
1209+
break;
12071210
case AddVecI16x8:
12081211
o << "i16x8.add";
12091212
break;
@@ -1237,6 +1240,9 @@ struct PrintExpressionContents
12371240
case MaxUVecI16x8:
12381241
o << "i16x8.max_u";
12391242
break;
1243+
case AvgrUVecI16x8:
1244+
o << "i16x8.avgr_u";
1245+
break;
12401246
case AddVecI32x4:
12411247
o << "i32x4.add";
12421248
break;

src/wasm-binary.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -765,6 +765,7 @@ enum ASTNodes {
765765
I8x16MinU = 0x5f,
766766
I8x16MaxS = 0x60,
767767
I8x16MaxU = 0x61,
768+
I8x16AvgrU = 0xd9,
768769
I16x8Neg = 0x62,
769770
I16x8AnyTrue = 0x63,
770771
I16x8AllTrue = 0x64,
@@ -782,6 +783,7 @@ enum ASTNodes {
782783
I16x8MinU = 0x70,
783784
I16x8MaxS = 0x71,
784785
I16x8MaxU = 0x72,
786+
I16x8AvgrU = 0xda,
785787
I32x4Neg = 0x73,
786788
I32x4AnyTrue = 0x74,
787789
I32x4AllTrue = 0x75,
@@ -795,7 +797,7 @@ enum ASTNodes {
795797
I32x4MinU = 0x81,
796798
I32x4MaxS = 0x82,
797799
I32x4MaxU = 0x83,
798-
I32x4DotSVecI16x8 = 0xd9,
800+
I32x4DotSVecI16x8 = 0xdb,
799801
I64x2Neg = 0x84,
800802
I64x2AnyTrue = 0x85,
801803
I64x2AllTrue = 0x86,

src/wasm-interpreter.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -765,6 +765,8 @@ class ExpressionRunner : public OverriddenVisitor<SubType, Flow> {
765765
return left.maxSI8x16(right);
766766
case MaxUVecI8x16:
767767
return left.maxUI8x16(right);
768+
case AvgrUVecI8x16:
769+
return left.avgrUI8x16(right);
768770
case AddVecI16x8:
769771
return left.addI16x8(right);
770772
case AddSatSVecI16x8:
@@ -787,6 +789,8 @@ class ExpressionRunner : public OverriddenVisitor<SubType, Flow> {
787789
return left.maxSI16x8(right);
788790
case MaxUVecI16x8:
789791
return left.maxUI16x8(right);
792+
case AvgrUVecI16x8:
793+
return left.avgrUI16x8(right);
790794
case AddVecI32x4:
791795
return left.addI32x4(right);
792796
case SubVecI32x4:

src/wasm.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -365,6 +365,7 @@ enum BinaryOp {
365365
MinUVecI8x16,
366366
MaxSVecI8x16,
367367
MaxUVecI8x16,
368+
AvgrUVecI8x16,
368369
AddVecI16x8,
369370
AddSatSVecI16x8,
370371
AddSatUVecI16x8,
@@ -376,6 +377,7 @@ enum BinaryOp {
376377
MinUVecI16x8,
377378
MaxSVecI16x8,
378379
MaxUVecI16x8,
380+
AvgrUVecI16x8,
379381
AddVecI32x4,
380382
SubVecI32x4,
381383
MulVecI32x4,

src/wasm/literal.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -860,6 +860,10 @@ Literal Literal::maxUInt(const Literal& other) const {
860860
return uint32_t(geti32()) > uint32_t(other.geti32()) ? *this : other;
861861
}
862862

863+
Literal Literal::avgrUInt(const Literal& other) const {
864+
return Literal((geti32() + other.geti32() + 1) / 2);
865+
}
866+
863867
Literal Literal::and_(const Literal& other) const {
864868
switch (type) {
865869
case Type::i32:
@@ -1729,6 +1733,9 @@ Literal Literal::maxSI8x16(const Literal& other) const {
17291733
Literal Literal::maxUI8x16(const Literal& other) const {
17301734
return binary<16, &Literal::getLanesUI8x16, &Literal::maxInt>(*this, other);
17311735
}
1736+
Literal Literal::avgrUI8x16(const Literal& other) const {
1737+
return binary<16, &Literal::getLanesUI8x16, &Literal::avgrUInt>(*this, other);
1738+
}
17321739
Literal Literal::addI16x8(const Literal& other) const {
17331740
return binary<8, &Literal::getLanesUI16x8, &Literal::add>(*this, other);
17341741
}
@@ -1766,6 +1773,9 @@ Literal Literal::maxSI16x8(const Literal& other) const {
17661773
Literal Literal::maxUI16x8(const Literal& other) const {
17671774
return binary<8, &Literal::getLanesUI16x8, &Literal::maxInt>(*this, other);
17681775
}
1776+
Literal Literal::avgrUI16x8(const Literal& other) const {
1777+
return binary<8, &Literal::getLanesUI16x8, &Literal::avgrUInt>(*this, other);
1778+
}
17691779
Literal Literal::addI32x4(const Literal& other) const {
17701780
return binary<4, &Literal::getLanesI32x4, &Literal::add>(*this, other);
17711781
}

src/wasm/wasm-binary.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3589,6 +3589,10 @@ bool WasmBinaryBuilder::maybeVisitSIMDBinary(Expression*& out, uint32_t code) {
35893589
curr = allocator.alloc<Binary>();
35903590
curr->op = MaxUVecI8x16;
35913591
break;
3592+
case BinaryConsts::I8x16AvgrU:
3593+
curr = allocator.alloc<Binary>();
3594+
curr->op = AvgrUVecI8x16;
3595+
break;
35923596
case BinaryConsts::I16x8Add:
35933597
curr = allocator.alloc<Binary>();
35943598
curr->op = AddVecI16x8;
@@ -3633,6 +3637,10 @@ bool WasmBinaryBuilder::maybeVisitSIMDBinary(Expression*& out, uint32_t code) {
36333637
curr = allocator.alloc<Binary>();
36343638
curr->op = MaxUVecI16x8;
36353639
break;
3640+
case BinaryConsts::I16x8AvgrU:
3641+
curr = allocator.alloc<Binary>();
3642+
curr->op = AvgrUVecI16x8;
3643+
break;
36363644
case BinaryConsts::I32x4Add:
36373645
curr = allocator.alloc<Binary>();
36383646
curr->op = AddVecI32x4;

src/wasm/wasm-stack.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1401,6 +1401,9 @@ void BinaryInstWriter::visitBinary(Binary* curr) {
14011401
case MaxUVecI8x16:
14021402
o << int8_t(BinaryConsts::SIMDPrefix) << U32LEB(BinaryConsts::I8x16MaxU);
14031403
break;
1404+
case AvgrUVecI8x16:
1405+
o << int8_t(BinaryConsts::SIMDPrefix) << U32LEB(BinaryConsts::I8x16AvgrU);
1406+
break;
14041407
case AddVecI16x8:
14051408
o << int8_t(BinaryConsts::SIMDPrefix) << U32LEB(BinaryConsts::I16x8Add);
14061409
break;
@@ -1438,6 +1441,9 @@ void BinaryInstWriter::visitBinary(Binary* curr) {
14381441
case MaxUVecI16x8:
14391442
o << int8_t(BinaryConsts::SIMDPrefix) << U32LEB(BinaryConsts::I16x8MaxU);
14401443
break;
1444+
case AvgrUVecI16x8:
1445+
o << int8_t(BinaryConsts::SIMDPrefix) << U32LEB(BinaryConsts::I16x8AvgrU);
1446+
break;
14411447
case AddVecI32x4:
14421448
o << int8_t(BinaryConsts::SIMDPrefix) << U32LEB(BinaryConsts::I32x4Add);
14431449
break;

src/wasm/wasm-validator.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1344,6 +1344,7 @@ void FunctionValidator::visitBinary(Binary* curr) {
13441344
case MinUVecI8x16:
13451345
case MaxSVecI8x16:
13461346
case MaxUVecI8x16:
1347+
case AvgrUVecI8x16:
13471348
case AddVecI16x8:
13481349
case AddSatSVecI16x8:
13491350
case AddSatUVecI16x8:
@@ -1355,6 +1356,7 @@ void FunctionValidator::visitBinary(Binary* curr) {
13551356
case MinUVecI16x8:
13561357
case MaxSVecI16x8:
13571358
case MaxUVecI16x8:
1359+
case AvgrUVecI16x8:
13581360
case AddVecI32x4:
13591361
case SubVecI32x4:
13601362
case MulVecI32x4:

test/binaryen.js/kitchen-sink.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -355,6 +355,7 @@ function test_core() {
355355
module.i8x16.min_u(module.v128.const(v128_bytes), module.v128.const(v128_bytes)),
356356
module.i8x16.max_s(module.v128.const(v128_bytes), module.v128.const(v128_bytes)),
357357
module.i8x16.max_u(module.v128.const(v128_bytes), module.v128.const(v128_bytes)),
358+
module.i8x16.avgr_u(module.v128.const(v128_bytes), module.v128.const(v128_bytes)),
358359
module.i16x8.add(module.v128.const(v128_bytes), module.v128.const(v128_bytes)),
359360
module.i16x8.add_saturate_s(module.v128.const(v128_bytes), module.v128.const(v128_bytes)),
360361
module.i16x8.add_saturate_u(module.v128.const(v128_bytes), module.v128.const(v128_bytes)),
@@ -366,6 +367,7 @@ function test_core() {
366367
module.i16x8.min_u(module.v128.const(v128_bytes), module.v128.const(v128_bytes)),
367368
module.i16x8.max_s(module.v128.const(v128_bytes), module.v128.const(v128_bytes)),
368369
module.i16x8.max_u(module.v128.const(v128_bytes), module.v128.const(v128_bytes)),
370+
module.i16x8.avgr_u(module.v128.const(v128_bytes), module.v128.const(v128_bytes)),
369371
module.i32x4.add(module.v128.const(v128_bytes), module.v128.const(v128_bytes)),
370372
module.i32x4.sub(module.v128.const(v128_bytes), module.v128.const(v128_bytes)),
371373
module.i32x4.mul(module.v128.const(v128_bytes), module.v128.const(v128_bytes)),

0 commit comments

Comments
 (0)