packaging: Add python3-base dependency
[platform/upstream/gdb.git] / opcodes / ppc-dis.c
1 /* ppc-dis.c -- Disassemble PowerPC instructions
2    Copyright (C) 1994-2022 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 (sizeof (*priv), 1);
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 }