diff --git a/library/stdarch/src/arm/mod.rs b/library/stdarch/src/arm/mod.rs new file mode 100644 index 000000000000..9472441ae4fe --- /dev/null +++ b/library/stdarch/src/arm/mod.rs @@ -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; diff --git a/library/stdarch/src/arm/v6.rs b/library/stdarch/src/arm/v6.rs new file mode 100644 index 000000000000..95442b374f8c --- /dev/null +++ b/library/stdarch/src/arm/v6.rs @@ -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 +} diff --git a/library/stdarch/src/arm/v7.rs b/library/stdarch/src/arm/v7.rs new file mode 100644 index 000000000000..1052b8477a92 --- /dev/null +++ b/library/stdarch/src/arm/v7.rs @@ -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 } +} diff --git a/library/stdarch/src/arm/v8.rs b/library/stdarch/src/arm/v8.rs new file mode 100644 index 000000000000..92b1507aada1 --- /dev/null +++ b/library/stdarch/src/arm/v8.rs @@ -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 +} diff --git a/library/stdarch/src/lib.rs b/library/stdarch/src/lib.rs index e2ec27688409..2e75c3e833d0 100644 --- a/library/stdarch/src/lib.rs +++ b/library/stdarch/src/lib.rs @@ -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;