mirror of
https://github.com/golang/go.git
synced 2025-05-17 13:24:38 +00:00
Move 8-bit flags field after 32-bit Block field Change-Id: I8e5e9a2285477aac2402a839a105e710d5340224 Reviewed-on: https://go-review.googlesource.com/37848 Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
409 lines
9.4 KiB
Go
409 lines
9.4 KiB
Go
// 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 (
|
|
"cmd/compile/internal/ssa"
|
|
"cmd/internal/bio"
|
|
"cmd/internal/obj"
|
|
"cmd/internal/src"
|
|
)
|
|
|
|
const (
|
|
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
|
|
Direct bool // imported directly
|
|
Syms map[string]*Sym
|
|
}
|
|
|
|
// isRuntime reports whether p is package runtime.
|
|
func (p *Pkg) isRuntime() bool {
|
|
if compiling_runtime && p == localpkg {
|
|
return true
|
|
}
|
|
return p.Path == "runtime"
|
|
}
|
|
|
|
// 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 an 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 {
|
|
Link *Sym
|
|
Importdef *Pkg // where imported definition was found
|
|
Linkname string // link name
|
|
|
|
// saved and restored by dcopy
|
|
Pkg *Pkg
|
|
Name string // object name
|
|
Def *Node // definition: ONAME OTYPE OPACK or OLITERAL
|
|
Lastlineno src.XPos // last declaration for diagnostic
|
|
Block int32 // blocknumber to catch redeclaration
|
|
|
|
flags bitset8
|
|
Label *Node // corresponding label (ephemeral)
|
|
Origpkg *Pkg // original package for . import
|
|
Lsym *obj.LSym
|
|
Fsym *Sym // funcsym
|
|
}
|
|
|
|
const (
|
|
symExport = 1 << iota // to be exported
|
|
symPackage
|
|
symExported // already written out by export
|
|
symUniq
|
|
symSiggen
|
|
symAsm
|
|
symAlgGen
|
|
)
|
|
|
|
func (sym *Sym) Export() bool { return sym.flags&symExport != 0 }
|
|
func (sym *Sym) Package() bool { return sym.flags&symPackage != 0 }
|
|
func (sym *Sym) Exported() bool { return sym.flags&symExported != 0 }
|
|
func (sym *Sym) Uniq() bool { return sym.flags&symUniq != 0 }
|
|
func (sym *Sym) Siggen() bool { return sym.flags&symSiggen != 0 }
|
|
func (sym *Sym) Asm() bool { return sym.flags&symAsm != 0 }
|
|
func (sym *Sym) AlgGen() bool { return sym.flags&symAlgGen != 0 }
|
|
|
|
func (sym *Sym) SetExport(b bool) { sym.flags.set(symExport, b) }
|
|
func (sym *Sym) SetPackage(b bool) { sym.flags.set(symPackage, b) }
|
|
func (sym *Sym) SetExported(b bool) { sym.flags.set(symExported, b) }
|
|
func (sym *Sym) SetUniq(b bool) { sym.flags.set(symUniq, b) }
|
|
func (sym *Sym) SetSiggen(b bool) { sym.flags.set(symSiggen, b) }
|
|
func (sym *Sym) SetAsm(b bool) { sym.flags.set(symAsm, b) }
|
|
func (sym *Sym) SetAlgGen(b bool) { sym.flags.set(symAlgGen, b) }
|
|
|
|
func (sym *Sym) isAlias() bool {
|
|
return sym.Def != nil && sym.Def.Sym != sym
|
|
}
|
|
|
|
// 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 outfile string
|
|
var linkobj string
|
|
var dolinkobj bool
|
|
|
|
var bout *bio.Writer
|
|
|
|
// nerrors is the number of compiler errors reported
|
|
// since the last call to saveerrors.
|
|
var nerrors int
|
|
|
|
// nsavederrors is the total number of compiler errors
|
|
// reported before the last call to saveerrors.
|
|
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 // fake 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 statuniqgen int // name generator for static temps
|
|
|
|
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 Nacl bool
|
|
|
|
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
|
|
|
|
// Optional 3rd input operand, only ever read.
|
|
From3Read = 1 << 30
|
|
)
|
|
|
|
type Arch struct {
|
|
LinkArch *obj.LinkArch
|
|
|
|
REGSP int
|
|
MAXWIDTH int64
|
|
|
|
Defframe func(*obj.Prog)
|
|
Proginfo func(*obj.Prog) ProgInfo
|
|
Use387 bool // should 8g use 387 FP instructions instead of sse2.
|
|
|
|
// 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 (
|
|
staticbytes,
|
|
zerobase *Node
|
|
|
|
Newproc,
|
|
Deferproc,
|
|
Deferreturn,
|
|
Duffcopy,
|
|
Duffzero,
|
|
panicindex,
|
|
panicslice,
|
|
panicdivide,
|
|
growslice,
|
|
panicdottypeE,
|
|
panicdottypeI,
|
|
panicnildottype,
|
|
assertE2I,
|
|
assertE2I2,
|
|
assertI2I,
|
|
assertI2I2 *obj.LSym
|
|
)
|