Skip to content

Commit 1b09eb2

Browse files
committed
Sync with latest changes to the unstable book
1 parent cb05739 commit 1b09eb2

File tree

1 file changed

+14
-13
lines changed

1 file changed

+14
-13
lines changed

src/inline-assembly.md

+14-13
Original file line numberDiff line numberDiff line change
@@ -42,9 +42,9 @@ reg_spec := <register class> / "<explicit register>"
4242
operand_expr := expr / "_" / expr "=>" expr / expr "=>" "_"
4343
reg_operand := dir_spec "(" reg_spec ")" operand_expr
4444
operand := reg_operand
45-
clobber_abi := "clobber_abi(" <abi> *["," <abi>] [","] ")"
45+
clobber_abi := "clobber_abi(" <abi> *("," <abi>) [","] ")"
4646
option := "pure" / "nomem" / "readonly" / "preserves_flags" / "noreturn" / "nostack" / "att_syntax" / "raw"
47-
options := "options(" option *["," option] [","] ")"
47+
options := "options(" option *("," option) [","] ")"
4848
asm := "asm!(" format_string *("," format_string) *("," [ident "="] operand) *("," clobber_abi) *("," options) [","] ")"
4949
global_asm := "global_asm!(" format_string *("," format_string) *("," [ident "="] operand) *("," options) [","] ")"
5050
```
@@ -161,9 +161,8 @@ Here is the list of currently supported register classes:
161161
| AArch64 | `vreg` | `v[0-31]` | `w` |
162162
| AArch64 | `vreg_low16` | `v[0-15]` | `x` |
163163
| AArch64 | `preg` | `p[0-15]`, `ffr` | Only clobbers |
164-
| ARM | `reg` | `r[0-12]`, `r14` | `r` |
165-
| ARM (Thumb) | `reg_thumb` | `r[0-r7]` | `l` |
166-
| ARM (ARM) | `reg_thumb` | `r[0-r12]`, `r14` | `l` |
164+
| ARM (ARM/Thumb2) | `reg` | `r[0-12]`, `r14` | `r` |
165+
| ARM (Thumb1) | `reg` | `r[0-7]` | `r` |
167166
| ARM | `sreg` | `s[0-31]` | `t` |
168167
| ARM | `sreg_low16` | `s[0-15]` | `x` |
169168
| ARM | `dreg` | `d[0-31]` | `w` |
@@ -284,21 +283,16 @@ Some registers cannot be used for input or output operands:
284283
| All | `si` (x86-32), `bx` (x86-64), `r6` (ARM), `x19` (AArch64), `x9` (RISC-V) | This is used internally by LLVM as a "base pointer" for functions with complex stack frames. |
285284
| x86 | `k0` | This is a constant zero register which can't be modified. |
286285
| x86 | `ip` | This is the program counter, not a real register. |
287-
| x86 | `mm[0-7]` | MMX registers are not currently supported (but may be in the future). |
288-
| x86 | `st([0-7])` | x87 registers are not currently supported (but may be in the future). |
289286
| AArch64 | `xzr` | This is a constant zero register which can't be modified. |
287+
| AArch64 | `x18` | This is a reserved register on some AArch64 targets. |
290288
| ARM | `pc` | This is the program counter, not a real register. |
291289
| ARM | `r9` | This is a reserved register on some ARM targets. |
292290
| RISC-V | `x0` | This is a constant zero register which can't be modified. |
293291
| RISC-V | `gp`, `tp` | These registers are reserved and cannot be used as inputs or outputs. |
294292

295293
In some cases LLVM will allocate a "reserved register" for `reg` operands even though this register cannot be explicitly specified.
296294
Assembly code making use of reserved registers should be careful since `reg` operands may alias with those registers.
297-
298-
These reserved registers are:
299-
- The frame pointer and LLVM base pointer on all architectures.
300-
- `r9` on ARM.
301-
- `x18` on AArch64.
295+
Reserved registers that can sometimes be allocated are the frame pointer and base pointer in the list above.
302296

303297
## Template modifiers
304298

@@ -362,6 +356,8 @@ If all references to an operand already have modifiers then the warning is suppr
362356
The `clobber_abi` keyword can be used to apply a default set of clobbers to an `asm!` block.
363357
This will automatically insert the necessary clobber constraints as needed for calling a function with a particular calling convention: if the calling convention does not fully preserve the value of a register across a call then a `lateout("reg") _` is implicitly added to the operands list.
364358

359+
`clobber_abi` may be specified any number of times. It will insert a clobber for all unique registers in the union of all specified calling conventions.
360+
365361
Generic register class outputs are disallowed by the compiler when `clobber_abi` is used: all outputs must specify an explicit register.
366362
Explicit register outputs have precedence over the implicit clobbers inserted by `clobber_abi`: a clobber will only be inserted for a register if that register is not used as an output.
367363
The following ABIs can be used with `clobber_abi`:
@@ -371,10 +367,13 @@ The following ABIs can be used with `clobber_abi`:
371367
| x86-32 | `"C"`, `"system"`, `"efiapi"`, `"cdecl"`, `"stdcall"`, `"fastcall"` | `ax`, `cx`, `dx`, `xmm[0-7]`, `mm[0-7]`, `k[1-7]`, `st([0-7])` |
372368
| x86-64 | `"C"`, `"system"` (on Windows), `"efiapi"`, `"win64"` | `ax`, `cx`, `dx`, `r[8-11]`, `xmm[0-31]`, `mm[0-7]`, `k[1-7]`, `st([0-7])` |
373369
| x86-64 | `"C"`, `"system"` (on non-Windows), `"sysv64"` | `ax`, `cx`, `dx`, `si`, `di`, `r[8-11]`, `xmm[0-31]`, `mm[0-7]`, `k[1-7]`, `st([0-7])` |
374-
| AArch64 | `"C"`, `"system"`, `"efiapi"` | `x[0-17]`, `x30`, `v[0-31]`, `p[0-15]`, `ffr` |
370+
| AArch64 | `"C"`, `"system"`, `"efiapi"` | `x[0-17]`, `x18`\*, `x30`, `v[0-31]`, `p[0-15]`, `ffr` |
375371
| ARM | `"C"`, `"system"`, `"efiapi"`, `"aapcs"` | `r[0-3]`, `r12`, `r14`, `s[0-15]`, `d[0-7]`, `d[16-31]` |
376372
| 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]` |
377373

374+
> Notes:
375+
> - On AArch64 `x18` only included in the clobber list if it is not considered as a reserved register on the target.
376+
378377
The list of clobbered registers for each ABI is updated in rustc as architectures gain new registers: this ensures that `asm!` clobbers will continue to be correct when LLVM starts using these new registers in its generated code.
379378

380379
## Options
@@ -469,5 +468,7 @@ To avoid undefined behavior, these rules must be followed when using function-sc
469468
- The set of memory locations that you may access is the intersection of those allowed by the `asm!` blocks you entered and exited.
470469
- You cannot assume that an `asm!` block will appear exactly once in the output binary.
471470
The compiler is allowed to instantiate multiple copies of the `asm!` block, for example when the function containing it is inlined in multiple places.
471+
- On x86, inline assembly must not end with an instruction prefix (such as `LOCK`) that would apply to instructions generated by the compiler.
472+
- The compiler is currently unable to detect this due to the way inline assembly is compiled, but may catch and reject this in the future.
472473

473474
> **Note**: As a general rule, the flags covered by `preserves_flags` are those which are *not* preserved when performing a function call.

0 commit comments

Comments
 (0)