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