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