Add Type::int_with_byte_size constructor
This commit is contained in:
@@ -104,6 +104,8 @@ impl Type {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Get an integer type with the requested number of bits.
|
/// Get an integer type with the requested number of bits.
|
||||||
|
///
|
||||||
|
/// For the same thing but in *bytes*, use [`Self::int_with_byte_size`].
|
||||||
pub fn int(bits: u16) -> Option<Self> {
|
pub fn int(bits: u16) -> Option<Self> {
|
||||||
match bits {
|
match bits {
|
||||||
8 => Some(I8),
|
8 => Some(I8),
|
||||||
@@ -115,6 +117,13 @@ impl Type {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Get an integer type with the requested number of bytes.
|
||||||
|
///
|
||||||
|
/// For the same thing but in *bits*, use [`Self::int`].
|
||||||
|
pub fn int_with_byte_size(bytes: u16) -> Option<Self> {
|
||||||
|
Self::int(bytes.checked_mul(8)?)
|
||||||
|
}
|
||||||
|
|
||||||
/// Get a type with the same number of lanes as `self`, but using `lane` as the lane type.
|
/// Get a type with the same number of lanes as `self`, but using `lane` as the lane type.
|
||||||
fn replace_lanes(self, lane: Self) -> Self {
|
fn replace_lanes(self, lane: Self) -> Self {
|
||||||
debug_assert!(lane.is_lane() && !self.is_special());
|
debug_assert!(lane.is_lane() && !self.is_special());
|
||||||
@@ -595,4 +604,22 @@ mod tests {
|
|||||||
assert_eq!(B8.as_int(), I8);
|
assert_eq!(B8.as_int(), I8);
|
||||||
assert_eq!(B128.as_int(), I128);
|
assert_eq!(B128.as_int(), I128);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn int_from_size() {
|
||||||
|
assert_eq!(Type::int(0), None);
|
||||||
|
assert_eq!(Type::int(8), Some(I8));
|
||||||
|
assert_eq!(Type::int(33), None);
|
||||||
|
assert_eq!(Type::int(64), Some(I64));
|
||||||
|
|
||||||
|
assert_eq!(Type::int_with_byte_size(0), None);
|
||||||
|
assert_eq!(Type::int_with_byte_size(2), Some(I16));
|
||||||
|
assert_eq!(Type::int_with_byte_size(6), None);
|
||||||
|
assert_eq!(Type::int_with_byte_size(16), Some(I128));
|
||||||
|
|
||||||
|
// Ensure `int_with_byte_size` handles overflow properly
|
||||||
|
let evil = 0xE001_u16;
|
||||||
|
assert_eq!(evil.wrapping_mul(8), 8, "check the constant is correct");
|
||||||
|
assert_eq!(Type::int_with_byte_size(evil), None);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ use cranelift_codegen::ir::{
|
|||||||
};
|
};
|
||||||
use cranelift_codegen::isa::TargetFrontendConfig;
|
use cranelift_codegen::isa::TargetFrontendConfig;
|
||||||
use cranelift_codegen::packed_option::PackedOption;
|
use cranelift_codegen::packed_option::PackedOption;
|
||||||
|
use std::convert::TryInto; // FIXME: Remove in edition2021
|
||||||
|
|
||||||
/// Structure used for translating a series of functions into Cranelift IR.
|
/// Structure used for translating a series of functions into Cranelift IR.
|
||||||
///
|
///
|
||||||
@@ -892,13 +893,7 @@ impl<'a> FunctionBuilder<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Future work could consider expanding this to handle more-complex scenarios.
|
// Future work could consider expanding this to handle more-complex scenarios.
|
||||||
fn type_from_byte_size(size: u64) -> Option<Type> {
|
if let Some(small_type) = size.try_into().ok().and_then(Type::int_with_byte_size) {
|
||||||
if size > 16 {
|
|
||||||
return None;
|
|
||||||
}
|
|
||||||
Type::int(size as u16 * 8)
|
|
||||||
}
|
|
||||||
if let Some(small_type) = type_from_byte_size(size) {
|
|
||||||
if let Equal | NotEqual = zero_cc {
|
if let Equal | NotEqual = zero_cc {
|
||||||
let mut left_flags = flags;
|
let mut left_flags = flags;
|
||||||
if size == left_align.get().into() {
|
if size == left_align.get().into() {
|
||||||
|
|||||||
Reference in New Issue
Block a user