Permalink
Cannot retrieve contributors at this time
Fetching contributors…
| // 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 autopkg *Pkg // fake package for allocating auto variables | |
| 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 |