Home | History | Annotate | Line # | Download | only in opcodes
ppc-dis.c revision 1.9
      1 /* ppc-dis.c -- Disassemble PowerPC instructions
      2    Copyright (C) 1994-2020 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 "disassemble.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 };
     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   { "gekko",   PPC_OPCODE_PPC | PPC_OPCODE_750 | PPC_OPCODE_PPCPS
     98     , 0 },
     99   { "broadway", PPC_OPCODE_PPC | PPC_OPCODE_750 | PPC_OPCODE_PPCPS
    100     , 0 },
    101   { "821",     PPC_OPCODE_PPC | PPC_OPCODE_860,
    102     0 },
    103   { "850",     PPC_OPCODE_PPC | PPC_OPCODE_860,
    104     0 },
    105   { "860",     PPC_OPCODE_PPC | PPC_OPCODE_860,
    106     0 },
    107   { "a2",      (PPC_OPCODE_PPC | PPC_OPCODE_ISEL | PPC_OPCODE_POWER4
    108 		| PPC_OPCODE_POWER5 | PPC_OPCODE_CACHELCK | PPC_OPCODE_64
    109 		| PPC_OPCODE_A2),
    110     0 },
    111   { "altivec", PPC_OPCODE_PPC,
    112     PPC_OPCODE_ALTIVEC },
    113   { "any",     PPC_OPCODE_PPC,
    114     PPC_OPCODE_ANY },
    115   { "booke",   PPC_OPCODE_PPC | PPC_OPCODE_BOOKE,
    116     0 },
    117   { "booke32", PPC_OPCODE_PPC | PPC_OPCODE_BOOKE,
    118     0 },
    119   { "cell",    (PPC_OPCODE_PPC | PPC_OPCODE_64 | PPC_OPCODE_POWER4
    120 		| PPC_OPCODE_CELL | PPC_OPCODE_ALTIVEC),
    121     0 },
    122   { "com",     PPC_OPCODE_COMMON,
    123     0 },
    124   { "e200z4",  (PPC_OPCODE_PPC | PPC_OPCODE_BOOKE| PPC_OPCODE_SPE
    125 		| PPC_OPCODE_ISEL | PPC_OPCODE_EFS | PPC_OPCODE_BRLOCK
    126 		| PPC_OPCODE_PMR | PPC_OPCODE_CACHELCK | PPC_OPCODE_RFMCI
    127 		| PPC_OPCODE_E500 | PPC_OPCODE_VLE | PPC_OPCODE_E200Z4
    128 		| PPC_OPCODE_EFS2 | PPC_OPCODE_LSP),
    129     0 },
    130   { "e300",    PPC_OPCODE_PPC | PPC_OPCODE_E300,
    131     0 },
    132   { "e500",    (PPC_OPCODE_PPC | PPC_OPCODE_BOOKE | PPC_OPCODE_SPE
    133 		| PPC_OPCODE_ISEL | PPC_OPCODE_EFS | PPC_OPCODE_BRLOCK
    134 		| PPC_OPCODE_PMR | PPC_OPCODE_CACHELCK | PPC_OPCODE_RFMCI
    135 		| PPC_OPCODE_E500),
    136     0 },
    137   { "e500mc",  (PPC_OPCODE_PPC | PPC_OPCODE_BOOKE | PPC_OPCODE_ISEL
    138 		| PPC_OPCODE_PMR | PPC_OPCODE_CACHELCK | PPC_OPCODE_RFMCI
    139 		| PPC_OPCODE_E500MC),
    140     0 },
    141   { "e500mc64",  (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_POWER5
    144 		| PPC_OPCODE_POWER6 | PPC_OPCODE_POWER7),
    145     0 },
    146   { "e5500",    (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_POWER4
    149 		| PPC_OPCODE_POWER5 | PPC_OPCODE_POWER6 | PPC_OPCODE_POWER7),
    150     0 },
    151   { "e6500",   (PPC_OPCODE_PPC | PPC_OPCODE_BOOKE | PPC_OPCODE_ISEL
    152 		| PPC_OPCODE_PMR | PPC_OPCODE_CACHELCK | PPC_OPCODE_RFMCI
    153 		| PPC_OPCODE_E500MC | PPC_OPCODE_64 | PPC_OPCODE_ALTIVEC
    154 		| PPC_OPCODE_E6500 | PPC_OPCODE_TMR | PPC_OPCODE_POWER4
    155 		| PPC_OPCODE_POWER5 | PPC_OPCODE_POWER6 | PPC_OPCODE_POWER7),
    156     0 },
    157   { "e500x2",  (PPC_OPCODE_PPC | PPC_OPCODE_BOOKE | PPC_OPCODE_SPE
    158 		| PPC_OPCODE_ISEL | PPC_OPCODE_EFS | PPC_OPCODE_BRLOCK
    159 		| PPC_OPCODE_PMR | PPC_OPCODE_CACHELCK | PPC_OPCODE_RFMCI
    160 		| PPC_OPCODE_E500),
    161     0 },
    162   { "efs",     PPC_OPCODE_PPC | PPC_OPCODE_EFS,
    163     0 },
    164   { "efs2",    PPC_OPCODE_PPC | PPC_OPCODE_EFS | PPC_OPCODE_EFS2,
    165     0 },
    166   { "power4",  PPC_OPCODE_PPC | PPC_OPCODE_64 | PPC_OPCODE_POWER4,
    167     0 },
    168   { "power5",  (PPC_OPCODE_PPC | PPC_OPCODE_64 | PPC_OPCODE_POWER4
    169 		| PPC_OPCODE_POWER5),
    170     0 },
    171   { "power6",  (PPC_OPCODE_PPC | PPC_OPCODE_64 | PPC_OPCODE_POWER4
    172 		| PPC_OPCODE_POWER5 | PPC_OPCODE_POWER6 | PPC_OPCODE_ALTIVEC),
    173     0 },
    174   { "power7",  (PPC_OPCODE_PPC | PPC_OPCODE_ISEL | PPC_OPCODE_64
    175 		| PPC_OPCODE_POWER4 | PPC_OPCODE_POWER5 | PPC_OPCODE_POWER6
    176 		| PPC_OPCODE_POWER7 | PPC_OPCODE_ALTIVEC | PPC_OPCODE_VSX),
    177     0 },
    178   { "power8",  (PPC_OPCODE_PPC | PPC_OPCODE_ISEL | PPC_OPCODE_64
    179 		| PPC_OPCODE_POWER4 | PPC_OPCODE_POWER5 | PPC_OPCODE_POWER6
    180 		| PPC_OPCODE_POWER7 | PPC_OPCODE_POWER8
    181 		| PPC_OPCODE_ALTIVEC | PPC_OPCODE_VSX),
    182     0 },
    183   { "power9",  (PPC_OPCODE_PPC | PPC_OPCODE_ISEL | PPC_OPCODE_64
    184 		| PPC_OPCODE_POWER4 | PPC_OPCODE_POWER5 | PPC_OPCODE_POWER6
    185 		| PPC_OPCODE_POWER7 | PPC_OPCODE_POWER8 | PPC_OPCODE_POWER9
    186 		| PPC_OPCODE_ALTIVEC | PPC_OPCODE_VSX),
    187     0 },
    188   { "future",  (PPC_OPCODE_PPC | PPC_OPCODE_ISEL | PPC_OPCODE_64
    189 		| PPC_OPCODE_POWER4 | PPC_OPCODE_POWER5 | PPC_OPCODE_POWER6
    190 		| PPC_OPCODE_POWER7 | PPC_OPCODE_POWER8 | PPC_OPCODE_POWER9
    191 		| PPC_OPCODE_POWERXX | PPC_OPCODE_ALTIVEC | PPC_OPCODE_VSX),
    192     0 },
    193   { "ppc",     PPC_OPCODE_PPC,
    194     0 },
    195   { "ppc32",   PPC_OPCODE_PPC,
    196     0 },
    197   { "32",      PPC_OPCODE_PPC,
    198     0 },
    199   { "ppc64",   PPC_OPCODE_PPC | PPC_OPCODE_64,
    200     0 },
    201   { "64",      PPC_OPCODE_PPC | PPC_OPCODE_64,
    202     0 },
    203   { "ppc64bridge", PPC_OPCODE_PPC | PPC_OPCODE_64_BRIDGE,
    204     0 },
    205   { "ppcps",   PPC_OPCODE_PPC | PPC_OPCODE_PPCPS,
    206     0 },
    207   { "pwr",     PPC_OPCODE_POWER,
    208     0 },
    209   { "pwr2",    PPC_OPCODE_POWER | PPC_OPCODE_POWER2,
    210     0 },
    211   { "pwr4",    PPC_OPCODE_PPC | PPC_OPCODE_64 | PPC_OPCODE_POWER4,
    212     0 },
    213   { "pwr5",    (PPC_OPCODE_PPC | PPC_OPCODE_64 | PPC_OPCODE_POWER4
    214 		| PPC_OPCODE_POWER5),
    215     0 },
    216   { "pwr5x",   (PPC_OPCODE_PPC | PPC_OPCODE_64 | PPC_OPCODE_POWER4
    217 		| PPC_OPCODE_POWER5),
    218     0 },
    219   { "pwr6",    (PPC_OPCODE_PPC | PPC_OPCODE_64 | PPC_OPCODE_POWER4
    220 		| PPC_OPCODE_POWER5 | PPC_OPCODE_POWER6 | PPC_OPCODE_ALTIVEC),
    221     0 },
    222   { "pwr7",    (PPC_OPCODE_PPC | PPC_OPCODE_ISEL | PPC_OPCODE_64
    223 		| PPC_OPCODE_POWER4 | PPC_OPCODE_POWER5 | PPC_OPCODE_POWER6
    224 		| PPC_OPCODE_POWER7 | PPC_OPCODE_ALTIVEC | PPC_OPCODE_VSX),
    225     0 },
    226   { "pwr8",    (PPC_OPCODE_PPC | PPC_OPCODE_ISEL | PPC_OPCODE_64
    227 		| PPC_OPCODE_POWER4 | PPC_OPCODE_POWER5 | PPC_OPCODE_POWER6
    228 		| PPC_OPCODE_POWER7 | PPC_OPCODE_POWER8
    229 		| PPC_OPCODE_ALTIVEC | PPC_OPCODE_VSX),
    230     0 },
    231   { "pwr9",    (PPC_OPCODE_PPC | PPC_OPCODE_ISEL | PPC_OPCODE_64
    232 		| PPC_OPCODE_POWER4 | PPC_OPCODE_POWER5 | PPC_OPCODE_POWER6
    233 		| PPC_OPCODE_POWER7 | PPC_OPCODE_POWER8 | PPC_OPCODE_POWER9
    234 		| PPC_OPCODE_ALTIVEC | PPC_OPCODE_VSX),
    235     0 },
    236   { "pwrx",    PPC_OPCODE_POWER | PPC_OPCODE_POWER2,
    237     0 },
    238   { "raw",     PPC_OPCODE_PPC,
    239     PPC_OPCODE_RAW },
    240   { "spe",     PPC_OPCODE_PPC | PPC_OPCODE_EFS,
    241     PPC_OPCODE_SPE },
    242   { "spe2",     PPC_OPCODE_PPC | PPC_OPCODE_EFS | PPC_OPCODE_EFS2 | PPC_OPCODE_SPE,
    243     PPC_OPCODE_SPE2 },
    244   { "titan",   (PPC_OPCODE_PPC | PPC_OPCODE_BOOKE | PPC_OPCODE_PMR
    245 		| PPC_OPCODE_RFMCI | PPC_OPCODE_TITAN),
    246     0 },
    247   { "vle",     (PPC_OPCODE_PPC | PPC_OPCODE_BOOKE| PPC_OPCODE_SPE
    248 		| PPC_OPCODE_ISEL | PPC_OPCODE_EFS | PPC_OPCODE_BRLOCK
    249 		| PPC_OPCODE_PMR | PPC_OPCODE_CACHELCK | PPC_OPCODE_RFMCI
    250 		| PPC_OPCODE_LSP | PPC_OPCODE_EFS2 | PPC_OPCODE_SPE2),
    251     PPC_OPCODE_VLE },
    252   { "vsx",     PPC_OPCODE_PPC,
    253     PPC_OPCODE_VSX },
    254 };
    255 
    256 /* Switch between Booke and VLE dialects for interlinked dumps.  */
    257 static ppc_cpu_t
    258 get_powerpc_dialect (struct disassemble_info *info)
    259 {
    260   ppc_cpu_t dialect = 0;
    261 
    262   if (info->private_data)
    263     dialect = POWERPC_DIALECT (info);
    264 
    265   /* Disassemble according to the section headers flags for VLE-mode.  */
    266   if (dialect & PPC_OPCODE_VLE
    267       && info->section != NULL && info->section->owner != NULL
    268       && bfd_get_flavour (info->section->owner) == bfd_target_elf_flavour
    269       && elf_object_id (info->section->owner) == PPC32_ELF_DATA
    270       && (elf_section_flags (info->section) & SHF_PPC_VLE) != 0)
    271     return dialect;
    272   else
    273     return dialect & ~ PPC_OPCODE_VLE;
    274 }
    275 
    276 /* Handle -m and -M options that set cpu type, and .machine arg.  */
    277 
    278 ppc_cpu_t
    279 ppc_parse_cpu (ppc_cpu_t ppc_cpu, ppc_cpu_t *sticky, const char *arg)
    280 {
    281   unsigned int i;
    282 
    283   for (i = 0; i < ARRAY_SIZE (ppc_opts); i++)
    284     if (disassembler_options_cmp (ppc_opts[i].opt, arg) == 0)
    285       {
    286 	if (ppc_opts[i].sticky)
    287 	  {
    288 	    *sticky |= ppc_opts[i].sticky;
    289 	    if ((ppc_cpu & ~*sticky) != 0)
    290 	      break;
    291 	  }
    292 	ppc_cpu = ppc_opts[i].cpu;
    293 	break;
    294       }
    295   if (i >= ARRAY_SIZE (ppc_opts))
    296     return 0;
    297 
    298   ppc_cpu |= *sticky;
    299   return ppc_cpu;
    300 }
    301 
    302 /* Determine which set of machines to disassemble for.  */
    303 
    304 static void
    305 powerpc_init_dialect (struct disassemble_info *info)
    306 {
    307   ppc_cpu_t dialect = 0;
    308   ppc_cpu_t sticky = 0;
    309   struct dis_private *priv = calloc (sizeof (*priv), 1);
    310 
    311   if (priv == NULL)
    312     return;
    313 
    314   switch (info->mach)
    315     {
    316     case bfd_mach_ppc_403:
    317     case bfd_mach_ppc_403gc:
    318       dialect = ppc_parse_cpu (dialect, &sticky, "403");
    319       break;
    320     case bfd_mach_ppc_405:
    321       dialect = ppc_parse_cpu (dialect, &sticky, "405");
    322       break;
    323     case bfd_mach_ppc_601:
    324       dialect = ppc_parse_cpu (dialect, &sticky, "601");
    325       break;
    326     case bfd_mach_ppc_750:
    327       dialect = ppc_parse_cpu (dialect, &sticky, "750cl");
    328       break;
    329     case bfd_mach_ppc_a35:
    330     case bfd_mach_ppc_rs64ii:
    331     case bfd_mach_ppc_rs64iii:
    332       dialect = ppc_parse_cpu (dialect, &sticky, "pwr2") | PPC_OPCODE_64;
    333       break;
    334     case bfd_mach_ppc_e500:
    335       dialect = ppc_parse_cpu (dialect, &sticky, "e500");
    336       break;
    337     case bfd_mach_ppc_e500mc:
    338       dialect = ppc_parse_cpu (dialect, &sticky, "e500mc");
    339       break;
    340     case bfd_mach_ppc_e500mc64:
    341       dialect = ppc_parse_cpu (dialect, &sticky, "e500mc64");
    342       break;
    343     case bfd_mach_ppc_e5500:
    344       dialect = ppc_parse_cpu (dialect, &sticky, "e5500");
    345       break;
    346     case bfd_mach_ppc_e6500:
    347       dialect = ppc_parse_cpu (dialect, &sticky, "e6500");
    348       break;
    349     case bfd_mach_ppc_titan:
    350       dialect = ppc_parse_cpu (dialect, &sticky, "titan");
    351       break;
    352     case bfd_mach_ppc_vle:
    353       dialect = ppc_parse_cpu (dialect, &sticky, "vle");
    354       break;
    355     default:
    356       if (info->arch == bfd_arch_powerpc)
    357 	dialect = ppc_parse_cpu (dialect, &sticky, "power9") | PPC_OPCODE_ANY;
    358       else
    359 	dialect = ppc_parse_cpu (dialect, &sticky, "pwr");
    360       break;
    361     }
    362 
    363   const char *opt;
    364   FOR_EACH_DISASSEMBLER_OPTION (opt, info->disassembler_options)
    365     {
    366       ppc_cpu_t new_cpu = 0;
    367 
    368       if (disassembler_options_cmp (opt, "32") == 0)
    369 	dialect &= ~(ppc_cpu_t) PPC_OPCODE_64;
    370       else if (disassembler_options_cmp (opt, "64") == 0)
    371 	dialect |= PPC_OPCODE_64;
    372       else if ((new_cpu = ppc_parse_cpu (dialect, &sticky, opt)) != 0)
    373 	dialect = new_cpu;
    374       else
    375 	/* xgettext: c-format */
    376 	opcodes_error_handler (_("warning: ignoring unknown -M%s option"), opt);
    377     }
    378 
    379   info->private_data = priv;
    380   POWERPC_DIALECT(info) = dialect;
    381 }
    382 
    383 #define PPC_OPCD_SEGS (1 + PPC_OP (-1))
    384 static unsigned short powerpc_opcd_indices[PPC_OPCD_SEGS + 1];
    385 #define PREFIX_OPCD_SEGS (1 + PPC_PREFIX_SEG (-1))
    386 static unsigned short prefix_opcd_indices[PREFIX_OPCD_SEGS + 1];
    387 #define VLE_OPCD_SEGS (1 + VLE_OP_TO_SEG (VLE_OP (-1, 0xffff)))
    388 static unsigned short vle_opcd_indices[VLE_OPCD_SEGS + 1];
    389 #define SPE2_OPCD_SEGS (1 + SPE2_XOP_TO_SEG (SPE2_XOP (-1)))
    390 static unsigned short spe2_opcd_indices[SPE2_OPCD_SEGS + 1];
    391 
    392 /* Calculate opcode table indices to speed up disassembly,
    393    and init dialect.  */
    394 
    395 void
    396 disassemble_init_powerpc (struct disassemble_info *info)
    397 {
    398   if (powerpc_opcd_indices[PPC_OPCD_SEGS] == 0)
    399     {
    400       unsigned seg, idx, op;
    401 
    402       /* PPC opcodes */
    403       for (seg = 0, idx = 0; seg <= PPC_OPCD_SEGS; seg++)
    404 	{
    405 	  powerpc_opcd_indices[seg] = idx;
    406 	  for (; idx < powerpc_num_opcodes; idx++)
    407 	    if (seg < PPC_OP (powerpc_opcodes[idx].opcode))
    408 	      break;
    409 	}
    410 
    411       /* 64-bit prefix opcodes */
    412       for (seg = 0, idx = 0; seg <= PREFIX_OPCD_SEGS; seg++)
    413 	{
    414 	  prefix_opcd_indices[seg] = idx;
    415 	  for (; idx < prefix_num_opcodes; idx++)
    416 	    if (seg < PPC_PREFIX_SEG (prefix_opcodes[idx].opcode))
    417 	      break;
    418 	}
    419 
    420       /* VLE opcodes */
    421       for (seg = 0, idx = 0; seg <= VLE_OPCD_SEGS; seg++)
    422 	{
    423 	  vle_opcd_indices[seg] = idx;
    424 	  for (; idx < vle_num_opcodes; idx++)
    425 	    {
    426 	      op = VLE_OP (vle_opcodes[idx].opcode, vle_opcodes[idx].mask);
    427 	      if (seg < VLE_OP_TO_SEG (op))
    428 		break;
    429 	    }
    430 	}
    431 
    432       /* SPE2 opcodes */
    433       for (seg = 0, idx = 0; seg <= SPE2_OPCD_SEGS; seg++)
    434 	{
    435 	  spe2_opcd_indices[seg] = idx;
    436 	  for (; idx < spe2_num_opcodes; idx++)
    437 	    {
    438 	      op = SPE2_XOP (spe2_opcodes[idx].opcode);
    439 	      if (seg < SPE2_XOP_TO_SEG (op))
    440 		break;
    441 	    }
    442 	}
    443     }
    444 
    445   powerpc_init_dialect (info);
    446 }
    447 
    448 /* Print a big endian PowerPC instruction.  */
    449 
    450 int
    451 print_insn_big_powerpc (bfd_vma memaddr, struct disassemble_info *info)
    452 {
    453   return print_insn_powerpc (memaddr, info, 1, get_powerpc_dialect (info));
    454 }
    455 
    456 /* Print a little endian PowerPC instruction.  */
    457 
    458 int
    459 print_insn_little_powerpc (bfd_vma memaddr, struct disassemble_info *info)
    460 {
    461   return print_insn_powerpc (memaddr, info, 0, get_powerpc_dialect (info));
    462 }
    463 
    464 /* Extract the operand value from the PowerPC or POWER instruction.  */
    465 
    466 static int64_t
    467 operand_value_powerpc (const struct powerpc_operand *operand,
    468 		       uint64_t insn, ppc_cpu_t dialect)
    469 {
    470   int64_t value;
    471   int invalid = 0;
    472   /* Extract the value from the instruction.  */
    473   if (operand->extract)
    474     value = (*operand->extract) (insn, dialect, &invalid);
    475   else
    476     {
    477       if (operand->shift >= 0)
    478 	value = (insn >> operand->shift) & operand->bitm;
    479       else
    480 	value = (insn << -operand->shift) & operand->bitm;
    481       if ((operand->flags & PPC_OPERAND_SIGNED) != 0)
    482 	{
    483 	  /* BITM is always some number of zeros followed by some
    484 	     number of ones, followed by some number of zeros.  */
    485 	  uint64_t top = operand->bitm;
    486 	  /* top & -top gives the rightmost 1 bit, so this
    487 	     fills in any trailing zeros.  */
    488 	  top |= (top & -top) - 1;
    489 	  top &= ~(top >> 1);
    490 	  value = (value ^ top) - top;
    491 	}
    492     }
    493 
    494   return value;
    495 }
    496 
    497 /* Determine whether the optional operand(s) should be printed.  */
    498 
    499 static bfd_boolean
    500 skip_optional_operands (const unsigned char *opindex,
    501 			uint64_t insn, ppc_cpu_t dialect)
    502 {
    503   const struct powerpc_operand *operand;
    504   int num_optional;
    505 
    506   for (num_optional = 0; *opindex != 0; opindex++)
    507     {
    508       operand = &powerpc_operands[*opindex];
    509       if ((operand->flags & PPC_OPERAND_NEXT) != 0)
    510 	return FALSE;
    511       if ((operand->flags & PPC_OPERAND_OPTIONAL) != 0)
    512 	{
    513 	  /* Negative count is used as a flag to extract function.  */
    514 	  --num_optional;
    515 	  if (operand_value_powerpc (operand, insn, dialect)
    516 	      != ppc_optional_operand_value (operand, insn, dialect,
    517 					     num_optional))
    518 	    return FALSE;
    519 	}
    520     }
    521 
    522   return TRUE;
    523 }
    524 
    525 /* Find a match for INSN in the opcode table, given machine DIALECT.  */
    526 
    527 static const struct powerpc_opcode *
    528 lookup_powerpc (uint64_t insn, ppc_cpu_t dialect)
    529 {
    530   const struct powerpc_opcode *opcode, *opcode_end, *last;
    531   unsigned long op;
    532 
    533   /* Get the major opcode of the instruction.  */
    534   op = PPC_OP (insn);
    535 
    536   /* Find the first match in the opcode table for this major opcode.  */
    537   opcode_end = powerpc_opcodes + powerpc_opcd_indices[op + 1];
    538   last = NULL;
    539   for (opcode = powerpc_opcodes + powerpc_opcd_indices[op];
    540        opcode < opcode_end;
    541        ++opcode)
    542     {
    543       const unsigned char *opindex;
    544       const struct powerpc_operand *operand;
    545       int invalid;
    546 
    547       if ((insn & opcode->mask) != opcode->opcode
    548 	  || ((dialect & PPC_OPCODE_ANY) == 0
    549 	      && ((opcode->flags & dialect) == 0
    550 		  || (opcode->deprecated & dialect) != 0)))
    551 	continue;
    552 
    553       /* Check validity of operands.  */
    554       invalid = 0;
    555       for (opindex = opcode->operands; *opindex != 0; opindex++)
    556 	{
    557 	  operand = powerpc_operands + *opindex;
    558 	  if (operand->extract)
    559 	    (*operand->extract) (insn, dialect, &invalid);
    560 	}
    561       if (invalid)
    562 	continue;
    563 
    564       if ((dialect & PPC_OPCODE_RAW) == 0)
    565 	return opcode;
    566 
    567       /* The raw machine insn is one that is not a specialization.  */
    568       if (last == NULL
    569 	  || (last->mask & ~opcode->mask) != 0)
    570 	last = opcode;
    571     }
    572 
    573   return last;
    574 }
    575 
    576 /* Find a match for INSN in the PREFIX opcode table.  */
    577 
    578 static const struct powerpc_opcode *
    579 lookup_prefix (uint64_t insn, ppc_cpu_t dialect)
    580 {
    581   const struct powerpc_opcode *opcode, *opcode_end, *last;
    582   unsigned long seg;
    583 
    584   /* Get the opcode segment of the instruction.  */
    585   seg = PPC_PREFIX_SEG (insn);
    586 
    587   /* Find the first match in the opcode table for this major opcode.  */
    588   opcode_end = prefix_opcodes + prefix_opcd_indices[seg + 1];
    589   last = NULL;
    590   for (opcode = prefix_opcodes + prefix_opcd_indices[seg];
    591        opcode < opcode_end;
    592        ++opcode)
    593     {
    594       const unsigned char *opindex;
    595       const struct powerpc_operand *operand;
    596       int invalid;
    597 
    598       if ((insn & opcode->mask) != opcode->opcode
    599 	  || ((dialect & PPC_OPCODE_ANY) == 0
    600 	      && ((opcode->flags & dialect) == 0
    601 		  || (opcode->deprecated & dialect) != 0)))
    602 	continue;
    603 
    604       /* Check validity of operands.  */
    605       invalid = 0;
    606       for (opindex = opcode->operands; *opindex != 0; opindex++)
    607 	{
    608 	  operand = powerpc_operands + *opindex;
    609 	  if (operand->extract)
    610 	    (*operand->extract) (insn, dialect, &invalid);
    611 	}
    612       if (invalid)
    613 	continue;
    614 
    615       if ((dialect & PPC_OPCODE_RAW) == 0)
    616 	return opcode;
    617 
    618       /* The raw machine insn is one that is not a specialization.  */
    619       if (last == NULL
    620 	  || (last->mask & ~opcode->mask) != 0)
    621 	last = opcode;
    622     }
    623 
    624   return last;
    625 }
    626 
    627 /* Find a match for INSN in the VLE opcode table.  */
    628 
    629 static const struct powerpc_opcode *
    630 lookup_vle (uint64_t insn)
    631 {
    632   const struct powerpc_opcode *opcode;
    633   const struct powerpc_opcode *opcode_end;
    634   unsigned op, seg;
    635 
    636   op = PPC_OP (insn);
    637   if (op >= 0x20 && op <= 0x37)
    638     {
    639       /* This insn has a 4-bit opcode.  */
    640       op &= 0x3c;
    641     }
    642   seg = VLE_OP_TO_SEG (op);
    643 
    644   /* Find the first match in the opcode table for this major opcode.  */
    645   opcode_end = vle_opcodes + vle_opcd_indices[seg + 1];
    646   for (opcode = vle_opcodes + vle_opcd_indices[seg];
    647        opcode < opcode_end;
    648        ++opcode)
    649     {
    650       uint64_t table_opcd = opcode->opcode;
    651       uint64_t table_mask = opcode->mask;
    652       bfd_boolean table_op_is_short = PPC_OP_SE_VLE(table_mask);
    653       uint64_t insn2;
    654       const unsigned char *opindex;
    655       const struct powerpc_operand *operand;
    656       int invalid;
    657 
    658       insn2 = insn;
    659       if (table_op_is_short)
    660 	insn2 >>= 16;
    661       if ((insn2 & table_mask) != table_opcd)
    662 	continue;
    663 
    664       /* Check validity of operands.  */
    665       invalid = 0;
    666       for (opindex = opcode->operands; *opindex != 0; ++opindex)
    667 	{
    668 	  operand = powerpc_operands + *opindex;
    669 	  if (operand->extract)
    670 	    (*operand->extract) (insn, (ppc_cpu_t)0, &invalid);
    671 	}
    672       if (invalid)
    673 	continue;
    674 
    675       return opcode;
    676     }
    677 
    678   return NULL;
    679 }
    680 
    681 /* Find a match for INSN in the SPE2 opcode table.  */
    682 
    683 static const struct powerpc_opcode *
    684 lookup_spe2 (uint64_t insn)
    685 {
    686   const struct powerpc_opcode *opcode, *opcode_end;
    687   unsigned op, xop, seg;
    688 
    689   op = PPC_OP (insn);
    690   if (op != 0x4)
    691     {
    692       /* This is not SPE2 insn.
    693        * All SPE2 instructions have OP=4 and differs by XOP  */
    694       return NULL;
    695     }
    696   xop = SPE2_XOP (insn);
    697   seg = SPE2_XOP_TO_SEG (xop);
    698 
    699   /* Find the first match in the opcode table for this major opcode.  */
    700   opcode_end = spe2_opcodes + spe2_opcd_indices[seg + 1];
    701   for (opcode = spe2_opcodes + spe2_opcd_indices[seg];
    702        opcode < opcode_end;
    703        ++opcode)
    704     {
    705       uint64_t table_opcd = opcode->opcode;
    706       uint64_t table_mask = opcode->mask;
    707       uint64_t insn2;
    708       const unsigned char *opindex;
    709       const struct powerpc_operand *operand;
    710       int invalid;
    711 
    712       insn2 = insn;
    713       if ((insn2 & table_mask) != table_opcd)
    714 	continue;
    715 
    716       /* Check validity of operands.  */
    717       invalid = 0;
    718       for (opindex = opcode->operands; *opindex != 0; ++opindex)
    719 	{
    720 	  operand = powerpc_operands + *opindex;
    721 	  if (operand->extract)
    722 	    (*operand->extract) (insn, (ppc_cpu_t)0, &invalid);
    723 	}
    724       if (invalid)
    725 	continue;
    726 
    727       return opcode;
    728     }
    729 
    730   return NULL;
    731 }
    732 
    733 /* Print a PowerPC or POWER instruction.  */
    734 
    735 static int
    736 print_insn_powerpc (bfd_vma memaddr,
    737 		    struct disassemble_info *info,
    738 		    int bigendian,
    739 		    ppc_cpu_t dialect)
    740 {
    741   bfd_byte buffer[4];
    742   int status;
    743   uint64_t insn;
    744   const struct powerpc_opcode *opcode;
    745   int insn_length = 4;  /* Assume we have a normal 4-byte instruction.  */
    746 
    747   status = (*info->read_memory_func) (memaddr, buffer, 4, info);
    748 
    749   /* The final instruction may be a 2-byte VLE insn.  */
    750   if (status != 0 && (dialect & PPC_OPCODE_VLE) != 0)
    751     {
    752       /* Clear buffer so unused bytes will not have garbage in them.  */
    753       buffer[0] = buffer[1] = buffer[2] = buffer[3] = 0;
    754       status = (*info->read_memory_func) (memaddr, buffer, 2, info);
    755     }
    756 
    757   if (status != 0)
    758     {
    759       (*info->memory_error_func) (status, memaddr, info);
    760       return -1;
    761     }
    762 
    763   if (bigendian)
    764     insn = bfd_getb32 (buffer);
    765   else
    766     insn = bfd_getl32 (buffer);
    767 
    768   /* Get the major opcode of the insn.  */
    769   opcode = NULL;
    770   if ((dialect & PPC_OPCODE_POWERXX) != 0
    771       && PPC_OP (insn) == 0x1)
    772     {
    773       uint64_t temp_insn, suffix;
    774       status = (*info->read_memory_func) (memaddr + 4, buffer, 4, info);
    775       if (status == 0)
    776 	{
    777 	  if (bigendian)
    778 	    suffix = bfd_getb32 (buffer);
    779 	  else
    780 	    suffix = bfd_getl32 (buffer);
    781 	  temp_insn = (insn << 32) | suffix;
    782 	  opcode = lookup_prefix (temp_insn, dialect & ~PPC_OPCODE_ANY);
    783 	  if (opcode == NULL && (dialect & PPC_OPCODE_ANY) != 0)
    784 	    opcode = lookup_prefix (temp_insn, dialect);
    785 	  if (opcode != NULL)
    786 	    {
    787 	      insn = temp_insn;
    788 	      insn_length = 8;
    789 	      if ((info->flags & WIDE_OUTPUT) != 0)
    790 		info->bytes_per_line = 8;
    791 	    }
    792 	}
    793     }
    794   if (opcode == NULL && (dialect & PPC_OPCODE_VLE) != 0)
    795     {
    796       opcode = lookup_vle (insn);
    797       if (opcode != NULL && PPC_OP_SE_VLE (opcode->mask))
    798 	{
    799 	  /* The operands will be fetched out of the 16-bit instruction.  */
    800 	  insn >>= 16;
    801 	  insn_length = 2;
    802 	}
    803     }
    804   if (opcode == NULL && (dialect & PPC_OPCODE_SPE2) != 0)
    805     opcode = lookup_spe2 (insn);
    806   if (opcode == NULL)
    807     opcode = lookup_powerpc (insn, dialect & ~PPC_OPCODE_ANY);
    808   if (opcode == NULL && (dialect & PPC_OPCODE_ANY) != 0)
    809     opcode = lookup_powerpc (insn, dialect);
    810 
    811   if (opcode != NULL)
    812     {
    813       const unsigned char *opindex;
    814       const struct powerpc_operand *operand;
    815       enum {
    816 	need_comma = 0,
    817 	need_1space = 1,
    818 	need_2spaces = 2,
    819 	need_3spaces = 3,
    820 	need_4spaces = 4,
    821 	need_5spaces = 5,
    822 	need_6spaces = 6,
    823 	need_7spaces = 7,
    824 	need_paren
    825       } op_separator;
    826       bfd_boolean skip_optional;
    827       int blanks;
    828 
    829       (*info->fprintf_func) (info->stream, "%s", opcode->name);
    830       /* gdb fprintf_func doesn't return count printed.  */
    831       blanks = 8 - strlen (opcode->name);
    832       if (blanks <= 0)
    833 	blanks = 1;
    834 
    835       /* Now extract and print the operands.  */
    836       op_separator = blanks;
    837       skip_optional = FALSE;
    838       for (opindex = opcode->operands; *opindex != 0; opindex++)
    839 	{
    840 	  int64_t value;
    841 
    842 	  operand = powerpc_operands + *opindex;
    843 
    844 	  /* If all of the optional operands past this one have their
    845 	     default value, then don't print any of them.  Except in
    846 	     raw mode, print them all.  */
    847 	  if ((operand->flags & PPC_OPERAND_OPTIONAL) != 0
    848 	      && (dialect & PPC_OPCODE_RAW) == 0)
    849 	    {
    850 	      if (!skip_optional)
    851 		skip_optional = skip_optional_operands (opindex, insn, dialect);
    852 	      if (skip_optional)
    853 		continue;
    854 	    }
    855 
    856 	  value = operand_value_powerpc (operand, insn, dialect);
    857 
    858 	  if (op_separator == need_comma)
    859 	    (*info->fprintf_func) (info->stream, ",");
    860 	  else if (op_separator == need_paren)
    861 	    (*info->fprintf_func) (info->stream, "(");
    862 	  else
    863 	    (*info->fprintf_func) (info->stream, "%*s", op_separator, " ");
    864 
    865 	  /* Print the operand as directed by the flags.  */
    866 	  if ((operand->flags & PPC_OPERAND_GPR) != 0
    867 	      || ((operand->flags & PPC_OPERAND_GPR_0) != 0 && value != 0))
    868 	    (*info->fprintf_func) (info->stream, "r%" PRId64, value);
    869 	  else if ((operand->flags & PPC_OPERAND_FPR) != 0)
    870 	    (*info->fprintf_func) (info->stream, "f%" PRId64, value);
    871 	  else if ((operand->flags & PPC_OPERAND_VR) != 0)
    872 	    (*info->fprintf_func) (info->stream, "v%" PRId64, value);
    873 	  else if ((operand->flags & PPC_OPERAND_VSR) != 0)
    874 	    (*info->fprintf_func) (info->stream, "vs%" PRId64, value);
    875 	  else if ((operand->flags & PPC_OPERAND_RELATIVE) != 0)
    876 	    (*info->print_address_func) (memaddr + value, info);
    877 	  else if ((operand->flags & PPC_OPERAND_ABSOLUTE) != 0)
    878 	    (*info->print_address_func) ((bfd_vma) value & 0xffffffff, info);
    879 	  else if ((operand->flags & PPC_OPERAND_FSL) != 0)
    880 	    (*info->fprintf_func) (info->stream, "fsl%" PRId64, value);
    881 	  else if ((operand->flags & PPC_OPERAND_FCR) != 0)
    882 	    (*info->fprintf_func) (info->stream, "fcr%" PRId64, value);
    883 	  else if ((operand->flags & PPC_OPERAND_UDI) != 0)
    884 	    (*info->fprintf_func) (info->stream, "%" PRId64, value);
    885 	  else if ((operand->flags & PPC_OPERAND_CR_REG) != 0
    886 		   && (operand->flags & PPC_OPERAND_CR_BIT) == 0
    887 		   && (((dialect & PPC_OPCODE_PPC) != 0)
    888 		       || ((dialect & PPC_OPCODE_VLE) != 0)))
    889 	    (*info->fprintf_func) (info->stream, "cr%" PRId64, value);
    890 	  else if ((operand->flags & PPC_OPERAND_CR_BIT) != 0
    891 		   && (operand->flags & PPC_OPERAND_CR_REG) == 0
    892 		   && (((dialect & PPC_OPCODE_PPC) != 0)
    893 		       || ((dialect & PPC_OPCODE_VLE) != 0)))
    894 	    {
    895 	      static const char *cbnames[4] = { "lt", "gt", "eq", "so" };
    896 	      int cr;
    897 	      int cc;
    898 
    899 	      cr = value >> 2;
    900 	      if (cr != 0)
    901 		(*info->fprintf_func) (info->stream, "4*cr%d+", cr);
    902 	      cc = value & 3;
    903 	      (*info->fprintf_func) (info->stream, "%s", cbnames[cc]);
    904 	    }
    905 	  else
    906 	    (*info->fprintf_func) (info->stream, "%" PRId64, value);
    907 
    908 	  if (op_separator == need_paren)
    909 	    (*info->fprintf_func) (info->stream, ")");
    910 
    911 	  op_separator = need_comma;
    912 	  if ((operand->flags & PPC_OPERAND_PARENS) != 0)
    913 	    op_separator = need_paren;
    914 	}
    915 
    916       /* We have found and printed an instruction.  */
    917       return insn_length;
    918     }
    919 
    920   /* We could not find a match.  */
    921   (*info->fprintf_func) (info->stream, ".long 0x%" PRIx64, insn);
    922 
    923   return 4;
    924 }
    925 
    926 const disasm_options_and_args_t *
    927 disassembler_options_powerpc (void)
    928 {
    929   static disasm_options_and_args_t *opts_and_args;
    930 
    931   if (opts_and_args == NULL)
    932     {
    933       size_t i, num_options = ARRAY_SIZE (ppc_opts);
    934       disasm_options_t *opts;
    935 
    936       opts_and_args = XNEW (disasm_options_and_args_t);
    937       opts_and_args->args = NULL;
    938 
    939       opts = &opts_and_args->options;
    940       opts->name = XNEWVEC (const char *, num_options + 1);
    941       opts->description = NULL;
    942       opts->arg = NULL;
    943       for (i = 0; i < num_options; i++)
    944 	opts->name[i] = ppc_opts[i].opt;
    945       /* The array we return must be NULL terminated.  */
    946       opts->name[i] = NULL;
    947     }
    948 
    949   return opts_and_args;
    950 }
    951 
    952 void
    953 print_ppc_disassembler_options (FILE *stream)
    954 {
    955   unsigned int i, col;
    956 
    957   fprintf (stream, _("\n\
    958 The following PPC specific disassembler options are supported for use with\n\
    959 the -M switch:\n"));
    960 
    961   for (col = 0, i = 0; i < ARRAY_SIZE (ppc_opts); i++)
    962     {
    963       col += fprintf (stream, " %s,", ppc_opts[i].opt);
    964       if (col > 66)
    965 	{
    966 	  fprintf (stream, "\n");
    967 	  col = 0;
    968 	}
    969     }
    970   fprintf (stream, "\n");
    971 }
    972