[go] runtime: use stp/ldp to save and restore all registers on arm64

85 views
Skip to first unread message

Eric Fang (Gerrit)

unread,
Jan 19, 2022, 10:37:10 PM1/19/22
to goph...@pubsubhelper.golang.org, golang-co...@googlegroups.com

Eric Fang has uploaded this change for review.

View Change

runtime: use stp/ldp to save and restore all registers on arm64

Async preemption needs to save and restore almost all of the registers,
currently this is done by ldr and str on arm64. We can do it with ldp
and stp as they are more efficient.

Change-Id: Ida5a6f0a8d825a56af607ba2c2cd91fdc2e8f67f
---
M src/runtime/mkpreempt.go
M src/runtime/preempt_arm64.s
2 files changed, 103 insertions(+), 154 deletions(-)

diff --git a/src/runtime/mkpreempt.go b/src/runtime/mkpreempt.go
index 17c9b75..10079ac 100644
--- a/src/runtime/mkpreempt.go
+++ b/src/runtime/mkpreempt.go
@@ -122,7 +122,7 @@
fmt.Fprintf(out, "// Code generated by mkpreempt.go; DO NOT EDIT.\n\n")
if beLe[arch] {
base := arch[:len(arch)-1]
- fmt.Fprintf(out, "//go:build %s || %sle\n", base, base)
+ fmt.Fprintf(out, "//go:build %s || %sle\n\n", base, base)
}
fmt.Fprintf(out, "#include \"go_asm.h\"\n")
fmt.Fprintf(out, "#include \"textflag.h\"\n\n")
@@ -147,8 +147,9 @@
type regPos struct {
pos int

- op string
- reg string
+ saveOp string
+ restoreOp string
+ reg string

// If this register requires special save and restore, these
// give those operations with a %d placeholder for the stack
@@ -156,8 +157,8 @@
save, restore string
}

-func (l *layout) add(op, reg string, size int) {
- l.regs = append(l.regs, regPos{op: op, reg: reg, pos: l.stack})
+func (l *layout) add(sop, rop, reg string, size int) {
+ l.regs = append(l.regs, regPos{saveOp: sop, restoreOp: rop, reg: reg, pos: l.stack})
l.stack += size
}

@@ -171,7 +172,7 @@
if reg.save != "" {
p(reg.save, reg.pos)
} else {
- p("%s %s, %d(%s)", reg.op, reg.reg, reg.pos, l.sp)
+ p("%s %s, %d(%s)", reg.saveOp, reg.reg, reg.pos, l.sp)
}
}
}
@@ -182,7 +183,7 @@
if reg.restore != "" {
p(reg.restore, reg.pos)
} else {
- p("%s %d(%s), %s", reg.op, reg.pos, l.sp, reg.reg)
+ p("%s %d(%s), %s", reg.restoreOp, reg.pos, l.sp, reg.reg)
}
}
}
@@ -195,7 +196,7 @@
if reg == "SP" || strings.HasPrefix(reg, "X") {
continue
}
- l.add("MOVL", reg, 4)
+ l.add("MOVL", "MOVL", reg, 4)
}

softfloat := "GO386_softfloat"
@@ -203,7 +204,7 @@
// Save SSE state only if supported.
lSSE := layout{stack: l.stack, sp: "SP"}
for i := 0; i < 8; i++ {
- lSSE.add("MOVUPS", fmt.Sprintf("X%d", i), 16)
+ lSSE.add("MOVUPS", "MOVUPS", fmt.Sprintf("X%d", i), 16)
}

p("ADJSP $%d", lSSE.stack)
@@ -231,13 +232,13 @@
continue
}
if !strings.HasPrefix(reg, "X") {
- l.add("MOVQ", reg, 8)
+ l.add("MOVQ", "MOVQ", reg, 8)
}
}
lSSE := layout{stack: l.stack, sp: "SP"}
for _, reg := range regNamesAMD64 {
if strings.HasPrefix(reg, "X") {
- lSSE.add("MOVUPS", reg, 16)
+ lSSE.add("MOVUPS", "MOVUPS", reg, 16)
}
}

@@ -284,7 +285,7 @@
if i == 10 {
continue // R10 is g register, no need to save/restore
}
- l.add("MOVW", reg, 4)
+ l.add("MOVW", "MOVW", reg, 4)
}
// Add flag register.
l.addSpecial(
@@ -300,7 +301,7 @@
4)
for i := 0; i <= 15; i++ {
reg := fmt.Sprintf("F%d", i)
- lfp.add("MOVD", reg, 8)
+ lfp.add("MOVD", "MOVD", reg, 8)
}

