96477c55bc
Support clobber_abi and vector registers (clobber-only) in PowerPC inline assembly This supports `clobber_abi` which is one of the requirements of stabilization mentioned in #93335. This basically does a similar thing I did in https://github.com/rust-lang/rust/pull/130630 to implement `clobber_abi` for s390x, but for powerpc/powerpc64/powerpc64le. - This also supports vector registers (as `vreg`) as clobber-only, which need to support clobbering of them to implement `clobber_abi`. - `vreg` should be able to accept `#[repr(simd)]` types as input/output if the unstable `altivec` target feature is enabled, but `core::arch::{powerpc,powerpc64}` vector types, `#[repr(simd)]`, and `core::simd` are all unstable, so the fact that this is currently a clobber-only should not be considered a blocker of clobber_abi implementation or stabilization. So I have not implemented it in this PR. - See https://github.com/rust-lang/rust/pull/131551 (which is based on this PR) for a PR to implement this. - (I'm not sticking to whether that PR should be a separate PR or part of this PR, so I can merge that PR into this PR if needed.) Refs: - PPC32 SysV: Section "Function Calling Sequence" in [System V Application Binary Interface PowerPC Processor Supplement](https://refspecs.linuxfoundation.org/elf/elfspec_ppc.pdf) - PPC64 ELFv1: Section 3.2 "Function Calling Sequence" in [64-bit PowerPC ELF Application Binary Interface Supplement](https://refspecs.linuxfoundation.org/ELF/ppc64/PPC-elf64abi.html#FUNC-CALL) - PPC64 ELFv2: Section 2.2 "Function Calling Sequence" in [64-Bit ELF V2 ABI Specification](https://openpowerfoundation.org/specifications/64bitelfabi/) - AIX: [Register usage and conventions](https://www.ibm.com/docs/en/aix/7.3?topic=overview-register-usage-conventions), [Special registers in the PowerPC®](https://www.ibm.com/docs/en/aix/7.3?topic=overview-special-registers-in-powerpc), [AIX vector programming](https://www.ibm.com/docs/en/aix/7.3?topic=concepts-aix-vector-programming) - Register definition in LLVM: https://github.com/llvm/llvm-project/blob/llvmorg-19.1.0/llvm/lib/Target/PowerPC/PPCRegisterInfo.td#L189 If I understand the above four ABI documentations correctly, except for the PPC32 SysV's VR (Vector Registers) and 32-bit AIX (currently not supported by rustc)'s r13, there does not appear to be important differences in terms of implementing `clobber_abi`: - The above four ABIs are consistent about FPR (0-13: volatile, 14-31: nonvolatile), CR (0-1,5-7: volatile, 2-4: nonvolatile), XER (volatile), and CTR (volatile). - As for GPR, only the registers we are treating as reserved are slightly different - r0, r3-r12 are volatile - r1(sp, reserved), r14-31 are nonvolatile - r2(reserved) is TOC pointer in PPC64 ELF/AIX, system-reserved register in PPC32 SysV (AFAIK used as thread pointer in Linux/BSDs) - r13(reserved for non-32-bit-AIX) is thread pointer in PPC64 ELF, small data area pointer register in PPC32 SysV, "reserved under 64-bit environment; not restored across system calls[^r13]" in AIX) - As for FPSCR, volatile in PPC64 ELFv1/AIX, some fields are volatile only in certain situations (rest are volatile) in PPC32 SysV/PPC64 ELFv2. - As for VR (Vector Registers), it is not mentioned in PPC32 SysV, v0-v19 are volatile in both in PPC64 ELF/AIX, v20-v31 are nonvolatile in PPC64 ELF, reserved or nonvolatile depending on the ABI ([vec-extabi vs vec-default in LLVM](https://reviews.llvm.org/D89684), we are [using vec-extabi](https://github.com/rust-lang/rust/pull/131341#discussion_r1797693299)) in AIX: > When the default Vector enabled mode is used, these registers are reserved and must not be used. > In the extended ABI vector enabled mode, these registers are nonvolatile and their values are preserved across function calls I left [FIXME comment about PPC32 SysV](https://github.com/rust-lang/rust/pull/131341#discussion_r1790496095) and added ABI check for AIX. - As for VRSAVE, it is not mentioned in PPC32 SysV, nonvolatile in PPC64 ELFv1, reserved in PPC64 ELFv2/AIX - As for VSCR, it is not mentioned in PPC32 SysV/PPC64 ELFv1, some fields are volatile only in certain situations (rest are volatile) in PPC64 ELFv2, volatile in AIX We are currently treating r1-r2, r13 (non-32-bit-AIX), r29-r31, LR, CTR, and VRSAVE as reserved. We are currently not processing anything about FPSCR and VSCR, but I feel those are things that should be processed by `preserves_flags` rather than `clobber_abi` if we need to do something about them. (However, PPCRegisterInfo.td in LLVM does not seem to define anything about them.) Replaces #111335 and #124279 cc `@ecnelises` `@bzEq` `@lu-zero` r? `@Amanieu` `@rustbot` label +O-PowerPC +A-inline-assembly [^r13]: callee-saved, according to [LLVM]( |
||
---|---|---|
.. | ||
aarch64 | ||
powerpc | ||
riscv | ||
s390x | ||
x86_64 | ||
arm-low-dreg.rs | ||
bad-arch.rs | ||
bad-arch.stderr | ||
bad-template.aarch64.stderr | ||
bad-template.rs | ||
bad-template.x86_64.stderr | ||
binary_asm_labels_allowed.rs | ||
binary_asm_labels.rs | ||
binary_asm_labels.stderr | ||
const-error.rs | ||
const-refs-to-static.rs | ||
const-refs-to-static.stderr | ||
empty_global_asm.rs | ||
fail-const-eval-issue-121099.rs | ||
fail-const-eval-issue-121099.stderr | ||
generic-const.rs | ||
ice-bad-err-span-in-template-129503.rs | ||
ice-bad-err-span-in-template-129503.stderr | ||
inline-syntax.arm.stderr | ||
inline-syntax.rs | ||
inline-syntax.x86_64.stderr | ||
invalid-const-operand.rs | ||
invalid-const-operand.stderr | ||
invalid-sym-operand.rs | ||
invalid-sym-operand.stderr | ||
issue-72570.rs | ||
issue-72570.stderr | ||
issue-85247.rs | ||
issue-85247.rwpi.stderr | ||
issue-87802.rs | ||
issue-87802.stderr | ||
issue-89305.rs | ||
issue-89305.stderr | ||
issue-92378.rs | ||
issue-97490.rs | ||
issue-99071.rs | ||
issue-99071.stderr | ||
issue-99122-2.rs | ||
issue-99122.rs | ||
issue-99122.stderr | ||
issue-113788.rs | ||
issue-113788.stderr | ||
may_unwind.rs | ||
naked-asm-outside-naked-fn.rs | ||
naked-asm-outside-naked-fn.stderr | ||
naked-functions-ffi.rs | ||
naked-functions-ffi.stderr | ||
naked-functions-inline.rs | ||
naked-functions-inline.stderr | ||
naked-functions-instruction-set.rs | ||
naked-functions-testattrs.rs | ||
naked-functions-testattrs.stderr | ||
naked-functions-unused.aarch64.stderr | ||
naked-functions-unused.rs | ||
naked-functions-unused.x86_64.stderr | ||
naked-functions.rs | ||
naked-functions.stderr | ||
naked-invalid-attr.rs | ||
naked-invalid-attr.stderr | ||
naked-with-invalid-repr-attr.rs | ||
naked-with-invalid-repr-attr.stderr | ||
named-asm-labels.rs | ||
named-asm-labels.s | ||
named-asm-labels.stderr | ||
non-const.rs | ||
non-const.stderr | ||
noreturn.rs | ||
parse-error.rs | ||
parse-error.stderr | ||
reg-conflict.rs | ||
reg-conflict.stderr | ||
simple_global_asm.rs | ||
type-check-1.rs | ||
type-check-1.stderr | ||
type-check-4.rs | ||
type-check-4.stderr | ||
unpretty-expanded.rs | ||
unpretty-expanded.stdout | ||
unsupported-option.fixed | ||
unsupported-option.rs | ||
unsupported-option.stderr |