Support clobber_abi and vector registers (clobber-only) in PowerPC inline assembly#131341
Support clobber_abi and vector registers (clobber-only) in PowerPC inline assembly#131341bors merged 1 commit intorust-lang:masterfrom
Conversation
|
Some changes occurred in compiler/rustc_codegen_gcc |
This comment has been minimized.
This comment has been minimized.
76500b8 to
fc3dc84
Compare
|
|
||
| // v0-v19 | ||
| // FIXME: PPC32 SysV ABI does not mention vector registers processing. | ||
| // https://refspecs.linuxfoundation.org/elf/elfspec_ppc.pdf | ||
| v0, v1, v2, v3, v4, v5, v6, v7, | ||
| v8, v9, v10, v11, v12, v13, v14, | ||
| v15, v16, v17, v18, v19, |
There was a problem hiding this comment.
The reason I did not treat these as clobbered only on PPC64 is that the PPC32 ABI document I referenced was released at a time when Altivec/VMX did not exist, and I thought it might not reflect the final status of the PPC32 ABI.
In a similar case, the early ABI documents for s390x (e.g., the one mentioned here) do not mention vector registers, but the ABI documents since the addition of vector facility mention them and all are treated as volatile.
There was a problem hiding this comment.
According to Power Architecture 32-bit Application Binary Interface Supplement 1.0 - Linux & Embedded published in 2011, PPC32 has the same convention here as PPC64.
Therefore, we can just remove the FIXME comment here.
UPDATE: filed #132638
| // FIXME: In AIX, v20-v31 are reserved or nonvolatile depending on the mode. | ||
| // https://www.ibm.com/docs/en/aix/7.3?topic=concepts-aix-vector-programming |
There was a problem hiding this comment.
@ecnelises @bzEq: Is the default in Rust the default Vector enabled mode, as the name implies? Also, is there a way provided for the compiler to understand the current mode?
(If the first is yes and the second is no, it would be sufficient to simply reject the use of v20-v31 as reserved. If the first is no, this code is fine as is.)
There was a problem hiding this comment.
It should refer to vec-extabi, which is the default. See
Opened #131551 (which is based on this 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.) |
9fbedcb to
bad0db8
Compare
In fact, |
7eee8ce to
369edf1
Compare
|
Updated to check ABI in v20-v31 for AIX, and update def_regs to reflect the fact that r13 is not reserved on 32-bit AIX (see also LLVM's getReservedRegs). (32-bit AIX is currently not supported by rustc, although) |
f3a4182 to
d30a53e
Compare
| | MIPS | `$ra` | Return address cannot be used as inputs or outputs. | | ||
| | Hexagon | `lr` | This is the link register which cannot be used as an input or output. | | ||
| | PowerPC | `$r2`, `$r13` | These are system reserved registers. | | ||
| | PowerPC | `$r29`, `$r30` | These are used internally by LLVM. | |
There was a problem hiding this comment.
It's ok to not support these two registers conservasively IMO, might rephrase to These might be used as base pointer inside LLVM.
There was a problem hiding this comment.
I found a line that collectively describes registers in the same situation, so I moved these two there.
| | MIPS | `$28`/`$gp` | Global pointer cannot be used as inputs or outputs. | | ||
| | MIPS | `$ra` | Return address cannot be used as inputs or outputs. | | ||
| | Hexagon | `lr` | This is the link register which cannot be used as an input or output. | | ||
| | PowerPC | `$r2`, `$r13` | These are system reserved registers. | |
There was a problem hiding this comment.
nit: Separate r2 and r13.
r2 is used as TOC pointer.
r13 is system reserved register.
There was a problem hiding this comment.
| | Hexagon | `lr` | This is the link register which cannot be used as an input or output. | | ||
| | PowerPC | `$r2`, `$r13` | These are system reserved registers. | | ||
| | PowerPC | `$r29`, `$r30` | These are used internally by LLVM. | | ||
| | PowerPC | `lr` | The link register cannot be used as an input or output. | |
There was a problem hiding this comment.
I think xer should be not supported either and should occupy a line after lr.
There was a problem hiding this comment.
Currently, xer is supported as a clobber-only register.
See https://rust-lang.zulipchat.com/#narrow/stream/216763-project-inline-asm/topic/preserve_flags.20on.20OpenPower.2FPowerPC.3F/near/251292056 for more context.
There was a problem hiding this comment.
Cool, I thought these lines are for input or output operands. It makes sense xer as clobber operand since there are instructions changing the ca bit of xer.
0633ee4 to
cb969ca
Compare
|
I have no more comments and LGTM. |
Rollup of 9 pull requests Successful merges: - rust-lang#131153 (Improve duplicate derive Copy/Clone diagnostics) - rust-lang#131341 (Support clobber_abi and vector registers (clobber-only) in PowerPC inline assembly) - rust-lang#132025 (fix suggestion for diagnostic error E0027) - rust-lang#132153 (Stabilise `const_char_encode_utf16`.) - rust-lang#132303 (More tests for non-exhaustive C-like enums in FFI) - rust-lang#132473 ([core/fmt] Replace checked slice indexing by unchecked to support panic-free code) - rust-lang#132598 (Clippy: Move some attribute lints to be early pass (post expansion)) - rust-lang#132606 (Improve example of `impl Pattern for &[char]`) - rust-lang#132609 (docs: fix grammar in doc comment at unix/process.rs) r? `@ghost` `@rustbot` modify labels: rollup
|
☀️ Test successful - checks-actions |
|
Finished benchmarking commit (96477c5): comparison URL. Overall result: ❌ regressions - no action needed@rustbot label: -perf-regression Instruction countThis is the most reliable metric that we have; it was used to determine the overall result at the top of this comment. However, even this metric can sometimes exhibit noise.
Max RSS (memory usage)Results (primary 2.7%, secondary -0.7%)This is a less reliable metric that may be of interest but was not used to determine the overall result at the top of this comment.
CyclesThis benchmark run did not return any relevant results for this metric. Binary sizeThis benchmark run did not return any relevant results for this metric. Bootstrap: 780.214s -> 781.474s (0.16%) |
Remove fixme comment about clobber_abi on PowerPC This was considered an unresolved question in rust-lang#131341, but according to the ABI document published in 2011 by Power.org the current implementation is fine as-is. rust-lang#131341 (comment) > According to [Power Architecture 32-bit Application Binary Interface Supplement 1.0 - Linux & Embedded](https://web.archive.org/web/20120608163804/https://www.power.org/resources/downloads/Power-Arch-32-bit-ABI-supp-1.0-Unified.pdf) published in 2011, PPC32 has the same convention here as PPC64. > > Therefore, we can just remove the FIXME comment here. r? workingjubilee
Rollup merge of rust-lang#132638 - taiki-e:ppc-asm-fixme, r=jieyouxu Remove fixme comment about clobber_abi on PowerPC This was considered an unresolved question in rust-lang#131341, but according to the ABI document published in 2011 by Power.org the current implementation is fine as-is. rust-lang#131341 (comment) > According to [Power Architecture 32-bit Application Binary Interface Supplement 1.0 - Linux & Embedded](https://web.archive.org/web/20120608163804/https://www.power.org/resources/downloads/Power-Arch-32-bit-ABI-supp-1.0-Unified.pdf) published in 2011, PPC32 has the same convention here as PPC64. > > Therefore, we can just remove the FIXME comment here. r? workingjubilee
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 rust-lang/rust#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 rust-lang/rust#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](rust-lang/rust#131341 (comment))) 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](rust-lang/rust#131341 (comment)) 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](https://github.com/llvm/llvm-project/blob/6a6af0246bd2d68291582e9aefc0543e5c6102fe/llvm/lib/Target/PowerPC/PPCCallingConv.td#L322) and [GCC](https://github.com/gcc-mirror/gcc/blob/a9173a50e7e346a218323916e4d3add8552529ae/gcc/config/rs6000/rs6000.h#L859).
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 rust-lang/rust#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 rust-lang/rust#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](rust-lang/rust#131341 (comment))) 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](rust-lang/rust#131341 (comment)) 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](https://github.com/llvm/llvm-project/blob/6a6af0246bd2d68291582e9aefc0543e5c6102fe/llvm/lib/Target/PowerPC/PPCCallingConv.td#L322) and [GCC](https://github.com/gcc-mirror/gcc/blob/a9173a50e7e346a218323916e4d3add8552529ae/gcc/config/rs6000/rs6000.h#L859).
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 rust-lang/rust#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 rust-lang/rust#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](rust-lang/rust#131341 (comment))) 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](rust-lang/rust#131341 (comment)) 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](https://github.com/llvm/llvm-project/blob/6a6af0246bd2d68291582e9aefc0543e5c6102fe/llvm/lib/Target/PowerPC/PPCCallingConv.td#L322) and [GCC](https://github.com/gcc-mirror/gcc/blob/a9173a50e7e346a218323916e4d3add8552529ae/gcc/config/rs6000/rs6000.h#L859).
Support ctr and lr as clobber-only registers in PowerPC inline assembly Follow-up to rust-lang#131341. CTR and LR are marked as volatile in all ABIs, but I skipped them in rust-lang#131341 due to they are currently marked as reserved. https://github.com/rust-lang/rust/blob/dd7fda570040e8a736f7d8bc28ddd1b444aabc82/compiler/rustc_target/src/asm/powerpc.rs#L209-L212 However, they are actually only unusable as input/output of inline assembly, and should be fine to support as clobber-only registers as discussed in [#t-compiler > ppc/ppc64 inline asm support](https://rust-lang.zulipchat.com/#narrow/channel/131828-t-compiler/topic/ppc.2Fppc64.20inline.20asm.20support/with/540413845). r? `@Amanieu` or `@workingjubilee` cc `@programmerjake` `@rustbot` label +O-PowerPC +A-inline-assembly
Support ctr and lr as clobber-only registers in PowerPC inline assembly Follow-up to rust-lang#131341. CTR and LR are marked as volatile in all ABIs, but I skipped them in rust-lang#131341 due to they are currently marked as reserved. https://github.com/rust-lang/rust/blob/dd7fda570040e8a736f7d8bc28ddd1b444aabc82/compiler/rustc_target/src/asm/powerpc.rs#L209-L212 However, they are actually only unusable as input/output of inline assembly, and should be fine to support as clobber-only registers as discussed in [#t-compiler > ppc/ppc64 inline asm support](https://rust-lang.zulipchat.com/#narrow/channel/131828-t-compiler/topic/ppc.2Fppc64.20inline.20asm.20support/with/540413845). r? ``@Amanieu`` or ``@workingjubilee`` cc ``@programmerjake`` ``@rustbot`` label +O-PowerPC +A-inline-assembly
Support ctr and lr as clobber-only registers in PowerPC inline assembly Follow-up to rust-lang#131341. CTR and LR are marked as volatile in all ABIs, but I skipped them in rust-lang#131341 due to they are currently marked as reserved. https://github.com/rust-lang/rust/blob/dd7fda570040e8a736f7d8bc28ddd1b444aabc82/compiler/rustc_target/src/asm/powerpc.rs#L209-L212 However, they are actually only unusable as input/output of inline assembly, and should be fine to support as clobber-only registers as discussed in [#t-compiler > ppc/ppc64 inline asm support](https://rust-lang.zulipchat.com/#narrow/channel/131828-t-compiler/topic/ppc.2Fppc64.20inline.20asm.20support/with/540413845). r? ```@Amanieu``` or ```@workingjubilee``` cc ```@programmerjake``` ```@rustbot``` label +O-PowerPC +A-inline-assembly
Support ctr and lr as clobber-only registers in PowerPC inline assembly Follow-up to rust-lang#131341. CTR and LR are marked as volatile in all ABIs, but I skipped them in rust-lang#131341 due to they are currently marked as reserved. https://github.com/rust-lang/rust/blob/dd7fda570040e8a736f7d8bc28ddd1b444aabc82/compiler/rustc_target/src/asm/powerpc.rs#L209-L212 However, they are actually only unusable as input/output of inline assembly, and should be fine to support as clobber-only registers as discussed in [#t-compiler > ppc/ppc64 inline asm support](https://rust-lang.zulipchat.com/#narrow/channel/131828-t-compiler/topic/ppc.2Fppc64.20inline.20asm.20support/with/540413845). r? ````@Amanieu```` or ````@workingjubilee```` cc ````@programmerjake```` ````@rustbot```` label +O-PowerPC +A-inline-assembly
Rollup merge of #146831 - taiki-e:powerpc-clobber, r=Amanieu Support ctr and lr as clobber-only registers in PowerPC inline assembly Follow-up to #131341. CTR and LR are marked as volatile in all ABIs, but I skipped them in #131341 due to they are currently marked as reserved. https://github.com/rust-lang/rust/blob/dd7fda570040e8a736f7d8bc28ddd1b444aabc82/compiler/rustc_target/src/asm/powerpc.rs#L209-L212 However, they are actually only unusable as input/output of inline assembly, and should be fine to support as clobber-only registers as discussed in [#t-compiler > ppc/ppc64 inline asm support](https://rust-lang.zulipchat.com/#narrow/channel/131828-t-compiler/topic/ppc.2Fppc64.20inline.20asm.20support/with/540413845). r? ````@Amanieu```` or ````@workingjubilee```` cc ````@programmerjake```` ````@rustbot```` label +O-PowerPC +A-inline-assembly
Support ctr and lr as clobber-only registers in PowerPC inline assembly Follow-up to rust-lang#131341. CTR and LR are marked as volatile in all ABIs, but I skipped them in rust-lang#131341 due to they are currently marked as reserved. https://github.com/rust-lang/rust/blob/dd7fda570040e8a736f7d8bc28ddd1b444aabc82/compiler/rustc_target/src/asm/powerpc.rs#L209-L212 However, they are actually only unusable as input/output of inline assembly, and should be fine to support as clobber-only registers as discussed in [#t-compiler > ppc/ppc64 inline asm support](https://rust-lang.zulipchat.com/#narrow/channel/131828-t-compiler/topic/ppc.2Fppc64.20inline.20asm.20support/with/540413845). r? ````@Amanieu```` or ````@workingjubilee```` cc ````@programmerjake```` ````@rustbot```` label +O-PowerPC +A-inline-assembly
Support ctr and lr as clobber-only registers in PowerPC inline assembly Follow-up to rust-lang/rust#131341. CTR and LR are marked as volatile in all ABIs, but I skipped them in rust-lang/rust#131341 due to they are currently marked as reserved. https://github.com/rust-lang/rust/blob/dd7fda570040e8a736f7d8bc28ddd1b444aabc82/compiler/rustc_target/src/asm/powerpc.rs#L209-L212 However, they are actually only unusable as input/output of inline assembly, and should be fine to support as clobber-only registers as discussed in [#t-compiler > ppc/ppc64 inline asm support](https://rust-lang.zulipchat.com/#narrow/channel/131828-t-compiler/topic/ppc.2Fppc64.20inline.20asm.20support/with/540413845). r? ````@Amanieu```` or ````@workingjubilee```` cc ````@programmerjake```` ````@rustbot```` label +O-PowerPC +A-inline-assembly
Stabilize ppc inline assembly This stabilizes inline assembly for PowerPC and PowerPC64. Corresponding reference PR: rust-lang/reference#2056 --- From the requirements of stabilization mentioned in #93335 > Each architecture needs to be reviewed before stabilization: > * It must have clobber_abi. Done in #146949. > * It must be possible to clobber every register that is normally clobbered by a function call. Done in #131341 Similarly, `preserves_flags` is also implemented by this PR. Likewise, there is a non-code change to `preserve_flags` expectations that floating point and vector status and sticky bits are preserved. The reference manual update has more details. > * Generally review that the exposed register classes make sense. The followings can be used as input/output: * reg (`r0`, `r[3-12]`, `r[14-r28]`): Any usable general-purpose register * reg_nonzero (`r[3-12]`, `r[14-r28]`): General-purpose registers, but excludes `r0`. This is needed for instructions which define `r0` to be the value 0, such as register + immediate memory operations. * reg/reg_nonzero `r29` on PowerPC64 targets. * freg (`f[0-31]`): 64 bit floating pointer registers The following are clobber-only: * `ctr`, `lr`, `xer`: commonly clobbered special-purpose registers used in inline asm * `cr` (`cr[0-7]`, `cr`): the condition register fields, or the entire condition register. * `vreg` (`v[0-31]`): altivec/vmx register * `vsreg` (`vs[0-63]`): vector-scalar register * `spe_acc`: SPE accumulator, only available for PowerPC SPE targets. The vreg and vsreg registers technically accept `#[repr(simd)]` types, but require the experimental `altivec` or `vsx` target features to be enabled. That work seems to be tracked here, #42743. The following cannot be used as operands for inline asm: * `r2`: the TOC pointer, required for most PIC code. * `r13`: the TLS pointer * `r[29]`: Reserved for internal usage by LLVM on PowerPC * `r[30]`: Reserved for internal usage by LLVM on PowerPC and PowerPC64 * `r31`: the frame pointer * `vrsave`: this is effectively an unused special-purpose register. The `preserves_flags` behavior is updated with the following behavior (Note, this is not enforceable today due to LLVM restrictions): * All status and sticky bits of `fpscr`, `spefscr`, and `vscr` are preserved. The following registers are unavailable: * `mma[0-7]`: These are new "registers" available on Power10, they are 512b registers which overlay 4x vsx registers. If needed, users can mark such clobbers as vsN*4, vsN*4+1,...,vsN*4+3. * `ap`: This is actually a pseudo-register in gcc/llvm. * `mq`: This register is only available on Power1 and Power2, and is not supported by llvm. --- cc @taiki-e r? @Amanieu @rustbot label +A-inline-assembly
… r=Amanieu Stabilize ppc inline assembly This stabilizes inline assembly for PowerPC and PowerPC64. Corresponding reference PR: rust-lang/reference#2056 --- From the requirements of stabilization mentioned in rust-lang#93335 > Each architecture needs to be reviewed before stabilization: > * It must have clobber_abi. Done in rust-lang#146949. > * It must be possible to clobber every register that is normally clobbered by a function call. Done in rust-lang#131341 Similarly, `preserves_flags` is also implemented by this PR. Likewise, there is a non-code change to `preserve_flags` expectations that floating point and vector status and sticky bits are preserved. The reference manual update has more details. > * Generally review that the exposed register classes make sense. The followings can be used as input/output: * reg (`r0`, `r[3-12]`, `r[14-r28]`): Any usable general-purpose register * reg_nonzero (`r[3-12]`, `r[14-r28]`): General-purpose registers, but excludes `r0`. This is needed for instructions which define `r0` to be the value 0, such as register + immediate memory operations. * reg/reg_nonzero `r29` on PowerPC64 targets. * freg (`f[0-31]`): 64 bit floating pointer registers The following are clobber-only: * `ctr`, `lr`, `xer`: commonly clobbered special-purpose registers used in inline asm * `cr` (`cr[0-7]`, `cr`): the condition register fields, or the entire condition register. * `vreg` (`v[0-31]`): altivec/vmx register * `vsreg` (`vs[0-63]`): vector-scalar register * `spe_acc`: SPE accumulator, only available for PowerPC SPE targets. The vreg and vsreg registers technically accept `#[repr(simd)]` types, but require the experimental `altivec` or `vsx` target features to be enabled. That work seems to be tracked here, rust-lang#42743. The following cannot be used as operands for inline asm: * `r2`: the TOC pointer, required for most PIC code. * `r13`: the TLS pointer * `r[29]`: Reserved for internal usage by LLVM on PowerPC * `r[30]`: Reserved for internal usage by LLVM on PowerPC and PowerPC64 * `r31`: the frame pointer * `vrsave`: this is effectively an unused special-purpose register. The `preserves_flags` behavior is updated with the following behavior (Note, this is not enforceable today due to LLVM restrictions): * All status and sticky bits of `fpscr`, `spefscr`, and `vscr` are preserved. The following registers are unavailable: * `mma[0-7]`: These are new "registers" available on Power10, they are 512b registers which overlay 4x vsx registers. If needed, users can mark such clobbers as vsN*4, vsN*4+1,...,vsN*4+3. * `ap`: This is actually a pseudo-register in gcc/llvm. * `mq`: This register is only available on Power1 and Power2, and is not supported by llvm. --- cc @taiki-e r? @Amanieu @rustbot label +A-inline-assembly
Rollup merge of #147996 - pmur:murp/stabilize-ppc-inlineasm, r=Amanieu Stabilize ppc inline assembly This stabilizes inline assembly for PowerPC and PowerPC64. Corresponding reference PR: rust-lang/reference#2056 --- From the requirements of stabilization mentioned in #93335 > Each architecture needs to be reviewed before stabilization: > * It must have clobber_abi. Done in #146949. > * It must be possible to clobber every register that is normally clobbered by a function call. Done in #131341 Similarly, `preserves_flags` is also implemented by this PR. Likewise, there is a non-code change to `preserve_flags` expectations that floating point and vector status and sticky bits are preserved. The reference manual update has more details. > * Generally review that the exposed register classes make sense. The followings can be used as input/output: * reg (`r0`, `r[3-12]`, `r[14-r28]`): Any usable general-purpose register * reg_nonzero (`r[3-12]`, `r[14-r28]`): General-purpose registers, but excludes `r0`. This is needed for instructions which define `r0` to be the value 0, such as register + immediate memory operations. * reg/reg_nonzero `r29` on PowerPC64 targets. * freg (`f[0-31]`): 64 bit floating pointer registers The following are clobber-only: * `ctr`, `lr`, `xer`: commonly clobbered special-purpose registers used in inline asm * `cr` (`cr[0-7]`, `cr`): the condition register fields, or the entire condition register. * `vreg` (`v[0-31]`): altivec/vmx register * `vsreg` (`vs[0-63]`): vector-scalar register * `spe_acc`: SPE accumulator, only available for PowerPC SPE targets. The vreg and vsreg registers technically accept `#[repr(simd)]` types, but require the experimental `altivec` or `vsx` target features to be enabled. That work seems to be tracked here, #42743. The following cannot be used as operands for inline asm: * `r2`: the TOC pointer, required for most PIC code. * `r13`: the TLS pointer * `r[29]`: Reserved for internal usage by LLVM on PowerPC * `r[30]`: Reserved for internal usage by LLVM on PowerPC and PowerPC64 * `r31`: the frame pointer * `vrsave`: this is effectively an unused special-purpose register. The `preserves_flags` behavior is updated with the following behavior (Note, this is not enforceable today due to LLVM restrictions): * All status and sticky bits of `fpscr`, `spefscr`, and `vscr` are preserved. The following registers are unavailable: * `mma[0-7]`: These are new "registers" available on Power10, they are 512b registers which overlay 4x vsx registers. If needed, users can mark such clobbers as vsN*4, vsN*4+1,...,vsN*4+3. * `ap`: This is actually a pseudo-register in gcc/llvm. * `mq`: This register is only available on Power1 and Power2, and is not supported by llvm. --- cc @taiki-e r? @Amanieu @rustbot label +A-inline-assembly
Stabilize ppc inline assembly This stabilizes inline assembly for PowerPC and PowerPC64. Corresponding reference PR: rust-lang/reference#2056 --- From the requirements of stabilization mentioned in rust-lang/rust#93335 > Each architecture needs to be reviewed before stabilization: > * It must have clobber_abi. Done in rust-lang/rust#146949. > * It must be possible to clobber every register that is normally clobbered by a function call. Done in rust-lang/rust#131341 Similarly, `preserves_flags` is also implemented by this PR. Likewise, there is a non-code change to `preserve_flags` expectations that floating point and vector status and sticky bits are preserved. The reference manual update has more details. > * Generally review that the exposed register classes make sense. The followings can be used as input/output: * reg (`r0`, `r[3-12]`, `r[14-r28]`): Any usable general-purpose register * reg_nonzero (`r[3-12]`, `r[14-r28]`): General-purpose registers, but excludes `r0`. This is needed for instructions which define `r0` to be the value 0, such as register + immediate memory operations. * reg/reg_nonzero `r29` on PowerPC64 targets. * freg (`f[0-31]`): 64 bit floating pointer registers The following are clobber-only: * `ctr`, `lr`, `xer`: commonly clobbered special-purpose registers used in inline asm * `cr` (`cr[0-7]`, `cr`): the condition register fields, or the entire condition register. * `vreg` (`v[0-31]`): altivec/vmx register * `vsreg` (`vs[0-63]`): vector-scalar register * `spe_acc`: SPE accumulator, only available for PowerPC SPE targets. The vreg and vsreg registers technically accept `#[repr(simd)]` types, but require the experimental `altivec` or `vsx` target features to be enabled. That work seems to be tracked here, rust-lang/rust#42743. The following cannot be used as operands for inline asm: * `r2`: the TOC pointer, required for most PIC code. * `r13`: the TLS pointer * `r[29]`: Reserved for internal usage by LLVM on PowerPC * `r[30]`: Reserved for internal usage by LLVM on PowerPC and PowerPC64 * `r31`: the frame pointer * `vrsave`: this is effectively an unused special-purpose register. The `preserves_flags` behavior is updated with the following behavior (Note, this is not enforceable today due to LLVM restrictions): * All status and sticky bits of `fpscr`, `spefscr`, and `vscr` are preserved. The following registers are unavailable: * `mma[0-7]`: These are new "registers" available on Power10, they are 512b registers which overlay 4x vsx registers. If needed, users can mark such clobbers as vsN*4, vsN*4+1,...,vsN*4+3. * `ap`: This is actually a pseudo-register in gcc/llvm. * `mq`: This register is only available on Power1 and Power2, and is not supported by llvm. --- cc @taiki-e r? @Amanieu @rustbot label +A-inline-assembly
This supports
clobber_abiwhich is one of the requirements of stabilization mentioned in #93335.This basically does a similar thing I did in #130630 to implement
clobber_abifor s390x, but for powerpc/powerpc64/powerpc64le.vreg) as clobber-only, which need to support clobbering of them to implementclobber_abi.vregshould be able to accept#[repr(simd)]types as input/output if the unstablealtivectarget feature is enabled, butcore::arch::{powerpc,powerpc64}vector types,#[repr(simd)], andcore::simdare 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.Refs:
EDIT: this document is old; See section 3.2 "Function Calling Sequence" in Power Architecture 32-bit Application Binary Interface Supplement 1.0 - Linux & Embedded instead. (Remove fixme comment about clobber_abi on PowerPC #132638)
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
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, we are using vec-extabi) in AIX:
I left FIXME comment about PPC32 SysV 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_flagsrather thanclobber_abiif 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
Footnotes
callee-saved, according to LLVM and GCC. ↩