Skip to content

Conversation

@pmur
Copy link
Contributor

@pmur pmur commented Oct 22, 2025

This stabilizes inline assembly for PowerPC and PowerPC64.

Corresponding reference PR: rust-lang/reference#2056


From the requirements of stabilization mentioned in #93335

Each architecture needs to be reviewed before stabilization:

  • It must have clobber_abi.

Done in #146949.

  • It must be possible to clobber every register that is normally clobbered by a function call.

Done in #131341

Similarly, preserves_flags is also implemented by this PR. Notably, the consensus was to make this option do nothing on powerpc.

  • Generally review that the exposed register classes make sense.

The followings can be used as input/output:

  • reg (r0, r[3-12], r[14-r28]): Any usable general-purpose register
  • reg_nonzero (r[3-12], r[14-r28]): General-purpose registers, but excludes r0. This is needed for instructions which define r0 to be the value 0, such as register + immediate memory operations.
  • freg (f[0-31]): 64 bit floating pointer registers

The following are clobber-only:

  • ctr, lr, xer: commonly clobbered special-purpose registers used in inline asm
  • cr (cr[0-7], cr): the condition register fields, or the entire condition register.
  • vreg (v[0-31]): altivec/vmx register
  • vsreg (vs[0-63]): vector-scalar register

The vreg and vsreg registers technically accept #[repr(simd)] types, but require the experimental altivec or vsx target features to be enabled. That work seems to be tracked here, #42743.

The following cannot be used as operands for inline asm:

  • r2: the TOC pointer, required for most PIC code.
  • r13: the TLS pointer
  • r[29-30]: Reserved for internal usage by LLVM
  • r31: the frame pointer
  • vrsave: this is effectively an unused special-purpose register.

The following registers are unavailable:

  • spe_acc, spefscr: These are available exclusively on the SPE target (the e500, not cell). I am not sure how these are actually used. I think they can be added later if needed.
  • mma[0-7]: These are new "registers" available on Power10, they are 512b registers which overlay 4x vsx registers. They could be added if needed, however their usage is very specialized.
  • ap, mq: I don't think these registers exist on any usable power target supported by gcc/llvm.
  • fpscr: it is not modelled by gcc or llvm.
  • vscr: clang/gcc accept this as a clobber, but do not actually save/restore it.

cc @taiki-e
r? @Amanieu
@rustbot label +A-inline-assembly

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. A-inline-assembly Area: Inline assembly (`asm!(…)`) labels Oct 22, 2025
@Amanieu
Copy link
Member

Amanieu commented Oct 31, 2025

The vreg and vsreg registers technically accept #[repr(simd)] types, but require the experimental altivec or vsx target features to be enabled. That work seems to be tracked here, #42743.

These also accept f32 and f64 (as per the docs in rust-lang/reference#2056). Even though the target features are unstable, these are still usable on targets where these features are enabled by default. Passing SIMD vectors will remain implicitly unstable as long as the relevant stdarch bits are unstable.

  • r[29-30]: Reserved for internal usage by LLVM

r29 is only reserved on ppc32. We could allow r29 for powerpc64 only.

  • fpscr: it is not modelled by gcc or llvm.
  • vscr: clang/gcc accept this as a clobber, but do not actually save/restore it.

It would be good to document these as being controlled by preserves_flags like we do in RISC-V. That way when LLVM eventually adds support for modelling these then code will continue to properly handle them.

@folkertdev
Copy link
Contributor

Passing SIMD vectors will remain implicitly unstable as long as the relevant stdarch bits are unstable.

Specifically that would require a PR like #145656 for s390x, which stabilizes the target features (and presumably also the is_powerpc_feature_detected macro).

I'd assume that with this PR merged, stabilizing the vsx and altivec target features at least would be straightforward if there is appetite. If so, it's probably a good idea to ensure (via tests) that the interaction between vector types and asm works as expected.

@taiki-e
Copy link
Member

taiki-e commented Nov 1, 2025

@pmur

  • vscr: clang/gcc accept this as a clobber, but do not actually save/restore it.

However, I guess LLVM/GCC could potentially generate code that relies on the VSCR fields being the same before and after inline assembly, when it is not marked as clobbered.

  • spe_acc, spefscr: These are available exclusively on the SPE target (the e500, not cell). I am not sure how these are actually used. I think they can be added later if needed.

IIRC, these are used to store the results of SPE-specific instructions.

That said, since all SPE targets are tier 3, it might be fine to ignore them and proceed with stabilization.


@folkertdev

Passing SIMD vectors will remain implicitly unstable as long as the relevant stdarch bits are unstable.

Specifically that would require a PR like #145656 for s390x, which stabilizes the target features (and presumably also the is_powerpc_feature_detected macro).

AFAIK, when passing values to inline assembly, the required target features themselves do not need to be stable (since #114467).

Btw, s390x is a bit special in that passing values to vector registers in inline assembly requires a separate unstable feature: #133416 (This is due to vector ABI support being added after the inline assembly stabilization.)

@pmur
Copy link
Contributor Author

pmur commented Nov 3, 2025

@taiki-e

  • vscr: clang/gcc accept this as a clobber, but do not actually save/restore it.

However, I guess LLVM/GCC could potentially generate code that relies on the VSCR fields being the same before and after inline assembly, when it is not marked as clobbered.

Yes, that would make it even more difficult to correctly mark this a clobber. Making it unusable avoids the question of whether codegen will actually preserve it.

@Amanieu

  • fpscr: it is not modelled by gcc or llvm.
  • vscr: clang/gcc accept this as a clobber, but do not actually save/restore it.

It would be good to document these as being controlled by preserves_flags like we do in RISC-V. That way when LLVM eventually adds support for modelling these then code will continue to properly handle them.

I think the consensus is not to preserve any flags. Notably, XER is partially modeled, but we choose to ignore it. It depends on if and how LLVM/GCC would choose to expose it.

@pmur
Copy link
Contributor Author

pmur commented Nov 4, 2025

@Amanieu

r29 is only reserved on ppc32. We could allow r29 for powerpc64 only.

Yes, that seems reasonable. See #148492.

In general, is there any issue against relaxing restrictions post stabilization? Particularly, if we add FPSCR/VSCR preservation requirements for preserves_flags which we cannot enforce today.

For FPSCR, are there active plans to support it in LLVM?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-inline-assembly Area: Inline assembly (`asm!(…)`) S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants