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