1/* 2 * R4000 user-level atomic operations 3 */ 4 5#define LL(base, rt) WORD $((060<<26)|((base)<<21)|((rt)<<16)) 6#define SC(base, rt) WORD $((070<<26)|((base)<<21)|((rt)<<16)) 7#define NOOP WORD $0x27 8 9TEXT ainc(SB), 1, $-4 /* long ainc(long *); */ 10TEXT _xinc(SB), 1, $-4 /* void _xinc(long *); */ 11 MOVW R1, R2 /* address of counter */ 12loop: MOVW $1, R3 13 LL(2, 1) 14 NOOP 15 ADDU R1, R3 16 MOVW R3, R1 /* return new value */ 17 SC(2, 3) 18 NOOP 19 BEQ R3,loop 20 RET 21 22TEXT adec(SB), 1, $-4 /* long adec(long*); */ 23TEXT _xdec(SB), 1, $-4 /* long _xdec(long *); */ 24 MOVW R1, R2 /* address of counter */ 25loop1: MOVW $-1, R3 26 LL(2, 1) 27 NOOP 28 ADDU R1, R3 29 MOVW R3, R1 /* return new value */ 30 SC(2, 3) 31 NOOP 32 BEQ R3,loop1 33 RET 34 35/* 36 * int cas(uint* p, int ov, int nv); 37 */ 38TEXT cas(SB), 1, $-4 39 MOVW ov+4(FP), R2 40 MOVW nv+8(FP), R3 41spincas: 42 LL(1, 4) /* R4 = *R1 */ 43 NOOP 44 BNE R2, R4, fail 45 SC(1, 3) /* *R1 = R3 */ 46 NOOP 47 BEQ R3, spincas /* R3 == 0 means store failed */ 48 MOVW $1, R1 49 RET 50fail: 51 MOVW $0, R1 52 RET 53