type Op … type opInfo … type inputInfo … type outputInfo … type regInfo … func (r *regInfo) String() string { … } type auxType … type AuxNameOffset … func (a *AuxNameOffset) CanBeAnSSAAux() { … } func (a *AuxNameOffset) String() string { … } func (a *AuxNameOffset) FrameOffset() int64 { … } type AuxCall … // Reg returns the regInfo for a given call, combining the derived in/out register masks // with the machine-specific register information in the input i. (The machine-specific // regInfo is much handier at the call site than it is when the AuxCall is being constructed, // therefore do this lazily). // // TODO: there is a Clever Hack that allows pre-generation of a small-ish number of the slices // of inputInfo and outputInfo used here, provided that we are willing to reorder the inputs // and outputs from calls, so that all integer registers come first, then all floating registers. // At this point (active development of register ABI) that is very premature, // but if this turns out to be a cost, we could do it. func (a *AuxCall) Reg(i *regInfo, c *Config) *regInfo { … } func (a *AuxCall) ABI() *abi.ABIConfig { … } func (a *AuxCall) ABIInfo() *abi.ABIParamResultInfo { … } func (a *AuxCall) ResultReg(c *Config) *regInfo { … } // For ABI register index r, returns the (dense) register number used in // SSA backend. func archRegForAbiReg(r abi.RegIndex, c *Config) uint8 { … } // For ABI register index r, returns the register number used in the obj // package (assembler). func ObjRegForAbiReg(r abi.RegIndex, c *Config) int16 { … } // ArgWidth returns the amount of stack needed for all the inputs // and outputs of a function or method, including ABI-defined parameter // slots and ABI-defined spill slots for register-resident parameters. // // The name is taken from the types package's ArgWidth(<function type>), // which predated changes to the ABI; this version handles those changes. func (a *AuxCall) ArgWidth() int64 { … } // ParamAssignmentForResult returns the ABI Parameter assignment for result which (indexed 0, 1, etc). func (a *AuxCall) ParamAssignmentForResult(which int64) *abi.ABIParamAssignment { … } // OffsetOfResult returns the SP offset of result which (indexed 0, 1, etc). func (a *AuxCall) OffsetOfResult(which int64) int64 { … } // OffsetOfArg returns the SP offset of argument which (indexed 0, 1, etc). // If the call is to a method, the receiver is the first argument (i.e., index 0) func (a *AuxCall) OffsetOfArg(which int64) int64 { … } // RegsOfResult returns the register(s) used for result which (indexed 0, 1, etc). func (a *AuxCall) RegsOfResult(which int64) []abi.RegIndex { … } // RegsOfArg returns the register(s) used for argument which (indexed 0, 1, etc). // If the call is to a method, the receiver is the first argument (i.e., index 0) func (a *AuxCall) RegsOfArg(which int64) []abi.RegIndex { … } // NameOfResult returns the ir.Name of result which (indexed 0, 1, etc). func (a *AuxCall) NameOfResult(which int64) *ir.Name { … } // TypeOfResult returns the type of result which (indexed 0, 1, etc). func (a *AuxCall) TypeOfResult(which int64) *types.Type { … } // TypeOfArg returns the type of argument which (indexed 0, 1, etc). // If the call is to a method, the receiver is the first argument (i.e., index 0) func (a *AuxCall) TypeOfArg(which int64) *types.Type { … } // SizeOfResult returns the size of result which (indexed 0, 1, etc). func (a *AuxCall) SizeOfResult(which int64) int64 { … } // SizeOfArg returns the size of argument which (indexed 0, 1, etc). // If the call is to a method, the receiver is the first argument (i.e., index 0) func (a *AuxCall) SizeOfArg(which int64) int64 { … } // NResults returns the number of results. func (a *AuxCall) NResults() int64 { … } // LateExpansionResultType returns the result type (including trailing mem) // for a call that will be expanded later in the SSA phase. func (a *AuxCall) LateExpansionResultType() *types.Type { … } // NArgs returns the number of arguments (including receiver, if there is one). func (a *AuxCall) NArgs() int64 { … } // String returns "AuxCall{<fn>}" func (a *AuxCall) String() string { … } // StaticAuxCall returns an AuxCall for a static call. func StaticAuxCall(sym *obj.LSym, paramResultInfo *abi.ABIParamResultInfo) *AuxCall { … } // InterfaceAuxCall returns an AuxCall for an interface call. func InterfaceAuxCall(paramResultInfo *abi.ABIParamResultInfo) *AuxCall { … } // ClosureAuxCall returns an AuxCall for a closure call. func ClosureAuxCall(paramResultInfo *abi.ABIParamResultInfo) *AuxCall { … } func (*AuxCall) CanBeAnSSAAux() { … } // OwnAuxCall returns a function's own AuxCall. func OwnAuxCall(fn *obj.LSym, paramResultInfo *abi.ABIParamResultInfo) *AuxCall { … } const auxNone … const auxBool … const auxInt8 … const auxInt16 … const auxInt32 … const auxInt64 … const auxInt128 … const auxUInt8 … const auxFloat32 … const auxFloat64 … const auxFlagConstant … const auxCCop … const auxNameOffsetInt8 … const auxString … const auxSym … const auxSymOff … const auxSymValAndOff … const auxTyp … const auxTypSize … const auxCall … const auxCallOff … const auxARM64BitField … const auxS390XRotateParams … const auxS390XCCMask … const auxS390XCCMaskInt8 … const auxS390XCCMaskUint8 … type SymEffect … const SymRead … const SymWrite … const SymAddr … const SymRdWr … const SymNone … type Sym … type ValAndOff … func (x ValAndOff) Val() int32 { … } func (x ValAndOff) Val64() int64 { … } func (x ValAndOff) Val16() int16 { … } func (x ValAndOff) Val8() int8 { … } func (x ValAndOff) Off64() int64 { … } func (x ValAndOff) Off() int32 { … } func (x ValAndOff) String() string { … } // validVal reports whether the value can be used // as an argument to makeValAndOff. func validVal(val int64) bool { … } func makeValAndOff(val, off int32) ValAndOff { … } func (x ValAndOff) canAdd32(off int32) bool { … } func (x ValAndOff) canAdd64(off int64) bool { … } func (x ValAndOff) addOffset32(off int32) ValAndOff { … } func (x ValAndOff) addOffset64(off int64) ValAndOff { … } type int128 … type BoundsKind … const BoundsIndex … const BoundsIndexU … const BoundsSliceAlen … const BoundsSliceAlenU … const BoundsSliceAcap … const BoundsSliceAcapU … const BoundsSliceB … const BoundsSliceBU … const BoundsSlice3Alen … const BoundsSlice3AlenU … const BoundsSlice3Acap … const BoundsSlice3AcapU … const BoundsSlice3B … const BoundsSlice3BU … const BoundsSlice3C … const BoundsSlice3CU … const BoundsConvert … const BoundsKindCount … // boundsABI determines which register arguments a bounds check call should use. For an [a:b:c] slice, we do: // // CMPQ c, cap // JA fail1 // CMPQ b, c // JA fail2 // CMPQ a, b // JA fail3 // // fail1: CALL panicSlice3Acap (c, cap) // fail2: CALL panicSlice3B (b, c) // fail3: CALL panicSlice3C (a, b) // // When we register allocate that code, we want the same register to be used for // the first arg of panicSlice3Acap and the second arg to panicSlice3B. That way, // initializing that register once will satisfy both calls. // That desire ends up dividing the set of bounds check calls into 3 sets. This function // determines which set to use for a given panic call. // The first arg for set 0 should be the second arg for set 1. // The first arg for set 1 should be the second arg for set 2. func boundsABI(b int64) int { … } type arm64BitField …