1// Copyright 2016 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//go:build mips || mipsle 6 7#include "textflag.h" 8 9// bool Cas(int32 *val, int32 old, int32 new) 10// Atomically: 11// if(*val == old){ 12// *val = new; 13// return 1; 14// } else 15// return 0; 16TEXT ·Cas(SB),NOSPLIT,$0-13 17 MOVW ptr+0(FP), R1 18 MOVW old+4(FP), R2 19 MOVW new+8(FP), R5 20 SYNC 21try_cas: 22 MOVW R5, R3 23 LL (R1), R4 // R4 = *R1 24 BNE R2, R4, cas_fail 25 SC R3, (R1) // *R1 = R3 26 BEQ R3, try_cas 27 SYNC 28 MOVB R3, ret+12(FP) 29 RET 30cas_fail: 31 SYNC 32 MOVB R0, ret+12(FP) 33 RET 34 35TEXT ·Store(SB),NOSPLIT,$0-8 36 MOVW ptr+0(FP), R1 37 MOVW val+4(FP), R2 38 SYNC 39 MOVW R2, 0(R1) 40 SYNC 41 RET 42 43TEXT ·Store8(SB),NOSPLIT,$0-5 44 MOVW ptr+0(FP), R1 45 MOVB val+4(FP), R2 46 SYNC 47 MOVB R2, 0(R1) 48 SYNC 49 RET 50 51TEXT ·Load(SB),NOSPLIT,$0-8 52 MOVW ptr+0(FP), R1 53 SYNC 54 MOVW 0(R1), R1 55 SYNC 56 MOVW R1, ret+4(FP) 57 RET 58 59TEXT ·Load8(SB),NOSPLIT,$0-5 60 MOVW ptr+0(FP), R1 61 SYNC 62 MOVB 0(R1), R1 63 SYNC 64 MOVB R1, ret+4(FP) 65 RET 66 67// uint32 Xadd(uint32 volatile *val, int32 delta) 68// Atomically: 69// *val += delta; 70// return *val; 71TEXT ·Xadd(SB),NOSPLIT,$0-12 72 MOVW ptr+0(FP), R2 73 MOVW delta+4(FP), R3 74 SYNC 75try_xadd: 76 LL (R2), R1 // R1 = *R2 77 ADDU R1, R3, R4 78 MOVW R4, R1 79 SC R4, (R2) // *R2 = R4 80 BEQ R4, try_xadd 81 SYNC 82 MOVW R1, ret+8(FP) 83 RET 84 85// uint32 Xchg(ptr *uint32, new uint32) 86// Atomically: 87// old := *ptr; 88// *ptr = new; 89// return old; 90TEXT ·Xchg(SB),NOSPLIT,$0-12 91 MOVW ptr+0(FP), R2 92 MOVW new+4(FP), R5 93 SYNC 94try_xchg: 95 MOVW R5, R3 96 LL (R2), R1 // R1 = *R2 97 SC R3, (R2) // *R2 = R3 98 BEQ R3, try_xchg 99 SYNC 100 MOVW R1, ret+8(FP) 101 RET 102 103TEXT ·Casint32(SB),NOSPLIT,$0-13 104 JMP ·Cas(SB) 105 106TEXT ·Casint64(SB),NOSPLIT,$0-21 107 JMP ·Cas64(SB) 108 109TEXT ·Casuintptr(SB),NOSPLIT,$0-13 110 JMP ·Cas(SB) 111 112TEXT ·CasRel(SB),NOSPLIT,$0-13 113 JMP ·Cas(SB) 114 115TEXT ·Loaduintptr(SB),NOSPLIT,$0-8 116 JMP ·Load(SB) 117 118TEXT ·Loaduint(SB),NOSPLIT,$0-8 119 JMP ·Load(SB) 120 121TEXT ·Loadp(SB),NOSPLIT,$-0-8 122 JMP ·Load(SB) 123 124TEXT ·Storeint32(SB),NOSPLIT,$0-8 125 JMP ·Store(SB) 126 127TEXT ·Storeint64(SB),NOSPLIT,$0-12 128 JMP ·Store64(SB) 129 130TEXT ·Storeuintptr(SB),NOSPLIT,$0-8 131 JMP ·Store(SB) 132 133TEXT ·Xadduintptr(SB),NOSPLIT,$0-12 134 JMP ·Xadd(SB) 135 136TEXT ·Loadint32(SB),NOSPLIT,$0-8 137 JMP ·Load(SB) 138 139TEXT ·Loadint64(SB),NOSPLIT,$0-12 140 JMP ·Load64(SB) 141 142TEXT ·Xaddint32(SB),NOSPLIT,$0-12 143 JMP ·Xadd(SB) 144 145TEXT ·Xaddint64(SB),NOSPLIT,$0-20 146 JMP ·Xadd64(SB) 147 148TEXT ·Casp1(SB),NOSPLIT,$0-13 149 JMP ·Cas(SB) 150 151TEXT ·Xchgint32(SB),NOSPLIT,$0-12 152 JMP ·Xchg(SB) 153 154TEXT ·Xchgint64(SB),NOSPLIT,$0-20 155 JMP ·Xchg64(SB) 156 157TEXT ·Xchguintptr(SB),NOSPLIT,$0-12 158 JMP ·Xchg(SB) 159 160TEXT ·StorepNoWB(SB),NOSPLIT,$0-8 161 JMP ·Store(SB) 162 163TEXT ·StoreRel(SB),NOSPLIT,$0-8 164 JMP ·Store(SB) 165 166TEXT ·StoreReluintptr(SB),NOSPLIT,$0-8 167 JMP ·Store(SB) 168 169// void Or8(byte volatile*, byte); 170TEXT ·Or8(SB),NOSPLIT,$0-5 171 MOVW ptr+0(FP), R1 172 MOVBU val+4(FP), R2 173 MOVW $~3, R3 // Align ptr down to 4 bytes so we can use 32-bit load/store. 174 AND R1, R3 175#ifdef GOARCH_mips 176 // Big endian. ptr = ptr ^ 3 177 XOR $3, R1 178#endif 179 AND $3, R1, R4 // R4 = ((ptr & 3) * 8) 180 SLL $3, R4 181 SLL R4, R2, R2 // Shift val for aligned ptr. R2 = val << R4 182 SYNC 183try_or8: 184 LL (R3), R4 // R4 = *R3 185 OR R2, R4 186 SC R4, (R3) // *R3 = R4 187 BEQ R4, try_or8 188 SYNC 189 RET 190 191// void And8(byte volatile*, byte); 192TEXT ·And8(SB),NOSPLIT,$0-5 193 MOVW ptr+0(FP), R1 194 MOVBU val+4(FP), R2 195 MOVW $~3, R3 196 AND R1, R3 197#ifdef GOARCH_mips 198 // Big endian. ptr = ptr ^ 3 199 XOR $3, R1 200#endif 201 AND $3, R1, R4 // R4 = ((ptr & 3) * 8) 202 SLL $3, R4 203 MOVW $0xFF, R5 204 SLL R4, R2 205 SLL R4, R5 206 NOR R0, R5 207 OR R5, R2 // Shift val for aligned ptr. R2 = val << R4 | ^(0xFF << R4) 208 SYNC 209try_and8: 210 LL (R3), R4 // R4 = *R3 211 AND R2, R4 212 SC R4, (R3) // *R3 = R4 213 BEQ R4, try_and8 214 SYNC 215 RET 216 217// func Or(addr *uint32, v uint32) 218TEXT ·Or(SB), NOSPLIT, $0-8 219 MOVW ptr+0(FP), R1 220 MOVW val+4(FP), R2 221 222 SYNC 223 LL (R1), R3 224 OR R2, R3 225 SC R3, (R1) 226 BEQ R3, -4(PC) 227 SYNC 228 RET 229 230// func And(addr *uint32, v uint32) 231TEXT ·And(SB), NOSPLIT, $0-8 232 MOVW ptr+0(FP), R1 233 MOVW val+4(FP), R2 234 235 SYNC 236 LL (R1), R3 237 AND R2, R3 238 SC R3, (R1) 239 BEQ R3, -4(PC) 240 SYNC 241 RET 242 243// func Or32(addr *uint32, v uint32) old uint32 244TEXT ·Or32(SB), NOSPLIT, $0-12 245 MOVW ptr+0(FP), R1 246 MOVW val+4(FP), R2 247 248 SYNC 249 LL (R1), R3 250 OR R2, R3, R4 251 SC R4, (R1) 252 BEQ R4, -4(PC) 253 SYNC 254 MOVW R3, ret+8(FP) 255 RET 256 257// func And32(addr *uint32, v uint32) old uint32 258TEXT ·And32(SB), NOSPLIT, $0-12 259 MOVW ptr+0(FP), R1 260 MOVW val+4(FP), R2 261 262 SYNC 263 LL (R1), R3 264 AND R2, R3, R4 265 SC R4, (R1) 266 BEQ R4, -4(PC) 267 SYNC 268 MOVW R3, ret+8(FP) 269 RET 270 271// func Anduintptr(addr *uintptr, v uintptr) old uintptr 272TEXT ·Anduintptr(SB), NOSPLIT, $0-12 273 JMP ·And32(SB) 274 275// func Oruintptr(addr *uintptr, v uintptr) old uintptr 276TEXT ·Oruintptr(SB), NOSPLIT, $0-12 277 JMP ·Or32(SB) 278 279TEXT ·spinLock(SB),NOSPLIT,$0-4 280 MOVW state+0(FP), R1 281 MOVW $1, R2 282 SYNC 283try_lock: 284 MOVW R2, R3 285check_again: 286 LL (R1), R4 287 BNE R4, check_again 288 SC R3, (R1) 289 BEQ R3, try_lock 290 SYNC 291 RET 292 293TEXT ·spinUnlock(SB),NOSPLIT,$0-4 294 MOVW state+0(FP), R1 295 SYNC 296 MOVW R0, (R1) 297 SYNC 298 RET 299