From: Mauri de Souza Meneguzzo Date: Wed, 1 May 2024 14:33:11 +0000 (+0000) Subject: runtime/internal/atomic: add mips operators for And/Or X-Git-Tag: go1.23rc1~386 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=9623a3586fc6c2d11820f412d437de1a613f755c;p=gostls13.git 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: 95dca2a9f144c5d96dfa53eaf116e88be5f55040 GitHub-Pull-Request: golang/go#63297 Reviewed-on: https://go-review.googlesource.com/c/go/+/531835 Reviewed-by: Cherry Mui Reviewed-by: Keith Randall Reviewed-by: Keith Randall LUCI-TryBot-Result: Go LUCI --- diff --git a/src/internal/runtime/atomic/atomic_andor_generic.go b/src/internal/runtime/atomic/atomic_andor_generic.go index f8b148dda5..6c12037d94 100644 --- a/src/internal/runtime/atomic/atomic_andor_generic.go +++ b/src/internal/runtime/atomic/atomic_andor_generic.go @@ -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 diff --git a/src/internal/runtime/atomic/atomic_mips64x.go b/src/internal/runtime/atomic/atomic_mips64x.go index 1e12b83801..f434c939e3 100644 --- a/src/internal/runtime/atomic/atomic_mips64x.go +++ b/src/internal/runtime/atomic/atomic_mips64x.go @@ -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 diff --git a/src/internal/runtime/atomic/atomic_mips64x.s b/src/internal/runtime/atomic/atomic_mips64x.s index b4411d87da..7b0e080238 100644 --- a/src/internal/runtime/atomic/atomic_mips64x.s +++ b/src/internal/runtime/atomic/atomic_mips64x.s @@ -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 diff --git a/src/internal/runtime/atomic/atomic_mipsx.go b/src/internal/runtime/atomic/atomic_mipsx.go index e3dcde1bde..26c8047599 100644 --- a/src/internal/runtime/atomic/atomic_mipsx.go +++ b/src/internal/runtime/atomic/atomic_mipsx.go @@ -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) diff --git a/src/internal/runtime/atomic/atomic_mipsx.s b/src/internal/runtime/atomic/atomic_mipsx.s index 8f5fc53cb7..4ccc0a363b 100644 --- a/src/internal/runtime/atomic/atomic_mipsx.s +++ b/src/internal/runtime/atomic/atomic_mipsx.s @@ -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