summaryrefslogtreecommitdiff
path: root/src/wasm
diff options
context:
space:
mode:
Diffstat (limited to 'src/wasm')
-rw-r--r--src/wasm/literal.cpp19
-rw-r--r--src/wasm/wasm-binary.cpp14
-rw-r--r--src/wasm/wasm-stack.cpp9
-rw-r--r--src/wasm/wasm-validator.cpp9
-rw-r--r--src/wasm/wasm.cpp2
5 files changed, 53 insertions, 0 deletions
diff --git a/src/wasm/literal.cpp b/src/wasm/literal.cpp
index f2100ea71..a532b92d0 100644
--- a/src/wasm/literal.cpp
+++ b/src/wasm/literal.cpp
@@ -20,6 +20,7 @@
#include <cmath>
#include "emscripten-optimizer/simple_ast.h"
+#include "fp16.h"
#include "ir/bits.h"
#include "pretty_printing.h"
#include "support/bits.h"
@@ -1729,6 +1730,13 @@ LaneArray<4> Literal::getLanesI32x4() const {
LaneArray<2> Literal::getLanesI64x2() const {
return getLanes<int64_t, 2>(*this);
}
+LaneArray<8> Literal::getLanesF16x8() const {
+ auto lanes = getLanesUI16x8();
+ for (size_t i = 0; i < lanes.size(); ++i) {
+ lanes[i] = Literal(fp16_ieee_to_fp32_value(lanes[i].geti32()));
+ }
+ return lanes;
+}
LaneArray<4> Literal::getLanesF32x4() const {
auto lanes = getLanesI32x4();
for (size_t i = 0; i < lanes.size(); ++i) {
@@ -1766,6 +1774,10 @@ Literal Literal::splatI8x16() const { return splat<Type::i32, 16>(*this); }
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));
+}
Literal Literal::splatF32x4() const { return splat<Type::f32, 4>(*this); }
Literal Literal::splatF64x2() const { return splat<Type::f64, 2>(*this); }
@@ -1787,6 +1799,9 @@ Literal Literal::extractLaneI32x4(uint8_t index) const {
Literal Literal::extractLaneI64x2(uint8_t index) const {
return getLanesI64x2().at(index);
}
+Literal Literal::extractLaneF16x8(uint8_t index) const {
+ return getLanesF16x8().at(index);
+}
Literal Literal::extractLaneF32x4(uint8_t index) const {
return getLanesF32x4().at(index);
}
@@ -1815,6 +1830,10 @@ Literal Literal::replaceLaneI32x4(const Literal& other, uint8_t index) const {
Literal Literal::replaceLaneI64x2(const Literal& other, uint8_t index) const {
return replace<2, &Literal::getLanesI64x2>(*this, other, index);
}
+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);
+}
Literal Literal::replaceLaneF32x4(const Literal& other, uint8_t index) const {
return replace<4, &Literal::getLanesF32x4>(*this, other, index);
}
diff --git a/src/wasm/wasm-binary.cpp b/src/wasm/wasm-binary.cpp
index b9645ab8f..5eaa84515 100644
--- a/src/wasm/wasm-binary.cpp
+++ b/src/wasm/wasm-binary.cpp
@@ -6239,6 +6239,10 @@ bool WasmBinaryReader::maybeVisitSIMDUnary(Expression*& out, uint32_t code) {
curr = allocator.alloc<Unary>();
curr->op = SplatVecI64x2;
break;
+ case BinaryConsts::F16x8Splat:
+ curr = allocator.alloc<Unary>();
+ curr->op = SplatVecF16x8;
+ break;
case BinaryConsts::F32x4Splat:
curr = allocator.alloc<Unary>();
curr->op = SplatVecF32x4;
@@ -6569,6 +6573,11 @@ bool WasmBinaryReader::maybeVisitSIMDExtract(Expression*& out, uint32_t code) {
curr->op = ExtractLaneVecI64x2;
curr->index = getLaneIndex(2);
break;
+ case BinaryConsts::F16x8ExtractLane:
+ curr = allocator.alloc<SIMDExtract>();
+ curr->op = ExtractLaneVecF16x8;
+ curr->index = getLaneIndex(8);
+ break;
case BinaryConsts::F32x4ExtractLane:
curr = allocator.alloc<SIMDExtract>();
curr->op = ExtractLaneVecF32x4;
@@ -6611,6 +6620,11 @@ bool WasmBinaryReader::maybeVisitSIMDReplace(Expression*& out, uint32_t code) {
curr->op = ReplaceLaneVecI64x2;
curr->index = getLaneIndex(2);
break;
+ case BinaryConsts::F16x8ReplaceLane:
+ curr = allocator.alloc<SIMDReplace>();
+ curr->op = ReplaceLaneVecF16x8;
+ curr->index = getLaneIndex(8);
+ break;
case BinaryConsts::F32x4ReplaceLane:
curr = allocator.alloc<SIMDReplace>();
curr->op = ReplaceLaneVecF32x4;
diff --git a/src/wasm/wasm-stack.cpp b/src/wasm/wasm-stack.cpp
index 35db3b322..19b98769b 100644
--- a/src/wasm/wasm-stack.cpp
+++ b/src/wasm/wasm-stack.cpp
@@ -590,6 +590,9 @@ void BinaryInstWriter::visitSIMDExtract(SIMDExtract* curr) {
case ExtractLaneVecI64x2:
o << U32LEB(BinaryConsts::I64x2ExtractLane);
break;
+ case ExtractLaneVecF16x8:
+ o << U32LEB(BinaryConsts::F16x8ExtractLane);
+ break;
case ExtractLaneVecF32x4:
o << U32LEB(BinaryConsts::F32x4ExtractLane);
break;
@@ -615,6 +618,9 @@ void BinaryInstWriter::visitSIMDReplace(SIMDReplace* curr) {
case ReplaceLaneVecI64x2:
o << U32LEB(BinaryConsts::I64x2ReplaceLane);
break;
+ case ReplaceLaneVecF16x8:
+ o << U32LEB(BinaryConsts::F16x8ReplaceLane);
+ break;
case ReplaceLaneVecF32x4:
o << U32LEB(BinaryConsts::F32x4ReplaceLane);
break;
@@ -1050,6 +1056,9 @@ void BinaryInstWriter::visitUnary(Unary* curr) {
case SplatVecI64x2:
o << int8_t(BinaryConsts::SIMDPrefix) << U32LEB(BinaryConsts::I64x2Splat);
break;
+ case SplatVecF16x8:
+ o << int8_t(BinaryConsts::SIMDPrefix) << U32LEB(BinaryConsts::F16x8Splat);
+ break;
case SplatVecF32x4:
o << int8_t(BinaryConsts::SIMDPrefix) << U32LEB(BinaryConsts::F32x4Splat);
break;
diff --git a/src/wasm/wasm-validator.cpp b/src/wasm/wasm-validator.cpp
index b32917432..6e59ce8d8 100644
--- a/src/wasm/wasm-validator.cpp
+++ b/src/wasm/wasm-validator.cpp
@@ -1272,6 +1272,10 @@ void FunctionValidator::visitSIMDExtract(SIMDExtract* curr) {
lane_t = Type::i64;
lanes = 2;
break;
+ case ExtractLaneVecF16x8:
+ lane_t = Type::f32;
+ lanes = 8;
+ break;
case ExtractLaneVecF32x4:
lane_t = Type::f32;
lanes = 4;
@@ -1318,6 +1322,10 @@ void FunctionValidator::visitSIMDReplace(SIMDReplace* curr) {
lane_t = Type::i64;
lanes = 2;
break;
+ case ReplaceLaneVecF16x8:
+ lane_t = Type::f32;
+ lanes = 8;
+ break;
case ReplaceLaneVecF32x4:
lane_t = Type::f32;
lanes = 4;
@@ -2036,6 +2044,7 @@ void FunctionValidator::visitUnary(Unary* curr) {
shouldBeEqual(
curr->value->type, Type(Type::i64), curr, "expected i64 splat value");
break;
+ case SplatVecF16x8:
case SplatVecF32x4:
shouldBeEqual(
curr->type, Type(Type::v128), curr, "expected splat to have v128 type");
diff --git a/src/wasm/wasm.cpp b/src/wasm/wasm.cpp
index b17250e6c..ae70e4a22 100644
--- a/src/wasm/wasm.cpp
+++ b/src/wasm/wasm.cpp
@@ -386,6 +386,7 @@ void SIMDExtract::finalize() {
case ExtractLaneVecI64x2:
type = Type::i64;
break;
+ case ExtractLaneVecF16x8:
case ExtractLaneVecF32x4:
type = Type::f32;
break;
@@ -636,6 +637,7 @@ void Unary::finalize() {
case SplatVecI16x8:
case SplatVecI32x4:
case SplatVecI64x2:
+ case SplatVecF16x8:
case SplatVecF32x4:
case SplatVecF64x2:
case NotVec128: