104 lines
2.0 KiB
ArmAsm
104 lines
2.0 KiB
ArmAsm
// Instruction prefixes: LOCK, REP and REPN. go tool asm encodes each
|
|||
|
|
// statement as a standalone one-byte instruction with a PC of its own (F0,
|
||
|
|
// F3 and F2 respectively); the statement that follows is encoded unaware of
|
||
|
|
// it, and nothing validates the pairing. The shapes are the runtime's
|
||
|
|
// atomic read-modify-write family and the string moves, every result folded
|
||
|
|
// back.
|
||
|
|
|
||
|
|
#include "textflag.h"
|
||
|
|
|
||
|
|
// func cas64(ptr *uint64, old, new uint64) bool
|
||
|
|
TEXT ·cas64(SB), NOSPLIT, $0-25
|
||
|
|
MOVQ ptr+0(FP), BX
|
||
|
|
MOVQ old+8(FP), AX
|
||
|
|
MOVQ new+16(FP), CX
|
||
|
|
LOCK
|
||
|
|
CMPXCHGQ CX, 0(BX)
|
||
|
|
SETEQ ret+24(FP)
|
||
|
|
RET
|
||
|
|
|
||
|
|
// func casloop(addr *uint64, v uint64) uint64
|
||
|
|
// The runtime's Or64 shape: a LOCK inside a branch loop, the backward jump
|
||
|
|
// measuring over the prefix statement's own byte.
|
||
|
|
TEXT ·casloop(SB), NOSPLIT, $0-24
|
||
|
|
MOVQ addr+0(FP), BX
|
||
|
|
MOVQ v+8(FP), CX
|
||
|
|
|
||
|
|
loop:
|
||
|
|
MOVQ CX, DX
|
||
|
|
MOVQ (BX), AX
|
||
|
|
ORQ AX, DX
|
||
|
|
LOCK
|
||
|
|
CMPXCHGQ DX, (BX)
|
||
|
|
JNZ loop
|
||
|
|
MOVQ AX, ret+16(FP)
|
||
|
|
RET
|
||
|
|
|
||
|
|
// func xadd64(p *uint64, v uint64) uint64
|
||
|
|
TEXT ·xadd64(SB), NOSPLIT, $0-24
|
||
|
|
MOVQ p+0(FP), AX
|
||
|
|
MOVQ v+8(FP), BX
|
||
|
|
LOCK
|
||
|
|
XADDQ BX, (AX)
|
||
|
|
MOVQ AX, ret+16(FP)
|
||
|
|
RET
|
||
|
|
|
||
|
|
// func xaddw(p *uint16, v uint16) uint16
|
||
|
|
TEXT ·xaddw(SB), NOSPLIT, $0-12
|
||
|
|
MOVQ p+0(FP), AX
|
||
|
|
MOVW v+8(FP), BX
|
||
|
|
LOCK
|
||
|
|
XADDW BX, (AX)
|
||
|
|
MOVW AX, ret+8(FP)
|
||
|
|
RET
|
||
|
|
|
||
|
|
// func lockarith(p *uint64)
|
||
|
|
TEXT ·lockarith(SB), NOSPLIT, $0-8
|
||
|
|
MOVQ p+0(FP), AX
|
||
|
|
LOCK
|
||
|
|
ORQ CX, (AX)
|
||
|
|
LOCK
|
||
|
|
ANDL CX, (AX)
|
||
|
|
LOCK
|
||
|
|
INCQ (AX)
|
||
|
|
LOCK
|
||
|
|
DECQ (AX)
|
||
|
|
LOCK
|
||
|
|
ORB BX, (AX)
|
||
|
|
RET
|
||
|
|
|
||
|
|
// func repstring(dst, src *byte, n int)
|
||
|
|
// The memmove shapes: forward copy by quadwords, backward tails.
|
||
|
|
TEXT ·repstring(SB), NOSPLIT, $0-24
|
||
|
|
MOVQ dst+0(FP), DI
|
||
|
|
MOVQ src+8(FP), SI
|
||
|
|
REP
|
||
|
|
MOVSQ
|
||
|
|
REP
|
||
|
|
MOVSB
|
||
|
|
REPN
|
||
|
|
MOVSB
|
||
|
|
REP
|
||
|
|
STOSQ
|
||
|
|
REP
|
||
|
|
STOSB
|
||
|
|
RET
|
||
|
|
|
||
|
|
// func pfxlabel()
|
||
|
|
// Labels pinned on prefix statements' own bytes: pfx: sits on the LOCK,
|
||
|
|
// mid: on the REPN.
|
||
|
|
TEXT ·pfxlabel(SB), NOSPLIT, $0-0
|
||
|
|
pfx:
|
||
|
|
LOCK
|
||
|
|
XCHGL BX, (AX)
|
||
|
|
JMP done
|
||
|
|
|
||
|
|
mid:
|
||
|
|
REPN
|
||
|
|
MOVSB
|
||
|
|
|
||
|
|
done:
|
||
|
|
REP
|
||
|
|
STOSB
|
||
|
|
RET
|