golang.org/x/arch@v0.17.0/s390x/s390xasm/decode.go (about) 1 // Copyright 2024 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 s390xasm 6 7 import ( 8 "encoding/binary" 9 "fmt" 10 ) 11 12 // instFormat is a decoding rule for one specific instruction form. 13 // An instruction ins matches the rule if ins&Mask == Value. 14 // DontCare bits are mainly used for finding the same instruction 15 // name differing with the number of argument fields. 16 // The Args are stored in the same order as the instruction manual. 17 type instFormat struct { 18 Op Op 19 Mask uint64 20 Value uint64 21 DontCare uint64 22 Args [8]*argField 23 } 24 25 // argField indicate how to decode an argument to an instruction. 26 // First parse the value from the BitFields, shift it left by Shift 27 // bits to get the actual numerical value. 28 type argField struct { 29 Type ArgType 30 flags uint16 31 BitField 32 } 33 34 // Parse parses the Arg out from the given binary instruction i. 35 func (a argField) Parse(i uint64) Arg { 36 switch a.Type { 37 default: 38 return nil 39 case TypeUnknown: 40 return nil 41 case TypeReg: 42 return R0 + Reg(a.BitField.Parse(i)) 43 case TypeFPReg: 44 return F0 + Reg(a.BitField.Parse(i)) 45 case TypeCReg: 46 return C0 + Reg(a.BitField.Parse(i)) 47 case TypeACReg: 48 return A0 + Reg(a.BitField.Parse(i)) 49 case TypeBaseReg: 50 return B0 + Base(a.BitField.Parse(i)) 51 case TypeIndexReg: 52 return X0 + Index(a.BitField.Parse(i)) 53 case TypeDispUnsigned: 54 return Disp12(a.BitField.Parse(i)) 55 case TypeDispSigned20: 56 return Disp20(a.BitField.ParseSigned(i)) 57 case TypeVecReg: 58 m := i >> 24 // Handling RXB field(bits 36 to 39) 59 if ((m>>3)&0x1 == 1) && (a.BitField.Offs == 8) { 60 return V0 + VReg(a.BitField.Parse(i)) + VReg(16) 61 } else if ((m>>2)&0x1 == 1) && (a.BitField.Offs == 12) { 62 return V0 + VReg(a.BitField.Parse(i)) + VReg(16) 63 } else if ((m>>1)&0x1 == 1) && (a.BitField.Offs == 16) { 64 return V0 + VReg(a.BitField.Parse(i)) + VReg(16) 65 } else if ((m)&0x1 == 1) && (a.BitField.Offs == 32) { 66 return V0 + VReg(a.BitField.Parse(i)) + VReg(16) 67 } else { 68 return V0 + VReg(a.BitField.Parse(i)) 69 } 70 case TypeImmSigned8: 71 return Sign8(a.BitField.ParseSigned(i)) 72 case TypeImmSigned16: 73 return Sign16(a.BitField.ParseSigned(i)) 74 case TypeImmSigned32: 75 return Sign32(a.BitField.ParseSigned(i)) 76 case TypeImmUnsigned: 77 return Imm(a.BitField.Parse(i)) 78 case TypeRegImSigned12: 79 return RegIm12(a.BitField.ParseSigned(i)) 80 case TypeRegImSigned16: 81 return RegIm16(a.BitField.ParseSigned(i)) 82 case TypeRegImSigned24: 83 return RegIm24(a.BitField.ParseSigned(i)) 84 case TypeRegImSigned32: 85 return RegIm32(a.BitField.ParseSigned(i)) 86 case TypeMask: 87 return Mask(a.BitField.Parse(i)) 88 case TypeLen: 89 return Len(a.BitField.Parse(i)) 90 } 91 } 92 93 type ArgType int8 94 95 const ( 96 TypeUnknown ArgType = iota 97 TypeReg // integer register 98 TypeFPReg // floating point register 99 TypeACReg // access register 100 TypeCReg // control register 101 TypeVecReg // vector register 102 TypeImmUnsigned // unsigned immediate/flag/mask, this is the catch-all type 103 TypeImmSigned8 // Signed 8-bit Immdediate 104 TypeImmSigned16 // Signed 16-bit Immdediate 105 TypeImmSigned32 // Signed 32-bit Immdediate 106 TypeBaseReg // Base Register for accessing memory 107 TypeIndexReg // Index Register 108 TypeDispUnsigned // Displacement 12-bit unsigned for memory address 109 TypeDispSigned20 // Displacement 20-bit signed for memory address 110 TypeRegImSigned12 // RegisterImmediate 12-bit signed data 111 TypeRegImSigned16 // RegisterImmediate 16-bit signed data 112 TypeRegImSigned24 // RegisterImmediate 24-bit signed data 113 TypeRegImSigned32 // RegisterImmediate 32-bit signed data 114 TypeMask // 4-bit Mask 115 TypeLen // Length of Memory Operand 116 TypeLast 117 ) 118 119 func (t ArgType) String() string { 120 switch t { 121 default: 122 return fmt.Sprintf("ArgType(%d)", int(t)) 123 case TypeUnknown: 124 return "Unknown" 125 case TypeReg: 126 return "Reg" 127 case TypeFPReg: 128 return "FPReg" 129 case TypeACReg: 130 return "ACReg" 131 case TypeCReg: 132 return "CReg" 133 case TypeDispUnsigned: 134 return "DispUnsigned" 135 case TypeDispSigned20: 136 return "DispSigned20" 137 case TypeBaseReg: 138 return "BaseReg" 139 case TypeIndexReg: 140 return "IndexReg" 141 case TypeVecReg: 142 return "VecReg" 143 case TypeImmSigned8: 144 return "ImmSigned8" 145 case TypeImmSigned16: 146 return "ImmSigned16" 147 case TypeImmSigned32: 148 return "ImmSigned32" 149 case TypeImmUnsigned: 150 return "ImmUnsigned" 151 case TypeRegImSigned12: 152 return "RegImSigned12" 153 case TypeRegImSigned16: 154 return "RegImSigned16" 155 case TypeRegImSigned24: 156 return "RegImSigned24" 157 case TypeRegImSigned32: 158 return "RegImSigned32" 159 case TypeMask: 160 return "Mask" 161 case TypeLen: 162 return "Len" 163 } 164 } 165 166 func (t ArgType) GoString() string { 167 s := t.String() 168 if t > 0 && t < TypeLast { 169 return "Type" + s 170 } 171 return s 172 } 173 174 var ( 175 // Errors 176 errShort = fmt.Errorf("truncated instruction") 177 errUnknown = fmt.Errorf("unknown instruction") 178 ) 179 180 var decoderCover []bool 181 182 // Decode decodes the leading bytes in src as a single instruction using 183 // byte order ord. 184 func Decode(src []byte) (inst Inst, err error) { 185 if len(src) < 2 { 186 return inst, errShort 187 } 188 if decoderCover == nil { 189 decoderCover = make([]bool, len(instFormats)) 190 } 191 bit_check := binary.BigEndian.Uint16(src[:2]) 192 bit_check = bit_check >> 14 193 l := int(0) 194 if (bit_check & 0x03) == 0 { 195 l = 2 196 } else if bit_check&0x03 == 3 { 197 l = 6 198 } else if (bit_check&0x01 == 1) || (bit_check&0x02 == 2) { 199 l = 4 200 } 201 inst.Len = l 202 ui_extn := uint64(0) 203 switch l { 204 case 2: 205 ui_extn = uint64(binary.BigEndian.Uint16(src[:inst.Len])) 206 inst.Enc = ui_extn 207 ui_extn = ui_extn << 48 208 case 4: 209 ui_extn = uint64(binary.BigEndian.Uint32(src[:inst.Len])) 210 inst.Enc = ui_extn 211 ui_extn = ui_extn << 32 212 case 6: 213 u1 := binary.BigEndian.Uint32(src[:(inst.Len - 2)]) 214 u2 := binary.BigEndian.Uint16(src[(inst.Len - 2):inst.Len]) 215 ui_extn = uint64(u1)<<16 | uint64(u2) 216 ui_extn = ui_extn << 16 217 inst.Enc = ui_extn 218 default: 219 return inst, errShort 220 } 221 for _, iform := range instFormats { 222 if ui_extn&iform.Mask != iform.Value { 223 continue 224 } 225 if (iform.DontCare & ^(ui_extn)) != iform.DontCare { 226 continue 227 } 228 for j, argfield := range iform.Args { 229 if argfield == nil { 230 break 231 } 232 inst.Args[j] = argfield.Parse(ui_extn) 233 } 234 inst.Op = iform.Op 235 break 236 } 237 if inst.Op == 0 && inst.Enc != 0 { 238 return inst, errUnknown 239 } 240 return inst, nil 241 }