@@ -213,3 +213,66 @@ long __riscv_clmul (long a, long b); // clmul rd, rs1, rs2
213
213
#include <riscv_vector.h> // make RISC-V vector intrinsics available
214
214
vint8m1_t __riscv_vadd_vv_i8m1(vint8m1_t vs2, vint8m1_t vs1, size_t vl); // vadd.vv vd, vs2, vs1
215
215
```
216
+
217
+ ## Constraints on Operands of Inline Assembly Statements
218
+
219
+ This section lists operand constraints that can be used with inline assembly
220
+ statements, including both RISC-V specific and common operand constraints.
221
+
222
+
223
+ | Constraint | | Note |
224
+ | ------------------ | ---------------------------------- | ----------- |
225
+ | m | An address that is held in a general-purpose register with offset. | |
226
+ | A | An address that is held in a general-purpose register. | |
227
+ | r | General purpose register | |
228
+ | f | Floating-point register | |
229
+ | i | Immediate integer operand | |
230
+ | I | 12-bit signed immediate integer operand | |
231
+ | K | 5-bit unsigned immediate integer operand | |
232
+ | J | Zero integer immediate operand | |
233
+
234
+ NOTE: Immediate value must be a compile-time constant.
235
+
236
+ ### The Difference Between ` m ` and ` A ` Constraints
237
+
238
+ The difference between ` m ` and ` A ` is whether the operand can have an offset;
239
+ some instructions in RISC-V do not allow an offset for the address operand,
240
+ such as atomic or vector load/store instructions.
241
+
242
+ The following example demonstrates the difference; it is trying
243
+ to load value from ` foo[10] ` and using ` m ` and ` A ` to pass that address.
244
+
245
+ ``` c
246
+ int *foo;
247
+ void bar () {
248
+ int x;
249
+ __ asm__ volatile ("lw %0, %1" : "=r"(x) : "m" (foo[ 10] ));
250
+ __ asm__ volatile ("lw %0, %1" : "=r"(x) : "A" (foo[ 10] ));
251
+ }
252
+ ```
253
+
254
+ Then we compile with GCC with ` -O ` option:
255
+
256
+ ``` shell
257
+ $ riscv64-unknown-elf-gcc x.c -o - -O -S
258
+ ...
259
+ bar:
260
+ lui a5,%hi(foo)
261
+ ld a5,%lo(foo)(a5)
262
+ # APP
263
+ # 4 "x.c" 1
264
+ lw a4, 40(a5)
265
+ # 0 "" 2
266
+ # NO_APP
267
+ addi a5,a5,40
268
+ # APP
269
+ # 5 "x.c" 1
270
+ lw a5, 0(a5)
271
+ # 0 "" 2
272
+ # NO_APP
273
+ ret
274
+
275
+ ```
276
+
277
+ The compiler uses an immediate offset of 40 for the ` m ` constraint, but for the
278
+ ` A ` constraint uses an extra addi instruction instead.
0 commit comments