Automatic date update in version.in
[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
65b48a81 359 fprintf (stderr, _("warning: ignoring unknown -M%s option\n"), opt);
69fe9ce5 360 }
661bd698 361
fa452fa6
PB
362 info->private_data = priv;
363 POWERPC_DIALECT(info) = dialect;
b240011a
AM
364}
365
b9c361e0
JL
366#define PPC_OPCD_SEGS 64
367static unsigned short powerpc_opcd_indices[PPC_OPCD_SEGS+1];
368#define VLE_OPCD_SEGS 32
369static unsigned short vle_opcd_indices[VLE_OPCD_SEGS+1];
74081948
AF
370#define SPE2_OPCD_SEGS 13
371static unsigned short spe2_opcd_indices[SPE2_OPCD_SEGS+1];
b240011a
AM
372
373/* Calculate opcode table indices to speed up disassembly,
374 and init dialect. */
375
376void
377disassemble_init_powerpc (struct disassemble_info *info)
378{
379 int i;
d6688282 380 unsigned short last;
fa452fa6 381
27c49e9a 382 if (powerpc_opcd_indices[PPC_OPCD_SEGS] == 0)
b240011a 383 {
27c49e9a
AB
384 i = powerpc_num_opcodes;
385 while (--i >= 0)
0f873fd5
PB
386 {
387 unsigned op = PPC_OP (powerpc_opcodes[i].opcode);
388 powerpc_opcd_indices[op] = i;
389 }
27c49e9a
AB
390
391 last = powerpc_num_opcodes;
392 for (i = PPC_OPCD_SEGS; i > 0; --i)
0f873fd5
PB
393 {
394 if (powerpc_opcd_indices[i] == 0)
27c49e9a 395 powerpc_opcd_indices[i] = last;
0f873fd5
PB
396 last = powerpc_opcd_indices[i];
397 }
27c49e9a
AB
398
399 i = vle_num_opcodes;
400 while (--i >= 0)
0f873fd5
PB
401 {
402 unsigned op = VLE_OP (vle_opcodes[i].opcode, vle_opcodes[i].mask);
403 unsigned seg = VLE_OP_TO_SEG (op);
404 vle_opcd_indices[seg] = i;
405 }
27c49e9a
AB
406
407 last = vle_num_opcodes;
408 for (i = VLE_OPCD_SEGS; i > 0; --i)
0f873fd5
PB
409 {
410 if (vle_opcd_indices[i] == 0)
27c49e9a 411 vle_opcd_indices[i] = last;
0f873fd5
PB
412 last = vle_opcd_indices[i];
413 }
b9c361e0
JL
414 }
415
74081948
AF
416 /* SPE2 opcodes */
417 i = spe2_num_opcodes;
418 while (--i >= 0)
419 {
420 unsigned xop = SPE2_XOP (spe2_opcodes[i].opcode);
421 unsigned seg = SPE2_XOP_TO_SEG (xop);
74081948
AF
422 spe2_opcd_indices[seg] = i;
423 }
424
425 last = spe2_num_opcodes;
426 for (i = SPE2_OPCD_SEGS; i > 1; --i)
427 {
428 if (spe2_opcd_indices[i] == 0)
429 spe2_opcd_indices[i] = last;
430 last = spe2_opcd_indices[i];
431 }
432
b240011a
AM
433 if (info->arch == bfd_arch_powerpc)
434 powerpc_init_dialect (info);
418c1742
MG
435}
436
437/* Print a big endian PowerPC instruction. */
252b5132
RH
438
439int
823bbe9d 440print_insn_big_powerpc (bfd_vma memaddr, struct disassemble_info *info)
252b5132 441{
b9c361e0 442 return print_insn_powerpc (memaddr, info, 1, get_powerpc_dialect (info));
252b5132
RH
443}
444
418c1742 445/* Print a little endian PowerPC instruction. */
252b5132
RH
446
447int
823bbe9d 448print_insn_little_powerpc (bfd_vma memaddr, struct disassemble_info *info)
252b5132 449{
b9c361e0 450 return print_insn_powerpc (memaddr, info, 0, get_powerpc_dialect (info));
252b5132
RH
451}
452
453/* Print a POWER (RS/6000) instruction. */
454
455int
823bbe9d 456print_insn_rs6000 (bfd_vma memaddr, struct disassemble_info *info)
252b5132
RH
457{
458 return print_insn_powerpc (memaddr, info, 1, PPC_OPCODE_POWER);
459}
460
ea192fa3
PB
461/* Extract the operand value from the PowerPC or POWER instruction. */
462
0f873fd5 463static int64_t
ea192fa3 464operand_value_powerpc (const struct powerpc_operand *operand,
0f873fd5 465 uint64_t insn, ppc_cpu_t dialect)
ea192fa3 466{
0f873fd5 467 int64_t value;
ea192fa3
PB
468 int invalid;
469 /* Extract the value from the instruction. */
470 if (operand->extract)
471 value = (*operand->extract) (insn, dialect, &invalid);
472 else
473 {
b9c361e0
JL
474 if (operand->shift >= 0)
475 value = (insn >> operand->shift) & operand->bitm;
476 else
477 value = (insn << -operand->shift) & operand->bitm;
ea192fa3
PB
478 if ((operand->flags & PPC_OPERAND_SIGNED) != 0)
479 {
480 /* BITM is always some number of zeros followed by some
b9c361e0 481 number of ones, followed by some number of zeros. */
0f873fd5 482 uint64_t top = operand->bitm;
ea192fa3
PB
483 /* top & -top gives the rightmost 1 bit, so this
484 fills in any trailing zeros. */
485 top |= (top & -top) - 1;
486 top &= ~(top >> 1);
487 value = (value ^ top) - top;
488 }
489 }
490
491 return value;
492}
493
494/* Determine whether the optional operand(s) should be printed. */
495
496static int
497skip_optional_operands (const unsigned char *opindex,
0f873fd5 498 uint64_t insn, ppc_cpu_t dialect)
ea192fa3
PB
499{
500 const struct powerpc_operand *operand;
501
502 for (; *opindex != 0; opindex++)
503 {
504 operand = &powerpc_operands[*opindex];
505 if ((operand->flags & PPC_OPERAND_NEXT) != 0
506 || ((operand->flags & PPC_OPERAND_OPTIONAL) != 0
11a0cf2e
PB
507 && operand_value_powerpc (operand, insn, dialect) !=
508 ppc_optional_operand_value (operand)))
ea192fa3
PB
509 return 0;
510 }
511
512 return 1;
513}
514
52be03fd 515/* Find a match for INSN in the opcode table, given machine DIALECT. */
b9c361e0 516
d6688282 517static const struct powerpc_opcode *
0f873fd5 518lookup_powerpc (uint64_t insn, ppc_cpu_t dialect)
d6688282 519{
52be03fd 520 const struct powerpc_opcode *opcode, *opcode_end, *last;
d6688282
AM
521 unsigned long op;
522
523 /* Get the major opcode of the instruction. */
524 op = PPC_OP (insn);
525
526 /* Find the first match in the opcode table for this major opcode. */
527 opcode_end = powerpc_opcodes + powerpc_opcd_indices[op + 1];
52be03fd 528 last = NULL;
d6688282
AM
529 for (opcode = powerpc_opcodes + powerpc_opcd_indices[op];
530 opcode < opcode_end;
531 ++opcode)
532 {
533 const unsigned char *opindex;
534 const struct powerpc_operand *operand;
535 int invalid;
536
537 if ((insn & opcode->mask) != opcode->opcode
52be03fd 538 || ((dialect & PPC_OPCODE_ANY) == 0
d6688282
AM
539 && ((opcode->flags & dialect) == 0
540 || (opcode->deprecated & dialect) != 0)))
541 continue;
542
543 /* Check validity of operands. */
544 invalid = 0;
545 for (opindex = opcode->operands; *opindex != 0; opindex++)
546 {
547 operand = powerpc_operands + *opindex;
548 if (operand->extract)
549 (*operand->extract) (insn, dialect, &invalid);
550 }
551 if (invalid)
552 continue;
553
52be03fd
AM
554 if ((dialect & PPC_OPCODE_RAW) == 0)
555 return opcode;
556
557 /* The raw machine insn is one that is not a specialization. */
558 if (last == NULL
559 || (last->mask & ~opcode->mask) != 0)
560 last = opcode;
d6688282
AM
561 }
562
52be03fd 563 return last;
d6688282
AM
564}
565
b9c361e0
JL
566/* Find a match for INSN in the VLE opcode table. */
567
568static const struct powerpc_opcode *
0f873fd5 569lookup_vle (uint64_t insn)
b9c361e0
JL
570{
571 const struct powerpc_opcode *opcode;
572 const struct powerpc_opcode *opcode_end;
573 unsigned op, seg;
574
575 op = PPC_OP (insn);
576 if (op >= 0x20 && op <= 0x37)
577 {
578 /* This insn has a 4-bit opcode. */
579 op &= 0x3c;
580 }
581 seg = VLE_OP_TO_SEG (op);
582
583 /* Find the first match in the opcode table for this major opcode. */
584 opcode_end = vle_opcodes + vle_opcd_indices[seg + 1];
585 for (opcode = vle_opcodes + vle_opcd_indices[seg];
586 opcode < opcode_end;
587 ++opcode)
588 {
0f873fd5
PB
589 uint64_t table_opcd = opcode->opcode;
590 uint64_t table_mask = opcode->mask;
b9c361e0 591 bfd_boolean table_op_is_short = PPC_OP_SE_VLE(table_mask);
0f873fd5 592 uint64_t insn2;
b9c361e0
JL
593 const unsigned char *opindex;
594 const struct powerpc_operand *operand;
595 int invalid;
596
597 insn2 = insn;
598 if (table_op_is_short)
599 insn2 >>= 16;
600 if ((insn2 & table_mask) != table_opcd)
601 continue;
602
603 /* Check validity of operands. */
604 invalid = 0;
605 for (opindex = opcode->operands; *opindex != 0; ++opindex)
606 {
607 operand = powerpc_operands + *opindex;
608 if (operand->extract)
609 (*operand->extract) (insn, (ppc_cpu_t)0, &invalid);
610 }
611 if (invalid)
612 continue;
613
614 return opcode;
615 }
616
617 return NULL;
618}
619
74081948
AF
620/* Find a match for INSN in the SPE2 opcode table. */
621
622static const struct powerpc_opcode *
0f873fd5 623lookup_spe2 (uint64_t insn)
74081948
AF
624{
625 const struct powerpc_opcode *opcode, *opcode_end;
626 unsigned op, xop, seg;
627
628 op = PPC_OP (insn);
629 if (op != 0x4)
630 {
631 /* This is not SPE2 insn.
632 * All SPE2 instructions have OP=4 and differs by XOP */
633 return NULL;
634 }
635 xop = SPE2_XOP (insn);
636 seg = SPE2_XOP_TO_SEG (xop);
637
638 /* Find the first match in the opcode table for this major opcode. */
639 opcode_end = spe2_opcodes + spe2_opcd_indices[seg + 1];
640 for (opcode = spe2_opcodes + spe2_opcd_indices[seg];
641 opcode < opcode_end;
642 ++opcode)
643 {
0f873fd5
PB
644 uint64_t table_opcd = opcode->opcode;
645 uint64_t table_mask = opcode->mask;
646 uint64_t insn2;
74081948
AF
647 const unsigned char *opindex;
648 const struct powerpc_operand *operand;
649 int invalid;
650
651 insn2 = insn;
652 if ((insn2 & table_mask) != table_opcd)
653 continue;
654
655 /* Check validity of operands. */
656 invalid = 0;
657 for (opindex = opcode->operands; *opindex != 0; ++opindex)
658 {
659 operand = powerpc_operands + *opindex;
660 if (operand->extract)
661 (*operand->extract) (insn, (ppc_cpu_t)0, &invalid);
662 }
663 if (invalid)
664 continue;
665
666 return opcode;
667 }
668
669 return NULL;
670}
671
252b5132
RH
672/* Print a PowerPC or POWER instruction. */
673
674static int
823bbe9d
AM
675print_insn_powerpc (bfd_vma memaddr,
676 struct disassemble_info *info,
677 int bigendian,
fa452fa6 678 ppc_cpu_t dialect)
252b5132
RH
679{
680 bfd_byte buffer[4];
681 int status;
0f873fd5 682 uint64_t insn;
252b5132 683 const struct powerpc_opcode *opcode;
b9c361e0 684 bfd_boolean insn_is_short;
252b5132
RH
685
686 status = (*info->read_memory_func) (memaddr, buffer, 4, info);
687 if (status != 0)
688 {
b9c361e0
JL
689 /* The final instruction may be a 2-byte VLE insn. */
690 if ((dialect & PPC_OPCODE_VLE) != 0)
691 {
692 /* Clear buffer so unused bytes will not have garbage in them. */
693 buffer[0] = buffer[1] = buffer[2] = buffer[3] = 0;
694 status = (*info->read_memory_func) (memaddr, buffer, 2, info);
695 if (status != 0)
696 {
697 (*info->memory_error_func) (status, memaddr, info);
698 return -1;
699 }
700 }
701 else
702 {
703 (*info->memory_error_func) (status, memaddr, info);
704 return -1;
705 }
252b5132
RH
706 }
707
708 if (bigendian)
709 insn = bfd_getb32 (buffer);
710 else
711 insn = bfd_getl32 (buffer);
712
b9c361e0
JL
713 /* Get the major opcode of the insn. */
714 opcode = NULL;
715 insn_is_short = FALSE;
716 if ((dialect & PPC_OPCODE_VLE) != 0)
717 {
718 opcode = lookup_vle (insn);
719 if (opcode != NULL)
720 insn_is_short = PPC_OP_SE_VLE(opcode->mask);
721 }
74081948
AF
722 if (opcode == NULL && (dialect & PPC_OPCODE_SPE2) != 0)
723 opcode = lookup_spe2 (insn);
b9c361e0 724 if (opcode == NULL)
52be03fd 725 opcode = lookup_powerpc (insn, dialect & ~PPC_OPCODE_ANY);
d6688282 726 if (opcode == NULL && (dialect & PPC_OPCODE_ANY) != 0)
52be03fd 727 opcode = lookup_powerpc (insn, dialect);
252b5132 728
d6688282 729 if (opcode != NULL)
252b5132 730 {
252b5132
RH
731 const unsigned char *opindex;
732 const struct powerpc_operand *operand;
252b5132
RH
733 int need_comma;
734 int need_paren;
ea192fa3 735 int skip_optional;
252b5132 736
252b5132 737 if (opcode->operands[0] != 0)
fdd12ef3
AM
738 (*info->fprintf_func) (info->stream, "%-7s ", opcode->name);
739 else
740 (*info->fprintf_func) (info->stream, "%s", opcode->name);
252b5132 741
b9c361e0
JL
742 if (insn_is_short)
743 /* The operands will be fetched out of the 16-bit instruction. */
744 insn >>= 16;
745
252b5132
RH
746 /* Now extract and print the operands. */
747 need_comma = 0;
748 need_paren = 0;
ea192fa3 749 skip_optional = -1;
252b5132
RH
750 for (opindex = opcode->operands; *opindex != 0; opindex++)
751 {
0f873fd5 752 int64_t value;
252b5132
RH
753
754 operand = powerpc_operands + *opindex;
755
756 /* Operands that are marked FAKE are simply ignored. We
757 already made sure that the extract function considered
758 the instruction to be valid. */
759 if ((operand->flags & PPC_OPERAND_FAKE) != 0)
760 continue;
761
ea192fa3
PB
762 /* If all of the optional operands have the value zero,
763 then don't print any of them. */
65b650b4
AM
764 if ((operand->flags & PPC_OPERAND_OPTIONAL) != 0)
765 {
766 if (skip_optional < 0)
767 skip_optional = skip_optional_operands (opindex, insn,
768 dialect);
769 if (skip_optional)
770 continue;
771 }
252b5132 772
ea192fa3
PB
773 value = operand_value_powerpc (operand, insn, dialect);
774
252b5132
RH
775 if (need_comma)
776 {
777 (*info->fprintf_func) (info->stream, ",");
778 need_comma = 0;
779 }
780
781 /* Print the operand as directed by the flags. */
fdd12ef3
AM
782 if ((operand->flags & PPC_OPERAND_GPR) != 0
783 || ((operand->flags & PPC_OPERAND_GPR_0) != 0 && value != 0))
0f873fd5 784 (*info->fprintf_func) (info->stream, "r%" PPC_INT_FMT "d", value);
252b5132 785 else if ((operand->flags & PPC_OPERAND_FPR) != 0)
0f873fd5 786 (*info->fprintf_func) (info->stream, "f%" PPC_INT_FMT "d", value);
786e2c0f 787 else if ((operand->flags & PPC_OPERAND_VR) != 0)
0f873fd5 788 (*info->fprintf_func) (info->stream, "v%" PPC_INT_FMT "d", value);
9b4e5766 789 else if ((operand->flags & PPC_OPERAND_VSR) != 0)
0f873fd5 790 (*info->fprintf_func) (info->stream, "vs%" PPC_INT_FMT "d", value);
252b5132
RH
791 else if ((operand->flags & PPC_OPERAND_RELATIVE) != 0)
792 (*info->print_address_func) (memaddr + value, info);
793 else if ((operand->flags & PPC_OPERAND_ABSOLUTE) != 0)
794 (*info->print_address_func) ((bfd_vma) value & 0xffffffff, info);
43e65147 795 else if ((operand->flags & PPC_OPERAND_FSL) != 0)
0f873fd5 796 (*info->fprintf_func) (info->stream, "fsl%" PPC_INT_FMT "d", value);
081ba1b3 797 else if ((operand->flags & PPC_OPERAND_FCR) != 0)
0f873fd5 798 (*info->fprintf_func) (info->stream, "fcr%" PPC_INT_FMT "d", value);
081ba1b3 799 else if ((operand->flags & PPC_OPERAND_UDI) != 0)
0f873fd5 800 (*info->fprintf_func) (info->stream, "%" PPC_INT_FMT "d", value);
b9c361e0
JL
801 else if ((operand->flags & PPC_OPERAND_CR_REG) != 0
802 && (((dialect & PPC_OPCODE_PPC) != 0)
803 || ((dialect & PPC_OPCODE_VLE) != 0)))
0f873fd5 804 (*info->fprintf_func) (info->stream, "cr%" PPC_INT_FMT "d", value);
b9c361e0
JL
805 else if (((operand->flags & PPC_OPERAND_CR_BIT) != 0)
806 && (((dialect & PPC_OPCODE_PPC) != 0)
807 || ((dialect & PPC_OPCODE_VLE) != 0)))
252b5132 808 {
b9c361e0
JL
809 static const char *cbnames[4] = { "lt", "gt", "eq", "so" };
810 int cr;
811 int cc;
812
813 cr = value >> 2;
814 if (cr != 0)
815 (*info->fprintf_func) (info->stream, "4*cr%d+", cr);
816 cc = value & 3;
817 (*info->fprintf_func) (info->stream, "%s", cbnames[cc]);
252b5132 818 }
70dc4e32 819 else
0f873fd5 820 (*info->fprintf_func) (info->stream, "%" PPC_INT_FMT "d", value);
252b5132
RH
821
822 if (need_paren)
823 {
824 (*info->fprintf_func) (info->stream, ")");
825 need_paren = 0;
826 }
827
828 if ((operand->flags & PPC_OPERAND_PARENS) == 0)
829 need_comma = 1;
830 else
831 {
832 (*info->fprintf_func) (info->stream, "(");
833 need_paren = 1;
834 }
835 }
836
b9c361e0
JL
837 /* We have found and printed an instruction.
838 If it was a short VLE instruction we have more to do. */
839 if (insn_is_short)
840 {
841 memaddr += 2;
842 return 2;
843 }
844 else
845 /* Otherwise, return. */
846 return 4;
252b5132
RH
847 }
848
849 /* We could not find a match. */
0f873fd5 850 (*info->fprintf_func) (info->stream, ".long 0x%" PPC_INT_FMT "x", insn);
252b5132
RH
851
852 return 4;
853}
07dd56a9 854
65b48a81
PB
855const disasm_options_t *
856disassembler_options_powerpc (void)
857{
858 static disasm_options_t *opts = NULL;
859
860 if (opts == NULL)
861 {
862 size_t i, num_options = ARRAY_SIZE (ppc_opts);
863 opts = XNEW (disasm_options_t);
864 opts->name = XNEWVEC (const char *, num_options + 1);
865 for (i = 0; i < num_options; i++)
866 opts->name[i] = ppc_opts[i].opt;
867 /* The array we return must be NULL terminated. */
868 opts->name[i] = NULL;
869 opts->description = NULL;
870 }
871
872 return opts;
873}
874
07dd56a9 875void
823bbe9d 876print_ppc_disassembler_options (FILE *stream)
07dd56a9 877{
69fe9ce5
AM
878 unsigned int i, col;
879
880 fprintf (stream, _("\n\
07dd56a9 881The following PPC specific disassembler options are supported for use with\n\
69fe9ce5
AM
882the -M switch:\n"));
883
65b48a81 884 for (col = 0, i = 0; i < ARRAY_SIZE (ppc_opts); i++)
69fe9ce5
AM
885 {
886 col += fprintf (stream, " %s,", ppc_opts[i].opt);
887 if (col > 66)
888 {
889 fprintf (stream, "\n");
890 col = 0;
891 }
892 }
65b48a81 893 fprintf (stream, "\n");
07dd56a9 894}
This page took 1.41429 seconds and 4 git commands to generate.