Skip to content

Commit

Permalink
cmd/compile: mark R16, R17 clobbered for non-standard calls on ARM64
Browse files Browse the repository at this point in the history
On ARM64, (external) linker generated trampoline may clobber R16
and R17. In CL 183842 we change Duff's devices not to use those
registers. However, this is not enough. The register allocator
also needs to know that these registers may be clobbered in any
calls that don't follow the standard Go calling convention. This
include Duff's devices and the write barrier.

Fixes #32773, second attempt.

Change-Id: Ia52a891d9bbb8515c927617dd53aee5af5bd9aa4
Reviewed-on: https://go-review.googlesource.com/c/go/+/184437
Run-TryBot: Cherry Zhang <cherryyz@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Meng Zhuo <mzh@golangcn.org>
Reviewed-by: Keith Randall <khr@golang.org>
Trust: Meng Zhuo <mzh@golangcn.org>
  • Loading branch information
cherrymui authored and randall77 committed Mar 25, 2021
1 parent 5834ce1 commit 11b4aee
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 31 deletions.
9 changes: 6 additions & 3 deletions src/cmd/compile/internal/ssa/gen/ARM64Ops.go
Original file line number Diff line number Diff line change
Expand Up @@ -512,13 +512,14 @@ func init() {
// auxint = offset into duffzero code to start executing
// returns mem
// R20 changed as side effect
// R16 and R17 may be clobbered by linker trampoline.
{
name: "DUFFZERO",
aux: "Int64",
argLength: 2,
reg: regInfo{
inputs: []regMask{buildReg("R20")},
clobbers: buildReg("R20 R30"),
clobbers: buildReg("R16 R17 R20 R30"),
},
faultOnNilArg0: true,
unsafePoint: true, // FP maintenance around DUFFZERO can be clobbered by interrupts
Expand Down Expand Up @@ -552,13 +553,14 @@ func init() {
// auxint = offset into duffcopy code to start executing
// returns mem
// R20, R21 changed as side effect
// R16 and R17 may be clobbered by linker trampoline.
{
name: "DUFFCOPY",
aux: "Int64",
argLength: 3,
reg: regInfo{
inputs: []regMask{buildReg("R21"), buildReg("R20")},
clobbers: buildReg("R20 R21 R26 R30"),
clobbers: buildReg("R16 R17 R20 R21 R26 R30"),
},
faultOnNilArg0: true,
faultOnNilArg1: true,
Expand Down Expand Up @@ -717,7 +719,8 @@ func init() {
// LoweredWB invokes runtime.gcWriteBarrier. arg0=destptr, arg1=srcptr, arg2=mem, aux=runtime.gcWriteBarrier
// It saves all GP registers if necessary,
// but clobbers R30 (LR) because it's a call.
{name: "LoweredWB", argLength: 3, reg: regInfo{inputs: []regMask{buildReg("R2"), buildReg("R3")}, clobbers: (callerSave &^ gpg) | buildReg("R30")}, clobberFlags: true, aux: "Sym", symEffect: "None"},
// R16 and R17 may be clobbered by linker trampoline.
{name: "LoweredWB", argLength: 3, reg: regInfo{inputs: []regMask{buildReg("R2"), buildReg("R3")}, clobbers: (callerSave &^ gpg) | buildReg("R16 R17 R30")}, clobberFlags: true, aux: "Sym", symEffect: "None"},

// There are three of these functions so that they can have three different register inputs.
// When we check 0 <= c <= cap (A), then 0 <= b <= c (B), then 0 <= a <= b (C), we want the
Expand Down
6 changes: 3 additions & 3 deletions src/cmd/compile/internal/ssa/opGen.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

47 changes: 22 additions & 25 deletions src/runtime/asm_arm64.s
Original file line number Diff line number Diff line change
Expand Up @@ -1158,10 +1158,10 @@ TEXT ·checkASM(SB),NOSPLIT,$0-1
// It does not clobber any general-purpose registers,
// but may clobber others (e.g., floating point registers)
// The act of CALLing gcWriteBarrier will clobber R30 (LR).
TEXT runtime·gcWriteBarrier(SB),NOSPLIT,$216
TEXT runtime·gcWriteBarrier(SB),NOSPLIT,$200
// Save the registers clobbered by the fast path.
MOVD R0, 200(RSP)
MOVD R1, 208(RSP)
MOVD R0, 184(RSP)
MOVD R1, 192(RSP)
MOVD g_m(g), R0
MOVD m_p(R0), R0
MOVD (p_wbBuf+wbBuf_next)(R0), R1
Expand All @@ -1177,8 +1177,8 @@ TEXT runtime·gcWriteBarrier(SB),NOSPLIT,$216
// Is the buffer full? (flags set in CMP above)
BEQ flush
ret:
MOVD 200(RSP), R0
MOVD 208(RSP), R1
MOVD 184(RSP), R0
MOVD 192(RSP), R1
// Do the write.
MOVD R3, (R2)
RET
Expand All @@ -1202,17 +1202,16 @@ flush:
MOVD R13, 96(RSP)
MOVD R14, 104(RSP)
MOVD R15, 112(RSP)
MOVD R16, 120(RSP)
MOVD R17, 128(RSP)
// R16, R17 may be clobbered by linker trampoline
// R18 is unused.
MOVD R19, 136(RSP)
MOVD R20, 144(RSP)
MOVD R21, 152(RSP)
MOVD R22, 160(RSP)
MOVD R23, 168(RSP)
MOVD R24, 176(RSP)
MOVD R25, 184(RSP)
MOVD R26, 192(RSP)
MOVD R19, 120(RSP)
MOVD R20, 128(RSP)
MOVD R21, 136(RSP)
MOVD R22, 144(RSP)
MOVD R23, 152(RSP)
MOVD R24, 160(RSP)
MOVD R25, 168(RSP)
MOVD R26, 176(RSP)
// R27 is temp register.
// R28 is g.
// R29 is frame pointer (unused).
Expand All @@ -1236,16 +1235,14 @@ flush:
MOVD 96(RSP), R13
MOVD 104(RSP), R14
MOVD 112(RSP), R15
MOVD 120(RSP), R16
MOVD 128(RSP), R17
MOVD 136(RSP), R19
MOVD 144(RSP), R20
MOVD 152(RSP), R21
MOVD 160(RSP), R22
MOVD 168(RSP), R23
MOVD 176(RSP), R24
MOVD 184(RSP), R25
MOVD 192(RSP), R26
MOVD 120(RSP), R19
MOVD 128(RSP), R20
MOVD 136(RSP), R21
MOVD 144(RSP), R22
MOVD 152(RSP), R23
MOVD 160(RSP), R24
MOVD 168(RSP), R25
MOVD 176(RSP), R26
JMP ret

// Note: these functions use a special calling convention to save generated code space.
Expand Down

0 comments on commit 11b4aee

Please sign in to comment.