about summary refs log tree commit diff
path: root/src/librustc_trans
diff options
context:
space:
mode:
authorOliver Schneider <git-spam-no-reply9815368754983@oli-obk.de>2017-08-16 15:41:09 +0200
committerOliver Schneider <git-spam-no-reply9815368754983@oli-obk.de>2017-08-21 15:57:21 +0200
commit1dc3a2b5fa6de4aab7854b122213971217f13d77 (patch)
tree3497aaf28b251c5768d91832901dc7cc3be0da9f /src/librustc_trans
parent1b08e0f231cd30719c25a5992f1d9bb27ea02b61 (diff)
downloadrust-1dc3a2b5fa6de4aab7854b122213971217f13d77.tar.gz
rust-1dc3a2b5fa6de4aab7854b122213971217f13d77.zip
Add align_offset intrinsic
see https://github.com/rust-lang/rfcs/pull/2043 for details
Diffstat (limited to 'src/librustc_trans')
-rw-r--r--src/librustc_trans/intrinsic.rs12
1 files changed, 12 insertions, 0 deletions
diff --git a/src/librustc_trans/intrinsic.rs b/src/librustc_trans/intrinsic.rs
index 033ef988571..9a3c8a5079a 100644
--- a/src/librustc_trans/intrinsic.rs
+++ b/src/librustc_trans/intrinsic.rs
@@ -383,6 +383,18 @@ pub fn trans_intrinsic_call<'a, 'tcx>(bcx: &Builder<'a, 'tcx>,
                 _ => C_null(llret_ty)
             }
         }
+
+        "align_offset" => {
+            // `ptr as usize`
+            let ptr_val = bcx.ptrtoint(llargs[0], bcx.ccx.int_type());
+            // `ptr_val % align`
+            let offset = bcx.urem(ptr_val, llargs[1]);
+            let zero = C_null(bcx.ccx.int_type());
+            // `offset == 0`
+            let is_zero = bcx.icmp(llvm::IntPredicate::IntEQ, offset, zero);
+            // `if offset == 0 { 0 } else { offset - align }`
+            bcx.select(is_zero, zero, bcx.sub(offset, llargs[1]))
+        }
         name if name.starts_with("simd_") => {
             generic_simd_intrinsic(bcx, name,
                                    callee_ty,