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