xref: /plan9/sys/src/ape/lib/ap/mips/atom.s (revision 51f48f69b4c3e5c9d9f7955d28612ef2d4048ccc)
1/*
2 *	R4000 user-level atomic operations
3 */
4
5#define	LL(base, rt)	WORD	$((060<<26)|((base)<<21)|((rt)<<16))
6#define	SC(base, rt)	WORD	$((070<<26)|((base)<<21)|((rt)<<16))
7#define	NOOP		WORD	$0x27
8
9TEXT ainc(SB), 1, $-4			/* long ainc(long *); */
10TEXT _xinc(SB), 1, $-4			/* void _xinc(long *); */
11	MOVW	R1, R2			/* address of counter */
12loop:	MOVW	$1, R3
13	LL(2, 1)
14	NOOP
15	ADDU	R1, R3
16	MOVW	R3, R1			/* return new value */
17	SC(2, 3)
18	NOOP
19	BEQ	R3,loop
20	RET
21
22TEXT adec(SB), 1, $-4			/* long adec(long*); */
23TEXT _xdec(SB), 1, $-4			/* long _xdec(long *); */
24	MOVW	R1, R2			/* address of counter */
25loop1:	MOVW	$-1, R3
26	LL(2, 1)
27	NOOP
28	ADDU	R1, R3
29	MOVW	R3, R1			/* return new value */
30	SC(2, 3)
31	NOOP
32	BEQ	R3,loop1
33	RET
34
35/*
36 * int cas(uint* p, int ov, int nv);
37 */
38TEXT cas(SB), 1, $-4
39	MOVW	ov+4(FP), R2
40	MOVW	nv+8(FP), R3
41spincas:
42	LL(1, 4)			/* R4 = *R1 */
43	NOOP
44	BNE	R2, R4, fail
45	SC(1, 3)			/* *R1 = R3 */
46	NOOP
47	BEQ	R3, spincas		/* R3 == 0 means store failed */
48	MOVW	$1, R1
49	RET
50fail:
51	MOVW	$0, R1
52	RET
53