1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
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
|