github.com/primecitizens/pcz/std@v0.2.1/core/atomic/atomic_mipsx.s (about) 1 // SPDX-License-Identifier: Apache-2.0 2 // Copyright 2023 The Prime Citizens 3 // 4 // Copyright 2016 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 mips || mipsle 9 10 #include "textflag.h" 11 12 TEXT ·PublicationBarrier(SB),NOSPLIT,$0 13 SYNC 14 RET 15 16 TEXT ·spinLock(SB),NOSPLIT,$0-4 17 MOVW state+0(FP), R1 18 MOVW $1, R2 19 SYNC 20 try_lock: 21 MOVW R2, R3 22 check_again: 23 LL (R1), R4 24 BNE R4, check_again 25 SC R3, (R1) 26 BEQ R3, try_lock 27 SYNC 28 RET 29 30 TEXT ·spinUnlock(SB),NOSPLIT,$0-4 31 MOVW state+0(FP), R1 32 SYNC 33 MOVW R0, (R1) 34 SYNC 35 RET 36 37 // 38 // Store 39 // 40 41 TEXT ·Store8(SB),NOSPLIT,$0-5 42 MOVW ptr+0(FP), R1 43 MOVB val+4(FP), R2 44 SYNC 45 MOVB R2, 0(R1) 46 SYNC 47 RET 48 49 TEXT ·Store32(SB),NOSPLIT,$0-8 50 MOVW ptr+0(FP), R1 51 MOVW val+4(FP), R2 52 SYNC 53 MOVW R2, 0(R1) 54 SYNC 55 RET 56 57 TEXT ·StoreUintptr(SB),NOSPLIT,$0-8 58 JMP ·Store32(SB) 59 60 TEXT ·StorePointer(SB),NOSPLIT,$0-8 61 JMP ·Store32(SB) 62 63 // 64 // StoreRel 65 // 66 67 TEXT ·StoreRel32(SB),NOSPLIT,$0-8 68 JMP ·Store32(SB) 69 70 TEXT ·StoreRelUintptr(SB),NOSPLIT,$0-8 71 JMP ·Store32(SB) 72 73 TEXT ·StoreInt32(SB),NOSPLIT,$0-8 74 JMP ·Store32(SB) 75 76 TEXT ·StoreInt64(SB),NOSPLIT,$0-12 77 JMP ·Store64(SB) 78 79 // 80 // Load 81 // 82 83 TEXT ·Load8(SB),NOSPLIT,$0-5 84 MOVW ptr+0(FP), R1 85 SYNC 86 MOVB 0(R1), R1 87 SYNC 88 MOVB R1, ret+4(FP) 89 RET 90 91 TEXT ·Load32(SB),NOSPLIT,$0-8 92 MOVW ptr+0(FP), R1 93 SYNC 94 MOVW 0(R1), R1 95 SYNC 96 MOVW R1, ret+4(FP) 97 RET 98 99 TEXT ·LoadUintptr(SB),NOSPLIT,$0-8 100 JMP ·Load32(SB) 101 102 TEXT ·LoadPointer(SB),NOSPLIT,$-0-8 103 JMP ·Load32(SB) 104 105 TEXT ·LoadUint(SB),NOSPLIT,$0-8 106 JMP ·Load32(SB) 107 108 TEXT ·LoadInt32(SB),NOSPLIT,$0-8 109 JMP ·Load32(SB) 110 111 TEXT ·LoadInt64(SB),NOSPLIT,$0-12 112 JMP ·Load64(SB) 113 114 // 115 // bitwise 116 // 117 118 // void Or8(byte volatile*, byte); 119 TEXT ·Or8(SB),NOSPLIT,$0-5 120 MOVW ptr+0(FP), R1 121 MOVBU val+4(FP), R2 122 MOVW $~3, R3 // Align ptr down to 4 bytes so we can use 32-bit load/store. 123 AND R1, R3 124 #ifdef GOARCH_mips 125 // Big endian. ptr = ptr ^ 3 126 XOR $3, R1 127 #endif 128 AND $3, R1, R4 // R4 = ((ptr & 3) * 8) 129 SLL $3, R4 130 SLL R4, R2, R2 // Shift val for aligned ptr. R2 = val << R4 131 SYNC 132 try_or8: 133 LL (R3), R4 // R4 = *R3 134 OR R2, R4 135 SC R4, (R3) // *R3 = R4 136 BEQ R4, try_or8 137 SYNC 138 RET 139 140 // func Or32(addr *uint32, v uint32) 141 TEXT ·Or32(SB), NOSPLIT, $0-8 142 MOVW ptr+0(FP), R1 143 MOVW val+4(FP), R2 144 145 SYNC 146 LL (R1), R3 147 OR R2, R3 148 SC R3, (R1) 149 BEQ R3, -4(PC) 150 SYNC 151 RET 152 153 // void And8(byte volatile*, byte); 154 TEXT ·And8(SB),NOSPLIT,$0-5 155 MOVW ptr+0(FP), R1 156 MOVBU val+4(FP), R2 157 MOVW $~3, R3 158 AND R1, R3 159 #ifdef GOARCH_mips 160 // Big endian. ptr = ptr ^ 3 161 XOR $3, R1 162 #endif 163 AND $3, R1, R4 // R4 = ((ptr & 3) * 8) 164 SLL $3, R4 165 MOVW $0xFF, R5 166 SLL R4, R2 167 SLL R4, R5 168 NOR R0, R5 169 OR R5, R2 // Shift val for aligned ptr. R2 = val << R4 | ^(0xFF << R4) 170 SYNC 171 try_and8: 172 LL (R3), R4 // R4 = *R3 173 AND R2, R4 174 SC R4, (R3) // *R3 = R4 175 BEQ R4, try_and8 176 SYNC 177 RET 178 179 // func And32(addr *uint32, v uint32) 180 TEXT ·And32(SB), NOSPLIT, $0-8 181 MOVW ptr+0(FP), R1 182 MOVW val+4(FP), R2 183 184 SYNC 185 LL (R1), R3 186 AND R2, R3 187 SC R3, (R1) 188 BEQ R3, -4(PC) 189 SYNC 190 RET 191 192 // 193 // Swap 194 // 195 196 // uint32 Swap32(ptr *uint32, new uint32) 197 TEXT ·Swap32(SB),NOSPLIT,$0-12 198 MOVW ptr+0(FP), R2 199 MOVW new+4(FP), R5 200 SYNC 201 try_xchg: 202 MOVW R5, R3 203 LL (R2), R1 // R1 = *R2 204 SC R3, (R2) // *R2 = R3 205 BEQ R3, try_xchg 206 SYNC 207 MOVW R1, ret+8(FP) 208 RET 209 210 TEXT ·SwapUintptr(SB),NOSPLIT,$0-12 211 JMP ·Swap32(SB) 212 213 TEXT ·SwapInt32(SB),NOSPLIT,$0-12 214 JMP ·Swap32(SB) 215 216 TEXT ·SwapInt64(SB),NOSPLIT,$0-20 217 JMP ·Swap64(SB) 218 219 // 220 // Add 221 // 222 223 // uint32 Add32(uint32 volatile *val, int32 delta) 224 TEXT ·Add32(SB),NOSPLIT,$0-12 225 MOVW ptr+0(FP), R2 226 MOVW delta+4(FP), R3 227 SYNC 228 try_xadd: 229 LL (R2), R1 // R1 = *R2 230 ADDU R1, R3, R4 231 MOVW R4, R1 232 SC R4, (R2) // *R2 = R4 233 BEQ R4, try_xadd 234 SYNC 235 MOVW R1, ret+8(FP) 236 RET 237 238 TEXT ·AddUintptr(SB),NOSPLIT,$0-12 239 JMP ·Add32(SB) 240 241 TEXT ·AddInt32(SB),NOSPLIT,$0-12 242 JMP ·Add32(SB) 243 244 TEXT ·AddInt64(SB),NOSPLIT,$0-20 245 JMP ·Add64(SB) 246 247 // 248 // Compare and swap 249 // 250 251 // bool Cas32(int32 *val, int32 old, int32 new) 252 TEXT ·Cas32(SB),NOSPLIT,$0-13 253 MOVW ptr+0(FP), R1 254 MOVW old+4(FP), R2 255 MOVW new+8(FP), R5 256 SYNC 257 try_cas: 258 MOVW R5, R3 259 LL (R1), R4 // R4 = *R1 260 BNE R2, R4, cas_fail 261 SC R3, (R1) // *R1 = R3 262 BEQ R3, try_cas 263 SYNC 264 MOVB R3, ret+12(FP) 265 RET 266 cas_fail: 267 MOVB R0, ret+12(FP) 268 RET 269 270 TEXT ·CasUintptr(SB),NOSPLIT,$0-13 271 JMP ·Cas32(SB) 272 273 TEXT ·CasUnsafePointer(SB),NOSPLIT,$0-13 274 JMP ·Cas(SB) 275 276 TEXT ·CasInt32(SB),NOSPLIT,$0-13 277 JMP ·Cas32(SB) 278 279 TEXT ·CasInt64(SB),NOSPLIT,$0-21 280 JMP ·Cas64(SB) 281 282 // 283 // CasRel 284 // 285 286 TEXT ·CasRel32(SB),NOSPLIT,$0-13 287 JMP ·Cas32(SB)