mirror of
https://github.com/golang/go
synced 2024-11-20 09:24:50 -07:00
runtime/internal/atomic: add GOARCH=mips{,le} support
Change-Id: I99a48f719fd1a8178fc59787084a074e91c89ac6 Reviewed-on: https://go-review.googlesource.com/31489 Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Cherry Zhang <cherryyz@google.com>
This commit is contained in:
parent
2c39e50995
commit
b241a06479
149
src/runtime/internal/atomic/asm_mipsx.s
Normal file
149
src/runtime/internal/atomic/asm_mipsx.s
Normal file
@ -0,0 +1,149 @@
|
|||||||
|
// Copyright 2016 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build mips mipsle
|
||||||
|
|
||||||
|
#include "textflag.h"
|
||||||
|
|
||||||
|
TEXT ·Cas(SB),NOSPLIT,$0-13
|
||||||
|
MOVW ptr+0(FP), R1
|
||||||
|
MOVW old+4(FP), R2
|
||||||
|
MOVW new+8(FP), R5
|
||||||
|
SYNC
|
||||||
|
try_cas:
|
||||||
|
MOVW R5, R3
|
||||||
|
LL (R1), R4 // R4 = *R1
|
||||||
|
BNE R2, R4, cas_fail
|
||||||
|
SC R3, (R1) // *R1 = R3
|
||||||
|
BEQ R3, try_cas
|
||||||
|
SYNC
|
||||||
|
MOVB R3, ret+12(FP)
|
||||||
|
RET
|
||||||
|
cas_fail:
|
||||||
|
MOVB R0, ret+12(FP)
|
||||||
|
RET
|
||||||
|
|
||||||
|
TEXT ·Store(SB),NOSPLIT,$0-8
|
||||||
|
MOVW ptr+0(FP), R1
|
||||||
|
MOVW val+4(FP), R2
|
||||||
|
SYNC
|
||||||
|
MOVW R2, 0(R1)
|
||||||
|
SYNC
|
||||||
|
RET
|
||||||
|
|
||||||
|
TEXT ·Load(SB),NOSPLIT,$0-8
|
||||||
|
MOVW ptr+0(FP), R1
|
||||||
|
SYNC
|
||||||
|
MOVW 0(R1), R1
|
||||||
|
SYNC
|
||||||
|
MOVW R1, ret+4(FP)
|
||||||
|
RET
|
||||||
|
|
||||||
|
TEXT ·Xadd(SB),NOSPLIT,$0-12
|
||||||
|
MOVW ptr+0(FP), R2
|
||||||
|
MOVW delta+4(FP), R3
|
||||||
|
SYNC
|
||||||
|
try_xadd:
|
||||||
|
LL (R2), R1 // R1 = *R2
|
||||||
|
ADDU R1, R3, R4
|
||||||
|
MOVW R4, R1
|
||||||
|
SC R4, (R2) // *R2 = R4
|
||||||
|
BEQ R4, try_xadd
|
||||||
|
SYNC
|
||||||
|
MOVW R1, ret+8(FP)
|
||||||
|
RET
|
||||||
|
|
||||||
|
TEXT ·Xchg(SB),NOSPLIT,$0-12
|
||||||
|
MOVW ptr+0(FP), R2
|
||||||
|
MOVW new+4(FP), R5
|
||||||
|
SYNC
|
||||||
|
try_xchg:
|
||||||
|
MOVW R5, R3
|
||||||
|
LL (R2), R1 // R1 = *R2
|
||||||
|
SC R3, (R2) // *R2 = R3
|
||||||
|
BEQ R3, try_xchg
|
||||||
|
SYNC
|
||||||
|
MOVW R1, ret+8(FP)
|
||||||
|
RET
|
||||||
|
|
||||||
|
TEXT ·Casuintptr(SB),NOSPLIT,$0-13
|
||||||
|
JMP ·Cas(SB)
|
||||||
|
|
||||||
|
TEXT ·Loaduintptr(SB),NOSPLIT,$0-8
|
||||||
|
JMP ·Load(SB)
|
||||||
|
|
||||||
|
TEXT ·Loaduint(SB),NOSPLIT,$0-8
|
||||||
|
JMP ·Load(SB)
|
||||||
|
|
||||||
|
TEXT ·Loadp(SB),NOSPLIT,$-0-8
|
||||||
|
JMP ·Load(SB)
|
||||||
|
|
||||||
|
TEXT ·Storeuintptr(SB),NOSPLIT,$0-8
|
||||||
|
JMP ·Store(SB)
|
||||||
|
|
||||||
|
TEXT ·Xadduintptr(SB),NOSPLIT,$0-12
|
||||||
|
JMP ·Xadd(SB)
|
||||||
|
|
||||||
|
TEXT ·Loadint64(SB),NOSPLIT,$0-12
|
||||||
|
JMP ·Load64(SB)
|
||||||
|
|
||||||
|
TEXT ·Xaddint64(SB),NOSPLIT,$0-20
|
||||||
|
JMP ·Xadd64(SB)
|
||||||
|
|
||||||
|
TEXT ·Casp1(SB),NOSPLIT,$0-13
|
||||||
|
JMP ·Cas(SB)
|
||||||
|
|
||||||
|
TEXT ·Xchguintptr(SB),NOSPLIT,$0-12
|
||||||
|
JMP ·Xchg(SB)
|
||||||
|
|
||||||
|
TEXT ·StorepNoWB(SB),NOSPLIT,$0-8
|
||||||
|
JMP ·Store(SB)
|
||||||
|
|
||||||
|
// void Or8(byte volatile*, byte);
|
||||||
|
TEXT ·Or8(SB),NOSPLIT,$0-5
|
||||||
|
MOVW ptr+0(FP), R1
|
||||||
|
MOVBU val+4(FP), R2
|
||||||
|
MOVW $~3, R3 // Align ptr down to 4 bytes so we can use 32-bit load/store.
|
||||||
|
AND R1, R3
|
||||||
|
#ifdef GOARCH_mips
|
||||||
|
// Big endian. ptr = ptr ^ 3
|
||||||
|
XOR $3, R1
|
||||||
|
#endif
|
||||||
|
AND $3, R1, R4 // R4 = ((ptr & 3) * 8)
|
||||||
|
SLL $3, R4
|
||||||
|
SLL R4, R2, R2 // Shift val for aligned ptr. R2 = val << R4
|
||||||
|
SYNC
|
||||||
|
try_or8:
|
||||||
|
LL (R3), R4 // R4 = *R3
|
||||||
|
OR R2, R4
|
||||||
|
SC R4, (R3) // *R3 = R4
|
||||||
|
BEQ R4, try_or8
|
||||||
|
SYNC
|
||||||
|
RET
|
||||||
|
|
||||||
|
// void And8(byte volatile*, byte);
|
||||||
|
TEXT ·And8(SB),NOSPLIT,$0-5
|
||||||
|
MOVW ptr+0(FP), R1
|
||||||
|
MOVBU val+4(FP), R2
|
||||||
|
MOVW $~3, R3
|
||||||
|
AND R1, R3
|
||||||
|
#ifdef GOARCH_mips
|
||||||
|
// Big endian. ptr = ptr ^ 3
|
||||||
|
XOR $3, R1
|
||||||
|
#endif
|
||||||
|
AND $3, R1, R4 // R4 = ((ptr & 3) * 8)
|
||||||
|
SLL $3, R4
|
||||||
|
MOVW $0xFF, R5
|
||||||
|
SLL R4, R2
|
||||||
|
SLL R4, R5
|
||||||
|
NOR R0, R5
|
||||||
|
OR R5, R2 // Shift val for aligned ptr. R2 = val << R4 | ^(0xFF << R4)
|
||||||
|
SYNC
|
||||||
|
try_and8:
|
||||||
|
LL (R3), R4 // R4 = *R3
|
||||||
|
AND R2, R4
|
||||||
|
SC R4, (R3) // *R3 = R4
|
||||||
|
BEQ R4, try_and8
|
||||||
|
SYNC
|
||||||
|
RET
|
128
src/runtime/internal/atomic/atomic_mipsx.go
Normal file
128
src/runtime/internal/atomic/atomic_mipsx.go
Normal file
@ -0,0 +1,128 @@
|
|||||||
|
// Copyright 2016 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build mips mipsle
|
||||||
|
|
||||||
|
package atomic
|
||||||
|
|
||||||
|
import (
|
||||||
|
"runtime/internal/sys"
|
||||||
|
"unsafe"
|
||||||
|
)
|
||||||
|
|
||||||
|
// TODO implement lock striping
|
||||||
|
var lock struct {
|
||||||
|
state uint32
|
||||||
|
pad [sys.CacheLineSize - 4]byte
|
||||||
|
}
|
||||||
|
|
||||||
|
//go:noescape
|
||||||
|
func spinLock(state *uint32)
|
||||||
|
|
||||||
|
//go:noescape
|
||||||
|
func spinUnlock(state *uint32)
|
||||||
|
|
||||||
|
//go:nosplit
|
||||||
|
func lockAndCheck(addr *uint64) {
|
||||||
|
// force dereference before taking lock
|
||||||
|
_ = *addr
|
||||||
|
|
||||||
|
spinLock(&lock.state)
|
||||||
|
}
|
||||||
|
|
||||||
|
//go:nosplit
|
||||||
|
func unlock() {
|
||||||
|
spinUnlock(&lock.state)
|
||||||
|
}
|
||||||
|
|
||||||
|
//go:nosplit
|
||||||
|
func unlockNoFence() {
|
||||||
|
lock.state = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
//go:nosplit
|
||||||
|
func Xadd64(addr *uint64, delta int64) (new uint64) {
|
||||||
|
lockAndCheck(addr)
|
||||||
|
|
||||||
|
new = *addr + uint64(delta)
|
||||||
|
*addr = new
|
||||||
|
|
||||||
|
unlock()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
//go:nosplit
|
||||||
|
func Xchg64(addr *uint64, new uint64) (old uint64) {
|
||||||
|
lockAndCheck(addr)
|
||||||
|
|
||||||
|
old = *addr
|
||||||
|
*addr = new
|
||||||
|
|
||||||
|
unlock()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
//go:nosplit
|
||||||
|
func Cas64(addr *uint64, old, new uint64) (swapped bool) {
|
||||||
|
lockAndCheck(addr)
|
||||||
|
|
||||||
|
if (*addr) == old {
|
||||||
|
*addr = new
|
||||||
|
unlock()
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
unlockNoFence()
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
//go:nosplit
|
||||||
|
func Load64(addr *uint64) (val uint64) {
|
||||||
|
lockAndCheck(addr)
|
||||||
|
|
||||||
|
val = *addr
|
||||||
|
|
||||||
|
unlock()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
//go:nosplit
|
||||||
|
func Store64(addr *uint64, val uint64) {
|
||||||
|
lockAndCheck(addr)
|
||||||
|
|
||||||
|
*addr = val
|
||||||
|
|
||||||
|
unlock()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
//go:noescape
|
||||||
|
func Xadd(ptr *uint32, delta int32) uint32
|
||||||
|
|
||||||
|
//go:noescape
|
||||||
|
func Xadduintptr(ptr *uintptr, delta uintptr) uintptr
|
||||||
|
|
||||||
|
//go:noescape
|
||||||
|
func Xchg(ptr *uint32, new uint32) uint32
|
||||||
|
|
||||||
|
//go:noescape
|
||||||
|
func Xchguintptr(ptr *uintptr, new uintptr) uintptr
|
||||||
|
|
||||||
|
//go:noescape
|
||||||
|
func Load(ptr *uint32) uint32
|
||||||
|
|
||||||
|
//go:noescape
|
||||||
|
func Loadp(ptr unsafe.Pointer) unsafe.Pointer
|
||||||
|
|
||||||
|
//go:noescape
|
||||||
|
func And8(ptr *uint8, val uint8)
|
||||||
|
|
||||||
|
//go:noescape
|
||||||
|
func Or8(ptr *uint8, val uint8)
|
||||||
|
|
||||||
|
//go:noescape
|
||||||
|
func Store(ptr *uint32, val uint32)
|
||||||
|
|
||||||
|
// NO go:noescape annotation; see atomic_pointer.go.
|
||||||
|
func StorepNoWB(ptr unsafe.Pointer, val unsafe.Pointer)
|
28
src/runtime/internal/atomic/atomic_mipsx.s
Normal file
28
src/runtime/internal/atomic/atomic_mipsx.s
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
// Copyright 2016 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build mips mipsle
|
||||||
|
|
||||||
|
#include "textflag.h"
|
||||||
|
|
||||||
|
TEXT ·spinLock(SB),NOSPLIT,$0-4
|
||||||
|
MOVW state+0(FP), R1
|
||||||
|
MOVW $1, R2
|
||||||
|
SYNC
|
||||||
|
try_lock:
|
||||||
|
MOVW R2, R3
|
||||||
|
check_again:
|
||||||
|
LL (R1), R4
|
||||||
|
BNE R4, check_again
|
||||||
|
SC R3, (R1)
|
||||||
|
BEQ R3, try_lock
|
||||||
|
SYNC
|
||||||
|
RET
|
||||||
|
|
||||||
|
TEXT ·spinUnlock(SB),NOSPLIT,$0-4
|
||||||
|
MOVW state+0(FP), R1
|
||||||
|
SYNC
|
||||||
|
MOVW R0, (R1)
|
||||||
|
SYNC
|
||||||
|
RET
|
Loading…
Reference in New Issue
Block a user