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