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