asm_experimental_arch

The tracking issue for this feature is: #93335


This feature tracks asm! and global_asm! support for the following architectures:

  • NVPTX
  • PowerPC
  • Hexagon
  • MIPS32r2 and MIPS64r2
  • wasm32
  • BPF
  • SPIR-V
  • AVR
  • MSP430
  • M68k
  • CSKY
  • s390x
  • Arm64EC

Register classes

ArchitectureRegister classRegistersLLVM constraint code
MIPSreg$[2-25]r
MIPSfreg$f[0-31]f
NVPTXreg16None*h
NVPTXreg32None*r
NVPTXreg64None*l
Hexagonregr[0-28]r
PowerPCregr[0-31]r
PowerPCreg_nonzeror[1-31]b
PowerPCfregf[0-31]f
PowerPCcrcr[0-7], crOnly clobbers
PowerPCxerxerOnly clobbers
wasm32localNone*r
BPFregr[0-10]r
BPFwregw[0-10]w
AVRregr[2-25], XH, XL, ZH, ZLr
AVRreg_upperr[16-25], XH, XL, ZH, ZLd
AVRreg_pairr3r2 .. r25r24, X, Zr
AVRreg_iwr25r24, X, Zw
AVRreg_ptrX, Ze
MSP430regr[0-15]r
M68kregd[0-7], a[0-7]r
M68kreg_datad[0-7]d
M68kreg_addra[0-3]a
CSKYregr[0-31]r
CSKYfregf[0-31]f
s390xregr[0-10], r[12-14]r
s390xfregf[0-15]f
Arm64ECregx[0-12], x[15-22], x[25-27], x30r
Arm64ECvregv[0-15]w
Arm64ECvreg_low16v[0-15]x

Notes:

  • 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.

Register class supported types

ArchitectureRegister classTarget featureAllowed types
MIPS32regNonei8, i16, i32, f32
MIPS32fregNonef32, f64
MIPS64regNonei8, i16, i32, i64, f32, f64
MIPS64fregNonef32, f64
NVPTXreg16Nonei8, i16
NVPTXreg32Nonei8, i16, i32, f32
NVPTXreg64Nonei8, i16, i32, f32, i64, f64
HexagonregNonei8, i16, i32, f32
PowerPCregNonei8, i16, i32
PowerPCreg_nonzeroNonei8, i16, i32
PowerPCfregNonef32, f64
PowerPCcrN/AOnly clobbers
PowerPCxerN/AOnly clobbers
wasm32localNonei8 i16 i32 i64 f32 f64
BPFregNonei8 i16 i32 i64
BPFwregalu32i8 i16 i32
AVRreg, reg_upperNonei8
AVRreg_pair, reg_iw, reg_ptrNonei16
MSP430regNonei8, i16
M68kreg, reg_addrNonei16, i32
M68kreg_dataNonei8, i16, i32
CSKYregNonei8, i16, i32
CSKYfregNonef32,
s390xreg, reg_addrNonei8, i16, i32, i64
s390xfregNonef32, f64
Arm64ECregNonei8, i16, i32, f32, i64, f64
Arm64ECvregNonei8, i16, i32, f32, i64, f64,
i8x8, i16x4, i32x2, i64x1, f32x2, f64x1,
i8x16, i16x8, i32x4, i64x2, f32x4, f64x2

Register aliases

ArchitectureBase registerAliases
Hexagonr29sp
Hexagonr30fr
Hexagonr31lr
BPFr[0-10]w[0-10]
AVRXHr27
AVRXLr26
AVRZHr31
AVRZLr30
MSP430r0pc
MSP430r1sp
MSP430r2sr
MSP430r3cg
MSP430r4fp
M68ka5bp
M68ka6fp
M68ka7sp, usp, ssp, isp
CSKYr[0-3]a[0-3]
CSKYr[4-11]l[0-7]
CSKYr[12-13]t[0-1]
CSKYr14sp
CSKYr15lr
CSKYr[16-17]l[8-9]
CSKYr[18-25]t[2-9]
CSKYr28rgb
CSKYr29rtb
CSKYr30svbr
CSKYr31tls
Arm64ECx[0-30]w[0-30]
Arm64ECx29fp
Arm64ECx30lr
Arm64ECspwsp
Arm64ECxzrwzr
Arm64ECv[0-15]b[0-15], h[0-15], s[0-15], d[0-15], q[0-15]

Notes:

  • TI does not mandate a frame pointer for MSP430, but toolchains are allowed to use one; LLVM uses r4.

Unsupported registers

ArchitectureUnsupported registerReason
Allsp, r15 (s390x)The stack pointer must be restored to its original value at the end of an asm code block.
Allfr (Hexagon), $fp (MIPS), Y (AVR), r4 (MSP430), a6 (M68k), r11 (s390x), x29 (Arm64EC)The frame pointer cannot be used as an input or output.
Allr19 (Hexagon), x19 (Arm64EC)This is used internally by LLVM as a "base pointer" for functions with complex stack frames.
MIPS$0 or $zeroThis is a constant zero register which can't be modified.
MIPS$1 or $atReserved for assembler.
MIPS$26/$k0, $27/$k1OS-reserved registers.
MIPS$28/$gpGlobal pointer cannot be used as inputs or outputs.
MIPS$raReturn address cannot be used as inputs or outputs.
HexagonlrThis is the link register which cannot be used as an input or output.
AVRr0, r1, r1r0Due to an issue in LLVM, the r0 and r1 registers cannot be used as inputs or outputs. If modified, they must be restored to their original values before the end of the block.
MSP430r0, r2, r3These are the program counter, status register, and constant generator respectively. Neither the status register nor constant generator can be written to.
M68ka4, a5Used internally by LLVM for the base pointer and global base pointer.
CSKYr7, r28Used internally by LLVM for the base pointer and global base pointer.
CSKYr8Used internally by LLVM for the frame pointer.
CSKYr14Used internally by LLVM for the stack pointer.
CSKYr15This is the link register.
CSKYr[26-30]Reserved by its ABI.
CSKYr31This is the TLS register.
Arm64ECxzrThis is a constant zero register which can't be modified.
Arm64ECx18This is an OS-reserved register.
Arm64ECx13, x14, x23, x24, x28, v[16-31]These are AArch64 registers that are not supported for Arm64EC.

Template modifiers

ArchitectureRegister classModifierExample outputLLVM modifier
MIPSregNone$2None
MIPSfregNone$f0None
NVPTXreg16Noners0None
NVPTXreg32Noner0None
NVPTXreg64Nonerd0None
HexagonregNoner0None
PowerPCregNone0None
PowerPCreg_nonzeroNone3None
PowerPCfregNone0None
s390xregNone%r0None
s390xreg_addrNone%r1None
s390xfregNone%f0None
CSKYregNoner0None
CSKYfregNonef0None
Arm64ECregNonex0x
Arm64ECregww0w
Arm64ECregxx0x
Arm64ECvregNonev0None
Arm64ECvregvv0None
Arm64ECvregbb0b
Arm64ECvreghh0h
Arm64ECvregss0s
Arm64ECvregdd0d
Arm64ECvregqq0q

Flags covered by preserves_flags

These flags registers must be restored upon exiting the asm block if the preserves_flags option is set:

  • AVR
    • The status register SREG.
  • MSP430
    • The status register r2.
  • M68k
    • The condition code register ccr.
  • s390x
    • The condition code register cc.
  • Arm64EC
    • Condition flags (NZCV register).
    • Floating-point status (FPSR register).