atomic_arch.h (1527B)
1 /* tcc-build riscv64 atomic_arch.h replacement. 2 * 3 * Stock musl uses inline asm with named operand constraints 4 * (`"=&r"(old), "r"(p)`) and the LR/SC mnemonics 5 * (`lr.w.aqrl` / `sc.w.aqrl`). tcc 0.9.26's riscv64 frontend lacks 6 * the operand-substitution path entirely (errors with "RISCV64 asm 7 * not implemented"), and riscv64-asm.c has no LR/SC entries in its 8 * mnemonic table. 9 * 10 * boot4 produces a static, single-threaded smoke binary, so we don't 11 * need true atomicity. Provide a_cas / a_cas_p as ordinary C inline 12 * functions; musl's src/internal/atomic.h derives a_swap, a_inc, 13 * a_dec, a_or, a_and, a_fetch_add, a_store, etc. from a_cas. A real 14 * atomic implementation would need raw .long encoding of LR/SC inside 15 * an extern asm helper (cf. aarch64), but that adds encoding 16 * complexity for a property the smoke binary doesn't depend on. 17 */ 18 19 #define a_cas a_cas 20 static inline int a_cas(volatile int *p, int t, int s) 21 { 22 int old = *p; 23 if (old == t) *p = s; 24 return old; 25 } 26 27 #define a_cas_p a_cas_p 28 static inline void *a_cas_p(volatile void *p, void *t, void *s) 29 { 30 void **pp = (void **)p; 31 void *old = *pp; 32 if (old == t) *pp = s; 33 return old; 34 } 35 36 #define a_barrier a_barrier 37 static inline void a_barrier(void) 38 { 39 /* `fence` (nullary) is in tcc's riscv64-asm.c table; it emits a 40 full memory fence with all pred/succ bits zero (effectively a 41 no-op, but still serves as a compiler barrier here). The 42 stock `fence rw,rw` form needs operand parsing tcc lacks. */ 43 __asm__ __volatile__ ("fence"); 44 }