1/* ppc-dis.c -- Disassemble PowerPC instructions 2 Copyright 1994, 1995, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 3 2008, 2009, 2010 Free Software Foundation, Inc. 4 Written by Ian Lance Taylor, Cygnus Support 5 6 This file is part of the GNU opcodes library. 7 8 This library is free software; you can redistribute it and/or modify 9 it under the terms of the GNU General Public License as published by 10 the Free Software Foundation; either version 3, or (at your option) 11 any later version. 12 13 It is distributed in the hope that it will be useful, but WITHOUT 14 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 15 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public 16 License for more details. 17 18 You should have received a copy of the GNU General Public License 19 along with this file; see the file COPYING. If not, write to the 20 Free Software Foundation, 51 Franklin Street - Fifth Floor, Boston, 21 MA 02110-1301, USA. */ 22 23#include <stdio.h> 24#include "sysdep.h" 25#include "dis-asm.h" 26#include "opintl.h" 27#include "opcode/ppc.h" 28 29/* This file provides several disassembler functions, all of which use 30 the disassembler interface defined in dis-asm.h. Several functions 31 are provided because this file handles disassembly for the PowerPC 32 in both big and little endian mode and also for the POWER (RS/6000) 33 chip. */ 34static int print_insn_powerpc (bfd_vma, struct disassemble_info *, int, 35 ppc_cpu_t); 36 37struct dis_private 38{ 39 /* Stash the result of parsing disassembler_options here. */ 40 ppc_cpu_t dialect; 41}; 42 43#define POWERPC_DIALECT(INFO) \ 44 (((struct dis_private *) ((INFO)->private_data))->dialect) 45 46struct ppc_mopt { 47 const char *opt; 48 ppc_cpu_t cpu; 49 ppc_cpu_t sticky; 50}; 51 52struct ppc_mopt ppc_opts[] = { 53 { "403", (PPC_OPCODE_PPC | PPC_OPCODE_403), 54 0 }, 55 { "405", (PPC_OPCODE_PPC | PPC_OPCODE_403 | PPC_OPCODE_405), 56 0 }, 57 { "440", (PPC_OPCODE_PPC | PPC_OPCODE_BOOKE | PPC_OPCODE_440 58 | PPC_OPCODE_ISEL | PPC_OPCODE_RFMCI), 59 0 }, 60 { "464", (PPC_OPCODE_PPC | PPC_OPCODE_BOOKE | PPC_OPCODE_440 61 | PPC_OPCODE_ISEL | PPC_OPCODE_RFMCI), 62 0 }, 63 { "476", (PPC_OPCODE_PPC | PPC_OPCODE_ISEL | PPC_OPCODE_440 64 | PPC_OPCODE_476 | PPC_OPCODE_POWER4 | PPC_OPCODE_POWER5), 65 0 }, 66 { "601", (PPC_OPCODE_PPC | PPC_OPCODE_601), 67 0 }, 68 { "603", (PPC_OPCODE_PPC), 69 0 }, 70 { "604", (PPC_OPCODE_PPC), 71 0 }, 72 { "620", (PPC_OPCODE_PPC | PPC_OPCODE_64), 73 0 }, 74 { "7400", (PPC_OPCODE_PPC | PPC_OPCODE_ALTIVEC), 75 0 }, 76 { "7410", (PPC_OPCODE_PPC | PPC_OPCODE_ALTIVEC), 77 0 }, 78 { "7450", (PPC_OPCODE_PPC | PPC_OPCODE_ALTIVEC), 79 0 }, 80 { "7455", (PPC_OPCODE_PPC | PPC_OPCODE_ALTIVEC), 81 0 }, 82 { "750cl", (PPC_OPCODE_PPC | PPC_OPCODE_PPCPS) 83 , 0 }, 84 { "a2", (PPC_OPCODE_PPC | PPC_OPCODE_ISEL | PPC_OPCODE_POWER4 85 | PPC_OPCODE_POWER5 | PPC_OPCODE_CACHELCK | PPC_OPCODE_64 86 | PPC_OPCODE_A2), 87 0 }, 88 { "altivec", (PPC_OPCODE_PPC), 89 PPC_OPCODE_ALTIVEC }, 90 { "any", 0, 91 PPC_OPCODE_ANY }, 92 { "booke", (PPC_OPCODE_PPC | PPC_OPCODE_BOOKE), 93 0 }, 94 { "booke32", (PPC_OPCODE_PPC | PPC_OPCODE_BOOKE), 95 0 }, 96 { "cell", (PPC_OPCODE_PPC | PPC_OPCODE_64 | PPC_OPCODE_POWER4 97 | PPC_OPCODE_CELL | PPC_OPCODE_ALTIVEC), 98 0 }, 99 { "com", (PPC_OPCODE_COMMON), 100 0 }, 101 { "e300", (PPC_OPCODE_PPC | PPC_OPCODE_E300), 102 0 }, 103 { "e500", (PPC_OPCODE_PPC | PPC_OPCODE_BOOKE | PPC_OPCODE_SPE 104 | PPC_OPCODE_ISEL | PPC_OPCODE_EFS | PPC_OPCODE_BRLOCK 105 | PPC_OPCODE_PMR | PPC_OPCODE_CACHELCK | PPC_OPCODE_RFMCI 106 | PPC_OPCODE_E500), 107 0 }, 108 { "e500mc", (PPC_OPCODE_PPC | PPC_OPCODE_BOOKE | PPC_OPCODE_ISEL 109 | PPC_OPCODE_PMR | PPC_OPCODE_CACHELCK | PPC_OPCODE_RFMCI 110 | PPC_OPCODE_E500MC), 111 0 }, 112 { "e500mc64", (PPC_OPCODE_PPC | PPC_OPCODE_BOOKE | PPC_OPCODE_ISEL 113 | PPC_OPCODE_PMR | PPC_OPCODE_CACHELCK | PPC_OPCODE_RFMCI 114 | PPC_OPCODE_E500MC | PPC_OPCODE_64 | PPC_OPCODE_POWER5 115 | PPC_OPCODE_POWER6 | PPC_OPCODE_POWER7), 116 0 }, 117 { "e500x2", (PPC_OPCODE_PPC | PPC_OPCODE_BOOKE | PPC_OPCODE_SPE 118 | PPC_OPCODE_ISEL | PPC_OPCODE_EFS | PPC_OPCODE_BRLOCK 119 | PPC_OPCODE_PMR | PPC_OPCODE_CACHELCK | PPC_OPCODE_RFMCI 120 | PPC_OPCODE_E500), 121 0 }, 122 { "efs", (PPC_OPCODE_PPC | PPC_OPCODE_EFS), 123 0 }, 124 { "power4", (PPC_OPCODE_PPC | PPC_OPCODE_64 | PPC_OPCODE_POWER4), 125 0 }, 126 { "power5", (PPC_OPCODE_PPC | PPC_OPCODE_64 | PPC_OPCODE_POWER4 127 | PPC_OPCODE_POWER5), 128 0 }, 129 { "power6", (PPC_OPCODE_PPC | PPC_OPCODE_64 | PPC_OPCODE_POWER4 130 | PPC_OPCODE_POWER5 | PPC_OPCODE_POWER6 | PPC_OPCODE_ALTIVEC), 131 0 }, 132 { "power7", (PPC_OPCODE_PPC | PPC_OPCODE_ISEL | PPC_OPCODE_64 133 | PPC_OPCODE_POWER4 | PPC_OPCODE_POWER5 | PPC_OPCODE_POWER6 134 | PPC_OPCODE_POWER7 | PPC_OPCODE_ALTIVEC | PPC_OPCODE_VSX), 135 0 }, 136 { "ppc", (PPC_OPCODE_PPC), 137 0 }, 138 { "ppc32", (PPC_OPCODE_PPC), 139 0 }, 140 { "ppc64", (PPC_OPCODE_PPC | PPC_OPCODE_64), 141 0 }, 142 { "ppc64bridge", (PPC_OPCODE_PPC | PPC_OPCODE_64_BRIDGE), 143 0 }, 144 { "ppcps", (PPC_OPCODE_PPC | PPC_OPCODE_PPCPS), 145 0 }, 146 { "pwr", (PPC_OPCODE_POWER), 147 0 }, 148 { "pwr2", (PPC_OPCODE_POWER | PPC_OPCODE_POWER2), 149 0 }, 150 { "pwr4", (PPC_OPCODE_PPC | PPC_OPCODE_64 | PPC_OPCODE_POWER4), 151 0 }, 152 { "pwr5", (PPC_OPCODE_PPC | PPC_OPCODE_64 | PPC_OPCODE_POWER4 153 | PPC_OPCODE_POWER5), 154 0 }, 155 { "pwr5x", (PPC_OPCODE_PPC | PPC_OPCODE_64 | PPC_OPCODE_POWER4 156 | PPC_OPCODE_POWER5), 157 0 }, 158 { "pwr6", (PPC_OPCODE_PPC | PPC_OPCODE_64 | PPC_OPCODE_POWER4 159 | PPC_OPCODE_POWER5 | PPC_OPCODE_POWER6 | PPC_OPCODE_ALTIVEC), 160 0 }, 161 { "pwr7", (PPC_OPCODE_PPC | PPC_OPCODE_ISEL | PPC_OPCODE_64 162 | PPC_OPCODE_POWER4 | PPC_OPCODE_POWER5 | PPC_OPCODE_POWER6 163 | PPC_OPCODE_POWER7 | PPC_OPCODE_ALTIVEC | PPC_OPCODE_VSX), 164 0 }, 165 { "pwrx", (PPC_OPCODE_POWER | PPC_OPCODE_POWER2), 166 0 }, 167 { "spe", (PPC_OPCODE_PPC | PPC_OPCODE_EFS), 168 PPC_OPCODE_SPE }, 169 { "titan", (PPC_OPCODE_PPC | PPC_OPCODE_BOOKE | PPC_OPCODE_PMR 170 | PPC_OPCODE_RFMCI | PPC_OPCODE_TITAN), 171 0 }, 172 { "vsx", (PPC_OPCODE_PPC), 173 PPC_OPCODE_VSX }, 174}; 175 176/* Handle -m and -M options that set cpu type, and .machine arg. */ 177 178ppc_cpu_t 179ppc_parse_cpu (ppc_cpu_t ppc_cpu, const char *arg) 180{ 181 /* Sticky bits. */ 182 ppc_cpu_t retain_flags = ppc_cpu & (PPC_OPCODE_ALTIVEC | PPC_OPCODE_VSX 183 | PPC_OPCODE_SPE | PPC_OPCODE_ANY); 184 unsigned int i; 185 186 for (i = 0; i < sizeof (ppc_opts) / sizeof (ppc_opts[0]); i++) 187 if (strcmp (ppc_opts[i].opt, arg) == 0) 188 { 189 if (ppc_opts[i].sticky) 190 { 191 retain_flags |= ppc_opts[i].sticky; 192 if ((ppc_cpu & ~(ppc_cpu_t) (PPC_OPCODE_ALTIVEC | PPC_OPCODE_VSX 193 | PPC_OPCODE_SPE | PPC_OPCODE_ANY)) != 0) 194 break; 195 } 196 ppc_cpu = ppc_opts[i].cpu; 197 break; 198 } 199 if (i >= sizeof (ppc_opts) / sizeof (ppc_opts[0])) 200 return 0; 201 202 ppc_cpu |= retain_flags; 203 return ppc_cpu; 204} 205 206/* Determine which set of machines to disassemble for. */ 207 208static int 209powerpc_init_dialect (struct disassemble_info *info) 210{ 211 ppc_cpu_t dialect = 0; 212 char *arg; 213 struct dis_private *priv = calloc (sizeof (*priv), 1); 214 215 if (priv == NULL) 216 return FALSE; 217 218 arg = info->disassembler_options; 219 while (arg != NULL) 220 { 221 ppc_cpu_t new_cpu = 0; 222 char *end = strchr (arg, ','); 223 224 if (end != NULL) 225 *end = 0; 226 227 if ((new_cpu = ppc_parse_cpu (dialect, arg)) != 0) 228 dialect = new_cpu; 229 else if (strcmp (arg, "32") == 0) 230 dialect &= ~(ppc_cpu_t) PPC_OPCODE_64; 231 else if (strcmp (arg, "64") == 0) 232 dialect |= PPC_OPCODE_64; 233 else 234 fprintf (stderr, _("warning: ignoring unknown -M%s option\n"), arg); 235 236 if (end != NULL) 237 *end++ = ','; 238 arg = end; 239 } 240 241 if ((dialect & ~(ppc_cpu_t) PPC_OPCODE_64) == 0) 242 { 243 if (info->mach == bfd_mach_ppc64) 244 dialect |= PPC_OPCODE_64; 245 else 246 dialect &= ~(ppc_cpu_t) PPC_OPCODE_64; 247 /* Choose a reasonable default. */ 248 dialect |= (PPC_OPCODE_PPC | PPC_OPCODE_COMMON | PPC_OPCODE_601 249 | PPC_OPCODE_ALTIVEC); 250 } 251 252 info->private_data = priv; 253 POWERPC_DIALECT(info) = dialect; 254 255 return TRUE; 256} 257 258/* Print a big endian PowerPC instruction. */ 259 260int 261print_insn_big_powerpc (bfd_vma memaddr, struct disassemble_info *info) 262{ 263 if (info->private_data == NULL && !powerpc_init_dialect (info)) 264 return -1; 265 return print_insn_powerpc (memaddr, info, 1, POWERPC_DIALECT(info)); 266} 267 268/* Print a little endian PowerPC instruction. */ 269 270int 271print_insn_little_powerpc (bfd_vma memaddr, struct disassemble_info *info) 272{ 273 if (info->private_data == NULL && !powerpc_init_dialect (info)) 274 return -1; 275 return print_insn_powerpc (memaddr, info, 0, POWERPC_DIALECT(info)); 276} 277 278/* Print a POWER (RS/6000) instruction. */ 279 280int 281print_insn_rs6000 (bfd_vma memaddr, struct disassemble_info *info) 282{ 283 return print_insn_powerpc (memaddr, info, 1, PPC_OPCODE_POWER); 284} 285 286/* Extract the operand value from the PowerPC or POWER instruction. */ 287 288static long 289operand_value_powerpc (const struct powerpc_operand *operand, 290 unsigned long insn, ppc_cpu_t dialect) 291{ 292 long value; 293 int invalid; 294 /* Extract the value from the instruction. */ 295 if (operand->extract) 296 value = (*operand->extract) (insn, dialect, &invalid); 297 else 298 { 299 value = (insn >> operand->shift) & operand->bitm; 300 if ((operand->flags & PPC_OPERAND_SIGNED) != 0) 301 { 302 /* BITM is always some number of zeros followed by some 303 number of ones, followed by some numer of zeros. */ 304 unsigned long top = operand->bitm; 305 /* top & -top gives the rightmost 1 bit, so this 306 fills in any trailing zeros. */ 307 top |= (top & -top) - 1; 308 top &= ~(top >> 1); 309 value = (value ^ top) - top; 310 } 311 } 312 313 return value; 314} 315 316/* Determine whether the optional operand(s) should be printed. */ 317 318static int 319skip_optional_operands (const unsigned char *opindex, 320 unsigned long insn, ppc_cpu_t dialect) 321{ 322 const struct powerpc_operand *operand; 323 324 for (; *opindex != 0; opindex++) 325 { 326 operand = &powerpc_operands[*opindex]; 327 if ((operand->flags & PPC_OPERAND_NEXT) != 0 328 || ((operand->flags & PPC_OPERAND_OPTIONAL) != 0 329 && operand_value_powerpc (operand, insn, dialect) != 0)) 330 return 0; 331 } 332 333 return 1; 334} 335 336/* Print a PowerPC or POWER instruction. */ 337 338static int 339print_insn_powerpc (bfd_vma memaddr, 340 struct disassemble_info *info, 341 int bigendian, 342 ppc_cpu_t dialect) 343{ 344 bfd_byte buffer[4]; 345 int status; 346 unsigned long insn; 347 const struct powerpc_opcode *opcode; 348 const struct powerpc_opcode *opcode_end; 349 unsigned long op; 350 ppc_cpu_t dialect_orig = dialect; 351 352 status = (*info->read_memory_func) (memaddr, buffer, 4, info); 353 if (status != 0) 354 { 355 (*info->memory_error_func) (status, memaddr, info); 356 return -1; 357 } 358 359 if (bigendian) 360 insn = bfd_getb32 (buffer); 361 else 362 insn = bfd_getl32 (buffer); 363 364 /* Get the major opcode of the instruction. */ 365 op = PPC_OP (insn); 366 367 /* Find the first match in the opcode table. We could speed this up 368 a bit by doing a binary search on the major opcode. */ 369 opcode_end = powerpc_opcodes + powerpc_num_opcodes; 370 again: 371 for (opcode = powerpc_opcodes; opcode < opcode_end; opcode++) 372 { 373 unsigned long table_op; 374 const unsigned char *opindex; 375 const struct powerpc_operand *operand; 376 int invalid; 377 int need_comma; 378 int need_paren; 379 int skip_optional; 380 381 table_op = PPC_OP (opcode->opcode); 382 if (op < table_op) 383 break; 384 if (op > table_op) 385 continue; 386 387 if ((insn & opcode->mask) != opcode->opcode 388 || (opcode->flags & dialect) == 0 389 || (opcode->deprecated & dialect_orig) != 0) 390 continue; 391 392 /* Make two passes over the operands. First see if any of them 393 have extraction functions, and, if they do, make sure the 394 instruction is valid. */ 395 invalid = 0; 396 for (opindex = opcode->operands; *opindex != 0; opindex++) 397 { 398 operand = powerpc_operands + *opindex; 399 if (operand->extract) 400 (*operand->extract) (insn, dialect, &invalid); 401 } 402 if (invalid) 403 continue; 404 405 /* The instruction is valid. */ 406 if (opcode->operands[0] != 0) 407 (*info->fprintf_func) (info->stream, "%-7s ", opcode->name); 408 else 409 (*info->fprintf_func) (info->stream, "%s", opcode->name); 410 411 /* Now extract and print the operands. */ 412 need_comma = 0; 413 need_paren = 0; 414 skip_optional = -1; 415 for (opindex = opcode->operands; *opindex != 0; opindex++) 416 { 417 long value; 418 419 operand = powerpc_operands + *opindex; 420 421 /* Operands that are marked FAKE are simply ignored. We 422 already made sure that the extract function considered 423 the instruction to be valid. */ 424 if ((operand->flags & PPC_OPERAND_FAKE) != 0) 425 continue; 426 427 /* If all of the optional operands have the value zero, 428 then don't print any of them. */ 429 if ((operand->flags & PPC_OPERAND_OPTIONAL) != 0) 430 { 431 if (skip_optional < 0) 432 skip_optional = skip_optional_operands (opindex, insn, 433 dialect); 434 if (skip_optional) 435 continue; 436 } 437 438 value = operand_value_powerpc (operand, insn, dialect); 439 440 if (need_comma) 441 { 442 (*info->fprintf_func) (info->stream, ","); 443 need_comma = 0; 444 } 445 446 /* Print the operand as directed by the flags. */ 447 if ((operand->flags & PPC_OPERAND_GPR) != 0 448 || ((operand->flags & PPC_OPERAND_GPR_0) != 0 && value != 0)) 449 (*info->fprintf_func) (info->stream, "r%ld", value); 450 else if ((operand->flags & PPC_OPERAND_FPR) != 0) 451 (*info->fprintf_func) (info->stream, "f%ld", value); 452 else if ((operand->flags & PPC_OPERAND_VR) != 0) 453 (*info->fprintf_func) (info->stream, "v%ld", value); 454 else if ((operand->flags & PPC_OPERAND_VSR) != 0) 455 (*info->fprintf_func) (info->stream, "vs%ld", value); 456 else if ((operand->flags & PPC_OPERAND_RELATIVE) != 0) 457 (*info->print_address_func) (memaddr + value, info); 458 else if ((operand->flags & PPC_OPERAND_ABSOLUTE) != 0) 459 (*info->print_address_func) ((bfd_vma) value & 0xffffffff, info); 460 else if ((operand->flags & PPC_OPERAND_FSL) != 0) 461 (*info->fprintf_func) (info->stream, "fsl%ld", value); 462 else if ((operand->flags & PPC_OPERAND_FCR) != 0) 463 (*info->fprintf_func) (info->stream, "fcr%ld", value); 464 else if ((operand->flags & PPC_OPERAND_UDI) != 0) 465 (*info->fprintf_func) (info->stream, "%ld", value); 466 else if ((operand->flags & PPC_OPERAND_CR) != 0 467 && (dialect & PPC_OPCODE_PPC) != 0) 468 { 469 if (operand->bitm == 7) 470 (*info->fprintf_func) (info->stream, "cr%ld", value); 471 else 472 { 473 static const char *cbnames[4] = { "lt", "gt", "eq", "so" }; 474 int cr; 475 int cc; 476 477 cr = value >> 2; 478 if (cr != 0) 479 (*info->fprintf_func) (info->stream, "4*cr%d+", cr); 480 cc = value & 3; 481 (*info->fprintf_func) (info->stream, "%s", cbnames[cc]); 482 } 483 } 484 else 485 (*info->fprintf_func) (info->stream, "%ld", value); 486 487 if (need_paren) 488 { 489 (*info->fprintf_func) (info->stream, ")"); 490 need_paren = 0; 491 } 492 493 if ((operand->flags & PPC_OPERAND_PARENS) == 0) 494 need_comma = 1; 495 else 496 { 497 (*info->fprintf_func) (info->stream, "("); 498 need_paren = 1; 499 } 500 } 501 502 /* We have found and printed an instruction; return. */ 503 return 4; 504 } 505 506 if ((dialect & PPC_OPCODE_ANY) != 0) 507 { 508 dialect = ~(ppc_cpu_t) PPC_OPCODE_ANY; 509 goto again; 510 } 511 512 /* We could not find a match. */ 513 (*info->fprintf_func) (info->stream, ".long 0x%lx", insn); 514 515 return 4; 516} 517 518void 519print_ppc_disassembler_options (FILE *stream) 520{ 521 unsigned int i, col; 522 523 fprintf (stream, _("\n\ 524The following PPC specific disassembler options are supported for use with\n\ 525the -M switch:\n")); 526 527 for (col = 0, i = 0; i < sizeof (ppc_opts) / sizeof (ppc_opts[0]); i++) 528 { 529 col += fprintf (stream, " %s,", ppc_opts[i].opt); 530 if (col > 66) 531 { 532 fprintf (stream, "\n"); 533 col = 0; 534 } 535 } 536 fprintf (stream, " 32, 64\n"); 537} 538