]> git.lizzy.rs Git - rust.git/commitdiff
Add bitreverse intrinsic
authorAmanieu d'Antras <amanieu@gmail.com>
Thu, 7 Apr 2016 17:16:40 +0000 (18:16 +0100)
committerAmanieu d'Antras <amanieu@gmail.com>
Wed, 28 Feb 2018 18:23:54 +0000 (18:23 +0000)
src/libcore/intrinsics.rs
src/librustc_trans/context.rs
src/librustc_trans/intrinsic.rs
src/librustc_typeck/check/intrinsic.rs
src/test/run-pass/intrinsics-integer.rs

index a05d67a304fa02669a6cbc6cf3c09b291fd53b40..830ebad065427fa3954552f99f90595702e96ff2 100644 (file)
@@ -1292,6 +1292,10 @@ pub fn volatile_copy_nonoverlapping_memory<T>(dst: *mut T, src: *const T,
     /// Reverses the bytes in an integer type `T`.
     pub fn bswap<T>(x: T) -> T;
 
+    /// Reverses the bits in an integer type `T`.
+    #[cfg(not(stage0))]
+    pub fn bitreverse<T>(x: T) -> T;
+
     /// Performs checked integer addition.
     /// The stabilized versions of this intrinsic are available on the integer
     /// primitives via the `overflowing_add` method. For example,
index a285e5f263ab7037b3f0df4045203f6a89ab639b..b93e8c2ad21ca60e9bee59b4ff60b7cbf69189ee 100644 (file)
@@ -597,6 +597,12 @@ macro_rules! mk_struct {
     ifn!("llvm.bswap.i64", fn(t_i64) -> t_i64);
     ifn!("llvm.bswap.i128", fn(t_i128) -> t_i128);
 
+    ifn!("llvm.bitreverse.i8", fn(t_i8) -> t_i8);
+    ifn!("llvm.bitreverse.i16", fn(t_i16) -> t_i16);
+    ifn!("llvm.bitreverse.i32", fn(t_i32) -> t_i32);
+    ifn!("llvm.bitreverse.i64", fn(t_i64) -> t_i64);
+    ifn!("llvm.bitreverse.i128", fn(t_i128) -> t_i128);
+
     ifn!("llvm.sadd.with.overflow.i8", fn(t_i8, t_i8) -> mk_struct!{t_i8, i1});
     ifn!("llvm.sadd.with.overflow.i16", fn(t_i16, t_i16) -> mk_struct!{t_i16, i1});
     ifn!("llvm.sadd.with.overflow.i32", fn(t_i32, t_i32) -> mk_struct!{t_i32, i1});
index b1f1fb52c907d099c6a5d75b69344ee5e57a5248..3f87ce7e04792f4c417adc7ba63a0ef705576f37 100644 (file)
@@ -287,8 +287,8 @@ pub fn trans_intrinsic_call<'a, 'tcx>(bx: &Builder<'a, 'tcx>,
             ], None)
         },
         "ctlz" | "ctlz_nonzero" | "cttz" | "cttz_nonzero" | "ctpop" | "bswap" |
-        "add_with_overflow" | "sub_with_overflow" | "mul_with_overflow" |
-        "overflowing_add" | "overflowing_sub" | "overflowing_mul" |
+        "bitreverse" | "add_with_overflow" | "sub_with_overflow" |
+        "mul_with_overflow" | "overflowing_add" | "overflowing_sub" | "overflowing_mul" |
         "unchecked_div" | "unchecked_rem" | "unchecked_shl" | "unchecked_shr" => {
             let ty = arg_tys[0];
             match int_type_width_signed(ty, cx) {
@@ -315,6 +315,10 @@ pub fn trans_intrinsic_call<'a, 'tcx>(bx: &Builder<'a, 'tcx>,
                                         &[args[0].immediate()], None)
                             }
                         }
+                        "bitreverse" => {
+                            bx.call(cx.get_intrinsic(&format!("llvm.bitreverse.i{}", width)),
+                                &[args[0].immediate()], None)
+                        }
                         "add_with_overflow" | "sub_with_overflow" | "mul_with_overflow" => {
                             let intrinsic = format!("llvm.{}{}.with.overflow.i{}",
                                                     if signed { 's' } else { 'u' },
index 23243c3ad66c0e49422b242e732bdcb33e37132e..2e00040d99a73f58782bc810277aa9346486715b 100644 (file)
@@ -275,7 +275,8 @@ pub fn check_intrinsic_type<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
             "volatile_store" =>
                 (1, vec![ tcx.mk_mut_ptr(param(0)), param(0) ], tcx.mk_nil()),
 
-            "ctpop" | "ctlz" | "ctlz_nonzero" | "cttz" | "cttz_nonzero" | "bswap" =>
+            "ctpop" | "ctlz" | "ctlz_nonzero" | "cttz" | "cttz_nonzero" |
+            "bswap" | "bitreverse" =>
                 (1, vec![param(0)], param(0)),
 
             "add_with_overflow" | "sub_with_overflow"  | "mul_with_overflow" =>
index 4896f02da20b0b280e6fde0dbd555a4e5c4c8c1e..6e0712f6767ba765dea50b99674b50c0179bd9d0 100644 (file)
@@ -18,6 +18,7 @@ mod rusti {
         pub fn cttz<T>(x: T) -> T;
         pub fn cttz_nonzero<T>(x: T) -> T;
         pub fn bswap<T>(x: T) -> T;
+        pub fn bitreverse<T>(x: T) -> T;
     }
 }
 
@@ -138,5 +139,14 @@ pub fn main() {
         assert_eq!(bswap(0x0ABBCC0Di32), 0x0DCCBB0A);
         assert_eq!(bswap(0x0122334455667708u64), 0x0877665544332201);
         assert_eq!(bswap(0x0122334455667708i64), 0x0877665544332201);
+
+        assert_eq!(bitreverse(0x0Au8), 0x50);
+        assert_eq!(bitreverse(0x0Ai8), 0x50);
+        assert_eq!(bitreverse(0x0A0Cu16), 0x3050);
+        assert_eq!(bitreverse(0x0A0Ci16), 0x3050);
+        assert_eq!(bitreverse(0x0ABBCC0Eu32), 0x7033DD50);
+        assert_eq!(bitreverse(0x0ABBCC0Ei32), 0x7033DD50);
+        assert_eq!(bitreverse(0x0122334455667708u64), 0x10EE66AA22CC4480);
+        assert_eq!(bitreverse(0x0122334455667708i64), 0x10EE66AA22CC4480);
     }
 }