Skip to content

Commit c41b359

Browse files
committed
Remove references to unstable parts of asm!
1 parent 0719c11 commit c41b359

File tree

1 file changed

+6
-74
lines changed

1 file changed

+6
-74
lines changed

src/inline-assembly.md

+6-74
Original file line numberDiff line numberDiff line change
@@ -10,26 +10,19 @@ dir_spec := "in" / "out" / "lateout" / "inout" / "inlateout"
1010
reg_spec := <register class> / "<explicit register>"
1111
operand_expr := expr / "_" / expr "=>" expr / expr "=>" "_"
1212
reg_operand := dir_spec "(" reg_spec ")" operand_expr
13-
operand := reg_operand / "const" const_expr / "sym" path
13+
operand := reg_operand
1414
clobber_abi := "clobber_abi(" <abi> *["," <abi>] [","] ")"
1515
option := "pure" / "nomem" / "readonly" / "preserves_flags" / "noreturn" / "nostack" / "att_syntax" / "raw"
1616
options := "options(" option *["," option] [","] ")"
1717
asm := "asm!(" format_string *("," format_string) *("," [ident "="] operand) *("," clobber_abi) *("," options) [","] ")"
1818
global_asm := "global_asm!(" format_string *("," format_string) *("," [ident "="] operand) *("," options) [","] ")"
1919
```
2020

21-
Inline assembly is currently supported on the following architectures:
21+
Support for inline assembly is stable on the following architectures:
2222
- x86 and x86-64
2323
- ARM
2424
- AArch64
2525
- RISC-V
26-
- NVPTX
27-
- PowerPC
28-
- Hexagon
29-
- MIPS
30-
- WebAssembly
31-
- BPF
32-
- SPIR-V
3326

3427
Support for more targets may be added in the future. The compiler will emit an error if `asm!` is used on an unsupported target.
3528

@@ -86,22 +79,14 @@ Several types of operands are supported:
8679
* `inlateout(<reg>) <expr>` / `inlateout(<reg>) <in expr> => <out expr>`
8780
- Identical to `inout` except that the register allocator can reuse a register allocated to an `in` (this can happen if the compiler knows the `in` has the same initial value as the `inlateout`).
8881
- You should only write to the register after all inputs are read, otherwise you may clobber an input.
89-
* `const <expr>`
90-
- `<expr>` must be an integer constant expression.
91-
- The value of the expression is formatted as a string and substituted directly into the asm template string.
92-
* `sym <path>`
93-
- `<path>` must refer to a `fn` or `static`.
94-
- A mangled symbol name referring to the item is substituted into the asm template string.
95-
- The substituted string does not include any modifiers (e.g. GOT, PLT, relocations, etc).
96-
- `<path>` is allowed to point to a `#[thread_local]` static, in which case the asm code can combine the symbol with relocations (e.g. `@plt`, `@TPOFF`) to read from thread-local data.
9782

9883
Operand expressions are evaluated from left to right, just like function call arguments. After the `asm!` has executed, outputs are written to in left to right order. This is significant if two outputs point to the same place: that place will contain the value of the rightmost output.
9984

100-
Since `global_asm!` exists outside a function, only `const` and `sym` operands can be used with it.
85+
Since `global_asm!` exists outside a function, it cannot use input/output operands.
10186

10287
## Register operands
10388

104-
Input and output operands can be specified either as an explicit register or as a register class from which the register allocator can select a register. Explicit registers are specified as string literals (e.g. `"eax"`) while register classes are specified as identifiers (e.g. `reg`). Using string literals for register names enables support for architectures that use special characters in register names, such as MIPS (`$0`, `$1`, etc).
89+
Input and output operands can be specified either as an explicit register or as a register class from which the register allocator can select a register. Explicit registers are specified as string literals (e.g. `"eax"`) while register classes are specified as identifiers (e.g. `reg`).
10590

10691
Note that explicit registers treat register aliases (e.g. `r14` vs `lr` on ARM) and smaller views of a register (e.g. `eax` vs `rax`) as equivalent to the base register. It is a compile-time error to use the same explicit register for two input operands or two output operands. Additionally, it is also a compile-time error to use overlapping registers (e.g. ARM VFP) in input operands or in output operands.
10792

