github.com/golang-haiku/go-1.4.3@v0.0.0-20190609233734-1f5ae41cc308/src/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 #include "textflag.h" 8 9 TEXT ·SwapInt32(SB),NOSPLIT,$0-12 10 JMP ·SwapUint32(SB) 11 12 TEXT ·SwapUint32(SB),NOSPLIT,$0-12 13 MOVL addr+0(FP), BP 14 MOVL new+4(FP), AX 15 XCHGL AX, 0(BP) 16 MOVL AX, old+8(FP) 17 RET 18 19 TEXT ·SwapInt64(SB),NOSPLIT,$0-20 20 JMP ·SwapUint64(SB) 21 22 TEXT ·SwapUint64(SB),NOSPLIT,$0-20 23 // no XCHGQ so use CMPXCHG8B loop 24 MOVL addr+0(FP), BP 25 TESTL $7, BP 26 JZ 2(PC) 27 MOVL 0, AX // crash with nil ptr deref 28 // CX:BX = new 29 MOVL new_lo+4(FP), BX 30 MOVL new_hi+8(FP), CX 31 // DX:AX = *addr 32 MOVL 0(BP), AX 33 MOVL 4(BP), DX 34 swaploop: 35 // if *addr == DX:AX 36 // *addr = CX:BX 37 // else 38 // DX:AX = *addr 39 // all in one instruction 40 LOCK 41 CMPXCHG8B 0(BP) 42 JNZ swaploop 43 44 // success 45 // return DX:AX 46 MOVL AX, old_lo+12(FP) 47 MOVL DX, old_hi+16(FP) 48 RET 49 50 TEXT ·SwapUintptr(SB),NOSPLIT,$0-12 51 JMP ·SwapUint32(SB) 52 53 TEXT ·SwapPointer(SB),NOSPLIT,$0-12 54 JMP ·SwapUint32(SB) 55 56 TEXT ·CompareAndSwapInt32(SB),NOSPLIT,$0-13 57 JMP ·CompareAndSwapUint32(SB) 58 59 TEXT ·CompareAndSwapUint32(SB),NOSPLIT,$0-13 60 MOVL addr+0(FP), BP 61 MOVL old+4(FP), AX 62 MOVL new+8(FP), CX 63 // CMPXCHGL was introduced on the 486. 64 LOCK 65 CMPXCHGL CX, 0(BP) 66 SETEQ swapped+12(FP) 67 RET 68 69 TEXT ·CompareAndSwapUintptr(SB),NOSPLIT,$0-13 70 JMP ·CompareAndSwapUint32(SB) 71 72 TEXT ·CompareAndSwapPointer(SB),NOSPLIT,$0-13 73 JMP ·CompareAndSwapUint32(SB) 74 75 TEXT ·CompareAndSwapInt64(SB),NOSPLIT,$0-21 76 JMP ·CompareAndSwapUint64(SB) 77 78 TEXT ·CompareAndSwapUint64(SB),NOSPLIT,$0-21 79 MOVL addr+0(FP), BP 80 TESTL $7, BP 81 JZ 2(PC) 82 MOVL 0, AX // crash with nil ptr deref 83 MOVL old_lo+4(FP), AX 84 MOVL old_hi+8(FP), DX 85 MOVL new_lo+12(FP), BX 86 MOVL new_hi+16(FP), CX 87 // CMPXCHG8B was introduced on the Pentium. 88 LOCK 89 CMPXCHG8B 0(BP) 90 SETEQ swapped+20(FP) 91 RET 92 93 TEXT ·AddInt32(SB),NOSPLIT,$0-12 94 JMP ·AddUint32(SB) 95 96 TEXT ·AddUint32(SB),NOSPLIT,$0-12 97 MOVL addr+0(FP), BP 98 MOVL delta+4(FP), AX 99 MOVL AX, CX 100 // XADD was introduced on the 486. 101 LOCK 102 XADDL AX, 0(BP) 103 ADDL AX, CX 104 MOVL CX, new+8(FP) 105 RET 106 107 TEXT ·AddUintptr(SB),NOSPLIT,$0-12 108 JMP ·AddUint32(SB) 109 110 TEXT ·AddInt64(SB),NOSPLIT,$0-20 111 JMP ·AddUint64(SB) 112 113 TEXT ·AddUint64(SB),NOSPLIT,$0-20 114 // no XADDQ so use CMPXCHG8B loop 115 MOVL addr+0(FP), BP 116 TESTL $7, BP 117 JZ 2(PC) 118 MOVL 0, AX // crash with nil ptr deref 119 // DI:SI = delta 120 MOVL delta_lo+4(FP), SI 121 MOVL delta_hi+8(FP), DI 122 // DX:AX = *addr 123 MOVL 0(BP), AX 124 MOVL 4(BP), DX 125 addloop: 126 // CX:BX = DX:AX (*addr) + DI:SI (delta) 127 MOVL AX, BX 128 MOVL DX, CX 129 ADDL SI, BX 130 ADCL DI, CX 131 132 // if *addr == DX:AX { 133 // *addr = CX:BX 134 // } else { 135 // DX:AX = *addr 136 // } 137 // all in one instruction 138 LOCK 139 CMPXCHG8B 0(BP) 140 141 JNZ addloop 142 143 // success 144 // return CX:BX 145 MOVL BX, new_lo+12(FP) 146 MOVL CX, new_hi+16(FP) 147 RET 148 149 TEXT ·LoadInt32(SB),NOSPLIT,$0-8 150 JMP ·LoadUint32(SB) 151 152 TEXT ·LoadUint32(SB),NOSPLIT,$0-8 153 MOVL addr+0(FP), AX 154 MOVL 0(AX), AX 155 MOVL AX, val+4(FP) 156 RET 157 158 TEXT ·LoadInt64(SB),NOSPLIT,$0-12 159 JMP ·LoadUint64(SB) 160 161 TEXT ·LoadUint64(SB),NOSPLIT,$0-12 162 MOVL addr+0(FP), AX 163 TESTL $7, AX 164 JZ 2(PC) 165 MOVL 0, AX // crash with nil ptr deref 166 // MOVQ and EMMS were introduced on the Pentium MMX. 167 // MOVQ (%EAX), %MM0 168 BYTE $0x0f; BYTE $0x6f; BYTE $0x00 169 // MOVQ %MM0, 0x8(%ESP) 170 BYTE $0x0f; BYTE $0x7f; BYTE $0x44; BYTE $0x24; BYTE $0x08 171 EMMS 172 RET 173 174 TEXT ·LoadUintptr(SB),NOSPLIT,$0-8 175 JMP ·LoadUint32(SB) 176 177 TEXT ·LoadPointer(SB),NOSPLIT,$0-8 178 JMP ·LoadUint32(SB) 179 180 TEXT ·StoreInt32(SB),NOSPLIT,$0-8 181 JMP ·StoreUint32(SB) 182 183 TEXT ·StoreUint32(SB),NOSPLIT,$0-8 184 MOVL addr+0(FP), BP 185 MOVL val+4(FP), AX 186 XCHGL AX, 0(BP) 187 RET 188 189 TEXT ·StoreInt64(SB),NOSPLIT,$0-12 190 JMP ·StoreUint64(SB) 191 192 TEXT ·StoreUint64(SB),NOSPLIT,$0-12 193 MOVL addr+0(FP), AX 194 TESTL $7, AX 195 JZ 2(PC) 196 MOVL 0, AX // crash with nil ptr deref 197 // MOVQ and EMMS were introduced on the Pentium MMX. 198 // MOVQ 0x8(%ESP), %MM0 199 BYTE $0x0f; BYTE $0x6f; BYTE $0x44; BYTE $0x24; BYTE $0x08 200 // MOVQ %MM0, (%EAX) 201 BYTE $0x0f; BYTE $0x7f; BYTE $0x00 202 EMMS 203 // This is essentially a no-op, but it provides required memory fencing. 204 // It can be replaced with MFENCE, but MFENCE was introduced only on the Pentium4 (SSE2). 205 XORL AX, AX 206 LOCK 207 XADDL AX, (SP) 208 RET 209 210 TEXT ·StoreUintptr(SB),NOSPLIT,$0-8 211 JMP ·StoreUint32(SB) 212 213 TEXT ·StorePointer(SB),NOSPLIT,$0-8 214 JMP ·StoreUint32(SB)