github.com/zxy12/go_duplicate_112_new@v0.0.0-20200807091221-747231827200/src/runtime/internal/atomic/asm_386.s (about) 1 // Copyright 2015 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 #include "textflag.h" 6 7 // bool Cas(int32 *val, int32 old, int32 new) 8 // Atomically: 9 // if(*val == old){ 10 // *val = new; 11 // return 1; 12 // }else 13 // return 0; 14 TEXT runtime∕internal∕atomic·Cas(SB), NOSPLIT, $0-13 15 MOVL ptr+0(FP), BX 16 MOVL old+4(FP), AX 17 MOVL new+8(FP), CX 18 LOCK 19 CMPXCHGL CX, 0(BX) 20 SETEQ ret+12(FP) 21 RET 22 23 TEXT runtime∕internal∕atomic·Casuintptr(SB), NOSPLIT, $0-13 24 JMP runtime∕internal∕atomic·Cas(SB) 25 26 TEXT runtime∕internal∕atomic·CasRel(SB), NOSPLIT, $0-13 27 JMP runtime∕internal∕atomic·Cas(SB) 28 29 TEXT runtime∕internal∕atomic·Loaduintptr(SB), NOSPLIT, $0-8 30 JMP runtime∕internal∕atomic·Load(SB) 31 32 TEXT runtime∕internal∕atomic·Loaduint(SB), NOSPLIT, $0-8 33 JMP runtime∕internal∕atomic·Load(SB) 34 35 TEXT runtime∕internal∕atomic·Storeuintptr(SB), NOSPLIT, $0-8 36 JMP runtime∕internal∕atomic·Store(SB) 37 38 TEXT runtime∕internal∕atomic·Xadduintptr(SB), NOSPLIT, $0-12 39 JMP runtime∕internal∕atomic·Xadd(SB) 40 41 TEXT runtime∕internal∕atomic·Loadint64(SB), NOSPLIT, $0-12 42 JMP runtime∕internal∕atomic·Load64(SB) 43 44 TEXT runtime∕internal∕atomic·Xaddint64(SB), NOSPLIT, $0-20 45 JMP runtime∕internal∕atomic·Xadd64(SB) 46 47 48 // bool runtime∕internal∕atomic·Cas64(uint64 *val, uint64 old, uint64 new) 49 // Atomically: 50 // if(*val == *old){ 51 // *val = new; 52 // return 1; 53 // } else { 54 // return 0; 55 // } 56 TEXT runtime∕internal∕atomic·Cas64(SB), NOSPLIT, $0-21 57 MOVL ptr+0(FP), BP 58 TESTL $7, BP 59 JZ 2(PC) 60 MOVL 0, BP // crash with nil ptr deref 61 MOVL old_lo+4(FP), AX 62 MOVL old_hi+8(FP), DX 63 MOVL new_lo+12(FP), BX 64 MOVL new_hi+16(FP), CX 65 LOCK 66 CMPXCHG8B 0(BP) 67 SETEQ ret+20(FP) 68 RET 69 70 // bool Casp1(void **p, void *old, void *new) 71 // Atomically: 72 // if(*p == old){ 73 // *p = new; 74 // return 1; 75 // }else 76 // return 0; 77 TEXT runtime∕internal∕atomic·Casp1(SB), NOSPLIT, $0-13 78 MOVL ptr+0(FP), BX 79 MOVL old+4(FP), AX 80 MOVL new+8(FP), CX 81 LOCK 82 CMPXCHGL CX, 0(BX) 83 SETEQ ret+12(FP) 84 RET 85 86 // uint32 Xadd(uint32 volatile *val, int32 delta) 87 // Atomically: 88 // *val += delta; 89 // return *val; 90 TEXT runtime∕internal∕atomic·Xadd(SB), NOSPLIT, $0-12 91 MOVL ptr+0(FP), BX 92 MOVL delta+4(FP), AX 93 MOVL AX, CX 94 LOCK 95 XADDL AX, 0(BX) 96 ADDL CX, AX 97 MOVL AX, ret+8(FP) 98 RET 99 100 TEXT runtime∕internal∕atomic·Xadd64(SB), NOSPLIT, $0-20 101 // no XADDQ so use CMPXCHG8B loop 102 MOVL ptr+0(FP), BP 103 TESTL $7, BP 104 JZ 2(PC) 105 MOVL 0, AX // crash when unaligned 106 // DI:SI = delta 107 MOVL delta_lo+4(FP), SI 108 MOVL delta_hi+8(FP), DI 109 // DX:AX = *addr 110 MOVL 0(BP), AX 111 MOVL 4(BP), DX 112 addloop: 113 // CX:BX = DX:AX (*addr) + DI:SI (delta) 114 MOVL AX, BX 115 MOVL DX, CX 116 ADDL SI, BX 117 ADCL DI, CX 118 119 // if *addr == DX:AX { 120 // *addr = CX:BX 121 // } else { 122 // DX:AX = *addr 123 // } 124 // all in one instruction 125 LOCK 126 CMPXCHG8B 0(BP) 127 128 JNZ addloop 129 130 // success 131 // return CX:BX 132 MOVL BX, ret_lo+12(FP) 133 MOVL CX, ret_hi+16(FP) 134 RET 135 136 TEXT runtime∕internal∕atomic·Xchg(SB), NOSPLIT, $0-12 137 MOVL ptr+0(FP), BX 138 MOVL new+4(FP), AX 139 XCHGL AX, 0(BX) 140 MOVL AX, ret+8(FP) 141 RET 142 143 TEXT runtime∕internal∕atomic·Xchguintptr(SB), NOSPLIT, $0-12 144 JMP runtime∕internal∕atomic·Xchg(SB) 145 146 TEXT runtime∕internal∕atomic·Xchg64(SB),NOSPLIT,$0-20 147 // no XCHGQ so use CMPXCHG8B loop 148 MOVL ptr+0(FP), BP 149 TESTL $7, BP 150 JZ 2(PC) 151 MOVL 0, AX // crash when unaligned 152 // CX:BX = new 153 MOVL new_lo+4(FP), BX 154 MOVL new_hi+8(FP), CX 155 // DX:AX = *addr 156 MOVL 0(BP), AX 157 MOVL 4(BP), DX 158 swaploop: 159 // if *addr == DX:AX 160 // *addr = CX:BX 161 // else 162 // DX:AX = *addr 163 // all in one instruction 164 LOCK 165 CMPXCHG8B 0(BP) 166 JNZ swaploop 167 168 // success 169 // return DX:AX 170 MOVL AX, ret_lo+12(FP) 171 MOVL DX, ret_hi+16(FP) 172 RET 173 174 TEXT runtime∕internal∕atomic·StorepNoWB(SB), NOSPLIT, $0-8 175 MOVL ptr+0(FP), BX 176 MOVL val+4(FP), AX 177 XCHGL AX, 0(BX) 178 RET 179 180 TEXT runtime∕internal∕atomic·Store(SB), NOSPLIT, $0-8 181 MOVL ptr+0(FP), BX 182 MOVL val+4(FP), AX 183 XCHGL AX, 0(BX) 184 RET 185 186 TEXT runtime∕internal∕atomic·StoreRel(SB), NOSPLIT, $0-8 187 JMP runtime∕internal∕atomic·Store(SB) 188 189 // uint64 atomicload64(uint64 volatile* addr); 190 TEXT runtime∕internal∕atomic·Load64(SB), NOSPLIT, $0-12 191 MOVL ptr+0(FP), AX 192 TESTL $7, AX 193 JZ 2(PC) 194 MOVL 0, AX // crash with nil ptr deref 195 MOVQ (AX), M0 196 MOVQ M0, ret+4(FP) 197 EMMS 198 RET 199 200 // void runtime∕internal∕atomic·Store64(uint64 volatile* addr, uint64 v); 201 TEXT runtime∕internal∕atomic·Store64(SB), NOSPLIT, $0-12 202 MOVL ptr+0(FP), AX 203 TESTL $7, AX 204 JZ 2(PC) 205 MOVL 0, AX // crash with nil ptr deref 206 // MOVQ and EMMS were introduced on the Pentium MMX. 207 MOVQ val+4(FP), M0 208 MOVQ M0, (AX) 209 EMMS 210 // This is essentially a no-op, but it provides required memory fencing. 211 // It can be replaced with MFENCE, but MFENCE was introduced only on the Pentium4 (SSE2). 212 XORL AX, AX 213 LOCK 214 XADDL AX, (SP) 215 RET 216 217 // void runtime∕internal∕atomic·Or8(byte volatile*, byte); 218 TEXT runtime∕internal∕atomic·Or8(SB), NOSPLIT, $0-5 219 MOVL ptr+0(FP), AX 220 MOVB val+4(FP), BX 221 LOCK 222 ORB BX, (AX) 223 RET 224 225 // void runtime∕internal∕atomic·And8(byte volatile*, byte); 226 TEXT runtime∕internal∕atomic·And8(SB), NOSPLIT, $0-5 227 MOVL ptr+0(FP), AX 228 MOVB val+4(FP), BX 229 LOCK 230 ANDB BX, (AX) 231 RET