github.com/bir3/gocompiler@v0.9.2202/src/xvendor/golang.org/x/arch/ppc64/ppc64asm/decode.go (about) 1 // Copyright 2014 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 ppc64asm 6 7 import ( 8 "encoding/binary" 9 "fmt" 10 "log" 11 ) 12 13 const debugDecode = false 14 15 const prefixOpcode = 1 16 17 // instFormat is a decoding rule for one specific instruction form. 18 // an instruction ins matches the rule if ins&Mask == Value 19 // DontCare bits should be zero, but the machine might not reject 20 // ones in those bits, they are mainly reserved for future expansion 21 // of the instruction set. 22 // The Args are stored in the same order as the instruction manual. 23 // 24 // Prefixed instructions are stored as: 25 // 26 // prefix << 32 | suffix, 27 // 28 // Regular instructions are: 29 // 30 // inst << 32 31 type instFormat struct { 32 Op Op 33 Mask uint64 34 Value uint64 35 DontCare uint64 36 Args [6]*argField 37 } 38 39 // argField indicate how to decode an argument to an instruction. 40 // First parse the value from the BitFields, shift it left by Shift 41 // bits to get the actual numerical value. 42 type argField struct { 43 Type ArgType 44 Shift uint8 45 BitFields 46 } 47 48 // Parse parses the Arg out from the given binary instruction i. 49 func (a argField) Parse(i [2]uint32) Arg { 50 switch a.Type { 51 default: 52 return nil 53 case TypeUnknown: 54 return nil 55 case TypeReg: 56 return R0 + Reg(a.BitFields.Parse(i)) 57 case TypeCondRegBit: 58 return Cond0LT + CondReg(a.BitFields.Parse(i)) 59 case TypeCondRegField: 60 return CR0 + CondReg(a.BitFields.Parse(i)) 61 case TypeFPReg: 62 return F0 + Reg(a.BitFields.Parse(i)) 63 case TypeVecReg: 64 return V0 + Reg(a.BitFields.Parse(i)) 65 case TypeVecSReg: 66 return VS0 + Reg(a.BitFields.Parse(i)) 67 case TypeVecSpReg: 68 return VS0 + Reg(a.BitFields.Parse(i))*2 69 case TypeMMAReg: 70 return A0 + Reg(a.BitFields.Parse(i)) 71 case TypeSpReg: 72 return SpReg(a.BitFields.Parse(i)) 73 case TypeImmSigned: 74 return Imm(a.BitFields.ParseSigned(i) << a.Shift) 75 case TypeImmUnsigned: 76 return Imm(a.BitFields.Parse(i) << a.Shift) 77 case TypePCRel: 78 return PCRel(a.BitFields.ParseSigned(i) << a.Shift) 79 case TypeLabel: 80 return Label(a.BitFields.ParseSigned(i) << a.Shift) 81 case TypeOffset: 82 return Offset(a.BitFields.ParseSigned(i) << a.Shift) 83 case TypeNegOffset: 84 // An oddball encoding of offset for hashchk and similar. 85 // e.g hashchk offset is 0b1111111000000000 | DX << 8 | D << 3 86 off := a.BitFields.ParseSigned(i) << a.Shift 87 neg := int64(-1) << (int(a.Shift) + a.BitFields.NumBits()) 88 return Offset(neg | off) 89 } 90 } 91 92 type ArgType int8 93 94 const ( 95 TypeUnknown ArgType = iota 96 TypePCRel // PC-relative address 97 TypeLabel // absolute address 98 TypeReg // integer register 99 TypeCondRegBit // conditional register bit (0-31) 100 TypeCondRegField // conditional register field (0-7) 101 TypeFPReg // floating point register 102 TypeVecReg // vector register 103 TypeVecSReg // VSX register 104 TypeVecSpReg // VSX register pair (even only encoding) 105 TypeMMAReg // MMA register 106 TypeSpReg // special register (depends on Op) 107 TypeImmSigned // signed immediate 108 TypeImmUnsigned // unsigned immediate/flag/mask, this is the catch-all type 109 TypeOffset // signed offset in load/store 110 TypeNegOffset // A negative 16 bit value 0b1111111xxxxx000 encoded as 0bxxxxx (e.g in the hashchk instruction) 111 TypeLast // must be the last one 112 ) 113 114 func (t ArgType) String() string { 115 switch t { 116 default: 117 return fmt.Sprintf("ArgType(%d)", int(t)) 118 case TypeUnknown: 119 return "Unknown" 120 case TypeReg: 121 return "Reg" 122 case TypeCondRegBit: 123 return "CondRegBit" 124 case TypeCondRegField: 125 return "CondRegField" 126 case TypeFPReg: 127 return "FPReg" 128 case TypeVecReg: 129 return "VecReg" 130 case TypeVecSReg: 131 return "VecSReg" 132 case TypeVecSpReg: 133 return "VecSpReg" 134 case TypeMMAReg: 135 return "MMAReg" 136 case TypeSpReg: 137 return "SpReg" 138 case TypeImmSigned: 139 return "ImmSigned" 140 case TypeImmUnsigned: 141 return "ImmUnsigned" 142 case TypePCRel: 143 return "PCRel" 144 case TypeLabel: 145 return "Label" 146 case TypeOffset: 147 return "Offset" 148 case TypeNegOffset: 149 return "NegOffset" 150 } 151 } 152 153 func (t ArgType) GoString() string { 154 s := t.String() 155 if t > 0 && t < TypeLast { 156 return "Type" + s 157 } 158 return s 159 } 160 161 var ( 162 // Errors 163 errShort = fmt.Errorf("truncated instruction") 164 errUnknown = fmt.Errorf("unknown instruction") 165 ) 166 167 var decoderCover []bool 168 169 // Decode decodes the leading bytes in src as a single instruction using 170 // byte order ord. 171 func Decode(src []byte, ord binary.ByteOrder) (inst Inst, err error) { 172 if len(src) < 4 { 173 return inst, errShort 174 } 175 if decoderCover == nil { 176 decoderCover = make([]bool, len(instFormats)) 177 } 178 inst.Len = 4 179 ui_extn := [2]uint32{ord.Uint32(src[:inst.Len]), 0} 180 ui := uint64(ui_extn[0]) << 32 181 inst.Enc = ui_extn[0] 182 opcode := inst.Enc >> 26 183 if opcode == prefixOpcode { 184 // This is a prefixed instruction 185 inst.Len = 8 186 if len(src) < 8 { 187 return inst, errShort 188 } 189 // Merge the suffixed word. 190 ui_extn[1] = ord.Uint32(src[4:inst.Len]) 191 ui |= uint64(ui_extn[1]) 192 inst.SuffixEnc = ui_extn[1] 193 } 194 for i, iform := range instFormats { 195 if ui&iform.Mask != iform.Value { 196 continue 197 } 198 if ui&iform.DontCare != 0 { 199 if debugDecode { 200 log.Printf("Decode(%#x): unused bit is 1 for Op %s", ui, iform.Op) 201 } 202 // to match GNU objdump (libopcodes), we ignore don't care bits 203 } 204 for i, argfield := range iform.Args { 205 if argfield == nil { 206 break 207 } 208 inst.Args[i] = argfield.Parse(ui_extn) 209 } 210 inst.Op = iform.Op 211 if debugDecode { 212 log.Printf("%#x: search entry %d", ui, i) 213 continue 214 } 215 break 216 } 217 if inst.Op == 0 && inst.Enc != 0 { 218 return inst, errUnknown 219 } 220 return inst, nil 221 }