Skip to content

Commit db85e81

Browse files
authored
Merge pull request #2056 from pmur/murp/stabilize-ppc-inlineasm
Document ppc inline asm support
2 parents 141b1af + 1156d9b commit db85e81

1 file changed

Lines changed: 47 additions & 3 deletions

File tree

src/inline-assembly.md

Lines changed: 47 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ Support for inline assembly is stable on the following architectures:
1616
- RISC-V
1717
- LoongArch
1818
- s390x
19+
- PowerPC and PowerPC64
1920

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

@@ -627,11 +628,24 @@ Here is the list of currently supported register classes:
627628
| s390x | `freg` | `f[0-15]` | `f` |
628629
| s390x | `vreg` | `v[0-31]` | Only clobbers |
629630
| s390x | `areg` | `a[2-15]` | Only clobbers |
631+
| PowerPC | `reg` | `r0`, `r[3-12]`, `r[14-28]` | `r` |
632+
| PowerPC | `reg_nonzero` | `r[3-12]`, `r[14-28]` | `b` |
633+
| PowerPC | `spe_acc` | `spe_acc` | Only clobbers |
634+
| PowerPC64 | `reg` | `r0`, `r[3-12]`, `r[14-29]` | `r` |
635+
| PowerPC64 | `reg_nonzero` | `r[3-12]`, `r[14-29]` | `b` |
636+
| PowerPC/PowerPC64 | `freg` | `f[0-31]` | `f` |
637+
| PowerPC/PowerPC64 | `vreg` | `v[0-31]` | `v` |
638+
| PowerPC/PowerPC64 | `vsreg` | `vs[0-63]` | `wa` |
639+
| PowerPC/PowerPC64 | `cr` | `cr[0-7]`, `cr` | Only clobbers |
640+
| PowerPC/PowerPC64 | `ctr` | `ctr` | Only clobbers |
641+
| PowerPC/PowerPC64 | `lr` | `lr` | Only clobbers |
642+
| PowerPC/PowerPC64 | `xer` | `xer` | Only clobbers |
630643

631644
> [!NOTE]
632645
> - On x86 we treat `reg_byte` differently from `reg` because the compiler can allocate `al` and `ah` separately whereas `reg` reserves the whole register.
633646
> - On x86-64 the high byte registers (e.g. `ah`) are not available in the `reg_byte` register class.
634647
> - 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>) _`.
648+
> - The `spe_acc` register is only available on PowerPC SPE targets.
635649
636650
r[asm.register-operands.value-type-constraints]
637651
Each register class has constraints on which value types they can be used with. This is necessary because the way a value is loaded into a register depends on its type. For example, on big-endian systems, loading a `i32x4` and a `i8x16` into a SIMD register may result in different register contents even if the byte-wise memory representation of both values is identical. The availability of supported types for a particular register class may depend on what target features are currently enabled.
@@ -671,6 +685,17 @@ Each register class has constraints on which value types they can be used with.
671685
| s390x | `freg` | None | `f32`, `f64` |
672686
| s390x | `vreg` | N/A | Only clobbers |
673687
| s390x | `areg` | N/A | Only clobbers |
688+
| PowerPC | `spe_acc` | None | Only clobbers |
689+
| PowerPC/PowerPC64 | `reg` | None | `i8`, `i16`, `i32`, `i64` (PowerPC64 only) |
690+
| PowerPC/PowerPC64 | `reg_nonzero` | None | `i8`, `i16`, `i32`, `i64` (PowerPC64 only) |
691+
| PowerPC/PowerPC64 | `freg` | None | `f32`, `f64` |
692+
| PowerPC/PowerPC64 | `vreg` | `altivec` | `i8x16`, `i16x8`, `i32x4`, `f32x4` |
693+
| PowerPC/PowerPC64 | `vreg` | `vsx` | `f32`, `f64`, `i64x2`, `f64x2` |
694+
| PowerPC/PowerPC64 | `vsreg` | `vsx` | The union of vsx and altivec vreg types |
695+
| PowerPC/PowerPC64 | `cr` | None | Only clobbers |
696+
| PowerPC/PowerPC64 | `ctr` | None | Only clobbers |
697+
| PowerPC/PowerPC64 | `lr` | None | Only clobbers |
698+
| PowerPC/PowerPC64 | `xer` | None | Only clobbers |
674699

675700
> [!NOTE]
676701
> 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).
@@ -807,6 +832,10 @@ Some registers have multiple names. These are all treated by the compiler as ide
807832
| LoongArch | `$f[0-7]` | `$fa[0-7]` |
808833
| LoongArch | `$f[8-23]` | `$ft[0-15]` |
809834
| LoongArch | `$f[24-31]` | `$fs[0-7]` |
835+
| PowerPC/PowerPC64 | `r1` | `sp` |
836+
| PowerPC/PowerPC64 | `r31` | `fp` |
837+
| PowerPC/PowerPC64 | `r[0-31]` | `[0-31]` |
838+
| PowerPC/PowerPC64 | `f[0-31]` | `fr[0-31]`|
810839

811840
```rust
812841
# #[cfg(target_arch = "x86_64")] {
@@ -821,10 +850,10 @@ Some registers cannot be used for input or output operands:
821850

