aboutsummaryrefslogtreecommitdiff
path: root/src/runtime/internal
diff options
context:
space:
mode:
authorCherry Zhang <cherryyz@google.com>2016-09-12 15:24:11 -0400
committerCherry Zhang <cherryyz@google.com>2016-09-13 02:09:15 +0000
commit38d35e714a55f2e4bb67caadac7e61f8c1967d88 (patch)
treec9e644b4d110c56d662a557c8159139841894129 /src/runtime/internal
parent09686a58734382ace059f1dbd882dadbb39b2268 (diff)
downloadgo-38d35e714a55f2e4bb67caadac7e61f8c1967d88.tar.xz
cmd/compile, runtime/internal/atomic: intrinsify And8, Or8 on ARM64
Also add assembly implementation, in case intrinsics is disabled. Change-Id: Iff0a8a8ce326651bd29f6c403f5ec08dd3629993 Reviewed-on: https://go-review.googlesource.com/28979 Run-TryBot: Cherry Zhang <cherryyz@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Keith Randall <khr@golang.org>
Diffstat (limited to 'src/runtime/internal')
-rw-r--r--src/runtime/internal/atomic/atomic_arm64.go34
-rw-r--r--src/runtime/internal/atomic/atomic_arm64.s19
2 files changed, 23 insertions, 30 deletions
diff --git a/src/runtime/internal/atomic/atomic_arm64.go b/src/runtime/internal/atomic/atomic_arm64.go
index dc82c3396d..3554b7f236 100644
--- a/src/runtime/internal/atomic/atomic_arm64.go
+++ b/src/runtime/internal/atomic/atomic_arm64.go
@@ -35,37 +35,11 @@ func Load64(ptr *uint64) uint64
//go:noescape
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:noescape
+func Or8(ptr *uint8, val uint8)
-//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 And8(ptr *uint8, val uint8)
//go:noescape
func Cas64(ptr *uint64, old, new uint64) bool
diff --git a/src/runtime/internal/atomic/atomic_arm64.s b/src/runtime/internal/atomic/atomic_arm64.s
index eb32f378aa..6c2031c205 100644
--- a/src/runtime/internal/atomic/atomic_arm64.s
+++ b/src/runtime/internal/atomic/atomic_arm64.s
@@ -111,3 +111,22 @@ again:
TEXT runtime∕internal∕atomic·Xchguintptr(SB), NOSPLIT, $0-24
B runtime∕internal∕atomic·Xchg64(SB)
+
+TEXT ·And8(SB), NOSPLIT, $0-9
+ MOVD ptr+0(FP), R0
+ MOVB val+8(FP), R1
+ LDAXRB (R0), R2
+ AND R1, R2
+ STLXRB R2, (R0), R3
+ CBNZ R3, -3(PC)
+ RET
+
+TEXT ·Or8(SB), NOSPLIT, $0-9
+ MOVD ptr+0(FP), R0
+ MOVB val+8(FP), R1
+ LDAXRB (R0), R2
+ ORR R1, R2
+ STLXRB R2, (R0), R3
+ CBNZ R3, -3(PC)
+ RET
+