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