Skip to content

Commit abcdfe3

Browse files
authored
Implement automatic verification for ARM/AArch64 intrinsics (#626)
This commit implements automatic verification of implement ARM/AArch64 intrinsics. Or it's at least a start! This downloads a snapshot of ARM's [online documentation][docs] and implements necessary logic to parse that and use it to verify all the intrinsics. Almost everything checked out A-OK but a few minor tweaks were needed to the neon intrinsics and the crc ones needed some renaming. [docs]: https://developer.arm.com/technologies/neon/intrinsics
1 parent 513e067 commit abcdfe3

File tree

9 files changed

+94107
-56
lines changed

9 files changed

+94107
-56
lines changed

coresimd/aarch64/crc.rs

+26-26
Original file line numberDiff line numberDiff line change
@@ -25,63 +25,63 @@ use stdsimd_test::assert_instr;
2525
#[inline]
2626
#[target_feature(enable = "crc")]
2727
#[cfg_attr(test, assert_instr(crc32b))]
28-
pub unsafe fn crc32b(crc: u32, data: u8) -> u32 {
28+
pub unsafe fn __crc32b(crc: u32, data: u8) -> u32 {
2929
crc32b_(crc, data as u32)
3030
}
3131

3232
/// CRC32 single round checksum for half words (16 bits).
3333
#[inline]
3434
#[target_feature(enable = "crc")]
3535
#[cfg_attr(test, assert_instr(crc32h))]
36-
pub unsafe fn crc32h(crc: u32, data: u16) -> u32 {
36+
pub unsafe fn __crc32h(crc: u32, data: u16) -> u32 {
3737
crc32h_(crc, data as u32)
3838
}
3939

4040
/// CRC32 single round checksum for words (32 bits).
4141
#[inline]
4242
#[target_feature(enable = "crc")]
4343
#[cfg_attr(test, assert_instr(crc32w))]
44-
pub unsafe fn crc32w(crc: u32, data: u32) -> u32 {
44+
pub unsafe fn __crc32w(crc: u32, data: u32) -> u32 {
4545
crc32w_(crc, data)
4646
}
4747

4848
/// CRC32 single round checksum for quad words (64 bits).
4949
#[inline]
5050
#[target_feature(enable = "crc")]
5151
#[cfg_attr(test, assert_instr(crc32x))]
52-
pub unsafe fn crc32x(crc: u32, data: u64) -> u32 {
52+
pub unsafe fn __crc32d(crc: u32, data: u64) -> u32 {
5353
crc32x_(crc, data)
5454
}
5555

5656
/// CRC32-C single round checksum for bytes (8 bits).
5757
#[inline]
5858
#[target_feature(enable = "crc")]
5959
#[cfg_attr(test, assert_instr(crc32cb))]
60-
pub unsafe fn crc32cb(crc: u32, data: u8) -> u32 {
60+
pub unsafe fn __crc32cb(crc: u32, data: u8) -> u32 {
6161
crc32cb_(crc, data as u32)
6262
}
6363

6464
/// CRC32-C single round checksum for half words (16 bits).
6565
#[inline]
6666
#[target_feature(enable = "crc")]
6767
#[cfg_attr(test, assert_instr(crc32ch))]
68-
pub unsafe fn crc32ch(crc: u32, data: u16) -> u32 {
68+
pub unsafe fn __crc32ch(crc: u32, data: u16) -> u32 {
6969
crc32ch_(crc, data as u32)
7070
}
7171

7272
/// CRC32-C single round checksum for words (32 bits).
7373
#[inline]
7474
#[target_feature(enable = "crc")]
7575
#[cfg_attr(test, assert_instr(crc32cw))]
76-
pub unsafe fn crc32cw(crc: u32, data: u32) -> u32 {
76+
pub unsafe fn __crc32cw(crc: u32, data: u32) -> u32 {
7777
crc32cw_(crc, data)
7878
}
7979

8080
/// CRC32-C single round checksum for quad words (64 bits).
8181
#[inline]
8282
#[target_feature(enable = "crc")]
8383
#[cfg_attr(test, assert_instr(crc32cx))]
84-
pub unsafe fn crc32cx(crc: u32, data: u64) -> u32 {
84+
pub unsafe fn __crc32cd(crc: u32, data: u64) -> u32 {
8585
crc32cx_(crc, data)
8686
}
8787

@@ -94,50 +94,50 @@ mod tests {
9494

9595
#[simd_test(enable = "crc")]
9696
unsafe fn test_crc32b() {
97-
assert_eq!(crc32b(0, 0), 0);
98-
assert_eq!(crc32b(0, 255), 755167117);
97+
assert_eq!(__crc32b(0, 0), 0);
98+
assert_eq!(__crc32b(0, 255), 755167117);
9999
}
100100

101101
#[simd_test(enable = "crc")]
102102
unsafe fn test_crc32h() {
103-
assert_eq!(crc32h(0, 0), 0);
104-
assert_eq!(crc32h(0, 16384), 1994146192);
103+
assert_eq!(__crc32h(0, 0), 0);
104+
assert_eq!(__crc32h(0, 16384), 1994146192);
105105
}
106106

107107
#[simd_test(enable = "crc")]
108108
unsafe fn test_crc32w() {
109-
assert_eq!(crc32w(0, 0), 0);
110-
assert_eq!(crc32w(0, 4294967295), 3736805603);
109+
assert_eq!(__crc32w(0, 0), 0);
110+
assert_eq!(__crc32w(0, 4294967295), 3736805603);
111111
}
112112

113113
#[simd_test(enable = "crc")]
114-
unsafe fn test_crc32x() {
115-
assert_eq!(crc32x(0, 0), 0);
116-
assert_eq!(crc32x(0, 18446744073709551615), 1147535477);
114+
unsafe fn test_crc32d() {
115+
assert_eq!(__crc32d(0, 0), 0);
116+
assert_eq!(__crc32d(0, 18446744073709551615), 1147535477);
117117
}
118118

119119
#[simd_test(enable = "crc")]
120120
unsafe fn test_crc32cb() {
121-
assert_eq!(crc32cb(0, 0), 0);
122-
assert_eq!(crc32cb(0, 255), 2910671697);
121+
assert_eq!(__crc32cb(0, 0), 0);
122+
assert_eq!(__crc32cb(0, 255), 2910671697);
123123
}
124124

125125
#[simd_test(enable = "crc")]
126126
unsafe fn test_crc32ch() {
127-
assert_eq!(crc32ch(0, 0), 0);
128-
assert_eq!(crc32ch(0, 16384), 1098587580);
127+
assert_eq!(__crc32ch(0, 0), 0);
128+
assert_eq!(__crc32ch(0, 16384), 1098587580);
129129
}
130130

131131
#[simd_test(enable = "crc")]
132132
unsafe fn test_crc32cw() {
133-
assert_eq!(crc32cw(0, 0), 0);
134-
assert_eq!(crc32cw(0, 4294967295), 3080238136);
133+
assert_eq!(__crc32cw(0, 0), 0);
134+
assert_eq!(__crc32cw(0, 4294967295), 3080238136);
135135
}
136136

137137
#[simd_test(enable = "crc")]
138-
unsafe fn test_crc32cx() {
139-
assert_eq!(crc32cx(0, 0), 0);
140-
assert_eq!(crc32cx(0, 18446744073709551615), 3293575501);
138+
unsafe fn test_crc32cd() {
139+
assert_eq!(__crc32cd(0, 0), 0);
140+
assert_eq!(__crc32cd(0, 18446744073709551615), 3293575501);
141141
}
142142

143143
}

coresimd/aarch64/neon.rs

+10-4
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ use coresimd::simd_llvm::*;
99
#[cfg(test)]
1010
use stdsimd_test::assert_instr;
1111

12+
use mem;
13+
1214
types! {
1315
/// ARM-specific 64-bit wide vector of one packed `f64`.
1416
pub struct float64x1_t(f64); // FIXME: check this!
@@ -250,16 +252,20 @@ pub unsafe fn vaddq_f64(a: float64x2_t, b: float64x2_t) -> float64x2_t {
250252
#[inline]
251253
#[target_feature(enable = "neon")]
252254
#[cfg_attr(test, assert_instr(add))]
253-
pub unsafe fn vaddd_s64(a: int64x1_t, b: int64x1_t) -> int64x1_t {
254-
simd_add(a, b)
255+
pub unsafe fn vaddd_s64(a: i64, b: i64) -> i64 {
256+
let a: int64x1_t = mem::transmute(a);
257+
let b: int64x1_t = mem::transmute(b);
258+
simd_extract(simd_add(a, b), 0)
255259
}
256260

257261
/// Vector add.
258262
#[inline]
259263
#[target_feature(enable = "neon")]
260264
#[cfg_attr(test, assert_instr(add))]
261-
pub unsafe fn vaddd_u64(a: uint64x1_t, b: uint64x1_t) -> uint64x1_t {
262-
simd_add(a, b)
265+
pub unsafe fn vaddd_u64(a: u64, b: u64) -> u64 {
266+
let a: uint64x1_t = mem::transmute(a);
267+
let b: uint64x1_t = mem::transmute(b);
268+
simd_extract(simd_add(a, b), 0)
263269
}
264270

265271
/// Horizontal vector max.

coresimd/arm/neon.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -702,7 +702,7 @@ pub unsafe fn vtbl1_u8(a: uint8x8_t, b: uint8x8_t) -> uint8x8_t {
702702
#[cfg(target_endian = "little")]
703703
#[target_feature(enable = "neon,v7")]
704704
#[cfg_attr(test, assert_instr(vtbl))]
705-
pub unsafe fn vtbl1_p8(a: poly8x8_t, b: poly8x8_t) -> poly8x8_t {
705+
pub unsafe fn vtbl1_p8(a: poly8x8_t, b: uint8x8_t) -> poly8x8_t {
706706
::mem::transmute(vtbl1(::mem::transmute(a), ::mem::transmute(b)))
707707
}
708708

crates/stdsimd-verify/Cargo.toml

+3-2
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
name = "stdsimd-verify"
33
version = "0.1.0"
44
authors = ["Alex Crichton <[email protected]>"]
5+
edition = "2018"
56

67
[dependencies]
78
proc-macro2 = "0.4"
@@ -13,6 +14,6 @@ proc-macro = true
1314
test = false
1415

1516
[dev-dependencies]
16-
serde = "1.0"
17-
serde_derive = "1.0"
17+
serde = { version = "1.0", features = ['derive'] }
1818
serde-xml-rs = "0.2"
19+
html5ever = "0.22.5"

0 commit comments

Comments
 (0)