summaryrefslogtreecommitdiffstats
path: root/library/stdarch/crates/core_arch/src/aarch64/v8.rs
diff options
context:
space:
mode:
Diffstat (limited to 'library/stdarch/crates/core_arch/src/aarch64/v8.rs')
-rw-r--r--library/stdarch/crates/core_arch/src/aarch64/v8.rs104
1 files changed, 104 insertions, 0 deletions
diff --git a/library/stdarch/crates/core_arch/src/aarch64/v8.rs b/library/stdarch/crates/core_arch/src/aarch64/v8.rs
new file mode 100644
index 000000000..778721c68
--- /dev/null
+++ b/library/stdarch/crates/core_arch/src/aarch64/v8.rs
@@ -0,0 +1,104 @@
+//! ARMv8 intrinsics.
+//!
+//! The reference is [ARMv8-A Reference Manual][armv8].
+//!
+//! [armv8]: http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.
+//! ddi0487a.k_10775/index.html
+
+#[cfg(test)]
+use stdarch_test::assert_instr;
+
+/// Reverse the order of the bytes.
+#[inline]
+#[cfg_attr(test, assert_instr(rev))]
+pub unsafe fn _rev_u64(x: u64) -> u64 {
+ x.swap_bytes() as u64
+}
+
+/// Count Leading Zeros.
+#[inline]
+#[cfg_attr(test, assert_instr(clz))]
+pub unsafe fn _clz_u64(x: u64) -> u64 {
+ x.leading_zeros() as u64
+}
+
+/// Reverse the bit order.
+#[inline]
+#[cfg_attr(test, assert_instr(rbit))]
+pub unsafe fn _rbit_u64(x: u64) -> u64 {
+ crate::intrinsics::bitreverse(x)
+}
+
+/// 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]
+#[cfg_attr(test, assert_instr(cls))]
+pub unsafe fn _cls_u32(x: u32) -> u32 {
+ u32::leading_zeros((((((x as i32) >> 31) as u32) ^ x) << 1) | 1) 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]
+#[cfg_attr(test, assert_instr(cls))]
+pub unsafe fn _cls_u64(x: u64) -> u64 {
+ u64::leading_zeros((((((x as i64) >> 63) as u64) ^ x) << 1) | 1) as u64
+}
+
+#[cfg(test)]
+mod tests {
+ use crate::core_arch::aarch64::v8;
+
+ #[test]
+ fn _rev_u64() {
+ unsafe {
+ assert_eq!(
+ v8::_rev_u64(0b0000_0000_1111_1111_0000_0000_1111_1111_u64),
+ 0b1111_1111_0000_0000_1111_1111_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_u64
+ );
+ }
+ }
+
+ #[test]
+ fn _clz_u64() {
+ unsafe {
+ assert_eq!(v8::_clz_u64(0b0000_1010u64), 60u64);
+ }
+ }
+
+ #[test]
+ fn _rbit_u64() {
+ unsafe {
+ assert_eq!(
+ v8::_rbit_u64(0b0000_0000_1111_1101_0000_0000_1111_1111_u64),
+ 0b1111_1111_0000_0000_1011_1111_0000_0000_0000_0000_0000_0000_0000_0000_0000_0000_u64
+ );
+ }
+ }
+
+ #[test]
+ fn _cls_u32() {
+ unsafe {
+ assert_eq!(
+ v8::_cls_u32(0b1111_1111_1111_1111_0000_0000_1111_1111_u32),
+ 15_u32
+ );
+ }
+ }
+
+ #[test]
+ fn _cls_u64() {
+ unsafe {
+ assert_eq!(
+ v8::_cls_u64(
+ 0b1111_1111_1111_1111_0000_0000_1111_1111_0000_0000_0000_0000_0000_0000_0000_0000_u64
+ ),
+ 15_u64
+ );
+ }
+ }
+}