@@ -141,33 +126,15 @@ Here is the list of currently supported register classes:
141126
| ARM | `qreg` | `q[0-15]` | `w` |
142127
| ARM | `qreg_low8` | `q[0-7]` | `t` |
143128
| ARM | `qreg_low4` | `q[0-3]` | `x` |
144-
| MIPS | `reg` | `$[2-25]` | `r` |
145-
| MIPS | `freg` | `$f[0-31]` | `f` |
146-
| NVPTX | `reg16` | None\* | `h` |
147-
| NVPTX | `reg32` | None\* | `r` |
148-
| NVPTX | `reg64` | None\* | `l` |
149129
| RISC-V | `reg` | `x1`, `x[5-7]`, `x[9-15]`, `x[16-31]` (non-RV32E) | `r` |
150130
| RISC-V | `freg` | `f[0-31]` | `f` |
151131
| RISC-V | `vreg` | `v[0-31]` | Only clobbers |
152-
| Hexagon | `reg` | `r[0-28]` | `r` |
153-
| PowerPC | `reg` | `r[0-31]` | `r` |
154-
| PowerPC | `reg_nonzero` | | `r[1-31]` | `b` |
155-
| PowerPC | `freg` | `f[0-31]` | `f` |
156-
| PowerPC | `cr` | `cr[0-7]`, `cr` | Only clobbers |
157-
| PowerPC | `xer` | `xer` | Only clobbers |
158-
| wasm32 | `local` | None\* | `r` |
159-
| BPF | `reg` | `r[0-10]` | `r` |
160-
| BPF | `wreg` | `w[0-10]` | `w` |
161132

162133
> **Notes**:
163134
> - On x86 we treat `reg_byte` differently from `reg` because the compiler can allocate `al` and `ah` separately whereas `reg` reserves the whole register.
164135
>
165136
> - On x86-64 the high byte registers (e.g. `ah`) are not available in the `reg_byte` register class.
166137
>
167-
> - NVPTX doesn't have a fixed register set, so named registers are not supported.
168-
>
169-
> - WebAssembly doesn't have registers, so named registers are not supported.
170-
>
171138
> - Some register classes are marked as "Only clobbers" which means that they cannot be used for inputs or outputs, only clobbers of the form `out("reg") _` or `lateout("reg") _`.
172139
173140
Additional register classes may be added in the future based on demand (e.g. MMX, x87, etc).
@@ -193,27 +160,11 @@ Each register class has constraints on which value types they can be used with.
193160
| ARM | `sreg` | `vfp2` | `i32`, `f32` |
194161
| ARM | `dreg` | `vfp2` | `i64`, `f64`, `i8x8`, `i16x4`, `i32x2`, `i64x1`, `f32x2` |
195162
| ARM | `qreg` | `neon` | `i8x16`, `i16x8`, `i32x4`, `i64x2`, `f32x4` |
196-
| MIPS32 | `reg` | None | `i8`, `i16`, `i32`, `f32` |
197-
| MIPS32 | `freg` | None | `f32`, `f64` |
198-
| MIPS64 | `reg` | None | `i8`, `i16`, `i32`, `i64`, `f32`, `f64` |
199-
| MIPS64 | `freg` | None | `f32`, `f64` |
200-
| NVPTX | `reg16` | None | `i8`, `i16` |
201-
| NVPTX | `reg32` | None | `i8`, `i16`, `i32`, `f32` |
202-
| NVPTX | `reg64` | None | `i8`, `i16`, `i32`, `f32`, `i64`, `f64` |
203163
| RISC-V32 | `reg` | None | `i8`, `i16`, `i32`, `f32` |
204164
| RISC-V64 | `reg` | None | `i8`, `i16`, `i32`, `f32`, `i64`, `f64` |
205165
| RISC-V | `freg` | `f` | `f32` |
206166
| RISC-V | `freg` | `d` | `f64` |
207167
| RISC-V | `vreg` | N/A | Only clobbers |
208-
| Hexagon | `reg` | None | `i8`, `i16`, `i32`, `f32` |
209-
| PowerPC | `reg` | None | `i8`, `i16`, `i32` |
210-
| PowerPC | `reg_nonzero` | None | `i8`, `i16`, `i32` |
211-
| PowerPC | `freg` | None | `f32`, `f64` |
212-
| PowerPC | `cr` | N/A | Only clobbers |
213-
| PowerPC | `xer` | N/A | Only clobbers |
214-
| wasm32 | `local` | None | `i8` `i16` `i32` `i64` `f32` `f64` |
215-
| BPF | `reg` | None | `i8` `i16` `i32` `i64` |
216-
| BPF | `wreg` | `alu32` | `i8` `i16` `i32` |
217168

