summaryrefslogtreecommitdiff
path: root/src/ir.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/ir.h')
-rw-r--r--src/ir.h62
1 files changed, 53 insertions, 9 deletions
diff --git a/src/ir.h b/src/ir.h
index c46e48f5..6430b874 100644
--- a/src/ir.h
+++ b/src/ir.h
@@ -93,6 +93,19 @@ struct Const {
}
Type type() const { return type_; }
+ Type lane_type() const { assert(type_ == Type::V128); return lane_type_; }
+
+ int lane_count() const {
+ switch (lane_type()) {
+ case Type::I8: return 16;
+ case Type::I16: return 8;
+ case Type::I32: return 4;
+ case Type::I64: return 2;
+ case Type::F32: return 4;
+ case Type::F64: return 2;
+ default: WABT_UNREACHABLE;
+ }
+ }
uint32_t u32() const { return data_.u32(0); }
uint64_t u64() const { return data_.u64(0); }
@@ -101,40 +114,71 @@ struct Const {
uintptr_t ref_bits() const { return data_.To<uintptr_t>(0); }
v128 vec128() const { return data_; }
- bool is_expected_nan() const { return nan_ != ExpectedNan::None; }
- ExpectedNan expected() const { assert(is_expected_nan()); return nan_; }
+ template <typename T>
+ T v128_lane(int lane) const { return data_.To<T>(lane); }
void set_u32(uint32_t x) { From(Type::I32, x); }
void set_u64(uint64_t x) { From(Type::I64, x); }
void set_f32(uint32_t x) { From(Type::F32, x); }
void set_f64(uint64_t x) { From(Type::F64, x); }
- void set_vec128(v128 x) { From(Type::V128, x); }
+
+ void set_v128_u8(int lane, uint8_t x) { set_v128_lane(lane, Type::I8, x); }
+ void set_v128_u16(int lane, uint16_t x) { set_v128_lane(lane, Type::I16, x); }
+ void set_v128_u32(int lane, uint32_t x) { set_v128_lane(lane, Type::I32, x); }
+ void set_v128_u64(int lane, uint64_t x) { set_v128_lane(lane, Type::I64, x); }
+ void set_v128_f32(int lane, uint32_t x) { set_v128_lane(lane, Type::F32, x); }
+ void set_v128_f64(int lane, uint64_t x) { set_v128_lane(lane, Type::F64, x); }
// Only used for expectations. (e.g. wast assertions)
- void set_f32(ExpectedNan nan) { From<float>(Type::F32, 0); nan_ = nan; }
- void set_f64(ExpectedNan nan) { From<double>(Type::F64, 0); nan_ = nan; }
+ void set_f32(ExpectedNan nan) { set_f32(0); set_expected_nan(0, nan); }
+ void set_f64(ExpectedNan nan) { set_f64(0); set_expected_nan(0, nan); }
void set_hostref(uintptr_t x) { From(Type::Hostref, x); }
void set_nullref() { From<uintptr_t>(Type::Nullref, 0); }
void set_funcref() { From<uintptr_t>(Type::Funcref, 0); }
+ bool is_expected_nan(int lane = 0) const {
+ return expected_nan(lane) != ExpectedNan::None;
+ }
+
+ ExpectedNan expected_nan(int lane = 0) const {
+ return lane < 4 ? nan_[lane] : ExpectedNan::None;
+ }
+
+ void set_expected_nan(int lane, ExpectedNan nan) {
+ if (lane < 4) {
+ nan_[lane] = nan;
+ }
+ }
+
+ // v128 support
Location loc;
private:
template <typename T>
+ void set_v128_lane(int lane, Type lane_type, T x) {
+ lane_type_ = lane_type;
+ From(Type::V128, x, lane);
+ set_expected_nan(lane, ExpectedNan::None);
+ }
+
+ template <typename T>
Const(Type type, T data, const Location& loc = Location()) : loc(loc) {
From<T>(type, data);
}
template <typename T>
- void From(Type type, T data) {
+ void From(Type type, T data, int lane = 0) {
+ static_assert(sizeof(T) <= sizeof(data_), "Invalid cast!");
+ assert((lane + 1) * sizeof(T) <= sizeof(data_));
type_ = type;
- data_.From<T>(0, data);
- nan_ = ExpectedNan::None;
+ data_.From<T>(lane, data);
+ set_expected_nan(lane, ExpectedNan::None);
}
Type type_;
+ Type lane_type_; // Only valid if type_ == Type::V128.
v128 data_;
- ExpectedNan nan_ = ExpectedNan::None;
+ ExpectedNan nan_[4];
};
typedef std::vector<Const> ConstVector;