File tree Expand file tree Collapse file tree
Expand file tree Collapse file tree Original file line number Diff line number Diff line change @@ -133,6 +133,11 @@ func (c *Context) Label(name string) {
133133 c .activefunc ().AddLabel (ir .Label (name ))
134134}
135135
136+ // Comment adds comment lines to the active function.
137+ func (c * Context ) Comment (lines ... string ) {
138+ c .activefunc ().AddComment (lines ... )
139+ }
140+
136141func (c * Context ) activefunc () * ir.Function {
137142 if c .function == nil {
138143 c .adderrormessage ("no active function" )
Original file line number Diff line number Diff line change @@ -125,5 +125,8 @@ func AllocLocal(size int) operand.Mem { return ctx.AllocLocal(size) }
125125// Label adds a label to the active function.
126126func Label (name string ) { ctx .Label (name ) }
127127
128+ // Comment adds comment lines to the active function.
129+ func Comment (lines ... string ) { ctx .Comment (lines ... ) }
130+
128131// ConstData builds a static data section containing just the given constant.
129132func ConstData (name string , v operand.Constant ) operand.Mem { return ctx .ConstData (name , v ) }
Original file line number Diff line number Diff line change @@ -20,6 +20,20 @@ type Label string
2020
2121func (l Label ) node () {}
2222
23+ // Comment represents a multi-line comment.
24+ type Comment struct {
25+ Lines []string
26+ }
27+
28+ func (c * Comment ) node () {}
29+
30+ // NewComment builds a Comment consisting of the provided lines.
31+ func NewComment (lines ... string ) * Comment {
32+ return & Comment {
33+ Lines : lines ,
34+ }
35+ }
36+
2337// Instruction is a single instruction in a function.
2438type Instruction struct {
2539 Opcode string
@@ -176,6 +190,11 @@ func (f *Function) AddLabel(l Label) {
176190 f .AddNode (l )
177191}
178192
193+ // AddComment adds comment lines to f.
194+ func (f * Function ) AddComment (lines ... string ) {
195+ f .AddNode (NewComment (lines ... ))
196+ }
197+
179198// AddNode appends a Node to f.
180199func (f * Function ) AddNode (n Node ) {
181200 f .Nodes = append (f .Nodes , n )
Original file line number Diff line number Diff line change @@ -11,27 +11,27 @@ import (
1111// label name to the following instruction.
1212func LabelTarget (fn * ir.Function ) error {
1313 target := map [ir.Label ]* ir.Instruction {}
14- for idx := 0 ; idx < len (fn .Nodes ); idx ++ {
15- // Is this a label?
16- lbl , ok := fn .Nodes [idx ].(ir.Label )
17- if ! ok {
18- continue
19- }
20- // Check for a duplicate label.
21- if _ , found := target [lbl ]; found {
22- return fmt .Errorf ("duplicate label \" %s\" " , lbl )
23- }
24- // Advance to next node.
25- if idx == len (fn .Nodes )- 1 {
26- return errors .New ("function ends with label" )
27- }
28- idx ++
29- // Should be an instruction.
30- i , ok := fn .Nodes [idx ].(* ir.Instruction )
31- if ! ok {
32- return errors .New ("instruction should follow a label" )
14+ var empty ir.Label
15+ pending := empty
16+ for _ , node := range fn .Nodes {
17+ switch n := node .(type ) {
18+ case ir.Label :
19+ if pending != empty {
20+ return errors .New ("instruction should follow a label" )
21+ }
22+ pending = n
23+ if _ , found := target [pending ]; found {
24+ return fmt .Errorf ("duplicate label \" %s\" " , pending )
25+ }
26+ case * ir.Instruction :
27+ if pending != empty {
28+ target [pending ] = n
29+ pending = empty
30+ }
3331 }
34- target [lbl ] = i
32+ }
33+ if pending != empty {
34+ return errors .New ("function ends with label" )
3535 }
3636 fn .LabelTarget = target
3737 return nil
Original file line number Diff line number Diff line change @@ -18,6 +18,7 @@ func TestLabelTarget(t *testing.T) {
1818 f := ir .NewFunction ("happypath" )
1919 for lbl , i := range expect {
2020 f .AddLabel (lbl )
21+ f .AddComment ("comments should be ignored" )
2122 f .AddInstruction (i )
2223 f .AddInstruction (& ir.Instruction {Opcode : "IDK" })
2324 }
Original file line number Diff line number Diff line change @@ -84,6 +84,15 @@ func (p *goasm) function(f *ir.Function) {
8484 p .Printf (", %s\n " , textsize (f ))
8585
8686 w := p .tabwriter ()
87+ clear := true
88+ flush := func () {
89+ w .Flush ()
90+ w = p .tabwriter ()
91+ if ! clear {
92+ p .NL ()
93+ clear = true
94+ }
95+ }
8796 for _ , node := range f .Nodes {
8897 switch n := node .(type ) {
8998 case * ir.Instruction :
@@ -93,10 +102,15 @@ func (p *goasm) function(f *ir.Function) {
93102 fmt .Fprintf (w , "\t %s" , joinOperands (n .Operands ))
94103 }
95104 fmt .Fprint (w , "\n " )
105+ clear = false
96106 case ir.Label :
97- w .Flush ()
98- w = p .tabwriter ()
99- p .Printf ("\n %s:\n " , n )
107+ flush ()
108+ p .Printf ("%s:\n " , n )
109+ case * ir.Comment :
110+ flush ()
111+ for _ , line := range n .Lines {
112+ p .Printf ("\t // %s\n " , line )
113+ }
100114 default :
101115 panic ("unexpected node type" )
102116 }
Original file line number Diff line number Diff line change 1+ // +build ignore
2+
3+ package main
4+
5+ import (
6+ . "github.com/mmcloughlin/avo/build"
7+ . "github.com/mmcloughlin/avo/reg"
8+ )
9+
10+ func main () {
11+ TEXT ("Formatting" , NOSPLIT , "func()" )
12+ Doc ("Formatting contains various cases to test the formatter." )
13+
14+ ADDQ (R8 , R8 )
15+ Comment ("One comment line between instructions." )
16+ ADDQ (R8 , R8 )
17+
18+ Comment ("Comment before label." )
19+ Label ("label" )
20+ Comment ("Comment after label." )
21+ ADDQ (R8 , R8 )
22+
23+ RET ()
24+
25+ Generate ()
26+ }
Original file line number Diff line number Diff line change 1+ // Code generated by command: go run asm.go -out fmt.s -stubs stub.go. DO NOT EDIT.
2+
3+ #include "textflag.h"
4+
5+ // func Formatting()
6+ TEXT ·Formatting(SB), NOSPLIT, $0
7+ ADDQ R8, R8
8+
9+ // One comment line between instructions.
10+ ADDQ R8, R8
11+
12+ // Comment before label.
13+ label:
14+ // Comment after label.
15+ ADDQ R8, R8
16+ RET
Original file line number Diff line number Diff line change 1+ // Package fmt tests assembly printer formatting.
2+ package fmt
3+
4+ //go:generate go run asm.go -out fmt.s -stubs stub.go
You can’t perform that action at this time.
0 commit comments