Skip to content

Commit 02e021b

Browse files
committed
Add bitreverse intrinsic
1 parent 0ff9872 commit 02e021b

File tree

5 files changed

+28
-3
lines changed

5 files changed

+28
-3
lines changed

src/libcore/intrinsics.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1292,6 +1292,10 @@ extern "rust-intrinsic" {
12921292
/// Reverses the bytes in an integer type `T`.
12931293
pub fn bswap<T>(x: T) -> T;
12941294

1295+
/// Reverses the bits in an integer type `T`.
1296+
#[cfg(not(stage0))]
1297+
pub fn bitreverse<T>(x: T) -> T;
1298+
12951299
/// Performs checked integer addition.
12961300
/// The stabilized versions of this intrinsic are available on the integer
12971301
/// primitives via the `overflowing_add` method. For example,

src/librustc_trans/context.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -597,6 +597,12 @@ fn declare_intrinsic(cx: &CodegenCx, key: &str) -> Option<ValueRef> {
597597
ifn!("llvm.bswap.i64", fn(t_i64) -> t_i64);
598598
ifn!("llvm.bswap.i128", fn(t_i128) -> t_i128);
599599

600+
ifn!("llvm.bitreverse.i8", fn(t_i8) -> t_i8);
601+
ifn!("llvm.bitreverse.i16", fn(t_i16) -> t_i16);
602+
ifn!("llvm.bitreverse.i32", fn(t_i32) -> t_i32);
603+
ifn!("llvm.bitreverse.i64", fn(t_i64) -> t_i64);
604+
ifn!("llvm.bitreverse.i128", fn(t_i128) -> t_i128);
605+
600606
ifn!("llvm.sadd.with.overflow.i8", fn(t_i8, t_i8) -> mk_struct!{t_i8, i1});
601607
ifn!("llvm.sadd.with.overflow.i16", fn(t_i16, t_i16) -> mk_struct!{t_i16, i1});
602608
ifn!("llvm.sadd.with.overflow.i32", fn(t_i32, t_i32) -> mk_struct!{t_i32, i1});

src/librustc_trans/intrinsic.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -287,8 +287,8 @@ pub fn trans_intrinsic_call<'a, 'tcx>(bx: &Builder<'a, 'tcx>,
287287
], None)
288288
},
289289
"ctlz" | "ctlz_nonzero" | "cttz" | "cttz_nonzero" | "ctpop" | "bswap" |
290-
"add_with_overflow" | "sub_with_overflow" | "mul_with_overflow" |
291-
"overflowing_add" | "overflowing_sub" | "overflowing_mul" |
290+
"bitreverse" | "add_with_overflow" | "sub_with_overflow" |
291+
"mul_with_overflow" | "overflowing_add" | "overflowing_sub" | "overflowing_mul" |
292292
"unchecked_div" | "unchecked_rem" | "unchecked_shl" | "unchecked_shr" => {
293293
let ty = arg_tys[0];
294294
match int_type_width_signed(ty, cx) {
@@ -315,6 +315,10 @@ pub fn trans_intrinsic_call<'a, 'tcx>(bx: &Builder<'a, 'tcx>,
315315
&[args[0].immediate()], None)
316316
}
317317
}
318+
"bitreverse" => {
319+
bx.call(cx.get_intrinsic(&format!("llvm.bitreverse.i{}", width)),
320+
&[args[0].immediate()], None)
321+
}
318322
"add_with_overflow" | "sub_with_overflow" | "mul_with_overflow" => {
319323
let intrinsic = format!("llvm.{}{}.with.overflow.i{}",
320324
if signed { 's' } else { 'u' },

src/librustc_typeck/check/intrinsic.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -275,7 +275,8 @@ pub fn check_intrinsic_type<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
275275
"volatile_store" =>
276276
(1, vec![ tcx.mk_mut_ptr(param(0)), param(0) ], tcx.mk_nil()),
277277

278-
"ctpop" | "ctlz" | "ctlz_nonzero" | "cttz" | "cttz_nonzero" | "bswap" =>
278+
"ctpop" | "ctlz" | "ctlz_nonzero" | "cttz" | "cttz_nonzero" |
279+
"bswap" | "bitreverse" =>
279280
(1, vec![param(0)], param(0)),
280281

281282
"add_with_overflow" | "sub_with_overflow" | "mul_with_overflow" =>

src/test/run-pass/intrinsics-integer.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ mod rusti {
1818
pub fn cttz<T>(x: T) -> T;
1919
pub fn cttz_nonzero<T>(x: T) -> T;
2020
pub fn bswap<T>(x: T) -> T;
21+
pub fn bitreverse<T>(x: T) -> T;
2122
}
2223
}
2324

@@ -138,5 +139,14 @@ pub fn main() {
138139
assert_eq!(bswap(0x0ABBCC0Di32), 0x0DCCBB0A);
139140
assert_eq!(bswap(0x0122334455667708u64), 0x0877665544332201);
140141
assert_eq!(bswap(0x0122334455667708i64), 0x0877665544332201);
142+
143+
assert_eq!(bitreverse(0x0Au8), 0x50);
144+
assert_eq!(bitreverse(0x0Ai8), 0x50);
145+
assert_eq!(bitreverse(0x0A0Cu16), 0x3050);
146+
assert_eq!(bitreverse(0x0A0Ci16), 0x3050);
147+
assert_eq!(bitreverse(0x0ABBCC0Eu32), 0x7033DD50);
148+
assert_eq!(bitreverse(0x0ABBCC0Ei32), 0x7033DD50);
149+
assert_eq!(bitreverse(0x0122334455667708u64), 0x10EE66AA22CC4480);
150+
assert_eq!(bitreverse(0x0122334455667708i64), 0x10EE66AA22CC4480);
141151
}
142152
}

0 commit comments

Comments
 (0)