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 "bytes" 9 "fmt" 10 ) 11 12 type Inst struct { 13 Op Op // Opcode mnemonic 14 Enc uint32 // Raw encoding bits 15 Len int // Length of encoding in bytes. 16 Args Args // Instruction arguments, in Power ISA manual order. 17 } 18 19 func (i Inst) String() string { 20 var buf bytes.Buffer 21 buf.WriteString(i.Op.String()) 22 for j, arg := range i.Args { 23 if arg == nil { 24 break 25 } 26 if j == 0 { 27 buf.WriteString(" ") 28 } else { 29 buf.WriteString(", ") 30 } 31 buf.WriteString(arg.String()) 32 } 33 return buf.String() 34 } 35 36 // An Op is an instruction operation. 37 type Op uint16 38 39 func (o Op) String() string { 40 if int(o) >= len(opstr) || opstr[o] == "" { 41 return fmt.Sprintf("Op(%d)", int(o)) 42 } 43 return opstr[o] 44 } 45 46 // An Arg is a single instruction argument, one of these types: Reg, CondReg, SpReg, Imm, PCRel, Label, or Offset. 47 type Arg interface { 48 IsArg() 49 String() string 50 } 51 52 // An Args holds the instruction arguments. 53 // If an instruction has fewer than 4 arguments, 54 // the final elements in the array are nil. 55 type Args [5]Arg 56 57 // A Reg is a single register. The zero value means R0, not the absence of a register. 58 // It also includes special registers. 59 type Reg uint16 60 61 const ( 62 _ Reg = iota 63 R0 64 R1 65 R2 66 R3 67 R4 68 R5 69 R6 70 R7 71 R8 72 R9 73 R10 74 R11 75 R12 76 R13 77 R14 78 R15 79 R16 80 R17 81 R18 82 R19 83 R20 84 R21 85 R22 86 R23 87 R24 88 R25 89 R26 90 R27 91 R28 92 R29 93 R30 94 R31 95 F0 96 F1 97 F2 98 F3 99 F4 100 F5 101 F6 102 F7 103 F8 104 F9 105 F10 106 F11 107 F12 108 F13 109 F14 110 F15 111 F16 112 F17 113 F18 114 F19 115 F20 116 F21 117 F22 118 F23 119 F24 120 F25 121 F26 122 F27 123 F28 124 F29 125 F30 126 F31 127 V0 // VSX extension, F0 is V0[0:63]. 128 V1 129 V2 130 V3 131 V4 132 V5 133 V6 134 V7 135 V8 136 V9 137 V10 138 V11 139 V12 140 V13 141 V14 142 V15 143 V16 144 V17 145 V18 146 V19 147 V20 148 V21 149 V22 150 V23 151 V24 152 V25 153 V26 154 V27 155 V28 156 V29 157 V30 158 V31 159 VS0 160 VS1 161 VS2 162 VS3 163 VS4 164 VS5 165 VS6 166 VS7 167 VS8 168 VS9 169 VS10 170 VS11 171 VS12 172 VS13 173 VS14 174 VS15 175 VS16 176 VS17 177 VS18 178 VS19 179 VS20 180 VS21 181 VS22 182 VS23 183 VS24 184 VS25 185 VS26 186 VS27 187 VS28 188 VS29 189 VS30 190 VS31 191 VS32 192 VS33 193 VS34 194 VS35 195 VS36 196 VS37 197 VS38 198 VS39 199 VS40 200 VS41 201 VS42 202 VS43 203 VS44 204 VS45 205 VS46 206 VS47 207 VS48 208 VS49 209 VS50 210 VS51 211 VS52 212 VS53 213 VS54 214 VS55 215 VS56 216 VS57 217 VS58 218 VS59 219 VS60 220 VS61 221 VS62 222 VS63 223 ) 224 225 func (Reg) IsArg() {} 226 func (r Reg) String() string { 227 switch { 228 case R0 <= r && r <= R31: 229 return fmt.Sprintf("r%d", int(r-R0)) 230 case F0 <= r && r <= F31: 231 return fmt.Sprintf("f%d", int(r-F0)) 232 case V0 <= r && r <= V31: 233 return fmt.Sprintf("v%d", int(r-V0)) 234 case VS0 <= r && r <= VS63: 235 return fmt.Sprintf("vs%d", int(r-VS0)) 236 default: 237 return fmt.Sprintf("Reg(%d)", int(r)) 238 } 239 } 240 241 // CondReg is a bit or field in the conditon register. 242 type CondReg int8 243 244 const ( 245 _ CondReg = iota 246 // Condition Regster bits 247 Cond0LT 248 Cond0GT 249 Cond0EQ 250 Cond0SO 251 Cond1LT 252 Cond1GT 253 Cond1EQ 254 Cond1SO 255 Cond2LT 256 Cond2GT 257 Cond2EQ 258 Cond2SO 259 Cond3LT 260 Cond3GT 261 Cond3EQ 262 Cond3SO 263 Cond4LT 264 Cond4GT 265 Cond4EQ 266 Cond4SO 267 Cond5LT 268 Cond5GT 269 Cond5EQ 270 Cond5SO 271 Cond6LT 272 Cond6GT 273 Cond6EQ 274 Cond6SO 275 Cond7LT 276 Cond7GT 277 Cond7EQ 278 Cond7SO 279 // Condition Register Fields 280 CR0 281 CR1 282 CR2 283 CR3 284 CR4 285 CR5 286 CR6 287 CR7 288 ) 289 290 func (CondReg) IsArg() {} 291 func (c CondReg) String() string { 292 switch { 293 default: 294 return fmt.Sprintf("CondReg(%d)", int(c)) 295 case c >= CR0: 296 return fmt.Sprintf("CR%d", int(c-CR0)) 297 case c >= Cond0LT && c < CR0: 298 return fmt.Sprintf("Cond%d%s", int((c-Cond0LT)/4), [4]string{"LT", "GT", "EQ", "SO"}[(c-Cond0LT)%4]) 299 } 300 } 301 302 // SpReg is a special register, its meaning depends on Op. 303 type SpReg uint16 304 305 const ( 306 SpRegZero SpReg = 0 307 ) 308 309 func (SpReg) IsArg() {} 310 func (s SpReg) String() string { 311 return fmt.Sprintf("SpReg(%d)", int(s)) 312 } 313 314 // PCRel is a PC-relative offset, used only in branch instructions. 315 type PCRel int32 316 317 func (PCRel) IsArg() {} 318 func (r PCRel) String() string { 319 return fmt.Sprintf("PC%+#x", int32(r)) 320 } 321 322 // A Label is a code (text) address, used only in absolute branch instructions. 323 type Label uint32 324 325 func (Label) IsArg() {} 326 func (l Label) String() string { 327 return fmt.Sprintf("%#x", uint32(l)) 328 } 329 330 // Imm represents an immediate number. 331 type Imm int32 332 333 func (Imm) IsArg() {} 334 func (i Imm) String() string { 335 return fmt.Sprintf("%d", int32(i)) 336 } 337 338 // Offset represents a memory offset immediate. 339 type Offset int32 340 341 func (Offset) IsArg() {} 342 func (o Offset) String() string { 343 return fmt.Sprintf("%+d", int32(o)) 344 } 345