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