about summary refs log tree commit diff
path: root/compiler/rustc_codegen_gcc
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2022-08-28 01:34:47 +0000
committerbors <bors@rust-lang.org>2022-08-28 01:34:47 +0000
commit1e978a3627bd65064164af3548c585fb25eef9d2 (patch)
treed36b93e40e37cd26a0f15a200435c511ed21c0bd /compiler/rustc_codegen_gcc
parenteaadb8947b850a025404082f6297766c4680a42a (diff)
parentca753124088c0d57ca6728ee093363cbc1db5274 (diff)
downloadrust-1e978a3627bd65064164af3548c585fb25eef9d2.tar.gz
rust-1e978a3627bd65064164af3548c585fb25eef9d2.zip
Auto merge of #96946 - WaffleLapkin:ptr_mask, r=scottmcm
Add pointer masking convenience functions

This PR adds the following public API:
```rust
impl<T: ?Sized> *const T {
    fn mask(self, mask: usize) -> *const T;
}

impl<T: ?Sized> *mut T {
    fn mask(self, mask: usize) -> *const T;
}

// mod intrinsics
fn mask<T>(ptr: *const T, mask: usize) -> *const T
```
This is equivalent to `ptr.map_addr(|a| a & mask)` but also uses a cool llvm intrinsic.

Proposed in https://github.com/rust-lang/rust/pull/95643#issuecomment-1121562352

cc `@Gankra` `@scottmcm` `@RalfJung`

r? rust-lang/libs-api
Diffstat (limited to 'compiler/rustc_codegen_gcc')
-rw-r--r--compiler/rustc_codegen_gcc/src/intrinsic/mod.rs12
1 files changed, 12 insertions, 0 deletions
diff --git a/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs b/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs
index 352fe7568ef..02cedd4646b 100644
--- a/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs
+++ b/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs
@@ -309,6 +309,18 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallMethods<'tcx> for Builder<'a, 'gcc, 'tcx> {
                     return;
                 }
 
+                sym::ptr_mask => {
+                    let usize_type = self.context.new_type::<usize>();
+                    let void_ptr_type = self.context.new_type::<*const ()>();
+
+                    let ptr = args[0].immediate();
+                    let mask = args[1].immediate();
+
+                    let addr = self.bitcast(ptr, usize_type);
+                    let masked = self.and(addr, mask);
+                    self.bitcast(masked, void_ptr_type)
+                },
+                
                 _ if name_str.starts_with("simd_") => {
                     match generic_simd_intrinsic(self, name, callee_ty, args, ret_ty, llret_ty, span) {
                         Ok(llval) => llval,