822851
| Architecture | Unsupported register | Reason |
823852
| ------------ | -------------------- | ------ |
824-
| 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. |
825-
| 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. |
853+
| 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. |
854+
| 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. |
826855
| 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. |
827-
| 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. |
856+
| 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. |
828857
| x86 | `ip` | This is the program counter, not a real register. |
829858
| AArch64 | `xzr` | This is a constant zero register which can't be modified. |
830859
| AArch64 | `x18` | This is an OS-reserved register on some AArch64 targets. |
@@ -840,6 +869,8 @@ Some registers cannot be used for input or output operands:
840869
| LoongArch | `$r21` | This is reserved by the ABI. |
841870
| s390x | `c[0-15]` | Reserved by the kernel. |
842871
| s390x | `a[0-1]` | Reserved for system use. |
872+
| PowerPC/PowerPC64 | `r2`, `r13` | These are system reserved registers. |
873+
| PowerPC/PowerPC64 | `vrsave` | The vrsave register cannot be used as an input or output. |
843874

844875
```rust,compile_fail
845876
# #[cfg(target_arch = "x86_64")] {
@@ -914,6 +945,11 @@ The supported modifiers are a subset of LLVM's (and GCC's) [asm template argumen
914945
| s390x | `reg` | None | `%r0` | None |
915946
| s390x | `reg_addr` | None | `%r1` | None |
916947
| s390x | `freg` | None | `%f0` | None |
948+
| PowerPC/PowerPC64 | `reg` | None | `0` | None |
949+
| PowerPC/PowerPC64 | `reg_nonzero` | None | `3` | None |
950+
| PowerPC/PowerPC64 | `freg` | None | `0` | None |
951+
| PowerPC/PowerPC64 | `vreg` | None | `0` | None |
952+
| PowerPC/PowerPC64 | `vsreg` | None | `0` | None |
917953

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

1352+
r[asm.rules.stack-above-sp]
1353+
- Unless the `nostack` option is set, assembly code is allowed to modify the caller's stack frame when the target ABI requires storing certain values in the caller's frame (e.g., when saving the `lr` on PowerPC64).
1354+
13161355
r[asm.rules.noreturn]
13171356
- If the `noreturn` option is set then behavior is undefined if execution falls through the end of the assembly code.
13181357

@@ -1342,6 +1381,11 @@ r[asm.rules.preserved-registers]
13421381
- Vector extension state (`vtype`, `vl`, `vxsat`, and `vxrm`).
13431382
- LoongArch
13441383
- Floating-point condition flags in `$fcc[0-7]`.
1384+
- PowerPC/PowerPC64
1385+
- Floating-point status and sticky bits in the `fpscr` (any field other than DRN, VE, OE, UE, ZE, XE, NI, or RN).
1386+
- Vector status and sticky bits in the `vscr` (any field other than NJ).
1387+
- PowerPC SPE
1388+
- The sticky and status bits of the `spefscr` (any field other than FINXE, FINVE, FDBZE, FUNFE, FOVFE, or FRMC).
13451389
- s390x
13461390
- The condition code register `cc`.
13471391

0 commit comments

Comments
 (0)