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.
|
//! Common types for the Cretonne code generator.
|
||||||
|
|
||||||
use std::default::Default;
|
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.
|
/// 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);
|
pub struct Type(u8);
|
||||||
|
|
||||||
/// No type. Used for functions without a return value. Can't be loaded or stored. Can't be part of
|
/// 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);
|
pub const VOID: Type = Type(0);
|
||||||
|
|
||||||
// Include code generated by `meta/gen_types.py`. This file contains constant definitions for all
|
// 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"));
|
include!(concat!(env!("OUT_DIR"), "/types.rs"));
|
||||||
|
|
||||||
impl Type {
|
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
|
/// Get a type with the same number of lanes as this type, but with the lanes replaced by
|
||||||
/// booleans of the same size.
|
/// 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.
|
// Replace the low 4 bits with the boolean version, preserve the high 4 bits.
|
||||||
let lane = match self.lane_type() {
|
let lane = match self.lane_type() {
|
||||||
B8 | I8 => B8,
|
B8 | I8 => B8,
|
||||||
@@ -80,6 +83,18 @@ impl Type {
|
|||||||
Type(lane.0 | (self.0 & 0xf0))
|
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
|
/// Get a type with the same number of lanes as this type, but with lanes that are half the
|
||||||
/// number of bits.
|
/// number of bits.
|
||||||
pub fn half_width(self) -> Option<Type> {
|
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 {
|
impl Default for Type {
|
||||||
fn default() -> Type {
|
fn default() -> Type {
|
||||||
VOID
|
VOID
|
||||||
@@ -339,4 +372,12 @@ mod tests {
|
|||||||
assert_eq!(I8.by(512), None);
|
assert_eq!(I8.by(512), None);
|
||||||
assert_eq!(VOID.by(4), 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