Skip to content

Commit 818c5f6

Browse files
cherrymuicagedmantis
authored andcommitted
[release-branch.go1.15] cmd/compile: mark R16, R17 clobbered for non-standard calls on ARM64
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 #46927. Updates #32773. Change-Id: Ia52a891d9bbb8515c927617dd53aee5af5bd9aa4 Reviewed-on: https://go-review.googlesource.com/c/go/+/184437 Run-TryBot: Cherry Zhang <[email protected]> TryBot-Result: Go Bot <[email protected]> Reviewed-by: Meng Zhuo <[email protected]> Reviewed-by: Keith Randall <[email protected]> Trust: Meng Zhuo <[email protected]> (cherry picked from commit 11b4aee) Reviewed-on: https://go-review.googlesource.com/c/go/+/331030 Trust: Cherry Mui <[email protected]> Run-TryBot: Cherry Mui <[email protected]>
1 parent b81d75f commit 818c5f6

File tree

3 files changed

+31
-31
lines changed

3 files changed

+31
-31
lines changed

src/cmd/compile/internal/ssa/gen/ARM64Ops.go

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -498,13 +498,14 @@ func init() {
498498
// auxint = offset into duffzero code to start executing
499499
// returns mem
500500
// R20 changed as side effect
501+
// R16 and R17 may be clobbered by linker trampoline.
501502
{
502503
name: "DUFFZERO",
503504
aux: "Int64",
504505
argLength: 2,
505506
reg: regInfo{
506507
inputs: []regMask{buildReg("R20")},
507-
clobbers: buildReg("R20 R30"),
508+
clobbers: buildReg("R16 R17 R20 R30"),
508509
},
509510
faultOnNilArg0: true,
510511
},
@@ -537,13 +538,14 @@ func init() {
537538
// auxint = offset into duffcopy code to start executing
538539
// returns mem
539540
// R20, R21 changed as side effect
541+
// R16 and R17 may be clobbered by linker trampoline.
540542
{
541543
name: "DUFFCOPY",
542544
aux: "Int64",
543545
argLength: 3,
544546
reg: regInfo{
545547
inputs: []regMask{buildReg("R21"), buildReg("R20")},
546-
clobbers: buildReg("R20 R21 R26 R30"),
548+
clobbers: buildReg("R16 R17 R20 R21 R26 R30"),
547549
},
548550
faultOnNilArg0: true,
549551
faultOnNilArg1: true,
@@ -664,7 +666,8 @@ func init() {
664666
// LoweredWB invokes runtime.gcWriteBarrier. arg0=destptr, arg1=srcptr, arg2=mem, aux=runtime.gcWriteBarrier
665667
// It saves all GP registers if necessary,
666668
// but clobbers R30 (LR) because it's a call.
667-
{name: "LoweredWB", argLength: 3, reg: regInfo{inputs: []regMask{buildReg("R2"), buildReg("R3")}, clobbers: (callerSave &^ gpg) | buildReg("R30")}, clobberFlags: true, aux: "Sym", symEffect: "None"},
669+
// R16 and R17 may be clobbered by linker trampoline.
670+
{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"},
668671

669672
// There are three of these functions so that they can have three different register inputs.
670673
// When we check 0 <= c <= cap (A), then 0 <= b <= c (B), then 0 <= a <= b (C), we want the

src/cmd/compile/internal/ssa/opGen.go

Lines changed: 3 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/runtime/asm_arm64.s

Lines changed: 22 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1161,10 +1161,10 @@ TEXT ·checkASM(SB),NOSPLIT,$0-1
11611161
// It does not clobber any general-purpose registers,
11621162
// but may clobber others (e.g., floating point registers)
11631163
// The act of CALLing gcWriteBarrier will clobber R30 (LR).
1164-
TEXT runtime·gcWriteBarrier(SB),NOSPLIT,$216
1164+
TEXT runtime·gcWriteBarrier(SB),NOSPLIT,$200
11651165
// Save the registers clobbered by the fast path.
1166-
MOVD R0, 200(RSP)
1167-
MOVD R1, 208(RSP)
1166+
MOVD R0, 184(RSP)
1167+
MOVD R1, 192(RSP)
11681168
MOVD g_m(g), R0
11691169
MOVD m_p(R0), R0
11701170
MOVD (p_wbBuf+wbBuf_next)(R0), R1
@@ -1180,8 +1180,8 @@ TEXT runtime·gcWriteBarrier(SB),NOSPLIT,$216
11801180
// Is the buffer full? (flags set in CMP above)
11811181
BEQ flush
11821182
ret:
1183-
MOVD 200(RSP), R0
1184-
MOVD 208(RSP), R1
1183+
MOVD 184(RSP), R0
1184+
MOVD 192(RSP), R1
11851185
// Do the write.
11861186
MOVD R3, (R2)
11871187
RET
@@ -1205,17 +1205,16 @@ flush:
12051205
MOVD R13, 96(RSP)
12061206
MOVD R14, 104(RSP)
12071207
MOVD R15, 112(RSP)
1208-
MOVD R16, 120(RSP)
1209-
MOVD R17, 128(RSP)
1208+
// R16, R17 may be clobbered by linker trampoline
12101209
// R18 is unused.
1211-
MOVD R19, 136(RSP)
1212-
MOVD R20, 144(RSP)
1213-
MOVD R21, 152(RSP)
1214-
MOVD R22, 160(RSP)
1215-
MOVD R23, 168(RSP)
1216-
MOVD R24, 176(RSP)
1217-
MOVD R25, 184(RSP)
1218-
MOVD R26, 192(RSP)
1210+
MOVD R19, 120(RSP)
1211+
MOVD R20, 128(RSP)
1212+
MOVD R21, 136(RSP)
1213+
MOVD R22, 144(RSP)
1214+
MOVD R23, 152(RSP)
1215+
MOVD R24, 160(RSP)
1216+
MOVD R25, 168(RSP)
1217+
MOVD R26, 176(RSP)
12191218
// R27 is temp register.
12201219
// R28 is g.
12211220
// R29 is frame pointer (unused).
@@ -1239,16 +1238,14 @@ flush:
12391238
MOVD 96(RSP), R13
12401239
MOVD 104(RSP), R14
12411240
MOVD 112(RSP), R15
1242-
MOVD 120(RSP), R16
1243-
MOVD 128(RSP), R17
1244-
MOVD 136(RSP), R19
1245-
MOVD 144(RSP), R20
1246-
MOVD 152(RSP), R21
1247-
MOVD 160(RSP), R22
1248-
MOVD 168(RSP), R23
1249-
MOVD 176(RSP), R24
1250-
MOVD 184(RSP), R25
1251-
MOVD 192(RSP), R26
1241+
MOVD 120(RSP), R19
1242+
MOVD 128(RSP), R20
1243+
MOVD 136(RSP), R21
1244+
MOVD 144(RSP), R22
1245+
MOVD 152(RSP), R23
1246+
MOVD 160(RSP), R24
1247+
MOVD 168(RSP), R25
1248+
MOVD 176(RSP), R26
12521249
JMP ret
12531250

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

0 commit comments

Comments
 (0)