Home | History | Annotate | Line # | Download | only in opcodes
ppc-dis.c revision 1.10.2.1
      1 /* ppc-dis.c -- Disassemble PowerPC instructions
      2    Copyright (C) 1994-2024 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   /* .got and .plt sections.  NAME is set to NULL if not present.  */
     45   struct sec_buf {
     46     asection *sec;
     47     bfd_byte *buf;
     48     const char *name;
     49   } special[2];
     50 };
     51 
     52 static inline struct dis_private *
     53 private_data (struct disassemble_info *info)
     54 {
     55   return (struct dis_private *) info->private_data;
     56 }
     57 
     58 struct ppc_mopt {
     59   /* Option string, without -m or -M prefix.  */
     60   const char *opt;
     61   /* CPU option flags.  */
     62   ppc_cpu_t cpu;
     63   /* Flags that should stay on, even when combined with another cpu
     64      option.  This should only be used for generic options like
     65      "-many" or "-maltivec" where it is reasonable to add some
     66      capability to another cpu selection.  The added flags are sticky
     67      so that, for example, "-many -me500" and "-me500 -many" result in
     68      the same assembler or disassembler behaviour.  Do not use
     69      "sticky" for specific cpus, as this will prevent that cpu's flags
     70      from overriding the defaults set in powerpc_init_dialect or a
     71      prior -m option.  */
     72   ppc_cpu_t sticky;
     73 };
     74 
     75 struct ppc_mopt ppc_opts[] = {
     76   { "403",     PPC_OPCODE_PPC | PPC_OPCODE_403,
     77     0 },
     78   { "405",     PPC_OPCODE_PPC | PPC_OPCODE_403 | PPC_OPCODE_405,
     79     0 },
     80   { "440",     (PPC_OPCODE_PPC | PPC_OPCODE_BOOKE | PPC_OPCODE_440
     81 		| PPC_OPCODE_ISEL | PPC_OPCODE_RFMCI),
     82     0 },
     83   { "464",     (PPC_OPCODE_PPC | PPC_OPCODE_BOOKE | PPC_OPCODE_440
     84 		| PPC_OPCODE_ISEL | PPC_OPCODE_RFMCI),
     85     0 },
     86   { "476",     (PPC_OPCODE_PPC | PPC_OPCODE_ISEL | PPC_OPCODE_476
     87 		| PPC_OPCODE_POWER4 | PPC_OPCODE_POWER5),
     88     0 },
     89   { "601",     PPC_OPCODE_PPC | PPC_OPCODE_601,
     90     0 },
     91   { "603",     PPC_OPCODE_PPC,
     92     0 },
     93   { "604",     PPC_OPCODE_PPC,
     94     0 },
     95   { "620",     PPC_OPCODE_PPC | PPC_OPCODE_64,
     96     0 },
     97   { "7400",    PPC_OPCODE_PPC | PPC_OPCODE_ALTIVEC,
     98     0 },
     99   { "7410",    PPC_OPCODE_PPC | PPC_OPCODE_ALTIVEC,
    100     0 },
    101   { "7450",    PPC_OPCODE_PPC | PPC_OPCODE_7450 | PPC_OPCODE_ALTIVEC,
    102     0 },
    103   { "7455",    PPC_OPCODE_PPC | PPC_OPCODE_ALTIVEC,
    104     0 },
    105   { "750cl",   PPC_OPCODE_PPC | PPC_OPCODE_750 | PPC_OPCODE_PPCPS
    106     , 0 },
    107   { "gekko",   PPC_OPCODE_PPC | PPC_OPCODE_750 | PPC_OPCODE_PPCPS
    108     , 0 },
    109   { "broadway", PPC_OPCODE_PPC | PPC_OPCODE_750 | PPC_OPCODE_PPCPS
    110     , 0 },
    111   { "821",     PPC_OPCODE_PPC | PPC_OPCODE_860,
    112     0 },
    113   { "850",     PPC_OPCODE_PPC | PPC_OPCODE_860,
    114     0 },
    115   { "860",     PPC_OPCODE_PPC | PPC_OPCODE_860,
    116     0 },
    117   { "a2",      (PPC_OPCODE_PPC | PPC_OPCODE_ISEL | PPC_OPCODE_POWER4
    118 		| PPC_OPCODE_POWER5 | PPC_OPCODE_CACHELCK | PPC_OPCODE_64
    119 		| PPC_OPCODE_A2),
    120     0 },
    121   { "altivec", PPC_OPCODE_PPC,
    122     PPC_OPCODE_ALTIVEC },
    123   { "any",     PPC_OPCODE_PPC,
    124     PPC_OPCODE_ANY },
    125   { "booke",   PPC_OPCODE_PPC | PPC_OPCODE_BOOKE,
    126     0 },
    127   { "booke32", PPC_OPCODE_PPC | PPC_OPCODE_BOOKE,
    128     0 },
    129   { "cell",    (PPC_OPCODE_PPC | PPC_OPCODE_64 | PPC_OPCODE_POWER4
    130 		| PPC_OPCODE_CELL | PPC_OPCODE_ALTIVEC),
    131     0 },
    132   { "com",     PPC_OPCODE_COMMON,
    133     0 },
    134   { "e200z2",  (PPC_OPCODE_PPC | PPC_OPCODE_BOOKE | PPC_OPCODE_LSP
    135 		| PPC_OPCODE_ISEL | PPC_OPCODE_EFS | PPC_OPCODE_BRLOCK
    136 		| PPC_OPCODE_PMR | PPC_OPCODE_CACHELCK | PPC_OPCODE_RFMCI
    137 		| PPC_OPCODE_E500 | PPC_OPCODE_VLE | PPC_OPCODE_E200Z4
    138 		| PPC_OPCODE_EFS2),
    139     0 },
    140   { "e200z4",  (PPC_OPCODE_PPC | PPC_OPCODE_BOOKE | PPC_OPCODE_SPE
    141 		| PPC_OPCODE_ISEL | PPC_OPCODE_EFS | PPC_OPCODE_BRLOCK
    142 		| PPC_OPCODE_PMR | PPC_OPCODE_CACHELCK | PPC_OPCODE_RFMCI
    143 		| PPC_OPCODE_E500 | PPC_OPCODE_VLE | PPC_OPCODE_E200Z4
    144 		| PPC_OPCODE_EFS2),
    145     0 },
    146   { "e300",    PPC_OPCODE_PPC | PPC_OPCODE_E300,
    147     0 },
    148   { "e500",    (PPC_OPCODE_PPC | PPC_OPCODE_BOOKE | PPC_OPCODE_SPE
    149 		| PPC_OPCODE_ISEL | PPC_OPCODE_EFS | PPC_OPCODE_BRLOCK
    150 		| PPC_OPCODE_PMR | PPC_OPCODE_CACHELCK | PPC_OPCODE_RFMCI
    151 		| PPC_OPCODE_E500),
    152     0 },
    153   { "e500mc",  (PPC_OPCODE_PPC | PPC_OPCODE_BOOKE | PPC_OPCODE_ISEL
    154 		| PPC_OPCODE_PMR | PPC_OPCODE_CACHELCK | PPC_OPCODE_RFMCI
    155 		| PPC_OPCODE_E500MC),
    156     0 },
    157   { "e500mc64",  (PPC_OPCODE_PPC | PPC_OPCODE_BOOKE | PPC_OPCODE_ISEL
    158 		| PPC_OPCODE_PMR | PPC_OPCODE_CACHELCK | PPC_OPCODE_RFMCI
    159 		| PPC_OPCODE_E500MC | PPC_OPCODE_64 | PPC_OPCODE_POWER5
    160 		| PPC_OPCODE_POWER6 | PPC_OPCODE_POWER7),
    161     0 },
    162   { "e5500",    (PPC_OPCODE_PPC | PPC_OPCODE_BOOKE | PPC_OPCODE_ISEL
    163 		| PPC_OPCODE_PMR | PPC_OPCODE_CACHELCK | PPC_OPCODE_RFMCI
    164 		| PPC_OPCODE_E500MC | PPC_OPCODE_64 | PPC_OPCODE_POWER4
    165 		| PPC_OPCODE_POWER5 | PPC_OPCODE_POWER6 | PPC_OPCODE_POWER7),
    166     0 },
    167   { "e6500",   (PPC_OPCODE_PPC | PPC_OPCODE_BOOKE | PPC_OPCODE_ISEL
    168 		| PPC_OPCODE_PMR | PPC_OPCODE_CACHELCK | PPC_OPCODE_RFMCI
    169 		| PPC_OPCODE_E500MC | PPC_OPCODE_64 | PPC_OPCODE_ALTIVEC
    170 		| PPC_OPCODE_E6500 | PPC_OPCODE_TMR | PPC_OPCODE_POWER4
    171 		| PPC_OPCODE_POWER5 | PPC_OPCODE_POWER6 | PPC_OPCODE_POWER7),
    172     0 },
    173   { "e500x2",  (PPC_OPCODE_PPC | PPC_OPCODE_BOOKE | PPC_OPCODE_SPE
    174 		| PPC_OPCODE_ISEL | PPC_OPCODE_EFS | PPC_OPCODE_BRLOCK
    175 		| PPC_OPCODE_PMR | PPC_OPCODE_CACHELCK | PPC_OPCODE_RFMCI
    176 		| PPC_OPCODE_E500),
    177     0 },
    178   { "efs",     PPC_OPCODE_PPC | PPC_OPCODE_EFS,
    179     0 },
    180   { "efs2",    PPC_OPCODE_PPC | PPC_OPCODE_EFS | PPC_OPCODE_EFS2,
    181     0 },
    182   { "lsp",     PPC_OPCODE_PPC,
    183     PPC_OPCODE_LSP },
    184   { "power4",  PPC_OPCODE_PPC | PPC_OPCODE_64 | PPC_OPCODE_POWER4,
    185     0 },
    186   { "power5",  (PPC_OPCODE_PPC | PPC_OPCODE_64 | PPC_OPCODE_POWER4
    187 		| PPC_OPCODE_POWER5),
    188     0 },
    189   { "power6",  (PPC_OPCODE_PPC | PPC_OPCODE_64 | PPC_OPCODE_POWER4
    190 		| PPC_OPCODE_POWER5 | PPC_OPCODE_POWER6 | PPC_OPCODE_ALTIVEC),
    191     0 },
    192   { "power7",  (PPC_OPCODE_PPC | PPC_OPCODE_ISEL | PPC_OPCODE_64
    193 		| PPC_OPCODE_POWER4 | PPC_OPCODE_POWER5 | PPC_OPCODE_POWER6
    194 		| PPC_OPCODE_POWER7 | PPC_OPCODE_ALTIVEC | PPC_OPCODE_VSX),
    195     0 },
    196   { "power8",  (PPC_OPCODE_PPC | PPC_OPCODE_ISEL | PPC_OPCODE_64
    197 		| PPC_OPCODE_POWER4 | PPC_OPCODE_POWER5 | PPC_OPCODE_POWER6
    198 		| PPC_OPCODE_POWER7 | PPC_OPCODE_POWER8
    199 		| PPC_OPCODE_ALTIVEC | PPC_OPCODE_VSX),
    200     0 },
    201   { "power9",  (PPC_OPCODE_PPC | PPC_OPCODE_ISEL | PPC_OPCODE_64
    202 		| PPC_OPCODE_POWER4 | PPC_OPCODE_POWER5 | PPC_OPCODE_POWER6
    203 		| PPC_OPCODE_POWER7 | PPC_OPCODE_POWER8 | PPC_OPCODE_POWER9
    204 		| PPC_OPCODE_ALTIVEC | PPC_OPCODE_VSX),
    205     0 },
    206   { "power10", (PPC_OPCODE_PPC | PPC_OPCODE_ISEL | PPC_OPCODE_64
    207 		| PPC_OPCODE_POWER4 | PPC_OPCODE_POWER5 | PPC_OPCODE_POWER6
    208 		| PPC_OPCODE_POWER7 | PPC_OPCODE_POWER8 | PPC_OPCODE_POWER9
    209 		| PPC_OPCODE_POWER10 | PPC_OPCODE_ALTIVEC | PPC_OPCODE_VSX),
    210     0 },
    211   { "libresoc",(PPC_OPCODE_PPC | PPC_OPCODE_ISEL | PPC_OPCODE_64
    212 		| PPC_OPCODE_POWER4 | PPC_OPCODE_POWER5 | PPC_OPCODE_POWER6
    213 		| PPC_OPCODE_POWER7 | PPC_OPCODE_POWER8 | PPC_OPCODE_POWER9
    214 		| PPC_OPCODE_ALTIVEC | PPC_OPCODE_VSX | PPC_OPCODE_SVP64),
    215     0 },
    216   { "future",  (PPC_OPCODE_PPC | PPC_OPCODE_ISEL | PPC_OPCODE_64
    217 		| PPC_OPCODE_POWER4 | PPC_OPCODE_POWER5 | PPC_OPCODE_POWER6
    218 		| PPC_OPCODE_POWER7 | PPC_OPCODE_POWER8 | PPC_OPCODE_POWER9
    219 		| PPC_OPCODE_POWER10 | PPC_OPCODE_ALTIVEC | PPC_OPCODE_VSX
    220 		| PPC_OPCODE_FUTURE),
    221     0 },
    222   { "ppc",     PPC_OPCODE_PPC,
    223     0 },
    224   { "ppc32",   PPC_OPCODE_PPC,
    225     0 },
    226   { "32",      PPC_OPCODE_PPC,
    227     0 },
    228   { "ppc64",   PPC_OPCODE_PPC | PPC_OPCODE_64,
    229     0 },
    230   { "64",      PPC_OPCODE_PPC | PPC_OPCODE_64,
    231     0 },
    232   { "ppc64bridge", PPC_OPCODE_PPC | PPC_OPCODE_64_BRIDGE,
    233     0 },
    234   { "ppcps",   PPC_OPCODE_PPC | PPC_OPCODE_PPCPS,
    235     0 },
    236   { "pwr",     PPC_OPCODE_POWER,
    237     0 },
    238   { "pwr2",    PPC_OPCODE_POWER | PPC_OPCODE_POWER2,
    239     0 },
    240   { "pwr4",    PPC_OPCODE_PPC | PPC_OPCODE_64 | PPC_OPCODE_POWER4,
    241     0 },
    242   { "pwr5",    (PPC_OPCODE_PPC | PPC_OPCODE_64 | PPC_OPCODE_POWER4
    243 		| PPC_OPCODE_POWER5),
    244     0 },
    245   { "pwr5x",   (PPC_OPCODE_PPC | PPC_OPCODE_64 | PPC_OPCODE_POWER4
    246 		| PPC_OPCODE_POWER5),
    247     0 },
    248   { "pwr6",    (PPC_OPCODE_PPC | PPC_OPCODE_64 | PPC_OPCODE_POWER4
    249 		| PPC_OPCODE_POWER5 | PPC_OPCODE_POWER6 | PPC_OPCODE_ALTIVEC),
    250     0 },
    251   { "pwr7",    (PPC_OPCODE_PPC | PPC_OPCODE_ISEL | PPC_OPCODE_64
    252 		| PPC_OPCODE_POWER4 | PPC_OPCODE_POWER5 | PPC_OPCODE_POWER6
    253 		| PPC_OPCODE_POWER7 | PPC_OPCODE_ALTIVEC | PPC_OPCODE_VSX),
    254     0 },
    255   { "pwr8",    (PPC_OPCODE_PPC | PPC_OPCODE_ISEL | PPC_OPCODE_64
    256 		| PPC_OPCODE_POWER4 | PPC_OPCODE_POWER5 | PPC_OPCODE_POWER6
    257 		| PPC_OPCODE_POWER7 | PPC_OPCODE_POWER8
    258 		| PPC_OPCODE_ALTIVEC | PPC_OPCODE_VSX),
    259     0 },
    260   { "pwr9",    (PPC_OPCODE_PPC | PPC_OPCODE_ISEL | PPC_OPCODE_64
    261 		| PPC_OPCODE_POWER4 | PPC_OPCODE_POWER5 | PPC_OPCODE_POWER6
    262 		| PPC_OPCODE_POWER7 | PPC_OPCODE_POWER8 | PPC_OPCODE_POWER9
    263 		| PPC_OPCODE_ALTIVEC | PPC_OPCODE_VSX),
    264     0 },
    265   { "pwr10",   (PPC_OPCODE_PPC | PPC_OPCODE_ISEL | PPC_OPCODE_64
    266 		| PPC_OPCODE_POWER4 | PPC_OPCODE_POWER5 | PPC_OPCODE_POWER6
    267 		| PPC_OPCODE_POWER7 | PPC_OPCODE_POWER8 | PPC_OPCODE_POWER9
    268 		| PPC_OPCODE_POWER10 | PPC_OPCODE_ALTIVEC | PPC_OPCODE_VSX),
    269     0 },
    270   { "pwrx",    PPC_OPCODE_POWER | PPC_OPCODE_POWER2,
    271     0 },
    272   { "raw",     PPC_OPCODE_PPC,
    273     PPC_OPCODE_RAW },
    274   { "spe",     PPC_OPCODE_PPC | PPC_OPCODE_EFS,
    275     PPC_OPCODE_SPE },
    276   { "spe2",     PPC_OPCODE_PPC | PPC_OPCODE_EFS | PPC_OPCODE_EFS2 | PPC_OPCODE_SPE,
    277     PPC_OPCODE_SPE2 },
    278   { "titan",   (PPC_OPCODE_PPC | PPC_OPCODE_BOOKE | PPC_OPCODE_PMR
    279 		| PPC_OPCODE_RFMCI | PPC_OPCODE_TITAN),
    280     0 },
    281   { "vle",     (PPC_OPCODE_PPC | PPC_OPCODE_BOOKE | PPC_OPCODE_SPE
    282 		| PPC_OPCODE_ISEL | PPC_OPCODE_EFS | PPC_OPCODE_BRLOCK
    283 		| PPC_OPCODE_PMR | PPC_OPCODE_CACHELCK | PPC_OPCODE_RFMCI
    284 		| PPC_OPCODE_EFS2 | PPC_OPCODE_SPE2),
    285     PPC_OPCODE_VLE },
    286   { "vsx",     PPC_OPCODE_PPC,
    287     PPC_OPCODE_VSX },
    288 };
    289 
    290 /* Switch between Booke and VLE dialects for interlinked dumps.  */
    291 static ppc_cpu_t
    292 get_powerpc_dialect (struct disassemble_info *info)
    293 {
    294   ppc_cpu_t dialect = 0;
    295 
    296   if (info->private_data)
    297     dialect = private_data (info)->dialect;
    298 
    299   /* Disassemble according to the section headers flags for VLE-mode.  */
    300   if (dialect & PPC_OPCODE_VLE
    301       && info->section != NULL && info->section->owner != NULL
    302       && bfd_get_flavour (info->section->owner) == bfd_target_elf_flavour
    303       && elf_object_id (info->section->owner) == PPC32_ELF_DATA
    304       && (elf_section_flags (info->section) & SHF_PPC_VLE) != 0)
    305     return dialect;
    306   else
    307     return dialect & ~ PPC_OPCODE_VLE;
    308 }
    309 
    310 /* Handle -m and -M options that set cpu type, and .machine arg.  */
    311 
    312 ppc_cpu_t
    313 ppc_parse_cpu (ppc_cpu_t ppc_cpu, ppc_cpu_t *sticky, const char *arg)
    314 {
    315   unsigned int i;
    316 
    317   for (i = 0; i < ARRAY_SIZE (ppc_opts); i++)
    318     if (disassembler_options_cmp (ppc_opts[i].opt, arg) == 0)
    319       {
    320 	if (ppc_opts[i].sticky)
    321 	  {
    322 	    *sticky |= ppc_opts[i].sticky;
    323 	    if ((ppc_cpu & ~*sticky) != 0)
    324 	      break;
    325 	  }
    326 	ppc_cpu = ppc_opts[i].cpu;
    327 	break;
    328       }
    329   if (i >= ARRAY_SIZE (ppc_opts))
    330     return 0;
    331 
    332   /* SPE and LSP are mutually exclusive, don't allow them both in
    333      sticky options.  However do allow them both in ppc_cpu, so that
    334      for example, -mvle -mlsp enables both SPE and LSP for assembly.  */
    335   if ((ppc_opts[i].sticky & PPC_OPCODE_LSP) != 0)
    336     *sticky &= ~(PPC_OPCODE_SPE | PPC_OPCODE_SPE2);
    337   else if ((ppc_opts[i].sticky & (PPC_OPCODE_SPE | PPC_OPCODE_SPE2)) != 0)
    338     *sticky &= ~PPC_OPCODE_LSP;
    339   ppc_cpu |= *sticky;
    340 
    341   return ppc_cpu;
    342 }
    343 
    344 /* Determine which set of machines to disassemble for.  */
    345 
    346 static void
    347 powerpc_init_dialect (struct disassemble_info *info)
    348 {
    349   ppc_cpu_t dialect = 0;
    350   ppc_cpu_t sticky = 0;
    351   struct dis_private *priv = calloc (1, sizeof (*priv));
    352 
    353   if (priv == NULL)
    354     return;
    355 
    356   switch (info->mach)
    357     {
    358     case bfd_mach_ppc_403:
    359     case bfd_mach_ppc_403gc:
    360       dialect = ppc_parse_cpu (dialect, &sticky, "403");
    361       break;
    362     case bfd_mach_ppc_405:
    363       dialect = ppc_parse_cpu (dialect, &sticky, "405");
    364       break;
    365     case bfd_mach_ppc_601:
    366       dialect = ppc_parse_cpu (dialect, &sticky, "601");
    367       break;
    368     case bfd_mach_ppc_750:
    369       dialect = ppc_parse_cpu (dialect, &sticky, "750cl");
    370       break;
    371     case bfd_mach_ppc_a35:
    372     case bfd_mach_ppc_rs64ii:
    373     case bfd_mach_ppc_rs64iii:
    374       dialect = ppc_parse_cpu (dialect, &sticky, "pwr2") | PPC_OPCODE_64;
    375       break;
    376     case bfd_mach_ppc_e500:
    377       dialect = ppc_parse_cpu (dialect, &sticky, "e500");
    378       break;
    379     case bfd_mach_ppc_e500mc:
    380       dialect = ppc_parse_cpu (dialect, &sticky, "e500mc");
    381       break;
    382     case bfd_mach_ppc_e500mc64:
    383       dialect = ppc_parse_cpu (dialect, &sticky, "e500mc64");
    384       break;
    385     case bfd_mach_ppc_e5500:
    386       dialect = ppc_parse_cpu (dialect, &sticky, "e5500");
    387       break;
    388     case bfd_mach_ppc_e6500:
    389       dialect = ppc_parse_cpu (dialect, &sticky, "e6500");
    390       break;
    391     case bfd_mach_ppc_titan:
    392       dialect = ppc_parse_cpu (dialect, &sticky, "titan");
    393       break;
    394     case bfd_mach_ppc_vle:
    395       dialect = ppc_parse_cpu (dialect, &sticky, "vle");
    396       break;
    397     default:
    398       if (info->arch == bfd_arch_powerpc)
    399 	dialect = ppc_parse_cpu (dialect, &sticky, "power10") | PPC_OPCODE_ANY;
    400       else
    401 	dialect = ppc_parse_cpu (dialect, &sticky, "pwr");
    402       break;
    403     }
    404 
    405   const char *opt;
    406   FOR_EACH_DISASSEMBLER_OPTION (opt, info->disassembler_options)
    407     {
    408       ppc_cpu_t new_cpu = 0;
    409 
    410       if (disassembler_options_cmp (opt, "32") == 0)
    411 	dialect &= ~(ppc_cpu_t) PPC_OPCODE_64;
    412       else if (disassembler_options_cmp (opt, "64") == 0)
    413 	dialect |= PPC_OPCODE_64;
    414       else if ((new_cpu = ppc_parse_cpu (dialect, &sticky, opt)) != 0)
    415 	dialect = new_cpu;
    416       else
    417 	/* xgettext: c-format */
    418 	opcodes_error_handler (_("warning: ignoring unknown -M%s option"), opt);
    419     }
    420 
    421   info->private_data = priv;
    422   private_data (info)->dialect = dialect;
    423 }
    424 
    425 #define PPC_OPCD_SEGS (1 + PPC_OP (-1))
    426 static unsigned short powerpc_opcd_indices[PPC_OPCD_SEGS + 1];
    427 #define PREFIX_OPCD_SEGS (1 + PPC_PREFIX_SEG (-1))
    428 static unsigned short prefix_opcd_indices[PREFIX_OPCD_SEGS + 1];
    429 #define VLE_OPCD_SEGS (1 + VLE_OP_TO_SEG (VLE_OP (-1, 0xffff)))
    430 static unsigned short vle_opcd_indices[VLE_OPCD_SEGS + 1];
    431 #define LSP_OPCD_SEGS (1 + LSP_OP_TO_SEG (-1))
    432 static unsigned short lsp_opcd_indices[LSP_OPCD_SEGS + 1];
    433 #define SPE2_OPCD_SEGS (1 + SPE2_XOP_TO_SEG (SPE2_XOP (-1)))
    434 static unsigned short spe2_opcd_indices[SPE2_OPCD_SEGS + 1];
    435 
    436 static bool
    437 ppc_symbol_is_valid (asymbol *sym,
    438 		     struct disassemble_info *info ATTRIBUTE_UNUSED)
    439 {
    440   elf_symbol_type * est;
    441 
    442   if (sym == NULL)
    443     return false;
    444 
    445   est = elf_symbol_from (sym);
    446 
    447   /* Ignore ELF hidden, local, no-type symbols.
    448      These are generated by annobin.  */
    449   if (est != NULL
    450       && ELF_ST_VISIBILITY (est->internal_elf_sym.st_other) == STV_HIDDEN
    451       && ELF_ST_BIND (est->internal_elf_sym.st_info) == STB_LOCAL
    452       && ELF_ST_TYPE (est->internal_elf_sym.st_info) == STT_NOTYPE)
    453     return false;
    454 
    455   return true;
    456 }
    457 
    458 /* Calculate opcode table indices to speed up disassembly,
    459    and init dialect.  */
    460 
    461 void
    462 disassemble_init_powerpc (struct disassemble_info *info)
    463 {
    464   info->symbol_is_valid = ppc_symbol_is_valid;
    465 
    466   if (powerpc_opcd_indices[PPC_OPCD_SEGS] == 0)
    467     {
    468       unsigned seg, idx, op;
    469 
    470       /* PPC opcodes */
    471       for (seg = 0, idx = 0; seg <= PPC_OPCD_SEGS; seg++)
    472 	{
    473 	  powerpc_opcd_indices[seg] = idx;
    474 	  for (; idx < powerpc_num_opcodes; idx++)
    475 	    if (seg < PPC_OP (powerpc_opcodes[idx].opcode))
    476 	      break;
    477 	}
    478 
    479       /* 64-bit prefix opcodes */
    480       for (seg = 0, idx = 0; seg <= PREFIX_OPCD_SEGS; seg++)
    481 	{
    482 	  prefix_opcd_indices[seg] = idx;
    483 	  for (; idx < prefix_num_opcodes; idx++)
    484 	    if (seg < PPC_PREFIX_SEG (prefix_opcodes[idx].opcode))
    485 	      break;
    486 	}
    487 
    488       /* VLE opcodes */
    489       for (seg = 0, idx = 0; seg <= VLE_OPCD_SEGS; seg++)
    490 	{
    491 	  vle_opcd_indices[seg] = idx;
    492 	  for (; idx < vle_num_opcodes; idx++)
    493 	    {
    494 	      op = VLE_OP (vle_opcodes[idx].opcode, vle_opcodes[idx].mask);
    495 	      if (seg < VLE_OP_TO_SEG (op))
    496 		break;
    497 	    }
    498 	}
    499 
    500       /* LSP opcodes */
    501       for (seg = 0, idx = 0; seg <= LSP_OPCD_SEGS; seg++)
    502 	{
    503 	  lsp_opcd_indices[seg] = idx;
    504 	  for (; idx < lsp_num_opcodes; idx++)
    505 	    if (seg < LSP_OP_TO_SEG (lsp_opcodes[idx].opcode))
    506 	      break;
    507 	}
    508 
    509       /* SPE2 opcodes */
    510       for (seg = 0, idx = 0; seg <= SPE2_OPCD_SEGS; seg++)
    511 	{
    512 	  spe2_opcd_indices[seg] = idx;
    513 	  for (; idx < spe2_num_opcodes; idx++)
    514 	    {
    515 	      op = SPE2_XOP (spe2_opcodes[idx].opcode);
    516 	      if (seg < SPE2_XOP_TO_SEG (op))
    517 		break;
    518 	    }
    519 	}
    520     }
    521 
    522   powerpc_init_dialect (info);
    523   if (info->private_data != NULL)
    524     {
    525       private_data (info)->special[0].name = ".got";
    526       private_data (info)->special[1].name = ".plt";
    527     }
    528 }
    529 
    530 /* Print a big endian PowerPC instruction.  */
    531 
    532 int
    533 print_insn_big_powerpc (bfd_vma memaddr, struct disassemble_info *info)
    534 {
    535   return print_insn_powerpc (memaddr, info, 1, get_powerpc_dialect (info));
    536 }
    537 
    538 /* Print a little endian PowerPC instruction.  */
    539 
    540 int
    541 print_insn_little_powerpc (bfd_vma memaddr, struct disassemble_info *info)
    542 {
    543   return print_insn_powerpc (memaddr, info, 0, get_powerpc_dialect (info));
    544 }
    545 
    546 /* Extract the operand value from the PowerPC or POWER instruction.  */
    547 
    548 static int64_t
    549 operand_value_powerpc (const struct powerpc_operand *operand,
    550 		       uint64_t insn, ppc_cpu_t dialect)
    551 {
    552   int64_t value;
    553   int invalid = 0;
    554   /* Extract the value from the instruction.  */
    555   if (operand->extract)
    556     value = (*operand->extract) (insn, dialect, &invalid);
    557   else
    558     {
    559       if (operand->shift >= 0)
    560 	value = (insn >> operand->shift) & operand->bitm;
    561       else
    562 	value = (insn << -operand->shift) & operand->bitm;
    563       if ((operand->flags & PPC_OPERAND_SIGNED) != 0)
    564 	{
    565 	  /* BITM is always some number of zeros followed by some
    566 	     number of ones, followed by some number of zeros.  */
    567 	  uint64_t top = operand->bitm;
    568 	  /* top & -top gives the rightmost 1 bit, so this
    569 	     fills in any trailing zeros.  */
    570 	  top |= (top & -top) - 1;
    571 	  top &= ~(top >> 1);
    572 	  value = (value ^ top) - top;
    573 	}
    574     }
    575 
    576   if ((operand->flags & PPC_OPERAND_NONZERO) != 0)
    577     ++value;
    578 
    579   return value;
    580 }
    581 
    582 /* Determine whether the optional operand(s) should be printed.  */
    583 
    584 static bool
    585 skip_optional_operands (const ppc_opindex_t *opindex,
    586 			uint64_t insn, ppc_cpu_t dialect, bool *is_pcrel)
    587 {
    588   const struct powerpc_operand *operand;
    589   int num_optional;
    590 
    591   for (num_optional = 0; *opindex != 0; opindex++)
    592     {
    593       operand = &powerpc_operands[*opindex];
    594       if ((operand->flags & PPC_OPERAND_NEXT) != 0)
    595 	return false;
    596       if ((operand->flags & PPC_OPERAND_OPTIONAL) != 0)
    597 	{
    598 	  int64_t value = operand_value_powerpc (operand, insn, dialect);
    599 
    600 	  if (operand->shift == 52)
    601 	    *is_pcrel = value != 0;
    602 
    603 	  /* Negative count is used as a flag to extract function.  */
    604 	  --num_optional;
    605 	  if (value != ppc_optional_operand_value (operand, insn, dialect,
    606 						   num_optional))
    607 	    return false;
    608 	}
    609     }
    610 
    611   return true;
    612 }
    613 
    614 /* Find a match for INSN in the opcode table, given machine DIALECT.  */
    615 
    616 static const struct powerpc_opcode *
    617 lookup_powerpc (uint64_t insn, ppc_cpu_t dialect)
    618 {
    619   const struct powerpc_opcode *opcode, *opcode_end;
    620   unsigned long op;
    621 
    622   /* Get the major opcode of the instruction.  */
    623   op = PPC_OP (insn);
    624 
    625   /* Find the first match in the opcode table for this major opcode.  */
    626   opcode_end = powerpc_opcodes + powerpc_opcd_indices[op + 1];
    627   for (opcode = powerpc_opcodes + powerpc_opcd_indices[op];
    628        opcode < opcode_end;
    629        ++opcode)
    630     {
    631       const ppc_opindex_t *opindex;
    632       const struct powerpc_operand *operand;
    633       int invalid;
    634 
    635       if ((insn & opcode->mask) != opcode->opcode
    636 	  || ((dialect & PPC_OPCODE_ANY) == 0
    637 	      && ((opcode->flags & dialect) == 0
    638 		  || (opcode->deprecated & dialect) != 0))
    639 	  || (opcode->deprecated & dialect & PPC_OPCODE_RAW) != 0)
    640 	continue;
    641 
    642       /* Check validity of operands.  */
    643       invalid = 0;
    644       for (opindex = opcode->operands; *opindex != 0; opindex++)
    645 	{
    646 	  operand = powerpc_operands + *opindex;
    647 	  if (operand->extract)
    648 	    (*operand->extract) (insn, dialect, &invalid);
    649 	}
    650       if (invalid)
    651 	continue;
    652 
    653       return opcode;
    654     }
    655 
    656   return NULL;
    657 }
    658 
    659 /* Find a match for INSN in the PREFIX opcode table.  */
    660 
    661 static const struct powerpc_opcode *
    662 lookup_prefix (uint64_t insn, ppc_cpu_t dialect)
    663 {
    664   const struct powerpc_opcode *opcode, *opcode_end;
    665   unsigned long seg;
    666 
    667   /* Get the opcode segment of the instruction.  */
    668   seg = PPC_PREFIX_SEG (insn);
    669 
    670   /* Find the first match in the opcode table for this major opcode.  */
    671   opcode_end = prefix_opcodes + prefix_opcd_indices[seg + 1];
    672   for (opcode = prefix_opcodes + prefix_opcd_indices[seg];
    673        opcode < opcode_end;
    674        ++opcode)
    675     {
    676       const ppc_opindex_t *opindex;
    677       const struct powerpc_operand *operand;
    678       int invalid;
    679 
    680       if ((insn & opcode->mask) != opcode->opcode
    681 	  || ((dialect & PPC_OPCODE_ANY) == 0
    682 	      && (opcode->flags & dialect) == 0)
    683 	  || (opcode->deprecated & dialect) != 0)
    684 	continue;
    685 
    686       /* Check validity of operands.  */
    687       invalid = 0;
    688       for (opindex = opcode->operands; *opindex != 0; opindex++)
    689 	{
    690 	  operand = powerpc_operands + *opindex;
    691 	  if (operand->extract)
    692 	    (*operand->extract) (insn, dialect, &invalid);
    693 	}
    694       if (invalid)
    695 	continue;
    696 
    697       return opcode;
    698     }
    699 
    700   return NULL;
    701 }
    702 
    703 /* Find a match for INSN in the VLE opcode table.  */
    704 
    705 static const struct powerpc_opcode *
    706 lookup_vle (uint64_t insn, ppc_cpu_t dialect)
    707 {
    708   const struct powerpc_opcode *opcode;
    709   const struct powerpc_opcode *opcode_end;
    710   unsigned op, seg;
    711 
    712   op = PPC_OP (insn);
    713   if (op >= 0x20 && op <= 0x37)
    714     {
    715       /* This insn has a 4-bit opcode.  */
    716       op &= 0x3c;
    717     }
    718   seg = VLE_OP_TO_SEG (op);
    719 
    720   /* Find the first match in the opcode table for this major opcode.  */
    721   opcode_end = vle_opcodes + vle_opcd_indices[seg + 1];
    722   for (opcode = vle_opcodes + vle_opcd_indices[seg];
    723        opcode < opcode_end;
    724        ++opcode)
    725     {
    726       uint64_t table_opcd = opcode->opcode;
    727       uint64_t table_mask = opcode->mask;
    728       bool table_op_is_short = PPC_OP_SE_VLE(table_mask);
    729       uint64_t insn2;
    730       const ppc_opindex_t *opindex;
    731       const struct powerpc_operand *operand;
    732       int invalid;
    733 
    734       insn2 = insn;
    735       if (table_op_is_short)
    736 	insn2 >>= 16;
    737       if ((insn2 & table_mask) != table_opcd
    738 	  || (opcode->deprecated & dialect) != 0)
    739 	continue;
    740 
    741       /* Check validity of operands.  */
    742       invalid = 0;
    743       for (opindex = opcode->operands; *opindex != 0; ++opindex)
    744 	{
    745 	  operand = powerpc_operands + *opindex;
    746 	  if (operand->extract)
    747 	    (*operand->extract) (insn, (ppc_cpu_t)0, &invalid);
    748 	}
    749       if (invalid)
    750 	continue;
    751 
    752       return opcode;
    753     }
    754 
    755   return NULL;
    756 }
    757 
    758 /* Find a match for INSN in the LSP opcode table.  */
    759 
    760 static const struct powerpc_opcode *
    761 lookup_lsp (uint64_t insn, ppc_cpu_t dialect)
    762 {
    763   const struct powerpc_opcode *opcode, *opcode_end;
    764   unsigned op, seg;
    765 
    766   op = PPC_OP (insn);
    767   if (op != 0x4)
    768     return NULL;
    769 
    770   seg = LSP_OP_TO_SEG (insn);
    771 
    772   /* Find the first match in the opcode table for this opcode.  */
    773   opcode_end = lsp_opcodes + lsp_opcd_indices[seg + 1];
    774   for (opcode = lsp_opcodes + lsp_opcd_indices[seg];
    775        opcode < opcode_end;
    776        ++opcode)
    777     {
    778       const ppc_opindex_t *opindex;
    779       const struct powerpc_operand *operand;
    780       int invalid;
    781 
    782       if ((insn & opcode->mask) != opcode->opcode
    783 	  || (opcode->deprecated & dialect) != 0)
    784 	continue;
    785 
    786       /* Check validity of operands.  */
    787       invalid = 0;
    788       for (opindex = opcode->operands; *opindex != 0; ++opindex)
    789 	{
    790 	  operand = powerpc_operands + *opindex;
    791 	  if (operand->extract)
    792 	    (*operand->extract) (insn, (ppc_cpu_t) 0, &invalid);
    793 	}
    794       if (invalid)
    795 	continue;
    796 
    797       return opcode;
    798     }
    799 
    800   return NULL;
    801 }
    802 
    803 /* Find a match for INSN in the SPE2 opcode table.  */
    804 
    805 static const struct powerpc_opcode *
    806 lookup_spe2 (uint64_t insn, ppc_cpu_t dialect)
    807 {
    808   const struct powerpc_opcode *opcode, *opcode_end;
    809   unsigned op, xop, seg;
    810 
    811   op = PPC_OP (insn);
    812   if (op != 0x4)
    813     {
    814       /* This is not SPE2 insn.
    815        * All SPE2 instructions have OP=4 and differs by XOP  */
    816       return NULL;
    817     }
    818   xop = SPE2_XOP (insn);
    819   seg = SPE2_XOP_TO_SEG (xop);
    820 
    821   /* Find the first match in the opcode table for this opcode.  */
    822   opcode_end = spe2_opcodes + spe2_opcd_indices[seg + 1];
    823   for (opcode = spe2_opcodes + spe2_opcd_indices[seg];
    824        opcode < opcode_end;
    825        ++opcode)
    826     {
    827       uint64_t table_opcd = opcode->opcode;
    828       uint64_t table_mask = opcode->mask;
    829       uint64_t insn2;
    830       const ppc_opindex_t *opindex;
    831       const struct powerpc_operand *operand;
    832       int invalid;
    833 
    834       insn2 = insn;
    835       if ((insn2 & table_mask) != table_opcd
    836 	  || (opcode->deprecated & dialect) != 0)
    837 	continue;
    838 
    839       /* Check validity of operands.  */
    840       invalid = 0;
    841       for (opindex = opcode->operands; *opindex != 0; ++opindex)
    842 	{
    843 	  operand = powerpc_operands + *opindex;
    844 	  if (operand->extract)
    845 	    (*operand->extract) (insn, (ppc_cpu_t)0, &invalid);
    846 	}
    847       if (invalid)
    848 	continue;
    849 
    850       return opcode;
    851     }
    852 
    853   return NULL;
    854 }
    855 
    856 static arelent *
    857 bsearch_reloc (arelent **lo, arelent **hi, bfd_vma vma)
    858 {
    859   while (lo < hi)
    860     {
    861       arelent **mid = lo + (hi - lo) / 2;
    862       arelent *rel = *mid;
    863 
    864       if (vma < rel->address)
    865 	hi = mid;
    866       else if (vma > rel->address)
    867 	lo = mid + 1;
    868       else
    869 	return rel;
    870     }
    871   return NULL;
    872 }
    873 
    874 static bool
    875 print_got_plt (struct sec_buf *sb, uint64_t vma, struct disassemble_info *info)
    876 {
    877   if (sb->name != NULL)
    878     {
    879       asection *s = sb->sec;
    880       if (s == NULL)
    881 	{
    882 	  s = bfd_get_section_by_name (info->section->owner, sb->name);
    883 	  sb->sec = s;
    884 	  if (s == NULL)
    885 	    sb->name = NULL;
    886 	}
    887       if (s != NULL
    888 	  && vma >= s->vma
    889 	  && vma < s->vma + s->size)
    890 	{
    891 	  asymbol *sym = NULL;
    892 	  uint64_t ent = 0;
    893 	  if (info->dynrelcount > 0)
    894 	    {
    895 	      arelent **lo = info->dynrelbuf;
    896 	      arelent **hi = lo + info->dynrelcount;
    897 	      arelent *rel = bsearch_reloc (lo, hi, vma);
    898 	      if (rel != NULL && rel->sym_ptr_ptr != NULL)
    899 		sym = *rel->sym_ptr_ptr;
    900 	    }
    901 	  if (sym == NULL && (s->flags & SEC_HAS_CONTENTS) != 0)
    902 	    {
    903 	      if (sb->buf == NULL
    904 		  && !bfd_malloc_and_get_section (s->owner, s, &sb->buf))
    905 		sb->name = NULL;
    906 	      if (sb->buf != NULL)
    907 		{
    908 		  ent = bfd_get_64 (s->owner, sb->buf + (vma - s->vma));
    909 		  if (ent != 0)
    910 		    sym = (*info->symbol_at_address_func) (ent, info);
    911 		}
    912 	    }
    913 	  (*info->fprintf_styled_func) (info->stream, dis_style_text, " [");
    914 	  if (sym != NULL)
    915 	    {
    916 	      (*info->fprintf_styled_func) (info->stream, dis_style_symbol,
    917 					    "%s", bfd_asymbol_name (sym));
    918 	      (*info->fprintf_styled_func) (info->stream, dis_style_text, "@");
    919 	      (*info->fprintf_styled_func) (info->stream, dis_style_symbol,
    920 					    "%s", sb->name + 1);
    921 	    }
    922 	  else
    923 	    {
    924 	      (*info->fprintf_styled_func) (info->stream, dis_style_address,
    925 					    "%" PRIx64, ent);
    926 	      (*info->fprintf_styled_func) (info->stream, dis_style_text, "@");
    927 	      (*info->fprintf_styled_func) (info->stream, dis_style_symbol,
    928 					    "%s", sb->name + 1);
    929 	    }
    930 	  (*info->fprintf_styled_func) (info->stream, dis_style_text, "]");
    931 	  return true;
    932 	}
    933     }
    934   return false;
    935 }
    936 
    937 /* Print a PowerPC or POWER instruction.  */
    938 
    939 static int
    940 print_insn_powerpc (bfd_vma memaddr,
    941 		    struct disassemble_info *info,
    942 		    int bigendian,
    943 		    ppc_cpu_t dialect)
    944 {
    945   bfd_byte buffer[4];
    946   int status;
    947   uint64_t insn;
    948   const struct powerpc_opcode *opcode;
    949   int insn_length = 4;  /* Assume we have a normal 4-byte instruction.  */
    950 
    951   status = (*info->read_memory_func) (memaddr, buffer, 4, info);
    952 
    953   /* The final instruction may be a 2-byte VLE insn.  */
    954   if (status != 0 && (dialect & PPC_OPCODE_VLE) != 0)
    955     {
    956       /* Clear buffer so unused bytes will not have garbage in them.  */
    957       buffer[2] = buffer[3] = 0;
    958       status = (*info->read_memory_func) (memaddr, buffer, 2, info);
    959       insn_length = 2;
    960     }
    961 
    962   if (status != 0)
    963     {
    964       (*info->memory_error_func) (status, memaddr, info);
    965       return -1;
    966     }
    967 
    968   if (bigendian)
    969     insn = bfd_getb32 (buffer);
    970   else
    971     insn = bfd_getl32 (buffer);
    972 
    973   /* Get the major opcode of the insn.  */
    974   opcode = NULL;
    975   if ((dialect & PPC_OPCODE_POWER10) != 0
    976       && PPC_OP (insn) == 0x1)
    977     {
    978       uint64_t temp_insn, suffix;
    979       status = (*info->read_memory_func) (memaddr + 4, buffer, 4, info);
    980       if (status == 0)
    981 	{
    982 	  if (bigendian)
    983 	    suffix = bfd_getb32 (buffer);
    984 	  else
    985 	    suffix = bfd_getl32 (buffer);
    986 	  temp_insn = (insn << 32) | suffix;
    987 	  opcode = lookup_prefix (temp_insn, dialect & ~PPC_OPCODE_ANY);
    988 	  if (opcode == NULL && (dialect & PPC_OPCODE_ANY) != 0)
    989 	    opcode = lookup_prefix (temp_insn, dialect);
    990 	  if (opcode != NULL)
    991 	    {
    992 	      insn = temp_insn;
    993 	      insn_length = 8;
    994 	      if ((info->flags & WIDE_OUTPUT) != 0)
    995 		info->bytes_per_line = 8;
    996 	    }
    997 	}
    998     }
    999   if (opcode == NULL && (dialect & PPC_OPCODE_VLE) != 0)
   1000     {
   1001       opcode = lookup_vle (insn, dialect);
   1002       if (opcode != NULL && PPC_OP_SE_VLE (opcode->mask))
   1003 	{
   1004 	  /* The operands will be fetched out of the 16-bit instruction.  */
   1005 	  insn >>= 16;
   1006 	  insn_length = 2;
   1007 	}
   1008     }
   1009   if (opcode == NULL && insn_length == 4)
   1010     {
   1011       if ((dialect & PPC_OPCODE_LSP) != 0)
   1012 	opcode = lookup_lsp (insn, dialect);
   1013       if ((dialect & PPC_OPCODE_SPE2) != 0)
   1014 	opcode = lookup_spe2 (insn, dialect);
   1015       if (opcode == NULL)
   1016 	opcode = lookup_powerpc (insn, dialect & ~PPC_OPCODE_ANY);
   1017       if (opcode == NULL && (dialect & PPC_OPCODE_ANY) != 0)
   1018 	opcode = lookup_powerpc (insn, dialect);
   1019       if (opcode == NULL && (dialect & PPC_OPCODE_ANY) != 0)
   1020 	opcode = lookup_spe2 (insn, dialect);
   1021       if (opcode == NULL && (dialect & PPC_OPCODE_ANY) != 0)
   1022 	opcode = lookup_lsp (insn, dialect);
   1023     }
   1024 
   1025   if (opcode != NULL)
   1026     {
   1027       const ppc_opindex_t *opindex;
   1028       const struct powerpc_operand *operand;
   1029       enum {
   1030 	need_comma = 0,
   1031 	need_1space = 1,
   1032 	need_2spaces = 2,
   1033 	need_3spaces = 3,
   1034 	need_4spaces = 4,
   1035 	need_5spaces = 5,
   1036 	need_6spaces = 6,
   1037 	need_7spaces = 7,
   1038 	need_paren
   1039       } op_separator;
   1040       bool skip_optional;
   1041       bool is_pcrel;
   1042       uint64_t d34;
   1043       int blanks;
   1044 
   1045       (*info->fprintf_styled_func) (info->stream, dis_style_mnemonic,
   1046 				    "%s", opcode->name);
   1047       /* gdb fprintf_styled_func doesn't return count printed.  */
   1048       blanks = 8 - strlen (opcode->name);
   1049       if (blanks <= 0)
   1050 	blanks = 1;
   1051 
   1052       /* Now extract and print the operands.  */
   1053       op_separator = blanks;
   1054       skip_optional = false;
   1055       is_pcrel = false;
   1056       d34 = 0;
   1057       for (opindex = opcode->operands; *opindex != 0; opindex++)
   1058 	{
   1059 	  int64_t value;
   1060 
   1061 	  operand = powerpc_operands + *opindex;
   1062 
   1063 	  /* If all of the optional operands past this one have their
   1064 	     default value, then don't print any of them.  Except in
   1065 	     raw mode, print them all.  */
   1066 	  if ((operand->flags & PPC_OPERAND_OPTIONAL) != 0
   1067 	      && (dialect & PPC_OPCODE_RAW) == 0)
   1068 	    {
   1069 	      if (!skip_optional)
   1070 		skip_optional = skip_optional_operands (opindex, insn,
   1071 							dialect, &is_pcrel);
   1072 	      if (skip_optional)
   1073 		continue;
   1074 	    }
   1075 
   1076 	  value = operand_value_powerpc (operand, insn, dialect);
   1077 
   1078 	  if (op_separator == need_comma)
   1079 	    (*info->fprintf_styled_func) (info->stream, dis_style_text, ",");
   1080 	  else if (op_separator == need_paren)
   1081 	    (*info->fprintf_styled_func) (info->stream, dis_style_text, "(");
   1082 	  else
   1083 	    (*info->fprintf_styled_func) (info->stream, dis_style_text, "%*s",
   1084 					  op_separator, " ");
   1085 
   1086 	  /* Print the operand as directed by the flags.  */
   1087 	  if ((operand->flags & PPC_OPERAND_GPR) != 0
   1088 	      || ((operand->flags & PPC_OPERAND_GPR_0) != 0 && value != 0))
   1089 	    (*info->fprintf_styled_func) (info->stream, dis_style_register,
   1090 					  "r%" PRId64, value);
   1091 	  else if ((operand->flags & PPC_OPERAND_FPR) != 0)
   1092 	    (*info->fprintf_styled_func) (info->stream, dis_style_register,
   1093 					  "f%" PRId64, value);
   1094 	  else if ((operand->flags & PPC_OPERAND_VR) != 0)
   1095 	    (*info->fprintf_styled_func) (info->stream, dis_style_register,
   1096 					  "v%" PRId64, value);
   1097 	  else if ((operand->flags & PPC_OPERAND_VSR) != 0)
   1098 	    (*info->fprintf_styled_func) (info->stream, dis_style_register,
   1099 					  "vs%" PRId64, value);
   1100 	  else if ((operand->flags & PPC_OPERAND_DMR) != 0)
   1101 	    (*info->fprintf_styled_func) (info->stream, dis_style_register,
   1102 					  "dm%" PRId64, value);
   1103 	  else if ((operand->flags & PPC_OPERAND_ACC) != 0)
   1104 	    (*info->fprintf_styled_func) (info->stream, dis_style_register,
   1105 					  "a%" PRId64, value);
   1106 	  else if ((operand->flags & PPC_OPERAND_RELATIVE) != 0)
   1107 	    (*info->print_address_func) (memaddr + value, info);
   1108 	  else if ((operand->flags & PPC_OPERAND_ABSOLUTE) != 0)
   1109 	    (*info->print_address_func) ((bfd_vma) value & 0xffffffff, info);
   1110 	  else if ((operand->flags & PPC_OPERAND_FSL) != 0)
   1111 	    (*info->fprintf_styled_func) (info->stream, dis_style_register,
   1112 					  "fsl%" PRId64, value);
   1113 	  else if ((operand->flags & PPC_OPERAND_FCR) != 0)
   1114 	    (*info->fprintf_styled_func) (info->stream, dis_style_register,
   1115 					  "fcr%" PRId64, value);
   1116 	  else if ((operand->flags & PPC_OPERAND_UDI) != 0)
   1117 	    (*info->fprintf_styled_func) (info->stream, dis_style_register,
   1118 					  "%" PRId64, value);
   1119 	  else if ((operand->flags & PPC_OPERAND_CR_REG) != 0
   1120 		   && (operand->flags & PPC_OPERAND_CR_BIT) == 0
   1121 		   && (((dialect & PPC_OPCODE_PPC) != 0)
   1122 		       || ((dialect & PPC_OPCODE_VLE) != 0)))
   1123 	    (*info->fprintf_styled_func) (info->stream, dis_style_register,
   1124 					  "cr%" PRId64, value);
   1125 	  else if ((operand->flags & PPC_OPERAND_CR_BIT) != 0
   1126 		   && (operand->flags & PPC_OPERAND_CR_REG) == 0
   1127 		   && (((dialect & PPC_OPCODE_PPC) != 0)
   1128 		       || ((dialect & PPC_OPCODE_VLE) != 0)))
   1129 	    {
   1130 	      static const char *cbnames[4] = { "lt", "gt", "eq", "so" };
   1131 	      int cr;
   1132 	      int cc;
   1133 
   1134 	      cr = value >> 2;
   1135 	      cc = value & 3;
   1136 	      if (cr != 0)
   1137 		{
   1138 		  (*info->fprintf_styled_func) (info->stream, dis_style_text,
   1139 						"4*");
   1140 		  (*info->fprintf_styled_func) (info->stream,
   1141 						dis_style_register,
   1142 						"cr%d", cr);
   1143 		  (*info->fprintf_styled_func) (info->stream, dis_style_text,
   1144 						"+");
   1145 		}
   1146 
   1147 	      (*info->fprintf_styled_func) (info->stream,
   1148 					    dis_style_sub_mnemonic,
   1149 					    "%s", cbnames[cc]);
   1150 	    }
   1151 	  else
   1152 	    {
   1153 	      /* An immediate, but what style?  */
   1154 	      enum disassembler_style style;
   1155 
   1156 	      if ((operand->flags & PPC_OPERAND_PARENS) != 0)
   1157 		style = dis_style_address_offset;
   1158 	      else
   1159 		style = dis_style_immediate;
   1160 
   1161 	      (*info->fprintf_styled_func) (info->stream, style,
   1162 					    "%" PRId64, value);
   1163 	    }
   1164 
   1165 	  if (operand->shift == 52)
   1166 	    is_pcrel = value != 0;
   1167 	  else if (operand->bitm == UINT64_C (0x3ffffffff))
   1168 	    d34 = value;
   1169 
   1170 	  if (op_separator == need_paren)
   1171 	    (*info->fprintf_styled_func) (info->stream, dis_style_text, ")");
   1172 
   1173 	  op_separator = need_comma;
   1174 	  if ((operand->flags & PPC_OPERAND_PARENS) != 0)
   1175 	    op_separator = need_paren;
   1176 	}
   1177 
   1178       if (is_pcrel)
   1179 	{
   1180 	  d34 += memaddr;
   1181 	  (*info->fprintf_styled_func) (info->stream,
   1182 					dis_style_comment_start,
   1183 					"\t# %" PRIx64, d34);
   1184 	  asymbol *sym = (*info->symbol_at_address_func) (d34, info);
   1185 	  if (sym)
   1186 	    (*info->fprintf_styled_func) (info->stream, dis_style_text,
   1187 					  " <%s>", bfd_asymbol_name (sym));
   1188 
   1189 	  if (info->private_data != NULL
   1190 	      && info->section != NULL
   1191 	      && info->section->owner != NULL
   1192 	      && (bfd_get_file_flags (info->section->owner)
   1193 		  & (EXEC_P | DYNAMIC)) != 0
   1194 	      && ((insn & ((-1ULL << 50) | (0x3fULL << 26)))
   1195 		  == ((1ULL << 58) | (1ULL << 52) | (57ULL << 26)) /* pld */))
   1196 	    {
   1197 	      for (int i = 0; i < 2; i++)
   1198 		if (print_got_plt (private_data (info)->special + i, d34, info))
   1199 		  break;
   1200 	    }
   1201 	}
   1202 
   1203       /* We have found and printed an instruction.  */
   1204       return insn_length;
   1205     }
   1206 
   1207   /* We could not find a match.  */
   1208   if (insn_length == 4)
   1209     (*info->fprintf_styled_func) (info->stream,
   1210 				  dis_style_assembler_directive, ".long");
   1211   else
   1212     {
   1213       (*info->fprintf_styled_func) (info->stream,
   1214 				    dis_style_assembler_directive, ".word");
   1215       insn >>= 16;
   1216     }
   1217   (*info->fprintf_styled_func) (info->stream, dis_style_text, " ");
   1218   (*info->fprintf_styled_func) (info->stream, dis_style_immediate, "0x%x",
   1219 				(unsigned int) insn);
   1220 
   1221 
   1222   return insn_length;
   1223 }
   1224 
   1225 const disasm_options_and_args_t *
   1226 disassembler_options_powerpc (void)
   1227 {
   1228   static disasm_options_and_args_t *opts_and_args;
   1229 
   1230   if (opts_and_args == NULL)
   1231     {
   1232       size_t i, num_options = ARRAY_SIZE (ppc_opts);
   1233       disasm_options_t *opts;
   1234 
   1235       opts_and_args = XNEW (disasm_options_and_args_t);
   1236       opts_and_args->args = NULL;
   1237 
   1238       opts = &opts_and_args->options;
   1239       opts->name = XNEWVEC (const char *, num_options + 1);
   1240       opts->description = NULL;
   1241       opts->arg = NULL;
   1242       for (i = 0; i < num_options; i++)
   1243 	opts->name[i] = ppc_opts[i].opt;
   1244       /* The array we return must be NULL terminated.  */
   1245       opts->name[i] = NULL;
   1246     }
   1247 
   1248   return opts_and_args;
   1249 }
   1250 
   1251 void
   1252 print_ppc_disassembler_options (FILE *stream)
   1253 {
   1254   unsigned int i, col;
   1255 
   1256   fprintf (stream, _("\n\
   1257 The following PPC specific disassembler options are supported for use with\n\
   1258 the -M switch:\n"));
   1259 
   1260   for (col = 0, i = 0; i < ARRAY_SIZE (ppc_opts); i++)
   1261     {
   1262       col += fprintf (stream, " %s,", ppc_opts[i].opt);
   1263       if (col > 66)
   1264 	{
   1265 	  fprintf (stream, "\n");
   1266 	  col = 0;
   1267 	}
   1268     }
   1269   fprintf (stream, "\n");
   1270 }
   1271