218169
> **Note**: 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).
219170
@@ -270,34 +221,24 @@ Some registers have multiple names. These are all treated by the compiler as ide
270221
| RISC-V | `f[10-17]` | `fa[0-7]` |
271222
| RISC-V | `f[18-27]` | `fs[2-11]` |
272223
| RISC-V | `f[28-31]` | `ft[8-11]` |
273-
| Hexagon | `r29` | `sp` |
274-
| Hexagon | `r30` | `fr` |
275-
| Hexagon | `r31` | `lr` |
276-
| BPF | `r[0-10]` | `w[0-10]` |
277224

278225
Some registers cannot be used for input or output operands:
279226

280227
| Architecture | Unsupported register | Reason |
281228
| ------------ | -------------------- | ------ |
282229
| All | `sp` | The stack pointer must be restored to its original value at the end of an asm code block. |
283-
| All | `bp` (x86), `x29` (AArch64), `x8` (RISC-V), `fr` (Hexagon), `$fp` (MIPS) | The frame pointer cannot be used as an input or output. |
230+
| All | `bp` (x86), `x29` (AArch64), `x8` (RISC-V) | The frame pointer cannot be used as an input or output. |
284231
| 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. |
285-
| All | `si` (x86-32), `bx` (x86-64), `r6` (ARM), `x19` (AArch64), `r19` (Hexagon), `x9` (RISC-V) | This is used internally by LLVM as a "base pointer" for functions with complex stack frames. |
232+
| 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. |
286233
| x86 | `k0` | This is a constant zero register which can't be modified. |
287234
| x86 | `ip` | This is the program counter, not a real register. |
288235
| x86 | `mm[0-7]` | MMX registers are not currently supported (but may be in the future). |
289236
| x86 | `st([0-7])` | x87 registers are not currently supported (but may be in the future). |
290237
| AArch64 | `xzr` | This is a constant zero register which can't be modified. |
291238
| ARM | `pc` | This is the program counter, not a real register. |
292239
| ARM | `r9` | This is a reserved register on some ARM targets. |
293-
| MIPS | `$0` or `$zero` | This is a constant zero register which can't be modified. |
294-
| MIPS | `$1` or `$at` | Reserved for assembler. |
295-
| MIPS | `$26`/`$k0`, `$27`/`$k1` | OS-reserved registers. |
296-
| MIPS | `$28`/`$gp` | Global pointer cannot be used as inputs or outputs. |
297-
| MIPS | `$ra` | Return address cannot be used as inputs or outputs. |
298240
| RISC-V | `x0` | This is a constant zero register which can't be modified. |
299241
| RISC-V | `gp`, `tp` | These registers are reserved and cannot be used as inputs or outputs. |
300-
| Hexagon | `lr` | This is the link register which cannot be used as an input or output. |
301242

302243
In some cases LLVM will allocate a "reserved register" for `reg` operands even though this register cannot be explicitly specified. Assembly code making use of reserved registers should be careful since `reg` operands may alias with those registers. Reserved registers are the frame pointer and base pointer
303244
- The frame pointer and LLVM base pointer on all architectures.
@@ -343,17 +284,8 @@ The supported modifiers are a subset of LLVM's (and GCC's) [asm template argumen
343284
| ARM | `dreg` | None | `d0` | `P` |
344285
| ARM | `qreg` | None | `q0` | `q` |
345286
| ARM | `qreg` | `e` / `f` | `d0` / `d1` | `e` / `f` |
346-
| MIPS | `reg` | None | `$2` | None |
347-
| MIPS | `freg` | None | `$f0` | None |
348-
| NVPTX | `reg16` | None | `rs0` | None |
349-
| NVPTX | `reg32` | None | `r0` | None |
350-
| NVPTX | `reg64` | None | `rd0` | None |
351287
| RISC-V | `reg` | None | `x1` | None |
352288
| RISC-V | `freg` | None | `f0` | None |
353-
| Hexagon | `reg` | None | `r0` | None |
354-
| PowerPC | `reg` | None | `0` | None |
355-
| PowerPC | `reg_nonzero` | None | `3` | `b` |
356-
| PowerPC | `freg` | None | `0` | None |
357289

358290
> **Notes**:
359291
> - on ARM `e` / `f`: this prints the low or high doubleword register name of a NEON quad (128-bit) register.

0 commit comments

Comments
 (0)