summaryrefslogtreecommitdiff
path: root/src/literal.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/literal.h')
-rw-r--r--src/literal.h220
1 files changed, 214 insertions, 6 deletions
diff --git a/src/literal.h b/src/literal.h
index 4ed23b80d..dd5688263 100644
--- a/src/literal.h
+++ b/src/literal.h
@@ -18,6 +18,7 @@
#define wasm_literal_h
#include <iostream>
+#include <array>
#include "support/hash.h"
#include "support/utilities.h"
@@ -36,10 +37,11 @@ private:
union {
int32_t i32;
int64_t i64;
+ uint8_t v128[16];
};
public:
- Literal() : type(Type::none), i64(0) {}
+ Literal() : type(Type::none), v128() {}
explicit Literal(Type type) : type(type), i64(0) {}
explicit Literal(int32_t init) : type(Type::i32), i32(init) {}
explicit Literal(uint32_t init) : type(Type::i32), i32(init) {}
@@ -47,10 +49,38 @@ public:
explicit Literal(uint64_t init) : type(Type::i64), i64(init) {}
explicit Literal(float init) : type(Type::f32), i32(bit_cast<int32_t>(init)) {}
explicit Literal(double init) : type(Type::f64), i64(bit_cast<int64_t>(init)) {}
+ // v128 literal from bytes
+ explicit Literal(const uint8_t init[16]);
+ // v128 literal from lane value literals
+ explicit Literal(const std::array<Literal, 16>&);
+ explicit Literal(const std::array<Literal, 8>&);
+ explicit Literal(const std::array<Literal, 4>&);
+ explicit Literal(const std::array<Literal, 2>&);
bool isConcrete() { return type != none; }
bool isNull() { return type == none; }
+ inline static Literal makeFromInt32(int32_t x, Type type) {
+ switch (type) {
+ case Type::i32: return Literal(int32_t(x)); break;
+ case Type::i64: return Literal(int64_t(x)); break;
+ case Type::f32: return Literal(float(x)); break;
+ case Type::f64: return Literal(double(x)); break;
+ case Type::v128: return Literal(
+ std::array<Literal, 4>{{
+ Literal(x), Literal(int32_t(0)), Literal(int32_t(0)), Literal(int32_t(0))
+ }}
+ );
+ case none:
+ case unreachable: WASM_UNREACHABLE();
+ }
+ WASM_UNREACHABLE();
+ }
+
+ inline static Literal makeZero(Type type) {
+ return makeFromInt32(0, type);
+ }
+
Literal castToF32();
Literal castToF64();
Literal castToI32();
@@ -60,8 +90,12 @@ public:
int64_t geti64() const { assert(type == Type::i64); return i64; }
float getf32() const { assert(type == Type::f32); return bit_cast<float>(i32); }
double getf64() const { assert(type == Type::f64); return bit_cast<double>(i64); }
+ std::array<uint8_t, 16> getv128() const;
- int32_t* geti32Ptr() { assert(type == Type::i32); return &i32; } // careful!
+ // careful!
+ int32_t* geti32Ptr() { assert(type == Type::i32); return &i32; }
+ uint8_t* getv128Ptr() { assert(type == Type::v128); return v128; }
+ const uint8_t* getv128Ptr() const { assert(type == Type::v128); return v128; }
int32_t reinterpreti32() const { assert(type == Type::f32); return i32; }
int64_t reinterpreti64() const { assert(type == Type::f64); return i64; }
@@ -70,7 +104,7 @@ public:
int64_t getInteger() const;
double getFloat() const;
- int64_t getBits() const;
+ void getBits(uint8_t (&buf)[16]) const;
// Equality checks for the type and the bits, so a nan float would
// be compared bitwise (which means that a Literal containing a nan
// would be equal to itself, if the bits are equal).
@@ -84,6 +118,7 @@ public:
static void printFloat(std::ostream &o, float f);
static void printDouble(std::ostream& o, double d);
+ static void printVec128(std::ostream& o, const std::array<uint8_t, 16>& v);
friend std::ostream& operator<<(std::ostream& o, Literal literal);
@@ -158,6 +193,163 @@ public:
Literal min(const Literal& other) const;
Literal max(const Literal& other) const;
Literal copysign(const Literal& other) const;
+
+ std::array<Literal, 16> getLanesSI8x16() const;
+ std::array<Literal, 16> getLanesUI8x16() const;
+ std::array<Literal, 8> getLanesSI16x8() const;
+ std::array<Literal, 8> getLanesUI16x8() const;
+ std::array<Literal, 4> getLanesI32x4() const;
+ std::array<Literal, 2> getLanesI64x2() const;
+ std::array<Literal, 4> getLanesF32x4() const;
+ std::array<Literal, 2> getLanesF64x2() const;
+
+ Literal shuffleV8x16(const Literal& other, const std::array<uint8_t, 16>& mask) const;
+ Literal splatI8x16() const;
+ Literal extractLaneSI8x16(uint8_t idx) const;
+ Literal extractLaneUI8x16(uint8_t idx) const;
+ Literal replaceLaneI8x16(const Literal& other, uint8_t idx) const;
+ Literal splatI16x8() const;
+ Literal extractLaneSI16x8(uint8_t idx) const;
+ Literal extractLaneUI16x8(uint8_t idx) const;
+ Literal replaceLaneI16x8(const Literal& other, uint8_t idx) const;
+ Literal splatI32x4() const;
+ Literal extractLaneI32x4(uint8_t idx) const;
+ Literal replaceLaneI32x4(const Literal& other, uint8_t idx) const;
+ Literal splatI64x2() const;
+ Literal extractLaneI64x2(uint8_t idx) const;
+ Literal replaceLaneI64x2(const Literal& other, uint8_t idx) const;
+ Literal splatF32x4() const;
+ Literal extractLaneF32x4(uint8_t idx) const;
+ Literal replaceLaneF32x4(const Literal& other, uint8_t idx) const;
+ Literal splatF64x2() const;
+ Literal extractLaneF64x2(uint8_t idx) const;
+ Literal replaceLaneF64x2(const Literal& other, uint8_t idx) const;
+ Literal eqI8x16(const Literal& other) const;
+ Literal neI8x16(const Literal& other) const;
+ Literal ltSI8x16(const Literal& other) const;
+ Literal ltUI8x16(const Literal& other) const;
+ Literal gtSI8x16(const Literal& other) const;
+ Literal gtUI8x16(const Literal& other) const;
+ Literal leSI8x16(const Literal& other) const;
+ Literal leUI8x16(const Literal& other) const;
+ Literal geSI8x16(const Literal& other) const;
+ Literal geUI8x16(const Literal& other) const;
+ Literal eqI16x8(const Literal& other) const;
+ Literal neI16x8(const Literal& other) const;
+ Literal ltSI16x8(const Literal& other) const;
+ Literal ltUI16x8(const Literal& other) const;
+ Literal gtSI16x8(const Literal& other) const;
+ Literal gtUI16x8(const Literal& other) const;
+ Literal leSI16x8(const Literal& other) const;
+ Literal leUI16x8(const Literal& other) const;
+ Literal geSI16x8(const Literal& other) const;
+ Literal geUI16x8(const Literal& other) const;
+ Literal eqI32x4(const Literal& other) const;
+ Literal neI32x4(const Literal& other) const;
+ Literal ltSI32x4(const Literal& other) const;
+ Literal ltUI32x4(const Literal& other) const;
+ Literal gtSI32x4(const Literal& other) const;
+ Literal gtUI32x4(const Literal& other) const;
+ Literal leSI32x4(const Literal& other) const;
+ Literal leUI32x4(const Literal& other) const;
+ Literal geSI32x4(const Literal& other) const;
+ Literal geUI32x4(const Literal& other) const;
+ Literal eqF32x4(const Literal& other) const;
+ Literal neF32x4(const Literal& other) const;
+ Literal ltF32x4(const Literal& other) const;
+ Literal gtF32x4(const Literal& other) const;
+ Literal leF32x4(const Literal& other) const;
+ Literal geF32x4(const Literal& other) const;
+ Literal eqF64x2(const Literal& other) const;
+ Literal neF64x2(const Literal& other) const;
+ Literal ltF64x2(const Literal& other) const;
+ Literal gtF64x2(const Literal& other) const;
+ Literal leF64x2(const Literal& other) const;
+ Literal geF64x2(const Literal& other) const;
+ Literal notV128() const;
+ Literal andV128(const Literal& other) const;
+ Literal orV128(const Literal& other) const;
+ Literal xorV128(const Literal& other) const;
+ Literal bitselectV128(const Literal& left, const Literal& right) const;
+ Literal negI8x16() const;
+ Literal anyTrueI8x16() const;
+ Literal allTrueI8x16() const;
+ Literal shlI8x16(const Literal& other) const;
+ Literal shrSI8x16(const Literal& other) const;
+ Literal shrUI8x16(const Literal& other) const;
+ Literal addI8x16(const Literal& other) const;
+ Literal addSaturateSI8x16(const Literal& other) const;
+ Literal addSaturateUI8x16(const Literal& other) const;
+ Literal subI8x16(const Literal& other) const;
+ Literal subSaturateSI8x16(const Literal& other) const;
+ Literal subSaturateUI8x16(const Literal& other) const;
+ Literal mulI8x16(const Literal& other) const;
+ Literal negI16x8() const;
+ Literal anyTrueI16x8() const;
+ Literal allTrueI16x8() const;
+ Literal shlI16x8(const Literal& other) const;
+ Literal shrSI16x8(const Literal& other) const;
+ Literal shrUI16x8(const Literal& other) const;
+ Literal addI16x8(const Literal& other) const;
+ Literal addSaturateSI16x8(const Literal& other) const;
+ Literal addSaturateUI16x8(const Literal& other) const;
+ Literal subI16x8(const Literal& other) const;
+ Literal subSaturateSI16x8(const Literal& other) const;
+ Literal subSaturateUI16x8(const Literal& other) const;
+ Literal mulI16x8(const Literal& other) const;
+ Literal negI32x4() const;
+ Literal anyTrueI32x4() const;
+ Literal allTrueI32x4() const;
+ Literal shlI32x4(const Literal& other) const;
+ Literal shrSI32x4(const Literal& other) const;
+ Literal shrUI32x4(const Literal& other) const;
+ Literal addI32x4(const Literal& other) const;
+ Literal subI32x4(const Literal& other) const;
+ Literal mulI32x4(const Literal& other) const;
+ Literal negI64x2() const;
+ Literal anyTrueI64x2() const;
+ Literal allTrueI64x2() const;
+ Literal shlI64x2(const Literal& other) const;
+ Literal shrSI64x2(const Literal& other) const;
+ Literal shrUI64x2(const Literal& other) const;
+ Literal addI64x2(const Literal& other) const;
+ Literal subI64x2(const Literal& other) const;
+ Literal absF32x4() const;
+ Literal negF32x4() const;
+ Literal sqrtF32x4() const;
+ Literal addF32x4(const Literal& other) const;
+ Literal subF32x4(const Literal& other) const;
+ Literal mulF32x4(const Literal& other) const;
+ Literal divF32x4(const Literal& other) const;
+ Literal minF32x4(const Literal& other) const;
+ Literal maxF32x4(const Literal& other) const;
+ Literal absF64x2() const;
+ Literal negF64x2() const;
+ Literal sqrtF64x2() const;
+ Literal addF64x2(const Literal& other) const;
+ Literal subF64x2(const Literal& other) const;
+ Literal mulF64x2(const Literal& other) const;
+ Literal divF64x2(const Literal& other) const;
+ Literal minF64x2(const Literal& other) const;
+ Literal maxF64x2(const Literal& other) const;
+ Literal truncSatToSI32x4() const;
+ Literal truncSatToUI32x4() const;
+ Literal truncSatToSI64x2() const;
+ Literal truncSatToUI64x2() const;
+ Literal convertSToF32x4() const;
+ Literal convertUToF32x4() const;
+ Literal convertSToF64x2() const;
+ Literal convertUToF64x2() const;
+
+ private:
+ Literal addSatSI8(const Literal& other) const;
+ Literal addSatUI8(const Literal& other) const;
+ Literal addSatSI16(const Literal& other) const;
+ Literal addSatUI16(const Literal& other) const;
+ Literal subSatSI8(const Literal& other) const;
+ Literal subSatUI8(const Literal& other) const;
+ Literal subSatSI16(const Literal& other) const;
+ Literal subSatUI16(const Literal& other) const;
};
} // namespace wasm
@@ -165,9 +357,16 @@ public:
namespace std {
template<> struct hash<wasm::Literal> {
size_t operator()(const wasm::Literal& a) const {
+ uint8_t bytes[16];
+ a.getBits(bytes);
+ int64_t chunks[2];
+ memcpy(chunks, bytes, sizeof(chunks));
return wasm::rehash(
- uint64_t(hash<size_t>()(size_t(a.type))),
- uint64_t(hash<int64_t>()(a.getBits()))
+ wasm::rehash(
+ uint64_t(hash<size_t>()(size_t(a.type))),
+ uint64_t(hash<int64_t>()(chunks[0]))
+ ),
+ uint64_t(hash<int64_t>()(chunks[1]))
);
}
};
@@ -175,7 +374,16 @@ template<> struct less<wasm::Literal> {
bool operator()(const wasm::Literal& a, const wasm::Literal& b) const {
if (a.type < b.type) return true;
if (a.type > b.type) return false;
- return a.getBits() < b.getBits();
+ switch (a.type) {
+ case wasm::Type::i32: return a.geti32() < b.geti32();
+ case wasm::Type::f32: return a.reinterpreti32() < b.reinterpreti32();
+ case wasm::Type::i64: return a.geti64() < b.geti64();
+ case wasm::Type::f64: return a.reinterpreti64() < b.reinterpreti64();
+ case wasm::Type::v128: return memcmp(a.getv128Ptr(), b.getv128Ptr(), 16) < 0;
+ case wasm::Type::none:
+ case wasm::Type::unreachable: return false;
+ }
+ WASM_UNREACHABLE();
}
};
}