// 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