Skip to content

Commit ab85b2d

Browse files
authored
Merge pull request #1653 from taiki-e/arm64ec-asm
Add Arm64EC to inline-assembly documentation
2 parents 3f57ad3 + 0875fcd commit ab85b2d

File tree

1 file changed

+32
-14
lines changed

1 file changed

+32
-14
lines changed

src/inline-assembly.md

+32-14
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ r[asm.stable-targets]
1313
Support for inline assembly is stable on the following architectures:
1414
- x86 and x86-64
1515
- ARM
16-
- AArch64
16+
- AArch64 and Arm64EC
1717
- RISC-V
1818
- LoongArch
1919
- s390x
@@ -235,6 +235,9 @@ Here is the list of currently supported register classes:
235235
| AArch64 | `vreg` | `v[0-31]` | `w` |
236236
| AArch64 | `vreg_low16` | `v[0-15]` | `x` |
237237
| AArch64 | `preg` | `p[0-15]`, `ffr` | Only clobbers |
238+
| Arm64EC | `reg` | `x[0-12]`, `x[15-22]`, `x[25-27]`, `x30` | `r` |
239+
| Arm64EC | `vreg` | `v[0-15]` | `w` |
240+
| Arm64EC | `vreg_low16` | `v[0-15]` | `x` |
238241
| ARM (ARM/Thumb2) | `reg` | `r[0-12]`, `r14` | `r` |
239242
| ARM (Thumb1) | `reg` | `r[0-7]` | `r` |
240243
| ARM | `sreg` | `s[0-31]` | `t` |
@@ -283,6 +286,8 @@ The availability of supported types for a particular register class may depend o
283286
| AArch64 | `reg` | None | `i8`, `i16`, `i32`, `f32`, `i64`, `f64` |
284287
| AArch64 | `vreg` | `neon` | `i8`, `i16`, `i32`, `f32`, `i64`, `f64`, <br> `i8x8`, `i16x4`, `i32x2`, `i64x1`, `f32x2`, `f64x1`, <br> `i8x16`, `i16x8`, `i32x4`, `i64x2`, `f32x4`, `f64x2` |
285288
| AArch64 | `preg` | N/A | Only clobbers |
289+
| Arm64EC | `reg` | None | `i8`, `i16`, `i32`, `f32`, `i64`, `f64` |
290+
| Arm64EC | `vreg` | `neon` | `i8`, `i16`, `i32`, `f32`, `i64`, `f64`, <br> `i8x8`, `i16x4`, `i32x2`, `i64x1`, `f32x2`, `f64x1`, <br> `i8x16`, `i16x8`, `i32x4`, `i64x2`, `f32x4`, `f64x2` |
286291
| ARM | `reg` | None | `i8`, `i16`, `i32`, `f32` |
287292
| ARM | `sreg` | `vfp2` | `i32`, `f32` |
288293
| ARM | `dreg` | `vfp2` | `i64`, `f64`, `i8x8`, `i16x4`, `i32x2`, `i64x1`, `f32x2` |
@@ -339,6 +344,12 @@ Here is the list of all supported register aliases:
339344
| AArch64 | `sp` | `wsp` |
340345
| AArch64 | `xzr` | `wzr` |
341346
| AArch64 | `v[0-31]` | `b[0-31]`, `h[0-31]`, `s[0-31]`, `d[0-31]`, `q[0-31]` |
347+
| Arm64EC | `x[0-30]` | `w[0-30]` |
348+
| Arm64EC | `x29` | `fp` |
349+
| Arm64EC | `x30` | `lr` |
350+
| Arm64EC | `sp` | `wsp` |
351+
| Arm64EC | `xzr` | `wzr` |
352+
| Arm64EC | `v[0-15]` | `b[0-15]`, `h[0-15]`, `s[0-15]`, `d[0-15]`, `q[0-15]` |
342353
| ARM | `r[0-3]` | `a[1-4]` |
343354
| ARM | `r[4-9]` | `v[1-6]` |
344355
| ARM | `r9` | `rfp` |
@@ -383,12 +394,15 @@ Some registers cannot be used for input or output operands:
383394
| Architecture | Unsupported register | Reason |
384395
| ------------ | -------------------- | ------ |
385396
| All | `sp`, `r15` (s390x) | The stack pointer must be restored to its original value at the end of an asm code block. |
386-
| All | `bp` (x86), `x29` (AArch64), `x8` (RISC-V), `$fp` (LoongArch), `r11` (s390x) | The frame pointer cannot be used as an input or output. |
397+
| 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. |
387398
| 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. |
388-
| All | `si` (x86-32), `bx` (x86-64), `r6` (ARM), `x19` (AArch64), `x9` (RISC-V), `$s8` (LoongArch) | This is used internally by LLVM as a "base pointer" for functions with complex stack frames. |
399+
| 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. |
389400
| x86 | `ip` | This is the program counter, not a real register. |
390401
| AArch64 | `xzr` | This is a constant zero register which can't be modified. |
391402
| AArch64 | `x18` | This is an OS-reserved register on some AArch64 targets. |
403+
| Arm64EC | `xzr` | This is a constant zero register which can't be modified. |
404+
| Arm64EC | `x18` | This is an OS-reserved register. |
405+
| Arm64EC | `x13`, `x14`, `x23`, `x24`, `x28`, `v[16-31]`, `p[0-15]`, `ffr` | These are AArch64 registers that are not supported for Arm64EC. |
392406
| ARM | `pc` | This is the program counter, not a real register. |
393407
| ARM | `r9` | This is an OS-reserved register on some ARM targets. |
394408
| RISC-V | `x0` | This is a constant zero register which can't be modified. |
@@ -434,16 +448,16 @@ The supported modifiers are a subset of LLVM's (and GCC's) [asm template argumen
434448
| x86 | `*mm_reg` | `y` | `ymm0` | `t` |
435449
| x86 | `*mm_reg` | `z` | `zmm0` | `g` |
436450
| x86 | `kreg` | None | `k1` | None |
437-
| AArch64 | `reg` | None | `x0` | `x` |
438-
| AArch64 | `reg` | `w` | `w0` | `w` |
439-
| AArch64 | `reg` | `x` | `x0` | `x` |
440-
| AArch64 | `vreg` | None | `v0` | None |
441-
| AArch64 | `vreg` | `v` | `v0` | None |
442-
| AArch64 | `vreg` | `b` | `b0` | `b` |
443-
| AArch64 | `vreg` | `h` | `h0` | `h` |
444-
| AArch64 | `vreg` | `s` | `s0` | `s` |
445-
| AArch64 | `vreg` | `d` | `d0` | `d` |
446-
| AArch64 | `vreg` | `q` | `q0` | `q` |
451+
| AArch64/Arm64EC | `reg` | None | `x0` | `x` |
452+
| AArch64/Arm64EC | `reg` | `w` | `w0` | `w` |
453+
| AArch64/Arm64EC | `reg` | `x` | `x0` | `x` |
454+
| AArch64/Arm64EC | `vreg` | None | `v0` | None |
455+
| AArch64/Arm64EC | `vreg` | `v` | `v0` | None |
456+
| AArch64/Arm64EC | `vreg` | `b` | `b0` | `b` |
457+
| AArch64/Arm64EC | `vreg` | `h` | `h0` | `h` |
458+
| AArch64/Arm64EC | `vreg` | `s` | `s0` | `s` |
459+
| AArch64/Arm64EC | `vreg` | `d` | `d0` | `d` |
460+
| AArch64/Arm64EC | `vreg` | `q` | `q0` | `q` |
447461
| ARM | `reg` | None | `r0` | None |
448462
| ARM | `sreg` | None | `s0` | None |
449463
| ARM | `dreg` | None | `d0` | `P` |
@@ -497,6 +511,7 @@ The following ABIs can be used with `clobber_abi`:
497511
| x86-64 | `"C"`, `"system"` (on Windows), `"efiapi"`, `"win64"` | `ax`, `cx`, `dx`, `r[8-11]`, `xmm[0-31]`, `mm[0-7]`, `k[0-7]`, `st([0-7])`, `tmm[0-7]` |
498512
| x86-64 | `"C"`, `"system"` (on non-Windows), `"sysv64"` | `ax`, `cx`, `dx`, `si`, `di`, `r[8-11]`, `xmm[0-31]`, `mm[0-7]`, `k[0-7]`, `st([0-7])`, `tmm[0-7]` |
499513
| AArch64 | `"C"`, `"system"`, `"efiapi"` | `x[0-17]`, `x18`\*, `x30`, `v[0-31]`, `p[0-15]`, `ffr` |
514+
| Arm64EC | `"C"`, `"system"` | `x[0-12]`, `x[15-17]`, `x30`, `v[0-15]` |
500515
| ARM | `"C"`, `"system"`, `"efiapi"`, `"aapcs"` | `r[0-3]`, `r12`, `r14`, `s[0-15]`, `d[0-7]`, `d[16-31]` |
501516
| RISC-V | `"C"`, `"system"`, `"efiapi"` | `x1`, `x[5-7]`, `x[10-17]`, `x[28-31]`, `f[0-7]`, `f[10-17]`, `f[28-31]`, `v[0-31]` |
502517
| LoongArch | `"C"`, `"system"` | `$r1`, `$r[4-20]`, `$f[0-23]` |
@@ -632,7 +647,7 @@ r[asm.rules.preserved-registers]
632647
- Condition flags in `FPSCR` (N, Z, C, V)
633648
- Saturation flag in `FPSCR` (QC)
634649
- Floating-point exception flags in `FPSCR` (IDC, IXC, UFC, OFC, DZC, IOC).
635-
- AArch64
650+
- AArch64 and Arm64EC
636651
- Condition flags (`NZCV` register).
637652
- Floating-point status (`FPSR` register).
638653
- RISC-V
@@ -651,6 +666,9 @@ r[asm.rules.x86-x87]
651666
- On x86, the x87 floating-point register stack must remain unchanged unless all of the `st([0-7])` registers have been marked as clobbered with `out("st(0)") _, out("st(1)") _, ...`.
652667
- If all x87 registers are clobbered then the x87 register stack is guaranteed to be empty upon entering an `asm` block. Assembly code must ensure that the x87 register stack is also empty when exiting the asm block.
653668

669+
r[asm.rules.arm64ec]
670+
- On arm64ec, [call checkers with appropriate thunks](https://learn.microsoft.com/en-us/windows/arm/arm64ec-abi#authoring-arm64ec-in-assembly) are mandatory when calling functions.
671+
654672
r[asm.rules.only-on-exit]
655673
- The requirement of restoring the stack pointer and non-output registers to their original value only applies when exiting an `asm!` block.
656674
- This means that `asm!` blocks that never return (even if not marked `noreturn`) don't need to preserve these registers.

0 commit comments

Comments
 (0)