Skip to content

Commit 760bcfe

Browse files
authored
Support crc32 even if on arm32 (#834)
CRC32 is supported on A32 and T32.
1 parent e8b70b8 commit 760bcfe

File tree

3 files changed

+126
-96
lines changed

3 files changed

+126
-96
lines changed

crates/core_arch/src/aarch64/crc.rs

Lines changed: 0 additions & 96 deletions
Original file line numberDiff line numberDiff line change
@@ -1,50 +1,14 @@
11
extern "C" {
2-
#[link_name = "llvm.aarch64.crc32b"]
3-
fn crc32b_(crc: u32, data: u32) -> u32;
4-
#[link_name = "llvm.aarch64.crc32h"]
5-
fn crc32h_(crc: u32, data: u32) -> u32;
6-
#[link_name = "llvm.aarch64.crc32w"]
7-
fn crc32w_(crc: u32, data: u32) -> u32;
82
#[link_name = "llvm.aarch64.crc32x"]
93
fn crc32x_(crc: u32, data: u64) -> u32;
104

11-
#[link_name = "llvm.aarch64.crc32cb"]
12-
fn crc32cb_(crc: u32, data: u32) -> u32;
13-
#[link_name = "llvm.aarch64.crc32ch"]
14-
fn crc32ch_(crc: u32, data: u32) -> u32;
15-
#[link_name = "llvm.aarch64.crc32cw"]
16-
fn crc32cw_(crc: u32, data: u32) -> u32;
175
#[link_name = "llvm.aarch64.crc32cx"]
186
fn crc32cx_(crc: u32, data: u64) -> u32;
197
}
208

219
#[cfg(test)]
2210
use stdarch_test::assert_instr;
2311

24-
/// CRC32 single round checksum for bytes (8 bits).
25-
#[inline]
26-
#[target_feature(enable = "crc")]
27-
#[cfg_attr(test, assert_instr(crc32b))]
28-
pub unsafe fn __crc32b(crc: u32, data: u8) -> u32 {
29-
crc32b_(crc, data as u32)
30-
}
31-
32-
/// CRC32 single round checksum for half words (16 bits).
33-
#[inline]
34-
#[target_feature(enable = "crc")]
35-
#[cfg_attr(test, assert_instr(crc32h))]
36-
pub unsafe fn __crc32h(crc: u32, data: u16) -> u32 {
37-
crc32h_(crc, data as u32)
38-
}
39-
40-
/// CRC32 single round checksum for words (32 bits).
41-
#[inline]
42-
#[target_feature(enable = "crc")]
43-
#[cfg_attr(test, assert_instr(crc32w))]
44-
pub unsafe fn __crc32w(crc: u32, data: u32) -> u32 {
45-
crc32w_(crc, data)
46-
}
47-
4812
/// CRC32 single round checksum for quad words (64 bits).
4913
#[inline]
5014
#[target_feature(enable = "crc")]
@@ -53,30 +17,6 @@ pub unsafe fn __crc32d(crc: u32, data: u64) -> u32 {
5317
crc32x_(crc, data)
5418
}
5519

56-
/// CRC32-C single round checksum for bytes (8 bits).
57-
#[inline]
58-
#[target_feature(enable = "crc")]
59-
#[cfg_attr(test, assert_instr(crc32cb))]
60-
pub unsafe fn __crc32cb(crc: u32, data: u8) -> u32 {
61-
crc32cb_(crc, data as u32)
62-
}
63-
64-
/// CRC32-C single round checksum for half words (16 bits).
65-
#[inline]
66-
#[target_feature(enable = "crc")]
67-
#[cfg_attr(test, assert_instr(crc32ch))]
68-
pub unsafe fn __crc32ch(crc: u32, data: u16) -> u32 {
69-
crc32ch_(crc, data as u32)
70-
}
71-
72-
/// CRC32-C single round checksum for words (32 bits).
73-
#[inline]
74-
#[target_feature(enable = "crc")]
75-
#[cfg_attr(test, assert_instr(crc32cw))]
76-
pub unsafe fn __crc32cw(crc: u32, data: u32) -> u32 {
77-
crc32cw_(crc, data)
78-
}
79-
8020
/// CRC32-C single round checksum for quad words (64 bits).
8121
#[inline]
8222
#[target_feature(enable = "crc")]
@@ -91,48 +31,12 @@ mod tests {
9131
use std::mem;
9232
use stdarch_test::simd_test;
9333

94-
#[simd_test(enable = "crc")]
95-
unsafe fn test_crc32b() {
96-
assert_eq!(__crc32b(0, 0), 0);
97-
assert_eq!(__crc32b(0, 255), 755167117);
98-
}
99-
100-
#[simd_test(enable = "crc")]
101-
unsafe fn test_crc32h() {
102-
assert_eq!(__crc32h(0, 0), 0);
103-
assert_eq!(__crc32h(0, 16384), 1994146192);
104-
}
105-
106-
#[simd_test(enable = "crc")]
107-
unsafe fn test_crc32w() {
108-
assert_eq!(__crc32w(0, 0), 0);
109-
assert_eq!(__crc32w(0, 4294967295), 3736805603);
110-
}
111-
11234
#[simd_test(enable = "crc")]
11335
unsafe fn test_crc32d() {
11436
assert_eq!(__crc32d(0, 0), 0);
11537
assert_eq!(__crc32d(0, 18446744073709551615), 1147535477);
11638
}
11739

118-
#[simd_test(enable = "crc")]
119-
unsafe fn test_crc32cb() {
120-
assert_eq!(__crc32cb(0, 0), 0);
121-
assert_eq!(__crc32cb(0, 255), 2910671697);
122-
}
123-
124-
#[simd_test(enable = "crc")]
125-
unsafe fn test_crc32ch() {
126-
assert_eq!(__crc32ch(0, 0), 0);
127-
assert_eq!(__crc32ch(0, 16384), 1098587580);
128-
}
129-
130-
#[simd_test(enable = "crc")]
131-
unsafe fn test_crc32cw() {
132-
assert_eq!(__crc32cw(0, 0), 0);
133-
assert_eq!(__crc32cw(0, 4294967295), 3080238136);
134-
}
135-
13640
#[simd_test(enable = "crc")]
13741
unsafe fn test_crc32cd() {
13842
assert_eq!(__crc32cd(0, 0), 0);

crates/core_arch/src/arm/crc.rs

Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
extern "C" {
2+
#[cfg_attr(target_arch = "aarch64", link_name = "llvm.aarch64.crc32b")]
3+
#[cfg_attr(target_arch = "arm", link_name = "llvm.arm.crc32b")]
4+
fn crc32b_(crc: u32, data: u32) -> u32;
5+
#[cfg_attr(target_arch = "aarch64", link_name = "llvm.aarch64.crc32h")]
6+
#[cfg_attr(target_arch = "arm", link_name = "llvm.arm.crc32h")]
7+
fn crc32h_(crc: u32, data: u32) -> u32;
8+
#[cfg_attr(target_arch = "aarch64", link_name = "llvm.aarch64.crc32w")]
9+
#[cfg_attr(target_arch = "arm", link_name = "llvm.arm.crc32w")]
10+
fn crc32w_(crc: u32, data: u32) -> u32;
11+
12+
#[cfg_attr(target_arch = "aarch64", link_name = "llvm.aarch64.crc32cb")]
13+
#[cfg_attr(target_arch = "arm", link_name = "llvm.arm.crc32cb")]
14+
fn crc32cb_(crc: u32, data: u32) -> u32;
15+
#[cfg_attr(target_arch = "aarch64", link_name = "llvm.aarch64.crc32ch")]
16+
#[cfg_attr(target_arch = "arm", link_name = "llvm.arm.crc32ch")]
17+
fn crc32ch_(crc: u32, data: u32) -> u32;
18+
#[cfg_attr(target_arch = "aarch64", link_name = "llvm.aarch64.crc32cw")]
19+
#[cfg_attr(target_arch = "arm", link_name = "llvm.arm.crc32cw")]
20+
fn crc32cw_(crc: u32, data: u32) -> u32;
21+
}
22+
23+
#[cfg(test)]
24+
use stdarch_test::assert_instr;
25+
26+
/// CRC32 single round checksum for bytes (8 bits).
27+
#[inline]
28+
#[target_feature(enable = "crc")]
29+
#[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
30+
#[cfg_attr(test, assert_instr(crc32b))]
31+
pub unsafe fn __crc32b(crc: u32, data: u8) -> u32 {
32+
crc32b_(crc, data as u32)
33+
}
34+
35+
/// CRC32 single round checksum for half words (16 bits).
36+
#[inline]
37+
#[target_feature(enable = "crc")]
38+
#[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
39+
#[cfg_attr(test, assert_instr(crc32h))]
40+
pub unsafe fn __crc32h(crc: u32, data: u16) -> u32 {
41+
crc32h_(crc, data as u32)
42+
}
43+
44+
/// CRC32 single round checksum for words (32 bits).
45+
#[inline]
46+
#[target_feature(enable = "crc")]
47+
#[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
48+
#[cfg_attr(test, assert_instr(crc32w))]
49+
pub unsafe fn __crc32w(crc: u32, data: u32) -> u32 {
50+
crc32w_(crc, data)
51+
}
52+
53+
/// CRC32-C single round checksum for bytes (8 bits).
54+
#[inline]
55+
#[target_feature(enable = "crc")]
56+
#[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
57+
#[cfg_attr(test, assert_instr(crc32cb))]
58+
pub unsafe fn __crc32cb(crc: u32, data: u8) -> u32 {
59+
crc32cb_(crc, data as u32)
60+
}
61+
62+
/// CRC32-C single round checksum for half words (16 bits).
63+
#[inline]
64+
#[target_feature(enable = "crc")]
65+
#[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
66+
#[cfg_attr(test, assert_instr(crc32ch))]
67+
pub unsafe fn __crc32ch(crc: u32, data: u16) -> u32 {
68+
crc32ch_(crc, data as u32)
69+
}
70+
71+
/// CRC32-C single round checksum for words (32 bits).
72+
#[inline]
73+
#[target_feature(enable = "crc")]
74+
#[cfg_attr(target_arch = "arm", target_feature(enable = "v8"))]
75+
#[cfg_attr(test, assert_instr(crc32cw))]
76+
pub unsafe fn __crc32cw(crc: u32, data: u32) -> u32 {
77+
crc32cw_(crc, data)
78+
}
79+
80+
#[cfg(test)]
81+
mod tests {
82+
use crate::core_arch::{arm::*, simd::*};
83+
use std::mem;
84+
use stdarch_test::simd_test;
85+
86+
#[simd_test(enable = "crc")]
87+
unsafe fn test_crc32b() {
88+
assert_eq!(__crc32b(0, 0), 0);
89+
assert_eq!(__crc32b(0, 255), 755167117);
90+
}
91+
92+
#[simd_test(enable = "crc")]
93+
unsafe fn test_crc32h() {
94+
assert_eq!(__crc32h(0, 0), 0);
95+
assert_eq!(__crc32h(0, 16384), 1994146192);
96+
}
97+
98+
#[simd_test(enable = "crc")]
99+
unsafe fn test_crc32w() {
100+
assert_eq!(__crc32w(0, 0), 0);
101+
assert_eq!(__crc32w(0, 4294967295), 3736805603);
102+
}
103+
104+
#[simd_test(enable = "crc")]
105+
unsafe fn test_crc32cb() {
106+
assert_eq!(__crc32cb(0, 0), 0);
107+
assert_eq!(__crc32cb(0, 255), 2910671697);
108+
}
109+
110+
#[simd_test(enable = "crc")]
111+
unsafe fn test_crc32ch() {
112+
assert_eq!(__crc32ch(0, 0), 0);
113+
assert_eq!(__crc32ch(0, 16384), 1098587580);
114+
}
115+
116+
#[simd_test(enable = "crc")]
117+
unsafe fn test_crc32cw() {
118+
assert_eq!(__crc32cw(0, 0), 0);
119+
assert_eq!(__crc32cw(0, 4294967295), 3080238136);
120+
}
121+
}

crates/core_arch/src/arm/mod.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,11 @@ mod neon;
3434
))]
3535
pub use self::neon::*;
3636

37+
#[cfg(any(target_arch = "aarch64", target_feature = "v7"))]
38+
mod crc;
39+
#[cfg(any(target_arch = "aarch64", target_feature = "v7"))]
40+
pub use self::crc::*;
41+
3742
pub use crate::core_arch::acle::*;
3843

3944
#[cfg(test)]

0 commit comments

Comments
 (0)