xref: /plan9-contrib/sys/src/ape/lib/ap/riscv/tas.s (revision ce95e1b3727b9cb1c223ffbed69aff21a8ced255)
1*ce95e1b3SDavid du Colombier/*
2*ce95e1b3SDavid du Colombier *	risc-v test-and-set
3*ce95e1b3SDavid du Colombier *	assumes A extension
4*ce95e1b3SDavid du Colombier */
5*ce95e1b3SDavid du Colombier
6*ce95e1b3SDavid du Colombier#define LINK	R1
7*ce95e1b3SDavid du Colombier#define SP	R2
8*ce95e1b3SDavid du Colombier#define ARG	8
9*ce95e1b3SDavid du Colombier
10*ce95e1b3SDavid du Colombier#define SYNC	WORD $0xf	/* FENCE */
11*ce95e1b3SDavid du Colombier#define LRW(rs2, rs1, rd) \
12*ce95e1b3SDavid du Colombier	WORD $((2<<27)|(    0<<20)|((rs1)<<15)|(2<<12)|((rd)<<7)|057)
13*ce95e1b3SDavid du Colombier#define SCW(rs2, rs1, rd) \
14*ce95e1b3SDavid du Colombier	WORD $((3<<27)|((rs2)<<20)|((rs1)<<15)|(2<<12)|((rd)<<7)|057)
15*ce95e1b3SDavid du Colombier
16*ce95e1b3SDavid du Colombier/* atomically set (RARG) non-zero and return previous contents */
17*ce95e1b3SDavid du Colombier	TEXT	_tas(SB), $-4
18*ce95e1b3SDavid du Colombier	MOVW	R(ARG), R12		/* address of key */
19*ce95e1b3SDavid du Colombier	MOVW	$1, R10
20*ce95e1b3SDavid du Colombier	SYNC
21*ce95e1b3SDavid du Colombiertas1:
22*ce95e1b3SDavid du Colombier	LRW(0, 12, ARG)	// LR_W R0, R12, RARG /* (R12) -> R(ARG) */
23*ce95e1b3SDavid du Colombier	SCW(10, 12, 14) // SC_W R10, R12, R14 /* R10 -> (R12) maybe, R14=0 if ok */
24*ce95e1b3SDavid du Colombier	BNE	R14, tas1
25*ce95e1b3SDavid du Colombier	RET
26