github.com/primecitizens/pcz/std@v0.2.1/core/atomic/atomic_s390x.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 s390x 9 10 #include "textflag.h" 11 12 TEXT ·PublicationBarrier(SB),NOSPLIT|NOFRAME,$0-0 13 // Stores are already ordered on s390x, so this is just a 14 // compile barrier. 15 RET 16 17 // func Store8(ptr *uint8, val uint8) 18 TEXT ·Store8(SB), NOSPLIT, $0 19 MOVD ptr+0(FP), R2 20 MOVB val+8(FP), R3 21 MOVB R3, 0(R2) 22 SYNC 23 RET 24 25 // func Store32(ptr *uint32, val uint32) 26 TEXT ·Store32(SB), NOSPLIT, $0 27 MOVD ptr+0(FP), R2 28 MOVWZ val+8(FP), R3 29 MOVW R3, 0(R2) 30 SYNC 31 RET 32 33 // func Store64(ptr *uint64, val uint64) 34 TEXT ·Store64(SB), NOSPLIT, $0 35 MOVD ptr+0(FP), R2 36 MOVD val+8(FP), R3 37 MOVD R3, 0(R2) 38 SYNC 39 RET 40 41 // func StorePointer(ptr unsafe.Pointer, val unsafe.Pointer) 42 TEXT ·StorePointer(SB), NOSPLIT, $0 43 MOVD ptr+0(FP), R2 44 MOVD val+8(FP), R3 45 MOVD R3, 0(R2) 46 SYNC 47 RET 48 49 // func StoreUintptr(ptr *uintptr, new uintptr) 50 TEXT ·StoreUintptr(SB), NOSPLIT, $0-16 51 BR ·Store64(SB) 52 53 // func StoreInt32(ptr *int32, new int32) 54 TEXT ·StoreInt32(SB), NOSPLIT, $0-12 55 BR ·Store32(SB) 56 57 // func StoreInt64(ptr *int64, new int64) 58 TEXT ·StoreInt64(SB), NOSPLIT, $0-16 59 BR ·Store64(SB) 60 61 // 62 // Load 63 // 64 65 // func LoadUintptr(ptr *uintptr) uintptr 66 TEXT ·LoadUintptr(SB), NOSPLIT, $0-16 67 BR ·Load64(SB) 68 69 // func LoadUint(ptr *uint) uint 70 TEXT ·LoadUint(SB), NOSPLIT, $0-16 71 BR ·Load64(SB) 72 73 // func LoadInt32(ptr *int32) int32 74 TEXT ·LoadInt32(SB), NOSPLIT, $0-12 75 BR ·Load32(SB) 76 77 // func LoadInt64(ptr *int64) int64 78 TEXT ·LoadInt64(SB), NOSPLIT, $0-16 79 BR ·Load64(SB) 80 81 // 82 // bitwise 83 // 84 85 // func Or8(addr *uint8, v uint8) 86 TEXT ·Or8(SB), NOSPLIT, $0-9 87 MOVD ptr+0(FP), R3 88 MOVBZ val+8(FP), R4 89 // We don't have atomic operations that work on individual bytes so we 90 // need to align addr down to a word boundary and create a mask 91 // containing v to OR with the entire word atomically. 92 MOVD $(3<<3), R5 93 RXSBG $59, $60, $3, R3, R5 // R5 = 24 - ((addr % 4) * 8) = ((addr & 3) << 3) ^ (3 << 3) 94 ANDW $~3, R3 // R3 = floor(addr, 4) = addr &^ 3 95 SLW R5, R4 // R4 = uint32(v) << R5 96 LAO R4, R6, 0(R3) // R6 = *R3; *R3 |= R4; (atomic) 97 RET 98 99 // func Or32(addr *uint32, v uint32) 100 TEXT ·Or32(SB), NOSPLIT, $0-12 101 MOVD ptr+0(FP), R3 102 MOVW val+8(FP), R4 103 LAO R4, R6, 0(R3) // R6 = *R3; *R3 |= R4; (atomic) 104 RET 105 106 // func And8(addr *uint8, v uint8) 107 TEXT ·And8(SB), NOSPLIT, $0-9 108 MOVD ptr+0(FP), R3 109 MOVBZ val+8(FP), R4 110 // We don't have atomic operations that work on individual bytes so we 111 // need to align addr down to a word boundary and create a mask 112 // containing v to AND with the entire word atomically. 113 ORW $~0xff, R4 // R4 = uint32(v) | 0xffffff00 114 MOVD $(3<<3), R5 115 RXSBG $59, $60, $3, R3, R5 // R5 = 24 - ((addr % 4) * 8) = ((addr & 3) << 3) ^ (3 << 3) 116 ANDW $~3, R3 // R3 = floor(addr, 4) = addr &^ 3 117 RLL R5, R4, R4 // R4 = rotl(R4, R5) 118 LAN R4, R6, 0(R3) // R6 = *R3; *R3 &= R4; (atomic) 119 RET 120 121 // func And32(addr *uint32, v uint32) 122 TEXT ·And32(SB), NOSPLIT, $0-12 123 MOVD ptr+0(FP), R3 124 MOVW val+8(FP), R4 125 LAN R4, R6, 0(R3) // R6 = *R3; *R3 &= R4; (atomic) 126 RET 127 128 129 // 130 // Swap 131 // 132 133 // func Swap32(ptr *uint32, new uint32) uint32 134 TEXT ·Swap32(SB), NOSPLIT, $0-20 135 MOVD ptr+0(FP), R4 136 MOVW new+8(FP), R3 137 MOVW (R4), R6 138 repeat: 139 CS R6, R3, (R4) // if R6==(R4) then (R4)=R3 else R6=(R4) 140 BNE repeat 141 MOVW R6, ret+16(FP) 142 RET 143 144 // func Swap64(ptr *uint64, new uint64) uint64 145 TEXT ·Swap64(SB), NOSPLIT, $0-24 146 MOVD ptr+0(FP), R4 147 MOVD new+8(FP), R3 148 MOVD (R4), R6 149 repeat: 150 CSG R6, R3, (R4) // if R6==(R4) then (R4)=R3 else R6=(R4) 151 BNE repeat 152 MOVD R6, ret+16(FP) 153 RET 154 155 // func SwapInt32(ptr *int32, new int32) int32 156 TEXT ·SwapInt32(SB), NOSPLIT, $0-20 157 BR ·Swap32(SB) 158 159 // func SwapInt64(ptr *int64, new int64) int64 160 TEXT ·SwapInt64(SB), NOSPLIT, $0-24 161 BR ·Swap64(SB) 162 163 // func SwapUintptr(ptr *uintptr, new uintptr) uintptr 164 TEXT ·SwapUintptr(SB), NOSPLIT, $0-24 165 BR ·Swap64(SB) 166 167 // 168 // Add 169 // 170 171 // func AddUintptr(ptr *uintptr, delta uintptr) uintptr 172 TEXT ·AddUintptr(SB), NOSPLIT, $0-24 173 BR ·Add64(SB) 174 175 // func AddInt32(ptr *int32, delta int32) int32 176 TEXT ·AddInt32(SB), NOSPLIT, $0-20 177 BR ·Add32(SB) 178 179 // func AddInt64(ptr *int64, delta int64) int64 180 TEXT ·AddInt64(SB), NOSPLIT, $0-24 181 BR ·Add64(SB) 182 183 // func Add32(ptr *uint32, delta int32) uint32 184 // Atomically: 185 // *ptr += delta 186 // return *ptr 187 TEXT ·Add32(SB), NOSPLIT, $0-20 188 MOVD ptr+0(FP), R4 189 MOVW delta+8(FP), R5 190 MOVW (R4), R3 191 repeat: 192 ADD R5, R3, R6 193 CS R3, R6, (R4) // if R3==(R4) then (R4)=R6 else R3=(R4) 194 BNE repeat 195 MOVW R6, ret+16(FP) 196 RET 197 198 // func Add64(ptr *uint64, delta int64) uint64 199 TEXT ·Add64(SB), NOSPLIT, $0-24 200 MOVD ptr+0(FP), R4 201 MOVD delta+8(FP), R5 202 MOVD (R4), R3 203 repeat: 204 ADD R5, R3, R6 205 CSG R3, R6, (R4) // if R3==(R4) then (R4)=R6 else R3=(R4) 206 BNE repeat 207 MOVD R6, ret+16(FP) 208 RET 209 210 // 211 // Compare and swap 212 // 213 214 // func Cas32(ptr *uint32, old, new uint32) bool 215 TEXT ·Cas32(SB), NOSPLIT, $0-17 216 MOVD ptr+0(FP), R3 217 MOVWZ old+8(FP), R4 218 MOVWZ new+12(FP), R5 219 CS R4, R5, 0(R3) // if (R4 == 0(R3)) then 0(R3)= R5 220 BNE cas_fail 221 MOVB $1, ret+16(FP) 222 RET 223 cas_fail: 224 MOVB $0, ret+16(FP) 225 RET 226 227 // func Cas64(ptr *uint64, old, new uint64) bool 228 TEXT ·Cas64(SB), NOSPLIT, $0-25 229 MOVD ptr+0(FP), R3 230 MOVD old+8(FP), R4 231 MOVD new+16(FP), R5 232 CSG R4, R5, 0(R3) // if (R4 == 0(R3)) then 0(R3)= R5 233 BNE cas64_fail 234 MOVB $1, ret+24(FP) 235 RET 236 cas64_fail: 237 MOVB $0, ret+24(FP) 238 RET 239 240 // func CasUintptr(ptr *uintptr, old, new uintptr) bool 241 TEXT ·CasUintptr(SB), NOSPLIT, $0-25 242 BR ·Cas64(SB) 243 244 // func CasUnsafePointer(ptr *unsafe.Pointer, old, new unsafe.Pointer) bool 245 TEXT ·CasUnsafePointer(SB), NOSPLIT, $0-25 246 BR ·Cas64(SB) 247 248 // func CasInt32(ptr *int32, old, new int32) bool 249 TEXT ·CasInt32(SB), NOSPLIT, $0-17 250 BR ·Cas32(SB) 251 252 // func CasInt64(ptr *int64, old, new int64) bool 253 TEXT ·CasInt64(SB), NOSPLIT, $0-25 254 BR ·Cas64(SB) 255 256 // func CasRel32(ptr *uint32, old, new uint32) bool 257 TEXT ·CasRel32(SB), NOSPLIT, $0-17 258 BR ·Cas32(SB)