Auto merge of #148492 - pmur:murp/ppc-relax-r29-inlineasm, r=Amanieu
Relax r29 inline asm restriction on PowerPC64 targets LLVM uses r29 to hold a base pointer for some PowerPC target configurations. It is usable on all 64 bit targets as a callee save register. r? `@Amanieu`
This commit is contained in:
commit
53efb3d4f3
7 changed files with 31 additions and 34 deletions
|
|
@ -82,6 +82,20 @@ fn reserved_r13(
|
|||
}
|
||||
}
|
||||
|
||||
fn reserved_r29(
|
||||
arch: InlineAsmArch,
|
||||
_reloc_model: RelocModel,
|
||||
_target_features: &FxIndexSet<Symbol>,
|
||||
_target: &Target,
|
||||
_is_clobber: bool,
|
||||
) -> Result<(), &'static str> {
|
||||
if arch != InlineAsmArch::PowerPC {
|
||||
Ok(())
|
||||
} else {
|
||||
Err("r29 is used internally by LLVM and cannot be used as an operand for inline asm")
|
||||
}
|
||||
}
|
||||
|
||||
fn reserved_v20to31(
|
||||
_arch: InlineAsmArch,
|
||||
_reloc_model: RelocModel,
|
||||
|
|
@ -129,6 +143,7 @@ def_regs! {
|
|||
r26: reg, reg_nonzero = ["r26", "26"],
|
||||
r27: reg, reg_nonzero = ["r27", "27"],
|
||||
r28: reg, reg_nonzero = ["r28", "28"],
|
||||
r29: reg, reg_nonzero = ["r29", "29"] % reserved_r29,
|
||||
f0: freg = ["f0", "fr0"],
|
||||
f1: freg = ["f1", "fr1"],
|
||||
f2: freg = ["f2", "fr2"],
|
||||
|
|
@ -274,8 +289,6 @@ def_regs! {
|
|||
"the stack pointer cannot be used as an operand for inline asm",
|
||||
#error = ["r2", "2"] =>
|
||||
"r2 is a system reserved register and cannot be used as an operand for inline asm",
|
||||
#error = ["r29", "29"] =>
|
||||
"r29 is used internally by LLVM and cannot be used as an operand for inline asm",
|
||||
#error = ["r30", "30"] =>
|
||||
"r30 is used internally by LLVM and cannot be used as an operand for inline asm",
|
||||
#error = ["r31", "31", "fp"] =>
|
||||
|
|
@ -306,7 +319,7 @@ impl PowerPCInlineAsmReg {
|
|||
(r0, "0"), (r3, "3"), (r4, "4"), (r5, "5"), (r6, "6"), (r7, "7");
|
||||
(r8, "8"), (r9, "9"), (r10, "10"), (r11, "11"), (r12, "12"), (r13, "13"), (r14, "14"), (r15, "15");
|
||||
(r16, "16"), (r17, "17"), (r18, "18"), (r19, "19"), (r20, "20"), (r21, "21"), (r22, "22"), (r23, "23");
|
||||
(r24, "24"), (r25, "25"), (r26, "26"), (r27, "27"), (r28, "28");
|
||||
(r24, "24"), (r25, "25"), (r26, "26"), (r27, "27"), (r28, "28"), (r29, "29");
|
||||
(f0, "0"), (f1, "1"), (f2, "2"), (f3, "3"), (f4, "4"), (f5, "5"), (f6, "6"), (f7, "7");
|
||||
(f8, "8"), (f9, "9"), (f10, "10"), (f11, "11"), (f12, "12"), (f13, "13"), (f14, "14"), (f15, "15");
|
||||
(f16, "16"), (f17, "17"), (f18, "18"), (f19, "19"), (f20, "20"), (f21, "21"), (f22, "22"), (f23, "23");
|
||||
|
|
|
|||
|
|
@ -31,8 +31,8 @@ This feature tracks `asm!` and `global_asm!` support for the following architect
|
|||
| NVPTX | `reg64` | None\* | `l` |
|
||||
| Hexagon | `reg` | `r[0-28]` | `r` |
|
||||
| Hexagon | `preg` | `p[0-3]` | Only clobbers |
|
||||
| PowerPC | `reg` | `r0`, `r[3-12]`, `r[14-28]` | `r` |
|
||||
| PowerPC | `reg_nonzero` | `r[3-12]`, `r[14-28]` | `b` |
|
||||
| PowerPC | `reg` | `r0`, `r[3-12]`, `r[14-29]`\* | `r` |
|
||||
| PowerPC | `reg_nonzero` | `r[3-12]`, `r[14-29]`\* | `b` |
|
||||
| PowerPC | `freg` | `f[0-31]` | `f` |
|
||||
| PowerPC | `vreg` | `v[0-31]` | `v` |
|
||||
| PowerPC | `vsreg | `vs[0-63]` | `wa` |
|
||||
|
|
@ -61,6 +61,8 @@ This feature tracks `asm!` and `global_asm!` support for the following architect
|
|||
> - NVPTX doesn't have a fixed register set, so named registers are not supported.
|
||||
>
|
||||
> - WebAssembly doesn't have registers, so named registers are not supported.
|
||||
>
|
||||
> - r29 is reserved only on 32 bit PowerPC targets.
|
||||
|
||||
# Register class supported types
|
||||
|
||||
|
|
@ -148,7 +150,7 @@ This feature tracks `asm!` and `global_asm!` support for the following architect
|
|||
| ------------ | --------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| All | `sp`, `r14`/`o6` (SPARC) | The stack pointer must be restored to its original value at the end of an asm code block. |
|
||||
| All | `fr` (Hexagon), `fp` (PowerPC), `$fp` (MIPS), `Y` (AVR), `r4` (MSP430), `a6` (M68k), `r30`/`i6` (SPARC) | The frame pointer cannot be used as an input or output. |
|
||||
| All | `r19` (Hexagon), `r29` (PowerPC), `r30` (PowerPC) | These are used internally by LLVM as "base pointer" for functions with complex stack frames. |
|
||||
| All | `r19` (Hexagon), `r29` (PowerPC 32 bit only), `r30` (PowerPC) | These are used internally by LLVM as "base pointer" for functions with complex stack frames. |
|
||||
| MIPS | `$0` or `$zero` | This is a constant zero register which can't be modified. |
|
||||
| MIPS | `$1` or `$at` | Reserved for assembler. |
|
||||
| MIPS | `$26`/`$k0`, `$27`/`$k1` | OS-reserved registers. |
|
||||
|
|
|
|||
|
|
@ -10,12 +10,6 @@ error: invalid register `r2`: r2 is a system reserved register and cannot be use
|
|||
LL | asm!("", out("r2") _);
|
||||
| ^^^^^^^^^^^
|
||||
|
||||
error: invalid register `r29`: r29 is used internally by LLVM and cannot be used as an operand for inline asm
|
||||
--> $DIR/bad-reg.rs:42:18
|
||||
|
|
||||
LL | asm!("", out("r29") _);
|
||||
| ^^^^^^^^^^^^
|
||||
|
||||
error: invalid register `r30`: r30 is used internally by LLVM and cannot be used as an operand for inline asm
|
||||
--> $DIR/bad-reg.rs:44:18
|
||||
|
|
||||
|
|
@ -856,5 +850,5 @@ LL | asm!("/* {} */", in(xer) x);
|
|||
|
|
||||
= note: register class `xer` supports these types:
|
||||
|
||||
error: aborting due to 113 previous errors
|
||||
error: aborting due to 112 previous errors
|
||||
|
||||
|
|
|
|||
|
|
@ -10,12 +10,6 @@ error: invalid register `r2`: r2 is a system reserved register and cannot be use
|
|||
LL | asm!("", out("r2") _);
|
||||
| ^^^^^^^^^^^
|
||||
|
||||
error: invalid register `r29`: r29 is used internally by LLVM and cannot be used as an operand for inline asm
|
||||
--> $DIR/bad-reg.rs:42:18
|
||||
|
|
||||
LL | asm!("", out("r29") _);
|
||||
| ^^^^^^^^^^^^
|
||||
|
||||
error: invalid register `r30`: r30 is used internally by LLVM and cannot be used as an operand for inline asm
|
||||
--> $DIR/bad-reg.rs:44:18
|
||||
|
|
||||
|
|
@ -712,6 +706,12 @@ error: cannot use register `r13`: r13 is a reserved register on this target
|
|||
LL | asm!("", out("r13") _);
|
||||
| ^^^^^^^^^^^^
|
||||
|
||||
error: cannot use register `r29`: r29 is used internally by LLVM and cannot be used as an operand for inline asm
|
||||
--> $DIR/bad-reg.rs:42:18
|
||||
|
|
||||
LL | asm!("", out("r29") _);
|
||||
| ^^^^^^^^^^^^
|
||||
|
||||
error: register class `vreg` requires at least one of the following target features: altivec, vsx
|
||||
--> $DIR/bad-reg.rs:53:18
|
||||
|
|
||||
|
|
|
|||
|
|
@ -10,12 +10,6 @@ error: invalid register `r2`: r2 is a system reserved register and cannot be use
|
|||
LL | asm!("", out("r2") _);
|
||||
| ^^^^^^^^^^^
|
||||
|
||||
error: invalid register `r29`: r29 is used internally by LLVM and cannot be used as an operand for inline asm
|
||||
--> $DIR/bad-reg.rs:42:18
|
||||
|
|
||||
LL | asm!("", out("r29") _);
|
||||
| ^^^^^^^^^^^^
|
||||
|
||||
error: invalid register `r30`: r30 is used internally by LLVM and cannot be used as an operand for inline asm
|
||||
--> $DIR/bad-reg.rs:44:18
|
||||
|
|
||||
|
|
@ -916,5 +910,5 @@ LL | asm!("/* {} */", in(xer) x);
|
|||
|
|
||||
= note: register class `xer` supports these types:
|
||||
|
||||
error: aborting due to 123 previous errors
|
||||
error: aborting due to 122 previous errors
|
||||
|
||||
|
|
|
|||
|
|
@ -10,12 +10,6 @@ error: invalid register `r2`: r2 is a system reserved register and cannot be use
|
|||
LL | asm!("", out("r2") _);
|
||||
| ^^^^^^^^^^^
|
||||
|
||||
error: invalid register `r29`: r29 is used internally by LLVM and cannot be used as an operand for inline asm
|
||||
--> $DIR/bad-reg.rs:42:18
|
||||
|
|
||||
LL | asm!("", out("r29") _);
|
||||
| ^^^^^^^^^^^^
|
||||
|
||||
error: invalid register `r30`: r30 is used internally by LLVM and cannot be used as an operand for inline asm
|
||||
--> $DIR/bad-reg.rs:44:18
|
||||
|
|
||||
|
|
@ -856,5 +850,5 @@ LL | asm!("/* {} */", in(xer) x);
|
|||
|
|
||||
= note: register class `xer` supports these types:
|
||||
|
||||
error: aborting due to 113 previous errors
|
||||
error: aborting due to 112 previous errors
|
||||
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ fn f() {
|
|||
asm!("", out("r13") _);
|
||||
//~^ ERROR cannot use register `r13`: r13 is a reserved register on this target
|
||||
asm!("", out("r29") _);
|
||||
//~^ ERROR invalid register `r29`: r29 is used internally by LLVM and cannot be used as an operand for inline asm
|
||||
//[powerpc]~^ ERROR cannot use register `r29`: r29 is used internally by LLVM and cannot be used as an operand for inline asm
|
||||
asm!("", out("r30") _);
|
||||
//~^ ERROR invalid register `r30`: r30 is used internally by LLVM and cannot be used as an operand for inline asm
|
||||
asm!("", out("fp") _);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue