aboutsummaryrefslogtreecommitdiff
path: root/src/runtime/internal
diff options
context:
space:
mode:
authorMauri de Souza Meneguzzo <mauri870@gmail.com>2023-11-06 22:33:25 +0000
committerKeith Randall <khr@golang.org>2023-11-07 17:27:06 +0000
commit0ccbf6306c8cac2b6f68ea6e8b098bb72b53473f (patch)
tree5d1d877ccd61c1a0505bd6d568f5ca3699e4d2ae /src/runtime/internal
parent72da49caee3319dcdc5f03a8f70352eb4b725a64 (diff)
downloadgo-0ccbf6306c8cac2b6f68ea6e8b098bb72b53473f.tar.xz
runtime/internal/atomic: add arm/arm64 operators for And/Or
This CL continues adding support for And/Or primitives to more architectures, this time for arm/arm64. For #61395 Change-Id: Icc44ea65884c825698a345299d8f9511392aceb6 GitHub-Last-Rev: 8267665a0348faa0a10ac63b18909a1b13f9971d GitHub-Pull-Request: golang/go#62674 Reviewed-on: https://go-review.googlesource.com/c/go/+/528797 Reviewed-by: Matthew Dempsky <mdempsky@google.com> Reviewed-by: Keith Randall <khr@golang.org> Run-TryBot: Mauri de Souza Meneguzzo <mauri870@gmail.com> TryBot-Result: Gopher Robot <gobot@golang.org> Reviewed-by: Keith Randall <khr@google.com>
Diffstat (limited to 'src/runtime/internal')
-rw-r--r--src/runtime/internal/atomic/atomic_andor_test.go2
-rw-r--r--src/runtime/internal/atomic/atomic_arm.go60
-rw-r--r--src/runtime/internal/atomic/atomic_arm64.go18
-rw-r--r--src/runtime/internal/atomic/atomic_arm64.s78
4 files changed, 157 insertions, 1 deletions
diff --git a/src/runtime/internal/atomic/atomic_andor_test.go b/src/runtime/internal/atomic/atomic_andor_test.go
index 1c198ba5c4..9dd8b60ae4 100644
--- a/src/runtime/internal/atomic/atomic_andor_test.go
+++ b/src/runtime/internal/atomic/atomic_andor_test.go
@@ -1,4 +1,4 @@
-//go:build 386 || amd64 || ppc64 || ppc64le || riscv64 || wasm
+//go:build 386 || amd64 || arm || arm64 || ppc64 || ppc64le || riscv64 || wasm
//
// Copyright 2023 The Go Authors. All rights reserved.
diff --git a/src/runtime/internal/atomic/atomic_arm.go b/src/runtime/internal/atomic/atomic_arm.go
index 567e951244..ae609cf4db 100644
--- a/src/runtime/internal/atomic/atomic_arm.go
+++ b/src/runtime/internal/atomic/atomic_arm.go
@@ -209,6 +209,66 @@ func And(addr *uint32, v uint32) {
}
//go:nosplit
+func Or32(addr *uint32, v uint32) uint32 {
+ for {
+ old := *addr
+ if Cas(addr, old, old|v) {
+ return old
+ }
+ }
+}
+
+//go:nosplit
+func And32(addr *uint32, v uint32) uint32 {
+ for {
+ old := *addr
+ if Cas(addr, old, old&v) {
+ return old
+ }
+ }
+}
+
+//go:nosplit
+func Or64(addr *uint64, v uint64) uint64 {
+ for {
+ old := *addr
+ if Cas64(addr, old, old|v) {
+ return old
+ }
+ }
+}
+
+//go:nosplit
+func And64(addr *uint64, v uint64) uint64 {
+ for {
+ old := *addr
+ if Cas64(addr, old, old&v) {
+ return old
+ }
+ }
+}
+
+//go:nosplit
+func Oruintptr(addr *uintptr, v uintptr) uintptr {
+ for {
+ old := *addr
+ if Casuintptr(addr, old, old|v) {
+ return old
+ }
+ }
+}
+
+//go:nosplit
+func Anduintptr(addr *uintptr, v uintptr) uintptr {
+ for {
+ old := *addr
+ if Casuintptr(addr, old, old&v) {
+ return old
+ }
+ }
+}
+
+//go:nosplit
func armcas(ptr *uint32, old, new uint32) bool
//go:noescape
diff --git a/src/runtime/internal/atomic/atomic_arm64.go b/src/runtime/internal/atomic/atomic_arm64.go
index 459fb9978d..c4c56ae895 100644
--- a/src/runtime/internal/atomic/atomic_arm64.go
+++ b/src/runtime/internal/atomic/atomic_arm64.go
@@ -67,6 +67,24 @@ func And(ptr *uint32, val uint32)
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
diff --git a/src/runtime/internal/atomic/atomic_arm64.s b/src/runtime/internal/atomic/atomic_arm64.s
index 5f77d92deb..3a249d3ed2 100644
--- a/src/runtime/internal/atomic/atomic_arm64.s
+++ b/src/runtime/internal/atomic/atomic_arm64.s
@@ -331,3 +331,81 @@ load_store_loop:
STLXRW R2, (R0), R3
CBNZ R3, load_store_loop
RET
+
+// func Or32(addr *uint32, v uint32) old uint32
+TEXT ·Or32(SB), NOSPLIT, $0-20
+ MOVD ptr+0(FP), R0
+ MOVW val+8(FP), R1
+ MOVBU internal∕cpu·ARM64+const_offsetARM64HasATOMICS(SB), R4
+ CBZ R4, load_store_loop
+ LDORALW R1, (R0), R2
+ MOVD R2, ret+16(FP)
+ RET
+load_store_loop:
+ LDAXRW (R0), R2
+ ORR R1, R2, R3
+ STLXRW R3, (R0), R4
+ CBNZ R4, load_store_loop
+ MOVD R2, ret+16(FP)
+ RET
+
+// func And32(addr *uint32, v uint32) old uint32
+TEXT ·And32(SB), NOSPLIT, $0-20
+ MOVD ptr+0(FP), R0
+ MOVW val+8(FP), R1
+ MOVBU internal∕cpu·ARM64+const_offsetARM64HasATOMICS(SB), R4
+ CBZ R4, load_store_loop
+ MVN R1, R2
+ LDCLRALW R2, (R0), R3
+ MOVD R3, ret+16(FP)
+ RET
+load_store_loop:
+ LDAXRW (R0), R2
+ AND R1, R2, R3
+ STLXRW R3, (R0), R4
+ CBNZ R4, load_store_loop
+ MOVD R2, ret+16(FP)
+ RET
+
+// func Or64(addr *uint64, v uint64) old uint64
+TEXT ·Or64(SB), NOSPLIT, $0-24
+ MOVD ptr+0(FP), R0
+ MOVD val+8(FP), R1
+ MOVBU internal∕cpu·ARM64+const_offsetARM64HasATOMICS(SB), R4
+ CBZ R4, load_store_loop
+ LDORALD R1, (R0), R2
+ MOVD R2, ret+16(FP)
+ RET
+load_store_loop:
+ LDAXR (R0), R2
+ ORR R1, R2, R3
+ STLXR R3, (R0), R4
+ CBNZ R4, load_store_loop
+ MOVD R2, ret+16(FP)
+ RET
+
+// func And64(addr *uint64, v uint64) old uint64
+TEXT ·And64(SB), NOSPLIT, $0-24
+ MOVD ptr+0(FP), R0
+ MOVD val+8(FP), R1
+ MOVBU internal∕cpu·ARM64+const_offsetARM64HasATOMICS(SB), R4
+ CBZ R4, load_store_loop
+ MVN R1, R2
+ LDCLRALD R2, (R0), R3
+ MOVD R3, ret+16(FP)
+ RET
+load_store_loop:
+ LDAXR (R0), R2
+ AND R1, R2, R3
+ STLXR R3, (R0), R4
+ CBNZ R4, load_store_loop
+ MOVD R2, ret+16(FP)
+ RET
+
+// func Anduintptr(addr *uintptr, v uintptr) old uintptr
+TEXT ·Anduintptr(SB), NOSPLIT, $0-24
+ B ·And64(SB)
+
+// func Oruintptr(addr *uintptr, v uintptr) old uintptr
+TEXT ·Oruintptr(SB), NOSPLIT, $0-24
+ B ·Or64(SB)