github.com/ice-blockchain/go/src@v0.0.0-20240403114104-1564d284e521/runtime/internal/atomic/atomic_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 #include "funcdata.h" 7 8 // bool Cas(int32 *val, int32 old, int32 new) 9 // Atomically: 10 // if(*val == old){ 11 // *val = new; 12 // return 1; 13 // }else 14 // return 0; 15 TEXT ·Cas(SB), NOSPLIT, $0-13 16 MOVL ptr+0(FP), BX 17 MOVL old+4(FP), AX 18 MOVL new+8(FP), CX 19 LOCK 20 CMPXCHGL CX, 0(BX) 21 SETEQ ret+12(FP) 22 RET 23 24 TEXT ·Casint32(SB), NOSPLIT, $0-13 25 JMP ·Cas(SB) 26 27 TEXT ·Casint64(SB), NOSPLIT, $0-21 28 JMP ·Cas64(SB) 29 30 TEXT ·Casuintptr(SB), NOSPLIT, $0-13 31 JMP ·Cas(SB) 32 33 TEXT ·CasRel(SB), NOSPLIT, $0-13 34 JMP ·Cas(SB) 35 36 TEXT ·Loaduintptr(SB), NOSPLIT, $0-8 37 JMP ·Load(SB) 38 39 TEXT ·Loaduint(SB), NOSPLIT, $0-8 40 JMP ·Load(SB) 41 42 TEXT ·Storeint32(SB), NOSPLIT, $0-8 43 JMP ·Store(SB) 44 45 TEXT ·Storeint64(SB), NOSPLIT, $0-12 46 JMP ·Store64(SB) 47 48 TEXT ·Storeuintptr(SB), NOSPLIT, $0-8 49 JMP ·Store(SB) 50 51 TEXT ·Xadduintptr(SB), NOSPLIT, $0-12 52 JMP ·Xadd(SB) 53 54 TEXT ·Loadint32(SB), NOSPLIT, $0-8 55 JMP ·Load(SB) 56 57 TEXT ·Loadint64(SB), NOSPLIT, $0-12 58 JMP ·Load64(SB) 59 60 TEXT ·Xaddint32(SB), NOSPLIT, $0-12 61 JMP ·Xadd(SB) 62 63 TEXT ·Xaddint64(SB), NOSPLIT, $0-20 64 JMP ·Xadd64(SB) 65 66 // bool ·Cas64(uint64 *val, uint64 old, uint64 new) 67 // Atomically: 68 // if(*val == old){ 69 // *val = new; 70 // return 1; 71 // } else { 72 // return 0; 73 // } 74 TEXT ·Cas64(SB), NOSPLIT, $0-21 75 NO_LOCAL_POINTERS 76 MOVL ptr+0(FP), BP 77 TESTL $7, BP 78 JZ 2(PC) 79 CALL ·panicUnaligned(SB) 80 MOVL old_lo+4(FP), AX 81 MOVL old_hi+8(FP), DX 82 MOVL new_lo+12(FP), BX 83 MOVL new_hi+16(FP), CX 84 LOCK 85 CMPXCHG8B 0(BP) 86 SETEQ ret+20(FP) 87 RET 88 89 // bool Casp1(void **p, void *old, void *new) 90 // Atomically: 91 // if(*p == old){ 92 // *p = new; 93 // return 1; 94 // }else 95 // return 0; 96 TEXT ·Casp1(SB), NOSPLIT, $0-13 97 MOVL ptr+0(FP), BX 98 MOVL old+4(FP), AX 99 MOVL new+8(FP), CX 100 LOCK 101 CMPXCHGL CX, 0(BX) 102 SETEQ ret+12(FP) 103 RET 104 105 // uint32 Xadd(uint32 volatile *val, int32 delta) 106 // Atomically: 107 // *val += delta; 108 // return *val; 109 TEXT ·Xadd(SB), NOSPLIT, $0-12 110 MOVL ptr+0(FP), BX 111 MOVL delta+4(FP), AX 112 MOVL AX, CX 113 LOCK 114 XADDL AX, 0(BX) 115 ADDL CX, AX 116 MOVL AX, ret+8(FP) 117 RET 118 119 TEXT ·Xadd64(SB), NOSPLIT, $0-20 120 NO_LOCAL_POINTERS 121 // no XADDQ so use CMPXCHG8B loop 122 MOVL ptr+0(FP), BP 123 TESTL $7, BP 124 JZ 2(PC) 125 CALL ·panicUnaligned(SB) 126 // DI:SI = delta 127 MOVL delta_lo+4(FP), SI 128 MOVL delta_hi+8(FP), DI 129 // DX:AX = *addr 130 MOVL 0(BP), AX 131 MOVL 4(BP), DX 132 addloop: 133 // CX:BX = DX:AX (*addr) + DI:SI (delta) 134 MOVL AX, BX 135 MOVL DX, CX 136 ADDL SI, BX 137 ADCL DI, CX 138 139 // if *addr == DX:AX { 140 // *addr = CX:BX 141 // } else { 142 // DX:AX = *addr 143 // } 144 // all in one instruction 145 LOCK 146 CMPXCHG8B 0(BP) 147 148 JNZ addloop 149 150 // success 151 // return CX:BX 152 MOVL BX, ret_lo+12(FP) 153 MOVL CX, ret_hi+16(FP) 154 RET 155 156 TEXT ·Xchg(SB), NOSPLIT, $0-12 157 MOVL ptr+0(FP), BX 158 MOVL new+4(FP), AX 159 XCHGL AX, 0(BX) 160 MOVL AX, ret+8(FP) 161 RET 162 163 TEXT ·Xchgint32(SB), NOSPLIT, $0-12 164 JMP ·Xchg(SB) 165 166 TEXT ·Xchgint64(SB), NOSPLIT, $0-20 167 JMP ·Xchg64(SB) 168 169 TEXT ·Xchguintptr(SB), NOSPLIT, $0-12 170 JMP ·Xchg(SB) 171 172 TEXT ·Xchg64(SB),NOSPLIT,$0-20 173 NO_LOCAL_POINTERS 174 // no XCHGQ so use CMPXCHG8B loop 175 MOVL ptr+0(FP), BP 176 TESTL $7, BP 177 JZ 2(PC) 178 CALL ·panicUnaligned(SB) 179 // CX:BX = new 180 MOVL new_lo+4(FP), BX 181 MOVL new_hi+8(FP), CX 182 // DX:AX = *addr 183 MOVL 0(BP), AX 184 MOVL 4(BP), DX 185 swaploop: 186 // if *addr == DX:AX 187 // *addr = CX:BX 188 // else 189 // DX:AX = *addr 190 // all in one instruction 191 LOCK 192 CMPXCHG8B 0(BP) 193 JNZ swaploop 194 195 // success 196 // return DX:AX 197 MOVL AX, ret_lo+12(FP) 198 MOVL DX, ret_hi+16(FP) 199 RET 200 201 TEXT ·StorepNoWB(SB), NOSPLIT, $0-8 202 MOVL ptr+0(FP), BX 203 MOVL val+4(FP), AX 204 XCHGL AX, 0(BX) 205 RET 206 207 TEXT ·Store(SB), NOSPLIT, $0-8 208 MOVL ptr+0(FP), BX 209 MOVL val+4(FP), AX 210 XCHGL AX, 0(BX) 211 RET 212 213 TEXT ·StoreRel(SB), NOSPLIT, $0-8 214 JMP ·Store(SB) 215 216 TEXT ·StoreReluintptr(SB), NOSPLIT, $0-8 217 JMP ·Store(SB) 218 219 // uint64 atomicload64(uint64 volatile* addr); 220 TEXT ·Load64(SB), NOSPLIT, $0-12 221 NO_LOCAL_POINTERS 222 MOVL ptr+0(FP), AX 223 TESTL $7, AX 224 JZ 2(PC) 225 CALL ·panicUnaligned(SB) 226 MOVQ (AX), M0 227 MOVQ M0, ret+4(FP) 228 EMMS 229 RET 230 231 // void ·Store64(uint64 volatile* addr, uint64 v); 232 TEXT ·Store64(SB), NOSPLIT, $0-12 233 NO_LOCAL_POINTERS 234 MOVL ptr+0(FP), AX 235 TESTL $7, AX 236 JZ 2(PC) 237 CALL ·panicUnaligned(SB) 238 // MOVQ and EMMS were introduced on the Pentium MMX. 239 MOVQ val+4(FP), M0 240 MOVQ M0, (AX) 241 EMMS 242 // This is essentially a no-op, but it provides required memory fencing. 243 // It can be replaced with MFENCE, but MFENCE was introduced only on the Pentium4 (SSE2). 244 XORL AX, AX 245 LOCK 246 XADDL AX, (SP) 247 RET 248 249 // void ·Or8(byte volatile*, byte); 250 TEXT ·Or8(SB), NOSPLIT, $0-5 251 MOVL ptr+0(FP), AX 252 MOVB val+4(FP), BX 253 LOCK 254 ORB BX, (AX) 255 RET 256 257 // void ·And8(byte volatile*, byte); 258 TEXT ·And8(SB), NOSPLIT, $0-5 259 MOVL ptr+0(FP), AX 260 MOVB val+4(FP), BX 261 LOCK 262 ANDB BX, (AX) 263 RET 264 265 TEXT ·Store8(SB), NOSPLIT, $0-5 266 MOVL ptr+0(FP), BX 267 MOVB val+4(FP), AX 268 XCHGB AX, 0(BX) 269 RET 270 271 // func Or(addr *uint32, v uint32) 272 TEXT ·Or(SB), NOSPLIT, $0-8 273 MOVL ptr+0(FP), AX 274 MOVL val+4(FP), BX 275 LOCK 276 ORL BX, (AX) 277 RET 278 279 // func And(addr *uint32, v uint32) 280 TEXT ·And(SB), NOSPLIT, $0-8 281 MOVL ptr+0(FP), AX 282 MOVL val+4(FP), BX 283 LOCK 284 ANDL BX, (AX) 285 RET 286 287 // func And32(addr *uint32, v uint32) old uint32 288 TEXT ·And32(SB), NOSPLIT, $0-12 289 MOVL ptr+0(FP), BX 290 MOVL val+4(FP), CX 291 casloop: 292 MOVL CX, DX 293 MOVL (BX), AX 294 ANDL AX, DX 295 LOCK 296 CMPXCHGL DX, (BX) 297 JNZ casloop 298 MOVL AX, ret+8(FP) 299 RET 300 301 // func Or32(addr *uint32, v uint32) old uint32 302 TEXT ·Or32(SB), NOSPLIT, $0-12 303 MOVL ptr+0(FP), BX 304 MOVL val+4(FP), CX 305 casloop: 306 MOVL CX, DX 307 MOVL (BX), AX 308 ORL AX, DX 309 LOCK 310 CMPXCHGL DX, (BX) 311 JNZ casloop 312 MOVL AX, ret+8(FP) 313 RET 314 315 // func And64(addr *uint64, v uint64) old uint64 316 TEXT ·And64(SB), NOSPLIT, $0-20 317 MOVL ptr+0(FP), BP 318 // DI:SI = v 319 MOVL val_lo+4(FP), SI 320 MOVL val_hi+8(FP), DI 321 // DX:AX = *addr 322 MOVL 0(BP), AX 323 MOVL 4(BP), DX 324 casloop: 325 // CX:BX = DX:AX (*addr) & DI:SI (mask) 326 MOVL AX, BX 327 MOVL DX, CX 328 ANDL SI, BX 329 ANDL DI, CX 330 LOCK 331 CMPXCHG8B 0(BP) 332 JNZ casloop 333 MOVL AX, ret_lo+12(FP) 334 MOVL DX, ret_hi+16(FP) 335 RET 336 337 338 // func Or64(addr *uint64, v uint64) old uint64 339 TEXT ·Or64(SB), NOSPLIT, $0-20 340 MOVL ptr+0(FP), BP 341 // DI:SI = v 342 MOVL val_lo+4(FP), SI 343 MOVL val_hi+8(FP), DI 344 // DX:AX = *addr 345 MOVL 0(BP), AX 346 MOVL 4(BP), DX 347 casloop: 348 // CX:BX = DX:AX (*addr) | DI:SI (mask) 349 MOVL AX, BX 350 MOVL DX, CX 351 ORL SI, BX 352 ORL DI, CX 353 LOCK 354 CMPXCHG8B 0(BP) 355 JNZ casloop 356 MOVL AX, ret_lo+12(FP) 357 MOVL DX, ret_hi+16(FP) 358 RET 359 360 // func Anduintptr(addr *uintptr, v uintptr) old uintptr 361 TEXT ·Anduintptr(SB), NOSPLIT, $0-12 362 JMP ·And32(SB) 363 364 // func Oruintptr(addr *uintptr, v uintptr) old uintptr 365 TEXT ·Oruintptr(SB), NOSPLIT, $0-12 366 JMP ·Or32(SB)