xref: /plan9-contrib/sys/src/libc/arm/atom.s (revision 424ff5fba102a9afd75c96acb80f750c1c923dbf)
1#define DMB	MCR 15, 0, R0, C7, C10, 5
2#define	CLREX		WORD	$0xf57ff01f
3#define	LDREX(a,r)	WORD	$(0xe<<28|0x01900f9f | (a)<<16 | (r)<<12)
4/* `The order of operands is from left to right in dataflow order' - asm man */
5#define	STREX(v,a,r)	WORD	$(0xe<<28|0x01800f90 | (a)<<16 | (r)<<12 | (v)<<0)
6
7/*
8 * int cas(ulong *p, ulong ov, ulong nv);
9 */
10
11TEXT	cas+0(SB),0,$0		/* r0 holds p */
12TEXT	casp+0(SB),0,$0		/* r0 holds p */
13	MOVW	ov+4(FP), R1
14	MOVW	nv+8(FP), R2
15spincas:
16	LDREX(0,3)	/*	LDREX	0(R0),R3	*/
17	CMP.S	R3, R1
18	BNE	fail
19	STREX(2,0,4)	/*	STREX	0(R0),R2,R4	*/
20	CMP.S	$0, R4
21	BNE	spincas
22	MOVW	$0, R0
23	DMB
24	MOVW	$1, R0
25	RET
26fail:
27	CLREX
28	MOVW	$0, R0
29	DMB
30	RET
31
32TEXT _xinc(SB), $0	/* void	_xinc(long *); */
33TEXT ainc(SB), $0	/* long ainc(long *); */
34	DMB
35spinainc:
36	LDREX(0,3)	/*	LDREX	0(R0),R3	*/
37	ADD	$1,R3
38	STREX(3,0,4)	/*	STREX	0(R0),R3,R4	*/
39	CMP.S	$0, R4
40	BNE	spinainc
41	MOVW	$0, R0
42	DMB
43	MOVW	R3, R0
44	RET
45
46TEXT _xdec(SB), $0	/* long _xdec(long *); */
47TEXT adec(SB), $0	/* long adec(long *); */
48	DMB
49spinadec:
50	LDREX(0,3)	/*	LDREX	0(R0),R3	*/
51	SUB	$1,R3
52	STREX(3,0,4)	/*	STREX	0(R0),R3,R4	*/
53	CMP.S	$0, R4
54	BNE	spinadec
55	MOVW	$0, R0
56	DMB
57	MOVW	R3, R0
58	RET
59
60TEXT loadlinked(SB), $0	/* long loadlinked(long *); */
61	LDREX(0,0)	/*	LDREX	0(R0),R0	*/
62	RET
63
64TEXT storecond(SB), $0	/* int storecond(long *, long); */
65	MOVW	ov+4(FP), R3
66	STREX(3,0,4)	/*	STREX	0(R0),R3,R4	*/
67	MOVW	$0, R0
68	DMB
69	RSB	$1, R4, R0
70	RET
71