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