Basic i128 support

This commit is contained in:
bjorn3
2019-06-12 19:24:47 +02:00
committed by Dan Gohman
parent 3b0e244316
commit c9a25abbc4
7 changed files with 26 additions and 9 deletions

View File

@@ -219,8 +219,9 @@ impl LaneType {
LaneType::IntType(shared_types::Int::I16) => 6, LaneType::IntType(shared_types::Int::I16) => 6,
LaneType::IntType(shared_types::Int::I32) => 7, LaneType::IntType(shared_types::Int::I32) => 7,
LaneType::IntType(shared_types::Int::I64) => 8, LaneType::IntType(shared_types::Int::I64) => 8,
LaneType::FloatType(shared_types::Float::F32) => 9, LaneType::IntType(shared_types::Int::I128) => 9,
LaneType::FloatType(shared_types::Float::F64) => 10, LaneType::FloatType(shared_types::Float::F32) => 10,
LaneType::FloatType(shared_types::Float::F64) => 11,
} }
} }
@@ -241,6 +242,7 @@ impl LaneType {
16 => shared_types::Int::I16, 16 => shared_types::Int::I16,
32 => shared_types::Int::I32, 32 => shared_types::Int::I32,
64 => shared_types::Int::I64, 64 => shared_types::Int::I64,
128 => shared_types::Int::I128,
_ => unreachable!("unxpected num bits for int"), _ => unreachable!("unxpected num bits for int"),
}) })
} }

View File

@@ -9,7 +9,7 @@ use std::rc::Rc;
use crate::cdsl::types::{BVType, LaneType, ReferenceType, SpecialType, ValueType}; use crate::cdsl::types::{BVType, LaneType, ReferenceType, SpecialType, ValueType};
const MAX_LANES: u16 = 256; const MAX_LANES: u16 = 256;
const MAX_BITS: u16 = 64; const MAX_BITS: u16 = 128;
const MAX_BITVEC: u16 = MAX_BITS * MAX_LANES; const MAX_BITVEC: u16 = MAX_BITS * MAX_LANES;
/// Type variables can be used in place of concrete types when defining /// Type variables can be used in place of concrete types when defining

View File

@@ -3143,7 +3143,7 @@ pub(crate) fn define(
"WideInt", "WideInt",
"An integer type with lanes from `i16` upwards", "An integer type with lanes from `i16` upwards",
TypeSetBuilder::new() TypeSetBuilder::new()
.ints(16..64) .ints(16..128)
.simd_lanes(Interval::All) .simd_lanes(Interval::All)
.build(), .build(),
); );
@@ -3171,9 +3171,9 @@ pub(crate) fn define(
let NarrowInt = &TypeVar::new( let NarrowInt = &TypeVar::new(
"NarrowInt", "NarrowInt",
"An integer type with lanes type to `i32`", "An integer type with lanes type to `i64`",
TypeSetBuilder::new() TypeSetBuilder::new()
.ints(8..32) .ints(8..64)
.simd_lanes(Interval::All) .simd_lanes(Interval::All)
.build(), .build(),
); );

View File

@@ -51,6 +51,8 @@ pub enum Int {
I32 = 32, I32 = 32,
/// 64-bit int. /// 64-bit int.
I64 = 64, I64 = 64,
/// 128-bit int.
I128 = 128,
} }
/// This provides an iterator through all of the supported int variants. /// This provides an iterator through all of the supported int variants.
@@ -72,6 +74,7 @@ impl Iterator for IntIterator {
1 => Some(Int::I16), 1 => Some(Int::I16),
2 => Some(Int::I32), 2 => Some(Int::I32),
3 => Some(Int::I64), 3 => Some(Int::I64),
4 => Some(Int::I128),
_ => return None, _ => return None,
}; };
self.index += 1; self.index += 1;
@@ -199,6 +202,7 @@ mod iter_tests {
assert_eq!(int_iter.next(), Some(Int::I16)); assert_eq!(int_iter.next(), Some(Int::I16));
assert_eq!(int_iter.next(), Some(Int::I32)); assert_eq!(int_iter.next(), Some(Int::I32));
assert_eq!(int_iter.next(), Some(Int::I64)); assert_eq!(int_iter.next(), Some(Int::I64));
assert_eq!(int_iter.next(), Some(Int::I128));
assert_eq!(int_iter.next(), None); assert_eq!(int_iter.next(), None);
} }

View File

