Add MTE register set support for core files
[deliverable/binutils-gdb.git] / opcodes / ppc-dis.c
1 /* ppc-dis.c -- Disassemble PowerPC instructions
2 Copyright (C) 1994-2021 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, *last;
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 last = NULL;
592 for (opcode = powerpc_opcodes + powerpc_opcd_indices[op];
593 opcode < opcode_end;
594 ++opcode)
595 {
596 const unsigned char *opindex;
597 const struct powerpc_operand *operand;
598 int invalid;
599
600 if ((insn & opcode->mask) != opcode->opcode
601 || ((dialect & PPC_OPCODE_ANY) == 0
602 && ((opcode->flags & dialect) == 0
603 || (opcode->deprecated & dialect) != 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 if ((dialect & PPC_OPCODE_RAW) == 0)
618 return opcode;
619
620 /* The raw machine insn is one that is not a specialization. */
621 if (last == NULL
622 || (last->mask & ~opcode->mask) != 0)
623 last = opcode;
624 }
625
626 return last;
627 }
628
629 /* Find a match for INSN in the PREFIX opcode table. */
630
631 static const struct powerpc_opcode *
632 lookup_prefix (uint64_t insn, ppc_cpu_t dialect)
633 {
634 const struct powerpc_opcode *opcode, *opcode_end, *last;
635 unsigned long seg;
636
637 /* Get the opcode segment of the instruction. */
638 seg = PPC_PREFIX_SEG (insn);
639
640 /* Find the first match in the opcode table for this major opcode. */
641 opcode_end = prefix_opcodes + prefix_opcd_indices[seg + 1];
642 last = NULL;
643 for (opcode = prefix_opcodes + prefix_opcd_indices[seg];
644 opcode < opcode_end;
645 ++opcode)
646 {
647 const unsigned char *opindex;
648 const struct powerpc_operand *operand;
649 int invalid;
650
651 if ((insn & opcode->mask) != opcode->opcode
652 || ((dialect & PPC_OPCODE_ANY) == 0
653 && ((opcode->flags & dialect) == 0
654 || (opcode->deprecated & dialect) != 0)))
655 continue;
656
657 /* Check validity of operands. */
658 invalid = 0;
659 for (opindex = opcode->operands; *opindex != 0; opindex++)
660 {
661 operand = powerpc_operands + *opindex;
662 if (operand->extract)
663 (*operand->extract) (insn, dialect, &invalid);
664 }
665 if (invalid)
666 continue;
667
668 if ((dialect & PPC_OPCODE_RAW) == 0)
669 return opcode;
670
671 /* The raw machine insn is one that is not a specialization. */
672 if (last == NULL
673 || (last->mask & ~opcode->mask) != 0)
674 last = opcode;
675 }
676
677 return last;
678 }
679
680 /* Find a match for INSN in the VLE opcode table. */
681
682 static const struct powerpc_opcode *
683 lookup_vle (uint64_t insn)
684 {
685 const struct powerpc_opcode *opcode;
686 const struct powerpc_opcode *opcode_end;
687 unsigned op, seg;
688
689 op = PPC_OP (insn);
690 if (op >= 0x20 && op <= 0x37)
691 {
692 /* This insn has a 4-bit opcode. */
693 op &= 0x3c;
694 }
695 seg = VLE_OP_TO_SEG (op);
696
697 /* Find the first match in the opcode table for this major opcode. */
698 opcode_end = vle_opcodes + vle_opcd_indices[seg + 1];
699 for (opcode = vle_opcodes + vle_opcd_indices[seg];
700 opcode < opcode_end;
701 ++opcode)
702 {
703 uint64_t table_opcd = opcode->opcode;
704 uint64_t table_mask = opcode->mask;
705 bool table_op_is_short = PPC_OP_SE_VLE(table_mask);
706 uint64_t insn2;
707 const unsigned char *opindex;
708 const struct powerpc_operand *operand;
709 int invalid;
710
711 insn2 = insn;
712 if (table_op_is_short)
713 insn2 >>= 16;
714 if ((insn2 & table_mask) != table_opcd)
715 continue;
716
717 /* Check validity of operands. */
718 invalid = 0;
719 for (opindex = opcode->operands; *opindex != 0; ++opindex)
720 {
721 operand = powerpc_operands + *opindex;
722 if (operand->extract)
723 (*operand->extract) (insn, (ppc_cpu_t)0, &invalid);
724 }
725 if (invalid)
726 continue;
727
728 return opcode;
729 }
730
731 return NULL;
732 }
733
734 /* Find a match for INSN in the SPE2 opcode table. */
735
736 static const struct powerpc_opcode *
737 lookup_spe2 (uint64_t insn)
738 {
739 const struct powerpc_opcode *opcode, *opcode_end;
740 unsigned op, xop, seg;
741
742 op = PPC_OP (insn);
743 if (op != 0x4)
744 {
745 /* This is not SPE2 insn.
746 * All SPE2 instructions have OP=4 and differs by XOP */
747 return NULL;
748 }
749 xop = SPE2_XOP (insn);
750 seg = SPE2_XOP_TO_SEG (xop);
751
752 /* Find the first match in the opcode table for this major opcode. */
753 opcode_end = spe2_opcodes + spe2_opcd_indices[seg + 1];
754 for (opcode = spe2_opcodes + spe2_opcd_indices[seg];
755 opcode < opcode_end;
756 ++opcode)
757 {
758 uint64_t table_opcd = opcode->opcode;
759 uint64_t table_mask = opcode->mask;
760 uint64_t insn2;
761 const unsigned char *opindex;
762 const struct powerpc_operand *operand;
763 int invalid;
764
765 insn2 = insn;
766 if ((insn2 & table_mask) != table_opcd)
767 continue;
768
769 /* Check validity of operands. */
770 invalid = 0;
771 for (opindex = opcode->operands; *opindex != 0; ++opindex)
772 {
773 operand = powerpc_operands + *opindex;
774 if (operand->extract)
775 (*operand->extract) (insn, (ppc_cpu_t)0, &invalid);
776 }
777 if (invalid)
778 continue;
779
780 return opcode;
781 }
782
783 return NULL;
784 }
785
786 static arelent *
787 bsearch_reloc (arelent **lo, arelent **hi, bfd_vma vma)
788 {
789 while (lo < hi)
790 {
791 arelent **mid = lo + (hi - lo) / 2;
792 arelent *rel = *mid;
793
794 if (vma < rel->address)
795 hi = mid;
796 else if (vma > rel->address)
797 lo = mid + 1;
798 else
799 return rel;
800 }
801 return NULL;
802 }
803
804 static bool
805 print_got_plt (struct sec_buf *sb, uint64_t vma, struct disassemble_info *info)
806 {
807 if (sb->name != NULL)
808 {
809 asection *s = sb->sec;
810 if (s == NULL)
811 {
812 s = bfd_get_section_by_name (info->section->owner, sb->name);
813 sb->sec = s;
814 if (s == NULL)
815 sb->name = NULL;
816 }
817 if (s != NULL
818 && vma >= s->vma
819 && vma < s->vma + s->size)
820 {
821 asymbol *sym = NULL;
822 uint64_t ent = 0;
823 if (info->dynrelcount > 0)
824 {
825 arelent **lo = info->dynrelbuf;
826 arelent **hi = lo + info->dynrelcount;
827 arelent *rel = bsearch_reloc (lo, hi, vma);
828 if (rel != NULL && rel->sym_ptr_ptr != NULL)
829 sym = *rel->sym_ptr_ptr;
830 }
831 if (sym == NULL && (s->flags & SEC_HAS_CONTENTS) != 0)
832 {
833 if (sb->buf == NULL
834 && !bfd_malloc_and_get_section (s->owner, s, &sb->buf))
835 sb->name = NULL;
836 if (sb->buf != NULL)
837 {
838 ent = bfd_get_64 (s->owner, sb->buf + (vma - s->vma));
839 if (ent != 0)
840 sym = (*info->symbol_at_address_func) (ent, info);
841 }
842 }
843 if (sym != NULL)
844 (*info->fprintf_func) (info->stream, " [%s@%s]",
845 bfd_asymbol_name (sym), sb->name + 1);
846 else
847 (*info->fprintf_func) (info->stream, " [%" PRIx64 "@%s]",
848 ent, sb->name + 1);
849 return true;
850 }
851 }
852 return false;
853 }
854
855 /* Print a PowerPC or POWER instruction. */
856
857 static int
858 print_insn_powerpc (bfd_vma memaddr,
859 struct disassemble_info *info,
860 int bigendian,
861 ppc_cpu_t dialect)
862 {
863 bfd_byte buffer[4];
864 int status;
865 uint64_t insn;
866 const struct powerpc_opcode *opcode;
867 int insn_length = 4; /* Assume we have a normal 4-byte instruction. */
868
869 status = (*info->read_memory_func) (memaddr, buffer, 4, info);
870
871 /* The final instruction may be a 2-byte VLE insn. */
872 if (status != 0 && (dialect & PPC_OPCODE_VLE) != 0)
873 {
874 /* Clear buffer so unused bytes will not have garbage in them. */
875 buffer[2] = buffer[3] = 0;
876 status = (*info->read_memory_func) (memaddr, buffer, 2, info);
877 insn_length = 2;
878 }
879
880 if (status != 0)
881 {
882 (*info->memory_error_func) (status, memaddr, info);
883 return -1;
884 }
885
886 if (bigendian)
887 insn = bfd_getb32 (buffer);
888 else
889 insn = bfd_getl32 (buffer);
890
891 /* Get the major opcode of the insn. */
892 opcode = NULL;
893 if ((dialect & PPC_OPCODE_POWER10) != 0
894 && PPC_OP (insn) == 0x1)
895 {
896 uint64_t temp_insn, suffix;
897 status = (*info->read_memory_func) (memaddr + 4, buffer, 4, info);
898 if (status == 0)
899 {
900 if (bigendian)
901 suffix = bfd_getb32 (buffer);
902 else
903 suffix = bfd_getl32 (buffer);
904 temp_insn = (insn << 32) | suffix;
905 opcode = lookup_prefix (temp_insn, dialect & ~PPC_OPCODE_ANY);
906 if (opcode == NULL && (dialect & PPC_OPCODE_ANY) != 0)
907 opcode = lookup_prefix (temp_insn, dialect);
908 if (opcode != NULL)
909 {
910 insn = temp_insn;
911 insn_length = 8;
912 if ((info->flags & WIDE_OUTPUT) != 0)
913 info->bytes_per_line = 8;
914 }
915 }
916 }
917 if (opcode == NULL && (dialect & PPC_OPCODE_VLE) != 0)
918 {
919 opcode = lookup_vle (insn);
920 if (opcode != NULL && PPC_OP_SE_VLE (opcode->mask))
921 {
922 /* The operands will be fetched out of the 16-bit instruction. */
923 insn >>= 16;
924 insn_length = 2;
925 }
926 }
927 if (opcode == NULL && insn_length == 4)
928 {
929 if ((dialect & PPC_OPCODE_SPE2) != 0)
930 opcode = lookup_spe2 (insn);
931 if (opcode == NULL)
932 opcode = lookup_powerpc (insn, dialect & ~PPC_OPCODE_ANY);
933 if (opcode == NULL && (dialect & PPC_OPCODE_ANY) != 0)
934 opcode = lookup_powerpc (insn, dialect);
935 }
936
937 if (opcode != NULL)
938 {
939 const unsigned char *opindex;
940 const struct powerpc_operand *operand;
941 enum {
942 need_comma = 0,
943 need_1space = 1,
944 need_2spaces = 2,
945 need_3spaces = 3,
946 need_4spaces = 4,
947 need_5spaces = 5,
948 need_6spaces = 6,
949 need_7spaces = 7,
950 need_paren
951 } op_separator;
952 bool skip_optional;
953 bool is_pcrel;
954 uint64_t d34;
955 int blanks;
956
957 (*info->fprintf_func) (info->stream, "%s", opcode->name);
958 /* gdb fprintf_func doesn't return count printed. */
959 blanks = 8 - strlen (opcode->name);
960 if (blanks <= 0)
961 blanks = 1;
962
963 /* Now extract and print the operands. */
964 op_separator = blanks;
965 skip_optional = false;
966 is_pcrel = false;
967 d34 = 0;
968 for (opindex = opcode->operands; *opindex != 0; opindex++)
969 {
970 int64_t value;
971
972 operand = powerpc_operands + *opindex;
973
974 /* If all of the optional operands past this one have their
975 default value, then don't print any of them. Except in
976 raw mode, print them all. */
977 if ((operand->flags & PPC_OPERAND_OPTIONAL) != 0
978 && (dialect & PPC_OPCODE_RAW) == 0)
979 {
980 if (!skip_optional)
981 skip_optional = skip_optional_operands (opindex, insn,
982 dialect, &is_pcrel);
983 if (skip_optional)
984 continue;
985 }
986
987 value = operand_value_powerpc (operand, insn, dialect);
988
989 if (op_separator == need_comma)
990 (*info->fprintf_func) (info->stream, ",");
991 else if (op_separator == need_paren)
992 (*info->fprintf_func) (info->stream, "(");
993 else
994 (*info->fprintf_func) (info->stream, "%*s", op_separator, " ");
995
996 /* Print the operand as directed by the flags. */
997 if ((operand->flags & PPC_OPERAND_GPR) != 0
998 || ((operand->flags & PPC_OPERAND_GPR_0) != 0 && value != 0))
999 (*info->fprintf_func) (info->stream, "r%" PRId64, value);
1000 else if ((operand->flags & PPC_OPERAND_FPR) != 0)
1001 (*info->fprintf_func) (info->stream, "f%" PRId64, value);
1002 else if ((operand->flags & PPC_OPERAND_VR) != 0)
1003 (*info->fprintf_func) (info->stream, "v%" PRId64, value);
1004 else if ((operand->flags & PPC_OPERAND_VSR) != 0)
1005 (*info->fprintf_func) (info->stream, "vs%" PRId64, value);
1006 else if ((operand->flags & PPC_OPERAND_ACC) != 0)
1007 (*info->fprintf_func) (info->stream, "a%" PRId64, value);
1008 else if ((operand->flags & PPC_OPERAND_RELATIVE) != 0)
1009 (*info->print_address_func) (memaddr + value, info);
1010 else if ((operand->flags & PPC_OPERAND_ABSOLUTE) != 0)
1011 (*info->print_address_func) ((bfd_vma) value & 0xffffffff, info);
1012 else if ((operand->flags & PPC_OPERAND_FSL) != 0)
1013 (*info->fprintf_func) (info->stream, "fsl%" PRId64, value);
1014 else if ((operand->flags & PPC_OPERAND_FCR) != 0)
1015 (*info->fprintf_func) (info->stream, "fcr%" PRId64, value);
1016 else if ((operand->flags & PPC_OPERAND_UDI) != 0)
1017 (*info->fprintf_func) (info->stream, "%" PRId64, value);
1018 else if ((operand->flags & PPC_OPERAND_CR_REG) != 0
1019 && (operand->flags & PPC_OPERAND_CR_BIT) == 0
1020 && (((dialect & PPC_OPCODE_PPC) != 0)
1021 || ((dialect & PPC_OPCODE_VLE) != 0)))
1022 (*info->fprintf_func) (info->stream, "cr%" PRId64, value);
1023 else if ((operand->flags & PPC_OPERAND_CR_BIT) != 0
1024 && (operand->flags & PPC_OPERAND_CR_REG) == 0
1025 && (((dialect & PPC_OPCODE_PPC) != 0)
1026 || ((dialect & PPC_OPCODE_VLE) != 0)))
1027 {
1028 static const char *cbnames[4] = { "lt", "gt", "eq", "so" };
1029 int cr;
1030 int cc;
1031
1032 cr = value >> 2;
1033 if (cr != 0)
1034 (*info->fprintf_func) (info->stream, "4*cr%d+", cr);
1035 cc = value & 3;
1036 (*info->fprintf_func) (info->stream, "%s", cbnames[cc]);
1037 }
1038 else
1039 (*info->fprintf_func) (info->stream, "%" PRId64, value);
1040
1041 if (operand->shift == 52)
1042 is_pcrel = value != 0;
1043 else if (operand->bitm == UINT64_C (0x3ffffffff))
1044 d34 = value;
1045
1046 if (op_separator == need_paren)
1047 (*info->fprintf_func) (info->stream, ")");
1048
1049 op_separator = need_comma;
1050 if ((operand->flags & PPC_OPERAND_PARENS) != 0)
1051 op_separator = need_paren;
1052 }
1053
1054 if (is_pcrel)
1055 {
1056 d34 += memaddr;
1057 (*info->fprintf_func) (info->stream, "\t# %" PRIx64, d34);
1058 asymbol *sym = (*info->symbol_at_address_func) (d34, info);
1059 if (sym)
1060 (*info->fprintf_func) (info->stream, " <%s>",
1061 bfd_asymbol_name (sym));
1062
1063 if (info->private_data != NULL
1064 && info->section != NULL
1065 && info->section->owner != NULL
1066 && (bfd_get_file_flags (info->section->owner)
1067 & (EXEC_P | DYNAMIC)) != 0
1068 && ((insn & ((-1ULL << 50) | (0x3fULL << 26)))
1069 == ((1ULL << 58) | (1ULL << 52) | (57ULL << 26)) /* pld */))
1070 {
1071 for (int i = 0; i < 2; i++)
1072 if (print_got_plt (private_data (info)->special + i, d34, info))
1073 break;
1074 }
1075 }
1076
1077 /* We have found and printed an instruction. */
1078 return insn_length;
1079 }
1080
1081 /* We could not find a match. */
1082 if (insn_length == 4)
1083 (*info->fprintf_func) (info->stream, ".long 0x%x",
1084 (unsigned int) insn);
1085 else
1086 (*info->fprintf_func) (info->stream, ".word 0x%x",
1087 (unsigned int) insn >> 16);
1088 return insn_length;
1089 }
1090
1091 const disasm_options_and_args_t *
1092 disassembler_options_powerpc (void)
1093 {
1094 static disasm_options_and_args_t *opts_and_args;
1095
1096 if (opts_and_args == NULL)
1097 {
1098 size_t i, num_options = ARRAY_SIZE (ppc_opts);
1099 disasm_options_t *opts;
1100
1101 opts_and_args = XNEW (disasm_options_and_args_t);
1102 opts_and_args->args = NULL;
1103
1104 opts = &opts_and_args->options;
1105 opts->name = XNEWVEC (const char *, num_options + 1);
1106 opts->description = NULL;
1107 opts->arg = NULL;
1108 for (i = 0; i < num_options; i++)
1109 opts->name[i] = ppc_opts[i].opt;
1110 /* The array we return must be NULL terminated. */
1111 opts->name[i] = NULL;
1112 }
1113
1114 return opts_and_args;
1115 }
1116
1117 void
1118 print_ppc_disassembler_options (FILE *stream)
1119 {
1120 unsigned int i, col;
1121
1122 fprintf (stream, _("\n\
1123 The following PPC specific disassembler options are supported for use with\n\
1124 the -M switch:\n"));
1125
1126 for (col = 0, i = 0; i < ARRAY_SIZE (ppc_opts); i++)
1127 {
1128 col += fprintf (stream, " %s,", ppc_opts[i].opt);
1129 if (col > 66)
1130 {
1131 fprintf (stream, "\n");
1132 col = 0;
1133 }
1134 }
1135 fprintf (stream, "\n");
1136 }
This page took 0.07234 seconds and 4 git commands to generate.