1#define DMB MCR 15, 0, R0, C7, C10, 5 2#define STREX(f,tp,r) WORD $(0xe<<28|0x01800f90 | (tp)<<16 | (r)<<12 | (f)<<0) 3#define LDREX(fp,t) WORD $(0xe<<28|0x01900f9f | (fp)<<16 | (t)<<12) 4#define CLREX WORD $0xf57ff01f 5 6TEXT tas(SB), $-4 /* tas(ulong *) */ 7 /* returns old (R0) after modifying (R0) */ 8 MOVW R0,R5 9 MOVW $0, R0 10 DMB 11 12 MOVW $1,R2 /* new value of (R0) */ 13tas1: 14 LDREX(5,1) /* LDREX 0(R5),R1 */ 15 CMP.S $0, R1 /* old value non-zero (lock taken)? */ 16 BNE lockbusy /* we lose */ 17 STREX(2,5,4) /* STREX R2,(R5),R4 */ 18 CMP.S $0, R4 19 BNE tas1 /* strex failed? try again */ 20 MOVW $0, R0 21 DMB 22 MOVW R1, R0 23 RET 24lockbusy: 25 CLREX 26 MOVW $0, R0 27 DMB 28 MOVW R1, R0 29 RET 30