...

Source file src/github.com/twitchyliquid64/golang-asm/builder.go

Documentation: github.com/twitchyliquid64/golang-asm

     1  package golangasm
     2  
     3  import (
     4  	"fmt"
     5  
     6  	"github.com/twitchyliquid64/golang-asm/asm/arch"
     7  	"github.com/twitchyliquid64/golang-asm/obj"
     8  	"github.com/twitchyliquid64/golang-asm/objabi"
     9  )
    10  
    11  // Builder allows you to assemble a series of instructions.
    12  type Builder struct {
    13  	ctxt *obj.Link
    14  	arch *arch.Arch
    15  
    16  	first *obj.Prog
    17  	last  *obj.Prog
    18  
    19  	// bulk allocator.
    20  	block *[]obj.Prog
    21  	used  int
    22  }
    23  
    24  // Root returns the first instruction.
    25  func (b *Builder) Root() *obj.Prog {
    26  	return b.first
    27  }
    28  
    29  // NewProg returns a new instruction structure.
    30  func (b *Builder) NewProg() *obj.Prog {
    31  	return b.progAlloc()
    32  }
    33  
    34  func (b *Builder) progAlloc() *obj.Prog {
    35  	var p *obj.Prog
    36  
    37  	if b.used >= len(*b.block) {
    38  		p = b.ctxt.NewProg()
    39  	} else {
    40  		p = &(*b.block)[b.used]
    41  		b.used++
    42  	}
    43  
    44  	p.Ctxt = b.ctxt
    45  	return p
    46  }
    47  
    48  // AddInstruction adds an instruction to the list of instructions
    49  // to be assembled.
    50  func (b *Builder) AddInstruction(p *obj.Prog) {
    51  	if b.first == nil {
    52  		b.first = p
    53  		b.last = p
    54  	} else {
    55  		b.last.Link = p
    56  		b.last = p
    57  	}
    58  }
    59  
    60  // Assemble generates the machine code from the given instructions.
    61  func (b *Builder) Assemble() []byte {
    62  	s := &obj.LSym{
    63  		Func: &obj.FuncInfo{
    64  			Text: b.first,
    65  		},
    66  	}
    67  	b.arch.Assemble(b.ctxt, s, b.progAlloc)
    68  	return s.P
    69  }
    70  
    71  // NewBuilder constructs an assembler for the given architecture.
    72  func NewBuilder(archStr string, cacheSize int) (*Builder, error) {
    73  	a := arch.Set(archStr)
    74  	ctxt := obj.Linknew(a.LinkArch)
    75  	ctxt.Headtype = objabi.Hlinux
    76  	ctxt.DiagFunc = func(in string, args ...interface{}) {
    77  		fmt.Printf(in+"\n", args...)
    78  	}
    79  	a.Init(ctxt)
    80  
    81  	block := make([]obj.Prog, cacheSize)
    82  
    83  	return &Builder{
    84  		ctxt:  ctxt,
    85  		arch:  a,
    86  		block: &block,
    87  	}, nil
    88  }
    89  

View as plain text