Add HalfWidth and DoubleWidth type variable functions.

These functions compute types with half or double the number of bits in
each lane.
This commit is contained in:
Jakob Stoklund Olesen
2016-09-27 15:39:54 -07:00
parent a14bb077ee
commit d256c46f60
4 changed files with 122 additions and 2 deletions

View File

@@ -547,6 +547,12 @@ enum OperandConstraint {
/// This operand is `ctrlType.as_bool()`.
AsBool,
/// This operand is `ctrlType.half_width()`.
HalfWidth,
/// This operand is `ctrlType.double_width()`.
DoubleWidth,
}
impl OperandConstraint {
@@ -562,6 +568,8 @@ impl OperandConstraint {
Same => Some(ctrl_type),
LaneOf => Some(ctrl_type.lane_type()),
AsBool => Some(ctrl_type.as_bool()),
HalfWidth => Some(ctrl_type.half_width().expect("invalid type for half_width")),
DoubleWidth => Some(ctrl_type.double_width().expect("invalid type for double_width")),
}
}
}

View File

@@ -67,7 +67,7 @@ impl Type {
}
}
/// Get a type with the same number of lanes as this type, but with the lanes replaces by
/// 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 {
// Replace the low 4 bits with the boolean version, preserve the high 4 bits.
@@ -81,6 +81,38 @@ impl Type {
Type(lane.0 | (self.0 & 0xf0))
}
/// 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> {
let lane = match self.lane_type() {
I16 => I8,
I32 => I16,
I64 => I32,
F64 => F32,
B16 => B8,
B32 => B16,
B64 => B32,
_ => return None,
};
Some(Type(lane.0 | (self.0 & 0xf0)))
}
/// Get a type with the same number of lanes as this type, but with lanes that are twice the
/// number of bits.
pub fn double_width(self) -> Option<Type> {
let lane = match self.lane_type() {
I8 => I16,
I16 => I32,
I32 => I64,
F32 => F64,
B8 => B16,
B16 => B32,
B32 => B64,
_ => return None,
};
Some(Type(lane.0 | (self.0 & 0xf0)))
}
/// Is this the VOID type?
pub fn is_void(self) -> bool {
self == VOID
@@ -333,6 +365,37 @@ mod tests {
assert_eq!(F64.lane_bits(), 64);
}
#[test]
fn typevar_functions() {
assert_eq!(VOID.half_width(), None);
assert_eq!(B1.half_width(), None);
assert_eq!(B8.half_width(), None);
assert_eq!(B16.half_width(), Some(B8));
assert_eq!(B32.half_width(), Some(B16));
assert_eq!(B64.half_width(), Some(B32));
assert_eq!(I8.half_width(), None);
assert_eq!(I16.half_width(), Some(I8));
assert_eq!(I32.half_width(), Some(I16));
assert_eq!(I32X4.half_width(), Some(I16X4));
assert_eq!(I64.half_width(), Some(I32));
assert_eq!(F32.half_width(), None);
assert_eq!(F64.half_width(), Some(F32));
assert_eq!(VOID.double_width(), None);
assert_eq!(B1.double_width(), None);
assert_eq!(B8.double_width(), Some(B16));
assert_eq!(B16.double_width(), Some(B32));
assert_eq!(B32.double_width(), Some(B64));
assert_eq!(B64.double_width(), None);
assert_eq!(I8.double_width(), Some(I16));
assert_eq!(I16.double_width(), Some(I32));
assert_eq!(I32.double_width(), Some(I64));
assert_eq!(I32X4.double_width(), Some(I64X4));
assert_eq!(I64.double_width(), None);
assert_eq!(F32.double_width(), Some(F64));
assert_eq!(F64.double_width(), None);
}
#[test]
fn vectors() {
let big = F64.by(256).unwrap();