parent
9a378c3f3f
commit
cd684e39e0
@ -159,7 +159,13 @@ pub(crate) fn clif_int_or_float_cast(
|
||||
} else {
|
||||
fx.bcx.ins().fcvt_to_uint_sat(types::I32, from)
|
||||
};
|
||||
let (min, max) = type_min_max_value(to_ty, to_signed);
|
||||
let (min, max) = match (to_ty, to_signed) {
|
||||
(types::I8, false) => (0, u8::MAX as i64),
|
||||
(types::I16, false) => (0, u16::MAX as i64),
|
||||
(types::I8, true) => (i8::MIN as i64, i8::MAX as i64),
|
||||
(types::I16, true) => (i16::MIN as i64, i16::MAX as i64),
|
||||
_ => unreachable!(),
|
||||
};
|
||||
let min_val = fx.bcx.ins().iconst(types::I32, min);
|
||||
let max_val = fx.bcx.ins().iconst(types::I32, max);
|
||||
|
||||
|
@ -215,8 +215,33 @@ pub(crate) fn resolve_value_imm(func: &Function, val: Value) -> Option<u128> {
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn type_min_max_value(ty: Type, signed: bool) -> (i64, i64) {
|
||||
pub(crate) fn type_min_max_value(bcx: &mut FunctionBuilder<'_>, ty: Type, signed: bool) -> (Value, Value) {
|
||||
assert!(ty.is_int());
|
||||
|
||||
if ty == types::I128 {
|
||||
if signed {
|
||||
let min = i128::MIN as u128;
|
||||
let min_lsb = bcx.ins().iconst(types::I64, min as u64 as i64);
|
||||
let min_msb = bcx.ins().iconst(types::I64, (min >> 64) as u64 as i64);
|
||||
let min = bcx.ins().iconcat(min_lsb, min_msb);
|
||||
|
||||
let max = i128::MIN as u128;
|
||||
let max_lsb = bcx.ins().iconst(types::I64, max as u64 as i64);
|
||||
let max_msb = bcx.ins().iconst(types::I64, (max >> 64) as u64 as i64);
|
||||
let max = bcx.ins().iconcat(max_lsb, max_msb);
|
||||
|
||||
return (min, max);
|
||||
} else {
|
||||
let min_half = bcx.ins().iconst(types::I64, 0);
|
||||
let min = bcx.ins().iconcat(min_half, min_half);
|
||||
|
||||
let max_half = bcx.ins().iconst(types::I64, u64::MAX as i64);
|
||||
let max = bcx.ins().iconcat(max_half, max_half);
|
||||
|
||||
return (min, max);
|
||||
}
|
||||
}
|
||||
|
||||
let min = match (ty, signed) {
|
||||
(types::I8, false) | (types::I16, false) | (types::I32, false) | (types::I64, false) => {
|
||||
0i64
|
||||
@ -225,7 +250,6 @@ pub(crate) fn type_min_max_value(ty: Type, signed: bool) -> (i64, i64) {
|
||||
(types::I16, true) => i16::MIN as i64,
|
||||
(types::I32, true) => i32::MIN as i64,
|
||||
(types::I64, true) => i64::MIN,
|
||||
(types::I128, _) => unimplemented!(),
|
||||
_ => unreachable!(),
|
||||
};
|
||||
|
||||
@ -238,10 +262,11 @@ pub(crate) fn type_min_max_value(ty: Type, signed: bool) -> (i64, i64) {
|
||||
(types::I16, true) => i16::MAX as i64,
|
||||
(types::I32, true) => i32::MAX as i64,
|
||||
(types::I64, true) => i64::MAX,
|
||||
(types::I128, _) => unimplemented!(),
|
||||
_ => unreachable!(),
|
||||
};
|
||||
|
||||
let (min, max) = (bcx.ins().iconst(ty, min), bcx.ins().iconst(ty, max));
|
||||
|
||||
(min, max)
|
||||
}
|
||||
|
||||
|
@ -583,9 +583,7 @@ pub(crate) fn codegen_intrinsic_call<'tcx>(
|
||||
// `select.i8` is not implemented by Cranelift.
|
||||
let has_overflow = fx.bcx.ins().uextend(types::I32, has_overflow);
|
||||
|
||||
let (min, max) = type_min_max_value(clif_ty, signed);
|
||||
let min = fx.bcx.ins().iconst(clif_ty, min);
|
||||
let max = fx.bcx.ins().iconst(clif_ty, max);
|
||||
let (min, max) = type_min_max_value(&mut fx.bcx, clif_ty, signed);
|
||||
|
||||
let val = match (intrinsic, signed) {
|
||||
("saturating_add", false) => fx.bcx.ins().select(has_overflow, max, val),
|
||||
|
Loading…
x
Reference in New Issue
Block a user