1
0
mirror of https://github.com/golang/go synced 2024-11-14 23:30:27 -07:00

runtime/internal/atomic: add mips operators for And/Or

These primitives will be used by the new And/Or sync/atomic apis.

Implemented for mips/mipsle and mips64/mips64le.

For #61395

Change-Id: Icc604a2b5cdfe72646d47d3c6a0bb49a0fd0d353
GitHub-Last-Rev: 95dca2a9f1
GitHub-Pull-Request: golang/go#63297
Reviewed-on: https://go-review.googlesource.com/c/go/+/531835
Reviewed-by: Cherry Mui <cherryyz@google.com>
Reviewed-by: Keith Randall <khr@google.com>
Reviewed-by: Keith Randall <khr@golang.org>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
This commit is contained in:
Mauri de Souza Meneguzzo 2024-05-01 14:33:11 +00:00 committed by Keith Randall
parent 7f9edb4225
commit 9623a3586f
5 changed files with 151 additions and 1 deletions

View File

@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
//go:build arm || mips || mipsle || mips64 || mips64le || wasm
//go:build arm || wasm
package atomic

View File

@ -61,6 +61,24 @@ 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

View File

@ -310,6 +310,70 @@ TEXT ·And(SB), NOSPLIT, $0-12
SYNC
RET
// func Or32(addr *uint32, v uint32) old uint32
TEXT ·Or32(SB), NOSPLIT, $0-20
MOVV ptr+0(FP), R1
MOVW val+8(FP), R2
SYNC
LL (R1), R3
OR R2, R3, R4
SC R4, (R1)
BEQ R4, -3(PC)
SYNC
MOVW R3, ret+16(FP)
RET
// func And32(addr *uint32, v uint32) old uint32
TEXT ·And32(SB), NOSPLIT, $0-20
MOVV ptr+0(FP), R1
MOVW val+8(FP), R2
SYNC
LL (R1), R3
AND R2, R3, R4
SC R4, (R1)
BEQ R4, -3(PC)
SYNC
MOVW R3, ret+16(FP)
RET
// func Or64(addr *uint64, v uint64) old uint64
TEXT ·Or64(SB), NOSPLIT, $0-24
MOVV ptr+0(FP), R1
MOVV val+8(FP), R2
SYNC
LLV (R1), R3
OR R2, R3, R4
SCV R4, (R1)
BEQ R4, -3(PC)
SYNC
MOVV R3, ret+16(FP)
RET
// func And64(addr *uint64, v uint64) old uint64
TEXT ·And64(SB), NOSPLIT, $0-24
MOVV ptr+0(FP), R1
MOVV val+8(FP), R2
SYNC
LLV (R1), R3
AND R2, R3, R4
SCV R4, (R1)
BEQ R4, -3(PC)
SYNC
MOVV R3, ret+16(FP)
RET
// func Anduintptr(addr *uintptr, v uintptr) old uintptr
TEXT ·Anduintptr(SB), NOSPLIT, $0-24
JMP ·And64(SB)
// func Oruintptr(addr *uintptr, v uintptr) old uintptr
TEXT ·Oruintptr(SB), NOSPLIT, $0-24
JMP ·Or64(SB)
// uint32 ·Load(uint32 volatile* ptr)
TEXT ·Load(SB),NOSPLIT|NOFRAME,$0-12
MOVV ptr+0(FP), R1

View File

@ -104,6 +104,26 @@ func Store64(addr *uint64, val uint64) {
return
}
//go:nosplit
func Or64(addr *uint64, val uint64) (old uint64) {
for {
old = *addr
if Cas64(addr, old, old|val) {
return old
}
}
}
//go:nosplit
func And64(addr *uint64, val uint64) (old uint64) {
for {
old = *addr
if Cas64(addr, old, old&val) {
return old
}
}
}
//go:noescape
func Xadd(ptr *uint32, delta int32) uint32
@ -143,6 +163,18 @@ 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 Anduintptr(ptr *uintptr, val uintptr) uintptr
//go:noescape
func Oruintptr(ptr *uintptr, val uintptr) uintptr
//go:noescape
func Store(ptr *uint32, val uint32)

View File

@ -240,6 +240,42 @@ TEXT ·And(SB), NOSPLIT, $0-8
SYNC
RET
// func Or32(addr *uint32, v uint32) old uint32
TEXT ·Or32(SB), NOSPLIT, $0-12
MOVW ptr+0(FP), R1
MOVW val+4(FP), R2
SYNC
LL (R1), R3
OR R2, R3, R4
SC R4, (R1)
BEQ R4, -4(PC)
SYNC
MOVW R3, ret+8(FP)
RET
// func And32(addr *uint32, v uint32) old uint32
TEXT ·And32(SB), NOSPLIT, $0-12
MOVW ptr+0(FP), R1
MOVW val+4(FP), R2
SYNC
LL (R1), R3
AND R2, R3, R4
SC R4, (R1)
BEQ R4, -4(PC)
SYNC
MOVW R3, ret+8(FP)
RET
// func Anduintptr(addr *uintptr, v uintptr) old uintptr
TEXT ·Anduintptr(SB), NOSPLIT, $0-12
JMP ·And32(SB)
// func Oruintptr(addr *uintptr, v uintptr) old uintptr
TEXT ·Oruintptr(SB), NOSPLIT, $0-12
JMP ·Or32(SB)
TEXT ·spinLock(SB),NOSPLIT,$0-4
MOVW state+0(FP), R1
MOVW $1, R2