1/* ppc-dis.c -- Disassemble PowerPC instructions 2 Copyright 1994, 1995, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007 3 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 "opcode/ppc.h" 27 28/* This file provides several disassembler functions, all of which use 29 the disassembler interface defined in dis-asm.h. Several functions 30 are provided because this file handles disassembly for the PowerPC 31 in both big and little endian mode and also for the POWER (RS/6000) 32 chip. */ 33 34static int print_insn_powerpc (bfd_vma, struct disassemble_info *, int, int); 35 36/* Determine which set of machines to disassemble for. PPC403/601 or 37 BookE. For convenience, also disassemble instructions supported 38 by the AltiVec vector unit. */ 39 40static int 41powerpc_dialect (struct disassemble_info *info) 42{ 43 int dialect = PPC_OPCODE_PPC; 44 45 if (BFD_DEFAULT_TARGET_SIZE == 64) 46 dialect |= PPC_OPCODE_64; 47 48 if (info->disassembler_options 49 && strstr (info->disassembler_options, "ppcps") != NULL) 50 dialect |= PPC_OPCODE_PPCPS; 51 else if (info->disassembler_options 52 && strstr (info->disassembler_options, "booke") != NULL) 53 dialect |= PPC_OPCODE_BOOKE | PPC_OPCODE_BOOKE64; 54 else if ((info->mach == bfd_mach_ppc_e500) 55 || (info->disassembler_options 56 && strstr (info->disassembler_options, "e500") != NULL)) 57 dialect |= (PPC_OPCODE_BOOKE 58 | PPC_OPCODE_SPE | PPC_OPCODE_ISEL 59 | PPC_OPCODE_EFS | PPC_OPCODE_BRLOCK 60 | PPC_OPCODE_PMR | PPC_OPCODE_CACHELCK 61 | PPC_OPCODE_RFMCI); 62 else if (info->disassembler_options 63 && strstr (info->disassembler_options, "efs") != NULL) 64 dialect |= PPC_OPCODE_EFS; 65 else if (info->disassembler_options 66 && strstr (info->disassembler_options, "e300") != NULL) 67 dialect |= PPC_OPCODE_E300 | PPC_OPCODE_CLASSIC | PPC_OPCODE_COMMON; 68 else if (info->disassembler_options 69 && strstr (info->disassembler_options, "440") != NULL) 70 dialect |= PPC_OPCODE_BOOKE | PPC_OPCODE_32 71 | PPC_OPCODE_440 | PPC_OPCODE_ISEL | PPC_OPCODE_RFMCI; 72 else 73 dialect |= (PPC_OPCODE_403 | PPC_OPCODE_601 | PPC_OPCODE_CLASSIC 74 | PPC_OPCODE_COMMON | PPC_OPCODE_ALTIVEC); 75 76 if (info->disassembler_options 77 && strstr (info->disassembler_options, "power4") != NULL) 78 dialect |= PPC_OPCODE_POWER4; 79 80 if (info->disassembler_options 81 && strstr (info->disassembler_options, "power5") != NULL) 82 dialect |= PPC_OPCODE_POWER4 | PPC_OPCODE_POWER5; 83 84 if (info->disassembler_options 85 && strstr (info->disassembler_options, "cell") != NULL) 86 dialect |= PPC_OPCODE_POWER4 | PPC_OPCODE_CELL | PPC_OPCODE_ALTIVEC; 87 88 if (info->disassembler_options 89 && strstr (info->disassembler_options, "power6") != NULL) 90 dialect |= PPC_OPCODE_POWER4 | PPC_OPCODE_POWER5 | PPC_OPCODE_POWER6 | PPC_OPCODE_ALTIVEC; 91 92 if (info->disassembler_options 93 && strstr (info->disassembler_options, "any") != NULL) 94 dialect |= PPC_OPCODE_ANY; 95 96 if (info->disassembler_options) 97 { 98 if (strstr (info->disassembler_options, "32") != NULL) 99 dialect &= ~PPC_OPCODE_64; 100 else if (strstr (info->disassembler_options, "64") != NULL) 101 dialect |= PPC_OPCODE_64; 102 } 103 104 info->private_data = (char *) 0 + dialect; 105 return dialect; 106} 107 108/* Print a big endian PowerPC instruction. */ 109 110int 111print_insn_big_powerpc (bfd_vma memaddr, struct disassemble_info *info) 112{ 113 int dialect = (char *) info->private_data - (char *) 0; 114 return print_insn_powerpc (memaddr, info, 1, dialect); 115} 116 117/* Print a little endian PowerPC instruction. */ 118 119int 120print_insn_little_powerpc (bfd_vma memaddr, struct disassemble_info *info) 121{ 122 int dialect = (char *) info->private_data - (char *) 0; 123 return print_insn_powerpc (memaddr, info, 0, dialect); 124} 125 126/* Print a POWER (RS/6000) instruction. */ 127 128int 129print_insn_rs6000 (bfd_vma memaddr, struct disassemble_info *info) 130{ 131 return print_insn_powerpc (memaddr, info, 1, PPC_OPCODE_POWER); 132} 133 134/* Extract the operand value from the PowerPC or POWER instruction. */ 135 136static long 137operand_value_powerpc (const struct powerpc_operand *operand, 138 unsigned long insn, int dialect) 139{ 140 long value; 141 int invalid; 142 /* Extract the value from the instruction. */ 143 if (operand->extract) 144 value = (*operand->extract) (insn, dialect, &invalid); 145 else 146 { 147 value = (insn >> operand->shift) & operand->bitm; 148 if ((operand->flags & PPC_OPERAND_SIGNED) != 0) 149 { 150 /* BITM is always some number of zeros followed by some 151 number of ones, followed by some numer of zeros. */ 152 unsigned long top = operand->bitm; 153 /* top & -top gives the rightmost 1 bit, so this 154 fills in any trailing zeros. */ 155 top |= (top & -top) - 1; 156 top &= ~(top >> 1); 157 value = (value ^ top) - top; 158 } 159 } 160 161 return value; 162} 163 164/* Determine whether the optional operand(s) should be printed. */ 165 166static int 167skip_optional_operands (const unsigned char *opindex, 168 unsigned long insn, int dialect) 169{ 170 const struct powerpc_operand *operand; 171 172 for (; *opindex != 0; opindex++) 173 { 174 operand = &powerpc_operands[*opindex]; 175 if ((operand->flags & PPC_OPERAND_NEXT) != 0 176 || ((operand->flags & PPC_OPERAND_OPTIONAL) != 0 177 && operand_value_powerpc (operand, insn, dialect) != 0)) 178 return 0; 179 } 180 181 return 1; 182} 183 184/* Print a PowerPC or POWER instruction. */ 185 186static int 187print_insn_powerpc (bfd_vma memaddr, 188 struct disassemble_info *info, 189 int bigendian, 190 int dialect) 191{ 192 bfd_byte buffer[4]; 193 int status; 194 unsigned long insn; 195 const struct powerpc_opcode *opcode; 196 const struct powerpc_opcode *opcode_end; 197 unsigned long op; 198 199 if (dialect == 0) 200 dialect = powerpc_dialect (info); 201 202 status = (*info->read_memory_func) (memaddr, buffer, 4, info); 203 if (status != 0) 204 { 205 (*info->memory_error_func) (status, memaddr, info); 206 return -1; 207 } 208 209 if (bigendian) 210 insn = bfd_getb32 (buffer); 211 else 212 insn = bfd_getl32 (buffer); 213 214 /* Get the major opcode of the instruction. */ 215 op = PPC_OP (insn); 216 217 /* Find the first match in the opcode table. We could speed this up 218 a bit by doing a binary search on the major opcode. */ 219 opcode_end = powerpc_opcodes + powerpc_num_opcodes; 220 again: 221 for (opcode = powerpc_opcodes; opcode < opcode_end; opcode++) 222 { 223 unsigned long table_op; 224 const unsigned char *opindex; 225 const struct powerpc_operand *operand; 226 int invalid; 227 int need_comma; 228 int need_paren; 229 int skip_optional; 230 231 table_op = PPC_OP (opcode->opcode); 232 if (op < table_op) 233 break; 234 if (op > table_op) 235 continue; 236 237 if ((insn & opcode->mask) != opcode->opcode 238 || (opcode->flags & dialect) == 0) 239 continue; 240 241 /* Make two passes over the operands. First see if any of them 242 have extraction functions, and, if they do, make sure the 243 instruction is valid. */ 244 invalid = 0; 245 for (opindex = opcode->operands; *opindex != 0; opindex++) 246 { 247 operand = powerpc_operands + *opindex; 248 if (operand->extract) 249 (*operand->extract) (insn, dialect, &invalid); 250 } 251 if (invalid) 252 continue; 253 254 /* The instruction is valid. */ 255 if (opcode->operands[0] != 0) 256 (*info->fprintf_func) (info->stream, "%-7s ", opcode->name); 257 else 258 (*info->fprintf_func) (info->stream, "%s", opcode->name); 259 260 /* Now extract and print the operands. */ 261 need_comma = 0; 262 need_paren = 0; 263 skip_optional = -1; 264 for (opindex = opcode->operands; *opindex != 0; opindex++) 265 { 266 long value; 267 268 operand = powerpc_operands + *opindex; 269 270 /* Operands that are marked FAKE are simply ignored. We 271 already made sure that the extract function considered 272 the instruction to be valid. */ 273 if ((operand->flags & PPC_OPERAND_FAKE) != 0) 274 continue; 275 276 /* If all of the optional operands have the value zero, 277 then don't print any of them. */ 278 if ((operand->flags & PPC_OPERAND_OPTIONAL) != 0) 279 { 280 if (skip_optional < 0) 281 skip_optional = skip_optional_operands (opindex, insn, 282 dialect); 283 if (skip_optional) 284 continue; 285 } 286 287 value = operand_value_powerpc (operand, insn, dialect); 288 289 if (need_comma) 290 { 291 (*info->fprintf_func) (info->stream, ","); 292 need_comma = 0; 293 } 294 295 /* Print the operand as directed by the flags. */ 296 if ((operand->flags & PPC_OPERAND_GPR) != 0 297 || ((operand->flags & PPC_OPERAND_GPR_0) != 0 && value != 0)) 298 (*info->fprintf_func) (info->stream, "r%ld", value); 299 else if ((operand->flags & PPC_OPERAND_FPR) != 0) 300 (*info->fprintf_func) (info->stream, "f%ld", value); 301 else if ((operand->flags & PPC_OPERAND_VR) != 0) 302 (*info->fprintf_func) (info->stream, "v%ld", value); 303 else if ((operand->flags & PPC_OPERAND_RELATIVE) != 0) 304 (*info->print_address_func) (memaddr + value, info); 305 else if ((operand->flags & PPC_OPERAND_ABSOLUTE) != 0) 306 (*info->print_address_func) ((bfd_vma) value & 0xffffffff, info); 307 else if ((operand->flags & PPC_OPERAND_CR) == 0 308 || (dialect & PPC_OPCODE_PPC) == 0) 309 (*info->fprintf_func) (info->stream, "%ld", value); 310 else 311 { 312 if (operand->bitm == 7) 313 (*info->fprintf_func) (info->stream, "cr%ld", value); 314 else 315 { 316 static const char *cbnames[4] = { "lt", "gt", "eq", "so" }; 317 int cr; 318 int cc; 319 320 cr = value >> 2; 321 if (cr != 0) 322 (*info->fprintf_func) (info->stream, "4*cr%d+", cr); 323 cc = value & 3; 324 (*info->fprintf_func) (info->stream, "%s", cbnames[cc]); 325 } 326 } 327 328 if (need_paren) 329 { 330 (*info->fprintf_func) (info->stream, ")"); 331 need_paren = 0; 332 } 333 334 if ((operand->flags & PPC_OPERAND_PARENS) == 0) 335 need_comma = 1; 336 else 337 { 338 (*info->fprintf_func) (info->stream, "("); 339 need_paren = 1; 340 } 341 } 342 343 /* We have found and printed an instruction; return. */ 344 return 4; 345 } 346 347 if ((dialect & PPC_OPCODE_ANY) != 0) 348 { 349 dialect = ~PPC_OPCODE_ANY; 350 goto again; 351 } 352 353 /* We could not find a match. */ 354 (*info->fprintf_func) (info->stream, ".long 0x%lx", insn); 355 356 return 4; 357} 358 359void 360print_ppc_disassembler_options (FILE *stream) 361{ 362 fprintf (stream, "\n\ 363The following PPC specific disassembler options are supported for use with\n\ 364the -M switch:\n"); 365 366 fprintf (stream, " booke|booke32|booke64 Disassemble the BookE instructions\n"); 367 fprintf (stream, " e300 Disassemble the e300 instructions\n"); 368 fprintf (stream, " e500|e500x2 Disassemble the e500 instructions\n"); 369 fprintf (stream, " 440 Disassemble the 440 instructions\n"); 370 fprintf (stream, " efs Disassemble the EFS instructions\n"); 371 fprintf (stream, " ppcps Disassemble the PowerPC paired singles instructions\n"); 372 fprintf (stream, " power4 Disassemble the Power4 instructions\n"); 373 fprintf (stream, " power5 Disassemble the Power5 instructions\n"); 374 fprintf (stream, " power6 Disassemble the Power6 instructions\n"); 375 fprintf (stream, " 32 Do not disassemble 64-bit instructions\n"); 376 fprintf (stream, " 64 Allow disassembly of 64-bit instructions\n"); 377} 378