Skip to content

Commit 53efb3d

Browse files
committed
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`
2 parents 8e0b68e + 5f6fa96 commit 53efb3d

File tree

7 files changed

+31
-34
lines changed

7 files changed

+31
-34
lines changed

compiler/rustc_target/src/asm/powerpc.rs

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,20 @@ fn reserved_r13(
8282
}
8383
}
8484

85+
fn reserved_r29(
86+
arch: InlineAsmArch,
87+
_reloc_model: RelocModel,
88+
_target_features: &FxIndexSet<Symbol>,
89+
_target: &Target,
90+
_is_clobber: bool,
91+
) -> Result<(), &'static str> {
92+
if arch != InlineAsmArch::PowerPC {
93+
Ok(())
94+
} else {
95+
Err("r29 is used internally by LLVM and cannot be used as an operand for inline asm")
96+
}
97+
}
98+
8599
fn reserved_v20to31(
86100
_arch: InlineAsmArch,
87101
_reloc_model: RelocModel,
@@ -129,6 +143,7 @@ def_regs! {
129143
r26: reg, reg_nonzero = ["r26", "26"],
130144
r27: reg, reg_nonzero = ["r27", "27"],
131145
r28: reg, reg_nonzero = ["r28", "28"],
146+
r29: reg, reg_nonzero = ["r29", "29"] % reserved_r29,
132147
f0: freg = ["f0", "fr0"],
133148
f1: freg = ["f1", "fr1"],
134149
f2: freg = ["f2", "fr2"],
@@ -274,8 +289,6 @@ def_regs! {
274289
"the stack pointer cannot be used as an operand for inline asm",
275290
#error = ["r2", "2"] =>
276291
"r2 is a system reserved register and cannot be used as an operand for inline asm",
277-
#error = ["r29", "29"] =>
278-
"r29 is used internally by LLVM and cannot be used as an operand for inline asm",
279292
#error = ["r30", "30"] =>
280293
"r30 is used internally by LLVM and cannot be used as an operand for inline asm",
281294
#error = ["r31", "31", "fp"] =>
@@ -306,7 +319,7 @@ impl PowerPCInlineAsmReg {
306319
(r0, "0"), (r3, "3"), (r4, "4"), (r5, "5"), (r6, "6"), (r7, "7");
307320
(r8, "8"), (r9, "9"), (r10, "10"), (r11, "11"), (r12, "12"), (r13, "13"), (r14, "14"), (r15, "15");
308321
(r16, "16"), (r17, "17"), (r18, "18"), (r19, "19"), (r20, "20"), (r21, "21"), (r22, "22"), (r23, "23");
309-
(r24, "24"), (r25, "25"), (r26, "26"), (r27, "27"), (r28, "28");
322+
(r24, "24"), (r25, "25"), (r26, "26"), (r27, "27"), (r28, "28"), (r29, "29");
310323
(f0, "0"), (f1, "1"), (f2, "2"), (f3, "3"), (f4, "4"), (f5, "5"), (f6, "6"), (f7, "7");
311324
(f8, "8"), (f9, "9"), (f10, "10"), (f11, "11"), (f12, "12"), (f13, "13"), (f14, "14"), (f15, "15");
312325
(f16, "16"), (f17, "17"), (f18, "18"), (f19, "19"), (f20, "20"), (f21, "21"), (f22, "22"), (f23, "23");

src/doc/unstable-book/src/language-features/asm-experimental-arch.md

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,8 @@ This feature tracks `asm!` and `global_asm!` support for the following architect
3131
| NVPTX | `reg64` | None\* | `l` |
3232
| Hexagon | `reg` | `r[0-28]` | `r` |
3333
| Hexagon | `preg` | `p[0-3]` | Only clobbers |
34-
| PowerPC | `reg` | `r0`, `r[3-12]`, `r[14-28]` | `r` |
35-
| PowerPC | `reg_nonzero` | `r[3-12]`, `r[14-28]` | `b` |
34+
| PowerPC | `reg` | `r0`, `r[3-12]`, `r[14-29]`\* | `r` |
35+
| PowerPC | `reg_nonzero` | `r[3-12]`, `r[14-29]`\* | `b` |
3636
| PowerPC | `freg` | `f[0-31]` | `f` |
3737
| PowerPC | `vreg` | `v[0-31]` | `v` |
3838
| PowerPC | `vsreg | `vs[0-63]` | `wa` |
@@ -61,6 +61,8 @@ This feature tracks `asm!` and `global_asm!` support for the following architect
6161
> - NVPTX doesn't have a fixed register set, so named registers are not supported.
6262
>
6363
> - WebAssembly doesn't have registers, so named registers are not supported.
64+
>
65+
> - r29 is reserved only on 32 bit PowerPC targets.
6466
6567
# Register class supported types
6668

@@ -148,7 +150,7 @@ This feature tracks `asm!` and `global_asm!` support for the following architect
148150
| ------------ | --------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
149151
| All | `sp`, `r14`/`o6` (SPARC) | The stack pointer must be restored to its original value at the end of an asm code block. |
150152
| 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. |
151-
| All | `r19` (Hexagon), `r29` (PowerPC), `r30` (PowerPC) | These are used internally by LLVM as "base pointer" for functions with complex stack frames. |
153+
| 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. |
152154
| MIPS | `$0` or `$zero` | This is a constant zero register which can't be modified. |
153155
| MIPS | `$1` or `$at` | Reserved for assembler. |
154156
| MIPS | `$26`/`$k0`, `$27`/`$k1` | OS-reserved registers. |

tests/ui/asm/powerpc/bad-reg.aix64.stderr

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,6 @@ error: invalid register `r2`: r2 is a system reserved register and cannot be use
1010
LL | asm!("", out("r2") _);
1111
| ^^^^^^^^^^^
1212

13-
error: invalid register `r29`: r29 is used internally by LLVM and cannot be used as an operand for inline asm
14-
--> $DIR/bad-reg.rs:42:18
15-
|
16-
LL | asm!("", out("r29") _);
17-
| ^^^^^^^^^^^^
18-
1913
error: invalid register `r30`: r30 is used internally by LLVM and cannot be used as an operand for inline asm
2014
--> $DIR/bad-reg.rs:44:18
2115
|
@@ -856,5 +850,5 @@ LL | asm!("/* {} */", in(xer) x);
856850
|
857851
= note: register class `xer` supports these types:
858852

859-
error: aborting due to 113 previous errors
853+
error: aborting due to 112 previous errors
860854

tests/ui/asm/powerpc/bad-reg.powerpc.stderr

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,6 @@ error: invalid register `r2`: r2 is a system reserved register and cannot be use
1010
LL | asm!("", out("r2") _);
1111
| ^^^^^^^^^^^
1212

13-
error: invalid register `r29`: r29 is used internally by LLVM and cannot be used as an operand for inline asm
14-
--> $DIR/bad-reg.rs:42:18
15-
|
16-
LL | asm!("", out("r29") _);
17-
| ^^^^^^^^^^^^
18-
1913
error: invalid register `r30`: r30 is used internally by LLVM and cannot be used as an operand for inline asm
2014
--> $DIR/bad-reg.rs:44:18
2115
|
@@ -712,6 +706,12 @@ error: cannot use register `r13`: r13 is a reserved register on this target
712706
LL | asm!("", out("r13") _);
713707
| ^^^^^^^^^^^^
714708

709+
error: cannot use register `r29`: r29 is used internally by LLVM and cannot be used as an operand for inline asm
710+
--> $DIR/bad-reg.rs:42:18
711+
|
712+
LL | asm!("", out("r29") _);
713+
| ^^^^^^^^^^^^
714+
715715
error: register class `vreg` requires at least one of the following target features: altivec, vsx
716716
--> $DIR/bad-reg.rs:53:18
717717
|

tests/ui/asm/powerpc/bad-reg.powerpc64.stderr

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,6 @@ error: invalid register `r2`: r2 is a system reserved register and cannot be use
1010
LL | asm!("", out("r2") _);
1111
| ^^^^^^^^^^^
1212

13-
error: invalid register `r29`: r29 is used internally by LLVM and cannot be used as an operand for inline asm
14-
--> $DIR/bad-reg.rs:42:18
15-
|
16-
LL | asm!("", out("r29") _);
17-
| ^^^^^^^^^^^^
18-
1913
error: invalid register `r30`: r30 is used internally by LLVM and cannot be used as an operand for inline asm
2014
--> $DIR/bad-reg.rs:44:18
2115
|
@@ -916,5 +910,5 @@ LL | asm!("/* {} */", in(xer) x);
916910
|
917911
= note: register class `xer` supports these types:
918912

919-
error: aborting due to 123 previous errors
913+
error: aborting due to 122 previous errors
920914

tests/ui/asm/powerpc/bad-reg.powerpc64le.stderr

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,6 @@ error: invalid register `r2`: r2 is a system reserved register and cannot be use
1010
LL | asm!("", out("r2") _);
1111
| ^^^^^^^^^^^
1212

13-
error: invalid register `r29`: r29 is used internally by LLVM and cannot be used as an operand for inline asm
14-
--> $DIR/bad-reg.rs:42:18
15-
|
16-
LL | asm!("", out("r29") _);
17-
| ^^^^^^^^^^^^
18-
1913
error: invalid register `r30`: r30 is used internally by LLVM and cannot be used as an operand for inline asm
2014
--> $DIR/bad-reg.rs:44:18
2115
|
@@ -856,5 +850,5 @@ LL | asm!("/* {} */", in(xer) x);
856850
|
857851
= note: register class `xer` supports these types:
858852

859-
error: aborting due to 113 previous errors
853+
error: aborting due to 112 previous errors
860854

tests/ui/asm/powerpc/bad-reg.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ fn f() {
4040
asm!("", out("r13") _);
4141
//~^ ERROR cannot use register `r13`: r13 is a reserved register on this target
4242
asm!("", out("r29") _);
43-
//~^ ERROR invalid register `r29`: r29 is used internally by LLVM and cannot be used as an operand for inline asm
43+
//[powerpc]~^ ERROR cannot use register `r29`: r29 is used internally by LLVM and cannot be used as an operand for inline asm
4444
asm!("", out("r30") _);
4545
//~^ ERROR invalid register `r30`: r30 is used internally by LLVM and cannot be used as an operand for inline asm
4646
asm!("", out("fp") _);

0 commit comments

Comments
 (0)