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