xref: /plan9-contrib/sys/src/ape/lib/ap/arm/atom.s (revision 43fc641d02286a1fe4c6ca8065ef945254a88744)
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 *); */
34spinainc:
35	LDREX(0,3)	/*	LDREX	0(R0),R3	*/
36	ADD	$1,R3
37	STREX(3,0,4)	/*	STREX	0(R0),R3,R4	*/
38	CMP.S	$0, R4
39	BNE	spinainc
40	MOVW	$0, R0
41	DMB
42	MOVW	R3, R0
43	RET
44
45TEXT _xdec(SB), $0	/* long _xdec(long *); */
46TEXT adec(SB), $0	/* long adec(long *); */
47spinadec:
48	LDREX(0,3)	/*	LDREX	0(R0),R3	*/
49	SUB	$1,R3
50	STREX(3,0,4)	/*	STREX	0(R0),R3,R4	*/
51	CMP.S	$0, R4
52	BNE	spinadec
53	MOVW	$0, R0
54	DMB
55	MOVW	R3, R0
56	RET
57
58TEXT loadlinked(SB), $0	/* long loadlinked(long *); */
59	LDREX(0,0)	/*	LDREX	0(R0),R0	*/
60	RET
61
62TEXT storecond(SB), $0	/* int storecond(long *, long); */
63	MOVW	ov+4(FP), R3
64	STREX(3,0,4)	/*	STREX	0(R0),R3,R4	*/
65	MOVW	$0, R0
66	DMB
67	RSB	$1, R4, R0
68	RET
69