]> Cypherpunks.ru repositories - gostls13.git/blobdiff - src/runtime/internal/atomic/atomic_arm64.go
runtime/internal/atomic: add arm/arm64 operators for And/Or
[gostls13.git] / src / runtime / internal / atomic / atomic_arm64.go
index dc82c3396d9362e897b1a6da9cb2d7c87f89888e..c4c56ae8951c6b548f1bb0eee1e58692d4d1aa19 100644 (file)
@@ -2,11 +2,18 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build arm64
+//go:build arm64
 
 package atomic
 
-import "unsafe"
+import (
+       "internal/cpu"
+       "unsafe"
+)
+
+const (
+       offsetARM64HasATOMICS = unsafe.Offsetof(cpu.ARM64.HasATOMICS)
+)
 
 //go:noescape
 func Xadd(ptr *uint32, delta int32) uint32
@@ -30,51 +37,76 @@ func Xchguintptr(ptr *uintptr, new uintptr) uintptr
 func Load(ptr *uint32) uint32
 
 //go:noescape
-func Load64(ptr *uint64) uint64
+func Load8(ptr *uint8) uint8
 
 //go:noescape
+func Load64(ptr *uint64) uint64
+
+// NO go:noescape annotation; *ptr escapes if result escapes (#31525)
 func Loadp(ptr unsafe.Pointer) unsafe.Pointer
 
-//go:nosplit
-func Or8(addr *uint8, v uint8) {
-       // TODO(dfc) implement this in asm.
-       // Align down to 4 bytes and use 32-bit CAS.
-       uaddr := uintptr(unsafe.Pointer(addr))
-       addr32 := (*uint32)(unsafe.Pointer(uaddr &^ 3))
-       word := uint32(v) << ((uaddr & 3) * 8) // little endian
-       for {
-               old := *addr32
-               if Cas(addr32, old, old|word) {
-                       return
-               }
-       }
-}
-
-//go:nosplit
-func And8(addr *uint8, v uint8) {
-       // TODO(dfc) implement this in asm.
-       // Align down to 4 bytes and use 32-bit CAS.
-       uaddr := uintptr(unsafe.Pointer(addr))
-       addr32 := (*uint32)(unsafe.Pointer(uaddr &^ 3))
-       word := uint32(v) << ((uaddr & 3) * 8)    // little endian
-       mask := uint32(0xFF) << ((uaddr & 3) * 8) // little endian
-       word |= ^mask
-       for {
-               old := *addr32
-               if Cas(addr32, old, old&word) {
-                       return
-               }
-       }
-}
+//go:noescape
+func LoadAcq(addr *uint32) uint32
+
+//go:noescape
+func LoadAcq64(ptr *uint64) uint64
+
+//go:noescape
+func LoadAcquintptr(ptr *uintptr) uintptr
+
+//go:noescape
+func Or8(ptr *uint8, val uint8)
+
+//go:noescape
+func And8(ptr *uint8, val uint8)
+
+//go:noescape
+func And(ptr *uint32, val uint32)
+
+//go:noescape
+func Or(ptr *uint32, val uint32)
+
+//go:noescape
+func And32(ptr *uint32, val uint32) uint32
+
+//go:noescape
+func Or32(ptr *uint32, val uint32) uint32
+
+//go:noescape
+func And64(ptr *uint64, val uint64) uint64
+
+//go:noescape
+func Or64(ptr *uint64, val uint64) uint64
+
+//go:noescape
+func Anduintptr(ptr *uintptr, val uintptr) uintptr
+
+//go:noescape
+func Oruintptr(ptr *uintptr, val uintptr) uintptr
 
 //go:noescape
 func Cas64(ptr *uint64, old, new uint64) bool
 
+//go:noescape
+func CasRel(ptr *uint32, old, new uint32) bool
+
 //go:noescape
 func Store(ptr *uint32, val uint32)
 
+//go:noescape
+func Store8(ptr *uint8, val uint8)
+
 //go:noescape
 func Store64(ptr *uint64, val uint64)
 
 // NO go:noescape annotation; see atomic_pointer.go.
 func StorepNoWB(ptr unsafe.Pointer, val unsafe.Pointer)
+
+//go:noescape
+func StoreRel(ptr *uint32, val uint32)
+
+//go:noescape
+func StoreRel64(ptr *uint64, val uint64)
+
+//go:noescape
+func StoreReluintptr(ptr *uintptr, val uintptr)