-
Notifications
You must be signed in to change notification settings - Fork 243
/
compiler.go
335 lines (329 loc) · 20.4 KB
/
compiler.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
package compiler
import (
"github.com/tetratelabs/wazero/internal/asm"
"github.com/tetratelabs/wazero/internal/wasm"
"github.com/tetratelabs/wazero/internal/wazeroir"
)
// compiler is the interface of architecture-specific native code compiler,
// and this is responsible for compiling native code for all wazeroir operations.
type compiler interface {
Init(functionType *wasm.FunctionType, ir *wazeroir.CompilationResult, withListener bool)
// String is for debugging purpose.
String() string
// compilePreamble is called before compiling any wazeroir operation.
// This is used, for example, to initialize the reserved registers, etc.
compilePreamble() error
// compile generates the native code into buf.
// stackPointerCeil is the max stack pointer that the target function would reach.
compile(buf asm.Buffer) (stackPointerCeil uint64, err error)
// compileGoHostFunction adds the trampoline code from which native code can jump into the Go-defined host function.
// TODO: maybe we wouldn't need to have trampoline for host functions.
compileGoDefinedHostFunction() error
// compileLabel notify compilers of the beginning of a label.
// Return true if the compiler decided to skip the entire label.
// See wazeroir.NewOperationLabel
compileLabel(o *wazeroir.UnionOperation) (skipThisLabel bool)
// compileUnreachable adds instruction to perform wazeroir.OperationUnreachable.
compileUnreachable() error
// compileSet adds instruction to perform wazeroir.OperationSet.
compileSet(o *wazeroir.UnionOperation) error
// compileGlobalGet adds instructions to perform wazeroir.OperationGlobalGet.
compileGlobalGet(o *wazeroir.UnionOperation) error
// compileGlobalSet adds instructions to perform wazeroir.OperationGlobalSet.
compileGlobalSet(o *wazeroir.UnionOperation) error
// compileBr adds instructions to perform wazeroir.NewOperationBr.
compileBr(o *wazeroir.UnionOperation) error
// compileBrIf adds instructions to perform wazeroir.NewOperationBrIf.
compileBrIf(o *wazeroir.UnionOperation) error
// compileBrTable adds instructions to perform wazeroir.NewOperationBrTable.
compileBrTable(o *wazeroir.UnionOperation) error
// compileCall adds instructions to perform wazeroir.OperationCall.
compileCall(o *wazeroir.UnionOperation) error
// compileCallIndirect adds instructions to perform wazeroir.OperationCallIndirect.
compileCallIndirect(o *wazeroir.UnionOperation) error
// compileDrop adds instructions to perform wazeroir.NewOperationDrop.
compileDrop(o *wazeroir.UnionOperation) error
// compileSelect adds instructions to perform wazeroir.OperationSelect.
compileSelect(o *wazeroir.UnionOperation) error
// compilePick adds instructions to perform wazeroir.OperationPick.
compilePick(o *wazeroir.UnionOperation) error
// compileAdd adds instructions to perform wazeroir.OperationAdd.
compileAdd(o *wazeroir.UnionOperation) error
// compileSub adds instructions to perform wazeroir.OperationSub.
compileSub(o *wazeroir.UnionOperation) error
// compileMul adds instructions to perform wazeroir.OperationMul.
compileMul(o *wazeroir.UnionOperation) error
// compileClz adds instructions to perform wazeroir.OperationClz.
compileClz(o *wazeroir.UnionOperation) error
// compileCtz adds instructions to perform wazeroir.OperationCtz.
compileCtz(o *wazeroir.UnionOperation) error
// compilePopcnt adds instructions to perform wazeroir.OperationPopcnt.
compilePopcnt(o *wazeroir.UnionOperation) error
// compileDiv adds instructions to perform wazeroir.OperationDiv.
compileDiv(o *wazeroir.UnionOperation) error
// compileRem adds instructions to perform wazeroir.OperationRem.
compileRem(o *wazeroir.UnionOperation) error
// compileAnd adds instructions to perform wazeroir.OperationAnd.
compileAnd(o *wazeroir.UnionOperation) error
// compileOr adds instructions to perform wazeroir.OperationOr.
compileOr(o *wazeroir.UnionOperation) error
// compileXor adds instructions to perform wazeroir.OperationXor.
compileXor(o *wazeroir.UnionOperation) error
// compileShl adds instructions to perform wazeroir.OperationShl.
compileShl(o *wazeroir.UnionOperation) error
// compileShr adds instructions to perform wazeroir.OperationShr.
compileShr(o *wazeroir.UnionOperation) error
// compileRotl adds instructions to perform wazeroir.OperationRotl.
compileRotl(o *wazeroir.UnionOperation) error
// compileRotr adds instructions to perform wazeroir.OperationRotr.
compileRotr(o *wazeroir.UnionOperation) error
// compileNeg adds instructions to perform wazeroir.OperationAbs.
compileAbs(o *wazeroir.UnionOperation) error
// compileNeg adds instructions to perform wazeroir.OperationNeg.
compileNeg(o *wazeroir.UnionOperation) error
// compileCeil adds instructions to perform wazeroir.OperationCeil.
compileCeil(o *wazeroir.UnionOperation) error
// compileFloor adds instructions to perform wazeroir.OperationFloor.
compileFloor(o *wazeroir.UnionOperation) error
// compileTrunc adds instructions to perform wazeroir.OperationTrunc.
compileTrunc(o *wazeroir.UnionOperation) error
// compileNearest adds instructions to perform wazeroir.OperationNearest.
compileNearest(o *wazeroir.UnionOperation) error
// compileSqrt adds instructions perform wazeroir.OperationSqrt.
compileSqrt(o *wazeroir.UnionOperation) error
// compileMin adds instructions perform wazeroir.OperationMin.
compileMin(o *wazeroir.UnionOperation) error
// compileMax adds instructions perform wazeroir.OperationMax.
compileMax(o *wazeroir.UnionOperation) error
// compileCopysign adds instructions to perform wazeroir.OperationCopysign.
compileCopysign(o *wazeroir.UnionOperation) error
// compileI32WrapFromI64 adds instructions to perform wazeroir.OperationI32WrapFromI64.
compileI32WrapFromI64() error
// compileITruncFromF adds instructions to perform wazeroir.NewOperationITruncFromF.
compileITruncFromF(o *wazeroir.UnionOperation) error
// compileFConvertFromI adds instructions to perform wazeroir.NewOperationFConvertFromI.
compileFConvertFromI(o *wazeroir.UnionOperation) error
// compileF32DemoteFromF64 adds instructions to perform wazeroir.OperationF32DemoteFromF64.
compileF32DemoteFromF64() error
// compileF64PromoteFromF32 adds instructions to perform wazeroir.OperationF64PromoteFromF32.
compileF64PromoteFromF32() error
// compileI32ReinterpretFromF32 adds instructions to perform wazeroir.OperationI32ReinterpretFromF32.
compileI32ReinterpretFromF32() error
// compileI64ReinterpretFromF64 adds instructions to perform wazeroir.OperationI64ReinterpretFromF64.
compileI64ReinterpretFromF64() error
// compileF32ReinterpretFromI32 adds instructions to perform wazeroir.OperationF32ReinterpretFromI32.
compileF32ReinterpretFromI32() error
// compileF64ReinterpretFromI64 adds instructions to perform wazeroir.OperationF64ReinterpretFromI64.
compileF64ReinterpretFromI64() error
// compileExtend adds instructions to perform wazeroir.NewOperationExtend.
compileExtend(o *wazeroir.UnionOperation) error
// compileEq adds instructions to perform wazeroir.OperationEq.
compileEq(o *wazeroir.UnionOperation) error
// compileEq adds instructions to perform wazeroir.OperationNe.
compileNe(o *wazeroir.UnionOperation) error
// compileEq adds instructions to perform wazeroir.OperationEqz.
compileEqz(o *wazeroir.UnionOperation) error
// compileLt adds instructions to perform wazeroir.OperationLt.
compileLt(o *wazeroir.UnionOperation) error
// compileGt adds instructions to perform wazeroir.OperationGt.
compileGt(o *wazeroir.UnionOperation) error
// compileLe adds instructions to perform wazeroir.OperationLe.
compileLe(o *wazeroir.UnionOperation) error
// compileLe adds instructions to perform wazeroir.OperationGe.
compileGe(o *wazeroir.UnionOperation) error
// compileLoad adds instructions to perform wazeroir.OperationLoad.
compileLoad(o *wazeroir.UnionOperation) error
// compileLoad8 adds instructions to perform wazeroir.OperationLoad8.
compileLoad8(o *wazeroir.UnionOperation) error
// compileLoad16 adds instructions to perform wazeroir.OperationLoad16.
compileLoad16(o *wazeroir.UnionOperation) error
// compileLoad32 adds instructions to perform wazeroir.OperationLoad32.
compileLoad32(o *wazeroir.UnionOperation) error
// compileStore adds instructions to perform wazeroir.OperationStore.
compileStore(o *wazeroir.UnionOperation) error
// compileStore8 adds instructions to perform wazeroir.OperationStore8.
compileStore8(o *wazeroir.UnionOperation) error
// compileStore16 adds instructions to perform wazeroir.OperationStore16.
compileStore16(o *wazeroir.UnionOperation) error
// compileStore32 adds instructions to perform wazeroir.OperationStore32.
compileStore32(o *wazeroir.UnionOperation) error
// compileMemorySize adds instruction to perform wazeroir.OperationMemoryGrow.
compileMemoryGrow() error
// compileMemorySize adds instruction to perform wazeroir.OperationMemorySize.
compileMemorySize() error
// compileConstI32 adds instruction to perform wazeroir.NewOperationConstI32.
compileConstI32(o *wazeroir.UnionOperation) error
// compileConstI64 adds instruction to perform wazeroir.NewOperationConstI64.
compileConstI64(o *wazeroir.UnionOperation) error
// compileConstF32 adds instruction to perform wazeroir.NewOperationConstF32.
compileConstF32(o *wazeroir.UnionOperation) error
// compileConstF64 adds instruction to perform wazeroir.NewOperationConstF64.
compileConstF64(o *wazeroir.UnionOperation) error
// compileSignExtend32From8 adds instructions to perform wazeroir.OperationSignExtend32From8.
compileSignExtend32From8() error
// compileSignExtend32From16 adds instructions to perform wazeroir.OperationSignExtend32From16.
compileSignExtend32From16() error
// compileSignExtend64From8 adds instructions to perform wazeroir.OperationSignExtend64From8.
compileSignExtend64From8() error
// compileSignExtend64From16 adds instructions to perform wazeroir.OperationSignExtend64From16.
compileSignExtend64From16() error
// compileSignExtend64From32 adds instructions to perform wazeroir.OperationSignExtend64From32.
compileSignExtend64From32() error
// compileMemoryInit adds instructions to perform wazeroir.NewOperationMemoryInit.
compileMemoryInit(*wazeroir.UnionOperation) error
// compileDataDrop adds instructions to perform wazeroir.NewOperationDataDrop.
compileDataDrop(*wazeroir.UnionOperation) error
// compileMemoryCopy adds instructions to perform wazeroir.OperationMemoryCopy.
compileMemoryCopy() error
// compileMemoryFill adds instructions to perform wazeroir.OperationMemoryFill.
compileMemoryFill() error
// compileTableInit adds instructions to perform wazeroir.NewOperationTableInit.
compileTableInit(*wazeroir.UnionOperation) error
// compileTableCopy adds instructions to perform wazeroir.NewOperationTableCopy.
compileTableCopy(*wazeroir.UnionOperation) error
// compileElemDrop adds instructions to perform wazeroir.NewOperationElemDrop.
compileElemDrop(*wazeroir.UnionOperation) error
// compileRefFunc adds instructions to perform wazeroir.NewOperationRefFunc.
compileRefFunc(*wazeroir.UnionOperation) error
// compileTableGet adds instructions to perform wazeroir.NewOperationTableGet.
compileTableGet(*wazeroir.UnionOperation) error
// compileTableSet adds instructions to perform wazeroir.NewOperationTableSet.
compileTableSet(*wazeroir.UnionOperation) error
// compileTableGrow adds instructions to perform wazeroir.NewOperationTableGrow.
compileTableGrow(*wazeroir.UnionOperation) error
// compileTableSize adds instructions to perform wazeroir.NewOperationTableSize.
compileTableSize(*wazeroir.UnionOperation) error
// compileTableFill adds instructions to perform wazeroir.NewOperationTableFill.
compileTableFill(*wazeroir.UnionOperation) error
// compileV128Const adds instructions to perform wazeroir.NewOperationV128Const.
compileV128Const(*wazeroir.UnionOperation) error
// compileV128Add adds instructions to perform wazeroir.OperationV128Add.
compileV128Add(o *wazeroir.UnionOperation) error
// compileV128Sub adds instructions to perform wazeroir.OperationV128Sub.
compileV128Sub(o *wazeroir.UnionOperation) error
// compileV128Load adds instructions to perform wazeroir.OperationV128Load.
compileV128Load(o *wazeroir.UnionOperation) error
// compileV128LoadLane adds instructions to perform wazeroir.OperationV128LoadLane.
compileV128LoadLane(o *wazeroir.UnionOperation) error
// compileV128Store adds instructions to perform wazeroir.NewOperationV128Store.
compileV128Store(o *wazeroir.UnionOperation) error
// compileV128StoreLane adds instructions to perform wazeroir.NewOperationV128StoreLane.
compileV128StoreLane(o *wazeroir.UnionOperation) error
// compileV128ExtractLane adds instructions to perform wazeroir.NewOperationV128ExtractLane.
compileV128ExtractLane(o *wazeroir.UnionOperation) error
// compileV128ReplaceLane adds instructions to perform wazeroir.NewOperationV128ReplaceLane.
compileV128ReplaceLane(o *wazeroir.UnionOperation) error
// compileV128Splat adds instructions to perform wazeroir.NewOperationV128Splat.
compileV128Splat(o *wazeroir.UnionOperation) error
// compileV128Shuffle adds instructions to perform wazeroir.NewOperationV128Shuffle.
compileV128Shuffle(o *wazeroir.UnionOperation) error
// compileV128Swizzle adds instructions to perform wazeroir.OperationV128Swizzle.
compileV128Swizzle(o *wazeroir.UnionOperation) error
// compileV128AnyTrue adds instructions to perform wazeroir.OperationV128AnyTrue.
compileV128AnyTrue(o *wazeroir.UnionOperation) error
// compileV128AllTrue adds instructions to perform wazeroir.NewOperationV128AllTrue.
compileV128AllTrue(o *wazeroir.UnionOperation) error
// compileV128BitMask adds instructions to perform wazeroir.NewOperationV128BitMask.
compileV128BitMask(*wazeroir.UnionOperation) error
// compileV128And adds instructions to perform wazeroir.OperationV128And.
compileV128And(*wazeroir.UnionOperation) error
// compileV128Not adds instructions to perform wazeroir.OperationV128Not.
compileV128Not(*wazeroir.UnionOperation) error
// compileV128Or adds instructions to perform wazeroir.OperationV128Or.
compileV128Or(*wazeroir.UnionOperation) error
// compileV128Xor adds instructions to perform wazeroir.OperationV128Xor.
compileV128Xor(*wazeroir.UnionOperation) error
// compileV128Bitselect adds instructions to perform wazeroir.OperationV128Bitselect.
compileV128Bitselect(*wazeroir.UnionOperation) error
// compileV128AndNot adds instructions to perform wazeroir.OperationV128AndNot.
compileV128AndNot(*wazeroir.UnionOperation) error
// compileV128Shr adds instructions to perform wazeroir.NewOperationV128Shr.
compileV128Shr(*wazeroir.UnionOperation) error
// compileV128Shl adds instructions to perform wazeroir.NewOperationV128Shl.
compileV128Shl(*wazeroir.UnionOperation) error
// compileV128Cmp adds instructions to perform wazeroir.NewOperationV128Cmp.
compileV128Cmp(*wazeroir.UnionOperation) error
// compileV128AddSat adds instructions to perform wazeroir.NewOperationV128AddSat.
compileV128AddSat(*wazeroir.UnionOperation) error
// compileV128SubSat adds instructions to perform wazeroir.NewOperationV128SubSat.
compileV128SubSat(*wazeroir.UnionOperation) error
// compileV128Mul adds instructions to perform wazeroir.NewOperationV128Mul.
compileV128Mul(*wazeroir.UnionOperation) error
// compileV128Div adds instructions to perform wazeroir.NewOperationV128Div.
compileV128Div(*wazeroir.UnionOperation) error
// compileV128Neg adds instructions to perform wazeroir.NewOperationV128Neg.
compileV128Neg(*wazeroir.UnionOperation) error
// compileV128Sqrt adds instructions to perform wazeroir.NewOperationV128Sqrt.
compileV128Sqrt(*wazeroir.UnionOperation) error
// compileV128Abs adds instructions to perform wazeroir.NewOperationV128Abs.
compileV128Abs(*wazeroir.UnionOperation) error
// compileV128Popcnt adds instructions to perform wazeroir.NewOperationV128Popcnt.
compileV128Popcnt(*wazeroir.UnionOperation) error
// compileV128Min adds instructions to perform wazeroir.NewOperationV128Min.
compileV128Min(*wazeroir.UnionOperation) error
// compileV128Max adds instructions to perform wazeroir.NewOperationV128Max.
compileV128Max(*wazeroir.UnionOperation) error
// compileV128AvgrU adds instructions to perform wazeroir.NewOperationV128AvgrU.
compileV128AvgrU(*wazeroir.UnionOperation) error
// compileV128Pmin adds instructions to perform wazeroir.NewOperationV128Pmin.
compileV128Pmin(*wazeroir.UnionOperation) error
// compileV128Pmax adds instructions to perform wazeroir.NewOperationV128Pmax.
compileV128Pmax(*wazeroir.UnionOperation) error
// compileV128Ceil adds instructions to perform wazeroir.NewOperationV128Ceil.
compileV128Ceil(*wazeroir.UnionOperation) error
// compileV128Floor adds instructions to perform wazeroir.NewOperationV128Floor.
compileV128Floor(*wazeroir.UnionOperation) error
// compileV128Trunc adds instructions to perform wazeroir.NewOperationV128Trunc.
compileV128Trunc(*wazeroir.UnionOperation) error
// compileV128Nearest adds instructions to perform wazeroir.NewOperationV128Nearest.
compileV128Nearest(*wazeroir.UnionOperation) error
// compileV128Extend adds instructions to perform wazeroir.NewOperationV128Extend.
compileV128Extend(*wazeroir.UnionOperation) error
// compileV128ExtMul adds instructions to perform wazeroir.NewOperationV128ExtMul.
compileV128ExtMul(*wazeroir.UnionOperation) error
// compileV128Q15mulrSatS adds instructions to perform wazeroir.OperationV128Q15mulrSatS.
compileV128Q15mulrSatS(*wazeroir.UnionOperation) error
// compileV128ExtAddPairwise adds instructions to perform wazeroir.NewOperationV128ExtAddPairwise.
compileV128ExtAddPairwise(o *wazeroir.UnionOperation) error
// compileV128FloatPromote adds instructions to perform wazeroir.OperationV128FloatPromote.
compileV128FloatPromote(o *wazeroir.UnionOperation) error
// compileV128FloatDemote adds instructions to perform wazeroir.OperationV128FloatDemote.
compileV128FloatDemote(o *wazeroir.UnionOperation) error
// compileV128FConvertFromI adds instructions to perform wazeroir.NewOperationV128FConvertFromI.
compileV128FConvertFromI(o *wazeroir.UnionOperation) error
// compileV128Dot adds instructions to perform wazeroir.OperationV128Dot.
compileV128Dot(o *wazeroir.UnionOperation) error
// compileV128Narrow adds instructions to perform wazeroir.NewOperationV128Narrow.
compileV128Narrow(o *wazeroir.UnionOperation) error
// compileV128ITruncSatFromF adds instructions to perform wazeroir.NewOperationV128ITruncSatFromF.
compileV128ITruncSatFromF(o *wazeroir.UnionOperation) error
// compileBuiltinFunctionCheckExitCode adds instructions to perform wazeroir.OperationBuiltinFunctionCheckExitCode.
compileBuiltinFunctionCheckExitCode() error
// compileReleaseRegisterToStack adds instructions to write the value on a register back to memory stack region.
compileReleaseRegisterToStack(loc *runtimeValueLocation)
// compileLoadValueOnStackToRegister adds instructions to load the value located on the stack to the assigned register.
compileLoadValueOnStackToRegister(loc *runtimeValueLocation)
// maybeCompileMoveTopConditionalToGeneralPurposeRegister moves the top value on the stack
// if the value is located on a conditional register.
//
// This is usually called at the beginning of methods on compiler interface where we possibly
// compile instructions without saving the conditional register value.
// The compileXXX functions without calling this function is saving the conditional
// value to the stack or register by invoking compileEnsureOnRegister for the top.
maybeCompileMoveTopConditionalToGeneralPurposeRegister() error
// allocateRegister returns an unused register of the given type. The register will be taken
// either from the free register pool or by stealing a used register.
//
// Note: resulting registers will not be marked as used so the call site should
// mark it used if necessary.
allocateRegister(t registerType) (reg asm.Register, err error)
// runtimeValueLocationStack returns the current runtimeValueLocationStack of the compiler implementation.
runtimeValueLocationStack() *runtimeValueLocationStack
// pushRuntimeValueLocationOnRegister pushes a new runtimeValueLocation on a register `reg` and of the type `vt`.
pushRuntimeValueLocationOnRegister(reg asm.Register, vt runtimeValueType) (ret *runtimeValueLocation)
// pushRuntimeValueLocationOnRegister pushes a new vector value's runtimeValueLocation on a register `reg`.
pushVectorRuntimeValueLocationOnRegister(reg asm.Register) (lowerBitsLocation *runtimeValueLocation)
// compileNOP compiles NOP instruction and returns the corresponding asm.Node in the assembled native code.
// This is used to emit DWARF based stack traces.
compileNOP() asm.Node
}