boot2

Playing with the boostrap
git clone https://git.ryansepassi.com/git/boot2.git
Log | Files | Refs | README

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 }