github.com/xushiwei/go@v0.0.0-20130601165731-2b9d83f45bc9/src/pkg/sync/atomic/asm_386.s (about) 1 // Copyright 2011 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 // +build !race 6 7 TEXT ·CompareAndSwapInt32(SB),7,$0 8 JMP ·CompareAndSwapUint32(SB) 9 10 TEXT ·CompareAndSwapUint32(SB),7,$0 11 MOVL addr+0(FP), BP 12 MOVL old+4(FP), AX 13 MOVL new+8(FP), CX 14 // CMPXCHGL was introduced on the 486. 15 LOCK 16 CMPXCHGL CX, 0(BP) 17 SETEQ swapped+12(FP) 18 RET 19 20 TEXT ·CompareAndSwapUintptr(SB),7,$0 21 JMP ·CompareAndSwapUint32(SB) 22 23 TEXT ·CompareAndSwapPointer(SB),7,$0 24 JMP ·CompareAndSwapUint32(SB) 25 26 TEXT ·CompareAndSwapInt64(SB),7,$0 27 JMP ·CompareAndSwapUint64(SB) 28 29 TEXT ·CompareAndSwapUint64(SB),7,$0 30 MOVL addr+0(FP), BP 31 TESTL $7, BP 32 JZ 2(PC) 33 MOVL 0, AX // crash with nil ptr deref 34 MOVL old_lo+4(FP), AX 35 MOVL old_hi+8(FP), DX 36 MOVL new_lo+12(FP), BX 37 MOVL new_hi+16(FP), CX 38 // CMPXCHG8B was introduced on the Pentium. 39 LOCK 40 CMPXCHG8B 0(BP) 41 SETEQ swapped+20(FP) 42 RET 43 44 TEXT ·AddInt32(SB),7,$0 45 JMP ·AddUint32(SB) 46 47 TEXT ·AddUint32(SB),7,$0 48 MOVL addr+0(FP), BP 49 MOVL delta+4(FP), AX 50 MOVL AX, CX 51 // XADD was introduced on the 486. 52 LOCK 53 XADDL AX, 0(BP) 54 ADDL AX, CX 55 MOVL CX, new+8(FP) 56 RET 57 58 TEXT ·AddUintptr(SB),7,$0 59 JMP ·AddUint32(SB) 60 61 TEXT ·AddInt64(SB),7,$0 62 JMP ·AddUint64(SB) 63 64 TEXT ·AddUint64(SB),7,$0 65 // no XADDQ so use CMPXCHG8B loop 66 MOVL addr+0(FP), BP 67 TESTL $7, BP 68 JZ 2(PC) 69 MOVL 0, AX // crash with nil ptr deref 70 // DI:SI = delta 71 MOVL delta_lo+4(FP), SI 72 MOVL delta_hi+8(FP), DI 73 // DX:AX = *addr 74 MOVL 0(BP), AX 75 MOVL 4(BP), DX 76 addloop: 77 // CX:BX = DX:AX (*addr) + DI:SI (delta) 78 MOVL AX, BX 79 MOVL DX, CX 80 ADDL SI, BX 81 ADCL DI, CX 82 83 // if *addr == DX:AX { 84 // *addr = CX:BX 85 // } else { 86 // DX:AX = *addr 87 // } 88 // all in one instruction 89 LOCK 90 CMPXCHG8B 0(BP) 91 92 JNZ addloop 93 94 // success 95 // return CX:BX 96 MOVL BX, new_lo+12(FP) 97 MOVL CX, new_hi+16(FP) 98 RET 99 100 TEXT ·LoadInt32(SB),7,$0 101 JMP ·LoadUint32(SB) 102 103 TEXT ·LoadUint32(SB),7,$0 104 MOVL addr+0(FP), AX 105 MOVL 0(AX), AX 106 MOVL AX, val+4(FP) 107 RET 108 109 TEXT ·LoadInt64(SB),7,$0 110 JMP ·LoadUint64(SB) 111 112 TEXT ·LoadUint64(SB),7,$0 113 MOVL addr+0(FP), AX 114 TESTL $7, AX 115 JZ 2(PC) 116 MOVL 0, AX // crash with nil ptr deref 117 // MOVQ and EMMS were introduced on the Pentium MMX. 118 // MOVQ (%EAX), %MM0 119 BYTE $0x0f; BYTE $0x6f; BYTE $0x00 120 // MOVQ %MM0, 0x8(%ESP) 121 BYTE $0x0f; BYTE $0x7f; BYTE $0x44; BYTE $0x24; BYTE $0x08 122 EMMS 123 RET 124 125 TEXT ·LoadUintptr(SB),7,$0 126 JMP ·LoadUint32(SB) 127 128 TEXT ·LoadPointer(SB),7,$0 129 JMP ·LoadUint32(SB) 130 131 TEXT ·StoreInt32(SB),7,$0 132 JMP ·StoreUint32(SB) 133 134 TEXT ·StoreUint32(SB),7,$0 135 MOVL addr+0(FP), BP 136 MOVL val+4(FP), AX 137 XCHGL AX, 0(BP) 138 RET 139 140 TEXT ·StoreInt64(SB),7,$0 141 JMP ·StoreUint64(SB) 142 143 TEXT ·StoreUint64(SB),7,$0 144 MOVL addr+0(FP), AX 145 TESTL $7, AX 146 JZ 2(PC) 147 MOVL 0, AX // crash with nil ptr deref 148 // MOVQ and EMMS were introduced on the Pentium MMX. 149 // MOVQ 0x8(%ESP), %MM0 150 BYTE $0x0f; BYTE $0x6f; BYTE $0x44; BYTE $0x24; BYTE $0x08 151 // MOVQ %MM0, (%EAX) 152 BYTE $0x0f; BYTE $0x7f; BYTE $0x00 153 EMMS 154 // This is essentially a no-op, but it provides required memory fencing. 155 // It can be replaced with MFENCE, but MFENCE was introduced only on the Pentium4 (SSE2). 156 XORL AX, AX 157 LOCK 158 XADDL AX, (SP) 159 RET 160 161 TEXT ·StoreUintptr(SB),7,$0 162 JMP ·StoreUint32(SB) 163 164 TEXT ·StorePointer(SB),7,$0 165 JMP ·StoreUint32(SB)