Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions scripts/gen-s-parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -452,6 +452,14 @@
("i64x2.extmul_high_i32x4_s", "makeBinary(BinaryOp::ExtMulHighSVecI64x2)"),
("i64x2.extmul_low_i32x4_u", "makeBinary(BinaryOp::ExtMulLowUVecI64x2)"),
("i64x2.extmul_high_i32x4_u", "makeBinary(BinaryOp::ExtMulHighUVecI64x2)"),
("f16x8.add", "makeBinary(BinaryOp::AddVecF16x8)"),
("f16x8.sub", "makeBinary(BinaryOp::SubVecF16x8)"),
("f16x8.mul", "makeBinary(BinaryOp::MulVecF16x8)"),
("f16x8.div", "makeBinary(BinaryOp::DivVecF16x8)"),
("f16x8.min", "makeBinary(BinaryOp::MinVecF16x8)"),
("f16x8.max", "makeBinary(BinaryOp::MaxVecF16x8)"),
("f16x8.pmin", "makeBinary(BinaryOp::PMinVecF16x8)"),
("f16x8.pmax", "makeBinary(BinaryOp::PMaxVecF16x8)"),
("f32x4.abs", "makeUnary(UnaryOp::AbsVecF32x4)"),
("f32x4.neg", "makeUnary(UnaryOp::NegVecF32x4)"),
("f32x4.sqrt", "makeUnary(UnaryOp::SqrtVecF32x4)"),
Expand Down
73 changes: 68 additions & 5 deletions src/gen-s-parser.inc
Original file line number Diff line number Diff line change
Expand Up @@ -309,6 +309,18 @@ switch (buf[0]) {
switch (buf[1]) {
case '1': {
switch (buf[6]) {
case 'a':
if (op == "f16x8.add"sv) {
CHECK_ERR(makeBinary(ctx, pos, annotations, BinaryOp::AddVecF16x8));
return Ok{};
}
goto parse_error;
case 'd':
if (op == "f16x8.div"sv) {
CHECK_ERR(makeBinary(ctx, pos, annotations, BinaryOp::DivVecF16x8));
return Ok{};
}
goto parse_error;
case 'e': {
switch (buf[7]) {
case 'q':
Expand Down Expand Up @@ -360,24 +372,75 @@ switch (buf[0]) {
default: goto parse_error;
}
}
case 'm': {
switch (buf[7]) {
case 'a':
if (op == "f16x8.max"sv) {
CHECK_ERR(makeBinary(ctx, pos, annotations, BinaryOp::MaxVecF16x8));
return Ok{};
}
goto parse_error;
case 'i':
if (op == "f16x8.min"sv) {
CHECK_ERR(makeBinary(ctx, pos, annotations, BinaryOp::MinVecF16x8));
return Ok{};
}
goto parse_error;
case 'u':
if (op == "f16x8.mul"sv) {
CHECK_ERR(makeBinary(ctx, pos, annotations, BinaryOp::MulVecF16x8));
return Ok{};
}
goto parse_error;
default: goto parse_error;
}
}
case 'n':
if (op == "f16x8.ne"sv) {
CHECK_ERR(makeBinary(ctx, pos, annotations, BinaryOp::NeVecF16x8));
return Ok{};
}
goto parse_error;
case 'p': {
switch (buf[8]) {
case 'a':
if (op == "f16x8.pmax"sv) {
CHECK_ERR(makeBinary(ctx, pos, annotations, BinaryOp::PMaxVecF16x8));
return Ok{};
}
goto parse_error;
case 'i':
if (op == "f16x8.pmin"sv) {
CHECK_ERR(makeBinary(ctx, pos, annotations, BinaryOp::PMinVecF16x8));
return Ok{};
}
goto parse_error;
default: goto parse_error;
}
}
case 'r':
if (op == "f16x8.replace_lane"sv) {
CHECK_ERR(makeSIMDReplace(ctx, pos, annotations, SIMDReplaceOp::ReplaceLaneVecF16x8, 8));
return Ok{};
}
goto parse_error;
case 's':
if (op == "f16x8.splat"sv) {
CHECK_ERR(makeUnary(ctx, pos, annotations, UnaryOp::SplatVecF16x8));
return Ok{};
case 's': {
switch (buf[7]) {
case 'p':
if (op == "f16x8.splat"sv) {
CHECK_ERR(makeUnary(ctx, pos, annotations, UnaryOp::SplatVecF16x8));
return Ok{};
}
goto parse_error;
case 'u':
if (op == "f16x8.sub"sv) {
CHECK_ERR(makeBinary(ctx, pos, annotations, BinaryOp::SubVecF16x8));
return Ok{};
}
goto parse_error;
default: goto parse_error;
}
goto parse_error;
}
default: goto parse_error;
}
}
Expand Down
8 changes: 8 additions & 0 deletions src/ir/child-typer.h
Original file line number Diff line number Diff line change
Expand Up @@ -627,6 +627,14 @@ template<typename Subtype> struct ChildTyper : OverriddenVisitor<Subtype> {
case ExtMulHighSVecI64x2:
case ExtMulLowUVecI64x2:
case ExtMulHighUVecI64x2:
case AddVecF16x8:
case SubVecF16x8:
case MulVecF16x8:
case DivVecF16x8:
case MinVecF16x8:
case MaxVecF16x8:
case PMinVecF16x8:
case PMaxVecF16x8:
case AddVecF32x4:
case SubVecF32x4:
case MulVecF32x4:
Expand Down
16 changes: 16 additions & 0 deletions src/ir/cost.h
Original file line number Diff line number Diff line change
Expand Up @@ -475,6 +475,22 @@ struct CostAnalyzer : public OverriddenVisitor<CostAnalyzer, CostType> {
case ExtMulHighSVecI64x2:
case ExtMulLowUVecI64x2:
case ExtMulHighUVecI64x2:
case AddVecF16x8:
case SubVecF16x8:
ret = 1;
break;
case MulVecF16x8:
ret = 2;
break;
case DivVecF16x8:
ret = 3;
break;
case MinVecF16x8:
case MaxVecF16x8:
case PMinVecF16x8:
case PMaxVecF16x8:
ret = 1;
break;
case AddVecF32x4:
case SubVecF32x4:
ret = 1;
Expand Down
9 changes: 9 additions & 0 deletions src/literal.h
Original file line number Diff line number Diff line change
Expand Up @@ -375,6 +375,7 @@ class Literal {
Literal convertUIToF32() const;
Literal convertSIToF64() const;
Literal convertUIToF64() const;
Literal convertF32ToF16() const;

Literal truncSatToSI32() const;
Literal truncSatToSI64() const;
Expand Down Expand Up @@ -611,6 +612,14 @@ class Literal {
Literal extMulHighSI64x2(const Literal& other) const;
Literal extMulLowUI64x2(const Literal& other) const;
Literal extMulHighUI64x2(const Literal& other) const;
Literal addF16x8(const Literal& other) const;
Literal subF16x8(const Literal& other) const;
Literal mulF16x8(const Literal& other) const;
Literal divF16x8(const Literal& other) const;
Literal minF16x8(const Literal& other) const;
Literal maxF16x8(const Literal& other) const;
Literal pminF16x8(const Literal& other) const;
Literal pmaxF16x8(const Literal& other) const;
Literal absF32x4() const;
Literal negF32x4() const;
Literal sqrtF32x4() const;
Expand Down
25 changes: 25 additions & 0 deletions src/passes/Print.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1901,6 +1901,31 @@ struct PrintExpressionContents
o << "i64x2.extmul_high_i32x4_u";
break;

case AddVecF16x8:
o << "f16x8.add";
break;
case SubVecF16x8:
o << "f16x8.sub";
break;
case MulVecF16x8:
o << "f16x8.mul";
break;
case DivVecF16x8:
o << "f16x8.div";
break;
case MinVecF16x8:
o << "f16x8.min";
break;
case MaxVecF16x8:
o << "f16x8.max";
break;
case PMinVecF16x8:
o << "f16x8.pmin";
break;
case PMaxVecF16x8:
o << "f16x8.pmax";
break;

case AddVecF32x4:
o << "f32x4.add";
break;
Expand Down
6 changes: 6 additions & 0 deletions src/tools/fuzzing/fuzzing.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3345,6 +3345,12 @@ Expression* TranslateToFuzzReader::makeBinary(Type type) {
DotSVecI16x8ToVecI32x4,
AddVecI64x2,
SubVecI64x2,
AddVecF16x8,
SubVecF16x8,
MulVecF16x8,
DivVecF16x8,
MinVecF16x8,
MaxVecF16x8,
AddVecF32x4,
SubVecF32x4,
MulVecF32x4,
Expand Down
8 changes: 8 additions & 0 deletions src/wasm-binary.h
Original file line number Diff line number Diff line change
Expand Up @@ -1063,6 +1063,14 @@ enum ASTNodes {
F16x8Gt = 0x13a,
F16x8Le = 0x13b,
F16x8Ge = 0x13c,
F16x8Add = 0x13d,
F16x8Sub = 0x13e,
F16x8Mul = 0x13f,
F16x8Div = 0x140,
F16x8Min = 0x141,
F16x8Max = 0xe142,
F16x8Pmin = 0x143,
F16x8Pmax = 0x144,

// bulk memory opcodes

Expand Down
17 changes: 17 additions & 0 deletions src/wasm-interpreter.h
Original file line number Diff line number Diff line change
Expand Up @@ -1006,6 +1006,23 @@ class ExpressionRunner : public OverriddenVisitor<SubType, Flow> {
case ExtMulHighUVecI64x2:
return left.extMulHighUI64x2(right);

case AddVecF16x8:
return left.addF16x8(right);
case SubVecF16x8:
return left.subF16x8(right);
case MulVecF16x8:
return left.mulF16x8(right);
case DivVecF16x8:
return left.divF16x8(right);
case MinVecF16x8:
return left.minF16x8(right);
case MaxVecF16x8:
return left.maxF16x8(right);
case PMinVecF16x8:
return left.pminF16x8(right);
case PMaxVecF16x8:
return left.pmaxF16x8(right);

case AddVecF32x4:
return left.addF32x4(right);
case SubVecF32x4:
Expand Down
8 changes: 8 additions & 0 deletions src/wasm.h
Original file line number Diff line number Diff line change
Expand Up @@ -452,6 +452,14 @@ enum BinaryOp {
ExtMulHighSVecI64x2,
ExtMulLowUVecI64x2,
ExtMulHighUVecI64x2,
AddVecF16x8,
SubVecF16x8,
MulVecF16x8,
DivVecF16x8,
MinVecF16x8,
MaxVecF16x8,
PMinVecF16x8,
PMaxVecF16x8,
AddVecF32x4,
SubVecF32x4,
MulVecF32x4,
Expand Down
51 changes: 46 additions & 5 deletions src/wasm/literal.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -840,6 +840,10 @@ Literal Literal::convertUIToF64() const {
WASM_UNREACHABLE("invalid type");
}

Literal Literal::convertF32ToF16() const {
return Literal(fp16_ieee_from_fp32_value(getf32()));
}

template<typename F> struct AsInt { using type = void; };
template<> struct AsInt<float> { using type = int32_t; };
template<> struct AsInt<double> { using type = int64_t; };
Expand Down Expand Up @@ -1775,8 +1779,7 @@ Literal Literal::splatI16x8() const { return splat<Type::i32, 8>(*this); }
Literal Literal::splatI32x4() const { return splat<Type::i32, 4>(*this); }
Literal Literal::splatI64x2() const { return splat<Type::i64, 2>(*this); }
Literal Literal::splatF16x8() const {
uint16_t f16 = fp16_ieee_from_fp32_value(getf32());
return splat<Type::i32, 8>(Literal(f16));
return splat<Type::i32, 8>(convertF32ToF16());
}
Literal Literal::splatF32x4() const { return splat<Type::f32, 4>(*this); }
Literal Literal::splatF64x2() const { return splat<Type::f64, 2>(*this); }
Expand Down Expand Up @@ -1832,7 +1835,7 @@ Literal Literal::replaceLaneI64x2(const Literal& other, uint8_t index) const {
}
Literal Literal::replaceLaneF16x8(const Literal& other, uint8_t index) const {
return replace<8, &Literal::getLanesF16x8>(
*this, Literal(fp16_ieee_from_fp32_value(other.getf32())), index);
*this, other.convertF32ToF16(), index);
}
Literal Literal::replaceLaneF32x4(const Literal& other, uint8_t index) const {
return replace<4, &Literal::getLanesF32x4>(*this, other, index);
Expand Down Expand Up @@ -2270,14 +2273,20 @@ Literal Literal::geF64x2(const Literal& other) const {
other);
}

static Literal passThrough(const Literal& literal) { return literal; }
static Literal toFP16(const Literal& literal) {
return literal.convertF32ToF16();
}

template<int Lanes,
LaneArray<Lanes> (Literal::*IntoLanes)() const,
Literal (Literal::*BinaryOp)(const Literal&) const>
Literal (Literal::*BinaryOp)(const Literal&) const,
Literal (*Convert)(const Literal&) = passThrough>
static Literal binary(const Literal& val, const Literal& other) {
LaneArray<Lanes> lanes = (val.*IntoLanes)();
LaneArray<Lanes> other_lanes = (other.*IntoLanes)();
for (size_t i = 0; i < Lanes; ++i) {
lanes[i] = (lanes[i].*BinaryOp)(other_lanes[i]);
lanes[i] = Convert((lanes[i].*BinaryOp)(other_lanes[i]));
}
return Literal(lanes);
}
Expand Down Expand Up @@ -2402,6 +2411,38 @@ Literal Literal::subI64x2(const Literal& other) const {
Literal Literal::mulI64x2(const Literal& other) const {
return binary<2, &Literal::getLanesI64x2, &Literal::mul>(*this, other);
}
Literal Literal::addF16x8(const Literal& other) const {
return binary<8, &Literal::getLanesF16x8, &Literal::add, &toFP16>(*this,
other);
}
Literal Literal::subF16x8(const Literal& other) const {
return binary<8, &Literal::getLanesF16x8, &Literal::sub, &toFP16>(*this,
other);
}
Literal Literal::mulF16x8(const Literal& other) const {
return binary<8, &Literal::getLanesF16x8, &Literal::mul, &toFP16>(*this,
other);
}
Literal Literal::divF16x8(const Literal& other) const {
return binary<8, &Literal::getLanesF16x8, &Literal::div, &toFP16>(*this,
other);
}
Literal Literal::minF16x8(const Literal& other) const {
return binary<8, &Literal::getLanesF16x8, &Literal::min, &toFP16>(*this,
other);
}
Literal Literal::maxF16x8(const Literal& other) const {
return binary<8, &Literal::getLanesF16x8, &Literal::max, &toFP16>(*this,
other);
}
Literal Literal::pminF16x8(const Literal& other) const {
return binary<8, &Literal::getLanesF16x8, &Literal::pmin, &toFP16>(*this,
other);
}
Literal Literal::pmaxF16x8(const Literal& other) const {
return binary<8, &Literal::getLanesF16x8, &Literal::pmax, &toFP16>(*this,
other);
}
Literal Literal::addF32x4(const Literal& other) const {
return binary<4, &Literal::getLanesF32x4, &Literal::add>(*this, other);
}
Expand Down
Loading