@@ -73,16 +73,14 @@ var regNamesAMD64 = []string{
73
73
"X15" ,
74
74
}
75
75
76
- var out io.Writer
77
-
78
- var arches = map [string ]func (){
76
+ var arches = map [string ]func (g * gen ){
79
77
"386" : gen386 ,
80
78
"amd64" : genAMD64 ,
81
79
"arm" : genARM ,
82
80
"arm64" : genARM64 ,
83
81
"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 ) },
86
84
"ppc64x" : genPPC64 ,
87
85
"riscv64" : genRISCV64 ,
88
86
"s390x" : genS390X ,
@@ -93,53 +91,58 @@ var beLe = map[string]bool{"mips64x": true, "mipsx": true, "ppc64x": true}
93
91
func main () {
94
92
flag .Parse ()
95
93
if flag .NArg () > 0 {
96
- out = os .Stdout
97
94
for _ , arch := range flag .Args () {
98
- gen , ok := arches [arch ]
95
+ genFn , ok := arches [arch ]
99
96
if ! ok {
100
97
log .Fatalf ("unknown arch %s" , arch )
101
98
}
102
- header (arch )
103
- gen ()
99
+ g := gen {os .Stdout , arch }
100
+ g .asmHeader ()
101
+ genFn (& g )
104
102
}
105
103
return
106
104
}
107
105
108
- for arch , gen := range arches {
106
+ for arch , genFn := range arches {
109
107
f , err := os .Create (fmt .Sprintf ("preempt_%s.s" , arch ))
110
108
if err != nil {
111
109
log .Fatal (err )
112
110
}
113
- out = f
114
- header ( arch )
115
- gen ( )
111
+ g := gen { f , arch }
112
+ g . asmHeader ( )
113
+ genFn ( & g )
116
114
if err := f .Close (); err != nil {
117
115
log .Fatal (err )
118
116
}
119
117
}
120
118
}
121
119
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 )
127
130
}
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 " )
131
134
}
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 " )
134
137
}
135
138
136
- func p (f string , args ... any ) {
139
+ func ( g * gen ) p (f string , args ... any ) {
137
140
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 " ))
139
142
}
140
143
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 )
143
146
}
144
147
145
148
type layout struct {
@@ -176,28 +179,30 @@ func (l *layout) addSpecial(save, restore string, size int) {
176
179
l .stack += size
177
180
}
178
181
179
- func (l * layout ) save () {
182
+ func (l * layout ) save (g * gen ) {
180
183
for _ , reg := range l .regs {
181
184
if reg .save != "" {
182
- p (reg .save , reg .pos )
185
+ g . p (reg .save , reg .pos )
183
186
} 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 )
185
188
}
186
189
}
187
190
}
188
191
189
- func (l * layout ) restore () {
192
+ func (l * layout ) restore (g * gen ) {
190
193
for i := len (l .regs ) - 1 ; i >= 0 ; i -- {
191
194
reg := l .regs [i ]
192
195
if reg .restore != "" {
193
- p (reg .restore , reg .pos )
196
+ g . p (reg .restore , reg .pos )
194
197
} 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 )
196
199
}
197
200
}
198
201
}
199
202
200
- func gen386 () {
203
+ func gen386 (g * gen ) {
204
+ p := g .p
205
+
201
206
p ("PUSHFL" )
202
207
// Save general purpose registers.
203
208
var l = layout {sp : "SP" }
@@ -218,22 +223,24 @@ func gen386() {
218
223
219
224
p ("ADJSP $%d" , lSSE .stack )
220
225
p ("NOP SP" )
221
- l .save ()
226
+ l .save (g )
222
227
p ("#ifndef %s" , softfloat )
223
- lSSE .save ()
228
+ lSSE .save (g )
224
229
p ("#endif" )
225
230
p ("CALL ·asyncPreempt2(SB)" )
226
231
p ("#ifndef %s" , softfloat )
227
- lSSE .restore ()
232
+ lSSE .restore (g )
228
233
p ("#endif" )
229
- l .restore ()
234
+ l .restore (g )
230
235
p ("ADJSP $%d" , - lSSE .stack )
231
236
232
237
p ("POPFL" )
233
238
p ("RET" )
234
239
}
235
240
236
- func genAMD64 () {
241
+ func genAMD64 (g * gen ) {
242
+ p := g .p
243
+
237
244
// Assign stack offsets.
238
245
var l = layout {sp : "SP" }
239
246
for _ , reg := range regNamesAMD64 {
@@ -262,19 +269,21 @@ func genAMD64() {
262
269
p ("// But vet doesn't know ADJSP, so suppress vet stack checking" )
263
270
p ("NOP SP" )
264
271
265
- l .save ()
272
+ l .save (g )
266
273
267
- lSSE .save ()
274
+ lSSE .save (g )
268
275
p ("CALL ·asyncPreempt2(SB)" )
269
- lSSE .restore ()
270
- l .restore ()
276
+ lSSE .restore (g )
277
+ l .restore (g )
271
278
p ("ADJSP $%d" , - lSSE .stack )
272
279
p ("POPFQ" )
273
280
p ("POPQ BP" )
274
281
p ("RET" )
275
282
}
276
283
277
- func genARM () {
284
+ func genARM (g * gen ) {
285
+ p := g .p
286
+
278
287
// Add integer registers R0-R12.
279
288
// R13 (SP), R14 (LR), R15 (PC) are special and not saved here.
280
289
var l = layout {sp : "R13" , stack : 4 } // add LR slot
@@ -303,22 +312,23 @@ func genARM() {
303
312
}
304
313
305
314
p ("MOVW.W R14, -%d(R13)" , lfp .stack ) // allocate frame, save LR
306
- l .save ()
315
+ l .save (g )
307
316
p ("MOVB ·goarmsoftfp(SB), R0\n CMP $0, R0\n BNE nofp" ) // test goarmsoftfp, and skip FP registers if goarmsoftfp!=0.
308
- lfp .save ()
309
- label ("nofp:" )
317
+ lfp .save (g )
318
+ g . label ("nofp:" )
310
319
p ("CALL ·asyncPreempt2(SB)" )
311
320
p ("MOVB ·goarmsoftfp(SB), R0\n CMP $0, R0\n BNE 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 )
315
324
316
325
p ("MOVW %d(R13), R14" , lfp .stack ) // sigctxt.pushCall pushes LR on stack, restore it
317
326
p ("MOVW.P %d(R13), R15" , lfp .stack + 4 ) // load PC, pop frame (including the space pushed by sigctxt.pushCall)
318
327
p ("UNDEF" ) // shouldn't get here
319
328
}
320
329
321
- func genARM64 () {
330
+ func genARM64 (g * gen ) {
331
+ p := g .p
322
332
// Add integer registers R0-R26
323
333
// R27 (REGTMP), R28 (g), R29 (FP), R30 (LR), R31 (SP) are special
324
334
// and not saved here.
@@ -362,9 +372,9 @@ func genARM64() {
362
372
p ("MOVD R30, (RSP)" )
363
373
p ("#endif" )
364
374
365
- l .save ()
375
+ l .save (g )
366
376
p ("CALL ·asyncPreempt2(SB)" )
367
- l .restore ()
377
+ l .restore (g )
368
378
369
379
p ("MOVD %d(RSP), R30" , l .stack ) // sigctxt.pushCall has pushed LR (at interrupt) on stack, restore it
370
380
p ("MOVD -8(RSP), R29" ) // restore frame pointer
@@ -373,7 +383,9 @@ func genARM64() {
373
383
p ("RET (R27)" )
374
384
}
375
385
376
- func genMIPS (_64bit bool ) {
386
+ func genMIPS (g * gen , _64bit bool ) {
387
+ p := g .p
388
+
377
389
mov := "MOVW"
378
390
movf := "MOVF"
379
391
add := "ADD"
@@ -428,23 +440,25 @@ func genMIPS(_64bit bool) {
428
440
p (mov + " R31, -%d(R29)" , lfp .stack )
429
441
p (sub + " $%d, R29" , lfp .stack )
430
442
431
- l .save ()
443
+ l .save (g )
432
444
p ("#ifndef %s" , softfloat )
433
- lfp .save ()
445
+ lfp .save (g )
434
446
p ("#endif" )
435
447
p ("CALL ·asyncPreempt2(SB)" )
436
448
p ("#ifndef %s" , softfloat )
437
- lfp .restore ()
449
+ lfp .restore (g )
438
450
p ("#endif" )
439
- l .restore ()
451
+ l .restore (g )
440
452
441
453
p (mov + " %d(R29), R31" , lfp .stack ) // sigctxt.pushCall has pushed LR (at interrupt) on stack, restore it
442
454
p (mov + " (R29), R23" ) // load PC to REGTMP
443
455
p (add + " $%d, R29" , lfp .stack + regsize ) // pop frame (including the space pushed by sigctxt.pushCall)
444
456
p ("JMP (R23)" )
445
457
}
446
458
447
- func genLoong64 () {
459
+ func genLoong64 (g * gen ) {
460
+ p := g .p
461
+
448
462
mov := "MOVV"
449
463
movf := "MOVD"
450
464
add := "ADDV"
@@ -478,17 +492,19 @@ func genLoong64() {
478
492
p (mov + " R1, -%d(R3)" , l .stack )
479
493
p (sub + " $%d, R3" , l .stack )
480
494
481
- l .save ()
495
+ l .save (g )
482
496
p ("CALL ·asyncPreempt2(SB)" )
483
- l .restore ()
497
+ l .restore (g )
484
498
485
499
p (mov + " %d(R3), R1" , l .stack ) // sigctxt.pushCall has pushed LR (at interrupt) on stack, restore it
486
500
p (mov + " (R3), R30" ) // load PC to REGTMP
487
501
p (add + " $%d, R3" , l .stack + regsize ) // pop frame (including the space pushed by sigctxt.pushCall)
488
502
p ("JMP (R30)" )
489
503
}
490
504
491
- func genPPC64 () {
505
+ func genPPC64 (g * gen ) {
506
+ p := g .p
507
+
492
508
// Add integer registers R3-R29
493
509
// R0 (zero), R1 (SP), R30 (g) are special and not saved here.
494
510
// 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() {
528
544
p ("MOVD LR, R31" )
529
545
p ("MOVDU R31, -%d(R1)" , l .stack ) // allocate frame, save PC of interrupted instruction (in LR)
530
546
531
- l .save ()
547
+ l .save (g )
532
548
p ("CALL ·asyncPreempt2(SB)" )
533
- l .restore ()
549
+ l .restore (g )
534
550
535
551
p ("MOVD %d(R1), R31" , l .stack ) // sigctxt.pushCall has pushed LR, R2, R12 (at interrupt) on stack, restore them
536
552
p ("MOVD R31, LR" )
@@ -543,7 +559,9 @@ func genPPC64() {
543
559
p ("JMP (CTR)" )
544
560
}
545
561
546
- func genRISCV64 () {
562
+ func genRISCV64 (g * gen ) {
563
+ p := g .p
564
+
547
565
// X0 (zero), X1 (LR), X2 (SP), X3 (GP), X4 (TP), X27 (g), X31 (TMP) are special.
548
566
var l = layout {sp : "X2" , stack : 8 }
549
567
@@ -564,16 +582,18 @@ func genRISCV64() {
564
582
565
583
p ("MOV X1, -%d(X2)" , l .stack )
566
584
p ("SUB $%d, X2" , l .stack )
567
- l .save ()
585
+ l .save (g )
568
586
p ("CALL ·asyncPreempt2(SB)" )
569
- l .restore ()
587
+ l .restore (g )
570
588
p ("MOV %d(X2), X1" , l .stack )
571
589
p ("MOV (X2), X31" )
572
590
p ("ADD $%d, X2" , l .stack + 8 )
573
591
p ("JMP (X31)" )
574
592
}
575
593
576
- func genS390X () {
594
+ func genS390X (g * gen ) {
595
+ p := g .p
596
+
577
597
// Add integer registers R0-R12
578
598
// R13 (g), R14 (LR), R15 (SP) are special, and not saved here.
579
599
// Saving R10 (REGTMP) is not necessary, but it is saved anyway.
@@ -594,9 +614,9 @@ func genS390X() {
594
614
p ("ADD $-%d, R15" , l .stack )
595
615
p ("MOVW R10, 8(R15)" ) // save flags
596
616
597
- l .save ()
617
+ l .save (g )
598
618
p ("CALL ·asyncPreempt2(SB)" )
599
- l .restore ()
619
+ l .restore (g )
600
620
601
621
p ("MOVD %d(R15), R14" , l .stack ) // sigctxt.pushCall has pushed LR (at interrupt) on stack, restore it
602
622
p ("ADD $%d, R15" , l .stack + 8 ) // pop frame (including the space pushed by sigctxt.pushCall)
@@ -606,12 +626,14 @@ func genS390X() {
606
626
p ("JMP (R10)" )
607
627
}
608
628
609
- func genWasm () {
629
+ func genWasm (g * gen ) {
630
+ p := g .p
610
631
p ("// No async preemption on wasm" )
611
632
p ("UNDEF" )
612
633
}
613
634
614
- func notImplemented () {
635
+ func notImplemented (g * gen ) {
636
+ p := g .p
615
637
p ("// Not implemented yet" )
616
638
p ("JMP ·abort(SB)" )
617
639
}
0 commit comments