diff options
Diffstat (limited to 'src/literal.h')
-rw-r--r-- | src/literal.h | 151 |
1 files changed, 151 insertions, 0 deletions
diff --git a/src/literal.h b/src/literal.h new file mode 100644 index 000000000..af87e620d --- /dev/null +++ b/src/literal.h @@ -0,0 +1,151 @@ +/* + * Copyright 2017 WebAssembly Community Group participants + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef wasm_literal_h +#define wasm_literal_h + +#include <iostream> +#include "support/utilities.h" +#include "compiler-support.h" +#include "wasm-type.h" + +namespace wasm { + +class Literal { +public: + WasmType type; + +private: + // store only integers, whose bits are deterministic. floats + // can have their signalling bit set, for example. + union { + int32_t i32; + int64_t i64; + }; + + // The RHS of shl/shru/shrs must be masked by bitwidth. + template <typename T> + static T shiftMask(T val) { + return val & (sizeof(T) * 8 - 1); + } + + public: + Literal() : type(WasmType::none), i64(0) {} + explicit Literal(WasmType type) : type(type), i64(0) {} + explicit Literal(int32_t init) : type(WasmType::i32), i32(init) {} + explicit Literal(uint32_t init) : type(WasmType::i32), i32(init) {} + explicit Literal(int64_t init) : type(WasmType::i64), i64(init) {} + explicit Literal(uint64_t init) : type(WasmType::i64), i64(init) {} + explicit Literal(float init) : type(WasmType::f32), i32(bit_cast<int32_t>(init)) {} + explicit Literal(double init) : type(WasmType::f64), i64(bit_cast<int64_t>(init)) {} + + Literal castToF32(); + Literal castToF64(); + Literal castToI32(); + Literal castToI64(); + + int32_t geti32() const { assert(type == WasmType::i32); return i32; } + int64_t geti64() const { assert(type == WasmType::i64); return i64; } + float getf32() const { assert(type == WasmType::f32); return bit_cast<float>(i32); } + double getf64() const { assert(type == WasmType::f64); return bit_cast<double>(i64); } + + int32_t* geti32Ptr() { assert(type == WasmType::i32); return &i32; } // careful! + + int32_t reinterpreti32() const { assert(type == WasmType::f32); return i32; } + int64_t reinterpreti64() const { assert(type == WasmType::f64); return i64; } + float reinterpretf32() const { assert(type == WasmType::i32); return bit_cast<float>(i32); } + double reinterpretf64() const { assert(type == WasmType::i64); return bit_cast<double>(i64); } + + int64_t getInteger(); + double getFloat(); + int64_t getBits(); + bool operator==(const Literal& other) const; + bool operator!=(const Literal& other) const; + + static uint32_t NaNPayload(float f); + static uint64_t NaNPayload(double f); + static float setQuietNaN(float f); + static double setQuietNaN(double f); + + static void printFloat(std::ostream &o, float f); + static void printDouble(std::ostream& o, double d); + + friend std::ostream& operator<<(std::ostream& o, Literal literal); + + Literal countLeadingZeroes() const; + Literal countTrailingZeroes() const; + Literal popCount() const; + + Literal extendToSI64() const; + Literal extendToUI64() const; + Literal extendToF64() const; + Literal truncateToI32() const; + Literal truncateToF32() const; + + Literal convertSToF32() const; + Literal convertUToF32() const; + Literal convertSToF64() const; + Literal convertUToF64() const; + + Literal neg() const; + Literal abs() const; + Literal ceil() const; + Literal floor() const; + Literal trunc() const; + Literal nearbyint() const; + Literal sqrt() const; + + Literal add(const Literal& other) const; + Literal sub(const Literal& other) const; + Literal mul(const Literal& other) const; + Literal div(const Literal& other) const; + Literal divS(const Literal& other) const; + Literal divU(const Literal& other) const; + Literal remS(const Literal& other) const; + Literal remU(const Literal& other) const; + Literal and_(const Literal& other) const; + Literal or_(const Literal& other) const; + Literal xor_(const Literal& other) const; + Literal shl(const Literal& other) const; + Literal shrS(const Literal& other) const; + Literal shrU(const Literal& other) const; + Literal rotL(const Literal& other) const; + Literal rotR(const Literal& other) const; + + Literal eq(const Literal& other) const; + Literal ne(const Literal& other) const; + Literal ltS(const Literal& other) const; + Literal ltU(const Literal& other) const; + Literal lt(const Literal& other) const; + Literal leS(const Literal& other) const; + Literal leU(const Literal& other) const; + Literal le(const Literal& other) const; + + Literal gtS(const Literal& other) const; + Literal gtU(const Literal& other) const; + Literal gt(const Literal& other) const; + Literal geS(const Literal& other) const; + Literal geU(const Literal& other) const; + Literal ge(const Literal& other) const; + + Literal min(const Literal& other) const; + Literal max(const Literal& other) const; + Literal copysign(const Literal& other) const; +}; + +} // namespace wasm + +#endif // wasm_literal_h |