mir,
ty::{self, FloatTy, Ty},
};
-use rustc_target::abi::Integer;
+use rustc_target::abi::{Integer, Size};
use crate::*;
use atomic::EvalContextExt as _;
this.write_bytes_ptr(ptr, iter::repeat(val_byte).take(byte_count.bytes_usize()))?;
}
+ "ptr_mask" => {
+ let [ptr, mask] = check_arg_count(args)?;
+
+ let ptr = this.read_pointer(ptr)?;
+ let mask = this.read_scalar(mask)?.to_machine_usize(this)?;
+
+ let masked_addr = Size::from_bytes(ptr.addr().bytes() & mask);
+
+ this.write_pointer(Pointer::new(ptr.provenance, masked_addr), dest)?;
+ }
+
// Floating-point operations
"fabsf32" => {
let [f] = check_arg_count(args)?;
--- /dev/null
+#![feature(ptr_mask)]
+#![feature(strict_provenance)]
+
+fn main() {
+ let v: u32 = 0xABCDABCD;
+ let ptr: *const u32 = &v;
+
+ // u32 is 4 aligned,
+ // so the lower `log2(4) = 2` bits of the address are always 0
+ assert_eq!(ptr.addr() & 0b11, 0);
+
+ let tagged_ptr = ptr.map_addr(|a| a | 0b11);
+ let tag = tagged_ptr.addr() & 0b11;
+ let masked_ptr = tagged_ptr.mask(!0b11);
+
+ assert_eq!(tag, 0b11);
+ assert_eq!(unsafe { *masked_ptr }, 0xABCDABCD);
+}