Don't compare boolean values against TRUE or FALSE
[external/binutils.git] / opcodes / ppc-dis.c
1 /* ppc-dis.c -- Disassemble PowerPC instructions
2    Copyright (C) 1994-2017 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 "dis-asm.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 } private;
44
45 #define POWERPC_DIALECT(INFO) \
46   (((struct dis_private *) ((INFO)->private_data))->dialect)
47
48 struct ppc_mopt {
49   /* Option string, without -m or -M prefix.  */
50   const char *opt;
51   /* CPU option flags.  */
52   ppc_cpu_t cpu;
53   /* Flags that should stay on, even when combined with another cpu
54      option.  This should only be used for generic options like
55      "-many" or "-maltivec" where it is reasonable to add some
56      capability to another cpu selection.  The added flags are sticky
57      so that, for example, "-many -me500" and "-me500 -many" result in
58      the same assembler or disassembler behaviour.  Do not use
59      "sticky" for specific cpus, as this will prevent that cpu's flags
60      from overriding the defaults set in powerpc_init_dialect or a
61      prior -m option.  */
62   ppc_cpu_t sticky;
63 };
64
65 struct ppc_mopt ppc_opts[] = {
66   { "403",     PPC_OPCODE_PPC | PPC_OPCODE_403,
67     0 },
68   { "405",     PPC_OPCODE_PPC | PPC_OPCODE_403 | PPC_OPCODE_405,
69     0 },
70   { "440",     (PPC_OPCODE_PPC | PPC_OPCODE_BOOKE | PPC_OPCODE_440
71                 | PPC_OPCODE_ISEL | PPC_OPCODE_RFMCI),
72     0 },
73   { "464",     (PPC_OPCODE_PPC | PPC_OPCODE_BOOKE | PPC_OPCODE_440
74                 | PPC_OPCODE_ISEL | PPC_OPCODE_RFMCI),
75     0 },
76   { "476",     (PPC_OPCODE_PPC | PPC_OPCODE_ISEL | PPC_OPCODE_476
77                 | PPC_OPCODE_POWER4 | PPC_OPCODE_POWER5),
78     0 },
79   { "601",     PPC_OPCODE_PPC | PPC_OPCODE_601,
80     0 },
81   { "603",     PPC_OPCODE_PPC,
82     0 },
83   { "604",     PPC_OPCODE_PPC,
84     0 },
85   { "620",     PPC_OPCODE_PPC | PPC_OPCODE_64,
86     0 },
87   { "7400",    PPC_OPCODE_PPC | PPC_OPCODE_ALTIVEC,
88     0 },
89   { "7410",    PPC_OPCODE_PPC | PPC_OPCODE_ALTIVEC,
90     0 },
91   { "7450",    PPC_OPCODE_PPC | PPC_OPCODE_7450 | PPC_OPCODE_ALTIVEC,
92     0 },
93   { "7455",    PPC_OPCODE_PPC | PPC_OPCODE_ALTIVEC,
94     0 },
95   { "750cl",   PPC_OPCODE_PPC | PPC_OPCODE_750 | PPC_OPCODE_PPCPS
96     , 0 },
97   { "821",     PPC_OPCODE_PPC | PPC_OPCODE_860,
98     0 },
99   { "850",     PPC_OPCODE_PPC | PPC_OPCODE_860,
100     0 },
101   { "860",     PPC_OPCODE_PPC | PPC_OPCODE_860,
102     0 },
103   { "a2",      (PPC_OPCODE_PPC | PPC_OPCODE_ISEL | PPC_OPCODE_POWER4
104                 | PPC_OPCODE_POWER5 | PPC_OPCODE_CACHELCK | PPC_OPCODE_64
105                 | PPC_OPCODE_A2),
106     0 },
107   { "altivec", PPC_OPCODE_PPC,
108     PPC_OPCODE_ALTIVEC },
109   { "any",     PPC_OPCODE_PPC,
110     PPC_OPCODE_ANY },
111   { "booke",   PPC_OPCODE_PPC | PPC_OPCODE_BOOKE,
112     0 },
113   { "booke32", PPC_OPCODE_PPC | PPC_OPCODE_BOOKE,
114     0 },
115   { "cell",    (PPC_OPCODE_PPC | PPC_OPCODE_64 | PPC_OPCODE_POWER4
116                 | PPC_OPCODE_CELL | PPC_OPCODE_ALTIVEC),
117     0 },
118   { "com",     PPC_OPCODE_COMMON,
119     0 },
120   { "e200z4",  (PPC_OPCODE_PPC | PPC_OPCODE_BOOKE| PPC_OPCODE_SPE
121                 | PPC_OPCODE_ISEL | PPC_OPCODE_EFS | PPC_OPCODE_BRLOCK
122                 | PPC_OPCODE_PMR | PPC_OPCODE_CACHELCK | PPC_OPCODE_RFMCI
123                 | PPC_OPCODE_E500 | PPC_OPCODE_VLE | PPC_OPCODE_E200Z4),
124     0 },
125   { "e300",    PPC_OPCODE_PPC | PPC_OPCODE_E300,
126     0 },
127   { "e500",    (PPC_OPCODE_PPC | PPC_OPCODE_BOOKE | PPC_OPCODE_SPE
128                 | PPC_OPCODE_ISEL | PPC_OPCODE_EFS | PPC_OPCODE_BRLOCK
129                 | PPC_OPCODE_PMR | PPC_OPCODE_CACHELCK | PPC_OPCODE_RFMCI
130                 | PPC_OPCODE_E500),
131     0 },
132   { "e500mc",  (PPC_OPCODE_PPC | PPC_OPCODE_BOOKE | PPC_OPCODE_ISEL
133                 | PPC_OPCODE_PMR | PPC_OPCODE_CACHELCK | PPC_OPCODE_RFMCI
134                 | PPC_OPCODE_E500MC),
135     0 },
136   { "e500mc64",  (PPC_OPCODE_PPC | PPC_OPCODE_BOOKE | PPC_OPCODE_ISEL
137                 | PPC_OPCODE_PMR | PPC_OPCODE_CACHELCK | PPC_OPCODE_RFMCI
138                 | PPC_OPCODE_E500MC | PPC_OPCODE_64 | PPC_OPCODE_POWER5
139                 | PPC_OPCODE_POWER6 | PPC_OPCODE_POWER7),
140     0 },
141   { "e5500",    (PPC_OPCODE_PPC | PPC_OPCODE_BOOKE | PPC_OPCODE_ISEL
142                 | PPC_OPCODE_PMR | PPC_OPCODE_CACHELCK | PPC_OPCODE_RFMCI
143                 | PPC_OPCODE_E500MC | PPC_OPCODE_64 | PPC_OPCODE_POWER4
144                 | PPC_OPCODE_POWER5 | PPC_OPCODE_POWER6 | PPC_OPCODE_POWER7),
145     0 },
146   { "e6500",   (PPC_OPCODE_PPC | PPC_OPCODE_BOOKE | PPC_OPCODE_ISEL
147                 | PPC_OPCODE_PMR | PPC_OPCODE_CACHELCK | PPC_OPCODE_RFMCI
148                 | PPC_OPCODE_E500MC | PPC_OPCODE_64 | PPC_OPCODE_ALTIVEC
149                 | PPC_OPCODE_E6500 | PPC_OPCODE_TMR | PPC_OPCODE_POWER4
150                 | PPC_OPCODE_POWER5 | PPC_OPCODE_POWER6 | PPC_OPCODE_POWER7),
151     0 },
152   { "e500x2",  (PPC_OPCODE_PPC | PPC_OPCODE_BOOKE | PPC_OPCODE_SPE
153                 | PPC_OPCODE_ISEL | PPC_OPCODE_EFS | PPC_OPCODE_BRLOCK
154                 | PPC_OPCODE_PMR | PPC_OPCODE_CACHELCK | PPC_OPCODE_RFMCI
155                 | PPC_OPCODE_E500),
156     0 },
157   { "efs",     PPC_OPCODE_PPC | PPC_OPCODE_EFS,
158     0 },
159   { "power4",  PPC_OPCODE_PPC | PPC_OPCODE_64 | PPC_OPCODE_POWER4,
160     0 },
161   { "power5",  (PPC_OPCODE_PPC | PPC_OPCODE_64 | PPC_OPCODE_POWER4
162                 | PPC_OPCODE_POWER5),
163     0 },
164   { "power6",  (PPC_OPCODE_PPC | PPC_OPCODE_64 | PPC_OPCODE_POWER4
165                 | PPC_OPCODE_POWER5 | PPC_OPCODE_POWER6 | PPC_OPCODE_ALTIVEC),
166     0 },
167   { "power7",  (PPC_OPCODE_PPC | PPC_OPCODE_ISEL | PPC_OPCODE_64
168                 | PPC_OPCODE_POWER4 | PPC_OPCODE_POWER5 | PPC_OPCODE_POWER6
169                 | PPC_OPCODE_POWER7 | PPC_OPCODE_ALTIVEC | PPC_OPCODE_VSX),
170     0 },
171   { "power8",  (PPC_OPCODE_PPC | PPC_OPCODE_ISEL | PPC_OPCODE_64
172                 | PPC_OPCODE_POWER4 | PPC_OPCODE_POWER5 | PPC_OPCODE_POWER6
173                 | PPC_OPCODE_POWER7 | PPC_OPCODE_POWER8
174                 | PPC_OPCODE_ALTIVEC | PPC_OPCODE_VSX),
175     0 },
176   { "power9",  (PPC_OPCODE_PPC | PPC_OPCODE_ISEL | PPC_OPCODE_64
177                 | PPC_OPCODE_POWER4 | PPC_OPCODE_POWER5 | PPC_OPCODE_POWER6
178                 | PPC_OPCODE_POWER7 | PPC_OPCODE_POWER8 | PPC_OPCODE_POWER9
179                 | PPC_OPCODE_ALTIVEC | PPC_OPCODE_VSX),
180     0 },
181   { "ppc",     PPC_OPCODE_PPC,
182     0 },
183   { "ppc32",   PPC_OPCODE_PPC,
184     0 },
185   { "32",      PPC_OPCODE_PPC,
186     0 },
187   { "ppc64",   PPC_OPCODE_PPC | PPC_OPCODE_64,
188     0 },
189   { "64",      PPC_OPCODE_PPC | PPC_OPCODE_64,
190     0 },
191   { "ppc64bridge", PPC_OPCODE_PPC | PPC_OPCODE_64_BRIDGE,
192     0 },
193   { "ppcps",   PPC_OPCODE_PPC | PPC_OPCODE_PPCPS,
194     0 },
195   { "pwr",     PPC_OPCODE_POWER,
196     0 },
197   { "pwr2",    PPC_OPCODE_POWER | PPC_OPCODE_POWER2,
198     0 },
199   { "pwr4",    PPC_OPCODE_PPC | PPC_OPCODE_64 | PPC_OPCODE_POWER4,
200     0 },
201   { "pwr5",    (PPC_OPCODE_PPC | PPC_OPCODE_64 | PPC_OPCODE_POWER4
202                 | PPC_OPCODE_POWER5),
203     0 },
204   { "pwr5x",   (PPC_OPCODE_PPC | PPC_OPCODE_64 | PPC_OPCODE_POWER4
205                 | PPC_OPCODE_POWER5),
206     0 },
207   { "pwr6",    (PPC_OPCODE_PPC | PPC_OPCODE_64 | PPC_OPCODE_POWER4
208                 | PPC_OPCODE_POWER5 | PPC_OPCODE_POWER6 | PPC_OPCODE_ALTIVEC),
209     0 },
210   { "pwr7",    (PPC_OPCODE_PPC | PPC_OPCODE_ISEL | PPC_OPCODE_64
211                 | PPC_OPCODE_POWER4 | PPC_OPCODE_POWER5 | PPC_OPCODE_POWER6
212                 | PPC_OPCODE_POWER7 | PPC_OPCODE_ALTIVEC | PPC_OPCODE_VSX),
213     0 },
214   { "pwr8",    (PPC_OPCODE_PPC | PPC_OPCODE_ISEL | PPC_OPCODE_64
215                 | PPC_OPCODE_POWER4 | PPC_OPCODE_POWER5 | PPC_OPCODE_POWER6
216                 | PPC_OPCODE_POWER7 | PPC_OPCODE_POWER8
217                 | PPC_OPCODE_ALTIVEC | PPC_OPCODE_VSX),
218     0 },
219   { "pwr9",    (PPC_OPCODE_PPC | PPC_OPCODE_ISEL | PPC_OPCODE_64
220                 | PPC_OPCODE_POWER4 | PPC_OPCODE_POWER5 | PPC_OPCODE_POWER6
221                 | PPC_OPCODE_POWER7 | PPC_OPCODE_POWER8 | PPC_OPCODE_POWER9
222                 | PPC_OPCODE_ALTIVEC | PPC_OPCODE_VSX),
223     0 },
224   { "pwrx",    PPC_OPCODE_POWER | PPC_OPCODE_POWER2,
225     0 },
226   { "raw",     PPC_OPCODE_PPC,
227     PPC_OPCODE_RAW },
228   { "spe",     PPC_OPCODE_PPC | PPC_OPCODE_EFS,
229     PPC_OPCODE_SPE },
230   { "titan",   (PPC_OPCODE_PPC | PPC_OPCODE_BOOKE | PPC_OPCODE_PMR
231                 | PPC_OPCODE_RFMCI | PPC_OPCODE_TITAN),
232     0 },
233   { "vle",     (PPC_OPCODE_PPC | PPC_OPCODE_BOOKE| PPC_OPCODE_SPE
234                 | PPC_OPCODE_ISEL | PPC_OPCODE_EFS | PPC_OPCODE_BRLOCK
235                 | PPC_OPCODE_PMR | PPC_OPCODE_CACHELCK | PPC_OPCODE_RFMCI
236                 | PPC_OPCODE_E500),
237     PPC_OPCODE_VLE },
238   { "vsx",     PPC_OPCODE_PPC,
239     PPC_OPCODE_VSX },
240 };
241
242 /* Switch between Booke and VLE dialects for interlinked dumps.  */
243 static ppc_cpu_t
244 get_powerpc_dialect (struct disassemble_info *info)
245 {
246   ppc_cpu_t dialect = 0;
247
248   dialect = POWERPC_DIALECT (info);
249
250   /* Disassemble according to the section headers flags for VLE-mode.  */
251   if (dialect & PPC_OPCODE_VLE
252       && info->section != NULL && info->section->owner != NULL
253       && bfd_get_flavour (info->section->owner) == bfd_target_elf_flavour
254       && elf_object_id (info->section->owner) == PPC32_ELF_DATA
255       && (elf_section_flags (info->section) & SHF_PPC_VLE) != 0)
256     return dialect;
257   else
258     return dialect & ~ PPC_OPCODE_VLE;
259 }
260
261 /* Handle -m and -M options that set cpu type, and .machine arg.  */
262
263 ppc_cpu_t
264 ppc_parse_cpu (ppc_cpu_t ppc_cpu, ppc_cpu_t *sticky, const char *arg)
265 {
266   unsigned int i;
267
268   for (i = 0; i < ARRAY_SIZE (ppc_opts); i++)
269     if (disassembler_options_cmp (ppc_opts[i].opt, arg) == 0)
270       {
271         if (ppc_opts[i].sticky)
272           {
273             *sticky |= ppc_opts[i].sticky;
274             if ((ppc_cpu & ~*sticky) != 0)
275               break;
276           }
277         ppc_cpu = ppc_opts[i].cpu;
278         break;
279       }
280   if (i >= ARRAY_SIZE (ppc_opts))
281     return 0;
282
283   ppc_cpu |= *sticky;
284   return ppc_cpu;
285 }
286
287 /* Determine which set of machines to disassemble for.  */
288
289 static void
290 powerpc_init_dialect (struct disassemble_info *info)
291 {
292   ppc_cpu_t dialect = 0;
293   ppc_cpu_t sticky = 0;
294   struct dis_private *priv = calloc (sizeof (*priv), 1);
295
296   if (priv == NULL)
297     priv = &private;
298
299   switch (info->mach)
300     {
301     case bfd_mach_ppc_403:
302     case bfd_mach_ppc_403gc:
303       dialect = ppc_parse_cpu (dialect, &sticky, "403");
304       break;
305     case bfd_mach_ppc_405:
306       dialect = ppc_parse_cpu (dialect, &sticky, "405");
307       break;
308     case bfd_mach_ppc_601:
309       dialect = ppc_parse_cpu (dialect, &sticky, "601");
310       break;
311     case bfd_mach_ppc_a35:
312     case bfd_mach_ppc_rs64ii:
313     case bfd_mach_ppc_rs64iii:
314       dialect = ppc_parse_cpu (dialect, &sticky, "pwr2") | PPC_OPCODE_64;
315       break;
316     case bfd_mach_ppc_e500:
317       dialect = ppc_parse_cpu (dialect, &sticky, "e500");
318       break;
319     case bfd_mach_ppc_e500mc:
320       dialect = ppc_parse_cpu (dialect, &sticky, "e500mc");
321       break;
322     case bfd_mach_ppc_e500mc64:
323       dialect = ppc_parse_cpu (dialect, &sticky, "e500mc64");
324       break;
325     case bfd_mach_ppc_e5500:
326       dialect = ppc_parse_cpu (dialect, &sticky, "e5500");
327       break;
328     case bfd_mach_ppc_e6500:
329       dialect = ppc_parse_cpu (dialect, &sticky, "e6500");
330       break;
331     case bfd_mach_ppc_titan:
332       dialect = ppc_parse_cpu (dialect, &sticky, "titan");
333       break;
334     case bfd_mach_ppc_vle:
335       dialect = ppc_parse_cpu (dialect, &sticky, "vle");
336       break;
337     default:
338       dialect = ppc_parse_cpu (dialect, &sticky, "power9") | PPC_OPCODE_ANY;
339       break;
340     }
341
342   const char *opt;
343   FOR_EACH_DISASSEMBLER_OPTION (opt, info->disassembler_options)
344     {
345       ppc_cpu_t new_cpu = 0;
346
347       if (disassembler_options_cmp (opt, "32") == 0)
348         dialect &= ~(ppc_cpu_t) PPC_OPCODE_64;
349       else if (disassembler_options_cmp (opt, "64") == 0)
350         dialect |= PPC_OPCODE_64;
351       else if ((new_cpu = ppc_parse_cpu (dialect, &sticky, opt)) != 0)
352         dialect = new_cpu;
353       else
354         fprintf (stderr, _("warning: ignoring unknown -M%s option\n"), opt);
355     }
356
357   info->private_data = priv;
358   POWERPC_DIALECT(info) = dialect;
359 }
360
361 #define PPC_OPCD_SEGS 64
362 static unsigned short powerpc_opcd_indices[PPC_OPCD_SEGS+1];
363 #define VLE_OPCD_SEGS 32
364 static unsigned short vle_opcd_indices[VLE_OPCD_SEGS+1];
365
366 /* Calculate opcode table indices to speed up disassembly,
367    and init dialect.  */
368
369 void
370 disassemble_init_powerpc (struct disassemble_info *info)
371 {
372   int i;
373   unsigned short last;
374
375   if (powerpc_opcd_indices[PPC_OPCD_SEGS] == 0)
376     {
377
378       i = powerpc_num_opcodes;
379       while (--i >= 0)
380         {
381           unsigned op = PPC_OP (powerpc_opcodes[i].opcode);
382
383           powerpc_opcd_indices[op] = i;
384         }
385
386       last = powerpc_num_opcodes;
387       for (i = PPC_OPCD_SEGS; i > 0; --i)
388         {
389           if (powerpc_opcd_indices[i] == 0)
390             powerpc_opcd_indices[i] = last;
391           last = powerpc_opcd_indices[i];
392         }
393
394       i = vle_num_opcodes;
395       while (--i >= 0)
396         {
397           unsigned op = VLE_OP (vle_opcodes[i].opcode, vle_opcodes[i].mask);
398           unsigned seg = VLE_OP_TO_SEG (op);
399
400           vle_opcd_indices[seg] = i;
401         }
402
403       last = vle_num_opcodes;
404       for (i = VLE_OPCD_SEGS; i > 0; --i)
405         {
406           if (vle_opcd_indices[i] == 0)
407             vle_opcd_indices[i] = last;
408           last = vle_opcd_indices[i];
409         }
410     }
411
412   if (info->arch == bfd_arch_powerpc)
413     powerpc_init_dialect (info);
414 }
415
416 /* Print a big endian PowerPC instruction.  */
417
418 int
419 print_insn_big_powerpc (bfd_vma memaddr, struct disassemble_info *info)
420 {
421   return print_insn_powerpc (memaddr, info, 1, get_powerpc_dialect (info));
422 }
423
424 /* Print a little endian PowerPC instruction.  */
425
426 int
427 print_insn_little_powerpc (bfd_vma memaddr, struct disassemble_info *info)
428 {
429   return print_insn_powerpc (memaddr, info, 0, get_powerpc_dialect (info));
430 }
431
432 /* Print a POWER (RS/6000) instruction.  */
433
434 int
435 print_insn_rs6000 (bfd_vma memaddr, struct disassemble_info *info)
436 {
437   return print_insn_powerpc (memaddr, info, 1, PPC_OPCODE_POWER);
438 }
439
440 /* Extract the operand value from the PowerPC or POWER instruction.  */
441
442 static long
443 operand_value_powerpc (const struct powerpc_operand *operand,
444                        unsigned long insn, ppc_cpu_t dialect)
445 {
446   long value;
447   int invalid;
448   /* Extract the value from the instruction.  */
449   if (operand->extract)
450     value = (*operand->extract) (insn, dialect, &invalid);
451   else
452     {
453       if (operand->shift >= 0)
454         value = (insn >> operand->shift) & operand->bitm;
455       else
456         value = (insn << -operand->shift) & operand->bitm;
457       if ((operand->flags & PPC_OPERAND_SIGNED) != 0)
458         {
459           /* BITM is always some number of zeros followed by some
460              number of ones, followed by some number of zeros.  */
461           unsigned long top = operand->bitm;
462           /* top & -top gives the rightmost 1 bit, so this
463              fills in any trailing zeros.  */
464           top |= (top & -top) - 1;
465           top &= ~(top >> 1);
466           value = (value ^ top) - top;
467         }
468     }
469
470   return value;
471 }
472
473 /* Determine whether the optional operand(s) should be printed.  */
474
475 static int
476 skip_optional_operands (const unsigned char *opindex,
477                         unsigned long insn, ppc_cpu_t dialect)
478 {
479   const struct powerpc_operand *operand;
480
481   for (; *opindex != 0; opindex++)
482     {
483       operand = &powerpc_operands[*opindex];
484       if ((operand->flags & PPC_OPERAND_NEXT) != 0
485           || ((operand->flags & PPC_OPERAND_OPTIONAL) != 0
486               && operand_value_powerpc (operand, insn, dialect) !=
487                  ppc_optional_operand_value (operand)))
488         return 0;
489     }
490
491   return 1;
492 }
493
494 /* Find a match for INSN in the opcode table, given machine DIALECT.  */
495
496 static const struct powerpc_opcode *
497 lookup_powerpc (unsigned long insn, ppc_cpu_t dialect)
498 {
499   const struct powerpc_opcode *opcode, *opcode_end, *last;
500   unsigned long op;
501
502   /* Get the major opcode of the instruction.  */
503   op = PPC_OP (insn);
504
505   /* Find the first match in the opcode table for this major opcode.  */
506   opcode_end = powerpc_opcodes + powerpc_opcd_indices[op + 1];
507   last = NULL;
508   for (opcode = powerpc_opcodes + powerpc_opcd_indices[op];
509        opcode < opcode_end;
510        ++opcode)
511     {
512       const unsigned char *opindex;
513       const struct powerpc_operand *operand;
514       int invalid;
515
516       if ((insn & opcode->mask) != opcode->opcode
517           || ((dialect & PPC_OPCODE_ANY) == 0
518               && ((opcode->flags & dialect) == 0
519                   || (opcode->deprecated & dialect) != 0)))
520         continue;
521
522       /* Check validity of operands.  */
523       invalid = 0;
524       for (opindex = opcode->operands; *opindex != 0; opindex++)
525         {
526           operand = powerpc_operands + *opindex;
527           if (operand->extract)
528             (*operand->extract) (insn, dialect, &invalid);
529         }
530       if (invalid)
531         continue;
532
533       if ((dialect & PPC_OPCODE_RAW) == 0)
534         return opcode;
535
536       /* The raw machine insn is one that is not a specialization.  */
537       if (last == NULL
538           || (last->mask & ~opcode->mask) != 0)
539         last = opcode;
540     }
541
542   return last;
543 }
544
545 /* Find a match for INSN in the VLE opcode table.  */
546
547 static const struct powerpc_opcode *
548 lookup_vle (unsigned long insn)
549 {
550   const struct powerpc_opcode *opcode;
551   const struct powerpc_opcode *opcode_end;
552   unsigned op, seg;
553
554   op = PPC_OP (insn);
555   if (op >= 0x20 && op <= 0x37)
556     {
557       /* This insn has a 4-bit opcode.  */
558       op &= 0x3c;
559     }
560   seg = VLE_OP_TO_SEG (op);
561
562   /* Find the first match in the opcode table for this major opcode.  */
563   opcode_end = vle_opcodes + vle_opcd_indices[seg + 1];
564   for (opcode = vle_opcodes + vle_opcd_indices[seg];
565        opcode < opcode_end;
566        ++opcode)
567     {
568       unsigned long table_opcd = opcode->opcode;
569       unsigned long table_mask = opcode->mask;
570       bfd_boolean table_op_is_short = PPC_OP_SE_VLE(table_mask);
571       unsigned long insn2;
572       const unsigned char *opindex;
573       const struct powerpc_operand *operand;
574       int invalid;
575
576       insn2 = insn;
577       if (table_op_is_short)
578         insn2 >>= 16;
579       if ((insn2 & table_mask) != table_opcd)
580         continue;
581
582       /* Check validity of operands.  */
583       invalid = 0;
584       for (opindex = opcode->operands; *opindex != 0; ++opindex)
585         {
586           operand = powerpc_operands + *opindex;
587           if (operand->extract)
588             (*operand->extract) (insn, (ppc_cpu_t)0, &invalid);
589         }
590       if (invalid)
591         continue;
592
593       return opcode;
594     }
595
596   return NULL;
597 }
598
599 /* Print a PowerPC or POWER instruction.  */
600
601 static int
602 print_insn_powerpc (bfd_vma memaddr,
603                     struct disassemble_info *info,
604                     int bigendian,
605                     ppc_cpu_t dialect)
606 {
607   bfd_byte buffer[4];
608   int status;
609   unsigned long insn;
610   const struct powerpc_opcode *opcode;
611   bfd_boolean insn_is_short;
612
613   status = (*info->read_memory_func) (memaddr, buffer, 4, info);
614   if (status != 0)
615     {
616       /* The final instruction may be a 2-byte VLE insn.  */
617       if ((dialect & PPC_OPCODE_VLE) != 0)
618         {
619           /* Clear buffer so unused bytes will not have garbage in them.  */
620           buffer[0] = buffer[1] = buffer[2] = buffer[3] = 0;
621           status = (*info->read_memory_func) (memaddr, buffer, 2, info);
622           if (status != 0)
623             {
624               (*info->memory_error_func) (status, memaddr, info);
625               return -1;
626             }
627         }
628       else
629         {
630           (*info->memory_error_func) (status, memaddr, info);
631           return -1;
632         }
633     }
634
635   if (bigendian)
636     insn = bfd_getb32 (buffer);
637   else
638     insn = bfd_getl32 (buffer);
639
640   /* Get the major opcode of the insn.  */
641   opcode = NULL;
642   insn_is_short = FALSE;
643   if ((dialect & PPC_OPCODE_VLE) != 0)
644     {
645       opcode = lookup_vle (insn);
646       if (opcode != NULL)
647         insn_is_short = PPC_OP_SE_VLE(opcode->mask);
648     }
649   if (opcode == NULL)
650     opcode = lookup_powerpc (insn, dialect & ~PPC_OPCODE_ANY);
651   if (opcode == NULL && (dialect & PPC_OPCODE_ANY) != 0)
652     opcode = lookup_powerpc (insn, dialect);
653
654   if (opcode != NULL)
655     {
656       const unsigned char *opindex;
657       const struct powerpc_operand *operand;
658       int need_comma;
659       int need_paren;
660       int skip_optional;
661
662       if (opcode->operands[0] != 0)
663         (*info->fprintf_func) (info->stream, "%-7s ", opcode->name);
664       else
665         (*info->fprintf_func) (info->stream, "%s", opcode->name);
666
667       if (insn_is_short)
668         /* The operands will be fetched out of the 16-bit instruction.  */
669         insn >>= 16;
670
671       /* Now extract and print the operands.  */
672       need_comma = 0;
673       need_paren = 0;
674       skip_optional = -1;
675       for (opindex = opcode->operands; *opindex != 0; opindex++)
676         {
677           long value;
678
679           operand = powerpc_operands + *opindex;
680
681           /* Operands that are marked FAKE are simply ignored.  We
682              already made sure that the extract function considered
683              the instruction to be valid.  */
684           if ((operand->flags & PPC_OPERAND_FAKE) != 0)
685             continue;
686
687           /* If all of the optional operands have the value zero,
688              then don't print any of them.  */
689           if ((operand->flags & PPC_OPERAND_OPTIONAL) != 0)
690             {
691               if (skip_optional < 0)
692                 skip_optional = skip_optional_operands (opindex, insn,
693                                                         dialect);
694               if (skip_optional)
695                 continue;
696             }
697
698           value = operand_value_powerpc (operand, insn, dialect);
699
700           if (need_comma)
701             {
702               (*info->fprintf_func) (info->stream, ",");
703               need_comma = 0;
704             }
705
706           /* Print the operand as directed by the flags.  */
707           if ((operand->flags & PPC_OPERAND_GPR) != 0
708               || ((operand->flags & PPC_OPERAND_GPR_0) != 0 && value != 0))
709             (*info->fprintf_func) (info->stream, "r%ld", value);
710           else if ((operand->flags & PPC_OPERAND_FPR) != 0)
711             (*info->fprintf_func) (info->stream, "f%ld", value);
712           else if ((operand->flags & PPC_OPERAND_VR) != 0)
713             (*info->fprintf_func) (info->stream, "v%ld", value);
714           else if ((operand->flags & PPC_OPERAND_VSR) != 0)
715             (*info->fprintf_func) (info->stream, "vs%ld", value);
716           else if ((operand->flags & PPC_OPERAND_RELATIVE) != 0)
717             (*info->print_address_func) (memaddr + value, info);
718           else if ((operand->flags & PPC_OPERAND_ABSOLUTE) != 0)
719             (*info->print_address_func) ((bfd_vma) value & 0xffffffff, info);
720           else if ((operand->flags & PPC_OPERAND_FSL) != 0)
721             (*info->fprintf_func) (info->stream, "fsl%ld", value);
722           else if ((operand->flags & PPC_OPERAND_FCR) != 0)
723             (*info->fprintf_func) (info->stream, "fcr%ld", value);
724           else if ((operand->flags & PPC_OPERAND_UDI) != 0)
725             (*info->fprintf_func) (info->stream, "%ld", value);
726           else if ((operand->flags & PPC_OPERAND_CR_REG) != 0
727                    && (((dialect & PPC_OPCODE_PPC) != 0)
728                        || ((dialect & PPC_OPCODE_VLE) != 0)))
729             (*info->fprintf_func) (info->stream, "cr%ld", value);
730           else if (((operand->flags & PPC_OPERAND_CR_BIT) != 0)
731                    && (((dialect & PPC_OPCODE_PPC) != 0)
732                        || ((dialect & PPC_OPCODE_VLE) != 0)))
733             {
734               static const char *cbnames[4] = { "lt", "gt", "eq", "so" };
735               int cr;
736               int cc;
737
738               cr = value >> 2;
739               if (cr != 0)
740                 (*info->fprintf_func) (info->stream, "4*cr%d+", cr);
741               cc = value & 3;
742               (*info->fprintf_func) (info->stream, "%s", cbnames[cc]);
743             }
744           else
745             (*info->fprintf_func) (info->stream, "%d", (int) value);
746
747           if (need_paren)
748             {
749               (*info->fprintf_func) (info->stream, ")");
750               need_paren = 0;
751             }
752
753           if ((operand->flags & PPC_OPERAND_PARENS) == 0)
754             need_comma = 1;
755           else
756             {
757               (*info->fprintf_func) (info->stream, "(");
758               need_paren = 1;
759             }
760         }
761
762       /* We have found and printed an instruction.
763          If it was a short VLE instruction we have more to do.  */
764       if (insn_is_short)
765         {
766           memaddr += 2;
767           return 2;
768         }
769       else
770         /* Otherwise, return.  */
771         return 4;
772     }
773
774   /* We could not find a match.  */
775   (*info->fprintf_func) (info->stream, ".long 0x%lx", insn);
776
777   return 4;
778 }
779
780 const disasm_options_t *
781 disassembler_options_powerpc (void)
782 {
783   static disasm_options_t *opts = NULL;
784
785   if (opts == NULL)
786     {
787       size_t i, num_options = ARRAY_SIZE (ppc_opts);
788       opts = XNEW (disasm_options_t);
789       opts->name = XNEWVEC (const char *, num_options + 1);
790       for (i = 0; i < num_options; i++)
791         opts->name[i] = ppc_opts[i].opt;
792       /* The array we return must be NULL terminated.  */
793       opts->name[i] = NULL;
794       opts->description = NULL;
795     }
796
797   return opts;
798 }
799
800 void
801 print_ppc_disassembler_options (FILE *stream)
802 {
803   unsigned int i, col;
804
805   fprintf (stream, _("\n\
806 The following PPC specific disassembler options are supported for use with\n\
807 the -M switch:\n"));
808
809   for (col = 0, i = 0; i < ARRAY_SIZE (ppc_opts); i++)
810     {
811       col += fprintf (stream, " %s,", ppc_opts[i].opt);
812       if (col > 66)
813         {
814           fprintf (stream, "\n");
815           col = 0;
816         }
817     }
818   fprintf (stream, "\n");
819 }