Skip to content

Commit cef381b

Browse files
aclementsgopherbot
authored andcommitted
runtime: eliminate global state in mkpreempt.go
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 <[email protected]> Reviewed-by: Cherry Mui <[email protected]> LUCI-TryBot-Result: Go LUCI <[email protected]>
1 parent c0025d5 commit cef381b

File tree

1 file changed

+94
-72
lines changed

1 file changed

+94
-72
lines changed

src/runtime/mkpreempt.go

Lines changed: 94 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -73,16 +73,14 @@ var regNamesAMD64 = []string{
7373
"X15",
7474
}
7575

76-
var out io.Writer
77-
78-
var arches = map[string]func(){
76+
var arches = map[string]func(g *gen){
7977
"386": gen386,
8078
"amd64": genAMD64,
8179
"arm": genARM,
8280
"arm64": genARM64,
8381
"loong64": genLoong64,
84-
"mips64x": func() { genMIPS(true) },
85-
"mipsx": func() { genMIPS(false) },
82+
"mips64x": func(g *gen) { genMIPS(g, true) },
83+
"mipsx": func(g *gen) { genMIPS(g, false) },
8684
"ppc64x": genPPC64,
8785
"riscv64": genRISCV64,
8886
"s390x": genS390X,
@@ -93,53 +91,58 @@ var beLe = map[string]bool{"mips64x": true, "mipsx": true, "ppc64x": true}
9391
func main() {
9492
flag.Parse()
9593
if flag.NArg() > 0 {
96-
out = os.Stdout
9794
for _, arch := range flag.Args() {
98-
gen, ok := arches[arch]
95+
genFn, ok := arches[arch]
9996
if !ok {
10097
log.Fatalf("unknown arch %s", arch)
10198
}
102-
header(arch)
103-
gen()
99+
g := gen{os.Stdout, arch}
100+
g.asmHeader()
101+
genFn(&g)
104102
}
105103
return
106104
}
107105

108-
for arch, gen := range arches {
106+
for arch, genFn := range arches {
109107
f, err := os.Create(fmt.Sprintf("preempt_%s.s", arch))
110108
if err != nil {
111109
log.Fatal(err)
112110
}
113-
out = f
114-
header(arch)
115-
gen()
111+
g := gen{f, arch}
112+
g.asmHeader()
113+
genFn(&g)
116114
if err := f.Close(); err != nil {
117115
log.Fatal(err)
118116
}
119117
}
120118
}
121119

122-
func header(arch string) {
123-
fmt.Fprintf(out, "// Code generated by mkpreempt.go; DO NOT EDIT.\n\n")
124-
if beLe[arch] {
125-
base := arch[:len(arch)-1]
126-
fmt.Fprintf(out, "//go:build %s || %sle\n\n", base, base)
120+
type gen struct {
121+
w io.Writer
122+
goarch string
123+
}
124+
125+
func (g *gen) asmHeader() {
126+
fmt.Fprintf(g.w, "// Code generated by mkpreempt.go; DO NOT EDIT.\n\n")
127+
if beLe[g.goarch] {
128+
base := g.goarch[:len(g.goarch)-1]
129+
fmt.Fprintf(g.w, "//go:build %s || %sle\n\n", base, base)
127130
}
128-
fmt.Fprintf(out, "#include \"go_asm.h\"\n")
129-
if arch == "amd64" {
130-
fmt.Fprintf(out, "#include \"asm_amd64.h\"\n")
131+
fmt.Fprintf(g.w, "#include \"go_asm.h\"\n")
132+
if g.goarch == "amd64" {
133+
fmt.Fprintf(g.w, "#include \"asm_amd64.h\"\n")
131134
}
132-
fmt.Fprintf(out, "#include \"textflag.h\"\n\n")
133-
fmt.Fprintf(out, "TEXT ·asyncPreempt(SB),NOSPLIT|NOFRAME,$0-0\n")
135+
fmt.Fprintf(g.w, "#include \"textflag.h\"\n\n")
136+
fmt.Fprintf(g.w, "TEXT ·asyncPreempt(SB),NOSPLIT|NOFRAME,$0-0\n")
134137
}
135138

136-
func p(f string, args ...any) {
139+
func (g *gen) p(f string, args ...any) {
137140
fmted := fmt.Sprintf(f, args...)
138-
fmt.Fprintf(out, "\t%s\n", strings.ReplaceAll(fmted, "\n", "\n\t"))
141+
fmt.Fprintf(g.w, "\t%s\n", strings.ReplaceAll(fmted, "\n", "\n\t"))
139142
}
140143

141-
func label(l string) {
142-
fmt.Fprintf(out, "%s\n", l)
144+
func (g *gen) label(l string) {
145+
fmt.Fprintf(g.w, "%s\n", l)
143146
}
144147

145148
type layout struct {
@@ -176,28 +179,30 @@ func (l *layout) addSpecial(save, restore string, size int) {
176179
l.stack += size
177180
}
178181

179-
func (l *layout) save() {
182+
func (l *layout) save(g *gen) {
180183
for _, reg := range l.regs {
181184
if reg.save != "" {
182-
p(reg.save, reg.pos)
185+
g.p(reg.save, reg.pos)
183186
} else {
184-
p("%s %s, %d(%s)", reg.saveOp, reg.reg, reg.pos, l.sp)
187+
g.p("%s %s, %d(%s)", reg.saveOp, reg.reg, reg.pos, l.sp)
185188
}
186189
}
187190
}
188191

189-
func (l *layout) restore() {
192+
func (l *layout) restore(g *gen) {
190193
for i := len(l.regs) - 1; i >= 0; i-- {
191194
reg := l.regs[i]
192195
if reg.restore != "" {
193-
p(reg.restore, reg.pos)
196+
g.p(reg.restore, reg.pos)
194197
} else {
195-
p("%s %d(%s), %s", reg.restoreOp, reg.pos, l.sp, reg.reg)
198+
g.p("%s %d(%s), %s", reg.restoreOp, reg.pos, l.sp, reg.reg)
196199
}
197200
}
198201
}
199202

200-
func gen386() {
203+
func gen386(g *gen) {
204+
p := g.p
205+
201206
p("PUSHFL")
202207
// Save general purpose registers.
203208
var l = layout{sp: "SP"}
@@ -218,22 +223,24 @@ func gen386() {
218223

219224
p("ADJSP $%d", lSSE.stack)
220225
p("NOP SP")
221-
l.save()
226+
l.save(g)
222227
p("#ifndef %s", softfloat)
223-
lSSE.save()
228+
lSSE.save(g)
224229
p("#endif")
225230
p("CALL ·asyncPreempt2(SB)")
226231
p("#ifndef %s", softfloat)
227-
lSSE.restore()
232+
lSSE.restore(g)
228233
p("#endif")
229-
l.restore()
234+
l.restore(g)
230235
p("ADJSP $%d", -lSSE.stack)
231236

232237
p("POPFL")
233238
p("RET")
234239
}
235240

236-
func genAMD64() {
241+
func genAMD64(g *gen) {
242+
p := g.p
243+
237244
// Assign stack offsets.
238245
var l = layout{sp: "SP"}
239246
for _, reg := range regNamesAMD64 {
@@ -262,19 +269,21 @@ func genAMD64() {
262269
p("// But vet doesn't know ADJSP, so suppress vet stack checking")
263270
p("NOP SP")
264271

265-
l.save()
272+
l.save(g)
266273

267-
lSSE.save()
274+
lSSE.save(g)
268275
p("CALL ·asyncPreempt2(SB)")
269-
lSSE.restore()
270-
l.restore()
276+
lSSE.restore(g)
277+
l.restore(g)
271278
p("ADJSP $%d", -lSSE.stack)
272279
p("POPFQ")
273280
p("POPQ BP")
274281
p("RET")
275282
}
276283

277-
func genARM() {
284+
func genARM(g *gen) {
285+
p := g.p
286+
278287
// Add integer registers R0-R12.
279288
// R13 (SP), R14 (LR), R15 (PC) are special and not saved here.
280289
var l = layout{sp: "R13", stack: 4} // add LR slot
@@ -303,22 +312,23 @@ func genARM() {
303312
}
304313

305314
p("MOVW.W R14, -%d(R13)", lfp.stack) // allocate frame, save LR
306-
l.save()
315+
l.save(g)
307316
p("MOVB ·goarmsoftfp(SB), R0\nCMP $0, R0\nBNE nofp") // test goarmsoftfp, and skip FP registers if goarmsoftfp!=0.
308-
lfp.save()
309-
label("nofp:")
317+
lfp.save(g)
318+
g.label("nofp:")
310319
p("CALL ·asyncPreempt2(SB)")
311320
p("MOVB ·goarmsoftfp(SB), R0\nCMP $0, R0\nBNE nofp2") // test goarmsoftfp, and skip FP registers if goarmsoftfp!=0.
312-
lfp.restore()
313-
label("nofp2:")
314-
l.restore()
321+
lfp.restore(g)
322+
g.label("nofp2:")
323+
l.restore(g)
315324

316325
p("MOVW %d(R13), R14", lfp.stack) // sigctxt.pushCall pushes LR on stack, restore it
317326
p("MOVW.P %d(R13), R15", lfp.stack+4) // load PC, pop frame (including the space pushed by sigctxt.pushCall)
318327
p("UNDEF") // shouldn't get here
319328
}
320329

321-
func genARM64() {
330+
func genARM64(g *gen) {
331+
p := g.p
322332
// Add integer registers R0-R26
323333
// R27 (REGTMP), R28 (g), R29 (FP), R30 (LR), R31 (SP) are special
324334
// and not saved here.
@@ -362,9 +372,9 @@ func genARM64() {
362372
p("MOVD R30, (RSP)")
363373
p("#endif")
364374

365-
l.save()
375+
l.save(g)
366376
p("CALL ·asyncPreempt2(SB)")
367-
l.restore()
377+
l.restore(g)
368378

369379
p("MOVD %d(RSP), R30", l.stack) // sigctxt.pushCall has pushed LR (at interrupt) on stack, restore it
370380
p("MOVD -8(RSP), R29") // restore frame pointer
@@ -373,7 +383,9 @@ func genARM64() {
373383
p("RET (R27)")
374384
}
375385

376-
func genMIPS(_64bit bool) {
386+
func genMIPS(g *gen, _64bit bool) {
387+
p := g.p
388+
377389
mov := "MOVW"
378390
movf := "MOVF"
379391
add := "ADD"
@@ -428,23 +440,25 @@ func genMIPS(_64bit bool) {
428440
p(mov+" R31, -%d(R29)", lfp.stack)
429441
p(sub+" $%d, R29", lfp.stack)
430442

431-
l.save()
443+
l.save(g)
432444
p("#ifndef %s", softfloat)
433-
lfp.save()
445+
lfp.save(g)
434446
p("#endif")
435447
p("CALL ·asyncPreempt2(SB)")
436448
p("#ifndef %s", softfloat)
437-
lfp.restore()
449+
lfp.restore(g)
438450
p("#endif")
439-
l.restore()
451+
l.restore(g)
440452

441453
p(mov+" %d(R29), R31", lfp.stack) // sigctxt.pushCall has pushed LR (at interrupt) on stack, restore it
442454
p(mov + " (R29), R23") // load PC to REGTMP
443455
p(add+" $%d, R29", lfp.stack+regsize) // pop frame (including the space pushed by sigctxt.pushCall)
444456
p("JMP (R23)")
445457
}
446458

447-
func genLoong64() {
459+
func genLoong64(g *gen) {
460+
p := g.p
461+
448462
mov := "MOVV"
449463
movf := "MOVD"
450464
add := "ADDV"
@@ -478,17 +492,19 @@ func genLoong64() {
478492
p(mov+" R1, -%d(R3)", l.stack)
479493
p(sub+" $%d, R3", l.stack)
480494

481-
l.save()
495+
l.save(g)
482496
p("CALL ·asyncPreempt2(SB)")
483-
l.restore()
497+
l.restore(g)
484498

485499
p(mov+" %d(R3), R1", l.stack) // sigctxt.pushCall has pushed LR (at interrupt) on stack, restore it
486500
p(mov + " (R3), R30") // load PC to REGTMP
487501
p(add+" $%d, R3", l.stack+regsize) // pop frame (including the space pushed by sigctxt.pushCall)
488502
p("JMP (R30)")
489503
}
490504

491-
func genPPC64() {
505+
func genPPC64(g *gen) {
506+
p := g.p
507+
492508
// Add integer registers R3-R29
493509
// R0 (zero), R1 (SP), R30 (g) are special and not saved here.
494510
// 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() {
528544
p("MOVD LR, R31")
529545
p("MOVDU R31, -%d(R1)", l.stack) // allocate frame, save PC of interrupted instruction (in LR)
530546

531-
l.save()
547+
l.save(g)
532548
p("CALL ·asyncPreempt2(SB)")
533-
l.restore()
549+
l.restore(g)
534550

535551
p("MOVD %d(R1), R31", l.stack) // sigctxt.pushCall has pushed LR, R2, R12 (at interrupt) on stack, restore them
536552
p("MOVD R31, LR")
@@ -543,7 +559,9 @@ func genPPC64() {
543559
p("JMP (CTR)")
544560
}
545561

546-
func genRISCV64() {
562+
func genRISCV64(g *gen) {
563+
p := g.p
564+
547565
// X0 (zero), X1 (LR), X2 (SP), X3 (GP), X4 (TP), X27 (g), X31 (TMP) are special.
548566
var l = layout{sp: "X2", stack: 8}
549567

@@ -564,16 +582,18 @@ func genRISCV64() {
564582

565583
p("MOV X1, -%d(X2)", l.stack)
566584
p("SUB $%d, X2", l.stack)
567-
l.save()
585+
l.save(g)
568586
p("CALL ·asyncPreempt2(SB)")
569-
l.restore()
587+
l.restore(g)
570588
p("MOV %d(X2), X1", l.stack)
571589
p("MOV (X2), X31")
572590
p("ADD $%d, X2", l.stack+8)
573591
p("JMP (X31)")
574592
}
575593

576-
func genS390X() {
594+
func genS390X(g *gen) {
595+
p := g.p
596+
577597
// Add integer registers R0-R12
578598
// R13 (g), R14 (LR), R15 (SP) are special, and not saved here.
579599
// Saving R10 (REGTMP) is not necessary, but it is saved anyway.
@@ -594,9 +614,9 @@ func genS390X() {
594614
p("ADD $-%d, R15", l.stack)
595615
p("MOVW R10, 8(R15)") // save flags
596616

597-
l.save()
617+
l.save(g)
598618
p("CALL ·asyncPreempt2(SB)")
599-
l.restore()
619+
l.restore(g)
600620

601621
p("MOVD %d(R15), R14", l.stack) // sigctxt.pushCall has pushed LR (at interrupt) on stack, restore it
602622
p("ADD $%d, R15", l.stack+8) // pop frame (including the space pushed by sigctxt.pushCall)
@@ -606,12 +626,14 @@ func genS390X() {
606626
p("JMP (R10)")
607627
}
608628

609-
func genWasm() {
629+
func genWasm(g *gen) {
630+
p := g.p
610631
p("// No async preemption on wasm")
611632
p("UNDEF")
612633
}
613634

614-
func notImplemented() {
635+
func notImplemented(g *gen) {
636+
p := g.p
615637
p("// Not implemented yet")
616638
p("JMP ·abort(SB)")
617639
}

0 commit comments

Comments
 (0)