emitter.mx raw

   1  package emit
   2  
   3  import (
   4  	"git.smesh.lol/moxie/pkg/syntax"
   5  	"git.smesh.lol/moxie/pkg/ssa"
   6  	"git.smesh.lol/moxie/pkg/types"
   7  )
   8  
   9  var parseErrors []string
  10  var compileErrors []string
  11  var genericFuncDecls map[string]*syntax.FuncDecl
  12  var genericPkgScopes map[string]*types.Scope
  13  
  14  type irEmitter struct {
  15  	buf        []byte
  16  	triple     string
  17  	ptrBits    int32
  18  	pkg        *ssa.SSAPackage
  19  	valName    map[ssa.SSAValue]string
  20  	nextReg    int32
  21  	extDecls   map[string]string
  22  	extGlobals map[string]string
  23  	strConst   []string
  24  	strMap     map[string]int32
  25  	curFunc    *ssa.SSAFunction
  26  	typeIDs      map[string]int32
  27  	typeIDNext   int32
  28  	extTypeIDs   map[string]bool
  29  	localTypeIDs map[string]bool
  30  	allocTypes map[ssa.SSAValue]string
  31  	regTypes   map[string]string
  32  	hoisted    map[ssa.SSAValue]bool
  33  	blockExitLabel map[int32]string
  34  	nameUsed   map[string]bool
  35  	missingStores map[ssa.SSAValue]ssa.SSAValue
  36  	globalTypes     map[string]string
  37  	globalDeclTypes map[string]string
  38  	sortedMembers   []ssa.SSAMember
  39  	loadToGlobal    map[string]*ssa.SSAGlobal
  40  	allocBlock      map[ssa.SSAValue]int32
  41  	storedTo        map[string]bool
  42  	usedAs          map[string]bool
  43  	deferList  []*ssa.SSADefer
  44  	deferID    int32
  45  	deallocActive bool
  46  	deallocAllocs map[ssa.SSAValue]int32
  47  	deallocCount  int32
  48  	scopeAllocs map[int32][]string
  49  	instrScope  map[ssa.SSAInstruction]int32
  50  	scopeActive bool
  51  }
  52  
  53  func sortedKeys(m map[string]bool) []string {
  54  	var keys []string
  55  	for k := range m {
  56  		keys = append(keys, k)
  57  	}
  58  	for i := 1; i < len(keys); i++ {
  59  		for j := i; j > 0 && keys[j] < keys[j-1]; j-- {
  60  			keys[j], keys[j-1] = keys[j-1], keys[j]
  61  		}
  62  	}
  63  	return keys
  64  }
  65  
  66  func newIREmitter(pkg *ssa.SSAPackage, triple string) *irEmitter {
  67  	ptrBits := 64
  68  	if len(triple) >= 4 && triple[:4] == "wasm" {
  69  		ptrBits = 32
  70  	}
  71  	return &irEmitter{
  72  		buf:      []byte{:0:4096},
  73  		triple:   triple,
  74  		ptrBits:  ptrBits,
  75  		pkg:      pkg,
  76  		valName:  map[ssa.SSAValue]string{},
  77  		extDecls:   map[string]string{},
  78  		extGlobals: map[string]string{},
  79  		strMap:     map[string]int32{},
  80  		allocTypes: map[ssa.SSAValue]string{},
  81  		regTypes:   map[string]string{},
  82  		blockExitLabel: map[int32]string{},
  83  		nameUsed:   map[string]bool{},
  84  	}
  85  }
  86  
  87  func (e *irEmitter) dataLayout() string {
  88  	if len(e.triple) >= 6 && e.triple[:6] == "x86_64" {
  89  		return "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128"
  90  	}
  91  	if len(e.triple) >= 7 && e.triple[:7] == "aarch64" {
  92  		return "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128"
  93  	}
  94  	if len(e.triple) >= 6 && e.triple[:6] == "wasm32" {
  95  		return "e-m:e-p:32:32-p10:8:8-p20:8:8-i64:64-n32:64-S128-ni:1:10:20"
  96  	}
  97  	if len(e.triple) >= 3 && e.triple[:3] == "arm" {
  98  		return "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64"
  99  	}
 100  	return ""
 101  }
 102  
 103  func (e *irEmitter) w(s string) {
 104  	e.buf = append(e.buf, s...)
 105  }
 106