github.com/ice-blockchain/go/src@v0.0.0-20240403114104-1564d284e521/runtime/internal/atomic/atomic_s390x.s (about) 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 #include "textflag.h" 6 7 // func Store(ptr *uint32, val uint32) 8 TEXT ·Store(SB), NOSPLIT, $0 9 MOVD ptr+0(FP), R2 10 MOVWZ val+8(FP), R3 11 MOVW R3, 0(R2) 12 SYNC 13 RET 14 15 // func Store8(ptr *uint8, val uint8) 16 TEXT ·Store8(SB), NOSPLIT, $0 17 MOVD ptr+0(FP), R2 18 MOVB val+8(FP), R3 19 MOVB R3, 0(R2) 20 SYNC 21 RET 22 23 // func Store64(ptr *uint64, val uint64) 24 TEXT ·Store64(SB), NOSPLIT, $0 25 MOVD ptr+0(FP), R2 26 MOVD val+8(FP), R3 27 MOVD R3, 0(R2) 28 SYNC 29 RET 30 31 // func StorepNoWB(ptr unsafe.Pointer, val unsafe.Pointer) 32 TEXT ·StorepNoWB(SB), NOSPLIT, $0 33 MOVD ptr+0(FP), R2 34 MOVD val+8(FP), R3 35 MOVD R3, 0(R2) 36 SYNC 37 RET 38 39 // func Cas(ptr *uint32, old, new uint32) bool 40 // Atomically: 41 // if *ptr == old { 42 // *val = new 43 // return 1 44 // } else { 45 // return 0 46 // } 47 TEXT ·Cas(SB), NOSPLIT, $0-17 48 MOVD ptr+0(FP), R3 49 MOVWZ old+8(FP), R4 50 MOVWZ new+12(FP), R5 51 CS R4, R5, 0(R3) // if (R4 == 0(R3)) then 0(R3)= R5 52 BNE cas_fail 53 MOVB $1, ret+16(FP) 54 RET 55 cas_fail: 56 MOVB $0, ret+16(FP) 57 RET 58 59 // func Cas64(ptr *uint64, old, new uint64) bool 60 // Atomically: 61 // if *ptr == old { 62 // *ptr = new 63 // return 1 64 // } else { 65 // return 0 66 // } 67 TEXT ·Cas64(SB), NOSPLIT, $0-25 68 MOVD ptr+0(FP), R3 69 MOVD old+8(FP), R4 70 MOVD new+16(FP), R5 71 CSG R4, R5, 0(R3) // if (R4 == 0(R3)) then 0(R3)= R5 72 BNE cas64_fail 73 MOVB $1, ret+24(FP) 74 RET 75 cas64_fail: 76 MOVB $0, ret+24(FP) 77 RET 78 79 // func Casint32(ptr *int32, old, new int32) bool 80 TEXT ·Casint32(SB), NOSPLIT, $0-17 81 BR ·Cas(SB) 82 83 // func Casint64(ptr *int64, old, new int64) bool 84 TEXT ·Casint64(SB), NOSPLIT, $0-25 85 BR ·Cas64(SB) 86 87 // func Casuintptr(ptr *uintptr, old, new uintptr) bool 88 TEXT ·Casuintptr(SB), NOSPLIT, $0-25 89 BR ·Cas64(SB) 90 91 // func CasRel(ptr *uint32, old, new uint32) bool 92 TEXT ·CasRel(SB), NOSPLIT, $0-17 93 BR ·Cas(SB) 94 95 // func Loaduintptr(ptr *uintptr) uintptr 96 TEXT ·Loaduintptr(SB), NOSPLIT, $0-16 97 BR ·Load64(SB) 98 99 // func Loaduint(ptr *uint) uint 100 TEXT ·Loaduint(SB), NOSPLIT, $0-16 101 BR ·Load64(SB) 102 103 // func Storeint32(ptr *int32, new int32) 104 TEXT ·Storeint32(SB), NOSPLIT, $0-12 105 BR ·Store(SB) 106 107 // func Storeint64(ptr *int64, new int64) 108 TEXT ·Storeint64(SB), NOSPLIT, $0-16 109 BR ·Store64(SB) 110 111 // func Storeuintptr(ptr *uintptr, new uintptr) 112 TEXT ·Storeuintptr(SB), NOSPLIT, $0-16 113 BR ·Store64(SB) 114 115 // func Loadint32(ptr *int32) int32 116 TEXT ·Loadint32(SB), NOSPLIT, $0-12 117 BR ·Load(SB) 118 119 // func Loadint64(ptr *int64) int64 120 TEXT ·Loadint64(SB), NOSPLIT, $0-16 121 BR ·Load64(SB) 122 123 // func Xadduintptr(ptr *uintptr, delta uintptr) uintptr 124 TEXT ·Xadduintptr(SB), NOSPLIT, $0-24 125 BR ·Xadd64(SB) 126 127 // func Xaddint32(ptr *int32, delta int32) int32 128 TEXT ·Xaddint32(SB), NOSPLIT, $0-20 129 BR ·Xadd(SB) 130 131 // func Xaddint64(ptr *int64, delta int64) int64 132 TEXT ·Xaddint64(SB), NOSPLIT, $0-24 133 BR ·Xadd64(SB) 134 135 // func Casp1(ptr *unsafe.Pointer, old, new unsafe.Pointer) bool 136 // Atomically: 137 // if *ptr == old { 138 // *ptr = new 139 // return 1 140 // } else { 141 // return 0 142 // } 143 TEXT ·Casp1(SB), NOSPLIT, $0-25 144 BR ·Cas64(SB) 145 146 // func Xadd(ptr *uint32, delta int32) uint32 147 // Atomically: 148 // *ptr += delta 149 // return *ptr 150 TEXT ·Xadd(SB), NOSPLIT, $0-20 151 MOVD ptr+0(FP), R4 152 MOVW delta+8(FP), R5 153 MOVW (R4), R3 154 repeat: 155 ADD R5, R3, R6 156 CS R3, R6, (R4) // if R3==(R4) then (R4)=R6 else R3=(R4) 157 BNE repeat 158 MOVW R6, ret+16(FP) 159 RET 160 161 // func Xadd64(ptr *uint64, delta int64) uint64 162 TEXT ·Xadd64(SB), NOSPLIT, $0-24 163 MOVD ptr+0(FP), R4 164 MOVD delta+8(FP), R5 165 MOVD (R4), R3 166 repeat: 167 ADD R5, R3, R6 168 CSG R3, R6, (R4) // if R3==(R4) then (R4)=R6 else R3=(R4) 169 BNE repeat 170 MOVD R6, ret+16(FP) 171 RET 172 173 // func Xchg(ptr *uint32, new uint32) uint32 174 TEXT ·Xchg(SB), NOSPLIT, $0-20 175 MOVD ptr+0(FP), R4 176 MOVW new+8(FP), R3 177 MOVW (R4), R6 178 repeat: 179 CS R6, R3, (R4) // if R6==(R4) then (R4)=R3 else R6=(R4) 180 BNE repeat 181 MOVW R6, ret+16(FP) 182 RET 183 184 // func Xchg64(ptr *uint64, new uint64) uint64 185 TEXT ·Xchg64(SB), NOSPLIT, $0-24 186 MOVD ptr+0(FP), R4 187 MOVD new+8(FP), R3 188 MOVD (R4), R6 189 repeat: 190 CSG R6, R3, (R4) // if R6==(R4) then (R4)=R3 else R6=(R4) 191 BNE repeat 192 MOVD R6, ret+16(FP) 193 RET 194 195 // func Xchgint32(ptr *int32, new int32) int32 196 TEXT ·Xchgint32(SB), NOSPLIT, $0-20 197 BR ·Xchg(SB) 198 199 // func Xchgint64(ptr *int64, new int64) int64 200 TEXT ·Xchgint64(SB), NOSPLIT, $0-24 201 BR ·Xchg64(SB) 202 203 // func Xchguintptr(ptr *uintptr, new uintptr) uintptr 204 TEXT ·Xchguintptr(SB), NOSPLIT, $0-24 205 BR ·Xchg64(SB) 206 207 // func Or8(addr *uint8, v uint8) 208 TEXT ·Or8(SB), NOSPLIT, $0-9 209 MOVD ptr+0(FP), R3 210 MOVBZ val+8(FP), R4 211 // We don't have atomic operations that work on individual bytes so we 212 // need to align addr down to a word boundary and create a mask 213 // containing v to OR with the entire word atomically. 214 MOVD $(3<<3), R5 215 RXSBG $59, $60, $3, R3, R5 // R5 = 24 - ((addr % 4) * 8) = ((addr & 3) << 3) ^ (3 << 3) 216 ANDW $~3, R3 // R3 = floor(addr, 4) = addr &^ 3 217 SLW R5, R4 // R4 = uint32(v) << R5 218 LAO R4, R6, 0(R3) // R6 = *R3; *R3 |= R4; (atomic) 219 RET 220 221 // func And8(addr *uint8, v uint8) 222 TEXT ·And8(SB), NOSPLIT, $0-9 223 MOVD ptr+0(FP), R3 224 MOVBZ val+8(FP), R4 225 // We don't have atomic operations that work on individual bytes so we 226 // need to align addr down to a word boundary and create a mask 227 // containing v to AND with the entire word atomically. 228 ORW $~0xff, R4 // R4 = uint32(v) | 0xffffff00 229 MOVD $(3<<3), R5 230 RXSBG $59, $60, $3, R3, R5 // R5 = 24 - ((addr % 4) * 8) = ((addr & 3) << 3) ^ (3 << 3) 231 ANDW $~3, R3 // R3 = floor(addr, 4) = addr &^ 3 232 RLL R5, R4, R4 // R4 = rotl(R4, R5) 233 LAN R4, R6, 0(R3) // R6 = *R3; *R3 &= R4; (atomic) 234 RET 235 236 // func Or(addr *uint32, v uint32) 237 TEXT ·Or(SB), NOSPLIT, $0-12 238 MOVD ptr+0(FP), R3 239 MOVW val+8(FP), R4 240 LAO R4, R6, 0(R3) // R6 = *R3; *R3 |= R4; (atomic) 241 RET 242 243 // func And(addr *uint32, v uint32) 244 TEXT ·And(SB), NOSPLIT, $0-12 245 MOVD ptr+0(FP), R3 246 MOVW val+8(FP), R4 247 LAN R4, R6, 0(R3) // R6 = *R3; *R3 &= R4; (atomic) 248 RET 249 250 // func Or32(addr *uint32, v uint32) old uint32 251 TEXT ·Or32(SB), NOSPLIT, $0-20 252 MOVD ptr+0(FP), R4 253 MOVW val+8(FP), R5 254 MOVW (R4), R3 255 repeat: 256 OR R5, R3, R6 257 CS R3, R6, (R4) // if R3==(R4) then (R4)=R6 else R3=(R4) 258 BNE repeat 259 MOVW R3, ret+16(FP) 260 RET 261 262 // func And32(addr *uint32, v uint32) old uint32 263 TEXT ·And32(SB), NOSPLIT, $0-20 264 MOVD ptr+0(FP), R4 265 MOVW val+8(FP), R5 266 MOVW (R4), R3 267 repeat: 268 AND R5, R3, R6 269 CS R3, R6, (R4) // if R3==(R4) then (R4)=R6 else R3=(R4) 270 BNE repeat 271 MOVW R3, ret+16(FP) 272 RET 273 274 // func Or64(addr *uint64, v uint64) old uint64 275 TEXT ·Or64(SB), NOSPLIT, $0-24 276 MOVD ptr+0(FP), R4 277 MOVD val+8(FP), R5 278 MOVD (R4), R3 279 repeat: 280 OR R5, R3, R6 281 CSG R3, R6, (R4) // if R3==(R4) then (R4)=R6 else R3=(R4) 282 BNE repeat 283 MOVD R3, ret+16(FP) 284 RET 285 286 // func And64(addr *uint64, v uint64) old uint64 287 TEXT ·And64(SB), NOSPLIT, $0-24 288 MOVD ptr+0(FP), R4 289 MOVD val+8(FP), R5 290 MOVD (R4), R3 291 repeat: 292 AND R5, R3, R6 293 CSG R3, R6, (R4) // if R3==(R4) then (R4)=R6 else R3=(R4) 294 BNE repeat 295 MOVD R3, ret+16(FP) 296 RET 297 298 // func Anduintptr(addr *uintptr, v uintptr) old uintptr 299 TEXT ·Anduintptr(SB), NOSPLIT, $0-24 300 BR ·And64(SB) 301 302 // func Oruintptr(addr *uintptr, v uintptr) old uintptr 303 TEXT ·Oruintptr(SB), NOSPLIT, $0-24 304 BR ·Or64(SB)