diff options
Diffstat (limited to 'src/literal.h')
-rw-r--r-- | src/literal.h | 220 |
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(); } }; } |