p("MOVW.W R14, -%d(R13)", lfp.stack) // allocate frame, save LR
@@ -324,12 +325,13 @@
// R27 (REGTMP), R28 (g), R29 (FP), R30 (LR), R31 (SP) are special
// and not saved here.
var l = layout{sp: "RSP", stack: 8} // add slot to save PC of interrupted instruction
- for i := 0; i <= 26; i++ {
+ for i := 0; i < 26; i += 2 {
if i == 18 {
+ i--
continue // R18 is not used, skip
}
- reg := fmt.Sprintf("R%d", i)
- l.add("MOVD", reg, 8)
+ reg := fmt.Sprintf("(R%d, R%d)", i, i+1)
+ l.add("STP", "LDP", reg, 16)
}
// Add flag registers.
l.addSpecial(
@@ -342,9 +344,9 @@
8)
// TODO: FPCR? I don't think we'll change it, so no need to save.
// Add floating point registers F0-F31.
- for i := 0; i <= 31; i++ {
- reg := fmt.Sprintf("F%d", i)
- l.add("FMOVD", reg, 8)
+ for i := 0; i < 31; i += 2 {
+ reg := fmt.Sprintf("(F%d, F%d)", i, i+1)
+ l.add("FSTPD", "FLDPD", reg, 16)
}
if l.stack%16 != 0 {
l.stack += 8 // SP needs 16-byte alignment
@@ -353,10 +355,8 @@
// allocate frame, save PC of interrupted instruction (in LR)
p("MOVD R30, %d(RSP)", -l.stack)
p("SUB $%d, RSP", l.stack)
- p("#ifdef GOOS_linux")
p("MOVD R29, -8(RSP)") // save frame pointer (only used on Linux)
p("SUB $8, RSP, R29") // set up new frame pointer
- p("#endif")
// On iOS, save the LR again after decrementing SP. We run the
// signal handler on the G stack (as it doesn't support sigaltstack),
// so any writes below SP may be clobbered.
@@ -369,11 +369,9 @@
l.restore()

p("MOVD %d(RSP), R30", l.stack) // sigctxt.pushCall has pushed LR (at interrupt) on stack, restore it
- p("#ifdef GOOS_linux")
- p("MOVD -8(RSP), R29") // restore frame pointer
- p("#endif")
- p("MOVD (RSP), R27") // load PC to REGTMP
- p("ADD $%d, RSP", l.stack+16) // pop frame (including the space pushed by sigctxt.pushCall)
+ p("MOVD -8(RSP), R29") // restore frame pointer
+ p("MOVD (RSP), R27") // load PC to REGTMP
+ p("ADD $%d, RSP", l.stack+16) // pop frame (including the space pushed by sigctxt.pushCall)
p("JMP (R27)")
}

@@ -404,9 +402,9 @@
continue // R23 is REGTMP
}
reg := fmt.Sprintf("R%d", i)
- l.add(mov, reg, regsize)
+ l.add(mov, mov, reg, regsize)
}
- l.add(mov, r28, regsize)
+ l.add(mov, mov, r28, regsize)
l.addSpecial(
mov+" HI, R1\n"+mov+" R1, %d(R29)",
mov+" %d(R29), R1\n"+mov+" R1, HI",
@@ -425,7 +423,7 @@
// Add floating point registers F0-F31.
for i := 0; i <= 31; i++ {
reg := fmt.Sprintf("F%d", i)
- lfp.add(movf, reg, regsize)
+ lfp.add(movf, movf, reg, regsize)
}

// allocate frame, save PC of interrupted instruction (in LR)
@@ -463,7 +461,7 @@
continue
}
reg := fmt.Sprintf("R%d", i)
- l.add("MOVD", reg, 8)
+ l.add("MOVD", "MOVD", reg, 8)
}
l.addSpecial(
"MOVW CR, R31\nMOVW R31, %d(R1)",
@@ -476,7 +474,7 @@
// Add floating point registers F0-F31.
for i := 0; i <= 31; i++ {
reg := fmt.Sprintf("F%d", i)
- l.add("FMOVD", reg, 8)
+ l.add("FMOVD", "FMOVD", reg, 8)
}
// Add floating point control/status register FPSCR.
l.addSpecial(
@@ -513,13 +511,13 @@
continue
}
reg := fmt.Sprintf("X%d", i)
- l.add("MOV", reg, 8)
+ l.add("MOV", "MOV", reg, 8)
}

// Add floating point registers (F0-F31).
for i := 0; i <= 31; i++ {
reg := fmt.Sprintf("F%d", i)
- l.add("MOVD", reg, 8)
+ l.add("MOVD", "MOVD", reg, 8)
}

p("MOV X1, -%d(X2)", l.stack)
@@ -545,7 +543,7 @@
// Add floating point registers F0-F31.
for i := 0; i <= 15; i++ {
reg := fmt.Sprintf("F%d", i)
- l.add("FMOVD", reg, 8)
+ l.add("FMOVD", "FMOVD", reg, 8)
}

