xref: /plan9-contrib/sys/src/libc/arm/atom.s (revision 424ff5fba102a9afd75c96acb80f750c1c923dbf)
143fc641dSDavid du Colombier#define DMB	MCR 15, 0, R0, C7, C10, 5
2bb9c7457SDavid du Colombier#define	CLREX		WORD	$0xf57ff01f
3f05caca4SDavid du Colombier#define	LDREX(a,r)	WORD	$(0xe<<28|0x01900f9f | (a)<<16 | (r)<<12)
4bb9c7457SDavid du Colombier/* `The order of operands is from left to right in dataflow order' - asm man */
5bb9c7457SDavid du Colombier#define	STREX(v,a,r)	WORD	$(0xe<<28|0x01800f90 | (a)<<16 | (r)<<12 | (v)<<0)
6f05caca4SDavid du Colombier
753ff6c4dSDavid du Colombier/*
853ff6c4dSDavid du Colombier * int cas(ulong *p, ulong ov, ulong nv);
953ff6c4dSDavid du Colombier */
1053ff6c4dSDavid du Colombier
110f53e541SDavid du ColombierTEXT	cas+0(SB),0,$0		/* r0 holds p */
120f53e541SDavid du ColombierTEXT	casp+0(SB),0,$0		/* r0 holds p */
13f05caca4SDavid du Colombier	MOVW	ov+4(FP), R1
14f05caca4SDavid du Colombier	MOVW	nv+8(FP), R2
15f05caca4SDavid du Colombierspincas:
16f05caca4SDavid du Colombier	LDREX(0,3)	/*	LDREX	0(R0),R3	*/
17f05caca4SDavid du Colombier	CMP.S	R3, R1
18f05caca4SDavid du Colombier	BNE	fail
19bb9c7457SDavid du Colombier	STREX(2,0,4)	/*	STREX	0(R0),R2,R4	*/
20f05caca4SDavid du Colombier	CMP.S	$0, R4
21f05caca4SDavid du Colombier	BNE	spincas
2243fc641dSDavid du Colombier	MOVW	$0, R0
2343fc641dSDavid du Colombier	DMB
24f05caca4SDavid du Colombier	MOVW	$1, R0
25f05caca4SDavid du Colombier	RET
26f05caca4SDavid du Colombierfail:
2753ff6c4dSDavid du Colombier	CLREX
28f05caca4SDavid du Colombier	MOVW	$0, R0
2943fc641dSDavid du Colombier	DMB
30f05caca4SDavid du Colombier	RET
31f05caca4SDavid du Colombier
32711e4d0eSDavid du ColombierTEXT _xinc(SB), $0	/* void	_xinc(long *); */
33f05caca4SDavid du ColombierTEXT ainc(SB), $0	/* long ainc(long *); */
34*424ff5fbSDavid du Colombier	DMB
35f05caca4SDavid du Colombierspinainc:
36f05caca4SDavid du Colombier	LDREX(0,3)	/*	LDREX	0(R0),R3	*/
37f05caca4SDavid du Colombier	ADD	$1,R3
38bb9c7457SDavid du Colombier	STREX(3,0,4)	/*	STREX	0(R0),R3,R4	*/
39f05caca4SDavid du Colombier	CMP.S	$0, R4
40f05caca4SDavid du Colombier	BNE	spinainc
4143fc641dSDavid du Colombier	MOVW	$0, R0
4243fc641dSDavid du Colombier	DMB
43f05caca4SDavid du Colombier	MOVW	R3, R0
44f05caca4SDavid du Colombier	RET
45f05caca4SDavid du Colombier
46711e4d0eSDavid du ColombierTEXT _xdec(SB), $0	/* long _xdec(long *); */
47711e4d0eSDavid du ColombierTEXT adec(SB), $0	/* long adec(long *); */
48*424ff5fbSDavid du Colombier	DMB
49f05caca4SDavid du Colombierspinadec:
50f05caca4SDavid du Colombier	LDREX(0,3)	/*	LDREX	0(R0),R3	*/
51f05caca4SDavid du Colombier	SUB	$1,R3
52bb9c7457SDavid du Colombier	STREX(3,0,4)	/*	STREX	0(R0),R3,R4	*/
53f05caca4SDavid du Colombier	CMP.S	$0, R4
54f05caca4SDavid du Colombier	BNE	spinadec
5543fc641dSDavid du Colombier	MOVW	$0, R0
5643fc641dSDavid du Colombier	DMB
57f05caca4SDavid du Colombier	MOVW	R3, R0
58f05caca4SDavid du Colombier	RET
59f05caca4SDavid du Colombier
60f05caca4SDavid du ColombierTEXT loadlinked(SB), $0	/* long loadlinked(long *); */
61f05caca4SDavid du Colombier	LDREX(0,0)	/*	LDREX	0(R0),R0	*/
62f05caca4SDavid du Colombier	RET
63f05caca4SDavid du Colombier
64f05caca4SDavid du ColombierTEXT storecond(SB), $0	/* int storecond(long *, long); */
65f05caca4SDavid du Colombier	MOVW	ov+4(FP), R3
6643fc641dSDavid du Colombier	STREX(3,0,4)	/*	STREX	0(R0),R3,R4	*/
6743fc641dSDavid du Colombier	MOVW	$0, R0
6843fc641dSDavid du Colombier	DMB
6943fc641dSDavid du Colombier	RSB	$1, R4, R0
70f05caca4SDavid du Colombier	RET
71