Skip to content

Commit 483ca25

Browse files
committed
[arm] bitwise manipulation instructions
1 parent 35025db commit 483ca25

14 files changed

+190
-5
lines changed

asm/armv6_none_rev.asm

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
rev_u32:
2+
rev r0, r0
3+
bx lr

asm/armv6_none_rev.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
extern crate stdsimd;
2+
3+
#[no_mangle]
4+
pub fn rev_u32(x: u32) -> u32 {
5+
stdsimd::vendor::_rev_u32(x)
6+
}

asm/armv7_none_rbit.asm

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
rbit_u32:
2+
rbit r0, r0
3+
bx lr

asm/armv7_none_rbit.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
extern crate stdsimd;
2+
3+
#[no_mangle]
4+
pub fn rbit_u32(x: u32) -> u32 {
5+
stdsimd::vendor::_rbit_u32(x)
6+
}

asm/armv8_none_cls.asm

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
;; Should be:
2+
;; cls_u32:
3+
;; cls w0, w0
4+
;; ret
5+
;; cls_u64:
6+
;; cls x0, x0
7+
;; ret
8+
;; But due to LLVM Bug: https://bugs.llvm.org/show_bug.cgi?id=31802
9+
;; (stdsimd issue #30) is:
10+
cls_u32:
11+
mvn w8, w0
12+
clz w0, w8
13+
ret
14+
cls_u64:
15+
mvn x8, x0
16+
clz x0, x8
17+
ret

asm/armv8_none_cls.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
extern crate stdsimd;
2+
3+
#[no_mangle]
4+
pub fn cls_u32(x: u32) -> u32 {
5+
stdsimd::vendor::_cls_u32(x)
6+
}
7+
8+
#[no_mangle]
9+
pub fn cls_u64(x: u64) -> u64 {
10+
stdsimd::vendor::_cls_u64(x)
11+
}

asm/armv8_none_rbit.asm

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
rbit_u32:
2+
rbit w0, w0
3+
ret
4+
rbit_u64:
5+
rbit x0, x0
6+
ret

asm/armv8_none_rbit.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
extern crate stdsimd;
2+
3+
#[no_mangle]
4+
pub fn rbit_u32(x: u32) -> u32 {
5+
stdsimd::vendor::_rbit_u32(x)
6+
}
7+
8+
#[no_mangle]
9+
pub fn rbit_u64(x: u64) -> u64 {
10+
stdsimd::vendor::_rbit_u64(x)
11+
}

check_asm.py

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@
1212
extern_crate = None
1313

1414
def arm_triplet(arch) :
15-
triples = { 'armv7' : 'armv7-unknown-linux-gnueabihf',
15+
triples = { 'armv6': 'arm-unknown-linux-gnueabihf',
16+
'armv7' : 'armv7-unknown-linux-gnueabihf',
1617
'armv8' : 'aarch64-unknown-linux-gnu' }
1718
return triples[arch]
1819

@@ -57,14 +58,14 @@ def compile_file(file):
5758
cargo_args = 'cargo rustc --verbose --release -- -C panic=abort '
5859
if file.feature:
5960
cargo_args = cargo_args + '-C target-feature=+{}'.format(file.feature)
60-
if file.arch == 'armv7' or file.arch == 'armv8':
61+
if file.arch == 'armv6' or file.arch == 'armv7' or file.arch == 'armv8':
6162
cargo_args = cargo_args + '--target={}'.format(arm_triplet(file.arch))
6263
call(str(cargo_args))
6364

6465
rustc_args = 'rustc --verbose -C opt-level=3 -C panic="abort" --extern %s=target/release/lib%s.rlib --crate-type lib' % (extern_crate, extern_crate);
6566
if file.feature:
6667
rustc_args = rustc_args + ' -C target-feature=+{}'.format(file.feature)
67-
if file.arch == 'armv7' or file.arch == 'armv8':
68+
if file.arch == 'armv6' or file.arch == 'armv7' or file.arch == 'armv8':
6869
rustc_args = rustc_args + ' --target={}'.format(arm_triplet(file.arch))
6970
rustc_args_asm = rustc_args + ' --emit asm {} -o {}'.format(file.path_rs, file.path_asm_output)
7071
call(rustc_args_asm)
@@ -83,9 +84,9 @@ def diff_files(rustc_output, asm_snippet):
8384

8485
# remove all empty lines and lines starting with "."
8586
rustc_output_lines = [l.strip() for l in rustc_output_lines]
86-
rustc_output_lines = [l for l in rustc_output_lines if not l.startswith(".") and not len(l) == 0]
87+
rustc_output_lines = [l for l in rustc_output_lines if not l.startswith(".") and not len(l) == 0 and not l.startswith(";;")]
8788
asm_snippet_lines = [l.strip() for l in asm_snippet_lines]
88-
asm_snippet_lines = [l for l in asm_snippet_lines if not l.startswith(".") and not len(l) == 0]
89+
asm_snippet_lines = [l for l in asm_snippet_lines if not l.startswith(".") and not len(l) == 0 and not l.startswith(";;")]
8990

9091
results_differ = False
9192

src/arm/mod.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
//! ARM intrinsics.
2+
pub use self::v6::*;
3+
pub use self::v7::*;
4+
#[cfg(target_arch = "aarch64")]
5+
pub use self::v8::*;
6+
7+
mod v6;
8+
mod v7;
9+
#[cfg(target_arch = "aarch64")]
10+
mod v8;

src/arm/v6.rs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
//! ARMv6 intrinsics.
2+
//!
3+
//! The reference is [ARMv6-M Architecture Reference
4+
//! Manual](http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0419c/index.html).
5+
6+
/// Reverse the order of the bytes.
7+
#[inline(always)]
8+
pub fn _rev_u8(x: u8) -> u8 {
9+
x.swap_bytes() as u8
10+
}
11+
12+
/// Reverse the order of the bytes.
13+
#[inline(always)]
14+
pub fn _rev_u16(x: u16) -> u16 {
15+
x.swap_bytes() as u16
16+
}
17+
18+
/// Reverse the order of the bytes.
19+
#[inline(always)]
20+
pub fn _rev_u32(x: u32) -> u32 {
21+
x.swap_bytes() as u32
22+
}

src/arm/v7.rs

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
//! ARMv7 intrinsics.
2+
//!
3+
//! The reference is [ARMv7-M Architecture Reference Manual (Issue
4+
//! E.b)](http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0403e.b/index.html).
5+
6+
pub use super::v6::*;
7+
8+
/// Count Leading Zeros.
9+
#[inline(always)]
10+
pub fn _clz_u8(x: u8) -> u8 {
11+
x.leading_zeros() as u8
12+
}
13+
14+
/// Count Leading Zeros.
15+
#[inline(always)]
16+
pub fn _clz_u16(x: u16) -> u16 {
17+
x.leading_zeros() as u16
18+
}
19+
20+
/// Count Leading Zeros.
21+
#[inline(always)]
22+
pub fn _clz_u32(x: u32) -> u32 {
23+
x.leading_zeros() as u32
24+
}
25+
26+
#[allow(dead_code)]
27+
extern "C" {
28+
#[link_name="llvm.bitreverse.i32"]
29+
fn rbit_u32(i: i32) -> i32;
30+
}
31+
32+
/// Reverse the bit order.
33+
#[inline(always)]
34+
pub fn _rbit_u32(x: u32) -> u32 {
35+
unsafe { rbit_u32(x as i32) as u32 }
36+
}

src/arm/v8.rs

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
//! ARMv8 intrinsics.
2+
//!
3+
//! The reference is [ARMv8-A Reference Manual](http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0487a.k_10775/index.html).
4+
5+
pub use super::v7::*;
6+
7+
/// Reverse the order of the bytes.
8+
#[inline(always)]
9+
pub fn _rev_u64(x: u64) -> u64 {
10+
x.swap_bytes() as u64
11+
}
12+
13+
/// Count Leading Zeros.
14+
#[inline(always)]
15+
pub fn _clz_u64(x: u64) -> u64 {
16+
x.leading_zeros() as u64
17+
}
18+
19+
#[allow(dead_code)]
20+
extern "C" {
21+
#[link_name="llvm.bitreverse.i64"]
22+
fn rbit_u64(i: i64) -> i64;
23+
}
24+
25+
/// Reverse the bit order.
26+
#[inline(always)]
27+
pub fn _rbit_u64(x: u64) -> u64 {
28+
unsafe { rbit_u64(x as i64) as u64 }
29+
}
30+
31+
/// Counts the leading most significant bits set.
32+
///
33+
/// When all bits of the operand are set it returns the size of the operand in
34+
/// bits.
35+
#[inline(always)]
36+
pub fn _cls_u32(x: u32) -> u32 {
37+
u32::leading_zeros(!x) as u32
38+
}
39+
40+
/// Counts the leading most significant bits set.
41+
///
42+
/// When all bits of the operand are set it returns the size of the operand in
43+
/// bits.
44+
#[inline(always)]
45+
pub fn _cls_u64(x: u64) -> u64 {
46+
u64::leading_zeros(!x) as u64
47+
}

src/lib.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@ pub mod simd {
1616
pub mod vendor {
1717
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
1818
pub use x86::*;
19+
20+
#[cfg(any(target_arch = "arm", target_arch = "aarch64"))]
21+
pub use arm::*;
1922
}
2023

2124
#[macro_use]
@@ -27,3 +30,6 @@ mod v512;
2730
mod v64;
2831
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
2932
mod x86;
33+
34+
#[cfg(any(target_arch = "arm", target_arch = "aarch64"))]
35+
mod arm;

0 commit comments

Comments
 (0)