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