1 /* ppc-dis.c -- Disassemble PowerPC instructions 2 Copyright (C) 1994-2016 Free Software Foundation, Inc. 3 Written by Ian Lance Taylor, Cygnus Support 4 5 This file is part of the GNU opcodes library. 6 7 This library is free software; you can redistribute it and/or modify 8 it under the terms of the GNU General Public License as published by 9 the Free Software Foundation; either version 3, or (at your option) 10 any later version. 11 12 It is distributed in the hope that it will be useful, but WITHOUT 13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 14 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public 15 License for more details. 16 17 You should have received a copy of the GNU General Public License 18 along with this file; see the file COPYING. If not, write to the 19 Free Software Foundation, 51 Franklin Street - Fifth Floor, Boston, 20 MA 02110-1301, USA. */ 21 22 #include "sysdep.h" 23 #include <stdio.h> 24 #include "dis-asm.h" 25 #include "elf-bfd.h" 26 #include "elf/ppc.h" 27 #include "opintl.h" 28 #include "opcode/ppc.h" 29 30 /* This file provides several disassembler functions, all of which use 31 the disassembler interface defined in dis-asm.h. Several functions 32 are provided because this file handles disassembly for the PowerPC 33 in both big and little endian mode and also for the POWER (RS/6000) 34 chip. */ 35 static int print_insn_powerpc (bfd_vma, struct disassemble_info *, int, 36 ppc_cpu_t); 37 38 struct dis_private 39 { 40 /* Stash the result of parsing disassembler_options here. */ 41 ppc_cpu_t dialect; 42 } private; 43 44 #define POWERPC_DIALECT(INFO) \ 45 (((struct dis_private *) ((INFO)->private_data))->dialect) 46 47 struct ppc_mopt { 48 const char *opt; 49 ppc_cpu_t cpu; 50 ppc_cpu_t sticky; 51 }; 52 53 struct ppc_mopt ppc_opts[] = { 54 { "403", PPC_OPCODE_PPC | PPC_OPCODE_403, 55 0 }, 56 { "405", PPC_OPCODE_PPC | PPC_OPCODE_403 | PPC_OPCODE_405, 57 0 }, 58 { "440", (PPC_OPCODE_PPC | PPC_OPCODE_BOOKE | PPC_OPCODE_440 59 | PPC_OPCODE_ISEL | PPC_OPCODE_RFMCI), 60 0 }, 61 { "464", (PPC_OPCODE_PPC | PPC_OPCODE_BOOKE | PPC_OPCODE_440 62 | PPC_OPCODE_ISEL | PPC_OPCODE_RFMCI), 63 0 }, 64 { "476", (PPC_OPCODE_PPC | PPC_OPCODE_ISEL | PPC_OPCODE_440 65 | PPC_OPCODE_476 | PPC_OPCODE_POWER4 | PPC_OPCODE_POWER5), 66 0 }, 67 { "601", PPC_OPCODE_PPC | PPC_OPCODE_601, 68 0 }, 69 { "603", PPC_OPCODE_PPC, 70 0 }, 71 { "604", PPC_OPCODE_PPC, 72 0 }, 73 { "620", PPC_OPCODE_PPC | PPC_OPCODE_64, 74 0 }, 75 { "7400", PPC_OPCODE_PPC | PPC_OPCODE_ALTIVEC, 76 0 }, 77 { "7410", PPC_OPCODE_PPC | PPC_OPCODE_ALTIVEC, 78 0 }, 79 { "7450", PPC_OPCODE_PPC | PPC_OPCODE_7450 | PPC_OPCODE_ALTIVEC, 80 0 }, 81 { "7455", PPC_OPCODE_PPC | PPC_OPCODE_ALTIVEC, 82 0 }, 83 { "750cl", PPC_OPCODE_PPC | PPC_OPCODE_750 | PPC_OPCODE_PPCPS 84 , 0 }, 85 { "821", PPC_OPCODE_PPC | PPC_OPCODE_860, 86 0 }, 87 { "850", PPC_OPCODE_PPC | PPC_OPCODE_860, 88 0 }, 89 { "860", PPC_OPCODE_PPC | PPC_OPCODE_860, 90 0 }, 91 { "a2", (PPC_OPCODE_PPC | PPC_OPCODE_ISEL | PPC_OPCODE_POWER4 92 | PPC_OPCODE_POWER5 | PPC_OPCODE_CACHELCK | PPC_OPCODE_64 93 | PPC_OPCODE_A2), 94 0 }, 95 { "altivec", PPC_OPCODE_PPC, 96 PPC_OPCODE_ALTIVEC }, 97 { "any", 0, 98 PPC_OPCODE_ANY }, 99 { "booke", PPC_OPCODE_PPC | PPC_OPCODE_BOOKE, 100 0 }, 101 { "booke32", PPC_OPCODE_PPC | PPC_OPCODE_BOOKE, 102 0 }, 103 { "cell", (PPC_OPCODE_PPC | PPC_OPCODE_64 | PPC_OPCODE_POWER4 104 | PPC_OPCODE_CELL | PPC_OPCODE_ALTIVEC), 105 0 }, 106 { "com", PPC_OPCODE_COMMON, 107 0 }, 108 { "e300", PPC_OPCODE_PPC | PPC_OPCODE_E300, 109 0 }, 110 { "e500", (PPC_OPCODE_PPC | PPC_OPCODE_BOOKE | PPC_OPCODE_SPE 111 | PPC_OPCODE_ISEL | PPC_OPCODE_EFS | PPC_OPCODE_BRLOCK 112 | PPC_OPCODE_PMR | PPC_OPCODE_CACHELCK | PPC_OPCODE_RFMCI 113 | PPC_OPCODE_E500), 114 0 }, 115 { "e500mc", (PPC_OPCODE_PPC | PPC_OPCODE_BOOKE | PPC_OPCODE_ISEL 116 | PPC_OPCODE_PMR | PPC_OPCODE_CACHELCK | PPC_OPCODE_RFMCI 117 | PPC_OPCODE_E500MC), 118 0 }, 119 { "e500mc64", (PPC_OPCODE_PPC | PPC_OPCODE_BOOKE | PPC_OPCODE_ISEL 120 | PPC_OPCODE_PMR | PPC_OPCODE_CACHELCK | PPC_OPCODE_RFMCI 121 | PPC_OPCODE_E500MC | PPC_OPCODE_64 | PPC_OPCODE_POWER5 122 | PPC_OPCODE_POWER6 | PPC_OPCODE_POWER7), 123 0 }, 124 { "e5500", (PPC_OPCODE_PPC | PPC_OPCODE_BOOKE | PPC_OPCODE_ISEL 125 | PPC_OPCODE_PMR | PPC_OPCODE_CACHELCK | PPC_OPCODE_RFMCI 126 | PPC_OPCODE_E500MC | PPC_OPCODE_64 | PPC_OPCODE_POWER4 127 | PPC_OPCODE_POWER5 | PPC_OPCODE_POWER6 128 | PPC_OPCODE_POWER7), 129 0 }, 130 { "e6500", (PPC_OPCODE_PPC | PPC_OPCODE_BOOKE | PPC_OPCODE_ISEL 131 | PPC_OPCODE_PMR | PPC_OPCODE_CACHELCK | PPC_OPCODE_RFMCI 132 | PPC_OPCODE_E500MC | PPC_OPCODE_64 | PPC_OPCODE_ALTIVEC 133 | PPC_OPCODE_ALTIVEC2 | PPC_OPCODE_E6500 | PPC_OPCODE_POWER4 134 | PPC_OPCODE_POWER5 | PPC_OPCODE_POWER6 | PPC_OPCODE_POWER7), 135 0 }, 136 { "e500x2", (PPC_OPCODE_PPC | PPC_OPCODE_BOOKE | PPC_OPCODE_SPE 137 | PPC_OPCODE_ISEL | PPC_OPCODE_EFS | PPC_OPCODE_BRLOCK 138 | PPC_OPCODE_PMR | PPC_OPCODE_CACHELCK | PPC_OPCODE_RFMCI 139 | PPC_OPCODE_E500), 140 0 }, 141 { "efs", PPC_OPCODE_PPC | PPC_OPCODE_EFS, 142 0 }, 143 { "power4", PPC_OPCODE_PPC | PPC_OPCODE_64 | PPC_OPCODE_POWER4, 144 0 }, 145 { "power5", (PPC_OPCODE_PPC | PPC_OPCODE_64 | PPC_OPCODE_POWER4 146 | PPC_OPCODE_POWER5), 147 0 }, 148 { "power6", (PPC_OPCODE_PPC | PPC_OPCODE_64 | PPC_OPCODE_POWER4 149 | PPC_OPCODE_POWER5 | PPC_OPCODE_POWER6 | PPC_OPCODE_ALTIVEC), 150 0 }, 151 { "power7", (PPC_OPCODE_PPC | PPC_OPCODE_ISEL | PPC_OPCODE_64 152 | PPC_OPCODE_POWER4 | PPC_OPCODE_POWER5 | PPC_OPCODE_POWER6 153 | PPC_OPCODE_POWER7 | PPC_OPCODE_ALTIVEC | PPC_OPCODE_VSX), 154 0 }, 155 { "power8", (PPC_OPCODE_PPC | PPC_OPCODE_ISEL | PPC_OPCODE_64 156 | PPC_OPCODE_POWER4 | PPC_OPCODE_POWER5 | PPC_OPCODE_POWER6 157 | PPC_OPCODE_POWER7 | PPC_OPCODE_POWER8 | PPC_OPCODE_HTM 158 | PPC_OPCODE_ALTIVEC | PPC_OPCODE_ALTIVEC2 | PPC_OPCODE_VSX), 159 0 }, 160 { "power9", (PPC_OPCODE_PPC | PPC_OPCODE_ISEL | PPC_OPCODE_64 161 | PPC_OPCODE_POWER4 | PPC_OPCODE_POWER5 | PPC_OPCODE_POWER6 162 | PPC_OPCODE_POWER7 | PPC_OPCODE_POWER8 | PPC_OPCODE_POWER9 163 | PPC_OPCODE_HTM | PPC_OPCODE_ALTIVEC | PPC_OPCODE_ALTIVEC2 164 | PPC_OPCODE_VSX | PPC_OPCODE_VSX3 ), 165 0 }, 166 { "ppc", PPC_OPCODE_PPC, 167 0 }, 168 { "ppc32", PPC_OPCODE_PPC, 169 0 }, 170 { "ppc64", PPC_OPCODE_PPC | PPC_OPCODE_64, 171 0 }, 172 { "ppc64bridge", PPC_OPCODE_PPC | PPC_OPCODE_64_BRIDGE, 173 0 }, 174 { "ppcps", PPC_OPCODE_PPC | PPC_OPCODE_PPCPS, 175 0 }, 176 { "pwr", PPC_OPCODE_POWER, 177 0 }, 178 { "pwr2", PPC_OPCODE_POWER | PPC_OPCODE_POWER2, 179 0 }, 180 { "pwr4", PPC_OPCODE_PPC | PPC_OPCODE_64 | PPC_OPCODE_POWER4, 181 0 }, 182 { "pwr5", (PPC_OPCODE_PPC | PPC_OPCODE_64 | PPC_OPCODE_POWER4 183 | PPC_OPCODE_POWER5), 184 0 }, 185 { "pwr5x", (PPC_OPCODE_PPC | PPC_OPCODE_64 | PPC_OPCODE_POWER4 186 | PPC_OPCODE_POWER5), 187 0 }, 188 { "pwr6", (PPC_OPCODE_PPC | PPC_OPCODE_64 | PPC_OPCODE_POWER4 189 | PPC_OPCODE_POWER5 | PPC_OPCODE_POWER6 | PPC_OPCODE_ALTIVEC), 190 0 }, 191 { "pwr7", (PPC_OPCODE_PPC | PPC_OPCODE_ISEL | PPC_OPCODE_64 192 | PPC_OPCODE_POWER4 | PPC_OPCODE_POWER5 | PPC_OPCODE_POWER6 193 | PPC_OPCODE_POWER7 | PPC_OPCODE_ALTIVEC | PPC_OPCODE_VSX), 194 0 }, 195 { "pwr8", (PPC_OPCODE_PPC | PPC_OPCODE_ISEL | PPC_OPCODE_64 196 | PPC_OPCODE_POWER4 | PPC_OPCODE_POWER5 | PPC_OPCODE_POWER6 197 | PPC_OPCODE_POWER7 | PPC_OPCODE_POWER8 | PPC_OPCODE_HTM 198 | PPC_OPCODE_ALTIVEC | PPC_OPCODE_ALTIVEC2 | PPC_OPCODE_VSX), 199 0 }, 200 { "pwr9", (PPC_OPCODE_PPC | PPC_OPCODE_ISEL | PPC_OPCODE_64 201 | PPC_OPCODE_POWER4 | PPC_OPCODE_POWER5 | PPC_OPCODE_POWER6 202 | PPC_OPCODE_POWER7 | PPC_OPCODE_POWER8 | PPC_OPCODE_POWER9 203 | PPC_OPCODE_HTM | PPC_OPCODE_ALTIVEC | PPC_OPCODE_ALTIVEC2 204 | PPC_OPCODE_VSX | PPC_OPCODE_VSX3 ), 205 0 }, 206 { "pwrx", PPC_OPCODE_POWER | PPC_OPCODE_POWER2, 207 0 }, 208 { "spe", PPC_OPCODE_PPC | PPC_OPCODE_EFS, 209 PPC_OPCODE_SPE }, 210 { "titan", (PPC_OPCODE_PPC | PPC_OPCODE_BOOKE | PPC_OPCODE_PMR 211 | PPC_OPCODE_RFMCI | PPC_OPCODE_TITAN), 212 0 }, 213 { "vle", (PPC_OPCODE_PPC | PPC_OPCODE_BOOKE| PPC_OPCODE_SPE 214 | PPC_OPCODE_ISEL | PPC_OPCODE_EFS | PPC_OPCODE_BRLOCK 215 | PPC_OPCODE_PMR | PPC_OPCODE_CACHELCK | PPC_OPCODE_RFMCI 216 | PPC_OPCODE_E500), 217 PPC_OPCODE_VLE }, 218 { "vsx", PPC_OPCODE_PPC, 219 PPC_OPCODE_VSX }, 220 { "htm", PPC_OPCODE_PPC, 221 PPC_OPCODE_HTM }, 222 }; 223 224 /* Switch between Booke and VLE dialects for interlinked dumps. */ 225 static ppc_cpu_t 226 get_powerpc_dialect (struct disassemble_info *info) 227 { 228 ppc_cpu_t dialect = 0; 229 230 dialect = POWERPC_DIALECT (info); 231 232 /* Disassemble according to the section headers flags for VLE-mode. */ 233 if (dialect & PPC_OPCODE_VLE 234 && info->section->owner != NULL 235 && bfd_get_flavour (info->section->owner) == bfd_target_elf_flavour 236 && elf_object_id (info->section->owner) == PPC32_ELF_DATA 237 && (elf_section_flags (info->section) & SHF_PPC_VLE) != 0) 238 return dialect; 239 else 240 return dialect & ~ PPC_OPCODE_VLE; 241 } 242 243 /* Handle -m and -M options that set cpu type, and .machine arg. */ 244 245 ppc_cpu_t 246 ppc_parse_cpu (ppc_cpu_t ppc_cpu, ppc_cpu_t *sticky, const char *arg) 247 { 248 unsigned int i; 249 250 for (i = 0; i < sizeof (ppc_opts) / sizeof (ppc_opts[0]); i++) 251 if (strcmp (ppc_opts[i].opt, arg) == 0) 252 { 253 if (ppc_opts[i].sticky) 254 { 255 *sticky |= ppc_opts[i].sticky; 256 if ((ppc_cpu & ~*sticky) != 0) 257 break; 258 } 259 ppc_cpu = ppc_opts[i].cpu; 260 break; 261 } 262 if (i >= sizeof (ppc_opts) / sizeof (ppc_opts[0])) 263 return 0; 264 265 ppc_cpu |= *sticky; 266 return ppc_cpu; 267 } 268 269 /* Determine which set of machines to disassemble for. */ 270 271 static void 272 powerpc_init_dialect (struct disassemble_info *info) 273 { 274 ppc_cpu_t dialect = 0; 275 ppc_cpu_t sticky = 0; 276 char *arg; 277 struct dis_private *priv = calloc (sizeof (*priv), 1); 278 279 if (priv == NULL) 280 priv = &private; 281 282 switch (info->mach) 283 { 284 case bfd_mach_ppc_403: 285 case bfd_mach_ppc_403gc: 286 dialect = ppc_parse_cpu (dialect, &sticky, "403"); 287 break; 288 case bfd_mach_ppc_405: 289 dialect = ppc_parse_cpu (dialect, &sticky, "405"); 290 break; 291 case bfd_mach_ppc_601: 292 dialect = ppc_parse_cpu (dialect, &sticky, "601"); 293 break; 294 case bfd_mach_ppc_a35: 295 case bfd_mach_ppc_rs64ii: 296 case bfd_mach_ppc_rs64iii: 297 dialect = ppc_parse_cpu (dialect, &sticky, "pwr2") | PPC_OPCODE_64; 298 break; 299 case bfd_mach_ppc_e500: 300 dialect = ppc_parse_cpu (dialect, &sticky, "e500"); 301 break; 302 case bfd_mach_ppc_e500mc: 303 dialect = ppc_parse_cpu (dialect, &sticky, "e500mc"); 304 break; 305 case bfd_mach_ppc_e500mc64: 306 dialect = ppc_parse_cpu (dialect, &sticky, "e500mc64"); 307 break; 308 case bfd_mach_ppc_e5500: 309 dialect = ppc_parse_cpu (dialect, &sticky, "e5500"); 310 break; 311 case bfd_mach_ppc_e6500: 312 dialect = ppc_parse_cpu (dialect, &sticky, "e6500"); 313 break; 314 case bfd_mach_ppc_titan: 315 dialect = ppc_parse_cpu (dialect, &sticky, "titan"); 316 break; 317 case bfd_mach_ppc_vle: 318 dialect = ppc_parse_cpu (dialect, &sticky, "vle"); 319 break; 320 default: 321 dialect = ppc_parse_cpu (dialect, &sticky, "power9") | PPC_OPCODE_ANY; 322 } 323 324 arg = info->disassembler_options; 325 while (arg != NULL) 326 { 327 ppc_cpu_t new_cpu = 0; 328 char *end = strchr (arg, ','); 329 330 if (end != NULL) 331 *end = 0; 332 333 if ((new_cpu = ppc_parse_cpu (dialect, &sticky, arg)) != 0) 334 dialect = new_cpu; 335 else if (strcmp (arg, "32") == 0) 336 dialect &= ~(ppc_cpu_t) PPC_OPCODE_64; 337 else if (strcmp (arg, "64") == 0) 338 dialect |= PPC_OPCODE_64; 339 else 340 fprintf (stderr, _("warning: ignoring unknown -M%s option\n"), arg); 341 342 if (end != NULL) 343 *end++ = ','; 344 arg = end; 345 } 346 347 info->private_data = priv; 348 POWERPC_DIALECT(info) = dialect; 349 } 350 351 #define PPC_OPCD_SEGS 64 352 static unsigned short powerpc_opcd_indices[PPC_OPCD_SEGS+1]; 353 #define VLE_OPCD_SEGS 32 354 static unsigned short vle_opcd_indices[VLE_OPCD_SEGS+1]; 355 356 /* Calculate opcode table indices to speed up disassembly, 357 and init dialect. */ 358 359 void 360 disassemble_init_powerpc (struct disassemble_info *info) 361 { 362 int i; 363 unsigned short last; 364 365 if (powerpc_opcd_indices[PPC_OPCD_SEGS] == 0) 366 { 367 368 i = powerpc_num_opcodes; 369 while (--i >= 0) 370 { 371 unsigned op = PPC_OP (powerpc_opcodes[i].opcode); 372 373 powerpc_opcd_indices[op] = i; 374 } 375 376 last = powerpc_num_opcodes; 377 for (i = PPC_OPCD_SEGS; i > 0; --i) 378 { 379 if (powerpc_opcd_indices[i] == 0) 380 powerpc_opcd_indices[i] = last; 381 last = powerpc_opcd_indices[i]; 382 } 383 384 i = vle_num_opcodes; 385 while (--i >= 0) 386 { 387 unsigned op = VLE_OP (vle_opcodes[i].opcode, vle_opcodes[i].mask); 388 unsigned seg = VLE_OP_TO_SEG (op); 389 390 vle_opcd_indices[seg] = i; 391 } 392 393 last = vle_num_opcodes; 394 for (i = VLE_OPCD_SEGS; i > 0; --i) 395 { 396 if (vle_opcd_indices[i] == 0) 397 vle_opcd_indices[i] = last; 398 last = vle_opcd_indices[i]; 399 } 400 } 401 402 if (info->arch == bfd_arch_powerpc) 403 powerpc_init_dialect (info); 404 } 405 406 /* Print a big endian PowerPC instruction. */ 407 408 int 409 print_insn_big_powerpc (bfd_vma memaddr, struct disassemble_info *info) 410 { 411 return print_insn_powerpc (memaddr, info, 1, get_powerpc_dialect (info)); 412 } 413 414 /* Print a little endian PowerPC instruction. */ 415 416 int 417 print_insn_little_powerpc (bfd_vma memaddr, struct disassemble_info *info) 418 { 419 return print_insn_powerpc (memaddr, info, 0, get_powerpc_dialect (info)); 420 } 421 422 /* Print a POWER (RS/6000) instruction. */ 423 424 int 425 print_insn_rs6000 (bfd_vma memaddr, struct disassemble_info *info) 426 { 427 return print_insn_powerpc (memaddr, info, 1, PPC_OPCODE_POWER); 428 } 429 430 /* Extract the operand value from the PowerPC or POWER instruction. */ 431 432 static long 433 operand_value_powerpc (const struct powerpc_operand *operand, 434 unsigned long insn, ppc_cpu_t dialect) 435 { 436 long value; 437 int invalid; 438 /* Extract the value from the instruction. */ 439 if (operand->extract) 440 value = (*operand->extract) (insn, dialect, &invalid); 441 else 442 { 443 if (operand->shift >= 0) 444 value = (insn >> operand->shift) & operand->bitm; 445 else 446 value = (insn << -operand->shift) & operand->bitm; 447 if ((operand->flags & PPC_OPERAND_SIGNED) != 0) 448 { 449 /* BITM is always some number of zeros followed by some 450 number of ones, followed by some number of zeros. */ 451 unsigned long top = operand->bitm; 452 /* top & -top gives the rightmost 1 bit, so this 453 fills in any trailing zeros. */ 454 top |= (top & -top) - 1; 455 top &= ~(top >> 1); 456 value = (value ^ top) - top; 457 } 458 } 459 460 return value; 461 } 462 463 /* Determine whether the optional operand(s) should be printed. */ 464 465 static int 466 skip_optional_operands (const unsigned char *opindex, 467 unsigned long insn, ppc_cpu_t dialect) 468 { 469 const struct powerpc_operand *operand; 470 471 for (; *opindex != 0; opindex++) 472 { 473 operand = &powerpc_operands[*opindex]; 474 if ((operand->flags & PPC_OPERAND_NEXT) != 0 475 || ((operand->flags & PPC_OPERAND_OPTIONAL) != 0 476 && operand_value_powerpc (operand, insn, dialect) != 477 ppc_optional_operand_value (operand))) 478 return 0; 479 } 480 481 return 1; 482 } 483 484 /* Find a match for INSN in the opcode table, given machine DIALECT. 485 A DIALECT of -1 is special, matching all machine opcode variations. */ 486 487 static const struct powerpc_opcode * 488 lookup_powerpc (unsigned long insn, ppc_cpu_t dialect) 489 { 490 const struct powerpc_opcode *opcode; 491 const struct powerpc_opcode *opcode_end; 492 unsigned long op; 493 494 /* Get the major opcode of the instruction. */ 495 op = PPC_OP (insn); 496 497 /* Find the first match in the opcode table for this major opcode. */ 498 opcode_end = powerpc_opcodes + powerpc_opcd_indices[op + 1]; 499 for (opcode = powerpc_opcodes + powerpc_opcd_indices[op]; 500 opcode < opcode_end; 501 ++opcode) 502 { 503 const unsigned char *opindex; 504 const struct powerpc_operand *operand; 505 int invalid; 506 507 if ((insn & opcode->mask) != opcode->opcode 508 || (dialect != (ppc_cpu_t) -1 509 && ((opcode->flags & dialect) == 0 510 || (opcode->deprecated & dialect) != 0))) 511 continue; 512 513 /* Check validity of operands. */ 514 invalid = 0; 515 for (opindex = opcode->operands; *opindex != 0; opindex++) 516 { 517 operand = powerpc_operands + *opindex; 518 if (operand->extract) 519 (*operand->extract) (insn, dialect, &invalid); 520 } 521 if (invalid) 522 continue; 523 524 return opcode; 525 } 526 527 return NULL; 528 } 529 530 /* Find a match for INSN in the VLE opcode table. */ 531 532 static const struct powerpc_opcode * 533 lookup_vle (unsigned long insn) 534 { 535 const struct powerpc_opcode *opcode; 536 const struct powerpc_opcode *opcode_end; 537 unsigned op, seg; 538 539 op = PPC_OP (insn); 540 if (op >= 0x20 && op <= 0x37) 541 { 542 /* This insn has a 4-bit opcode. */ 543 op &= 0x3c; 544 } 545 seg = VLE_OP_TO_SEG (op); 546 547 /* Find the first match in the opcode table for this major opcode. */ 548 opcode_end = vle_opcodes + vle_opcd_indices[seg + 1]; 549 for (opcode = vle_opcodes + vle_opcd_indices[seg]; 550 opcode < opcode_end; 551 ++opcode) 552 { 553 unsigned long table_opcd = opcode->opcode; 554 unsigned long table_mask = opcode->mask; 555 bfd_boolean table_op_is_short = PPC_OP_SE_VLE(table_mask); 556 unsigned long insn2; 557 const unsigned char *opindex; 558 const struct powerpc_operand *operand; 559 int invalid; 560 561 insn2 = insn; 562 if (table_op_is_short) 563 insn2 >>= 16; 564 if ((insn2 & table_mask) != table_opcd) 565 continue; 566 567 /* Check validity of operands. */ 568 invalid = 0; 569 for (opindex = opcode->operands; *opindex != 0; ++opindex) 570 { 571 operand = powerpc_operands + *opindex; 572 if (operand->extract) 573 (*operand->extract) (insn, (ppc_cpu_t)0, &invalid); 574 } 575 if (invalid) 576 continue; 577 578 return opcode; 579 } 580 581 return NULL; 582 } 583 584 /* Print a PowerPC or POWER instruction. */ 585 586 static int 587 print_insn_powerpc (bfd_vma memaddr, 588 struct disassemble_info *info, 589 int bigendian, 590 ppc_cpu_t dialect) 591 { 592 bfd_byte buffer[4]; 593 int status; 594 unsigned long insn; 595 const struct powerpc_opcode *opcode; 596 bfd_boolean insn_is_short; 597 598 status = (*info->read_memory_func) (memaddr, buffer, 4, info); 599 if (status != 0) 600 { 601 /* The final instruction may be a 2-byte VLE insn. */ 602 if ((dialect & PPC_OPCODE_VLE) != 0) 603 { 604 /* Clear buffer so unused bytes will not have garbage in them. */ 605 buffer[0] = buffer[1] = buffer[2] = buffer[3] = 0; 606 status = (*info->read_memory_func) (memaddr, buffer, 2, info); 607 if (status != 0) 608 { 609 (*info->memory_error_func) (status, memaddr, info); 610 return -1; 611 } 612 } 613 else 614 { 615 (*info->memory_error_func) (status, memaddr, info); 616 return -1; 617 } 618 } 619 620 if (bigendian) 621 insn = bfd_getb32 (buffer); 622 else 623 insn = bfd_getl32 (buffer); 624 625 /* Get the major opcode of the insn. */ 626 opcode = NULL; 627 insn_is_short = FALSE; 628 if ((dialect & PPC_OPCODE_VLE) != 0) 629 { 630 opcode = lookup_vle (insn); 631 if (opcode != NULL) 632 insn_is_short = PPC_OP_SE_VLE(opcode->mask); 633 } 634 if (opcode == NULL) 635 opcode = lookup_powerpc (insn, dialect); 636 if (opcode == NULL && (dialect & PPC_OPCODE_ANY) != 0) 637 opcode = lookup_powerpc (insn, (ppc_cpu_t) -1); 638 639 if (opcode != NULL) 640 { 641 const unsigned char *opindex; 642 const struct powerpc_operand *operand; 643 int need_comma; 644 int need_paren; 645 int skip_optional; 646 647 if (opcode->operands[0] != 0) 648 (*info->fprintf_func) (info->stream, "%-7s ", opcode->name); 649 else 650 (*info->fprintf_func) (info->stream, "%s", opcode->name); 651 652 if (insn_is_short) 653 /* The operands will be fetched out of the 16-bit instruction. */ 654 insn >>= 16; 655 656 /* Now extract and print the operands. */ 657 need_comma = 0; 658 need_paren = 0; 659 skip_optional = -1; 660 for (opindex = opcode->operands; *opindex != 0; opindex++) 661 { 662 long value; 663 664 operand = powerpc_operands + *opindex; 665 666 /* Operands that are marked FAKE are simply ignored. We 667 already made sure that the extract function considered 668 the instruction to be valid. */ 669 if ((operand->flags & PPC_OPERAND_FAKE) != 0) 670 continue; 671 672 /* If all of the optional operands have the value zero, 673 then don't print any of them. */ 674 if ((operand->flags & PPC_OPERAND_OPTIONAL) != 0) 675 { 676 if (skip_optional < 0) 677 skip_optional = skip_optional_operands (opindex, insn, 678 dialect); 679 if (skip_optional) 680 continue; 681 } 682 683 value = operand_value_powerpc (operand, insn, dialect); 684 685 if (need_comma) 686 { 687 (*info->fprintf_func) (info->stream, ","); 688 need_comma = 0; 689 } 690 691 /* Print the operand as directed by the flags. */ 692 if ((operand->flags & PPC_OPERAND_GPR) != 0 693 || ((operand->flags & PPC_OPERAND_GPR_0) != 0 && value != 0)) 694 (*info->fprintf_func) (info->stream, "r%ld", value); 695 else if ((operand->flags & PPC_OPERAND_FPR) != 0) 696 (*info->fprintf_func) (info->stream, "f%ld", value); 697 else if ((operand->flags & PPC_OPERAND_VR) != 0) 698 (*info->fprintf_func) (info->stream, "v%ld", value); 699 else if ((operand->flags & PPC_OPERAND_VSR) != 0) 700 (*info->fprintf_func) (info->stream, "vs%ld", value); 701 else if ((operand->flags & PPC_OPERAND_RELATIVE) != 0) 702 (*info->print_address_func) (memaddr + value, info); 703 else if ((operand->flags & PPC_OPERAND_ABSOLUTE) != 0) 704 (*info->print_address_func) ((bfd_vma) value & 0xffffffff, info); 705 else if ((operand->flags & PPC_OPERAND_FSL) != 0) 706 (*info->fprintf_func) (info->stream, "fsl%ld", value); 707 else if ((operand->flags & PPC_OPERAND_FCR) != 0) 708 (*info->fprintf_func) (info->stream, "fcr%ld", value); 709 else if ((operand->flags & PPC_OPERAND_UDI) != 0) 710 (*info->fprintf_func) (info->stream, "%ld", value); 711 else if ((operand->flags & PPC_OPERAND_CR_REG) != 0 712 && (((dialect & PPC_OPCODE_PPC) != 0) 713 || ((dialect & PPC_OPCODE_VLE) != 0))) 714 (*info->fprintf_func) (info->stream, "cr%ld", value); 715 else if (((operand->flags & PPC_OPERAND_CR_BIT) != 0) 716 && (((dialect & PPC_OPCODE_PPC) != 0) 717 || ((dialect & PPC_OPCODE_VLE) != 0))) 718 { 719 static const char *cbnames[4] = { "lt", "gt", "eq", "so" }; 720 int cr; 721 int cc; 722 723 cr = value >> 2; 724 if (cr != 0) 725 (*info->fprintf_func) (info->stream, "4*cr%d+", cr); 726 cc = value & 3; 727 (*info->fprintf_func) (info->stream, "%s", cbnames[cc]); 728 } 729 else 730 (*info->fprintf_func) (info->stream, "%d", (int) value); 731 732 if (need_paren) 733 { 734 (*info->fprintf_func) (info->stream, ")"); 735 need_paren = 0; 736 } 737 738 if ((operand->flags & PPC_OPERAND_PARENS) == 0) 739 need_comma = 1; 740 else 741 { 742 (*info->fprintf_func) (info->stream, "("); 743 need_paren = 1; 744 } 745 } 746 747 /* We have found and printed an instruction. 748 If it was a short VLE instruction we have more to do. */ 749 if (insn_is_short) 750 { 751 memaddr += 2; 752 return 2; 753 } 754 else 755 /* Otherwise, return. */ 756 return 4; 757 } 758 759 /* We could not find a match. */ 760 (*info->fprintf_func) (info->stream, ".long 0x%lx", insn); 761 762 return 4; 763 } 764 765 void 766 print_ppc_disassembler_options (FILE *stream) 767 { 768 unsigned int i, col; 769 770 fprintf (stream, _("\n\ 771 The following PPC specific disassembler options are supported for use with\n\ 772 the -M switch:\n")); 773 774 for (col = 0, i = 0; i < sizeof (ppc_opts) / sizeof (ppc_opts[0]); i++) 775 { 776 col += fprintf (stream, " %s,", ppc_opts[i].opt); 777 if (col > 66) 778 { 779 fprintf (stream, "\n"); 780 col = 0; 781 } 782 } 783 fprintf (stream, " 32, 64\n"); 784 } 785