1TEXT ainc(SB), 1, $-4 /* int ainc(int*); */ 2 MOVL arg+0(FP), BX 3 MOVL $1, AX 4 LOCK; BYTE $0x0f; BYTE $0xc1; BYTE $0x03/* XADDL AX, (BX) */ 5 ADDL $1, AX /* overflow if -ve or 0 */ 6 RET 7 8TEXT adec(SB), 1, $-4 /* int adec(int*); */ 9 MOVL arg+0(FP), BX 10 MOVL $-1, AX 11 LOCK; BYTE $0x0f; BYTE $0xc1; BYTE $0x03/* XADDL AX, (BX) */ 12 SUBL $1, AX /* underflow if -ve */ 13 RET 14 15/* 16 * int cas32(u32int *p, u32int ov, u32int nv); 17 * int cas(uint *p, int ov, int nv); 18 * int casp(void **p, void *ov, void *nv); 19 * int casl(ulong *p, ulong ov, ulong nv); 20 */ 21 22/* 23 * CMPXCHG (CX), DX: 0000 1111 1011 000w oorr rmmm, 24 * mmm = CX = 001; rrr = DX = 010 25 */ 26 27#define CMPXCHG BYTE $0x0F; BYTE $0xB1; BYTE $0x11 28 29TEXT cas32+0(SB),0,$0 30TEXT cas+0(SB),0,$0 31TEXT casp+0(SB),0,$0 32TEXT casl+0(SB),0,$0 33 MOVL p+0(FP), CX 34 MOVL ov+4(FP), AX 35 MOVL nv+8(FP), DX 36 LOCK 37 CMPXCHG 38 JNE fail 39 MOVL $1,AX 40 RET 41fail: 42 MOVL $0,AX 43 RET 44 45/* 46 * int cas64(u64int *p, u64int ov, u64int nv); 47 */ 48 49/* 50 * CMPXCHG64 (DI): 0000 1111 1100 0111 0000 1110, 51 */ 52 53#define CMPXCHG64 BYTE $0x0F; BYTE $0xC7; BYTE $0x0F 54 55TEXT cas64+0(SB),0,$0 56 MOVL p+0(FP), DI 57 MOVL ov+0x4(FP), AX 58 MOVL ov+0x8(FP), DX 59 MOVL nv+0xc(FP), BX 60 MOVL nv+0x10(FP), CX 61 LOCK 62 CMPXCHG64 63 JNE fail 64 MOVL $1,AX 65 RET 66 67/* 68 * Versions of compare-and-swap that return the old value 69 * (i.e., the value of *p at the time of the operation 70 * xcas(p, o, n) == o 71 * yields the same value as 72 * cas(p, o, n) 73 * xcas can be used in constructs like 74 * for(o = *p; (oo = xcas(p, o, o+1)) != o; o = oo) 75 * ; 76 * to avoid the extra dereference of *p (the example is a silly 77 * way to increment *p atomically) 78 * 79 * u32int xcas32(u32int *p, u32int ov, u32int nv); 80 * u64int xcas64(u64int *p, u64int ov, u64int nv); 81 * int xcas(int *p, int ov, int nv); 82 * void* xcasp(void **p, void *ov, void *nv); 83 * ulong xcasl(ulong *p, ulong ov, ulong nv); 84 */ 85 86TEXT xcas32+0(SB),0,$0 87TEXT xcas+0(SB),0,$0 88TEXT xcasp+0(SB),0,$0 89TEXT xcasl+0(SB),0,$0 90 MOVL p+0(FP), CX 91 MOVL ov+4(FP), AX /* accumulator */ 92 MOVL nv+8(FP), DX 93 LOCK 94 CMPXCHG 95 RET 96 97/* 98 * The CMPXCHG8B instruction also requires three operands: 99 * a 64-bit value in EDX:EAX, a 64-bit value in ECX:EBX, 100 * and a destination operand in memory. The instruction compar 101 * es the 64-bit value in the EDX:EAX registers with the 102 * destination operand. If they are equal, the 64-bit value 103 * in the ECX:EBX register is stored in the destination 104 * operand. If the EDX:EAX register and the destination ar 105 * e not equal, the destination is loaded in the EDX:EAX 106 * register. The CMPXCHG8B instruction can be combined with 107 * the LOCK prefix to perform the operation atomically 108 */ 109 110TEXT xcas64+0(SB),0,$0 111 MOVL p+4(FP), DI 112 MOVL ov+0x8(FP), AX 113 MOVL ov+0xc(FP), DX 114 MOVL nv+0x10(FP), BX 115 MOVL nv+0x14(FP), CX 116 LOCK 117 CMPXCHG64 118 MOVL .ret+0x0(FP),CX /* pointer to return value */ 119 MOVL AX,0x0(CX) 120 MOVL DX,0x4(CX) 121 RET 122