// allocate frame, save PC of interrupted instruction (in LR) and flags (condition code)
diff --git a/src/runtime/preempt_arm64.s b/src/runtime/preempt_arm64.s
index 36ee132..c27d475 100644
--- a/src/runtime/preempt_arm64.s
+++ b/src/runtime/preempt_arm64.s
@@ -6,142 +6,80 @@
TEXT ·asyncPreempt(SB),NOSPLIT|NOFRAME,$0-0
MOVD R30, -496(RSP)
SUB $496, RSP
- #ifdef GOOS_linux
MOVD R29, -8(RSP)
SUB $8, RSP, R29
- #endif
#ifdef GOOS_ios
MOVD R30, (RSP)
#endif
- MOVD R0, 8(RSP)
- MOVD R1, 16(RSP)
- MOVD R2, 24(RSP)
- MOVD R3, 32(RSP)
- MOVD R4, 40(RSP)
- MOVD R5, 48(RSP)
- MOVD R6, 56(RSP)
- MOVD R7, 64(RSP)
- MOVD R8, 72(RSP)
- MOVD R9, 80(RSP)
- MOVD R10, 88(RSP)
- MOVD R11, 96(RSP)
- MOVD R12, 104(RSP)
- MOVD R13, 112(RSP)
- MOVD R14, 120(RSP)
- MOVD R15, 128(RSP)
- MOVD R16, 136(RSP)
- MOVD R17, 144(RSP)
- MOVD R19, 152(RSP)
- MOVD R20, 160(RSP)
- MOVD R21, 168(RSP)
- MOVD R22, 176(RSP)
- MOVD R23, 184(RSP)
- MOVD R24, 192(RSP)
- MOVD R25, 200(RSP)
- MOVD R26, 208(RSP)
+ STP (R0, R1), 8(RSP)
+ STP (R2, R3), 24(RSP)
+ STP (R4, R5), 40(RSP)
+ STP (R6, R7), 56(RSP)
+ STP (R8, R9), 72(RSP)
+ STP (R10, R11), 88(RSP)
+ STP (R12, R13), 104(RSP)
+ STP (R14, R15), 120(RSP)
+ STP (R16, R17), 136(RSP)
+ STP (R19, R20), 152(RSP)
+ STP (R21, R22), 168(RSP)
+ STP (R23, R24), 184(RSP)
+ STP (R25, R26), 200(RSP)
MOVD NZCV, R0
MOVD R0, 216(RSP)
MOVD FPSR, R0
MOVD R0, 224(RSP)
- FMOVD F0, 232(RSP)
- FMOVD F1, 240(RSP)
- FMOVD F2, 248(RSP)
- FMOVD F3, 256(RSP)
- FMOVD F4, 264(RSP)
- FMOVD F5, 272(RSP)
- FMOVD F6, 280(RSP)
- FMOVD F7, 288(RSP)
- FMOVD F8, 296(RSP)
- FMOVD F9, 304(RSP)
- FMOVD F10, 312(RSP)
- FMOVD F11, 320(RSP)
- FMOVD F12, 328(RSP)
- FMOVD F13, 336(RSP)
- FMOVD F14, 344(RSP)
- FMOVD F15, 352(RSP)
- FMOVD F16, 360(RSP)
- FMOVD F17, 368(RSP)
- FMOVD F18, 376(RSP)
- FMOVD F19, 384(RSP)
- FMOVD F20, 392(RSP)
- FMOVD F21, 400(RSP)
- FMOVD F22, 408(RSP)
- FMOVD F23, 416(RSP)
- FMOVD F24, 424(RSP)
- FMOVD F25, 432(RSP)
- FMOVD F26, 440(RSP)
- FMOVD F27, 448(RSP)
- FMOVD F28, 456(RSP)
- FMOVD F29, 464(RSP)
- FMOVD F30, 472(RSP)
- FMOVD F31, 480(RSP)
+ FSTPD (F0, F1), 232(RSP)
+ FSTPD (F2, F3), 248(RSP)
+ FSTPD (F4, F5), 264(RSP)
+ FSTPD (F6, F7), 280(RSP)
+ FSTPD (F8, F9), 296(RSP)
+ FSTPD (F10, F11), 312(RSP)
+ FSTPD (F12, F13), 328(RSP)
+ FSTPD (F14, F15), 344(RSP)
+ FSTPD (F16, F17), 360(RSP)
+ FSTPD (F18, F19), 376(RSP)
+ FSTPD (F20, F21), 392(RSP)
+ FSTPD (F22, F23), 408(RSP)
+ FSTPD (F24, F25), 424(RSP)
+ FSTPD (F26, F27), 440(RSP)
+ FSTPD (F28, F29), 456(RSP)
+ FSTPD (F30, F31), 472(RSP)
CALL ·asyncPreempt2(SB)
- FMOVD 480(RSP), F31
- FMOVD 472(RSP), F30
- FMOVD 464(RSP), F29
- FMOVD 456(RSP), F28
- FMOVD 448(RSP), F27
- FMOVD 440(RSP), F26
- FMOVD 432(RSP), F25
- FMOVD 424(RSP), F24
- FMOVD 416(RSP), F23
- FMOVD 408(RSP), F22
- FMOVD 400(RSP), F21
- FMOVD 392(RSP), F20
- FMOVD 384(RSP), F19
- FMOVD 376(RSP), F18
- FMOVD 368(RSP), F17
- FMOVD 360(RSP), F16
- FMOVD 352(RSP), F15
- FMOVD 344(RSP), F14
- FMOVD 336(RSP), F13
- FMOVD 328(RSP), F12
- FMOVD 320(RSP), F11
- FMOVD 312(RSP), F10
- FMOVD 304(RSP), F9
- FMOVD 296(RSP), F8
- FMOVD 288(RSP), F7
- FMOVD 280(RSP), F6
- FMOVD 272(RSP), F5
- FMOVD 264(RSP), F4
- FMOVD 256(RSP), F3
- FMOVD 248(RSP), F2
- FMOVD 240(RSP), F1
- FMOVD 232(RSP), F0
+ FLDPD 472(RSP), (F30, F31)
+ FLDPD 456(RSP), (F28, F29)
+ FLDPD 440(RSP), (F26, F27)
+ FLDPD 424(RSP), (F24, F25)
+ FLDPD 408(RSP), (F22, F23)
+ FLDPD 392(RSP), (F20, F21)
+ FLDPD 376(RSP), (F18, F19)
+ FLDPD 360(RSP), (F16, F17)
+ FLDPD 344(RSP), (F14, F15)
+ FLDPD 328(RSP), (F12, F13)
+ FLDPD 312(RSP), (F10, F11)
+ FLDPD 296(RSP), (F8, F9)
+ FLDPD 280(RSP), (F6, F7)
+ FLDPD 264(RSP), (F4, F5)
+ FLDPD 248(RSP), (F2, F3)
+ FLDPD 232(RSP), (F0, F1)
MOVD 224(RSP), R0
MOVD R0, FPSR
MOVD 216(RSP), R0
MOVD R0, NZCV
- MOVD 208(RSP), R26
- MOVD 200(RSP), R25
- MOVD 192(RSP), R24
- MOVD 184(RSP), R23
- MOVD 176(RSP), R22
- MOVD 168(RSP), R21
- MOVD 160(RSP), R20
- MOVD 152(RSP), R19
- MOVD 144(RSP), R17
- MOVD 136(RSP), R16
- MOVD 128(RSP), R15
- MOVD 120(RSP), R14
- MOVD 112(RSP), R13
- MOVD 104(RSP), R12
- MOVD 96(RSP), R11
- MOVD 88(RSP), R10
- MOVD 80(RSP), R9
- MOVD 72(RSP), R8
- MOVD 64(RSP), R7
- MOVD 56(RSP), R6
- MOVD 48(RSP), R5
- MOVD 40(RSP), R4
- MOVD 32(RSP), R3
- MOVD 24(RSP), R2
- MOVD 16(RSP), R1
- MOVD 8(RSP), R0
+ LDP 200(RSP), (R25, R26)
+ LDP 184(RSP), (R23, R24)
+ LDP 168(RSP), (R21, R22)
+ LDP 152(RSP), (R19, R20)
+ LDP 136(RSP), (R16, R17)
+ LDP 120(RSP), (R14, R15)
+ LDP 104(RSP), (R12, R13)
+ LDP 88(RSP), (R10, R11)
+ LDP 72(RSP), (R8, R9)
+ LDP 56(RSP), (R6, R7)
+ LDP 40(RSP), (R4, R5)
+ LDP 24(RSP), (R2, R3)
+ LDP 8(RSP), (R0, R1)
MOVD 496(RSP), R30
- #ifdef GOOS_linux
MOVD -8(RSP), R29
- #endif
MOVD (RSP), R27
ADD $512, RSP
JMP (R27)

