From 9e00ce5081b2cf77353c3869a71f195ea25dcaf9 Mon Sep 17 00:00:00 2001 From: Jakob Stoklund Olesen Date: Wed, 27 Apr 2016 14:51:16 -0700 Subject: [PATCH] Type::by() returns an Optional. Don't use assertions to enforce the limits on SIMD lanes in a type, Type is too fundamental for that. Instead, the Vector-forming by() method returns an Optional, and None if the requested SIMD vector is not valid. Same for Type::half_vector(). --- src/libcretonne/types.rs | 53 ++++++++++++++++++++++++---------------- 1 file changed, 32 insertions(+), 21 deletions(-) diff --git a/src/libcretonne/types.rs b/src/libcretonne/types.rs index 6c8fb90d90..0aaa30841b 100644 --- a/src/libcretonne/types.rs +++ b/src/libcretonne/types.rs @@ -147,21 +147,26 @@ impl Type { /// /// If this is already a SIMD vector type, this produces a SIMD vector type with `n * /// self.lane_count()` lanes. - pub fn by(self, n: u16) -> Type { - debug_assert!(self.lane_bits() > 0, - "Can't make SIMD vectors with void lanes."); - debug_assert!(n.is_power_of_two(), - "Number of SIMD lanes must be a power of two"); + pub fn by(self, n: u16) -> Option { + if self.lane_bits() == 0 || !n.is_power_of_two() { + return None; + } let log2_lanes: u32 = n.trailing_zeros(); let new_type = self.0 as u32 + (log2_lanes << 4); - assert!(new_type < 0x90, "No more than 256 SIMD lanes supported"); - Type(new_type as u8) + if new_type < 0x90 { + Some(Type(new_type as u8)) + } else { + None + } } /// Get a SIMD vector with half the number of lanes. - pub fn half_vector(self) -> Type { - assert!(!self.is_scalar(), "Expecting a proper SIMD vector type."); - Type(self.0 - 0x10) + pub fn half_vector(self) -> Option { + if self.is_scalar() { + None + } else { + Some(Type(self.0 - 0x10)) + } } } @@ -320,13 +325,16 @@ mod tests { #[test] fn vectors() { - let big = F64.by(256); + let big = F64.by(256).unwrap(); assert_eq!(big.lane_bits(), 64); assert_eq!(big.lane_count(), 256); assert_eq!(big.bits(), 64 * 256); - assert_eq!(format!("{}", big.half_vector()), "f64x128"); - assert_eq!(format!("{}", B1.by(2).half_vector()), "b1"); + assert_eq!(format!("{}", big.half_vector().unwrap()), "f64x128"); + assert_eq!(format!("{}", B1.by(2).unwrap().half_vector().unwrap()), + "b1"); + assert_eq!(I32.half_vector(), None); + assert_eq!(VOID.half_vector(), None); } #[test] @@ -347,13 +355,16 @@ mod tests { #[test] fn format_vectors() { - assert_eq!(format!("{}", B1.by(8)), "b1x8"); - assert_eq!(format!("{}", B8.by(1)), "b8"); - assert_eq!(format!("{}", B16.by(256)), "b16x256"); - assert_eq!(format!("{}", B32.by(4).by(2)), "b32x8"); - assert_eq!(format!("{}", B64.by(8)), "b64x8"); - assert_eq!(format!("{}", I8.by(64)), "i8x64"); - assert_eq!(format!("{}", F64.by(2)), "f64x2"); + assert_eq!(format!("{}", B1.by(8).unwrap()), "b1x8"); + assert_eq!(format!("{}", B8.by(1).unwrap()), "b8"); + assert_eq!(format!("{}", B16.by(256).unwrap()), "b16x256"); + assert_eq!(format!("{}", B32.by(4).unwrap().by(2).unwrap()), "b32x8"); + assert_eq!(format!("{}", B64.by(8).unwrap()), "b64x8"); + assert_eq!(format!("{}", I8.by(64).unwrap()), "i8x64"); + assert_eq!(format!("{}", F64.by(2).unwrap()), "f64x2"); + assert_eq!(I8.by(3), None); + assert_eq!(I8.by(512), None); + assert_eq!(VOID.by(4), None); } #[test] @@ -374,7 +385,7 @@ mod tests { assert_eq!(format!("{}", sig), "(i32)"); sig.return_types.push(ArgumentType::new(F32)); assert_eq!(format!("{}", sig), "(i32) -> f32"); - sig.argument_types.push(ArgumentType::new(I32.by(4))); + sig.argument_types.push(ArgumentType::new(I32.by(4).unwrap())); assert_eq!(format!("{}", sig), "(i32, i32x4) -> f32"); sig.return_types.push(ArgumentType::new(B8)); assert_eq!(format!("{}", sig), "(i32, i32x4) -> f32, b8");