You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
- 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`).
88
81
- 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.
97
82
98
83
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.
99
84
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.
101
86
102
87
## Register operands
103
88
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`).
105
90
106
91
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.
107
92
@@ -141,33 +126,15 @@ Here is the list of currently supported register classes:
> - On x86 we treat `reg_byte` differently from `reg` because the compiler can allocate `al` and `ah` separately whereas `reg` reserves the whole register.
164
135
>
165
136
> - On x86-64 the high byte registers (e.g. `ah`) are not available in the `reg_byte` register class.
166
137
>
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
-
>
171
138
> - 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") _`.
172
139
173
140
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.
193
160
| ARM |`sreg`|`vfp2`|`i32`, `f32`|
194
161
| ARM |`dreg`|`vfp2`|`i64`, `f64`, `i8x8`, `i16x4`, `i32x2`, `i64x1`, `f32x2`|
195
162
| ARM |`qreg`|`neon`|`i8x16`, `i16x8`, `i32x4`, `i64x2`, `f32x4`|
> **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).
219
170
@@ -270,34 +221,24 @@ Some registers have multiple names. These are all treated by the compiler as ide
270
221
| RISC-V |`f[10-17]`|`fa[0-7]`|
271
222
| RISC-V |`f[18-27]`|`fs[2-11]`|
272
223
| 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]`|
277
224
278
225
Some registers cannot be used for input or output operands:
279
226
280
227
| Architecture | Unsupported register | Reason |
281
228
| ------------ | -------------------- | ------ |
282
229
| 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. |
284
231
| 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. |
286
233
| x86 |`k0`| This is a constant zero register which can't be modified. |
287
234
| x86 |`ip`| This is the program counter, not a real register. |
288
235
| x86 |`mm[0-7]`| MMX registers are not currently supported (but may be in the future). |
289
236
| x86 |`st([0-7])`| x87 registers are not currently supported (but may be in the future). |
290
237
| AArch64 |`xzr`| This is a constant zero register which can't be modified. |
291
238
| ARM |`pc`| This is the program counter, not a real register. |
292
239
| 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. |
| MIPS |`$28`/`$gp`| Global pointer cannot be used as inputs or outputs. |
297
-
| MIPS |`$ra`| Return address cannot be used as inputs or outputs. |
298
240
| RISC-V |`x0`| This is a constant zero register which can't be modified. |
299
241
| 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. |
301
242
302
243
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
303
244
- 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
343
284
| ARM |`dreg`| None |`d0`|`P`|
344
285
| ARM |`qreg`| None |`q0`|`q`|
345
286
| 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 |
351
287
| RISC-V |`reg`| None |`x1`| None |
352
288
| 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 |
357
289
358
290
> **Notes**:
359
291
> - on ARM `e` / `f`: this prints the low or high doubleword register name of a NEON quad (128-bit) register.
0 commit comments