Skip to content

Commit

Permalink
Merge pull request #633 from tea/bswap
Browse files Browse the repository at this point in the history
Implement __bswap[si]i2 intrinsics
  • Loading branch information
Amanieu committed Jul 6, 2024
2 parents eb6d2b6 + 3641761 commit 06db2de
Show file tree
Hide file tree
Showing 5 changed files with 63 additions and 0 deletions.
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,9 @@ rely on CI.
- [ ] arm/unordsf2vfp.S
- [x] ashldi3.c
- [x] ashrdi3.c
- [x] bswapdi2.c
- [x] bswapsi2.c
- [x] bswapti2.c
- [x] comparedf2.c
- [x] comparesf2.c
- [x] divdf3.c
Expand Down
3 changes: 3 additions & 0 deletions build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,9 @@ fn configure_check_cfg() {
"__ashlsi3",
"__ashrdi3",
"__ashrsi3",
"__bswapsi2",
"__bswapdi2",
"__bswapti2",
"__clzsi2",
"__divdi3",
"__divsi3",
Expand Down
22 changes: 22 additions & 0 deletions src/int/bswap.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
intrinsics! {
#[maybe_use_optimized_c_shim]
#[avr_skip]
/// Swaps bytes in 32-bit number
pub extern "C" fn __bswapsi2(x: u32) -> u32 {
x.swap_bytes()
}

#[maybe_use_optimized_c_shim]
#[avr_skip]
/// Swaps bytes in 64-bit number
pub extern "C" fn __bswapdi2(x: u64) -> u64 {
x.swap_bytes()
}

#[maybe_use_optimized_c_shim]
#[avr_skip]
/// Swaps bytes in 128-bit number
pub extern "C" fn __bswapti2(x: u128) -> u128 {
x.swap_bytes()
}
}
1 change: 1 addition & 0 deletions src/int/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ mod specialized_div_rem;

pub mod addsub;
mod big;
pub mod bswap;
pub mod leading_zeros;
pub mod mul;
pub mod sdiv;
Expand Down
34 changes: 34 additions & 0 deletions testcrate/tests/misc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,40 @@ fn leading_zeros() {
})
}

#[test]
#[cfg(not(target_arch = "avr"))]
fn bswap() {
use compiler_builtins::int::bswap::{__bswapdi2, __bswapsi2};
fuzz(N, |x: u32| {
assert_eq!(x.swap_bytes(), __bswapsi2(x));
});
fuzz(N, |x: u64| {
assert_eq!(x.swap_bytes(), __bswapdi2(x));
});

assert_eq!(__bswapsi2(0x12345678u32), 0x78563412u32);
assert_eq!(__bswapsi2(0x00000001u32), 0x01000000u32);
assert_eq!(__bswapdi2(0x123456789ABCDEF0u64), 0xF0DEBC9A78563412u64);
assert_eq!(__bswapdi2(0x0200000001000000u64), 0x0000000100000002u64);

#[cfg(any(target_pointer_width = "32", target_pointer_width = "64"))]
{
use compiler_builtins::int::bswap::__bswapti2;
fuzz(N, |x: u128| {
assert_eq!(x.swap_bytes(), __bswapti2(x));
});

assert_eq!(
__bswapti2(0x123456789ABCDEF013579BDF02468ACEu128),
0xCE8A4602DF9B5713F0DEBC9A78563412u128
);
assert_eq!(
__bswapti2(0x04000000030000000200000001000000u128),
0x00000001000000020000000300000004u128
);
}
}

// This is approximate because of issues related to
// https://github.com/rust-lang/rust/issues/73920.
// TODO how do we resolve this indeterminacy?
Expand Down

0 comments on commit 06db2de

Please sign in to comment.