To view, visit change 379715. To unsubscribe, or for help writing mail filters, visit settings.

Gerrit-Project: go
Gerrit-Branch: master
Gerrit-Change-Id: Ida5a6f0a8d825a56af607ba2c2cd91fdc2e8f67f
Gerrit-Change-Number: 379715
Gerrit-PatchSet: 1
Gerrit-Owner: Eric Fang <eric...@arm.com>
Gerrit-MessageType: newchange

Eric Fang (Gerrit)

unread,
Jan 19, 2022, 10:38:29 PM1/19/22
to goph...@pubsubhelper.golang.org, Cherry Mui, golang-co...@googlegroups.com

Attention is currently required from: Cherry Mui.

Patch set 1:Run-TryBot +1Code-Review +1Trust +1

View Change

    To view, visit change 379715. To unsubscribe, or for help writing mail filters, visit settings.

    Gerrit-Project: go
    Gerrit-Branch: master
    Gerrit-Change-Id: Ida5a6f0a8d825a56af607ba2c2cd91fdc2e8f67f
    Gerrit-Change-Number: 379715
    Gerrit-PatchSet: 1
    Gerrit-Owner: Eric Fang <eric...@arm.com>
    Gerrit-Reviewer: Cherry Mui <cher...@google.com>
    Gerrit-Reviewer: Eric Fang <eric...@arm.com>
    Gerrit-Attention: Cherry Mui <cher...@google.com>
    Gerrit-Comment-Date: Thu, 20 Jan 2022 03:38:23 +0000
    Gerrit-HasComments: No
    Gerrit-Has-Labels: Yes
    Gerrit-MessageType: comment

    Cherry Mui (Gerrit)

    unread,
    Jan 20, 2022, 10:46:53 AM1/20/22
    to Eric Fang, goph...@pubsubhelper.golang.org, Gopher Robot, golang-co...@googlegroups.com

    Attention is currently required from: Eric Fang.

    View Change

    3 comments:

    • Patchset:

      • Patch Set #1:

        I don't think it actually matters. (But doesn't hurt.)

    • File src/runtime/mkpreempt.go:

      • Patch Set #1, Line 125: fmt.Fprintf(out, "//go:build %s || %sle\n\n", base, base)

        Is this change related? Does it affect all other generated files?

      • Patch Set #1, Line 160: func (l *layout) add(sop, rop, reg string, size int) {

        The change to all callers of add looks undesired. Maybe introduce an add2 method and undo those.

    To view, visit change 379715. To unsubscribe, or for help writing mail filters, visit settings.

    Gerrit-Project: go
    Gerrit-Branch: master
    Gerrit-Change-Id: Ida5a6f0a8d825a56af607ba2c2cd91fdc2e8f67f
    Gerrit-Change-Number: 379715
    Gerrit-PatchSet: 1
    Gerrit-Owner: Eric Fang <eric...@arm.com>
    Gerrit-Reviewer: Cherry Mui <cher...@google.com>
    Gerrit-Reviewer: Eric Fang <eric...@arm.com>
    Gerrit-Reviewer: Gopher Robot <go...@golang.org>
    Gerrit-Attention: Eric Fang <eric...@arm.com>
    Gerrit-Comment-Date: Thu, 20 Jan 2022 15:46:48 +0000
    Gerrit-HasComments: Yes
    Gerrit-Has-Labels: No
    Gerrit-MessageType: comment

    Eric Fang (Gerrit)

    unread,
    Jan 20, 2022, 10:46:25 PM1/20/22
    to goph...@pubsubhelper.golang.org, golang-co...@googlegroups.com

    Attention is currently required from: Eric Fang.

    Eric Fang uploaded patch set #2 to this change.

    View Change

    runtime: use stp/ldp to save and restore all registers on arm64

    Async preemption needs to save and restore almost all of the registers,
    currently this is done by ldr and str on arm64. We can do it with ldp
    and stp as they are more efficient.

    Change-Id: Ida5a6f0a8d825a56af607ba2c2cd91fdc2e8f67f
    ---
    M src/runtime/mkpreempt.go
    M src/runtime/preempt_arm64.s
    2 files changed, 93 insertions(+), 139 deletions(-)

    To view, visit change 379715. To unsubscribe, or for help writing mail filters, visit settings.

    Gerrit-Project: go
    Gerrit-Branch: master
    Gerrit-Change-Id: Ida5a6f0a8d825a56af607ba2c2cd91fdc2e8f67f
    Gerrit-Change-Number: 379715
    Gerrit-PatchSet: 2
    Gerrit-Owner: Eric Fang <eric...@arm.com>
    Gerrit-Reviewer: Cherry Mui <cher...@google.com>
    Gerrit-Reviewer: Eric Fang <eric...@arm.com>
    Gerrit-Reviewer: Gopher Robot <go...@golang.org>
    Gerrit-Attention: Eric Fang <eric...@arm.com>
    Gerrit-MessageType: newpatchset

    Eric Fang (Gerrit)

    unread,
    Jan 20, 2022, 10:52:15 PM1/20/22
    to goph...@pubsubhelper.golang.org, Gopher Robot, Cherry Mui, golang-co...@googlegroups.com

    Attention is currently required from: Cherry Mui.

    Patch set 2:Run-TryBot +1Code-Review +1Trust +1

    View Change

    3 comments:

    • Patchset:

      • Patch Set #1:

        I don't think it actually matters. (But doesn't hurt. […]

        In the process of building go, function asyncPreempt was called a lot, we also need to stop the world via async preemption when gc starts. This function may not be a performance critical part, but the change is worthwhile.

    • File src/runtime/mkpreempt.go:

      • Patch Set #1, Line 125: fmt.Fprintf(out, "//go:build %s || %sle\n\n", base, base)

        Is this change related? Does it affect all other generated files?

      • Without this change, other generated files will be affected. As we can see from preempt_mips64x.s, there's a blank before and after '//go:build mips64 || mips64le', without this additional '\n', there will not be a blank line after '//go:build mips64 || mips64le'.

      • Patch Set #1, Line 160: func (l *layout) add(sop, rop, reg string, size int) {

        The change to all callers of add looks undesired. Maybe introduce an add2 method and undo those.

      • Done

    To view, visit change 379715. To unsubscribe, or for help writing mail filters, visit settings.

    Gerrit-Project: go
    Gerrit-Branch: master
    Gerrit-Change-Id: Ida5a6f0a8d825a56af607ba2c2cd91fdc2e8f67f
    Gerrit-Change-Number: 379715
    Gerrit-PatchSet: 2
    Gerrit-Owner: Eric Fang <eric...@arm.com>
    Gerrit-Reviewer: Cherry Mui <cher...@google.com>
    Gerrit-Reviewer: Eric Fang <eric...@arm.com>
    Gerrit-Reviewer: Gopher Robot <go...@golang.org>
    Gerrit-Attention: Cherry Mui <cher...@google.com>
    Gerrit-Comment-Date: Fri, 21 Jan 2022 03:52:09 +0000
    Gerrit-HasComments: Yes
    Gerrit-Has-Labels: Yes
    Comment-In-Reply-To: Cherry Mui <cher...@google.com>
    Gerrit-MessageType: comment

    Eric Fang (Gerrit)

    unread,
    Jan 20, 2022, 10:52:41 PM1/20/22
    to goph...@pubsubhelper.golang.org, Gopher Robot, Cherry Mui, golang-co...@googlegroups.com

    Attention is currently required from: Cherry Mui.

    View Change

    1 comment:

    • File src/runtime/mkpreempt.go:

      • Without this change, other generated files will be affected. As we can see from preempt_mips64x. […]

        Done

    To view, visit change 379715. To unsubscribe, or for help writing mail filters, visit settings.

    Gerrit-Project: go
    Gerrit-Branch: master
    Gerrit-Change-Id: Ida5a6f0a8d825a56af607ba2c2cd91fdc2e8f67f
    Gerrit-Change-Number: 379715
    Gerrit-PatchSet: 2
    Gerrit-Owner: Eric Fang <eric...@arm.com>
    Gerrit-Reviewer: Cherry Mui <cher...@google.com>
    Gerrit-Reviewer: Eric Fang <eric...@arm.com>
    Gerrit-Reviewer: Gopher Robot <go...@golang.org>
    Gerrit-Attention: Cherry Mui <cher...@google.com>
    Gerrit-Comment-Date: Fri, 21 Jan 2022 03:52:35 +0000
    Gerrit-HasComments: Yes
    Gerrit-Has-Labels: No
    Comment-In-Reply-To: Eric Fang <eric...@arm.com>

    Cherry Mui (Gerrit)

    unread,
    Jan 21, 2022, 11:29:45 AM1/21/22
    to Eric Fang, goph...@pubsubhelper.golang.org, Gopher Robot, golang-co...@googlegroups.com

    Attention is currently required from: Eric Fang.

    View Change

    2 comments:

    • Patchset:

      • Patch Set #1:

        In the process of building go, function asyncPreempt was called a lot, we also need to stop the worl […]

        It is only called when receiving an OS signal. Compared to an OS signal (kernel/user mode switches, a bunch of functions called etc.) a few extra instructions are ignorable.

    • Patchset:

    To view, visit change 379715. To unsubscribe, or for help writing mail filters, visit settings.

    Gerrit-Project: go
    Gerrit-Branch: master
    Gerrit-Change-Id: Ida5a6f0a8d825a56af607ba2c2cd91fdc2e8f67f
    Gerrit-Change-Number: 379715
    Gerrit-PatchSet: 2
    Gerrit-Owner: Eric Fang <eric...@arm.com>
    Gerrit-Reviewer: Cherry Mui <cher...@google.com>
    Gerrit-Reviewer: Eric Fang <eric...@arm.com>
    Gerrit-Reviewer: Gopher Robot <go...@golang.org>
    Gerrit-Attention: Eric Fang <eric...@arm.com>
    Gerrit-Comment-Date: Fri, 21 Jan 2022 16:29:39 +0000

    Cherry Mui (Gerrit)

    unread,
    Mar 2, 2022, 11:26:55 AM3/2/22
    to Eric Fang, goph...@pubsubhelper.golang.org, Gopher Robot, golang-co...@googlegroups.com

    Attention is currently required from: Eric Fang.

    Patch set 2:Code-Review +2

    View Change

      To view, visit change 379715. To unsubscribe, or for help writing mail filters, visit settings.

      Gerrit-Project: go
      Gerrit-Branch: master
      Gerrit-Change-Id: Ida5a6f0a8d825a56af607ba2c2cd91fdc2e8f67f
      Gerrit-Change-Number: 379715
      Gerrit-PatchSet: 2
      Gerrit-Owner: Eric Fang <eric...@arm.com>
      Gerrit-Reviewer: Cherry Mui <cher...@google.com>
      Gerrit-Reviewer: Eric Fang <eric...@arm.com>
      Gerrit-Reviewer: Gopher Robot <go...@golang.org>
      Gerrit-Attention: Eric Fang <eric...@arm.com>
      Gerrit-Comment-Date: Wed, 02 Mar 2022 16:26:50 +0000

      Eric Fang (Gerrit)

      unread,
      Mar 2, 2022, 8:28:26 PM3/2/22
      to goph...@pubsubhelper.golang.org, Cherry Mui, Gopher Robot, golang-co...@googlegroups.com

      Patch set 3:Run-TryBot +1Code-Review +2Trust +1

      View Change

        To view, visit change 379715. To unsubscribe, or for help writing mail filters, visit settings.

        Gerrit-Project: go
        Gerrit-Branch: master
        Gerrit-Change-Id: Ida5a6f0a8d825a56af607ba2c2cd91fdc2e8f67f
        Gerrit-Change-Number: 379715
        Gerrit-PatchSet: 3
        Gerrit-Owner: Eric Fang <eric...@arm.com>
        Gerrit-Reviewer: Cherry Mui <cher...@google.com>
        Gerrit-Reviewer: Eric Fang <eric...@arm.com>
        Gerrit-Reviewer: Gopher Robot <go...@golang.org>
        Gerrit-Comment-Date: Thu, 03 Mar 2022 01:28:21 +0000

        Eric Fang (Gerrit)

        unread,
        Mar 2, 2022, 8:45:47 PM3/2/22
        to goph...@pubsubhelper.golang.org, Gopher Robot, Cherry Mui, golang-co...@googlegroups.com

        Patch set 4:Run-TryBot +1Code-Review +2Trust +1

        View Change

          To view, visit change 379715. To unsubscribe, or for help writing mail filters, visit settings.

          Gerrit-Project: go
          Gerrit-Branch: master
          Gerrit-Change-Id: Ida5a6f0a8d825a56af607ba2c2cd91fdc2e8f67f
          Gerrit-Change-Number: 379715
          Gerrit-PatchSet: 4
          Gerrit-Owner: Eric Fang <eric...@arm.com>
          Gerrit-Reviewer: Cherry Mui <cher...@google.com>
          Gerrit-Reviewer: Eric Fang <eric...@arm.com>
          Gerrit-Reviewer: Gopher Robot <go...@golang.org>
          Gerrit-Comment-Date: Thu, 03 Mar 2022 01:45:41 +0000

          Eric Fang (Gerrit)

          unread,
          Mar 2, 2022, 8:47:12 PM3/2/22
          to goph...@pubsubhelper.golang.org, Gopher Robot, Cherry Mui, golang-co...@googlegroups.com

          Patch set 4:-Code-Review

          View Change

            To view, visit change 379715. To unsubscribe, or for help writing mail filters, visit settings.

            Gerrit-Project: go
            Gerrit-Branch: master
            Gerrit-Change-Id: Ida5a6f0a8d825a56af607ba2c2cd91fdc2e8f67f
            Gerrit-Change-Number: 379715
            Gerrit-PatchSet: 4
            Gerrit-Owner: Eric Fang <eric...@arm.com>
            Gerrit-Reviewer: Cherry Mui <cher...@google.com>
            Gerrit-Reviewer: Eric Fang <eric...@arm.com>
            Gerrit-Reviewer: Gopher Robot <go...@golang.org>
            Gerrit-Comment-Date: Thu, 03 Mar 2022 01:47:06 +0000

            Eric Fang (Gerrit)

            unread,
            Mar 2, 2022, 8:59:03 PM3/2/22
            to goph...@pubsubhelper.golang.org, golang-...@googlegroups.com, Gopher Robot, Cherry Mui, golang-co...@googlegroups.com

            Eric Fang submitted this change.

            View Change



            3 is the latest approved patch-set.
            No files were changed between the latest approved patch-set and the submitted one.

            Approvals: Cherry Mui: Looks good to me, approved Eric Fang: Trusted; Run TryBots Gopher Robot: TryBots succeeded
            runtime: use stp/ldp to save and restore all registers on arm64

            Async preemption needs to save and restore almost all of the registers,
            currently this is done by ldr and str on arm64. We can do it with ldp
            and stp as they are more efficient.

            Change-Id: Ida5a6f0a8d825a56af607ba2c2cd91fdc2e8f67f
            Reviewed-on: https://go-review.googlesource.com/c/go/+/379715
            Reviewed-by: Cherry Mui <cher...@google.com>
            Trust: Eric Fang <eric...@arm.com>
            Run-TryBot: Eric Fang <eric...@arm.com>
            TryBot-Result: Gopher Robot <go...@golang.org>

            ---
            M src/runtime/mkpreempt.go
            M src/runtime/preempt_arm64.s
            2 files changed, 98 insertions(+), 139 deletions(-)

            diff --git a/src/runtime/mkpreempt.go b/src/runtime/mkpreempt.go
            index 17c9b75..37a8cf8 100644

            --- a/src/runtime/mkpreempt.go
            +++ b/src/runtime/mkpreempt.go
            @@ -122,7 +122,7 @@
            fmt.Fprintf(out, "// Code generated by mkpreempt.go; DO NOT EDIT.\n\n")
            if beLe[arch] {
            base := arch[:len(arch)-1]
            - fmt.Fprintf(out, "//go:build %s || %sle\n", base, base)
            + fmt.Fprintf(out, "//go:build %s || %sle\n\n", base, base)
            }
            fmt.Fprintf(out, "#include \"go_asm.h\"\n")
            fmt.Fprintf(out, "#include \"textflag.h\"\n\n")
            @@ -147,8 +147,9 @@
            type regPos struct {
            pos int

            - op string
            - reg string
            + saveOp string
            + restoreOp string
            + reg string

            // If this register requires special save and restore, these
            // give those operations with a %d placeholder for the stack
            @@ -157,7 +158,12 @@

            }

            func (l *layout) add(op, reg string, size int) {
            - l.regs = append(l.regs, regPos{op: op, reg: reg, pos: l.stack})
            +	l.regs = append(l.regs, regPos{saveOp: op, restoreOp: op, reg: reg, pos: l.stack})
            + l.stack += size
            +}
            +
            +func (l *layout) add2(sop, rop, reg string, size int) {

            + l.regs = append(l.regs, regPos{saveOp: sop, restoreOp: rop, reg: reg, pos: l.stack})
            l.stack += size
            }

            @@ -171,7 +177,7 @@

            if reg.save != "" {
            p(reg.save, reg.pos)
            } else {
            - p("%s %s, %d(%s)", reg.op, reg.reg, reg.pos, l.sp)
            + p("%s %s, %d(%s)", reg.saveOp, reg.reg, reg.pos, l.sp)
            }
            }
            }
            @@ -182,7 +188,7 @@

            if reg.restore != "" {
            p(reg.restore, reg.pos)
            } else {
            - p("%s %d(%s), %s", reg.op, reg.pos, l.sp, reg.reg)
            + p("%s %d(%s), %s", reg.restoreOp, reg.pos, l.sp, reg.reg)
            }
            }
            }
            @@ -324,12 +330,13 @@

            // R27 (REGTMP), R28 (g), R29 (FP), R30 (LR), R31 (SP) are special
            // and not saved here.
            var l = layout{sp: "RSP", stack: 8} // add slot to save PC of interrupted instruction
            - for i := 0; i <= 26; i++ {
            + for i := 0; i < 26; i += 2 {
            if i == 18 {
            + i--
            continue // R18 is not used, skip
            }
            - reg := fmt.Sprintf("R%d", i)
            - l.add("MOVD", reg, 8)
            + reg := fmt.Sprintf("(R%d, R%d)", i, i+1)
            +		l.add2("STP", "LDP", reg, 16)

            }
            // Add flag registers.
            l.addSpecial(
            @@ -342,9 +349,9 @@

            8)
            // TODO: FPCR? I don't think we'll change it, so no need to save.
            // Add floating point registers F0-F31.
            - for i := 0; i <= 31; i++ {
            - reg := fmt.Sprintf("F%d", i)
            - l.add("FMOVD", reg, 8)
            + for i := 0; i < 31; i += 2 {
            + reg := fmt.Sprintf("(F%d, F%d)", i, i+1)
            +		l.add2("FSTPD", "FLDPD", reg, 16)

            }
            if l.stack%16 != 0 {
            l.stack += 8 // SP needs 16-byte alignment
            @@ -353,10 +360,8 @@

            // allocate frame, save PC of interrupted instruction (in LR)
            p("MOVD R30, %d(RSP)", -l.stack)
            p("SUB $%d, RSP", l.stack)
            - p("#ifdef GOOS_linux")
            p("MOVD R29, -8(RSP)") // save frame pointer (only used on Linux)
            p("SUB $8, RSP, R29") // set up new frame pointer
            - p("#endif")
            // On iOS, save the LR again after decrementing SP. We run the
            // signal handler on the G stack (as it doesn't support sigaltstack),
            // so any writes below SP may be clobbered.
            @@ -369,11 +374,9 @@

            l.restore()

            p("MOVD %d(RSP), R30", l.stack) // sigctxt.pushCall has pushed LR (at interrupt) on stack, restore it
            - p("#ifdef GOOS_linux")
            - p("MOVD -8(RSP), R29") // restore frame pointer
            - p("#endif")
            - p("MOVD (RSP), R27") // load PC to REGTMP
            - p("ADD $%d, RSP", l.stack+16) // pop frame (including the space pushed by sigctxt.pushCall)
            + p("MOVD -8(RSP), R29") // restore frame pointer
            + p("MOVD (RSP), R27") // load PC to REGTMP
            + p("ADD $%d, RSP", l.stack+16) // pop frame (including the space pushed by sigctxt.pushCall)
            p("JMP (R27)")
            }

            To view, visit change 379715. To unsubscribe, or for help writing mail filters, visit settings.

            Gerrit-Project: go
            Gerrit-Branch: master
            Gerrit-Change-Id: Ida5a6f0a8d825a56af607ba2c2cd91fdc2e8f67f
            Gerrit-Change-Number: 379715
            Gerrit-PatchSet: 5
            Gerrit-Owner: Eric Fang <eric...@arm.com>
            Gerrit-Reviewer: Cherry Mui <cher...@google.com>
            Gerrit-Reviewer: Eric Fang <eric...@arm.com>
            Gerrit-Reviewer: Gopher Robot <go...@golang.org>
            Gerrit-MessageType: merged
            Reply all
            Reply to author
            Forward
            0 new messages