Skip to content

Commit 426001d

Browse files
authored
Merge pull request #33 from kito-cheng/inline-asm-constraint
Add operand constraint for inline asm statement.
2 parents dccfa30 + e0be2d6 commit 426001d

File tree

1 file changed

+63
-0
lines changed

1 file changed

+63
-0
lines changed

riscv-c-api.md

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -213,3 +213,66 @@ long __riscv_clmul (long a, long b); // clmul rd, rs1, rs2
213213
#include <riscv_vector.h> // make RISC-V vector intrinsics available
214214
vint8m1_t __riscv_vadd_vv_i8m1(vint8m1_t vs2, vint8m1_t vs1, size_t vl); // vadd.vv vd, vs2, vs1
215215
```
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

Comments
 (0)