From 3791e8660d82c3592d41913cdf6977edea3f9d6e Mon Sep 17 00:00:00 2001 From: Jakob Stoklund Olesen Date: Fri, 21 Oct 2016 10:39:05 -0700 Subject: [PATCH] Make Type::as_bool() less pedantic for scalars. All scalar types are mapped to b1 which is usually what you want for a scalar. Vector types have their lanes mapped to the wider boolean types. Add an as_bool_pedantic() methos that produces the scalar sized boolean types as before. Also add a friendlier Debug implementation for Type. --- lib/cretonne/src/ir/types.rs | 49 +++++++++++++++++++++++++++++++++--- 1 file changed, 45 insertions(+), 4 deletions(-) diff --git a/lib/cretonne/src/ir/types.rs b/lib/cretonne/src/ir/types.rs index 99390ee22a..f1e0998403 100644 --- a/lib/cretonne/src/ir/types.rs +++ b/lib/cretonne/src/ir/types.rs @@ -1,7 +1,7 @@ //! Common types for the Cretonne code generator. use std::default::Default; -use std::fmt::{self, Display, Formatter}; +use std::fmt::{self, Display, Debug, Formatter}; // ====--------------------------------------------------------------------------------------====// // @@ -23,7 +23,7 @@ use std::fmt::{self, Display, Formatter}; /// /// SIMD vector types have power-of-two lanes, up to 256. Lanes can be any int/float/bool type. /// -#[derive(Copy, Clone, PartialEq, Eq, Debug)] +#[derive(Copy, Clone, PartialEq, Eq)] pub struct Type(u8); /// No type. Used for functions without a return value. Can't be loaded or stored. Can't be part of @@ -31,7 +31,7 @@ pub struct Type(u8); pub const VOID: Type = Type(0); // Include code generated by `meta/gen_types.py`. This file contains constant definitions for all -// the scalar types as well as common vector types for 64, 128, 256, and 512-bit SID vectors. +// the scalar types as well as common vector types for 64, 128, 256, and 512-bit SIMD vectors. include!(concat!(env!("OUT_DIR"), "/types.rs")); impl Type { @@ -68,7 +68,10 @@ impl Type { /// Get a type with the same number of lanes as this type, but with the lanes replaced by /// booleans of the same size. - pub fn as_bool(self) -> Type { + /// + /// Scalar types are treated as vectors with one lane, so they are converted to the multi-bit + /// boolean types. + pub fn as_bool_pedantic(self) -> Type { // Replace the low 4 bits with the boolean version, preserve the high 4 bits. let lane = match self.lane_type() { B8 | I8 => B8, @@ -80,6 +83,18 @@ impl Type { Type(lane.0 | (self.0 & 0xf0)) } + /// Get a type with the same number of lanes as this type, but with the lanes replaced by + /// booleans of the same size. + /// + /// Scalar types are all converted to `b1` which is usually what you want. + pub fn as_bool(self) -> Type { + if self.is_scalar() { + B1 + } else { + self.as_bool_pedantic() + } + } + /// Get a type with the same number of lanes as this type, but with lanes that are half the /// number of bits. pub fn half_width(self) -> Option { @@ -222,6 +237,24 @@ impl Display for Type { } } +impl Debug for Type { + fn fmt(&self, f: &mut Formatter) -> fmt::Result { + if self.is_void() { + write!(f, "types::VOID") + } else if self.is_bool() { + write!(f, "types::B{}", self.lane_bits()) + } else if self.is_int() { + write!(f, "types::I{}", self.lane_bits()) + } else if self.is_float() { + write!(f, "types::F{}", self.lane_bits()) + } else if !self.is_scalar() { + write!(f, "{:?}X{}", self.lane_type(), self.lane_count()) + } else { + write!(f, "Type(0x{:x})", self.0) + } + } +} + impl Default for Type { fn default() -> Type { VOID @@ -339,4 +372,12 @@ mod tests { assert_eq!(I8.by(512), None); assert_eq!(VOID.by(4), None); } + + #[test] + fn as_bool() { + assert_eq!(I32X4.as_bool(), B32X4); + assert_eq!(I32.as_bool(), B1); + assert_eq!(I32X4.as_bool_pedantic(), B32X4); + assert_eq!(I32.as_bool_pedantic(), B32); + } }