From 400b05d3a32fd1c3e3b4cd21ee194adf82b682df Mon Sep 17 00:00:00 2001 From: Hanna Kruppe Date: Sun, 4 Oct 2026 20:47:09 +0200 Subject: [PATCH 1/6] Outline constant messages from panicking macros This emits (very slightly) less code per call site because it's passing one less argument (the implicit caller location is still passed). --- library/core/src/macros/mod.rs | 4 +-- library/core/src/panic.rs | 8 ++--- library/core/src/panicking.rs | 32 +++++++++++++++++++ ..._type_annotations.let_else.built.after.mir | 8 +---- ...otations.let_else_bindless.built.after.mir | 8 +---- ...implifyComparisonIntegral.panic-abort.diff | 8 +---- ...mplifyComparisonIntegral.panic-unwind.diff | 8 +---- tests/pretty/autodiff/autodiff_forward.pp | 12 +++---- tests/pretty/autodiff/autodiff_reverse.pp | 8 ++--- tests/pretty/offload/offload_kernel.host.pp | 2 +- tests/ui/proc-macro/quote/debug.stdout | 8 ++--- 11 files changed, 55 insertions(+), 51 deletions(-) diff --git a/library/core/src/macros/mod.rs b/library/core/src/macros/mod.rs index ab8fc47009186..f0fb18fa040d3 100644 --- a/library/core/src/macros/mod.rs +++ b/library/core/src/macros/mod.rs @@ -802,7 +802,7 @@ macro_rules! unreachable { #[rustc_diagnostic_opaque] macro_rules! unimplemented { () => { - $crate::panicking::panic("not implemented") + $crate::panicking::unimplemented_default_msg() }; ($($arg:tt)+) => { $crate::panic!("not implemented: {}", $crate::format_args!($($arg)+)) @@ -883,7 +883,7 @@ macro_rules! unimplemented { #[rustc_diagnostic_opaque] macro_rules! todo { () => { - $crate::panicking::panic("not yet implemented") + $crate::panicking::todo_default_msg() }; ($($arg:tt)+) => { $crate::panic!("not yet implemented: {}", $crate::format_args!($($arg)+)) diff --git a/library/core/src/panic.rs b/library/core/src/panic.rs index 4fcd5f615e993..66d45765f5320 100644 --- a/library/core/src/panic.rs +++ b/library/core/src/panic.rs @@ -22,7 +22,7 @@ pub use self::unwind_safe::{AssertUnwindSafe, RefUnwindSafe, UnwindSafe}; #[rustc_macro_transparency = "semiopaque"] pub macro panic_2015 { () => ( - $crate::panicking::panic("explicit panic") + $crate::panicking::panic_default_msg() ), ($msg:literal $(,)?) => ( $crate::panicking::panic($msg) @@ -49,7 +49,7 @@ pub macro panic_2015 { #[rustc_macro_transparency = "semiopaque"] pub macro panic_2021 { () => ( - $crate::panicking::panic("explicit panic") + $crate::panicking::panic_default_msg() ), // Special-case the single-argument case for const_panic. ("{}", $arg:expr $(,)?) => ({ @@ -69,7 +69,7 @@ pub macro panic_2021 { #[rustc_macro_transparency = "semiopaque"] pub macro unreachable_2015 { () => ( - $crate::panicking::panic("internal error: entered unreachable code") + $crate::panicking::unreachable_default_msg() ), // Use of `unreachable_display` for non_fmt_panic lint. // NOTE: the message ("internal error ...") is embedded directly in unreachable_display @@ -87,7 +87,7 @@ pub macro unreachable_2015 { #[rustc_macro_transparency = "semiopaque"] pub macro unreachable_2021 { () => ( - $crate::panicking::panic("internal error: entered unreachable code") + $crate::panicking::unreachable_default_msg() ), ($($t:tt)+) => ( $crate::panic!("internal error: entered unreachable code: {}", $crate::format_args!($($t)+)) diff --git a/library/core/src/panicking.rs b/library/core/src/panicking.rs index bd4fbcf68b256..8a5e0f035d775 100644 --- a/library/core/src/panicking.rs +++ b/library/core/src/panicking.rs @@ -456,3 +456,35 @@ fn assert_failed_inner( ), } } + +// panic!() without args expands to this, to generate slightly less code +#[cfg_attr(not(panic = "immediate-abort"), inline(never), cold)] +#[cfg_attr(panic = "immediate-abort", inline)] +#[track_caller] +pub const fn panic_default_msg() -> ! { + panic("explicit panic") +} + +// unreachable!() without args expands to this, to generate slightly less code +#[cfg_attr(not(panic = "immediate-abort"), inline(never), cold)] +#[cfg_attr(panic = "immediate-abort", inline)] +#[track_caller] +pub const fn unreachable_default_msg() -> ! { + panic("internal error: entered unreachable code") +} + +// unimplemented!() without args expands to this, to generate slightly less code +#[cfg_attr(not(panic = "immediate-abort"), inline(never), cold)] +#[cfg_attr(panic = "immediate-abort", inline)] +#[track_caller] +pub const fn unimplemented_default_msg() -> ! { + panic("not implemented") +} + +// todo!() without args expands to this, to generate slightly less code +#[cfg_attr(not(panic = "immediate-abort"), inline(never), cold)] +#[cfg_attr(panic = "immediate-abort", inline)] +#[track_caller] +pub const fn todo_default_msg() -> ! { + panic("not yet implemented") +} diff --git a/tests/mir-opt/building/user_type_annotations.let_else.built.after.mir b/tests/mir-opt/building/user_type_annotations.let_else.built.after.mir index db79f934ac3a3..38dd03c93bc96 100644 --- a/tests/mir-opt/building/user_type_annotations.let_else.built.after.mir +++ b/tests/mir-opt/building/user_type_annotations.let_else.built.after.mir @@ -35,7 +35,7 @@ fn let_else() -> () { } bb1: { - _1 = core::panicking::panic(const "internal error: entered unreachable code") -> [return: bb2, unwind: bb6]; + _1 = core::panicking::unreachable_default_msg() -> [return: bb2, unwind: bb6]; } bb2: { @@ -75,9 +75,3 @@ fn let_else() -> () { resume; } } - -ALLOC0 (size: 40, align: 1) { - 0x00 │ 69 6e 74 65 72 6e 61 6c 20 65 72 72 6f 72 3a 20 │ internal error: - 0x10 │ 65 6e 74 65 72 65 64 20 75 6e 72 65 61 63 68 61 │ entered unreacha - 0x20 │ 62 6c 65 20 63 6f 64 65 │ ble code -} diff --git a/tests/mir-opt/building/user_type_annotations.let_else_bindless.built.after.mir b/tests/mir-opt/building/user_type_annotations.let_else_bindless.built.after.mir index 098fc4e7437ae..d4300494952e5 100644 --- a/tests/mir-opt/building/user_type_annotations.let_else_bindless.built.after.mir +++ b/tests/mir-opt/building/user_type_annotations.let_else_bindless.built.after.mir @@ -29,7 +29,7 @@ fn let_else_bindless() -> () { } bb1: { - _1 = core::panicking::panic(const "internal error: entered unreachable code") -> [return: bb2, unwind: bb6]; + _1 = core::panicking::unreachable_default_msg() -> [return: bb2, unwind: bb6]; } bb2: { @@ -60,9 +60,3 @@ fn let_else_bindless() -> () { resume; } } - -ALLOC0 (size: 40, align: 1) { - 0x00 │ 69 6e 74 65 72 6e 61 6c 20 65 72 72 6f 72 3a 20 │ internal error: - 0x10 │ 65 6e 74 65 72 65 64 20 75 6e 72 65 61 63 68 61 │ entered unreacha - 0x20 │ 62 6c 65 20 63 6f 64 65 │ ble code -} diff --git a/tests/mir-opt/issue_76432.test.SimplifyComparisonIntegral.panic-abort.diff b/tests/mir-opt/issue_76432.test.SimplifyComparisonIntegral.panic-abort.diff index 95f9b5997d4f6..40d1b0e28bf1c 100644 --- a/tests/mir-opt/issue_76432.test.SimplifyComparisonIntegral.panic-abort.diff +++ b/tests/mir-opt/issue_76432.test.SimplifyComparisonIntegral.panic-abort.diff @@ -31,7 +31,7 @@ } bb1: { - _8 = core::panicking::panic(const "internal error: entered unreachable code") -> unwind unreachable; + _8 = core::panicking::unreachable_default_msg() -> unwind unreachable; } bb2: { @@ -43,9 +43,3 @@ } } - ALLOC0 (size: 40, align: 1) { - 0x00 │ 69 6e 74 65 72 6e 61 6c 20 65 72 72 6f 72 3a 20 │ internal error: - 0x10 │ 65 6e 74 65 72 65 64 20 75 6e 72 65 61 63 68 61 │ entered unreacha - 0x20 │ 62 6c 65 20 63 6f 64 65 │ ble code - } - diff --git a/tests/mir-opt/issue_76432.test.SimplifyComparisonIntegral.panic-unwind.diff b/tests/mir-opt/issue_76432.test.SimplifyComparisonIntegral.panic-unwind.diff index 87449b043fd5e..a72d0b6c51b3b 100644 --- a/tests/mir-opt/issue_76432.test.SimplifyComparisonIntegral.panic-unwind.diff +++ b/tests/mir-opt/issue_76432.test.SimplifyComparisonIntegral.panic-unwind.diff @@ -31,7 +31,7 @@ } bb1: { - _8 = core::panicking::panic(const "internal error: entered unreachable code") -> unwind continue; + _8 = core::panicking::unreachable_default_msg() -> unwind continue; } bb2: { @@ -43,9 +43,3 @@ } } - ALLOC0 (size: 40, align: 1) { - 0x00 │ 69 6e 74 65 72 6e 61 6c 20 65 72 72 6f 72 3a 20 │ internal error: - 0x10 │ 65 6e 74 65 72 65 64 20 75 6e 72 65 61 63 68 61 │ entered unreacha - 0x20 │ 62 6c 65 20 63 6f 64 65 │ ble code - } - diff --git a/tests/pretty/autodiff/autodiff_forward.pp b/tests/pretty/autodiff/autodiff_forward.pp index 0fb60061f6982..50370071db7b0 100644 --- a/tests/pretty/autodiff/autodiff_forward.pp +++ b/tests/pretty/autodiff/autodiff_forward.pp @@ -31,7 +31,7 @@ // Make sure we can handle generics - ::core::panicking::panic("not implemented") + ::core::panicking::unimplemented_default_msg() } #[rustc_autodiff(Forward, 1, Dual, Const, Dual)] pub fn df1(x: &[f64], bx_0: &[f64], y: f64) -> (f64, f64) { @@ -40,7 +40,7 @@ } #[rustc_autodiff] pub fn f2(x: &[f64], y: f64) -> f64 { - ::core::panicking::panic("not implemented") + ::core::panicking::unimplemented_default_msg() } #[rustc_autodiff(Forward, 1, Dual, Const, Const)] pub fn df2(x: &[f64], bx_0: &[f64], y: f64) -> f64 { @@ -49,7 +49,7 @@ } #[rustc_autodiff] pub fn f3(x: &[f64], y: f64) -> f64 { - ::core::panicking::panic("not implemented") + ::core::panicking::unimplemented_default_msg() } #[rustc_autodiff(Forward, 1, Dual, Const, Const)] pub fn df3(x: &[f64], bx_0: &[f64], y: f64) -> f64 { @@ -62,7 +62,7 @@ pub fn df4() -> () { ::core::intrinsics::autodiff(f4 as fn(), df4, ()) } #[rustc_autodiff] pub fn f5(x: &[f64], y: f64) -> f64 { - ::core::panicking::panic("not implemented") + ::core::panicking::unimplemented_default_msg() } #[rustc_autodiff(Forward, 1, Const, Dual, Const)] pub fn df5_y(x: &[f64], y: f64, by_0: f64) -> f64 { @@ -82,7 +82,7 @@ struct DoesNotImplDefault; #[rustc_autodiff] pub fn f6() -> DoesNotImplDefault { - ::core::panicking::panic("not implemented") + ::core::panicking::unimplemented_default_msg() } #[rustc_autodiff(Forward, 1, Const)] pub fn df6() -> DoesNotImplDefault { @@ -96,7 +96,7 @@ } #[no_mangle] #[rustc_autodiff] -fn f8(x: &f32) -> f32 { ::core::panicking::panic("not implemented") } +fn f8(x: &f32) -> f32 { ::core::panicking::unimplemented_default_msg() } #[rustc_autodiff(Forward, 4, Dual, Dual)] fn f8_3(x: &f32, bx_0: &f32, bx_1: &f32, bx_2: &f32, bx_3: &f32) -> [f32; 5usize] { diff --git a/tests/pretty/autodiff/autodiff_reverse.pp b/tests/pretty/autodiff/autodiff_reverse.pp index 01ac5a5888cfc..4dfd7cef8c9ed 100644 --- a/tests/pretty/autodiff/autodiff_reverse.pp +++ b/tests/pretty/autodiff/autodiff_reverse.pp @@ -24,7 +24,7 @@ // constructor) namespace? > It's expected to work normally. - ::core::panicking::panic("not implemented") + ::core::panicking::unimplemented_default_msg() } #[rustc_autodiff(Reverse, 1, Duplicated, Const, Active)] pub fn df1(x: &[f64], dx_0: &mut [f64], y: f64, dret: f64) -> f64 { @@ -37,7 +37,7 @@ pub fn df2() { ::core::intrinsics::autodiff(f2 as fn(), df2, ()) } #[rustc_autodiff] pub fn f3(x: &[f64], y: f64) -> f64 { - ::core::panicking::panic("not implemented") + ::core::panicking::unimplemented_default_msg() } #[rustc_autodiff(Reverse, 1, Duplicated, Const, Active)] pub fn df3(x: &[f64], dx_0: &mut [f64], y: f64, dret: f64) -> f64 { @@ -47,14 +47,14 @@ enum Foo { Reverse, } use Foo::Reverse; #[rustc_autodiff] -pub fn f4(x: f32) { ::core::panicking::panic("not implemented") } +pub fn f4(x: f32) { ::core::panicking::unimplemented_default_msg() } #[rustc_autodiff(Reverse, 1, Const, None)] pub fn df4(x: f32) { ::core::intrinsics::autodiff(f4 as fn(_: f32), df4, (x,)) } #[rustc_autodiff] pub fn f5(x: *const f32, y: &f32) { - ::core::panicking::panic("not implemented") + ::core::panicking::unimplemented_default_msg() } #[rustc_autodiff(Reverse, 1, DuplicatedOnly, Duplicated, None)] pub unsafe fn df5(x: *const f32, dx_0: *mut f32, y: &f32, dy_0: &mut f32) { diff --git a/tests/pretty/offload/offload_kernel.host.pp b/tests/pretty/offload/offload_kernel.host.pp index c35cf9474f709..eacfdab13b643 100644 --- a/tests/pretty/offload/offload_kernel.host.pp +++ b/tests/pretty/offload/offload_kernel.host.pp @@ -21,6 +21,6 @@ #[inline(never)] fn foo(_: &[f32], _: &[f32], _: *mut f32) { - ::core::panicking::panic("not implemented") + ::core::panicking::unimplemented_default_msg() } fn main() {} diff --git a/tests/ui/proc-macro/quote/debug.stdout b/tests/ui/proc-macro/quote/debug.stdout index 097cf75223bfb..fd2e25cbab017 100644 --- a/tests/ui/proc-macro/quote/debug.stdout +++ b/tests/ui/proc-macro/quote/debug.stdout @@ -34,9 +34,7 @@ fn main() { (iter.next(), iter.next()) { lit.set_span(crate::Span::recover_proc_macro_span(2)); lit - } else { - ::core::panicking::panic("internal error: entered unreachable code") - } + } else { ::core::panicking::unreachable_default_msg() } }), &mut ts); crate::ToTokens::to_tokens(&crate::TokenTree::Punct(crate::Punct::new(';', crate::Spacing::Alone)), &mut ts); @@ -53,9 +51,7 @@ fn main() { (iter.next(), iter.next()) { lit.set_span(crate::Span::recover_proc_macro_span(5)); lit - } else { - ::core::panicking::panic("internal error: entered unreachable code") - } + } else { ::core::panicking::unreachable_default_msg() } }), &mut ts); crate::ToTokens::to_tokens(&crate::TokenTree::Punct(crate::Punct::new(';', crate::Spacing::Alone)), &mut ts); From c860e0d40d81bc3b3d48c2583edeae391338cd74 Mon Sep 17 00:00:00 2001 From: TechnoPorg Date: Wed, 21 Oct 2026 09:13:50 -0400 Subject: [PATCH 2/6] Use 64-bit time for futex syscalls on RV32 --- Cargo.lock | 4 ++-- library/std/src/sys/sync/futex/unix.rs | 18 +++++++++++++++--- 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 634e81eaf80b4..73c7c8ab97e1c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2273,9 +2273,9 @@ checksum = "803ec87c9cfb29b9d2633f20cba1f488db3fd53f2158b1024cbefb47ba05d413" [[package]] name = "libc" -version = "0.2.189" +version = "0.2.191" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3eaf3ede3fee6db1a4c2ee091bf8a8b4dccdc6d17f656fb07896ee72867612f2" +checksum = "65cd87c9a6d60536580b316ad985726104730a5151c99845f2490428ef91240a" [[package]] name = "libffi" diff --git a/library/std/src/sys/sync/futex/unix.rs b/library/std/src/sys/sync/futex/unix.rs index 004d8323060e5..82861c35e4c43 100644 --- a/library/std/src/sys/sync/futex/unix.rs +++ b/library/std/src/sys/sync/futex/unix.rs @@ -11,6 +11,18 @@ pub type SmallFutex = Atomic; /// Must be the underlying type of SmallFutex pub type SmallPrimitive = u32; +#[cfg(any(target_os = "linux", target_os = "android"))] +cfg_select! { + // riscv32 only exposes the `SYS_futex_time64` syscall, + // whereas other 32-bit targets also expose `SYS_futex`, which uses 32-bit time. + target_arch = "riscv32" => { + use libc::SYS_futex_time64 as SYS_futex; + } + _ => { + use libc::SYS_futex; + } +} + /// Waits for a `futex_wake` operation to wake us. /// /// Returns directly if the futex doesn't hold the expected value. @@ -61,7 +73,7 @@ pub fn futex_wait(futex: &Atomic, expected: u32, timeout: Option) // Use FUTEX_WAIT_BITSET rather than FUTEX_WAIT to be able to give an // absolute time rather than a relative time. libc::syscall( - libc::SYS_futex, + SYS_futex, futex as *const Atomic as *const u32, libc::FUTEX_WAIT_BITSET | libc::FUTEX_PRIVATE_FLAG, expected, @@ -94,7 +106,7 @@ pub fn futex_wait(futex: &Atomic, expected: u32, timeout: Option) pub fn futex_wake(futex: &Atomic) -> bool { let ptr = futex as *const Atomic as *const u32; let op = libc::FUTEX_WAKE | libc::FUTEX_PRIVATE_FLAG; - unsafe { libc::syscall(libc::SYS_futex, ptr, op, 1) > 0 } + unsafe { libc::syscall(SYS_futex, ptr, op, 1) > 0 } } /// Wakes up all threads that are waiting on `futex_wait` on this futex. @@ -103,7 +115,7 @@ pub fn futex_wake_all(futex: &Atomic) { let ptr = futex as *const Atomic as *const u32; let op = libc::FUTEX_WAKE | libc::FUTEX_PRIVATE_FLAG; unsafe { - libc::syscall(libc::SYS_futex, ptr, op, i32::MAX); + libc::syscall(SYS_futex, ptr, op, i32::MAX); } } From e18ee6367f8ce37afd4e5494fa28ba637dfa0e04 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rom=C3=A1n=20C=C3=A1rdenas=20Rodr=C3=ADguez?= Date: Wed, 21 Oct 2026 16:13:50 +0900 Subject: [PATCH 3/6] add maintainers for tier 2 riscv64 targets (baremetal only) --- src/doc/rustc/src/SUMMARY.md | 2 +- src/doc/rustc/src/platform-support.md | 6 +++--- ...m-unknown-none-elf.md => riscv64-unknown-none-elf.md} | 9 +++++++-- 3 files changed, 11 insertions(+), 6 deletions(-) rename src/doc/rustc/src/platform-support/{riscv64im-unknown-none-elf.md => riscv64-unknown-none-elf.md} (84%) diff --git a/src/doc/rustc/src/SUMMARY.md b/src/doc/rustc/src/SUMMARY.md index 953789648485b..211cd48440725 100644 --- a/src/doc/rustc/src/SUMMARY.md +++ b/src/doc/rustc/src/SUMMARY.md @@ -120,7 +120,7 @@ - [riscv32i\*-unknown-none-elf](platform-support/riscv32-unknown-none-elf.md) - [riscv32im-risc0-zkvm-elf](platform-support/riscv32im-risc0-zkvm-elf.md) - [riscv32imac-unknown-xous-elf](platform-support/riscv32imac-unknown-xous-elf.md) - - [riscv64im-unknown-none-elf](platform-support/riscv64im-unknown-none-elf.md) + - [riscv64*-unknown-none-elf](platform-support/riscv64-unknown-none-elf.md) - [riscv64gc-unknown-linux-gnu](platform-support/riscv64gc-unknown-linux-gnu.md) - [riscv64gc-unknown-linux-musl](platform-support/riscv64gc-unknown-linux-musl.md) - [riscv64a23-unknown-linux-gnu](platform-support/riscv64a23-unknown-linux-gnu.md) diff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md index 2321dec16b8eb..c7064a7e58245 100644 --- a/src/doc/rustc/src/platform-support.md +++ b/src/doc/rustc/src/platform-support.md @@ -202,8 +202,8 @@ target | std | notes [`riscv32imafc-unknown-none-elf`](platform-support/riscv32-unknown-none-elf.md) | * | Bare RISC-V (RV32IMAFC ISA) [`riscv32imc-unknown-none-elf`](platform-support/riscv32-unknown-none-elf.md) | * | Bare RISC-V (RV32IMC ISA) [`riscv64a23-unknown-linux-gnu`](platform-support/riscv64a23-unknown-linux-gnu.md) | ✓ | RISC-V Linux (kernel 6.8.0+, glibc 2.39) -`riscv64gc-unknown-none-elf` | * | Bare RISC-V (RV64IMAFDC ISA) -`riscv64imac-unknown-none-elf` | * | Bare RISC-V (RV64IMAC ISA) +[`riscv64gc-unknown-none-elf`](platform-support/riscv64-unknown-none-elf.md) | * | Bare RISC-V (RV64IMAFDC ISA) +[`riscv64imac-unknown-none-elf`](platform-support/riscv64-unknown-none-elf.md) | * | Bare RISC-V (RV64IMAC ISA) `sparc64-unknown-linux-gnu` | ✓ | SPARC Linux (kernel 4.4+, glibc 2.23) [`s390x-unknown-none-softfloat`](platform-support/s390x-unknown-none-softfloat.md) | * | Bare S390x (softfloat ABI) [`thumbv6m-none-eabi`](platform-support/thumbv6m-none-eabi.md) | * | Bare Armv6-M @@ -424,7 +424,7 @@ target | std | host | notes [`riscv64gc-unknown-nuttx-elf`](platform-support/nuttx.md) | ✓ | | RISC-V 64bit with NuttX [`riscv64gc-unknown-openbsd`](platform-support/openbsd.md) | ✓ | ✓ | OpenBSD/riscv64 [`riscv64gc-unknown-redox`](platform-support/redox.md) | ✓ | | RISC-V 64bit Redox OS -[`riscv64im-unknown-none-elf`](platform-support/riscv64im-unknown-none-elf.md) | * | | Bare RISC-V (RV64IM ISA) +[`riscv64im-unknown-none-elf`](platform-support/riscv64-unknown-none-elf.md) | * | | Bare RISC-V (RV64IM ISA) [`riscv64imac-unknown-nuttx-elf`](platform-support/nuttx.md) | ✓ | | RISC-V 64bit with NuttX [`s390x-unknown-linux-musl`](platform-support/s390x-unknown-linux-musl.md) | ✓ | | S390x Linux (kernel 3.2, musl 1.2.5) `sparc-unknown-linux-gnu` | ✓ | | 32-bit SPARC Linux diff --git a/src/doc/rustc/src/platform-support/riscv64im-unknown-none-elf.md b/src/doc/rustc/src/platform-support/riscv64-unknown-none-elf.md similarity index 84% rename from src/doc/rustc/src/platform-support/riscv64im-unknown-none-elf.md rename to src/doc/rustc/src/platform-support/riscv64-unknown-none-elf.md index 505810caa4254..fd44f242c3325 100644 --- a/src/doc/rustc/src/platform-support/riscv64im-unknown-none-elf.md +++ b/src/doc/rustc/src/platform-support/riscv64-unknown-none-elf.md @@ -1,4 +1,8 @@ -# `riscv64im-unknown-none-elf` +# `riscv64{im,imac,gc}-unknown-none-elf` + +**Tier: 2** + +Bare-metal target for RISC-V CPUs with the RV64IMAC and RV64GC ISAs. **Tier: 3** @@ -44,4 +48,5 @@ This is a cross-compiled `no-std` target, which must be run either in a simulato ## Cross-compilation toolchains and C code -This target supports C code. If interlinking with C or C++, you may need to use `riscv64-unknown-elf-gcc` with the appropriate `-march=rv64im -mabi=lp64` flags as a linker instead of `rust-lld`. +This target supports C code. If interlinking with C or C++, you may need to use `riscv64-unknown-elf-gcc` as a linker instead of `rust-lld`. On `riscv64im*` targets +without the `a` extension, the flags `-march=rv64im -mabi=lp64` may be needed. From 093a6f1ed714109cf438091cebaf622c8e16e93c Mon Sep 17 00:00:00 2001 From: TechnoPorg Date: Fri, 23 Oct 2026 09:15:58 -0400 Subject: [PATCH 4/6] fix: update rustix to version compatible with latest libc --- Cargo.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 73c7c8ab97e1c..a2172bdb51513 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2378,9 +2378,9 @@ dependencies = [ [[package]] name = "linux-raw-sys" -version = "0.11.0" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df1d3c3b53da64cf5760482273a98e575c651a67eec7f77df96b5b642de8f039" +checksum = "32a66949e030da00e8c7d4434b251670a91556f4144941d37452769c25d58a53" [[package]] name = "litemap" @@ -5191,9 +5191,9 @@ dependencies = [ [[package]] name = "rustix" -version = "1.1.2" +version = "1.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd15f8a2c5551a84d56efdc1cd049089e409ac19a3072d5037a17fd70719ff3e" +checksum = "891efababe418670775f199f0d233d84843c227a0949a883ce15b37c78d6629d" dependencies = [ "bitflags", "errno", From d42b8ca73583613970a22f9701872621ae18bf75 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gabriel=20Bj=C3=B8rnager=20Jensen?= Date: Fri, 23 Oct 2026 15:15:27 +0200 Subject: [PATCH 5/6] Add 'unchecked_disjoint_bitor' method to 'bool', 'i8', 'i16', 'i32', 'i64', 'i128', and 'isize'; Update existing 'unchecked_disjoint_bitor' docs; Add 'must_use' to 'unchecked_disjoint_bitor'; --- library/core/src/bool.rs | 48 +++++++++++++++++++++++++++++ library/core/src/num/int_macros.rs | 47 +++++++++++++++++++++++++--- library/core/src/num/uint_macros.rs | 40 +++++++++++------------- 3 files changed, 109 insertions(+), 26 deletions(-) diff --git a/library/core/src/bool.rs b/library/core/src/bool.rs index e4ca53b59323f..146efbdc549bf 100644 --- a/library/core/src/bool.rs +++ b/library/core/src/bool.rs @@ -1,6 +1,8 @@ //! impl bool {} +use crate::intrinsics; use crate::marker::Destruct; +use crate::ub_checks::assert_unsafe_precondition; impl bool { /// Returns `Some(t)` if the `bool` is [`true`](../std/keyword.true.html), @@ -157,4 +159,50 @@ impl bool { pub const fn toggle(&mut self) { *self = !*self; } + + /// Disjoint, bitwise or. Computes `self | rhs`, assuming at most one, true value. + /// + /// Practically, this requires that `self | rhs` and `self ^ rhs` both yield the + /// same result, allowing for any of the two to be emitted in codegen -- depending + /// on whichever is cheapest. + /// + /// # Examples + /// + /// ``` + /// #![feature(disjoint_bitor)] + /// + /// assert_eq!( + /// // SAFETY: Only one, true value is passed. + /// unsafe { false.unchecked_disjoint_bitor(true) }, + /// true, + /// ); + /// + /// assert_eq!( + /// // SAFETY: No true values are passed. + /// unsafe { false.unchecked_disjoint_bitor(false) }, + /// false, + /// ); + /// ``` + /// + /// # Safety + /// + /// This results in undefined behaviour if both `self` and `rhs` are true. + #[unstable(feature = "disjoint_bitor", issue = "135758")] + #[rustc_const_unstable(feature = "disjoint_bitor", issue = "135758")] + #[must_use = "this returns the result of the operation, \ + without modifying the original"] + #[inline] + pub const unsafe fn unchecked_disjoint_bitor(self, rhs: Self) -> Self { + assert_unsafe_precondition!( + check_language_ub, + "bool::unchecked_disjoint_bitor cannot bitor two truths", + ( + lhs: bool = self, + rhs: bool = rhs, + ) => !(lhs & rhs), + ); + + // SAFETY: Same precondition. + unsafe { intrinsics::disjoint_bitor(self, rhs) } + } } diff --git a/library/core/src/num/int_macros.rs b/library/core/src/num/int_macros.rs index 058c0229aa530..ede69cb01c77a 100644 --- a/library/core/src/num/int_macros.rs +++ b/library/core/src/num/int_macros.rs @@ -1325,6 +1325,49 @@ macro_rules! int_impl { if b { imp::overflow_panic::rem() } else { a } } + /// Disjoint, bitwise or. Computes `self | rhs`, assuming no overlapping one bits. + /// + /// Practically, this requires that `self | rhs`, `self ^ rhs`, and `self + rhs` all + /// yield the same result, allowing for any of the three to be emitted in codegen -- + /// depending on whichever is cheapest. + /// + /// # Examples + /// + /// ``` + /// #![feature(disjoint_bitor)] + /// + /// assert_eq!( + /// // SAFETY: `1` and `-2` have no ones in common. + #[doc = concat!(" unsafe { 1_", stringify!($SelfT), ".unchecked_disjoint_bitor(-2) },")] + /// -1, + /// ); + /// ``` + /// + /// # Safety + /// + /// This results in undefined behaviour if `self` and `rhs` have any overlapping one + /// bits, i.e. `lhs & rhs` must be zero. + /// + /// Notably, this prevents both values from being negative. + #[unstable(feature = "disjoint_bitor", issue = "135758")] + #[rustc_const_unstable(feature = "disjoint_bitor", issue = "135758")] + #[must_use = "this returns the result of the operation, \ + without modifying the original"] + #[inline] + pub const unsafe fn unchecked_disjoint_bitor(self, rhs: Self) -> Self { + assert_unsafe_precondition!( + check_language_ub, + concat!(stringify!($SelfT), "::unchecked_disjoint_bitor cannot bitor overlapping ones"), + ( + lhs: $SelfT = self, + rhs: $SelfT = rhs, + ) => (lhs & rhs) == 0, + ); + + // SAFETY: Same precondition. + unsafe { intrinsics::disjoint_bitor(self, rhs) } + } + /// Checked negation. Computes `-self`, returning `None` if `self == MIN`. /// /// # Examples @@ -2929,7 +2972,6 @@ macro_rules! int_impl { } } - /// Overflowing Euclidean remainder. Calculates `self.rem_euclid(rhs)`. /// /// Returns a tuple of the remainder after dividing along with a boolean indicating whether an @@ -2959,7 +3001,6 @@ macro_rules! int_impl { } } - /// Negates self, overflowing if this is equal to the minimum value. /// /// Returns a tuple of the negated version of self along with a boolean indicating whether an overflow @@ -3217,7 +3258,6 @@ macro_rules! int_impl { q } - /// Calculates the least nonnegative remainder of `self` when /// divided by `rhs`. /// @@ -4061,7 +4101,6 @@ macro_rules! int_impl { traits::WidenTarget::internal_widen(self) } - /// Converts `self` to the target integer type, saturating at the numeric /// bounds instead of overflowing. /// diff --git a/library/core/src/num/uint_macros.rs b/library/core/src/num/uint_macros.rs index fcda1edcf4cb2..69352e9f3ed97 100644 --- a/library/core/src/num/uint_macros.rs +++ b/library/core/src/num/uint_macros.rs @@ -1737,48 +1737,45 @@ macro_rules! uint_impl { self % rhs } - /// Same value as `self | other`, but UB if any bit position is set in both inputs. + /// Disjoint, bitwise or. Computes `self | rhs`, assuming no overlapping one bits. /// - /// This is a situational micro-optimization for places where you'd rather - /// use addition on some platforms and bitwise or on other platforms, based - /// on exactly which instructions combine better with whatever else you're - /// doing. Note that there's no reason to bother using this for places - /// where it's clear from the operations involved that they can't overlap. - /// For example, if you're combining `u16`s into a `u32` with - /// `((a as u32) << 16) | (b as u32)`, that's fine, as the backend will - /// know those sides of the `|` are disjoint without needing help. + /// Practically, this requires that `self | rhs`, `self ^ rhs`, and `self + rhs` all + /// yield the same result, allowing for any of the three to be emitted in codegen -- + /// depending on whichever is cheapest. /// /// # Examples /// /// ``` /// #![feature(disjoint_bitor)] /// - /// // SAFETY: `1` and `4` have no bits in common. - /// unsafe { - #[doc = concat!(" assert_eq!(1_", stringify!($SelfT), ".unchecked_disjoint_bitor(4), 5);")] - /// } + /// assert_eq!( + /// // SAFETY: `1` and `4` have no ones in common. + #[doc = concat!(" unsafe { 1_", stringify!($SelfT), ".unchecked_disjoint_bitor(4) },")] + /// 5, + /// ); /// ``` /// /// # Safety /// - /// Requires that `(self & other) == 0`, otherwise it's immediate UB. - /// - /// Equivalently, requires that `(self | other) == (self + other)`. + /// This results in undefined behaviour if `self` and `rhs` have any overlapping one + /// bits, i.e. `lhs & rhs` must be zero. #[unstable(feature = "disjoint_bitor", issue = "135758")] #[rustc_const_unstable(feature = "disjoint_bitor", issue = "135758")] + #[must_use = "this returns the result of the operation, \ + without modifying the original"] #[inline] - pub const unsafe fn unchecked_disjoint_bitor(self, other: Self) -> Self { + pub const unsafe fn unchecked_disjoint_bitor(self, rhs: Self) -> Self { assert_unsafe_precondition!( check_language_ub, - concat!(stringify!($SelfT), "::unchecked_disjoint_bitor cannot have overlapping bits"), + concat!(stringify!($SelfT), "::unchecked_disjoint_bitor cannot bitor overlapping ones"), ( lhs: $SelfT = self, - rhs: $SelfT = other, + rhs: $SelfT = rhs, ) => (lhs & rhs) == 0, ); - // SAFETY: Same precondition - unsafe { intrinsics::disjoint_bitor(self, other) } + // SAFETY: Same precondition. + unsafe { intrinsics::disjoint_bitor(self, rhs) } } /// Returns the logarithm of the number with respect to an arbitrary base, @@ -3740,7 +3737,6 @@ macro_rules! uint_impl { self / rhs } - /// Calculates the least remainder of `self` when divided by /// `rhs`. /// From c84e3eff4179aea38fe3c0d7eeab92531df535d5 Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Sun, 18 Oct 2026 00:18:08 +0200 Subject: [PATCH 6/6] powerpc: support softfloat with c-variadic functions --- compiler/rustc_abi/src/lib.rs | 1 + compiler/rustc_codegen_llvm/src/va_arg.rs | 60 +++++---- tests/assembly-llvm/c-variadic/powerpc.rs | 156 +++++++++++++++------- 3 files changed, 144 insertions(+), 73 deletions(-) diff --git a/compiler/rustc_abi/src/lib.rs b/compiler/rustc_abi/src/lib.rs index ff62f04fff052..48c0c830325c4 100644 --- a/compiler/rustc_abi/src/lib.rs +++ b/compiler/rustc_abi/src/lib.rs @@ -1133,6 +1133,7 @@ impl fmt::Display for AlignFromBytesError { impl Align { pub const ONE: Align = Align { pow2: 0 }; + pub const FOUR: Align = Align { pow2: 2 }; pub const EIGHT: Align = Align { pow2: 3 }; // LLVM has a maximal supported alignment of 2^29, we inherit that. pub const MAX: Align = Align { pow2: 29 }; diff --git a/compiler/rustc_codegen_llvm/src/va_arg.rs b/compiler/rustc_codegen_llvm/src/va_arg.rs index 42df3e599267a..c74ea60ac11f3 100644 --- a/compiler/rustc_codegen_llvm/src/va_arg.rs +++ b/compiler/rustc_codegen_llvm/src/va_arg.rs @@ -9,7 +9,7 @@ use rustc_codegen_ssa::traits::{ use rustc_middle::ty::Ty; use rustc_middle::ty::layout::{HasTyCtxt, LayoutOf, TyAndLayout}; use rustc_span::bug; -use rustc_target::spec::{Arch, Env, LlvmAbi, RustcAbi}; +use rustc_target::spec::{Arch, Env, LlvmAbi, RustcAbi, Target}; use crate::builder::Builder; use crate::llvm::Value; @@ -97,7 +97,13 @@ fn get_param_type_alignment<'ll, 'tcx>( Primitive::Float(float) => match float { Float::F16 | Float::F16B | Float::F32 => unreachable!(), Float::F64 | Float::F128 => { /* fall through */ } - Float::PpcF128 => return Align::EIGHT, + Float::PpcF128 => { + return if is_powerpc_softfloat_abi(&bx.cx.tcx.sess.target) { + Align::FOUR + } else { + Align::EIGHT + }; + } }, Primitive::Pointer(_) => { /* fall through */ } }, @@ -222,7 +228,7 @@ fn emit_aapcs_va_arg<'ll, 'tcx>( let on_stack = bx.append_sibling_block("va_arg.on_stack"); let end = bx.append_sibling_block("va_arg.end"); let zero = bx.const_i32(0); - let offset_align = Align::from_bytes(4).unwrap(); + let offset_align = Align::FOUR; let gr_type = layout.ty.is_any_ptr() || layout.ty.is_integral(); let (reg_off, reg_top, slot_size) = if gr_type { @@ -291,6 +297,19 @@ fn emit_aapcs_va_arg<'ll, 'tcx>( val } +fn is_powerpc_softfloat_abi(target: &Target) -> bool { + if target.arch != Arch::PowerPC { + return false; + } + + match target.rustc_abi { + Some(RustcAbi::Softfloat) => bug!("there are currently no powerpc softfloat targets"), + Some(RustcAbi::PowerPcSpe) => true, // SPE is like softfloat in terms of ABI + None => false, + Some(other) => bug!("unexpected powerpc abi {other:?}"), + } +} + fn emit_powerpc_va_arg<'ll, 'tcx>( bx: &mut Builder<'_, 'll, 'tcx>, list: OperandRef<'tcx, &'ll Value>, @@ -310,26 +329,19 @@ fn emit_powerpc_va_arg<'ll, 'tcx>( // Peel off any newtype wrappers. let layout = layout.peel_transparent_wrappers_from_non_1zst(bx.cx); - // Rust does not currently support any powerpc softfloat targets. - // FIXME: however, the SPE targets are softfloat-like, and the current - // implementation doesn't handle them correctly. - let target = &bx.cx.tcx.sess.target; - let is_soft_float_abi = target.rustc_abi == Some(RustcAbi::Softfloat); - assert!(!is_soft_float_abi); - // All instances of VaArgSafe are passed directly. let is_indirect = false; - let (is_i64, is_int, is_f64) = match layout.layout.backend_repr() { + let is_int = match layout.layout.backend_repr() { BackendRepr::Scalar(scalar) => match scalar.primitive() { - rustc_abi::Primitive::Int(integer, _) => (integer.size().bits() == 64, true, false), - rustc_abi::Primitive::Float(float) => (false, false, matches!(float, Float::F64)), - rustc_abi::Primitive::Pointer(_) => (false, true, false), + rustc_abi::Primitive::Int(_, _) | rustc_abi::Primitive::Pointer(_) => true, + rustc_abi::Primitive::Float(_) => false, }, _ => unreachable!("all instances of VaArgSafe are represented as scalars"), }; - let is_passed_in_fprs = !(is_int || is_soft_float_abi); + let is_passed_in_fprs = !(is_int || is_powerpc_softfloat_abi(&bx.cx.tcx.sess.target)); + let num_regs_addr = if !is_passed_in_fprs { va_list_addr // gpr } else { @@ -339,7 +351,7 @@ fn emit_powerpc_va_arg<'ll, 'tcx>( let mut num_regs = bx.load(bx.type_i8(), num_regs_addr, dl.i8_align); // "Align" the register count when the type is passed as `i64`. - if is_i64 || (is_f64 && is_soft_float_abi) { + if layout.size.bytes() == 8 && !is_passed_in_fprs { num_regs = bx.add(num_regs, bx.const_u8(1)); num_regs = bx.and(num_regs, bx.const_u8(0b1111_1110)); } @@ -388,7 +400,7 @@ fn emit_powerpc_va_arg<'ll, 'tcx>( bx.store(bx.const_u8(max_regs), num_regs_addr, dl.i8_align); // Everything in the overflow area is rounded up to a size of at least 4. - let overflow_area_align = Align::from_bytes(4).unwrap(); + let overflow_area_align = Align::FOUR; let size = if !is_indirect { layout.layout.size.align_to(overflow_area_align) @@ -625,8 +637,8 @@ fn emit_x86_64_sysv64_va_arg<'ll, 'tcx>( let gp_offset_ptr = va_list_addr; let fp_offset_ptr = bx.inbounds_ptradd(va_list_addr, bx.cx.const_usize(unsigned_int_offset)); - let gp_offset_v = bx.load(bx.type_i32(), gp_offset_ptr, Align::from_bytes(8).unwrap()); - let fp_offset_v = bx.load(bx.type_i32(), fp_offset_ptr, Align::from_bytes(4).unwrap()); + let gp_offset_v = bx.load(bx.type_i32(), gp_offset_ptr, Align::EIGHT); + let fp_offset_v = bx.load(bx.type_i32(), fp_offset_ptr, Align::FOUR); let mut use_regs = bx.const_bool(false); @@ -759,7 +771,7 @@ fn emit_x86_64_sysv64_va_arg<'ll, 'tcx>( if num_fp_registers > 0 { let offset = bx.const_u32(num_fp_registers * 16); let sum = bx.add(fp_offset_v, offset); - bx.store(sum, fp_offset_ptr, Align::from_bytes(4).unwrap()); + bx.store(sum, fp_offset_ptr, Align::FOUR); } bx.br(end); @@ -872,11 +884,7 @@ fn emit_hexagon_va_arg_musl<'ll, 'tcx>( // Align current pointer based on argument type size (following LLVM's implementation) // Arguments <= 32 bits (4 bytes) use 4-byte alignment, > 32 bits use 8-byte alignment let type_size_bits = layout.size.bits(); - let arg_align = if type_size_bits > 32 { - Align::from_bytes(8).unwrap() - } else { - Align::from_bytes(4).unwrap() - }; + let arg_align = if type_size_bits > 32 { Align::EIGHT } else { Align::FOUR }; let aligned_current = round_pointer_up_to_alignment(bx, current_ptr, arg_align); // Calculate next pointer position (following LLVM's logic) @@ -991,7 +999,7 @@ fn emit_xtensa_va_arg<'ll, 'tcx>( let offset = bx.load(bx.type_i32(), offset_ptr, bx.tcx().data_layout.i32_align); let offset = round_up_to_alignment(bx, offset, layout.align.abi); - let slot_size = layout.size.align_to(Align::from_bytes(4).unwrap()).bytes() as i32; + let slot_size = layout.size.align_to(Align::FOUR).bytes() as i32; // Update the offset in va_list, by adding the slot's size. let offset_next = bx.add(offset, bx.const_i32(slot_size)); diff --git a/tests/assembly-llvm/c-variadic/powerpc.rs b/tests/assembly-llvm/c-variadic/powerpc.rs index ca97836d4e695..00c420c55be88 100644 --- a/tests/assembly-llvm/c-variadic/powerpc.rs +++ b/tests/assembly-llvm/c-variadic/powerpc.rs @@ -1,9 +1,13 @@ //@ add-minicore //@ assembly-output: emit-asm // -//@ revisions: POWERPC POWERPC64 POWERPC64LE AIX +//@ revisions: POWERPC SPE POWERPC64 POWERPC64LE AIX //@ [POWERPC] compile-flags: -Copt-level=3 --target powerpc-unknown-linux-gnu //@ [POWERPC] needs-llvm-components: powerpc +//@ [POWERPC] filecheck-flags: --check-prefix PPC32 +//@ [SPE] compile-flags: -Copt-level=3 --target powerpc-unknown-linux-gnuspe +//@ [SPE] needs-llvm-components: powerpc +//@ [SPE] filecheck-flags: --check-prefix PPC32 //@ [POWERPC64] compile-flags: -Copt-level=3 --target powerpc64-unknown-linux-gnu //@ [POWERPC64] needs-llvm-components: powerpc //@ [POWERPC64LE] compile-flags: -Copt-level=3 --target powerpc64le-unknown-linux-gnu @@ -50,6 +54,32 @@ unsafe extern "C" fn read_f64(ap: &mut VaList<'_>) -> f64 { // POWERPC-NEXT: stb 5, 1(3) // POWERPC-NEXT: blr // + // SPE: lbz 4, 0(3) + // SPE-NEXT: addi 4, 4, 1 + // SPE-NEXT: rlwinm 5, 4, 0, 24, 30 + // SPE-NEXT: cmplwi 5, 6 + // SPE-NEXT: bgt 0, .LBB0_2 + // SPE-NEXT: lwz 5, 8(3) + // SPE-NEXT: rlwinm 6, 4, 0, 0, 30 + // SPE-NEXT: rlwinm 4, 4, 2, 24, 28 + // SPE-NEXT: add 4, 5, 4 + // SPE-NEXT: addi 5, 6, 2 + // SPE-NEXT: evldd 4, 0(4) + // SPE-NEXT: stb 5, 0(3) + // SPE-NEXT: evmergehi 3, 4, 4 + // SPE-NEXT: blr + // SPE-NEXT: .LBB0_2: + // SPE-NEXT: lwz 4, 4(3) + // SPE-NEXT: addi 4, 4, 7 + // SPE-NEXT: rlwinm 4, 4, 0, 0, 28 + // SPE-NEXT: addi 5, 4, 8 + // SPE-NEXT: stw 5, 4(3) + // SPE-NEXT: li 5, 8 + // SPE-NEXT: evldd 4, 0(4) + // SPE-NEXT: stb 5, 0(3) + // SPE-NEXT: evmergehi 3, 4, 4 + // SPE-NEXT: blr + // // POWERPC64: ld 4, 0(3) // POWERPC64-NEXT: lfd 1, 0(4) // POWERPC64-NEXT: addi 4, 4, 8 @@ -74,25 +104,25 @@ unsafe extern "C" fn read_f64(ap: &mut VaList<'_>) -> f64 { unsafe extern "C" fn read_i32(ap: &mut VaList<'_>) -> i32 { // CHECK-LABEL: read_i32 // - // POWERPC: lbz 5, 0(3) - // POWERPC-NEXT: mr 4, 3 - // POWERPC-NEXT: cmplwi 5, 7 - // POWERPC-NEXT: bgt 0, .LBB1_2 - // POWERPC-NEXT: lwz 3, 8(4) - // POWERPC-NEXT: rlwinm 6, 5, 2, 24, 29 - // POWERPC-NEXT: addi 5, 5, 1 - // POWERPC-NEXT: add 3, 3, 6 - // POWERPC-NEXT: lwz 3, 0(3) - // POWERPC-NEXT: stb 5, 0(4) - // POWERPC-NEXT: blr - // POWERPC-NEXT: .LBB1_2: - // POWERPC-NEXT: lwz 3, 4(4) - // POWERPC-NEXT: addi 5, 3, 4 - // POWERPC-NEXT: stw 5, 4(4) - // POWERPC-NEXT: li 5, 8 - // POWERPC-NEXT: lwz 3, 0(3) - // POWERPC-NEXT: stb 5, 0(4) - // POWERPC-NEXT: blr + // PPC32: lbz 5, 0(3) + // PPC32-NEXT: mr 4, 3 + // PPC32-NEXT: cmplwi 5, 7 + // PPC32-NEXT: bgt 0, .LBB1_2 + // PPC32-NEXT: lwz 3, 8(4) + // PPC32-NEXT: rlwinm 6, 5, 2, 24, 29 + // PPC32-NEXT: addi 5, 5, 1 + // PPC32-NEXT: add 3, 3, 6 + // PPC32-NEXT: lwz 3, 0(3) + // PPC32-NEXT: stb 5, 0(4) + // PPC32-NEXT: blr + // PPC32-NEXT: .LBB1_2: + // PPC32-NEXT: lwz 3, 4(4) + // PPC32-NEXT: addi 5, 3, 4 + // PPC32-NEXT: stw 5, 4(4) + // PPC32-NEXT: li 5, 8 + // PPC32-NEXT: lwz 3, 0(3) + // PPC32-NEXT: stb 5, 0(4) + // PPC32-NEXT: blr // // POWERPC64: ld 5, 0(3) // POWERPC64-NEXT: mr 4, 3 @@ -119,32 +149,32 @@ unsafe extern "C" fn read_i32(ap: &mut VaList<'_>) -> i32 { unsafe extern "C" fn read_i64(ap: &mut VaList<'_>) -> i64 { // CHECK-LABEL: read_i64 // - // POWERPC: mr 5, 3 - // POWERPC-NEXT: lbz 3, 0(3) - // POWERPC-NEXT: addi 3, 3, 1 - // POWERPC-NEXT: rlwinm 4, 3, 0, 24, 30 - // POWERPC-NEXT: cmplwi 4, 6 - // POWERPC-NEXT: bgt 0, .LBB2_2 - // POWERPC-NEXT: lwz 4, 8(5) - // POWERPC-NEXT: rlwinm 6, 3, 0, 0, 30 - // POWERPC-NEXT: rlwinm 3, 3, 2, 24, 28 - // POWERPC-NEXT: addi 6, 6, 2 - // POWERPC-NEXT: add 4, 4, 3 - // POWERPC-NEXT: lwz 3, 0(4) - // POWERPC-NEXT: lwz 4, 4(4) - // POWERPC-NEXT: stb 6, 0(5) - // POWERPC-NEXT: blr - // POWERPC-NEXT: .LBB2_2: - // POWERPC-NEXT: lwz 3, 4(5) - // POWERPC-NEXT: li 6, 8 - // POWERPC-NEXT: addi 3, 3, 7 - // POWERPC-NEXT: rlwinm 4, 3, 0, 0, 28 - // POWERPC-NEXT: addi 3, 4, 8 - // POWERPC-NEXT: stw 3, 4(5) - // POWERPC-NEXT: lwz 3, 0(4) - // POWERPC-NEXT: lwz 4, 4(4) - // POWERPC-NEXT: stb 6, 0(5) - // POWERPC-NEXT: blr + // PPC32: mr 5, 3 + // PPC32-NEXT: lbz 3, 0(3) + // PPC32-NEXT: addi 3, 3, 1 + // PPC32-NEXT: rlwinm 4, 3, 0, 24, 30 + // PPC32-NEXT: cmplwi 4, 6 + // PPC32-NEXT: bgt 0, .LBB2_2 + // PPC32-NEXT: lwz 4, 8(5) + // PPC32-NEXT: rlwinm 6, 3, 0, 0, 30 + // PPC32-NEXT: rlwinm 3, 3, 2, 24, 28 + // PPC32-NEXT: addi 6, 6, 2 + // PPC32-NEXT: add 4, 4, 3 + // PPC32-NEXT: lwz 3, 0(4) + // PPC32-NEXT: lwz 4, 4(4) + // PPC32-NEXT: stb 6, 0(5) + // PPC32-NEXT: blr + // PPC32-NEXT: .LBB2_2: + // PPC32-NEXT: lwz 3, 4(5) + // PPC32-NEXT: li 6, 8 + // PPC32-NEXT: addi 3, 3, 7 + // PPC32-NEXT: rlwinm 4, 3, 0, 0, 28 + // PPC32-NEXT: addi 3, 4, 8 + // PPC32-NEXT: stw 3, 4(5) + // PPC32-NEXT: lwz 3, 0(4) + // PPC32-NEXT: lwz 4, 4(4) + // PPC32-NEXT: stb 6, 0(5) + // PPC32-NEXT: blr // // POWERPC64: ld 5, 0(3) // POWERPC64-NEXT: mr 4, 3 @@ -257,6 +287,38 @@ unsafe extern "C" fn read_ppcf128(ap: &mut VaList<'_>) -> ppcf128 { // POWERPC-NEXT: addi 1, 1, 32 // POWERPC-NEXT: blr // + // SPE: stwu 1, -32(1) + // SPE: lbz 6, 0(4) + // SPE-NEXT: cmplwi 6, 4 + // SPE-NEXT: bgt 0, .LBB3_2 + // SPE-NEXT: lwz 5, 8(4) + // SPE-NEXT: rlwinm 7, 6, 2, 24, 29 + // SPE-NEXT: addi 6, 6, 4 + // SPE-NEXT: add 5, 5, 7 + // SPE-NEXT: b .LBB3_3 + // SPE-NEXT: .LBB3_2: + // SPE-NEXT: lwz 5, 4(4) + // SPE-NEXT: addi 6, 5, 16 + // SPE-NEXT: stw 6, 4(4) + // SPE-NEXT: li 6, 8 + // SPE-NEXT: .LBB3_3: + // SPE-NEXT: lwz 7, 4(5) + // SPE-NEXT: stb 6, 0(4) + // SPE-NEXT: li 6, 8 + // SPE-NEXT: stw 7, 20(1) + // SPE-NEXT: lwz 4, 0(5) + // SPE-NEXT: stw 4, 16(1) + // SPE-NEXT: lwz 4, 12(5) + // SPE-NEXT: stw 4, 28(1) + // SPE-NEXT: lwz 4, 8(5) + // SPE-NEXT: evldd 5, 16(1) + // SPE-NEXT: stw 4, 24(1) + // SPE-NEXT: evldd 4, 24(1) + // SPE-NEXT: evstddx 4, 3, 6 + // SPE-NEXT: evstdd 5, 0(3) + // SPE-NEXT: addi 1, 1, 32 + // SPE-NEXT: blr + // // POWERPC64: ld 4, 0(3) // POWERPC64-NEXT: lfd 1, 0(4) // POWERPC64-NEXT: lfd 2, 8(4) @@ -282,7 +344,7 @@ unsafe extern "C" fn read_ppcf128(ap: &mut VaList<'_>) -> ppcf128 { #[unsafe(no_mangle)] unsafe extern "C" fn read_ptr(ap: &mut VaList<'_>) -> *const u8 { - // POWERPC: read_ptr = read_i32 + // PPC32: read_ptr = read_i32 // POWERPC64: read_ptr = read_i64 // POWERPC64LE: read_ptr = read_i64 ap.next_arg()