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:
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user