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