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