-
Notifications
You must be signed in to change notification settings - Fork 0
/
go.go
478 lines (350 loc) · 11.6 KB
/
go.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
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package gc
import (
"bufio"
"cmd/compile/internal/ssa"
"cmd/internal/bio"
"cmd/internal/obj"
)
const (
UINF = 100
BADWIDTH = -1000000000
MaxStackVarSize = 10 * 1024 * 1024
)
type Pkg struct {
Name string // package name, e.g. "sys"
Path string // string literal used in import statement, e.g. "runtime/internal/sys"
Pathsym *obj.LSym
Prefix string // escaped path for use in symbol table
Imported bool // export data of this package was parsed
Exported bool // import line written in export data
Direct bool // imported directly
Safe bool // whether the package is marked as safe
Syms map[string]*Sym
}
// Sym represents an object name. Most commonly, this is a Go identifier naming
// an object declared within a package, but Syms are also used to name internal
// synthesized objects.
//
// As a special exception, field and method names that are exported use the Sym
// associated with localpkg instead of the package that declared them. This
// allows using Sym pointer equality to test for Go identifier uniqueness when
// handling selector expressions.
type Sym struct {
Flags SymFlags
Link *Sym
Importdef *Pkg // where imported definition was found
Linkname string // link name
// saved and restored by dcopy
Pkg *Pkg
Name string // variable name
Def *Node // definition: ONAME OTYPE OPACK or OLITERAL
Block int32 // blocknumber to catch redeclaration
Lastlineno int32 // last declaration for diagnostic
Label *Label // corresponding label (ephemeral)
Origpkg *Pkg // original package for . import
Lsym *obj.LSym
Fsym *Sym // funcsym
}
type Label struct {
Sym *Sym
Def *Node
Use []*Node
// for use during gen
Gotopc *obj.Prog // pointer to unresolved gotos
Labelpc *obj.Prog // pointer to code
Breakpc *obj.Prog // pointer to code
Continpc *obj.Prog // pointer to code
Used bool
}
type SymFlags uint8
const (
SymExport SymFlags = 1 << iota // to be exported
SymPackage
SymExported // already written out by export
SymUniq
SymSiggen
SymAsm
SymAlgGen
)
// The Class of a variable/function describes the "storage class"
// of a variable or function. During parsing, storage classes are
// called declaration contexts.
type Class uint8
const (
Pxxx Class = iota
PEXTERN // global variable
PAUTO // local variables
PAUTOHEAP // local variable or parameter moved to heap
PPARAM // input arguments
PPARAMOUT // output results
PFUNC // global function
PDISCARD // discard during parse of duplicate import
)
// note this is the runtime representation
// of the compilers arrays.
//
// typedef struct
// { // must not move anything
// uchar array[8]; // pointer to data
// uchar nel[4]; // number of elements
// uchar cap[4]; // allocated number of elements
// } Array;
var Array_array int // runtime offsetof(Array,array) - same for String
var Array_nel int // runtime offsetof(Array,nel) - same for String
var Array_cap int // runtime offsetof(Array,cap)
var sizeof_Array int // runtime sizeof(Array)
// note this is the runtime representation
// of the compilers strings.
//
// typedef struct
// { // must not move anything
// uchar array[8]; // pointer to data
// uchar nel[4]; // number of elements
// } String;
var sizeof_String int // runtime sizeof(String)
var pragcgobuf string
var infile string
var outfile string
var linkobj string
var bout *bio.Writer
var nerrors int
var nsavederrors int
var nsyntaxerrors int
var decldepth int32
var safemode bool
var nolocalimports bool
var Debug [256]int
var debugstr string
var Debug_checknil int
var Debug_typeassert int
var localpkg *Pkg // package being compiled
var importpkg *Pkg // package being imported
var itabpkg *Pkg // fake pkg for itab entries
var itablinkpkg *Pkg // fake package for runtime itab entries
var Runtimepkg *Pkg // package runtime
var racepkg *Pkg // package runtime/race
var msanpkg *Pkg // package runtime/msan
var typepkg *Pkg // fake package for runtime type info (headers)
var unsafepkg *Pkg // package unsafe
var trackpkg *Pkg // fake package for field tracking
var mappkg *Pkg // fake package for map zero value
var zerosize int64
var Tptr EType // either TPTR32 or TPTR64
var myimportpath string
var localimport string
var asmhdr string
var Simtype [NTYPE]EType
var (
isforw [NTYPE]bool
Isint [NTYPE]bool
Isfloat [NTYPE]bool
Iscomplex [NTYPE]bool
issimple [NTYPE]bool
)
var (
okforeq [NTYPE]bool
okforadd [NTYPE]bool
okforand [NTYPE]bool
okfornone [NTYPE]bool
okforcmp [NTYPE]bool
okforbool [NTYPE]bool
okforcap [NTYPE]bool
okforlen [NTYPE]bool
okforarith [NTYPE]bool
okforconst [NTYPE]bool
)
var (
okfor [OEND][]bool
iscmp [OEND]bool
)
var Minintval [NTYPE]*Mpint
var Maxintval [NTYPE]*Mpint
var minfltval [NTYPE]*Mpflt
var maxfltval [NTYPE]*Mpflt
var xtop []*Node
var exportlist []*Node
var importlist []*Node // imported functions and methods with inlinable bodies
var funcsyms []*Node
var dclcontext Class // PEXTERN/PAUTO
var incannedimport int
var statuniqgen int // name generator for static temps
var iota_ int32
var lastconst []*Node
var lasttype *Node
var Maxarg int64
var Stksize int64 // stack size for current frame
var stkptrsize int64 // prefix of stack containing pointers
var hasdefer bool // flag that curfn has defer statement
var Curfn *Node
var Widthptr int
var Widthint int
var Widthreg int
var nblank *Node
var typecheckok bool
var compiling_runtime bool
var compiling_wrappers int
var use_writebarrier bool
var pure_go bool
var flag_installsuffix string
var flag_race bool
var flag_msan bool
var flag_largemodel bool
// Whether we are adding any sort of code instrumentation, such as
// when the race detector is enabled.
var instrumenting bool
var debuglive int
var Ctxt *obj.Link
var writearchive bool
var bstdout *bufio.Writer
var Nacl bool
var continpc *obj.Prog
var breakpc *obj.Prog
var Pc *obj.Prog
var nodfp *Node
var Disable_checknil int
// interface to back end
const (
// Pseudo-op, like TEXT, GLOBL, TYPE, PCDATA, FUNCDATA.
Pseudo = 1 << 1
// There's nothing to say about the instruction,
// but it's still okay to see.
OK = 1 << 2
// Size of right-side write, or right-side read if no write.
SizeB = 1 << 3
SizeW = 1 << 4
SizeL = 1 << 5
SizeQ = 1 << 6
SizeF = 1 << 7
SizeD = 1 << 8
// Left side (Prog.from): address taken, read, write.
LeftAddr = 1 << 9
LeftRead = 1 << 10
LeftWrite = 1 << 11
// Register in middle (Prog.reg); only ever read. (arm, ppc64)
RegRead = 1 << 12
CanRegRead = 1 << 13
// Right side (Prog.to): address taken, read, write.
RightAddr = 1 << 14
RightRead = 1 << 15
RightWrite = 1 << 16
// Instruction kinds
Move = 1 << 17 // straight move
Conv = 1 << 18 // size conversion
Cjmp = 1 << 19 // conditional jump
Break = 1 << 20 // breaks control flow (no fallthrough)
Call = 1 << 21 // function call
Jump = 1 << 22 // jump
Skip = 1 << 23 // data instruction
// Set, use, or kill of carry bit.
// Kill means we never look at the carry bit after this kind of instruction.
// Originally for understanding ADC, RCR, and so on, but now also
// tracks set, use, and kill of the zero and overflow bits as well.
// TODO rename to {Set,Use,Kill}Flags
SetCarry = 1 << 24
UseCarry = 1 << 25
KillCarry = 1 << 26
// Special cases for register use. (amd64, 386)
ShiftCX = 1 << 27 // possible shift by CX
ImulAXDX = 1 << 28 // possible multiply into DX:AX
// Instruction updates whichever of from/to is type D_OREG. (ppc64)
PostInc = 1 << 29
)
type Arch struct {
LinkArch *obj.LinkArch
REGSP int
REGCTXT int
REGCALLX int // BX
REGCALLX2 int // AX
REGRETURN int // AX
REGMIN int
REGMAX int
REGZERO int // architectural zero register, if available
FREGMIN int
FREGMAX int
MAXWIDTH int64
ReservedRegs []int
AddIndex func(*Node, int64, *Node) bool // optional
Betypeinit func()
Bgen_float func(*Node, bool, int, *obj.Prog) // optional
Cgen64 func(*Node, *Node) // only on 32-bit systems
Cgenindex func(*Node, *Node, bool) *obj.Prog
Cgen_bmul func(Op, *Node, *Node, *Node) bool
Cgen_float func(*Node, *Node) // optional
Cgen_hmul func(*Node, *Node, *Node)
RightShiftWithCarry func(*Node, uint, *Node) // only on systems without RROTC instruction
AddSetCarry func(*Node, *Node, *Node) // only on systems when ADD does not update carry flag
Cgen_shift func(Op, bool, *Node, *Node, *Node)
Clearfat func(*Node)
Cmp64 func(*Node, *Node, Op, int, *obj.Prog) // only on 32-bit systems
Defframe func(*obj.Prog)
Dodiv func(Op, *Node, *Node, *Node)
Excise func(*Flow)
Expandchecks func(*obj.Prog)
Getg func(*Node)
Gins func(obj.As, *Node, *Node) *obj.Prog
// Ginscmp generates code comparing n1 to n2 and jumping away if op is satisfied.
// The returned prog should be Patch'ed with the jump target.
// If op is not satisfied, code falls through to the next emitted instruction.
// Likely is the branch prediction hint: +1 for likely, -1 for unlikely, 0 for no opinion.
//
// Ginscmp must be able to handle all kinds of arguments for n1 and n2,
// not just simple registers, although it can assume that there are no
// function calls needed during the evaluation, and on 32-bit systems
// the values are guaranteed not to be 64-bit values, so no in-memory
// temporaries are necessary.
Ginscmp func(op Op, t *Type, n1, n2 *Node, likely int) *obj.Prog
// Ginsboolval inserts instructions to convert the result
// of a just-completed comparison to a boolean value.
// The first argument is the conditional jump instruction
// corresponding to the desired value.
// The second argument is the destination.
// If not present, Ginsboolval will be emulated with jumps.
Ginsboolval func(obj.As, *Node)
Ginscon func(obj.As, int64, *Node)
Ginsnop func()
Gmove func(*Node, *Node)
Igenindex func(*Node, *Node, bool) *obj.Prog
Peep func(*obj.Prog)
Proginfo func(*obj.Prog) // fills in Prog.Info
Regtyp func(*obj.Addr) bool
Sameaddr func(*obj.Addr, *obj.Addr) bool
Smallindir func(*obj.Addr, *obj.Addr) bool
Stackaddr func(*obj.Addr) bool
Blockcopy func(*Node, *Node, int64, int64, int64)
Sudoaddable func(obj.As, *Node, *obj.Addr) bool
Sudoclean func()
Excludedregs func() uint64
RtoB func(int) uint64
FtoB func(int) uint64
BtoR func(uint64) int
BtoF func(uint64) int
Optoas func(Op, *Type) obj.As
Doregbits func(int) uint64
Regnames func(*int) []string
Use387 bool // should 8g use 387 FP instructions instead of sse2.
// SSARegToReg maps ssa register numbers to obj register numbers.
SSARegToReg []int16
// SSAMarkMoves marks any MOVXconst ops that need to avoid clobbering flags.
SSAMarkMoves func(*SSAGenState, *ssa.Block)
// SSAGenValue emits Prog(s) for the Value.
SSAGenValue func(*SSAGenState, *ssa.Value)
// SSAGenBlock emits end-of-block Progs. SSAGenValue should be called
// for all values in the block before SSAGenBlock.
SSAGenBlock func(s *SSAGenState, b, next *ssa.Block)
}
var pcloc int32
var Thearch Arch
var Newproc *Node
var Deferproc *Node
var Deferreturn *Node
var Panicindex *Node
var panicslice *Node
var panicdivide *Node
var throwreturn *Node
var growslice *Node
var writebarrierptr *Node
var typedmemmove *Node
var panicdottype *Node