github.com/megatontech/mynoteforgo@v0.0.0-20200507084910-5d0c6ea6e890/源码/cmd/compile/internal/ssa/op.go (about) 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 ssa 6 7 import ( 8 "cmd/internal/obj" 9 "fmt" 10 ) 11 12 // An Op encodes the specific operation that a Value performs. 13 // Opcodes' semantics can be modified by the type and aux fields of the Value. 14 // For instance, OpAdd can be 32 or 64 bit, signed or unsigned, float or complex, depending on Value.Type. 15 // Semantics of each op are described in the opcode files in gen/*Ops.go. 16 // There is one file for generic (architecture-independent) ops and one file 17 // for each architecture. 18 type Op int32 19 20 type opInfo struct { 21 name string 22 reg regInfo 23 auxType auxType 24 argLen int32 // the number of arguments, -1 if variable length 25 asm obj.As 26 generic bool // this is a generic (arch-independent) opcode 27 rematerializeable bool // this op is rematerializeable 28 commutative bool // this operation is commutative (e.g. addition) 29 resultInArg0 bool // (first, if a tuple) output of v and v.Args[0] must be allocated to the same register 30 resultNotInArgs bool // outputs must not be allocated to the same registers as inputs 31 clobberFlags bool // this op clobbers flags register 32 call bool // is a function call 33 nilCheck bool // this op is a nil check on arg0 34 faultOnNilArg0 bool // this op will fault if arg0 is nil (and aux encodes a small offset) 35 faultOnNilArg1 bool // this op will fault if arg1 is nil (and aux encodes a small offset) 36 usesScratch bool // this op requires scratch memory space 37 hasSideEffects bool // for "reasons", not to be eliminated. E.g., atomic store, #19182. 38 zeroWidth bool // op never translates into any machine code. example: copy, which may sometimes translate to machine code, is not zero-width. 39 symEffect SymEffect // effect this op has on symbol in aux 40 } 41 42 type inputInfo struct { 43 idx int // index in Args array 44 regs regMask // allowed input registers 45 } 46 47 type outputInfo struct { 48 idx int // index in output tuple 49 regs regMask // allowed output registers 50 } 51 52 type regInfo struct { 53 // inputs encodes the register restrictions for an instruction's inputs. 54 // Each entry specifies an allowed register set for a particular input. 55 // They are listed in the order in which regalloc should pick a register 56 // from the register set (most constrained first). 57 // Inputs which do not need registers are not listed. 58 inputs []inputInfo 59 // clobbers encodes the set of registers that are overwritten by 60 // the instruction (other than the output registers). 61 clobbers regMask 62 // outputs is the same as inputs, but for the outputs of the instruction. 63 outputs []outputInfo 64 } 65 66 type auxType int8 67 68 const ( 69 auxNone auxType = iota 70 auxBool // auxInt is 0/1 for false/true 71 auxInt8 // auxInt is an 8-bit integer 72 auxInt16 // auxInt is a 16-bit integer 73 auxInt32 // auxInt is a 32-bit integer 74 auxInt64 // auxInt is a 64-bit integer 75 auxInt128 // auxInt represents a 128-bit integer. Always 0. 76 auxFloat32 // auxInt is a float32 (encoded with math.Float64bits) 77 auxFloat64 // auxInt is a float64 (encoded with math.Float64bits) 78 auxString // aux is a string 79 auxSym // aux is a symbol (a *gc.Node for locals or an *obj.LSym for globals) 80 auxSymOff // aux is a symbol, auxInt is an offset 81 auxSymValAndOff // aux is a symbol, auxInt is a ValAndOff 82 auxTyp // aux is a type 83 auxTypSize // aux is a type, auxInt is a size, must have Aux.(Type).Size() == AuxInt 84 auxCCop // aux is a ssa.Op that represents a flags-to-bool conversion (e.g. LessThan) 85 86 auxSymInt32 // aux is a symbol, auxInt is a 32-bit integer 87 ) 88 89 // A SymEffect describes the effect that an SSA Value has on the variable 90 // identified by the symbol in its Aux field. 91 type SymEffect int8 92 93 const ( 94 SymRead SymEffect = 1 << iota 95 SymWrite 96 SymAddr 97 98 SymRdWr = SymRead | SymWrite 99 100 SymNone SymEffect = 0 101 ) 102 103 // A ValAndOff is used by the several opcodes. It holds 104 // both a value and a pointer offset. 105 // A ValAndOff is intended to be encoded into an AuxInt field. 106 // The zero ValAndOff encodes a value of 0 and an offset of 0. 107 // The high 32 bits hold a value. 108 // The low 32 bits hold a pointer offset. 109 type ValAndOff int64 110 111 func (x ValAndOff) Val() int64 { 112 return int64(x) >> 32 113 } 114 func (x ValAndOff) Off() int64 { 115 return int64(int32(x)) 116 } 117 func (x ValAndOff) Int64() int64 { 118 return int64(x) 119 } 120 func (x ValAndOff) String() string { 121 return fmt.Sprintf("val=%d,off=%d", x.Val(), x.Off()) 122 } 123 124 // validVal reports whether the value can be used 125 // as an argument to makeValAndOff. 126 func validVal(val int64) bool { 127 return val == int64(int32(val)) 128 } 129 130 // validOff reports whether the offset can be used 131 // as an argument to makeValAndOff. 132 func validOff(off int64) bool { 133 return off == int64(int32(off)) 134 } 135 136 // validValAndOff reports whether we can fit the value and offset into 137 // a ValAndOff value. 138 func validValAndOff(val, off int64) bool { 139 if !validVal(val) { 140 return false 141 } 142 if !validOff(off) { 143 return false 144 } 145 return true 146 } 147 148 // makeValAndOff encodes a ValAndOff into an int64 suitable for storing in an AuxInt field. 149 func makeValAndOff(val, off int64) int64 { 150 if !validValAndOff(val, off) { 151 panic("invalid makeValAndOff") 152 } 153 return ValAndOff(val<<32 + int64(uint32(off))).Int64() 154 } 155 156 func (x ValAndOff) canAdd(off int64) bool { 157 newoff := x.Off() + off 158 return newoff == int64(int32(newoff)) 159 } 160 161 func (x ValAndOff) add(off int64) int64 { 162 if !x.canAdd(off) { 163 panic("invalid ValAndOff.add") 164 } 165 return makeValAndOff(x.Val(), x.Off()+off) 166 }