@@ -63,6 +63,7 @@ impl Type {
B16 | I16 => 4, B16 | I16 => 4,
B32 | I32 | F32 | R32 => 5, B32 | I32 | F32 | R32 => 5,
B64 | I64 | F64 | R64 => 6, B64 | I64 | F64 | R64 => 6,
I128 => 7,
_ => 0, _ => 0,
} }
} }
@@ -75,6 +76,7 @@ impl Type {
B16 | I16 => 16, B16 | I16 => 16,
B32 | I32 | F32 | R32 => 32, B32 | I32 | F32 | R32 => 32,
B64 | I64 | F64 | R64 => 64, B64 | I64 | F64 | R64 => 64,
I128 => 128,
_ => 0, _ => 0,
} }
} }
@@ -86,6 +88,7 @@ impl Type {
16 => Some(I16), 16 => Some(I16),
32 => Some(I32), 32 => Some(I32),
64 => Some(I64), 64 => Some(I64),
128 => Some(I128),
_ => None, _ => None,
} }
} }
@@ -132,6 +135,7 @@ impl Type {
I16 => I8, I16 => I8,
I32 => I16, I32 => I16,
I64 => I32, I64 => I32,
I128 => I64,
F64 => F32, F64 => F32,
B16 => B8, B16 => B8,
B32 => B16, B32 => B16,
@@ -147,6 +151,7 @@ impl Type {
I8 => I16, I8 => I16,
I16 => I32, I16 => I32,
I32 => I64, I32 => I64,
I64 => I128,
F32 => F64, F32 => F64,
B8 => B16, B8 => B16,
B16 => B32, B16 => B32,
@@ -190,7 +195,7 @@ impl Type {
/// Is this a scalar integer type? /// Is this a scalar integer type?
pub fn is_int(self) -> bool { pub fn is_int(self) -> bool {
match self { match self {
I8 | I16 | I32 | I64 => true, I8 | I16 | I32 | I64 | I128 => true,
_ => false, _ => false,
} }
} }
@@ -374,6 +379,7 @@ mod tests {
assert_eq!(I16, I16.lane_type()); assert_eq!(I16, I16.lane_type());
assert_eq!(I32, I32.lane_type()); assert_eq!(I32, I32.lane_type());
assert_eq!(I64, I64.lane_type()); assert_eq!(I64, I64.lane_type());
assert_eq!(I128, I128.lane_type());
assert_eq!(F32, F32.lane_type()); assert_eq!(F32, F32.lane_type());
assert_eq!(F64, F64.lane_type()); assert_eq!(F64, F64.lane_type());
assert_eq!(B1, B1.by(8).unwrap().lane_type()); assert_eq!(B1, B1.by(8).unwrap().lane_type());
@@ -394,6 +400,7 @@ mod tests {
assert_eq!(I16.lane_bits(), 16); assert_eq!(I16.lane_bits(), 16);
assert_eq!(I32.lane_bits(), 32); assert_eq!(I32.lane_bits(), 32);
assert_eq!(I64.lane_bits(), 64); assert_eq!(I64.lane_bits(), 64);
assert_eq!(I128.lane_bits(), 128);
assert_eq!(F32.lane_bits(), 32); assert_eq!(F32.lane_bits(), 32);
assert_eq!(F64.lane_bits(), 64); assert_eq!(F64.lane_bits(), 64);
assert_eq!(R32.lane_bits(), 32); assert_eq!(R32.lane_bits(), 32);
@@ -415,6 +422,7 @@ mod tests {
assert_eq!(I32.half_width(), Some(I16)); assert_eq!(I32.half_width(), Some(I16));
assert_eq!(I32X4.half_width(), Some(I16X4)); assert_eq!(I32X4.half_width(), Some(I16X4));
assert_eq!(I64.half_width(), Some(I32)); assert_eq!(I64.half_width(), Some(I32));
assert_eq!(I128.half_width(), Some(I64));
assert_eq!(F32.half_width(), None); assert_eq!(F32.half_width(), None);
assert_eq!(F64.half_width(), Some(F32)); assert_eq!(F64.half_width(), Some(F32));
@@ -430,7 +438,8 @@ mod tests {
assert_eq!(I16.double_width(), Some(I32)); assert_eq!(I16.double_width(), Some(I32));
assert_eq!(I32.double_width(), Some(I64)); assert_eq!(I32.double_width(), Some(I64));
assert_eq!(I32X4.double_width(), Some(I64X4)); assert_eq!(I32X4.double_width(), Some(I64X4));
assert_eq!(I64.double_width(), None); assert_eq!(I64.double_width(), Some(I128));
assert_eq!(I128.double_width(), None);
assert_eq!(F32.double_width(), Some(F64)); assert_eq!(F32.double_width(), Some(F64));
assert_eq!(F64.double_width(), None); assert_eq!(F64.double_width(), None);
} }
@@ -465,6 +474,7 @@ mod tests {
assert_eq!(I16.to_string(), "i16"); assert_eq!(I16.to_string(), "i16");
assert_eq!(I32.to_string(), "i32"); assert_eq!(I32.to_string(), "i32");
assert_eq!(I64.to_string(), "i64"); assert_eq!(I64.to_string(), "i64");
assert_eq!(I128.to_string(), "i128");
assert_eq!(F32.to_string(), "f32"); assert_eq!(F32.to_string(), "f32");
assert_eq!(F64.to_string(), "f64"); assert_eq!(F64.to_string(), "f64");
assert_eq!(R32.to_string(), "r32"); assert_eq!(R32.to_string(), "r32");

View File

@@ -233,7 +233,7 @@ impl<'a> Context<'a> {
let dst_ty = self.cur.func.dfg.value_type(dst_val); let dst_ty = self.cur.func.dfg.value_type(dst_val);
debug_assert!(src_ty == dst_ty); debug_assert!(src_ty == dst_ty);
// This limits the transformation to copies of the // This limits the transformation to copies of the
// types: I64 I32 I16 I8 F64 and F32, since that's // types: I128 I64 I32 I16 I8 F64 and F32, since that's
// the set of `copy_nop` encodings available. // the set of `copy_nop` encodings available.
src_ty.is_int() || src_ty.is_float() src_ty.is_int() || src_ty.is_float()
} }

View File

@@ -365,6 +365,7 @@ impl<'a> Lexer<'a> {
"i16" => types::I16, "i16" => types::I16,
"i32" => types::I32, "i32" => types::I32,
"i64" => types::I64, "i64" => types::I64,
"i128" => types::I128,
"f32" => types::F32, "f32" => types::F32,
"f64" => types::F64, "f64" => types::F64,
"b1" => types::B1, "b1" => types::B1,