RISCV Inline Assembly in GCC: Atomic Load/Store

Viewed 1032

Edit:

I believe that the clue here was "Illegal *operand". The problem was with operands. I changed some operand ATTRIBUTES from "m" (or whatever) to "A", and I made progress. For RISC-V, if you are passing an address/pointer, you must use "A" attribute!


Colleagues!

Please consider this block of inline gcc assembly (excerpted from foo.c):

  asm volatile(
    "als_%=:\n\t"
    "  lr.w.aq  t1, %[src]\n\t"
    "  sc.w.rl  t0, t1, %[dst]\n\t"
    "  bnez     t0, als_%="
    : [dst] "=&m" (*((uint32_t*)(0x27402448ULL)))
    : [src] "m"   (*((uint32_t*)(0x000a0018ULL))));  
  • It intends to, first, load the contents of the source address to t1.
  • Then to, second, store the contents of t1 to the destination address.
  • Finally, if the store fails (looking at status in t0), then the process will be attempted again.

Note that there is no "symbol" at these addresses. We're running bare-metal code, creating pathological coherency scenarios among "interesting" random memory locations.

I get this error using SiFive's pre-built gcc-8.3.0:

foo.c: Assembler messages:
foo.c:1106: Error: illegal operands `lr.w t1,8(a4)`
foo.c:1107: Error: illegal operands `sc.w t0,t1,1048(s0)`

I've tried to la from those locations into temporary registers and then to use the registers in the ld/st instructions, but I get similar errors on the la.

My command line is:

/path/to/riscv64-unknown-elf-gcc-8.3.0-2019.08.0-x86_64-linux-centos6/bin/riscv64-unknown-elf-gcc \
-ggdb3 \
-std=gnu99 \
-Wall -Wextra -Werror -Wshadow -Wstack-usage=1024 -Wno-implicit-fallthrough -Wno-unused-parameter \
-ffunction-sections \
-fdata-sections \
-I/path/to/target/include \
--specs=nano.specs \
-Os \
-nostartfiles \
-nostdlib \
-Xlinker -Map=foo.map \
-march=rv64imafdc \
-mabi=lp64d \
-mcmodel=medany \
-malign-data=natural \
-mriscv-attribute \
-I/path/to/freedom-e-sdk/bsp/qemu-sifive-u54mc/install/include \
-L/path/to/freedom-e-sdk/bsp/qemu-sifive-u54mc/install/lib/debug \
foo.c \
-T../riscv64/link.ld \
-Wl,--start-group \
  -lc -lgcc -lm -lmetal -lmetal-gloss \
-Wl,--end-group \
-Wl,--gc-sections \
-o foo.elf;
0 Answers
Related