diff options
| author | Cherry Zhang <cherryyz@google.com> | 2016-09-12 15:24:11 -0400 |
|---|---|---|
| committer | Cherry Zhang <cherryyz@google.com> | 2016-09-13 02:09:15 +0000 |
| commit | 38d35e714a55f2e4bb67caadac7e61f8c1967d88 (patch) | |
| tree | c9e644b4d110c56d662a557c8159139841894129 /src/runtime/internal/atomic | |
| parent | 09686a58734382ace059f1dbd882dadbb39b2268 (diff) | |
| download | go-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/atomic')
| -rw-r--r-- | src/runtime/internal/atomic/atomic_arm64.go | 34 | ||||
| -rw-r--r-- | src/runtime/internal/atomic/atomic_arm64.s | 19 |
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 + |
