github.com/primecitizens/pcz/std@v0.2.1/core/atomic/atomic_mips64x.s (about) 1 // SPDX-License-Identifier: Apache-2.0 2 // Copyright 2023 The Prime Citizens 3 // 4 // Copyright 2015 The Go Authors. All rights reserved. 5 // Use of this source code is governed by a BSD-style 6 // license that can be found in the LICENSE file. 7 8 //go:build mips64 || mips64le 9 10 #include "textflag.h" 11 12 #define SYNC WORD $0xf 13 14 TEXT ·PublicationBarrier(SB),NOSPLIT|NOFRAME,$0-0 15 SYNC 16 RET 17 18 // 19 // Store 20 // 21 22 TEXT ·Store8(SB), NOSPLIT, $0-9 23 MOVV ptr+0(FP), R1 24 MOVB val+8(FP), R2 25 SYNC 26 MOVB R2, 0(R1) 27 SYNC 28 RET 29 30 TEXT ·Store32(SB), NOSPLIT, $0-12 31 MOVV ptr+0(FP), R1 32 MOVW val+8(FP), R2 33 SYNC 34 MOVW R2, 0(R1) 35 SYNC 36 RET 37 38 TEXT ·Store64(SB), NOSPLIT, $0-16 39 MOVV ptr+0(FP), R1 40 MOVV val+8(FP), R2 41 SYNC 42 MOVV R2, 0(R1) 43 SYNC 44 RET 45 46 TEXT ·StoreUintptr(SB), NOSPLIT, $0-16 47 JMP ·Store64(SB) 48 49 TEXT ·StorePointer(SB), NOSPLIT, $0-16 50 JMP ·Store64(SB) 51 52 TEXT ·StoreInt32(SB), NOSPLIT, $0-12 53 JMP ·Store32(SB) 54 55 TEXT ·StoreInt64(SB), NOSPLIT, $0-16 56 JMP ·Store64(SB) 57 58 // 59 // StoreRel 60 // 61 62 TEXT ·StoreRel32(SB), NOSPLIT, $0-12 63 JMP ·Store32(SB) 64 65 TEXT ·StoreRel64(SB), NOSPLIT, $0-16 66 JMP ·Store64(SB) 67 68 TEXT ·StoreRelUintptr(SB), NOSPLIT, $0-16 69 JMP ·Store64(SB) 70 71 // 72 // Load 73 // 74 75 // uint8 ·Load8(uint8 volatile* ptr) 76 TEXT ·Load8(SB),NOSPLIT|NOFRAME,$0-9 77 MOVV ptr+0(FP), R1 78 SYNC 79 MOVBU 0(R1), R1 80 SYNC 81 MOVB R1, ret+8(FP) 82 RET 83 84 // uint32 ·Load32(uint32 volatile* ptr) 85 TEXT ·Load32(SB),NOSPLIT|NOFRAME,$0-12 86 MOVV ptr+0(FP), R1 87 SYNC 88 MOVWU 0(R1), R1 89 SYNC 90 MOVW R1, ret+8(FP) 91 RET 92 93 // uint64 ·Load64(uint64 volatile* ptr) 94 TEXT ·Load64(SB),NOSPLIT|NOFRAME,$0-16 95 MOVV ptr+0(FP), R1 96 SYNC 97 MOVV 0(R1), R1 98 SYNC 99 MOVV R1, ret+8(FP) 100 RET 101 102 TEXT ·LoadUintptr(SB),NOSPLIT|NOFRAME,$0-16 103 JMP ·Load64(SB) 104 105 // void *·LoadPointer(void *volatile *ptr) 106 TEXT ·LoadPointer(SB),NOSPLIT|NOFRAME,$0-16 107 MOVV ptr+0(FP), R1 108 SYNC 109 MOVV 0(R1), R1 110 SYNC 111 MOVV R1, ret+8(FP) 112 RET 113 114 TEXT ·LoadUint(SB), NOSPLIT|NOFRAME, $0-16 115 JMP ·Load64(SB) 116 117 TEXT ·LoadInt32(SB), NOSPLIT, $0-12 118 JMP ·Load32(SB) 119 120 TEXT ·LoadInt64(SB), NOSPLIT, $0-16 121 JMP ·Load64(SB) 122 123 // 124 // LoadAcq 125 // 126 127 // uint32 ·LoadAcq32(uint32 volatile* ptr) 128 TEXT ·LoadAcq32(SB),NOSPLIT|NOFRAME,$0-12 129 JMP ·Load32(SB) 130 131 // uint64 ·LoadAcq64(uint64 volatile* ptr) 132 TEXT ·LoadAcq64(SB),NOSPLIT|NOFRAME,$0-16 133 JMP ·Load64(SB) 134 135 // uintptr ·LoadAcqUintptr(uintptr volatile* ptr) 136 TEXT ·LoadAcqUintptr(SB),NOSPLIT|NOFRAME,$0-16 137 JMP ·Load64(SB) 138 139 // 140 // bitwise 141 // 142 143 // void Or8(byte volatile*, byte); 144 TEXT ·Or8(SB), NOSPLIT, $0-9 145 MOVV ptr+0(FP), R1 146 MOVBU val+8(FP), R2 147 // Align ptr down to 4 bytes so we can use 32-bit load/store. 148 MOVV $~3, R3 149 AND R1, R3 150 // Compute val shift. 151 #ifdef GOARCH_mips64 152 // Big endian. ptr = ptr ^ 3 153 XOR $3, R1 154 #endif 155 // R4 = ((ptr & 3) * 8) 156 AND $3, R1, R4 157 SLLV $3, R4 158 // Shift val for aligned ptr. R2 = val << R4 159 SLLV R4, R2 160 161 SYNC 162 LL (R3), R4 163 OR R2, R4 164 SC R4, (R3) 165 BEQ R4, -4(PC) 166 SYNC 167 RET 168 169 // func Or(addr *uint32, v uint32) 170 TEXT ·Or32(SB), NOSPLIT, $0-12 171 MOVV ptr+0(FP), R1 172 MOVW val+8(FP), R2 173 174 SYNC 175 LL (R1), R3 176 OR R2, R3 177 SC R3, (R1) 178 BEQ R3, -4(PC) 179 SYNC 180 RET 181 182 // void And8(byte volatile*, byte); 183 TEXT ·And8(SB), NOSPLIT, $0-9 184 MOVV ptr+0(FP), R1 185 MOVBU val+8(FP), R2 186 // Align ptr down to 4 bytes so we can use 32-bit load/store. 187 MOVV $~3, R3 188 AND R1, R3 189 // Compute val shift. 190 #ifdef GOARCH_mips64 191 // Big endian. ptr = ptr ^ 3 192 XOR $3, R1 193 #endif 194 // R4 = ((ptr & 3) * 8) 195 AND $3, R1, R4 196 SLLV $3, R4 197 // Shift val for aligned ptr. R2 = val << R4 | ^(0xFF << R4) 198 MOVV $0xFF, R5 199 SLLV R4, R2 200 SLLV R4, R5 201 NOR R0, R5 202 OR R5, R2 203 204 SYNC 205 LL (R3), R4 206 AND R2, R4 207 SC R4, (R3) 208 BEQ R4, -4(PC) 209 SYNC 210 RET 211 212 // func And(addr *uint32, v uint32) 213 TEXT ·And32(SB), NOSPLIT, $0-12 214 MOVV ptr+0(FP), R1 215 MOVW val+8(FP), R2 216 217 SYNC 218 LL (R1), R3 219 AND R2, R3 220 SC R3, (R1) 221 BEQ R3, -4(PC) 222 SYNC 223 RET 224 225 // 226 // Swap 227 // 228 229 // uint32 Swap32(ptr *uint32, new uint32) 230 TEXT ·Swap32(SB), NOSPLIT, $0-20 231 MOVV ptr+0(FP), R2 232 MOVW new+8(FP), R5 233 234 SYNC 235 MOVV R5, R3 236 LL (R2), R1 237 SC R3, (R2) 238 BEQ R3, -3(PC) 239 MOVW R1, ret+16(FP) 240 SYNC 241 RET 242 243 // uint64 Swap64(ptr *uint64, new uint64) 244 TEXT ·Swap64(SB), NOSPLIT, $0-24 245 MOVV ptr+0(FP), R2 246 MOVV new+8(FP), R5 247 248 SYNC 249 MOVV R5, R3 250 LLV (R2), R1 251 SCV R3, (R2) 252 BEQ R3, -3(PC) 253 MOVV R1, ret+16(FP) 254 SYNC 255 RET 256 257 TEXT ·SwapUintptr(SB), NOSPLIT, $0-24 258 JMP ·Swap64(SB) 259 260 TEXT ·SwapInt32(SB), NOSPLIT, $0-20 261 JMP ·Swap32(SB) 262 263 TEXT ·SwapInt64(SB), NOSPLIT, $0-24 264 JMP ·Swap64(SB) 265 266 // 267 // Add 268 // 269 270 // uint32 Add32(uint32 volatile *ptr, int32 delta) 271 TEXT ·Add32(SB), NOSPLIT, $0-20 272 MOVV ptr+0(FP), R2 273 MOVW delta+8(FP), R3 274 SYNC 275 LL (R2), R1 276 ADDU R1, R3, R4 277 MOVV R4, R1 278 SC R4, (R2) 279 BEQ R4, -4(PC) 280 MOVW R1, ret+16(FP) 281 SYNC 282 RET 283 284 // uint64 Add64(uint64 volatile *ptr, int64 delta) 285 TEXT ·Add64(SB), NOSPLIT, $0-24 286 MOVV ptr+0(FP), R2 287 MOVV delta+8(FP), R3 288 SYNC 289 LLV (R2), R1 290 ADDVU R1, R3, R4 291 MOVV R4, R1 292 SCV R4, (R2) 293 BEQ R4, -4(PC) 294 MOVV R1, ret+16(FP) 295 SYNC 296 RET 297 298 TEXT ·AddUintptr(SB), NOSPLIT, $0-24 299 JMP ·Add64(SB) 300 301 TEXT ·AddInt32(SB), NOSPLIT, $0-20 302 JMP ·Add32(SB) 303 304 TEXT ·AddInt64(SB), NOSPLIT, $0-24 305 JMP ·Add64(SB) 306 307 // 308 // Compare and swap 309 // 310 311 // bool Cas32(uint32 *ptr, uint32 old, uint32 new) 312 TEXT ·Cas32(SB), NOSPLIT, $0-17 313 MOVV ptr+0(FP), R1 314 MOVW old+8(FP), R2 315 MOVW new+12(FP), R5 316 SYNC 317 cas_again: 318 MOVV R5, R3 319 LL (R1), R4 320 BNE R2, R4, cas_fail 321 SC R3, (R1) 322 BEQ R3, cas_again 323 MOVV $1, R1 324 MOVB R1, ret+16(FP) 325 SYNC 326 RET 327 cas_fail: 328 MOVV $0, R1 329 JMP -4(PC) 330 331 // bool Cas64(uint64 *ptr, uint64 old, uint64 new) 332 TEXT ·Cas64(SB), NOSPLIT, $0-25 333 MOVV ptr+0(FP), R1 334 MOVV old+8(FP), R2 335 MOVV new+16(FP), R5 336 SYNC 337 cas64_again: 338 MOVV R5, R3 339 LLV (R1), R4 340 BNE R2, R4, cas64_fail 341 SCV R3, (R1) 342 BEQ R3, cas64_again 343 MOVV $1, R1 344 MOVB R1, ret+24(FP) 345 SYNC 346 RET 347 cas64_fail: 348 MOVV $0, R1 349 JMP -4(PC) 350 351 TEXT ·CasUintptr(SB), NOSPLIT, $0-25 352 JMP ·Cas64(SB) 353 354 // bool CasUnsafePointer(void **val, void *old, void *new) 355 TEXT ·CasUnsafePointer(SB), NOSPLIT, $0-25 356 JMP ·Cas64(SB) 357 358 TEXT ·CasInt32(SB), NOSPLIT, $0-17 359 JMP ·Cas32(SB) 360 361 TEXT ·CasInt64(SB), NOSPLIT, $0-25 362 JMP ·Cas64(SB) 363 364 // 365 // CasRel 366 // 367 368 TEXT ·CasRel32(SB), NOSPLIT, $0-17 369 JMP ·Cas32(SB)