-
Notifications
You must be signed in to change notification settings - Fork 12.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add asm clobbers for PPC / PPC64 #111335
The head ref may contain hidden characters: "ppc64_\u2663er"
Add asm clobbers for PPC / PPC64 #111335
Conversation
Thanks for the pull request, and welcome! The Rust team is excited to review your changes, and you should hear from @wesleywiser (or someone else) soon. Please see the contribution instructions for more information. Namely, in order to ensure the minimum review times lag, PR authors and assigned reviewers should ensure that the review label (
|
compiler/rustc_target/src/asm/mod.rs
Outdated
@@ -885,6 +886,10 @@ impl InlineAsmClobberAbi { | |||
"C" | "system" | "efiapi" => Ok(InlineAsmClobberAbi::LoongArch), | |||
_ => Err(&["C", "system", "efiapi"]), | |||
}, | |||
InlineAsmArch::PowerPC => match name { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You need to add PowerPC64
here as well if both use the same calling convention. If the registers are different then you need a separate 32-bit and 64-bit InlineAsmClobberAbi
.
You need to define the VMX registers in compiler/rustc_target/src/asm/powerpc.rs. You'll need to create a
See code comments.
All volatile registers need to be included. The point of |
This comment has been minimized.
This comment has been minimized.
Sorry, forgot pushing updates the PR. Still not done yet :) |
@@ -885,6 +886,10 @@ impl InlineAsmClobberAbi { | |||
"C" | "system" | "efiapi" => Ok(InlineAsmClobberAbi::LoongArch), | |||
_ => Err(&["C", "system", "efiapi"]), | |||
}, | |||
InlineAsmArch::PowerPC | InlineAsmArch::PowerPC64 => match name { | |||
"C" | "system" | "efiapi" => Ok(InlineAsmClobberAbi::PowerPC), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should not include efiapi
.
@@ -817,6 +818,12 @@ fn dummy_output_type<'ll>(cx: &CodegenCx<'ll, '_>, reg: InlineAsmRegClass) -> &' | |||
InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::reg) => cx.type_i32(), | |||
InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::reg_nonzero) => cx.type_i32(), | |||
InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::freg) => cx.type_f64(), | |||
InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::vreg) => { | |||
cx.type_vector(cx.type_i64(), 2) | |||
} //no clue if this is right :D |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is correct if the tests accept it! You'll need to extend the tests in tests/assembly/asm to include tests for vector regisers. Have a look at the AArch64/x86 tests for examples.
@@ -610,7 +610,8 @@ fn reg_to_gcc(reg: InlineAsmRegOrRegClass) -> ConstraintOrRegister { | |||
InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::reg) => "r", | |||
InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::reg_nonzero) => "b", | |||
InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::freg) => "f", | |||
InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::cr) | |||
InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::vreg) => "v", | |||
InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::cr)//should this not be either x or y ? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We are explicitly making these clobber-only for now. We can always revisit this later if needed.
@@ -47,6 +48,7 @@ impl PowerPCInlineAsmRegClass { | |||
} | |||
} | |||
Self::freg => types! { _: F32, F64; }, | |||
Self::vreg => todo!(), //not quite sure :) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this should be something like:
types! {
vsx: I8, I16, I32, I64, F32, F64,
altivec: VecI8(16), VecI16(8), VecI32(4), VecI64(2), VecF32(4), VecF64(2);
}
Altivec allows 128-bit vector types, and VSX allows using scalars in vector registers.
However this should be verified by writing asm tests that checks that LLVM is able to generate the correct code for these.
Should I make these tests in |
The tests should be added to |
@Richard-Rogalski any updates on this? |
bah, yeah, I should get back to this. I got a little lost, I'll try again when i get the time |
Closing this as inactive. Feel free to reöpen this pr or create a new pr if you get the time to work on this. Thanks |
@Richard-Rogalski - any chance you can get this over the line? |
I've gotten better at rust in the time since I started this PR. If i am recalling correctly, everything is done except for the tests :p I'll take another crack at this starting today @ky438 . |
Thank you! :)
…On Sun, May 26, 2024 at 07:42:29AM -0700, Richard-Rogalski wrote:
I've gotten better at rust in the time since I started this PR. If i am recalling correctly, everything is done except for the tests :p I'll take another crack at this starting today @ky438 .
--
Reply to this email directly or view it on GitHub:
#111335 (comment)
You are receiving this because you were mentioned.
Message ID: ***@***.***>
|
…rkingjubilee 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 rust-lang#93335. This basically does a similar thing I did in rust-lang#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#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#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#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 rust-lang#111335 and rust-lang#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).
…ingjubilee 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 rust-lang#93335. This basically does a similar thing I did in rust-lang#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#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#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#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 rust-lang#111335 and rust-lang#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).
Marking this as a draft as I have a few questions :D
For the VMX ones, I get
error[E0599]: no variant or associated item named 'v19' found for enum 'PowerPCInlineAsmReg' in the current scope
. I'm fairly new to rust, and can't quite figure out what's triggering this :). Also, should these be included, when they're not available on every power CPU?The second thing is this compiles without errors when I make the code specify PowerPC, but not when I make it for PowerPC64:
error[E0599]: no variant or associated item named 'PowerPC64' found for enum 'InlineAsmClobberAbi' in the current scope
. Some arches (like riscv) appear to use the same for 32bit and 64bit, while others have different clobbers for each. I'm pretty sure the registers correct for both 32 & 64 bit, but will PPC64 use this?The third thing is r11 and r12. They're both volatile but have 'special' uses.
I looked at other arches and their registers to see whether I should include these or not, but am unsure :).
@Amanieu