Skip to content

Commit 88edf14

Browse files
authored
cpubits: add 64-bit override for ARMv7 (#1419)
ARMv7 is one of the main architectures for which we've received requests for 64-bit overrides in the past (see discussion on #826). Though natively 32-bit, ARMv7 supports certain "doubleword" instructions which model 64-bit values as a pair of 32-bit registers, e.g. `ADDS`/`ADC` and `SUBS`/`SBC` for 2x32-bit addition/subtraction, as well as `UMULL`/`SMULL` for widening multiplication with 2x32-bit outputs. Many ARMv7 CPUs internally fetch 64-bits of instruction at once and can move 64-bits of data via `LDRD`/`STRD` in one cycle on optimized paths. Some high-performance ARMv7 CPUs internally combine the barrel shifter + ALU to speed multi-word shifts. If we use 64-bit implementations when targeting ARMv7, codegen is able to leverage these optimizations.
1 parent 6aa9161 commit 88edf14

File tree

2 files changed

+39
-4
lines changed

2 files changed

+39
-4
lines changed

.github/workflows/cpubits.yml

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,23 @@ jobs:
5252
- run: ${{ matrix.deps }}
5353
- run: cargo test --target ${{ matrix.target }}
5454

55+
# Test on foreign architectures using `cross test`
56+
test-cross:
57+
strategy:
58+
matrix:
59+
include:
60+
- target: armv7-unknown-linux-gnueabi # ARM32
61+
- target: powerpc-unknown-linux-gnu # PPC32
62+
runs-on: ubuntu-latest
63+
steps:
64+
- uses: actions/checkout@v6
65+
- uses: dtolnay/rust-toolchain@master
66+
with:
67+
toolchain: stable
68+
targets: ${{ matrix.target }}
69+
- run: cargo install cross
70+
- run: cross test --target ${{ matrix.target }}
71+
5572
# Test WASM using `wasm32-wasip1` target on `wasmtime`
5673
test-wasm:
5774
strategy:

cpubits/src/lib.rs

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/6ee8e381/logo.svg",
55
html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/6ee8e381/logo.svg"
66
)]
7+
#![allow(clippy::doc_markdown)]
78

89
//! # Supported bit sizes
910
//!
@@ -93,7 +94,8 @@
9394
/// certain targets from 32-bit to 64-bit ones.
9495
///
9596
/// This 64-bit promotion occurs if `any` of the following `cfg`s are true:
96-
/// - `target_family = "wasm"`
97+
/// - ARMv7: `all(target_arch = "arm", not(target_feature = "thumb-mode"))`
98+
/// - WASM: `target_arch = "wasm32"`
9799
#[macro_export]
98100
macro_rules! cpubits {
99101
// Only run the given block if we have selected a 16-bit word size, i.e. the code will be
@@ -173,9 +175,13 @@ macro_rules! cpubits {
173175
64 => { $( $tokens64:tt )* }
174176
) => {
175177
$crate::cpubits! {
178+
// `cfg` selector for 64-bit target overrides
179+
// Implicitly `cfg(any(...))`
176180
#[cfg(enable_64bit(
177-
// `cfg` selector for 64-bit targets (implicitly `any`)
178-
target_arch = "wasm32"
181+
// ARMv7
182+
all(target_arch = "arm", not(target_feature = "thumb-mode")),
183+
// WASM
184+
target_arch = "wasm32",
179185
))]
180186
16 => { $( $tokens32 )* }
181187
32 => { $( $tokens32 )* }
@@ -294,7 +300,12 @@ mod tests {
294300
/// Return the expected number of bits for the target.
295301
fn expected_bits() -> u32 {
296302
// Duplicated 64-bit override predicates need to go here
297-
if cfg!(target_arch = "wasm32") {
303+
if cfg!(any(
304+
// ARMv7
305+
all(target_arch = "arm", not(target_feature = "thumb-mode")),
306+
// WASM
307+
target_arch = "wasm32"
308+
)) {
298309
64
299310
} else {
300311
detect_pointer_width()
@@ -306,6 +317,13 @@ mod tests {
306317
assert_eq!(detected_bits(), expected_bits());
307318
}
308319

320+
/// Explicit test for ARMv7 so we can see the predicate is working
321+
#[cfg(all(target_arch = "arm", not(target_feature = "thumb-mode")))]
322+
#[test]
323+
fn cpubits_on_armv7_is_64bit() {
324+
assert_eq!(detected_bits(), 64);
325+
}
326+
309327
/// Explicit test for WASM so we can see the predicate is working
310328
#[cfg(target_arch = "wasm32")]
311329
#[test]

0 commit comments

Comments
 (0)