xref: /plan9-contrib/sys/src/ape/lib/ap/arm/tas.s (revision 43fc641d02286a1fe4c6ca8065ef945254a88744)
1#define DMB	MCR 15, 0, R0, C7, C10, 5
2#define	STREX(f,tp,r) WORD $(0xe<<28|0x01800f90 | (tp)<<16 | (r)<<12 | (f)<<0)
3#define	LDREX(fp,t)   WORD $(0xe<<28|0x01900f9f | (fp)<<16 | (t)<<12)
4#define	CLREX	WORD	$0xf57ff01f
5
6TEXT	tas(SB), $-4			/* tas(ulong *) */
7	/* returns old (R0) after modifying (R0) */
8	MOVW	R0,R5
9	MOVW	$0, R0
10	DMB
11
12	MOVW	$1,R2		/* new value of (R0) */
13tas1:
14	LDREX(5,1)		/* LDREX 0(R5),R1 */
15	CMP.S	$0, R1		/* old value non-zero (lock taken)? */
16	BNE	lockbusy	/* we lose */
17	STREX(2,5,4)		/* STREX R2,(R5),R4 */
18	CMP.S	$0, R4
19	BNE	tas1		/* strex failed? try again */
20	MOVW	$0, R0
21	DMB
22	MOVW	R1, R0
23	RET
24lockbusy:
25	CLREX
26	MOVW	$0, R0
27	DMB
28	MOVW	R1, R0
29	RET
30