]> Cypherpunks repositories - gostls13.git/commitdiff
runtime: eliminate global state in mkpreempt.go
authorAustin Clements <austin@google.com>
Thu, 12 Jun 2025 22:37:01 +0000 (18:37 -0400)
committerGopher Robot <gobot@golang.org>
Tue, 5 Aug 2025 20:55:01 +0000 (13:55 -0700)
We're going to start writing two files, so having a single global file
we're writing will be a problem.

This has no effect on the generated code.

This is a cherry-pick of CL 680897 from the dev.simd branch.

Change-Id: I49897ea0c6500a29eac89b597d75c0eb3e9b6706
Reviewed-on: https://go-review.googlesource.com/c/go/+/693395
Auto-Submit: Austin Clements <austin@google.com>
Reviewed-by: Cherry Mui <cherryyz@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>

src/runtime/mkpreempt.go

index 6a9cf77a43fcf09af04b50cddf73935c97c54d49..ec900a23d257e91415d05003b9687c062788b055 100644 (file)
@@ -73,16 +73,14 @@ var regNamesAMD64 = []string{
        "X15",
 }
 
-var out io.Writer
-
-var arches = map[string]func(){
+var arches = map[string]func(g *gen){
        "386":     gen386,
        "amd64":   genAMD64,
        "arm":     genARM,
        "arm64":   genARM64,
        "loong64": genLoong64,
-       "mips64x": func() { genMIPS(true) },
-       "mipsx":   func() { genMIPS(false) },
+       "mips64x": func(g *gen) { genMIPS(g, true) },
+       "mipsx":   func(g *gen) { genMIPS(g, false) },
        "ppc64x":  genPPC64,
        "riscv64": genRISCV64,
        "s390x":   genS390X,
@@ -93,53 +91,58 @@ var beLe = map[string]bool{"mips64x": true, "mipsx": true, "ppc64x": true}
 func main() {
        flag.Parse()
        if flag.NArg() > 0 {
-               out = os.Stdout
                for _, arch := range flag.Args() {
-                       gen, ok := arches[arch]
+                       genFn, ok := arches[arch]
                        if !ok {
                                log.Fatalf("unknown arch %s", arch)
                        }
-                       header(arch)
-                       gen()
+                       g := gen{os.Stdout, arch}
+                       g.asmHeader()
+                       genFn(&g)
                }
                return
        }
 
-       for arch, gen := range arches {
+       for arch, genFn := range arches {
                f, err := os.Create(fmt.Sprintf("preempt_%s.s", arch))
                if err != nil {
                        log.Fatal(err)
                }
-               out = f
-               header(arch)
-               gen()
+               g := gen{f, arch}
+               g.asmHeader()
+               genFn(&g)
                if err := f.Close(); err != nil {
                        log.Fatal(err)
                }
        }
 }
 
-func header(arch string) {
-       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\n", base, base)
+type gen struct {
+       w      io.Writer
+       goarch string
+}
+
+func (g *gen) asmHeader() {
+       fmt.Fprintf(g.w, "// Code generated by mkpreempt.go; DO NOT EDIT.\n\n")
+       if beLe[g.goarch] {
+               base := g.goarch[:len(g.goarch)-1]
+               fmt.Fprintf(g.w, "//go:build %s || %sle\n\n", base, base)
        }
-       fmt.Fprintf(out, "#include \"go_asm.h\"\n")
-       if arch == "amd64" {
-               fmt.Fprintf(out, "#include \"asm_amd64.h\"\n")
+       fmt.Fprintf(g.w, "#include \"go_asm.h\"\n")
+       if g.goarch == "amd64" {
+               fmt.Fprintf(g.w, "#include \"asm_amd64.h\"\n")
        }
-       fmt.Fprintf(out, "#include \"textflag.h\"\n\n")
-       fmt.Fprintf(out, "TEXT ·asyncPreempt(SB),NOSPLIT|NOFRAME,$0-0\n")
+       fmt.Fprintf(g.w, "#include \"textflag.h\"\n\n")
+       fmt.Fprintf(g.w, "TEXT ·asyncPreempt(SB),NOSPLIT|NOFRAME,$0-0\n")
 }
 
-func p(f string, args ...any) {
+func (g *gen) p(f string, args ...any) {
        fmted := fmt.Sprintf(f, args...)
-       fmt.Fprintf(out, "\t%s\n", strings.ReplaceAll(fmted, "\n", "\n\t"))
+       fmt.Fprintf(g.w, "\t%s\n", strings.ReplaceAll(fmted, "\n", "\n\t"))
 }
 
-func label(l string) {
-       fmt.Fprintf(out, "%s\n", l)
+func (g *gen) label(l string) {
+       fmt.Fprintf(g.w, "%s\n", l)
 }
 
 type layout struct {
@@ -176,28 +179,30 @@ func (l *layout) addSpecial(save, restore string, size int) {
        l.stack += size
 }
 
-func (l *layout) save() {
+func (l *layout) save(g *gen) {
        for _, reg := range l.regs {
                if reg.save != "" {
-                       p(reg.save, reg.pos)
+                       g.p(reg.save, reg.pos)
                } else {
-                       p("%s %s, %d(%s)", reg.saveOp, reg.reg, reg.pos, l.sp)
+                       g.p("%s %s, %d(%s)", reg.saveOp, reg.reg, reg.pos, l.sp)
                }
        }
 }
 
-func (l *layout) restore() {
+func (l *layout) restore(g *gen) {
        for i := len(l.regs) - 1; i >= 0; i-- {
                reg := l.regs[i]
                if reg.restore != "" {
-                       p(reg.restore, reg.pos)
+                       g.p(reg.restore, reg.pos)
                } else {
-                       p("%s %d(%s), %s", reg.restoreOp, reg.pos, l.sp, reg.reg)
+                       g.p("%s %d(%s), %s", reg.restoreOp, reg.pos, l.sp, reg.reg)
                }
        }
 }
 
-func gen386() {
+func gen386(g *gen) {
+       p := g.p
+
        p("PUSHFL")
        // Save general purpose registers.
        var l = layout{sp: "SP"}
@@ -218,22 +223,24 @@ func gen386() {
 
        p("ADJSP $%d", lSSE.stack)
        p("NOP SP")
-       l.save()
+       l.save(g)
        p("#ifndef %s", softfloat)
-       lSSE.save()
+       lSSE.save(g)
        p("#endif")
        p("CALL ·asyncPreempt2(SB)")
        p("#ifndef %s", softfloat)
-       lSSE.restore()
+       lSSE.restore(g)
        p("#endif")
-       l.restore()
+       l.restore(g)
        p("ADJSP $%d", -lSSE.stack)
 
        p("POPFL")
        p("RET")
 }
 
-func genAMD64() {
+func genAMD64(g *gen) {
+       p := g.p
+
        // Assign stack offsets.
        var l = layout{sp: "SP"}
        for _, reg := range regNamesAMD64 {
@@ -262,19 +269,21 @@ func genAMD64() {
        p("// But vet doesn't know ADJSP, so suppress vet stack checking")
        p("NOP SP")
 
-       l.save()
+       l.save(g)
 
-       lSSE.save()
+       lSSE.save(g)
        p("CALL ·asyncPreempt2(SB)")
-       lSSE.restore()
-       l.restore()
+       lSSE.restore(g)
+       l.restore(g)
        p("ADJSP $%d", -lSSE.stack)
        p("POPFQ")
        p("POPQ BP")
        p("RET")
 }
 
-func genARM() {
+func genARM(g *gen) {
+       p := g.p
+
        // Add integer registers R0-R12.
        // R13 (SP), R14 (LR), R15 (PC) are special and not saved here.
        var l = layout{sp: "R13", stack: 4} // add LR slot
@@ -303,22 +312,23 @@ func genARM() {
        }
 
        p("MOVW.W R14, -%d(R13)", lfp.stack) // allocate frame, save LR
-       l.save()
+       l.save(g)
        p("MOVB ·goarmsoftfp(SB), R0\nCMP $0, R0\nBNE nofp") // test goarmsoftfp, and skip FP registers if goarmsoftfp!=0.
-       lfp.save()
-       label("nofp:")
+       lfp.save(g)
+       g.label("nofp:")
        p("CALL ·asyncPreempt2(SB)")
        p("MOVB ·goarmsoftfp(SB), R0\nCMP $0, R0\nBNE nofp2") // test goarmsoftfp, and skip FP registers if goarmsoftfp!=0.
-       lfp.restore()
-       label("nofp2:")
-       l.restore()
+       lfp.restore(g)
+       g.label("nofp2:")
+       l.restore(g)
 
        p("MOVW %d(R13), R14", lfp.stack)     // sigctxt.pushCall pushes LR on stack, restore it
        p("MOVW.P %d(R13), R15", lfp.stack+4) // load PC, pop frame (including the space pushed by sigctxt.pushCall)
        p("UNDEF")                            // shouldn't get here
 }
 
-func genARM64() {
+func genARM64(g *gen) {
+       p := g.p
        // Add integer registers R0-R26
        // R27 (REGTMP), R28 (g), R29 (FP), R30 (LR), R31 (SP) are special
        // and not saved here.
@@ -362,9 +372,9 @@ func genARM64() {
        p("MOVD R30, (RSP)")
        p("#endif")
 
-       l.save()
+       l.save(g)
        p("CALL ·asyncPreempt2(SB)")
-       l.restore()
+       l.restore(g)
 
        p("MOVD %d(RSP), R30", l.stack) // sigctxt.pushCall has pushed LR (at interrupt) on stack, restore it
        p("MOVD -8(RSP), R29")          // restore frame pointer
@@ -373,7 +383,9 @@ func genARM64() {
        p("RET (R27)")
 }
 
-func genMIPS(_64bit bool) {
+func genMIPS(g *gen, _64bit bool) {
+       p := g.p
+
        mov := "MOVW"
        movf := "MOVF"
        add := "ADD"
@@ -428,15 +440,15 @@ func genMIPS(_64bit bool) {
        p(mov+" R31, -%d(R29)", lfp.stack)
        p(sub+" $%d, R29", lfp.stack)
 
-       l.save()
+       l.save(g)
        p("#ifndef %s", softfloat)
-       lfp.save()
+       lfp.save(g)
        p("#endif")
        p("CALL ·asyncPreempt2(SB)")
        p("#ifndef %s", softfloat)
-       lfp.restore()
+       lfp.restore(g)
        p("#endif")
-       l.restore()
+       l.restore(g)
 
        p(mov+" %d(R29), R31", lfp.stack)     // sigctxt.pushCall has pushed LR (at interrupt) on stack, restore it
        p(mov + " (R29), R23")                // load PC to REGTMP
@@ -444,7 +456,9 @@ func genMIPS(_64bit bool) {
        p("JMP (R23)")
 }
 
-func genLoong64() {
+func genLoong64(g *gen) {
+       p := g.p
+
        mov := "MOVV"
        movf := "MOVD"
        add := "ADDV"
@@ -478,9 +492,9 @@ func genLoong64() {
        p(mov+" R1, -%d(R3)", l.stack)
        p(sub+" $%d, R3", l.stack)
 
-       l.save()
+       l.save(g)
        p("CALL ·asyncPreempt2(SB)")
-       l.restore()
+       l.restore(g)
 
        p(mov+" %d(R3), R1", l.stack)      // sigctxt.pushCall has pushed LR (at interrupt) on stack, restore it
        p(mov + " (R3), R30")              // load PC to REGTMP
@@ -488,7 +502,9 @@ func genLoong64() {
        p("JMP (R30)")
 }
 
-func genPPC64() {
+func genPPC64(g *gen) {
+       p := g.p
+
        // Add integer registers R3-R29
        // R0 (zero), R1 (SP), R30 (g) are special and not saved here.
        // R2 (TOC pointer in PIC mode), R12 (function entry address in PIC mode) have been saved in sigctxt.pushCall.
@@ -528,9 +544,9 @@ func genPPC64() {
        p("MOVD LR, R31")
        p("MOVDU R31, -%d(R1)", l.stack) // allocate frame, save PC of interrupted instruction (in LR)
 
-       l.save()
+       l.save(g)
        p("CALL ·asyncPreempt2(SB)")
-       l.restore()
+       l.restore(g)
 
        p("MOVD %d(R1), R31", l.stack) // sigctxt.pushCall has pushed LR, R2, R12 (at interrupt) on stack, restore them
        p("MOVD R31, LR")
@@ -543,7 +559,9 @@ func genPPC64() {
        p("JMP (CTR)")
 }
 
-func genRISCV64() {
+func genRISCV64(g *gen) {
+       p := g.p
+
        // X0 (zero), X1 (LR), X2 (SP), X3 (GP), X4 (TP), X27 (g), X31 (TMP) are special.
        var l = layout{sp: "X2", stack: 8}
 
@@ -564,16 +582,18 @@ func genRISCV64() {
 
        p("MOV X1, -%d(X2)", l.stack)
        p("SUB $%d, X2", l.stack)
-       l.save()
+       l.save(g)
        p("CALL ·asyncPreempt2(SB)")
-       l.restore()
+       l.restore(g)
        p("MOV %d(X2), X1", l.stack)
        p("MOV (X2), X31")
        p("ADD $%d, X2", l.stack+8)
        p("JMP (X31)")
 }
 
-func genS390X() {
+func genS390X(g *gen) {
+       p := g.p
+
        // Add integer registers R0-R12
        // R13 (g), R14 (LR), R15 (SP) are special, and not saved here.
        // Saving R10 (REGTMP) is not necessary, but it is saved anyway.
@@ -594,9 +614,9 @@ func genS390X() {
        p("ADD $-%d, R15", l.stack)
        p("MOVW R10, 8(R15)") // save flags
 
-       l.save()
+       l.save(g)
        p("CALL ·asyncPreempt2(SB)")
-       l.restore()
+       l.restore(g)
 
        p("MOVD %d(R15), R14", l.stack)    // sigctxt.pushCall has pushed LR (at interrupt) on stack, restore it
        p("ADD $%d, R15", l.stack+8)       // pop frame (including the space pushed by sigctxt.pushCall)
@@ -606,12 +626,14 @@ func genS390X() {
        p("JMP (R10)")
 }
 
-func genWasm() {
+func genWasm(g *gen) {
+       p := g.p
        p("// No async preemption on wasm")
        p("UNDEF")
 }
 
-func notImplemented() {
+func notImplemented(g *gen) {
+       p := g.p
        p("// Not implemented yet")
        p("JMP ·abort(SB)")
 }