summaryrefslogtreecommitdiff
path: root/src/wasm.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/wasm.h')
-rw-r--r--src/wasm.h110
1 files changed, 108 insertions, 2 deletions
diff --git a/src/wasm.h b/src/wasm.h
index b09b4d7d3..52a0ca299 100644
--- a/src/wasm.h
+++ b/src/wasm.h
@@ -25,6 +25,7 @@
#define wasm_wasm_h
#include <algorithm>
+#include <array>
#include <cassert>
#include <map>
#include <string>
@@ -43,7 +44,8 @@ struct FeatureSet {
Atomics = 1 << 0,
MutableGlobals = 1 << 1,
TruncSat = 1 << 2,
- All = Atomics | MutableGlobals | TruncSat
+ SIMD = 1 << 3,
+ All = Atomics | MutableGlobals | TruncSat | SIMD
};
FeatureSet() : features(MVP) {}
@@ -54,13 +56,15 @@ struct FeatureSet {
bool hasAtomics() const { return features & Atomics; }
bool hasMutableGlobals() const { return features & MutableGlobals; }
bool hasTruncSat() const { return features & TruncSat; }
- bool hasAll() const { return features & (Atomics | MutableGlobals | TruncSat); }
+ bool hasSIMD() const { return features & SIMD; }
+ bool hasAll() const { return features & All; }
void makeMVP() { features = MVP; }
void set(Feature f, bool v = true) { features = v ? (features | f) : (features & ~f); }
void setAtomics(bool v = true) { set(Atomics, v); }
void setMutableGlobals(bool v = true) { set(MutableGlobals, v); }
void setTruncSat(bool v = true) { set(TruncSat, v); }
+ void setSIMD(bool v = true) { set(SIMD, v); }
void setAll(bool v = true) { features = v ? All : MVP; }
private:
@@ -116,6 +120,15 @@ enum UnaryOp {
// Saturating float-to-int
TruncSatSFloat32ToInt32, TruncSatUFloat32ToInt32, TruncSatSFloat64ToInt32, TruncSatUFloat64ToInt32,
TruncSatSFloat32ToInt64, TruncSatUFloat32ToInt64, TruncSatSFloat64ToInt64, TruncSatUFloat64ToInt64,
+ // SIMD splats
+ SplatVecI8x16, SplatVecI16x8, SplatVecI32x4, SplatVecI64x2, SplatVecF32x4, SplatVecF64x2,
+ // SIMD arithmetic
+ NotVec128,
+ NegVecI8x16, AnyTrueVecI8x16, AllTrueVecI8x16, NegVecI16x8, AnyTrueVecI16x8, AllTrueVecI16x8,
+ NegVecI32x4, AnyTrueVecI32x4, AllTrueVecI32x4, NegVecI64x2, AnyTrueVecI64x2, AllTrueVecI64x2,
+ AbsVecF32x4, NegVecF32x4, SqrtVecF32x4, AbsVecF64x2, NegVecF64x2, SqrtVecF64x2,
+ TruncSatSVecF32x4ToVecI32x4, TruncSatUVecF32x4ToVecI32x4, TruncSatSVecF64x2ToVecI64x2, TruncSatUVecF64x2ToVecI64x2,
+ ConvertSVecI32x4ToVecF32x4, ConvertUVecI32x4ToVecF32x4, ConvertSVecI64x2ToVecF64x2, ConvertUVecI64x2ToVecF64x2,
InvalidUnary
};
@@ -144,6 +157,19 @@ enum BinaryOp {
// relational ops
EqFloat64, NeFloat64, // int or float
LtFloat64, LeFloat64, GtFloat64, GeFloat64, // float
+ // SIMD relational ops (return vectors)
+ EqVecI8x16, NeVecI8x16, LtSVecI8x16, LtUVecI8x16, GtSVecI8x16, GtUVecI8x16, LeSVecI8x16, LeUVecI8x16, GeSVecI8x16, GeUVecI8x16,
+ EqVecI16x8, NeVecI16x8, LtSVecI16x8, LtUVecI16x8, GtSVecI16x8, GtUVecI16x8, LeSVecI16x8, LeUVecI16x8, GeSVecI16x8, GeUVecI16x8,
+ EqVecI32x4, NeVecI32x4, LtSVecI32x4, LtUVecI32x4, GtSVecI32x4, GtUVecI32x4, LeSVecI32x4, LeUVecI32x4, GeSVecI32x4, GeUVecI32x4,
+ EqVecF32x4, NeVecF32x4, LtVecF32x4, GtVecF32x4, LeVecF32x4, GeVecF32x4,
+ EqVecF64x2, NeVecF64x2, LtVecF64x2, GtVecF64x2, LeVecF64x2, GeVecF64x2,
+ // SIMD arithmetic
+ AndVec128, OrVec128, XorVec128,
+ AddVecI8x16, AddSatSVecI8x16, AddSatUVecI8x16, SubVecI8x16, SubSatSVecI8x16, SubSatUVecI8x16, MulVecI8x16,
+ AddVecI16x8, AddSatSVecI16x8, AddSatUVecI16x8, SubVecI16x8, SubSatSVecI16x8, SubSatUVecI16x8, MulVecI16x8,
+ AddVecI32x4, SubVecI32x4, MulVecI32x4, AddVecI64x2, SubVecI64x2,
+ AddVecF32x4, SubVecF32x4, MulVecF32x4, DivVecF32x4, MinVecF32x4, MaxVecF32x4,
+ AddVecF64x2, SubVecF64x2, MulVecF64x2, DivVecF64x2, MinVecF64x2, MaxVecF64x2,
InvalidBinary
};
@@ -156,6 +182,20 @@ enum AtomicRMWOp {
Add, Sub, And, Or, Xor, Xchg
};
+enum SIMDExtractOp {
+ ExtractLaneSVecI8x16, ExtractLaneUVecI8x16, ExtractLaneSVecI16x8, ExtractLaneUVecI16x8,
+ ExtractLaneVecI32x4, ExtractLaneVecI64x2, ExtractLaneVecF32x4, ExtractLaneVecF64x2
+};
+
+enum SIMDReplaceOp {
+ ReplaceLaneVecI8x16, ReplaceLaneVecI16x8, ReplaceLaneVecI32x4, ReplaceLaneVecI64x2, ReplaceLaneVecF32x4, ReplaceLaneVecF64x2
+};
+
+enum SIMDShiftOp {
+ ShlVecI8x16, ShrSVecI8x16, ShrUVecI8x16, ShlVecI16x8, ShrSVecI16x8, ShrUVecI16x8,
+ ShlVecI32x4, ShrSVecI32x4, ShrUVecI32x4, ShlVecI64x2, ShrSVecI64x2, ShrUVecI64x2
+};
+
//
// Expressions
//
@@ -206,6 +246,11 @@ public:
AtomicCmpxchgId,
AtomicWaitId,
AtomicWakeId,
+ SIMDExtractId,
+ SIMDReplaceId,
+ SIMDShuffleId,
+ SIMDBitselectId,
+ SIMDShiftId,
NumExpressionIds
};
Id _id;
@@ -502,6 +547,67 @@ class AtomicWake : public SpecificExpression<Expression::AtomicWakeId> {
void finalize();
};
+class SIMDExtract : public SpecificExpression<Expression::SIMDExtractId> {
+ public:
+ SIMDExtract() = default;
+ SIMDExtract(MixedArena& allocator) : SIMDExtract() {}
+
+ SIMDExtractOp op;
+ Expression* vec;
+ uint8_t idx;
+
+ void finalize();
+};
+
+class SIMDReplace : public SpecificExpression<Expression::SIMDReplaceId> {
+ public:
+ SIMDReplace() = default;
+ SIMDReplace(MixedArena& allocator) : SIMDReplace() {}
+
+ SIMDReplaceOp op;
+ Expression* vec;
+ uint8_t idx;
+ Expression* value;
+
+ void finalize();
+};
+
+class SIMDShuffle : public SpecificExpression<Expression::SIMDShuffleId> {
+ public:
+ SIMDShuffle() = default;
+ SIMDShuffle(MixedArena& allocator) : SIMDShuffle() {}
+
+ Expression* left;
+ Expression* right;
+ std::array<uint8_t, 16> mask;
+
+ void finalize();
+};
+
+class SIMDBitselect : public SpecificExpression<Expression::SIMDBitselectId> {
+ public:
+ SIMDBitselect() = default;
+ SIMDBitselect(MixedArena& allocator) : SIMDBitselect() {}
+
+ Expression* left;
+ Expression* right;
+ Expression* cond;
+
+ void finalize();
+};
+
+class SIMDShift : public SpecificExpression<Expression::SIMDShiftId> {
+ public:
+ SIMDShift() = default;
+ SIMDShift(MixedArena& allocator) : SIMDShift() {}
+
+ SIMDShiftOp op;
+ Expression* vec;
+ Expression* shift;
+
+ void finalize();
+};
+
class Const : public SpecificExpression<Expression::ConstId> {
public:
Const() {}