use funnel shift as fallback impl for rotating shifts
This commit is contained in:
parent
401ae55427
commit
bc809befe2
3 changed files with 19 additions and 26 deletions
|
|
@ -333,29 +333,6 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
|
|||
let r = self.read_immediate(&args[1])?;
|
||||
self.exact_div(&l, &r, dest)?;
|
||||
}
|
||||
sym::rotate_left | sym::rotate_right => {
|
||||
// rotate_left: (X << (S % BW)) | (X >> ((BW - S) % BW))
|
||||
// rotate_right: (X << ((BW - S) % BW)) | (X >> (S % BW))
|
||||
let layout_val = self.layout_of(instance_args.type_at(0))?;
|
||||
let val = self.read_scalar(&args[0])?;
|
||||
let val_bits = val.to_bits(layout_val.size)?; // sign is ignored here
|
||||
|
||||
let layout_raw_shift = self.layout_of(self.tcx.types.u32)?;
|
||||
let raw_shift = self.read_scalar(&args[1])?;
|
||||
let raw_shift_bits = raw_shift.to_bits(layout_raw_shift.size)?;
|
||||
|
||||
let width_bits = u128::from(layout_val.size.bits());
|
||||
let shift_bits = raw_shift_bits % width_bits;
|
||||
let inv_shift_bits = (width_bits - shift_bits) % width_bits;
|
||||
let result_bits = if intrinsic_name == sym::rotate_left {
|
||||
(val_bits << shift_bits) | (val_bits >> inv_shift_bits)
|
||||
} else {
|
||||
(val_bits >> shift_bits) | (val_bits << inv_shift_bits)
|
||||
};
|
||||
let truncated_bits = layout_val.size.truncate(result_bits);
|
||||
let result = Scalar::from_uint(truncated_bits, layout_val.size);
|
||||
self.write_scalar(result, dest)?;
|
||||
}
|
||||
sym::copy => {
|
||||
self.copy_intrinsic(&args[0], &args[1], &args[2], /*nonoverlapping*/ false)?;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -56,7 +56,7 @@
|
|||
|
||||
use crate::ffi::va_list::{VaArgSafe, VaListImpl};
|
||||
use crate::marker::{ConstParamTy, Destruct, DiscriminantKind, PointeeSized, Tuple};
|
||||
use crate::ptr;
|
||||
use crate::{mem, ptr};
|
||||
|
||||
mod bounds;
|
||||
pub mod fallback;
|
||||
|
|
@ -2017,7 +2017,14 @@ pub const unsafe fn unchecked_mul<T: Copy>(x: T, y: T) -> T;
|
|||
#[rustc_intrinsic_const_stable_indirect]
|
||||
#[rustc_nounwind]
|
||||
#[rustc_intrinsic]
|
||||
pub const fn rotate_left<T: Copy>(x: T, shift: u32) -> T;
|
||||
#[rustc_allow_const_fn_unstable(const_trait_impl, funnel_shifts)]
|
||||
#[miri::intrinsic_fallback_is_spec]
|
||||
pub const fn rotate_left<T: [const] fallback::FunnelShift>(x: T, shift: u32) -> T {
|
||||
// Make sure to call the intrinsic for `funnel_shl`, not the fallback impl.
|
||||
// SAFETY: we modulo `shift` so that the result is definitely less than the size of
|
||||
// `T` in bits.
|
||||
unsafe { unchecked_funnel_shl(x, x, shift % (mem::size_of::<T>() as u32 * 8)) }
|
||||
}
|
||||
|
||||
/// Performs rotate right.
|
||||
///
|
||||
|
|
@ -2032,7 +2039,14 @@ pub const fn rotate_left<T: Copy>(x: T, shift: u32) -> T;
|
|||
#[rustc_intrinsic_const_stable_indirect]
|
||||
#[rustc_nounwind]
|
||||
#[rustc_intrinsic]
|
||||
pub const fn rotate_right<T: Copy>(x: T, shift: u32) -> T;
|
||||
#[rustc_allow_const_fn_unstable(const_trait_impl, funnel_shifts)]
|
||||
#[miri::intrinsic_fallback_is_spec]
|
||||
pub const fn rotate_right<T: [const] fallback::FunnelShift>(x: T, shift: u32) -> T {
|
||||
// Make sure to call the intrinsic for `funnel_shr`, not the fallback impl.
|
||||
// SAFETY: we modulo `shift` so that the result is definitely less than the size of
|
||||
// `T` in bits.
|
||||
unsafe { unchecked_funnel_shr(x, x, shift % (mem::size_of::<T>() as u32 * 8)) }
|
||||
}
|
||||
|
||||
/// Returns (a + b) mod 2<sup>N</sup>, where N is the width of T in bits.
|
||||
///
|
||||
|
|
|
|||
|
|
@ -351,6 +351,7 @@ macro_rules! uint_impl {
|
|||
#[must_use = "this returns the result of the operation, \
|
||||
without modifying the original"]
|
||||
#[inline(always)]
|
||||
#[rustc_allow_const_fn_unstable(const_trait_impl)] // for the intrinsic fallback
|
||||
pub const fn rotate_left(self, n: u32) -> Self {
|
||||
return intrinsics::rotate_left(self, n);
|
||||
}
|
||||
|
|
@ -374,6 +375,7 @@ macro_rules! uint_impl {
|
|||
#[must_use = "this returns the result of the operation, \
|
||||
without modifying the original"]
|
||||
#[inline(always)]
|
||||
#[rustc_allow_const_fn_unstable(const_trait_impl)] // for the intrinsic fallback
|
||||
pub const fn rotate_right(self, n: u32) -> Self {
|
||||
return intrinsics::rotate_right(self, n);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue