Skip to content

Commit 3e8ee09

Browse files
committed
Document ppc inline asm support
Mark status and sticky bits of vscr, fpscr and spefscr as being preserved when using the `preserves_flags` option. These are not enforced by codegen today, but might be in future LLVM releases.
1 parent 182f2c6 commit 3e8ee09

File tree

1 file changed

+48
-3
lines changed

1 file changed

+48
-3
lines changed

src/inline-assembly.md

Lines changed: 48 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ Support for inline assembly is stable on the following architectures:
1717
- RISC-V
1818
- LoongArch
1919
- s390x
20+
- PowerPC and PowerPC64
2021

2122
The compiler will emit an error if an assembly macro is used on an unsupported target.
2223

@@ -602,11 +603,24 @@ Here is the list of currently supported register classes:
602603
| s390x | `freg` | `f[0-15]` | `f` |
603604
| s390x | `vreg` | `v[0-31]` | Only clobbers |
604605
| s390x | `areg` | `a[2-15]` | Only clobbers |
606+
| PowerPC | `reg` | `r0`, `r[3-12]`, `r[14-28]` | `r` |
607+
| PowerPC | `reg_nonzero` | `r[3-12]`, `r[14-28]` | `b` |
608+
| PowerPC | `spe_acc` | `spe_acc` | Only clobbers |
609+
| PowerPC64 | `reg` | `r0`, `r[3-12]`, `r[14-29]` | `r` |
610+
| PowerPC64 | `reg_nonzero` | `r[3-12]`, `r[14-29]` | `b` |
611+
| PowerPC/PowerPC64 | `freg` | `f[0-31]` | `f` |
612+
| PowerPC/PowerPC64 | `vreg` | `v[0-31]` | `v` |
613+
| PowerPC/PowerPC64 | `vsreg` | `vs[0-63]` | `wa` |
614+
| PowerPC/PowerPC64 | `cr` | `cr[0-7]`, `cr` | Only clobbers |
615+
| PowerPC/PowerPC64 | `ctr` | `ctr` | Only clobbers |
616+
| PowerPC/PowerPC64 | `lr` | `lr` | Only clobbers |
617+
| PowerPC/PowerPC64 | `xer` | `xer` | Only clobbers |
605618

606619
> [!NOTE]
607620
> - On x86 we treat `reg_byte` differently from `reg` because the compiler can allocate `al` and `ah` separately whereas `reg` reserves the whole register.
608621
> - On x86-64 the high byte registers (e.g. `ah`) are not available in the `reg_byte` register class.
609622
> - Some register classes are marked as "Only clobbers" which means that registers in these classes cannot be used for inputs or outputs, only clobbers of the form `out(<explicit register>) _` or `lateout(<explicit register>) _`.
623+
> - The `spe_acc` register is only available on PowerPC SPE targets
610624
611625
r[asm.register-operands.value-type-constraints]
612626
Each register class has constraints on which value types they can be used with.
@@ -649,6 +663,17 @@ The availability of supported types for a particular register class may depend o
649663
| s390x | `freg` | None | `f32`, `f64` |
650664
| s390x | `vreg` | N/A | Only clobbers |
651665
| s390x | `areg` | N/A | Only clobbers |
666+
| PowerPC | `spe_acc` | None | Only clobbers |
667+
| PowerPC/PowerPC64 | `reg` | None | `i8`, `i16`, `i32`, `i64` (PowerPC64 only) |
668+
| PowerPC/PowerPC64 | `reg_nonzero` | None | `i8`, `i16`, `i32`, `i64` (PowerPC64 only) |
669+
| PowerPC/PowerPC64 | `freg` | None | `f32`, `f64` |
670+
| PowerPC/PowerPC64 | `vreg` | `altivec` | `i8x16`, `i16x8`, `i32x4`, `f32x4` |
671+
| PowerPC/PowerPC64 | `vreg` | `vsx` | `f32`, `f64`, `i64x2`, `f64x2` |
672+
| PowerPC/PowerPC64 | `vsreg` | `vsx` | The union of vsx and altivec vreg types |
673+
| PowerPC/PowerPC64 | `cr` | None | Only clobbers |
674+
| PowerPC/PowerPC64 | `ctr` | None | Only clobbers |
675+
| PowerPC/PowerPC64 | `lr` | None | Only clobbers |
676+
| PowerPC/PowerPC64 | `xer` | None | Only clobbers |
652677

653678
> [!NOTE]
654679
> For the purposes of the above table pointers, function pointers and `isize`/`usize` are treated as the equivalent integer type (`i16`/`i32`/`i64` depending on the target).
@@ -790,6 +815,10 @@ Here is the list of all supported register aliases:
790815
| LoongArch | `$f[0-7]` | `$fa[0-7]` |
791816
| LoongArch | `$f[8-23]` | `$ft[0-15]` |
792817
| LoongArch | `$f[24-31]` | `$fs[0-7]` |
818+
| PowerPC/PowerPC64 | `r1` | `sp` |
819+
| PowerPC/PowerPC64 | `r31` | `fp` |
820+
| PowerPC/PowerPC64 | `r[0-31]` | `[0-31]` |
821+
| PowerPC/PowerPC64 | `f[0-31]` | `fr[0-31]`|
793822

794823
```rust
795824
# #[cfg(target_arch = "x86_64")] {
@@ -804,10 +833,10 @@ Some registers cannot be used for input or output operands:
804833

805834
| Architecture | Unsupported register | Reason |
806835
| ------------ | -------------------- | ------ |
807-
| All | `sp`, `r15` (s390x) | The stack pointer must be restored to its original value at the end of the assembly code or before jumping to a `label` block. |
808-
| All | `bp` (x86), `x29` (AArch64 and Arm64EC), `x8` (RISC-V), `$fp` (LoongArch), `r11` (s390x) | The frame pointer cannot be used as an input or output. |
836+
| All | `sp`, `r15` (s390x), `r1` (PowerPC and PowerPC64) | The stack pointer must be restored to its original value at the end of the assembly code or before jumping to a `label` block. |
837+
| All | `bp` (x86), `x29` (AArch64 and Arm64EC), `x8` (RISC-V), `$fp` (LoongArch), `r11` (s390x), `fp` (PowerPC and PowerPC64) | The frame pointer cannot be used as an input or output. |
809838
| ARM | `r7` or `r11` | On ARM the frame pointer can be either `r7` or `r11` depending on the target. The frame pointer cannot be used as an input or output. |
810-
| All | `si` (x86-32), `bx` (x86-64), `r6` (ARM), `x19` (AArch64 and Arm64EC), `x9` (RISC-V), `$s8` (LoongArch) | This is used internally by LLVM as a "base pointer" for functions with complex stack frames. |
839+
| All | `si` (x86-32), `bx` (x86-64), `r6` (ARM), `x19` (AArch64 and Arm64EC), `x9` (RISC-V), `$s8` (LoongArch), `r29` and `r30` (PowerPC), `r30` (PowerPC64) | This is used internally by LLVM as a "base pointer" for functions with complex stack frames. |
811840
| x86 | `ip` | This is the program counter, not a real register. |
812841
| AArch64 | `xzr` | This is a constant zero register which can't be modified. |
813842
| AArch64 | `x18` | This is an OS-reserved register on some AArch64 targets. |
@@ -823,6 +852,8 @@ Some registers cannot be used for input or output operands:
823852
| LoongArch | `$r21` | This is reserved by the ABI. |
824853
| s390x | `c[0-15]` | Reserved by the kernel. |
825854
| s390x | `a[0-1]` | Reserved for system use. |
855+
| PowerPC/PowerPC64 | `r2`, `r13` | These are system reserved registers. |
856+
| PowerPC/PowerPC64 | `vrsave` | The vrsave register cannot be used as an input or output. |
826857

827858
```rust,compile_fail
828859
# #[cfg(target_arch = "x86_64")] {
@@ -898,6 +929,11 @@ The supported modifiers are a subset of LLVM's (and GCC's) [asm template argumen
898929
| s390x | `reg` | None | `%r0` | None |
899930
| s390x | `reg_addr` | None | `%r1` | None |
900931
| s390x | `freg` | None | `%f0` | None |
932+
| PowerPC/PowerPC64 | `reg` | None | `0` | None |
933+
| PowerPC/PowerPC64 | `reg_nonzero` | None | `3` | None |
934+
| PowerPC/PowerPC64 | `freg` | None | `0` | None |
935+
| PowerPC/PowerPC64 | `vreg` | None | `0` | None |
936+
| PowerPC/PowerPC64 | `vsreg` | None | `0` | None |
901937

902938
> [!NOTE]
903939
> - on ARM `e` / `f`: this prints the low or high doubleword register name of a NEON quad (128-bit) register.
@@ -1316,6 +1352,10 @@ r[asm.rules.stack-below-sp]
13161352
- You should adjust the stack pointer when allocating stack memory as required by the target ABI.
13171353
- The stack pointer must be restored to its original value before leaving the assembly code.
13181354

1355+
r[asm.rules.stack-above-sp]
1356+
- Unless the `nostack` option is set, assembly code is allowed to modify the caller's stack frame in specific cases.
1357+
- The target ABI requires storing certain values in the caller's frame (e.g saving the `lr` on PowerPC64)
1358+
13191359
r[asm.rules.noreturn]
13201360
- If the `noreturn` option is set then behavior is undefined if execution falls through the end of the assembly code.
13211361

@@ -1346,6 +1386,11 @@ r[asm.rules.preserved-registers]
13461386
- Vector extension state (`vtype`, `vl`, `vxsat`, and `vxrm`).
13471387
- LoongArch
13481388
- Floating-point condition flags in `$fcc[0-7]`.
1389+
- PowerPC/PowerPC64
1390+
- Floating-point status and sticky bits in the `fpscr` (any field other than DRN, VE, OE, UE, ZE, XE, NI, or RN).
1391+
- Vector status and sticky bits in the `vscr` (any field other than NJ).
1392+
- PowerPC SPE
1393+
- The sticky and status bits of the `spefscr` (any field other than FINXE, FINVE, FDBZE, FUNFE, FOVFE, or FRMC)
13491394
- s390x
13501395
- The condition code register `cc`.
13511396

0 commit comments

Comments
 (0)