[arm] bitwise manipulation instructions

This commit is contained in:
gnzlbg 2017-09-20 12:16:54 +02:00
parent 8c89593883
commit 53540f0eee
5 changed files with 135 additions and 0 deletions

View file

@ -0,0 +1,10 @@
//! ARM intrinsics.
pub use self::v6::*;
pub use self::v7::*;
#[cfg(target_arch = "aarch64")]
pub use self::v8::*;
mod v6;
mod v7;
#[cfg(target_arch = "aarch64")]
mod v8;

View file

@ -0,0 +1,25 @@
//! ARMv6 intrinsics.
//!
//! The reference is [ARMv6-M Architecture Reference
//! Manual](http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0419c/index.html).
/// Reverse the order of the bytes.
#[inline(always)]
#[cfg_attr(test, assert_instr(rev))]
pub fn _rev_u8(x: u8) -> u8 {
x.swap_bytes() as u8
}
/// Reverse the order of the bytes.
#[inline(always)]
#[cfg_attr(test, assert_instr(rev))]
pub fn _rev_u16(x: u16) -> u16 {
x.swap_bytes() as u16
}
/// Reverse the order of the bytes.
#[inline(always)]
#[cfg_attr(test, assert_instr(rev))]
pub fn _rev_u32(x: u32) -> u32 {
x.swap_bytes() as u32
}

View file

@ -0,0 +1,40 @@
//! ARMv7 intrinsics.
//!
//! The reference is [ARMv7-M Architecture Reference Manual (Issue
//! E.b)](http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0403e.b/index.html).
pub use super::v6::*;
/// Count Leading Zeros.
#[inline(always)]
#[cfg_attr(test, assert_instr(clz))]
pub fn _clz_u8(x: u8) -> u8 {
x.leading_zeros() as u8
}
/// Count Leading Zeros.
#[inline(always)]
#[cfg_attr(test, assert_instr(clz))]
pub fn _clz_u16(x: u16) -> u16 {
x.leading_zeros() as u16
}
/// Count Leading Zeros.
#[inline(always)]
#[cfg_attr(test, assert_instr(clz))]
pub fn _clz_u32(x: u32) -> u32 {
x.leading_zeros() as u32
}
#[allow(dead_code)]
extern "C" {
#[link_name="llvm.bitreverse.i32"]
fn rbit_u32(i: i32) -> i32;
}
/// Reverse the bit order.
#[inline(always)]
#[cfg_attr(test, assert_instr(rbit))]
pub fn _rbit_u32(x: u32) -> u32 {
unsafe { rbit_u32(x as i32) as u32 }
}

View file

@ -0,0 +1,54 @@
//! ARMv8 intrinsics.
//!
//! The reference is [ARMv8-A Reference Manual](http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0487a.k_10775/index.html).
pub use super::v7::*;
/// Reverse the order of the bytes.
#[inline(always)]
#[cfg_attr(test, assert_instr(rev))]
pub fn _rev_u64(x: u64) -> u64 {
x.swap_bytes() as u64
}
/// Count Leading Zeros.
#[inline(always)]
#[cfg_attr(test, assert_instr(clz))]
pub fn _clz_u64(x: u64) -> u64 {
x.leading_zeros() as u64
}
#[allow(dead_code)]
extern "C" {
#[link_name="llvm.bitreverse.i64"]
fn rbit_u64(i: i64) -> i64;
}
/// Reverse the bit order.
#[inline(always)]
#[cfg_attr(test, assert_instr(rbit))]
pub fn _rbit_u64(x: u64) -> u64 {
unsafe { rbit_u64(x as i64) as u64 }
}
/// Counts the leading most significant bits set.
///
/// When all bits of the operand are set it returns the size of the operand in
/// bits.
#[inline(always)]
// #[cfg_attr(test, assert_instr(cls))] // LLVM Bug: https://bugs.llvm.org/show_bug.cgi?id=31802
#[cfg_attr(test, assert_instr(clz))]
pub fn _cls_u32(x: u32) -> u32 {
u32::leading_zeros(!x) as u32
}
/// Counts the leading most significant bits set.
///
/// When all bits of the operand are set it returns the size of the operand in
/// bits.
#[inline(always)]
// #[cfg_attr(test, assert_instr(cls))] // LLVM Bug: https://bugs.llvm.org/show_bug.cgi?id=31802
#[cfg_attr(test, assert_instr(clz))]
pub fn _cls_u64(x: u64) -> u64 {
u64::leading_zeros(!x) as u64
}

View file

@ -20,6 +20,9 @@ pub mod simd {
pub mod vendor {
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
pub use x86::*;
#[cfg(any(target_arch = "arm", target_arch = "aarch64"))]
pub use arm::*;
}
#[macro_use]
@ -31,3 +34,6 @@ mod v512;
mod v64;
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
mod x86;
#[cfg(any(target_arch = "arm", target_arch = "aarch64"))]
mod arm;