xref: /plan9-contrib/sys/src/libc/riscv64/tas.s (revision ce95e1b3727b9cb1c223ffbed69aff21a8ced255)
1/*
2 *	risc-v test-and-set
3 *	assumes the standard A extension
4 */
5
6#define ARG	8
7
8#define MASK(w)	((1<<(w))-1)
9#define FENCE	WORD $(0xf | MASK(8)<<20)  /* all i/o, mem ops before & after */
10#define AQ	(1<<26)			/* acquire */
11#define RL	(1<<25)			/* release */
12#define LRW(rs1, rd) \
13	WORD $((2<<27)|(    0<<20)|((rs1)<<15)|(2<<12)|((rd)<<7)|057|AQ)
14#define SCW(rs2, rs1, rd) \
15	WORD $((3<<27)|((rs2)<<20)|((rs1)<<15)|(2<<12)|((rd)<<7)|057|AQ|RL)
16
17/* atomically set *keyp non-zero and return previous contents */
18TEXT	_tas(SB), $-4		/* int _tas(ulong *keyp) */
19	MOV	R(ARG), R12		/* address of key */
20	MOV	$1, R10
21	FENCE
22tas1:
23	LRW(12, ARG)			/* (R12) -> R(ARG) */
24	SCW(10, 12, 14)			/* R10 -> (R12) maybe, R14=0 if ok */
25	BNE	R14, tas1
26	RET
27