Source file src/cmd/compile/internal/ssa/ssaop/op.go
1 // Copyright 2015 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package ssaop 6 7 import ( 8 "fmt" 9 "strings" 10 11 "cmd/internal/obj" 12 ) 13 14 type AuxType int8 15 16 const ( 17 AuxTypeNone AuxType = iota 18 AuxTypeBool // auxInt is 0/1 for false/true 19 AuxTypeInt8 // auxInt is an 8-bit integer 20 AuxTypeInt16 // auxInt is a 16-bit integer 21 AuxTypeInt32 // auxInt is a 32-bit integer 22 AuxTypeInt64 // auxInt is a 64-bit integer 23 AuxTypeInt128 // auxInt represents a 128-bit integer. Always 0. 24 AuxTypeUInt8 // auxInt is an 8-bit unsigned integer 25 AuxTypeFloat32 // auxInt is a float32 (encoded with math.Float64bits) 26 AuxTypeFloat64 // auxInt is a float64 (encoded with math.Float64bits) 27 AuxTypeFlagConstant // auxInt is a flagConstant 28 AuxTypeCCop // auxInt is a ssa.Op that represents a flags-to-bool conversion (e.g. LessThan) 29 AuxTypeNameOffsetInt8 // aux is a &struct{Name ir.Name, Offset int64}; auxInt is index in parameter registers array 30 AuxTypeString // aux is a string 31 AuxTypeSym // aux is a symbol (a *ir.Name for locals, an *obj.LSym for globals, or nil for none) 32 AuxTypeSymOff // aux is a symbol, auxInt is an offset 33 AuxTypeSymValAndOff // aux is a symbol, auxInt is a ValAndOff 34 AuxTypeTyp // aux is a type 35 AuxTypeTypSize // aux is a type, auxInt is a size, must have Aux.(Type).Size() == AuxInt 36 AuxTypeCall // aux is a *ssa.AuxCall 37 AuxTypeCallOff // aux is a *ssa.AuxCall, AuxInt is int64 param (in+out) size 38 39 AuxTypePanicBoundsC // constant for a bounds failure 40 AuxTypePanicBoundsCC // two constants for a bounds failure 41 42 // architecture specific aux types 43 AuxTypeARM64BitField // aux is an arm64 bitfield lsb and width packed into auxInt 44 AuxTypeARM64ConditionalParams // aux is a structure, which contains condition, NZCV flags and constant with indicator of using it 45 AuxTypeS390XRotateParams // aux is a s390x rotate parameters object encoding start bit, end bit and rotate amount 46 AuxTypeS390XCCMask // aux is a s390x 4-bit condition code mask 47 AuxTypeS390XCCMaskInt8 // aux is a s390x 4-bit condition code mask, auxInt is an int8 immediate 48 AuxTypeS390XCCMaskUint8 // aux is a s390x 4-bit condition code mask, auxInt is a uint8 immediate 49 AuxTypeSizeAndAlign // auxInt is an int64 size, aux is an int64 alignment 50 ) 51 52 // An Op encodes the specific operation that a Value performs. 53 // Opcodes' semantics can be modified by the type and aux fields of the Value. 54 // For instance, OpAdd can be 32 or 64 bit, signed or unsigned, float or complex, depending on Value.Type. 55 // Semantics of each op are described in the opcode files in _gen/*Ops.go. 56 // There is one file for generic (architecture-independent) ops and one file 57 // for each architecture. 58 type Op int32 59 60 type OpInfo struct { 61 Name string 62 Reg RegInfo 63 AuxType AuxType 64 ArgLen int32 // the number of arguments, -1 if variable length 65 asm obj.As 66 Generic bool // this is a generic (arch-independent) opcode 67 Rematerializeable bool // this op is rematerializeable 68 Commutative bool // this operation is commutative (e.g. addition) 69 ResultInArg0 bool // (first, if a tuple) output of v and v.Args[0] must be allocated to the same register 70 ResultNotInArgs bool // outputs must not be allocated to the same registers as inputs 71 ClobberFlags bool // this op clobbers flags register 72 NeedIntTemp bool // need a temporary free integer register 73 Call bool // is a function call 74 tailCall bool // is a tail call 75 NilCheck bool // this op is a nil check on arg0 76 FaultOnNilArg0 bool // this op will fault if arg0 is nil (and aux encodes a small offset) 77 FaultOnNilArg1 bool // this op will fault if arg1 is nil (and aux encodes a small offset) 78 usesScratch bool // this op requires scratch memory space 79 HasSideEffects bool // for "reasons", not to be eliminated. E.g., atomic store, #19182. 80 ZeroWidth bool // op never translates into any machine code. example: copy, which may sometimes translate to machine code, is not zero-width. 81 unsafePoint bool // this op is an unsafe point, i.e. not safe for async preemption 82 FixedReg bool // this op will be assigned a fixed register 83 EarlyOk bool // executing this op in an earlier block is ok 84 AddrSinkArg0 bool // the address in arg0 does not propagate to the result 85 AddrSinkArg1 bool // the address in arg1 does not propagate to the result 86 symEffect SymEffect // effect this op has on symbol in aux 87 scale uint8 // amd64/386 indexed load scale 88 ZeroUpperBits uint8 // the op writes a 64-bit GPR whose upper N bits are always zero (0, 32, 48 or 56); for a tuple op, this holds for every integer result 89 } 90 91 type OutputInfo struct { 92 Idx int // index in output tuple 93 Regs RegMask // allowed output registers 94 } 95 96 type RegInfo struct { 97 // Inputs encodes the register restrictions for an instruction's Inputs. 98 // Each entry specifies an allowed register set for a particular input. 99 // They are listed in the order in which regalloc should pick a register 100 // from the register set (most constrained first). 101 // Inputs which do not need registers are not listed. 102 Inputs []InputInfo 103 // Clobbers encodes the set of registers that are overwritten by 104 // the instruction (other than the output registers). 105 Clobbers RegMask 106 // Instruction clobbers the register containing input 0. 107 ClobbersArg0 bool 108 // Instruction clobbers the register containing input 1. 109 ClobbersArg1 bool 110 // Outputs is the same as inputs, but for the Outputs of the instruction. 111 Outputs []OutputInfo 112 } 113 114 // A SymEffect describes the effect that an SSA Value has on the variable 115 // identified by the symbol in its Aux field. 116 type SymEffect int8 117 118 const ( 119 SymRead SymEffect = 1 << iota 120 SymWrite 121 SymAddr 122 123 SymRdWr = SymRead | SymWrite 124 125 SymNone SymEffect = 0 126 ) 127 128 type InputInfo struct { 129 Idx int // index in Args array 130 Regs RegMask // allowed input registers 131 } 132 133 func (r *RegInfo) String() string { 134 s := "" 135 s += "INS:\n" 136 for _, i := range r.Inputs { 137 mask := fmt.Sprintf("%64b", i.Regs) 138 mask = strings.ReplaceAll(mask, "0", ".") 139 s += fmt.Sprintf("%2d |%s|\n", i.Idx, mask) 140 } 141 s += "OUTS:\n" 142 for _, i := range r.Outputs { 143 mask := fmt.Sprintf("%64b", i.Regs) 144 mask = strings.ReplaceAll(mask, "0", ".") 145 s += fmt.Sprintf("%2d |%s|\n", i.Idx, mask) 146 } 147 s += "CLOBBERS:\n" 148 mask := fmt.Sprintf("%64b", r.Clobbers) 149 mask = strings.ReplaceAll(mask, "0", ".") 150 s += fmt.Sprintf(" |%s|\n", mask) 151 return s 152 } 153 154 func (op Op) IsLoweredGetClosurePtr() bool { 155 switch op { 156 case OpAMD64LoweredGetClosurePtr, OpPPC64LoweredGetClosurePtr, OpARMLoweredGetClosurePtr, OpARM64LoweredGetClosurePtr, 157 Op386LoweredGetClosurePtr, OpMIPS64LoweredGetClosurePtr, OpLOONG64LoweredGetClosurePtr, OpS390XLoweredGetClosurePtr, OpMIPSLoweredGetClosurePtr, 158 OpRISCV64LoweredGetClosurePtr, OpWasmLoweredGetClosurePtr: 159 return true 160 } 161 return false 162 } 163