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.
This commit is contained in:
Jakob Stoklund Olesen
2016-10-21 10:39:05 -07:00
parent ce9049af90
commit 3791e8660d

View File

@@ -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<Type> {
@@ -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);
}
}