Coverage Report

Created: 2026-07-12 09:22

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/binutils-gdb/opcodes/ppc-dis.c
Line
Count
Source
1
/* ppc-dis.c -- Disassemble PowerPC instructions
2
   Copyright (C) 1994-2026 Free Software Foundation, Inc.
3
   Written by Ian Lance Taylor, Cygnus Support
4
5
   This file is part of the GNU opcodes library.
6
7
   This library is free software; you can redistribute it and/or modify
8
   it under the terms of the GNU General Public License as published by
9
   the Free Software Foundation; either version 3, or (at your option)
10
   any later version.
11
12
   It is distributed in the hope that it will be useful, but WITHOUT
13
   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14
   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
15
   License for more details.
16
17
   You should have received a copy of the GNU General Public License
18
   along with this file; see the file COPYING.  If not, write to the
19
   Free Software Foundation, 51 Franklin Street - Fifth Floor, Boston,
20
   MA 02110-1301, USA.  */
21
22
#include "sysdep.h"
23
#include <stdio.h>
24
#include "disassemble.h"
25
#include "elf-bfd.h"
26
#include "elf/ppc.h"
27
#include "opintl.h"
28
#include "opcode/ppc.h"
29
#include "libiberty.h"
30
31
/* This file provides several disassembler functions, all of which use
32
   the disassembler interface defined in dis-asm.h.  Several functions
33
   are provided because this file handles disassembly for the PowerPC
34
   in both big and little endian mode and also for the POWER (RS/6000)
35
   chip.  */
36
static int print_insn_powerpc (bfd_vma, struct disassemble_info *, int,
37
             ppc_cpu_t);
38
39
struct dis_private
40
{
41
  /* Stash the result of parsing disassembler_options here.  */
42
  ppc_cpu_t dialect;
43
44
  /* .got and .plt sections.  NAME is set to NULL if not present.  */
45
  struct sec_buf {
46
    asection *sec;
47
    bfd_byte *buf;
48
    const char *name;
49
  } special[2];
50
};
51
52
static inline struct dis_private *
53
private_data (struct disassemble_info *info)
54
945k
{
55
945k
  return (struct dis_private *) info->private_data;
56
945k
}
57
58
struct ppc_mopt {
59
  /* Option string, without -m or -M prefix.  */
60
  const char *opt;
61
  /* CPU option flags.  */
62
  ppc_cpu_t cpu;
63
  /* Flags that should stay on, even when combined with another cpu
64
     option.  This should only be used for generic options like
65
     "-many" or "-maltivec" where it is reasonable to add some
66
     capability to another cpu selection.  The added flags are sticky
67
     so that, for example, "-many -me500" and "-me500 -many" result in
68
     the same assembler or disassembler behaviour.  Do not use
69
     "sticky" for specific cpus, as this will prevent that cpu's flags
70
     from overriding the defaults set in powerpc_init_dialect or a
71
     prior -m option.  */
72
  ppc_cpu_t sticky;
73
};
74
75
static const struct ppc_mopt ppc_opts[] = {
76
  { "403",     PPC_OPCODE_PPC | PPC_OPCODE_403,
77
    0 },
78
  { "405",     PPC_OPCODE_PPC | PPC_OPCODE_403 | PPC_OPCODE_405,
79
    0 },
80
  { "440",     (PPC_OPCODE_PPC | PPC_OPCODE_BOOKE | PPC_OPCODE_440
81
    | PPC_OPCODE_ISEL | PPC_OPCODE_RFMCI),
82
    0 },
83
  { "464",     (PPC_OPCODE_PPC | PPC_OPCODE_BOOKE | PPC_OPCODE_440
84
    | PPC_OPCODE_ISEL | PPC_OPCODE_RFMCI),
85
    0 },
86
  { "476",     (PPC_OPCODE_PPC | PPC_OPCODE_ISEL | PPC_OPCODE_476
87
    | PPC_OPCODE_POWER4 | PPC_OPCODE_POWER5),
88
    0 },
89
  { "601",     PPC_OPCODE_PPC | PPC_OPCODE_601,
90
    0 },
91
  { "603",     PPC_OPCODE_PPC,
92
    0 },
93
  { "604",     PPC_OPCODE_PPC,
94
    0 },
95
  { "620",     PPC_OPCODE_PPC | PPC_OPCODE_64,
96
    0 },
97
  { "7400",    PPC_OPCODE_PPC | PPC_OPCODE_ALTIVEC,
98
    0 },
99
  { "7410",    PPC_OPCODE_PPC | PPC_OPCODE_ALTIVEC,
100
    0 },
101
  { "7450",    PPC_OPCODE_PPC | PPC_OPCODE_7450 | PPC_OPCODE_ALTIVEC,
102
    0 },
103
  { "7455",    PPC_OPCODE_PPC | PPC_OPCODE_ALTIVEC,
104
    0 },
105
  { "750cl",   PPC_OPCODE_PPC | PPC_OPCODE_750 | PPC_OPCODE_PPCPS
106
    , 0 },
107
  { "gekko",   PPC_OPCODE_PPC | PPC_OPCODE_750 | PPC_OPCODE_PPCPS
108
    , 0 },
109
  { "broadway", PPC_OPCODE_PPC | PPC_OPCODE_750 | PPC_OPCODE_PPCPS
110
    , 0 },
111
  { "821",     PPC_OPCODE_PPC | PPC_OPCODE_860,
112
    0 },
113
  { "850",     PPC_OPCODE_PPC | PPC_OPCODE_860,
114
    0 },
115
  { "860",     PPC_OPCODE_PPC | PPC_OPCODE_860,
116
    0 },
117
  { "a2",      (PPC_OPCODE_PPC | PPC_OPCODE_ISEL | PPC_OPCODE_POWER4
118
    | PPC_OPCODE_POWER5 | PPC_OPCODE_CACHELCK | PPC_OPCODE_64
119
    | PPC_OPCODE_A2),
120
    0 },
121
  { "altivec", PPC_OPCODE_PPC,
122
    PPC_OPCODE_ALTIVEC },
123
  { "any",     PPC_OPCODE_PPC,
124
    PPC_OPCODE_ANY },
125
  { "booke",   PPC_OPCODE_PPC | PPC_OPCODE_BOOKE,
126
    0 },
127
  { "booke32", PPC_OPCODE_PPC | PPC_OPCODE_BOOKE,
128
    0 },
129
  { "cell",    (PPC_OPCODE_PPC | PPC_OPCODE_64 | PPC_OPCODE_POWER4
130
    | PPC_OPCODE_CELL | PPC_OPCODE_ALTIVEC),
131
    0 },
132
  { "com",     PPC_OPCODE_COMMON,
133
    0 },
134
  { "e200z2",  (PPC_OPCODE_PPC | PPC_OPCODE_BOOKE | PPC_OPCODE_LSP
135
    | PPC_OPCODE_ISEL | PPC_OPCODE_EFS | PPC_OPCODE_BRLOCK
136
    | PPC_OPCODE_PMR | PPC_OPCODE_CACHELCK | PPC_OPCODE_RFMCI
137
    | PPC_OPCODE_E500 | PPC_OPCODE_VLE | PPC_OPCODE_E200Z4
138
    | PPC_OPCODE_EFS2),
139
    0 },
140
  { "e200z4",  (PPC_OPCODE_PPC | PPC_OPCODE_BOOKE | PPC_OPCODE_SPE
141
    | PPC_OPCODE_ISEL | PPC_OPCODE_EFS | PPC_OPCODE_BRLOCK
142
    | PPC_OPCODE_PMR | PPC_OPCODE_CACHELCK | PPC_OPCODE_RFMCI
143
    | PPC_OPCODE_E500 | PPC_OPCODE_VLE | PPC_OPCODE_E200Z4
144
    | PPC_OPCODE_EFS2),
145
    0 },
146
  { "e300",    PPC_OPCODE_PPC | PPC_OPCODE_E300,
147
    0 },
148
  { "e500",    (PPC_OPCODE_PPC | PPC_OPCODE_BOOKE | PPC_OPCODE_SPE
149
    | PPC_OPCODE_ISEL | PPC_OPCODE_EFS | PPC_OPCODE_BRLOCK
150
    | PPC_OPCODE_PMR | PPC_OPCODE_CACHELCK | PPC_OPCODE_RFMCI
151
    | PPC_OPCODE_E500),
152
    0 },
153
  { "e500mc",  (PPC_OPCODE_PPC | PPC_OPCODE_BOOKE | PPC_OPCODE_ISEL
154
    | PPC_OPCODE_PMR | PPC_OPCODE_CACHELCK | PPC_OPCODE_RFMCI
155
    | PPC_OPCODE_E500MC),
156
    0 },
157
  { "e500mc64",  (PPC_OPCODE_PPC | PPC_OPCODE_BOOKE | PPC_OPCODE_ISEL
158
    | PPC_OPCODE_PMR | PPC_OPCODE_CACHELCK | PPC_OPCODE_RFMCI
159
    | PPC_OPCODE_E500MC | PPC_OPCODE_64 | PPC_OPCODE_POWER5
160
    | PPC_OPCODE_POWER6 | PPC_OPCODE_POWER7),
161
    0 },
162
  { "e5500",    (PPC_OPCODE_PPC | PPC_OPCODE_BOOKE | PPC_OPCODE_ISEL
163
    | PPC_OPCODE_PMR | PPC_OPCODE_CACHELCK | PPC_OPCODE_RFMCI
164
    | PPC_OPCODE_E500MC | PPC_OPCODE_64 | PPC_OPCODE_POWER4
165
    | PPC_OPCODE_POWER5 | PPC_OPCODE_POWER6 | PPC_OPCODE_POWER7),
166
    0 },
167
  { "e6500",   (PPC_OPCODE_PPC | PPC_OPCODE_BOOKE | PPC_OPCODE_ISEL
168
    | PPC_OPCODE_PMR | PPC_OPCODE_CACHELCK | PPC_OPCODE_RFMCI
169
    | PPC_OPCODE_E500MC | PPC_OPCODE_64 | PPC_OPCODE_ALTIVEC
170
    | PPC_OPCODE_E6500 | PPC_OPCODE_TMR | PPC_OPCODE_POWER4
171
    | PPC_OPCODE_POWER5 | PPC_OPCODE_POWER6 | PPC_OPCODE_POWER7),
172
    0 },
173
  { "e500x2",  (PPC_OPCODE_PPC | PPC_OPCODE_BOOKE | PPC_OPCODE_SPE
174
    | PPC_OPCODE_ISEL | PPC_OPCODE_EFS | PPC_OPCODE_BRLOCK
175
    | PPC_OPCODE_PMR | PPC_OPCODE_CACHELCK | PPC_OPCODE_RFMCI
176
    | PPC_OPCODE_E500),
177
    0 },
178
  { "efs",     PPC_OPCODE_PPC | PPC_OPCODE_EFS,
179
    0 },
180
  { "efs2",    PPC_OPCODE_PPC | PPC_OPCODE_EFS | PPC_OPCODE_EFS2,
181
    0 },
182
  { "lsp",     PPC_OPCODE_PPC,
183
    PPC_OPCODE_LSP },
184
  { "power4",  PPC_OPCODE_PPC | PPC_OPCODE_64 | PPC_OPCODE_POWER4,
185
    0 },
186
  { "power5",  (PPC_OPCODE_PPC | PPC_OPCODE_64 | PPC_OPCODE_POWER4
187
    | PPC_OPCODE_POWER5),
188
    0 },
189
  { "power6",  (PPC_OPCODE_PPC | PPC_OPCODE_64 | PPC_OPCODE_POWER4
190
    | PPC_OPCODE_POWER5 | PPC_OPCODE_POWER6 | PPC_OPCODE_ALTIVEC),
191
    0 },
192
  { "power7",  (PPC_OPCODE_PPC | PPC_OPCODE_ISEL | PPC_OPCODE_64
193
    | PPC_OPCODE_POWER4 | PPC_OPCODE_POWER5 | PPC_OPCODE_POWER6
194
    | PPC_OPCODE_POWER7 | PPC_OPCODE_ALTIVEC | PPC_OPCODE_VSX),
195
    0 },
196
  { "power8",  (PPC_OPCODE_PPC | PPC_OPCODE_ISEL | PPC_OPCODE_64
197
    | PPC_OPCODE_POWER4 | PPC_OPCODE_POWER5 | PPC_OPCODE_POWER6
198
    | PPC_OPCODE_POWER7 | PPC_OPCODE_POWER8
199
    | PPC_OPCODE_ALTIVEC | PPC_OPCODE_VSX),
200
    0 },
201
  { "power9",  (PPC_OPCODE_PPC | PPC_OPCODE_ISEL | PPC_OPCODE_64
202
    | PPC_OPCODE_POWER4 | PPC_OPCODE_POWER5 | PPC_OPCODE_POWER6
203
    | PPC_OPCODE_POWER7 | PPC_OPCODE_POWER8 | PPC_OPCODE_POWER9
204
    | PPC_OPCODE_ALTIVEC | PPC_OPCODE_VSX),
205
    0 },
206
  { "power10", (PPC_OPCODE_PPC | PPC_OPCODE_ISEL | PPC_OPCODE_64
207
    | PPC_OPCODE_POWER4 | PPC_OPCODE_POWER5 | PPC_OPCODE_POWER6
208
    | PPC_OPCODE_POWER7 | PPC_OPCODE_POWER8 | PPC_OPCODE_POWER9
209
    | PPC_OPCODE_POWER10 | PPC_OPCODE_ALTIVEC | PPC_OPCODE_VSX),
210
    0 },
211
  { "power11", (PPC_OPCODE_PPC | PPC_OPCODE_ISEL | PPC_OPCODE_64
212
    | PPC_OPCODE_POWER4 | PPC_OPCODE_POWER5 | PPC_OPCODE_POWER6
213
    | PPC_OPCODE_POWER7 | PPC_OPCODE_POWER8 | PPC_OPCODE_POWER9
214
    | PPC_OPCODE_POWER10 | PPC_OPCODE_ALTIVEC | PPC_OPCODE_VSX),
215
    0 },
216
  { "libresoc",(PPC_OPCODE_PPC | PPC_OPCODE_ISEL | PPC_OPCODE_64
217
    | PPC_OPCODE_POWER4 | PPC_OPCODE_POWER5 | PPC_OPCODE_POWER6
218
    | PPC_OPCODE_POWER7 | PPC_OPCODE_POWER8 | PPC_OPCODE_POWER9
219
    | PPC_OPCODE_ALTIVEC | PPC_OPCODE_VSX | PPC_OPCODE_SVP64),
220
    0 },
221
  { "future",  (PPC_OPCODE_PPC | PPC_OPCODE_ISEL | PPC_OPCODE_64
222
    | PPC_OPCODE_POWER4 | PPC_OPCODE_POWER5 | PPC_OPCODE_POWER6
223
    | PPC_OPCODE_POWER7 | PPC_OPCODE_POWER8 | PPC_OPCODE_POWER9
224
    | PPC_OPCODE_POWER10 | PPC_OPCODE_ALTIVEC | PPC_OPCODE_VSX
225
    | PPC_OPCODE_FUTURE),
226
    0 },
227
  { "ppc",     PPC_OPCODE_PPC,
228
    0 },
229
  { "ppc32",   PPC_OPCODE_PPC,
230
    0 },
231
  { "32",      PPC_OPCODE_PPC,
232
    0 },
233
  { "ppc64",   PPC_OPCODE_PPC | PPC_OPCODE_64,
234
    0 },
235
  { "64",      PPC_OPCODE_PPC | PPC_OPCODE_64,
236
    0 },
237
  { "ppc64bridge", PPC_OPCODE_PPC | PPC_OPCODE_64_BRIDGE,
238
    0 },
239
  { "ppcps",   PPC_OPCODE_PPC | PPC_OPCODE_PPCPS,
240
    0 },
241
  { "pwr",     PPC_OPCODE_POWER,
242
    0 },
243
  { "pwr2",    PPC_OPCODE_POWER | PPC_OPCODE_POWER2,
244
    0 },
245
  { "pwr4",    PPC_OPCODE_PPC | PPC_OPCODE_64 | PPC_OPCODE_POWER4,
246
    0 },
247
  { "pwr5",    (PPC_OPCODE_PPC | PPC_OPCODE_64 | PPC_OPCODE_POWER4
248
    | PPC_OPCODE_POWER5),
249
    0 },
250
  { "pwr5x",   (PPC_OPCODE_PPC | PPC_OPCODE_64 | PPC_OPCODE_POWER4
251
    | PPC_OPCODE_POWER5),
252
    0 },
253
  { "pwr6",    (PPC_OPCODE_PPC | PPC_OPCODE_64 | PPC_OPCODE_POWER4
254
    | PPC_OPCODE_POWER5 | PPC_OPCODE_POWER6 | PPC_OPCODE_ALTIVEC),
255
    0 },
256
  { "pwr7",    (PPC_OPCODE_PPC | PPC_OPCODE_ISEL | PPC_OPCODE_64
257
    | PPC_OPCODE_POWER4 | PPC_OPCODE_POWER5 | PPC_OPCODE_POWER6
258
    | PPC_OPCODE_POWER7 | PPC_OPCODE_ALTIVEC | PPC_OPCODE_VSX),
259
    0 },
260
  { "pwr8",    (PPC_OPCODE_PPC | PPC_OPCODE_ISEL | PPC_OPCODE_64
261
    | PPC_OPCODE_POWER4 | PPC_OPCODE_POWER5 | PPC_OPCODE_POWER6
262
    | PPC_OPCODE_POWER7 | PPC_OPCODE_POWER8
263
    | PPC_OPCODE_ALTIVEC | PPC_OPCODE_VSX),
264
    0 },
265
  { "pwr9",    (PPC_OPCODE_PPC | PPC_OPCODE_ISEL | PPC_OPCODE_64
266
    | PPC_OPCODE_POWER4 | PPC_OPCODE_POWER5 | PPC_OPCODE_POWER6
267
    | PPC_OPCODE_POWER7 | PPC_OPCODE_POWER8 | PPC_OPCODE_POWER9
268
    | PPC_OPCODE_ALTIVEC | PPC_OPCODE_VSX),
269
    0 },
270
  { "pwr10",   (PPC_OPCODE_PPC | PPC_OPCODE_ISEL | PPC_OPCODE_64
271
    | PPC_OPCODE_POWER4 | PPC_OPCODE_POWER5 | PPC_OPCODE_POWER6
272
    | PPC_OPCODE_POWER7 | PPC_OPCODE_POWER8 | PPC_OPCODE_POWER9
273
    | PPC_OPCODE_POWER10 | PPC_OPCODE_ALTIVEC | PPC_OPCODE_VSX),
274
    0 },
275
  { "pwr11",   (PPC_OPCODE_PPC | PPC_OPCODE_ISEL | PPC_OPCODE_64
276
    | PPC_OPCODE_POWER4 | PPC_OPCODE_POWER5 | PPC_OPCODE_POWER6
277
    | PPC_OPCODE_POWER7 | PPC_OPCODE_POWER8 | PPC_OPCODE_POWER9
278
    | PPC_OPCODE_POWER10 | PPC_OPCODE_ALTIVEC | PPC_OPCODE_VSX),
279
    0 },
280
  { "pwrx",    PPC_OPCODE_POWER | PPC_OPCODE_POWER2,
281
    0 },
282
  { "raw",     PPC_OPCODE_PPC,
283
    PPC_OPCODE_RAW },
284
  { "spe",     PPC_OPCODE_PPC | PPC_OPCODE_EFS,
285
    PPC_OPCODE_SPE },
286
  { "spe2",     PPC_OPCODE_PPC | PPC_OPCODE_EFS | PPC_OPCODE_EFS2 | PPC_OPCODE_SPE,
287
    PPC_OPCODE_SPE2 },
288
  { "titan",   (PPC_OPCODE_PPC | PPC_OPCODE_BOOKE | PPC_OPCODE_PMR
289
    | PPC_OPCODE_RFMCI | PPC_OPCODE_TITAN),
290
    0 },
291
  { "vle",     (PPC_OPCODE_PPC | PPC_OPCODE_BOOKE | PPC_OPCODE_SPE
292
    | PPC_OPCODE_ISEL | PPC_OPCODE_EFS | PPC_OPCODE_BRLOCK
293
    | PPC_OPCODE_PMR | PPC_OPCODE_CACHELCK | PPC_OPCODE_RFMCI
294
    | PPC_OPCODE_EFS2 | PPC_OPCODE_SPE2),
295
    PPC_OPCODE_VLE },
296
  { "vsx",     PPC_OPCODE_PPC,
297
    PPC_OPCODE_VSX },
298
};
299
300
/* Switch between Booke and VLE dialects for interlinked dumps.  */
301
static ppc_cpu_t
302
get_powerpc_dialect (struct disassemble_info *info)
303
940k
{
304
940k
  ppc_cpu_t dialect = 0;
305
306
940k
  if (info->private_data)
307
940k
    dialect = private_data (info)->dialect;
308
309
  /* Disassemble according to the section headers flags for VLE-mode.  */
310
940k
  if (dialect & PPC_OPCODE_VLE
311
130k
      && info->section != NULL && info->section->owner != NULL
312
5.41k
      && bfd_get_flavour (info->section->owner) == bfd_target_elf_flavour
313
5.41k
      && elf_object_id (info->section->owner) == PPC32_ELF_DATA
314
5.41k
      && (elf_section_flags (info->section) & SHF_PPC_VLE) != 0)
315
9
    return dialect;
316
940k
  else
317
940k
    return dialect & ~ PPC_OPCODE_VLE;
318
940k
}
319
320
/* Handle -m and -M options that set cpu type, and .machine arg.  */
321
322
ppc_cpu_t
323
ppc_parse_cpu (ppc_cpu_t ppc_cpu, ppc_cpu_t *sticky, const char *arg)
324
978
{
325
978
  unsigned int i;
326
327
48.6k
  for (i = 0; i < ARRAY_SIZE (ppc_opts); i++)
328
48.6k
    if (strcmp (ppc_opts[i].opt, arg) == 0)
329
978
      {
330
978
  if (ppc_opts[i].sticky)
331
125
    {
332
125
      *sticky |= ppc_opts[i].sticky;
333
125
      if ((ppc_cpu & ~*sticky) != 0)
334
0
        break;
335
125
    }
336
978
  ppc_cpu = ppc_opts[i].cpu;
337
978
  break;
338
978
      }
339
978
  if (i >= ARRAY_SIZE (ppc_opts))
340
0
    return 0;
341
342
  /* SPE and LSP are mutually exclusive, don't allow them both in
343
     sticky options.  However do allow them both in ppc_cpu, so that
344
     for example, -mvle -mlsp enables both SPE and LSP for assembly.  */
345
978
  if ((ppc_opts[i].sticky & PPC_OPCODE_LSP) != 0)
346
0
    *sticky &= ~(PPC_OPCODE_SPE | PPC_OPCODE_SPE2);
347
978
  else if ((ppc_opts[i].sticky & (PPC_OPCODE_SPE | PPC_OPCODE_SPE2)) != 0)
348
0
    *sticky &= ~PPC_OPCODE_LSP;
349
978
  ppc_cpu |= *sticky;
350
351
978
  return ppc_cpu;
352
978
}
353
354
struct ppc_parse_data
355
{
356
  ppc_cpu_t dialect;
357
  ppc_cpu_t sticky;
358
};
359
360
static bool
361
ppc_parse_option (const char *opt, void *data)
362
0
{
363
0
  struct ppc_parse_data *res = data;
364
0
  ppc_cpu_t new_cpu;
365
366
0
  if (strcmp (opt, "32") == 0)
367
0
    res->dialect &= ~(ppc_cpu_t) PPC_OPCODE_64;
368
0
  else if (strcmp (opt, "64") == 0)
369
0
    res->dialect |= PPC_OPCODE_64;
370
0
  else if ((new_cpu = ppc_parse_cpu (res->dialect, &res->sticky, opt)) != 0)
371
0
    res->dialect = new_cpu;
372
0
  else
373
    /* xgettext: c-format */
374
0
    opcodes_error_handler (_("warning: ignoring unknown -M%s option"), opt);
375
0
  return true;
376
0
}
377
378
/* Determine which set of machines to disassemble for.  */
379
380
static void
381
powerpc_init_dialect (struct disassemble_info *info)
382
978
{
383
978
  struct ppc_parse_data out = { 0, 0 };
384
978
  struct dis_private *priv = calloc (1, sizeof (*priv));
385
386
978
  if (priv == NULL)
387
0
    return;
388
389
978
  switch (info->mach)
390
978
    {
391
0
    case bfd_mach_ppc_403:
392
0
    case bfd_mach_ppc_403gc:
393
0
      out.dialect = ppc_parse_cpu (out.dialect, &out.sticky, "403");
394
0
      break;
395
0
    case bfd_mach_ppc_405:
396
0
      out.dialect = ppc_parse_cpu (out.dialect, &out.sticky, "405");
397
0
      break;
398
1
    case bfd_mach_ppc_601:
399
1
      out.dialect = ppc_parse_cpu (out.dialect, &out.sticky, "601");
400
1
      break;
401
2
    case bfd_mach_ppc_750:
402
2
      out.dialect = ppc_parse_cpu (out.dialect, &out.sticky, "750cl");
403
2
      break;
404
3
    case bfd_mach_ppc_a35:
405
4
    case bfd_mach_ppc_rs64ii:
406
7
    case bfd_mach_ppc_rs64iii:
407
7
      out.dialect = (ppc_parse_cpu (out.dialect, &out.sticky, "pwr2")
408
7
         | PPC_OPCODE_64);
409
7
      break;
410
15
    case bfd_mach_ppc_e500:
411
15
      out.dialect = ppc_parse_cpu (out.dialect, &out.sticky, "e500");
412
15
      break;
413
6
    case bfd_mach_ppc_e500mc:
414
6
      out.dialect = ppc_parse_cpu (out.dialect, &out.sticky, "e500mc");
415
6
      break;
416
1
    case bfd_mach_ppc_e500mc64:
417
1
      out.dialect = ppc_parse_cpu (out.dialect, &out.sticky, "e500mc64");
418
1
      break;
419
1
    case bfd_mach_ppc_e5500:
420
1
      out.dialect = ppc_parse_cpu (out.dialect, &out.sticky, "e5500");
421
1
      break;
422
4
    case bfd_mach_ppc_e6500:
423
4
      out.dialect = ppc_parse_cpu (out.dialect, &out.sticky, "e6500");
424
4
      break;
425
3
    case bfd_mach_ppc_titan:
426
3
      out.dialect = ppc_parse_cpu (out.dialect, &out.sticky, "titan");
427
3
      break;
428
125
    case bfd_mach_ppc_vle:
429
125
      out.dialect = ppc_parse_cpu (out.dialect, &out.sticky, "vle");
430
125
      break;
431
813
    default:
432
813
      if (info->arch == bfd_arch_powerpc)
433
734
  out.dialect = (ppc_parse_cpu (out.dialect, &out.sticky, "power11")
434
734
           | PPC_OPCODE_ANY);
435
79
      else
436
79
  out.dialect = ppc_parse_cpu (out.dialect, &out.sticky, "pwr");
437
813
      break;
438
978
    }
439
440
978
  for_each_disassembler_option (info, ppc_parse_option, &out);
441
442
978
  info->private_data = priv;
443
978
  private_data (info)->dialect = out.dialect;
444
978
}
445
446
1.11k
#define PPC_OPCD_SEGS (1 + PPC_OP (-1))
447
static unsigned short powerpc_opcd_indices[PPC_OPCD_SEGS + 1];
448
68
#define PREFIX_OPCD_SEGS (1 + PPC_PREFIX_SEG (-1))
449
static unsigned short prefix_opcd_indices[PREFIX_OPCD_SEGS + 1];
450
68
#define VLE_OPCD_SEGS (1 + VLE_OP_TO_SEG (VLE_OP (-1, 0xffff)))
451
static unsigned short vle_opcd_indices[VLE_OPCD_SEGS + 1];
452
68
#define LSP_OPCD_SEGS (1 + LSP_OP_TO_SEG (-1))
453
static unsigned short lsp_opcd_indices[LSP_OPCD_SEGS + 1];
454
36
#define SPE2_OPCD_SEGS (1 + SPE2_XOP_TO_SEG (SPE2_XOP (-1)))
455
static unsigned short spe2_opcd_indices[SPE2_OPCD_SEGS + 1];
456
457
static bool
458
ppc_symbol_is_valid (asymbol *sym,
459
         struct disassemble_info *info ATTRIBUTE_UNUSED)
460
3
{
461
3
  elf_symbol_type * est;
462
463
3
  if (sym == NULL)
464
0
    return false;
465
466
3
  est = elf_symbol_from (sym);
467
468
  /* Ignore ELF hidden, local, no-type symbols.
469
     These are generated by annobin.  */
470
3
  if (est != NULL
471
3
      && ELF_ST_VISIBILITY (est->internal_elf_sym.st_other) == STV_HIDDEN
472
0
      && ELF_ST_BIND (est->internal_elf_sym.st_info) == STB_LOCAL
473
0
      && ELF_ST_TYPE (est->internal_elf_sym.st_info) == STT_NOTYPE)
474
0
    return false;
475
476
3
  return true;
477
3
}
478
479
/* Calculate opcode table indices to speed up disassembly,
480
   and init dialect.  */
481
482
void
483
disassemble_init_powerpc (struct disassemble_info *info)
484
978
{
485
978
  info->symbol_is_valid = ppc_symbol_is_valid;
486
487
978
  if (powerpc_opcd_indices[PPC_OPCD_SEGS] == 0)
488
2
    {
489
2
      unsigned seg, idx, op;
490
491
      /* PPC opcodes */
492
132
      for (seg = 0, idx = 0; seg <= PPC_OPCD_SEGS; seg++)
493
130
  {
494
130
    powerpc_opcd_indices[seg] = idx;
495
8.35k
    for (; idx < powerpc_num_opcodes; idx++)
496
8.35k
      if (seg < PPC_OP (powerpc_opcodes[idx].opcode))
497
126
        break;
498
130
  }
499
500
      /* 64-bit prefix opcodes */
501
68
      for (seg = 0, idx = 0; seg <= PREFIX_OPCD_SEGS; seg++)
502
66
  {
503
66
    prefix_opcd_indices[seg] = idx;
504
292
    for (; idx < prefix_num_opcodes; idx++)
505
288
      if (seg < PPC_PREFIX_SEG (prefix_opcodes[idx].opcode))
506
62
        break;
507
66
  }
508
509
      /* VLE opcodes */
510
68
      for (seg = 0, idx = 0; seg <= VLE_OPCD_SEGS; seg++)
511
66
  {
512
66
    vle_opcd_indices[seg] = idx;
513
512
    for (; idx < vle_num_opcodes; idx++)
514
504
      {
515
504
        op = VLE_OP (vle_opcodes[idx].opcode, vle_opcodes[idx].mask);
516
504
        if (seg < VLE_OP_TO_SEG (op))
517
58
    break;
518
504
      }
519
66
  }
520
521
      /* LSP opcodes */
522
68
      for (seg = 0, idx = 0; seg <= LSP_OPCD_SEGS; seg++)
523
66
  {
524
66
    lsp_opcd_indices[seg] = idx;
525
1.42k
    for (; idx < lsp_num_opcodes; idx++)
526
1.41k
      if (seg < LSP_OP_TO_SEG (lsp_opcodes[idx].opcode))
527
54
        break;
528
66
  }
529
530
      /* SPE2 opcodes */
531
36
      for (seg = 0, idx = 0; seg <= SPE2_OPCD_SEGS; seg++)
532
34
  {
533
34
    spe2_opcd_indices[seg] = idx;
534
1.61k
    for (; idx < spe2_num_opcodes; idx++)
535
1.60k
      {
536
1.60k
        op = SPE2_XOP (spe2_opcodes[idx].opcode);
537
1.60k
        if (seg < SPE2_XOP_TO_SEG (op))
538
24
    break;
539
1.60k
      }
540
34
  }
541
2
    }
542
543
978
  powerpc_init_dialect (info);
544
978
  if (info->private_data != NULL)
545
978
    {
546
978
      private_data (info)->special[0].name = ".got";
547
978
      private_data (info)->special[1].name = ".plt";
548
978
    }
549
978
}
550
551
void
552
disassemble_free_powerpc (struct disassemble_info *info)
553
899
{
554
899
  if (info->private_data != NULL)
555
899
    {
556
899
      free (private_data (info)->special[0].buf);
557
899
      free (private_data (info)->special[1].buf);
558
899
    }
559
899
}
560
561
/* Print a big endian PowerPC instruction.  */
562
563
int
564
print_insn_big_powerpc (bfd_vma memaddr, struct disassemble_info *info)
565
367k
{
566
367k
  return print_insn_powerpc (memaddr, info, 1, get_powerpc_dialect (info));
567
367k
}
568
569
/* Print a little endian PowerPC instruction.  */
570
571
int
572
print_insn_little_powerpc (bfd_vma memaddr, struct disassemble_info *info)
573
573k
{
574
573k
  return print_insn_powerpc (memaddr, info, 0, get_powerpc_dialect (info));
575
573k
}
576
577
/* Extract the operand value from the PowerPC or POWER instruction.  */
578
579
static int64_t
580
operand_value_powerpc (const struct powerpc_operand *operand,
581
           uint64_t insn, ppc_cpu_t dialect)
582
1.73M
{
583
1.73M
  int64_t value;
584
1.73M
  int invalid = 0;
585
  /* Extract the value from the instruction.  */
586
1.73M
  if (operand->extract)
587
152k
    value = (*operand->extract) (insn, dialect, &invalid);
588
1.58M
  else
589
1.58M
    {
590
1.58M
      if (operand->shift >= 0)
591
1.58M
  value = (insn >> operand->shift) & operand->bitm;
592
0
      else
593
0
  value = (insn << -operand->shift) & operand->bitm;
594
1.58M
      if ((operand->flags & PPC_OPERAND_SIGNED) != 0)
595
329k
  {
596
    /* BITM is always some number of zeros followed by some
597
       number of ones, followed by some number of zeros.  */
598
329k
    uint64_t top = operand->bitm;
599
    /* top & -top gives the rightmost 1 bit, so this
600
       fills in any trailing zeros.  */
601
329k
    top |= (top & -top) - 1;
602
329k
    top &= ~(top >> 1);
603
329k
    value = (value ^ top) - top;
604
329k
  }
605
1.58M
    }
606
607
1.73M
  if ((operand->flags & PPC_OPERAND_NONZERO) != 0)
608
0
    ++value;
609
610
1.73M
  return value;
611
1.73M
}
612
613
/* Determine whether the optional operand(s) should be printed.  */
614
615
static bool
616
skip_optional_operands (const ppc_opindex_t *opindex,
617
      uint64_t insn, ppc_cpu_t dialect, bool *is_pcrel)
618
60.6k
{
619
60.6k
  const struct powerpc_operand *operand;
620
60.6k
  int num_optional;
621
622
79.4k
  for (num_optional = 0; *opindex != 0; opindex++)
623
71.8k
    {
624
71.8k
      operand = &powerpc_operands[*opindex];
625
71.8k
      if ((operand->flags & PPC_OPERAND_NEXT) != 0)
626
32.7k
  return false;
627
39.0k
      if ((operand->flags & PPC_OPERAND_OPTIONAL) != 0)
628
28.4k
  {
629
28.4k
    int64_t value = operand_value_powerpc (operand, insn, dialect);
630
631
28.4k
    if (operand->shift == 52)
632
1.57k
      *is_pcrel = value != 0;
633
634
    /* Negative count is used as a flag to extract function.  */
635
28.4k
    --num_optional;
636
28.4k
    if (value != ppc_optional_operand_value (operand, insn, dialect,
637
28.4k
               num_optional))
638
20.3k
      return false;
639
28.4k
  }
640
39.0k
    }
641
642
7.61k
  return true;
643
60.6k
}
644
645
/* Find a match for INSN in the opcode table, given machine DIALECT.  */
646
647
static const struct powerpc_opcode *
648
lookup_powerpc (uint64_t insn, ppc_cpu_t dialect)
649
1.29M
{
650
1.29M
  const struct powerpc_opcode *opcode, *opcode_end;
651
1.29M
  unsigned long op;
652
653
  /* Get the major opcode of the instruction.  */
654
1.29M
  op = PPC_OP (insn);
655
656
  /* Find the first match in the opcode table for this major opcode.  */
657
1.29M
  opcode_end = powerpc_opcodes + powerpc_opcd_indices[op + 1];
658
1.29M
  for (opcode = powerpc_opcodes + powerpc_opcd_indices[op];
659
89.9M
       opcode < opcode_end;
660
88.6M
       ++opcode)
661
89.2M
    {
662
89.2M
      const ppc_opindex_t *opindex;
663
89.2M
      const struct powerpc_operand *operand;
664
89.2M
      int invalid;
665
666
89.2M
      if ((insn & opcode->mask) != opcode->opcode
667
766k
    || ((dialect & PPC_OPCODE_ANY) == 0
668
696k
        && ((opcode->flags & dialect) == 0
669
572k
      || (opcode->deprecated & dialect) != 0))
670
615k
    || (opcode->deprecated & dialect & PPC_OPCODE_RAW) != 0)
671
88.5M
  continue;
672
673
      /* Check validity of operands.  */
674
615k
      invalid = 0;
675
2.53M
      for (opindex = opcode->operands; *opindex != 0; opindex++)
676
1.91M
  {
677
1.91M
    operand = powerpc_operands + *opindex;
678
1.91M
    if (operand->extract)
679
266k
      (*operand->extract) (insn, dialect, &invalid);
680
1.91M
  }
681
615k
      if (invalid)
682
78.1k
  continue;
683
684
537k
      return opcode;
685
615k
    }
686
687
755k
  return NULL;
688
1.29M
}
689
690
/* Find a match for INSN in the PREFIX opcode table.  */
691
692
static const struct powerpc_opcode *
693
lookup_prefix (uint64_t insn, ppc_cpu_t dialect)
694
42.0k
{
695
42.0k
  const struct powerpc_opcode *opcode, *opcode_end;
696
42.0k
  unsigned long seg;
697
698
  /* Get the opcode segment of the instruction.  */
699
42.0k
  seg = PPC_PREFIX_SEG (insn);
700
701
  /* Find the first match in the opcode table for this major opcode.  */
702
42.0k
  opcode_end = prefix_opcodes + prefix_opcd_indices[seg + 1];
703
42.0k
  for (opcode = prefix_opcodes + prefix_opcd_indices[seg];
704
143k
       opcode < opcode_end;
705
101k
       ++opcode)
706
102k
    {
707
102k
      const ppc_opindex_t *opindex;
708
102k
      const struct powerpc_operand *operand;
709
102k
      int invalid;
710
711
102k
      if ((insn & opcode->mask) != opcode->opcode
712
3.35k
    || ((dialect & PPC_OPCODE_ANY) == 0
713
2.67k
        && (opcode->flags & dialect) == 0)
714
2.64k
    || (opcode->deprecated & dialect) != 0)
715
100k
  continue;
716
717
      /* Check validity of operands.  */
718
2.64k
      invalid = 0;
719
12.0k
      for (opindex = opcode->operands; *opindex != 0; opindex++)
720
9.37k
  {
721
9.37k
    operand = powerpc_operands + *opindex;
722
9.37k
    if (operand->extract)
723
5.20k
      (*operand->extract) (insn, dialect, &invalid);
724
9.37k
  }
725
2.64k
      if (invalid)
726
952
  continue;
727
728
1.68k
      return opcode;
729
2.64k
    }
730
731
40.4k
  return NULL;
732
42.0k
}
733
734
/* Find a match for INSN in the VLE opcode table.  */
735
736
static const struct powerpc_opcode *
737
lookup_vle (uint64_t insn, ppc_cpu_t dialect)
738
9
{
739
9
  const struct powerpc_opcode *opcode;
740
9
  const struct powerpc_opcode *opcode_end;
741
9
  unsigned op, seg;
742
743
9
  op = PPC_OP (insn);
744
9
  if (op >= 0x20 && op <= 0x37)
745
0
    {
746
      /* This insn has a 4-bit opcode.  */
747
0
      op &= 0x3c;
748
0
    }
749
9
  seg = VLE_OP_TO_SEG (op);
750
751
  /* Find the first match in the opcode table for this major opcode.  */
752
9
  opcode_end = vle_opcodes + vle_opcd_indices[seg + 1];
753
9
  for (opcode = vle_opcodes + vle_opcd_indices[seg];
754
38
       opcode < opcode_end;
755
29
       ++opcode)
756
37
    {
757
37
      uint64_t table_opcd = opcode->opcode;
758
37
      uint64_t table_mask = opcode->mask;
759
37
      bool table_op_is_short = PPC_OP_SE_VLE(table_mask);
760
37
      uint64_t insn2;
761
37
      const ppc_opindex_t *opindex;
762
37
      const struct powerpc_operand *operand;
763
37
      int invalid;
764
765
37
      insn2 = insn;
766
37
      if (table_op_is_short)
767
30
  insn2 >>= 16;
768
37
      if ((insn2 & table_mask) != table_opcd
769
8
    || (opcode->deprecated & dialect) != 0)
770
29
  continue;
771
772
      /* Check validity of operands.  */
773
8
      invalid = 0;
774
29
      for (opindex = opcode->operands; *opindex != 0; ++opindex)
775
21
  {
776
21
    operand = powerpc_operands + *opindex;
777
21
    if (operand->extract)
778
0
      (*operand->extract) (insn, (ppc_cpu_t)0, &invalid);
779
21
  }
780
8
      if (invalid)
781
0
  continue;
782
783
8
      return opcode;
784
8
    }
785
786
1
  return NULL;
787
9
}
788
789
/* Find a match for INSN in the LSP opcode table.  */
790
791
static const struct powerpc_opcode *
792
lookup_lsp (uint64_t insn, ppc_cpu_t dialect)
793
302k
{
794
302k
  const struct powerpc_opcode *opcode, *opcode_end;
795
302k
  unsigned op, seg;
796
797
302k
  op = PPC_OP (insn);
798
302k
  if (op != 0x4)
799
301k
    return NULL;
800
801
1.69k
  seg = LSP_OP_TO_SEG (insn);
802
803
  /* Find the first match in the opcode table for this opcode.  */
804
1.69k
  opcode_end = lsp_opcodes + lsp_opcd_indices[seg + 1];
805
1.69k
  for (opcode = lsp_opcodes + lsp_opcd_indices[seg];
806
37.2k
       opcode < opcode_end;
807
35.5k
       ++opcode)
808
35.9k
    {
809
35.9k
      const ppc_opindex_t *opindex;
810
35.9k
      const struct powerpc_operand *operand;
811
35.9k
      int invalid;
812
813
35.9k
      if ((insn & opcode->mask) != opcode->opcode
814
792
    || (opcode->deprecated & dialect) != 0)
815
35.1k
  continue;
816
817
      /* Check validity of operands.  */
818
792
      invalid = 0;
819
3.16k
      for (opindex = opcode->operands; *opindex != 0; ++opindex)
820
2.37k
  {
821
2.37k
    operand = powerpc_operands + *opindex;
822
2.37k
    if (operand->extract)
823
739
      (*operand->extract) (insn, (ppc_cpu_t) 0, &invalid);
824
2.37k
  }
825
792
      if (invalid)
826
447
  continue;
827
828
345
      return opcode;
829
792
    }
830
831
1.34k
  return NULL;
832
1.69k
}
833
834
/* Find a match for INSN in the SPE2 opcode table.  */
835
836
static const struct powerpc_opcode *
837
lookup_spe2 (uint64_t insn, ppc_cpu_t dialect)
838
436k
{
839
436k
  const struct powerpc_opcode *opcode, *opcode_end;
840
436k
  unsigned op, xop, seg;
841
842
436k
  op = PPC_OP (insn);
843
436k
  if (op != 0x4)
844
421k
    {
845
      /* This is not SPE2 insn.
846
       * All SPE2 instructions have OP=4 and differs by XOP  */
847
421k
      return NULL;
848
421k
    }
849
14.3k
  xop = SPE2_XOP (insn);
850
14.3k
  seg = SPE2_XOP_TO_SEG (xop);
851
852
  /* Find the first match in the opcode table for this opcode.  */
853
14.3k
  opcode_end = spe2_opcodes + spe2_opcd_indices[seg + 1];
854
14.3k
  for (opcode = spe2_opcodes + spe2_opcd_indices[seg];
855
599k
       opcode < opcode_end;
856
585k
       ++opcode)
857
592k
    {
858
592k
      uint64_t table_opcd = opcode->opcode;
859
592k
      uint64_t table_mask = opcode->mask;
860
592k
      uint64_t insn2;
861
592k
      const ppc_opindex_t *opindex;
862
592k
      const struct powerpc_operand *operand;
863
592k
      int invalid;
864
865
592k
      insn2 = insn;
866
592k
      if ((insn2 & table_mask) != table_opcd
867
8.33k
    || (opcode->deprecated & dialect) != 0)
868
584k
  continue;
869
870
      /* Check validity of operands.  */
871
8.33k
      invalid = 0;
872
33.5k
      for (opindex = opcode->operands; *opindex != 0; ++opindex)
873
25.1k
  {
874
25.1k
    operand = powerpc_operands + *opindex;
875
25.1k
    if (operand->extract)
876
1.70k
      (*operand->extract) (insn, (ppc_cpu_t)0, &invalid);
877
25.1k
  }
878
8.33k
      if (invalid)
879
879
  continue;
880
881
7.45k
      return opcode;
882
8.33k
    }
883
884
6.88k
  return NULL;
885
14.3k
}
886
887
static arelent *
888
bsearch_reloc (arelent **lo, arelent **hi, bfd_vma vma)
889
0
{
890
0
  while (lo < hi)
891
0
    {
892
0
      arelent **mid = lo + (hi - lo) / 2;
893
0
      arelent *rel = *mid;
894
895
0
      if (vma < rel->address)
896
0
  hi = mid;
897
0
      else if (vma > rel->address)
898
0
  lo = mid + 1;
899
0
      else
900
0
  return rel;
901
0
    }
902
0
  return NULL;
903
0
}
904
905
static bool
906
print_got_plt (struct sec_buf *sb, uint64_t vma, struct disassemble_info *info)
907
0
{
908
0
  if (sb->name != NULL)
909
0
    {
910
0
      asection *s = sb->sec;
911
0
      if (s == NULL)
912
0
  {
913
0
    s = bfd_get_section_by_name (info->section->owner, sb->name);
914
0
    sb->sec = s;
915
0
    if (s == NULL)
916
0
      sb->name = NULL;
917
0
  }
918
0
      if (s != NULL
919
0
    && vma >= s->vma
920
0
    && vma < s->vma + s->size)
921
0
  {
922
0
    asymbol *sym = NULL;
923
0
    uint64_t ent = 0;
924
0
    if (info->dynrelcount > 0)
925
0
      {
926
0
        arelent **lo = info->dynrelbuf;
927
0
        arelent **hi = lo + info->dynrelcount;
928
0
        arelent *rel = bsearch_reloc (lo, hi, vma);
929
0
        if (rel != NULL && rel->sym_ptr_ptr != NULL)
930
0
    sym = *rel->sym_ptr_ptr;
931
0
      }
932
0
    if (sym == NULL && (s->flags & SEC_HAS_CONTENTS) != 0)
933
0
      {
934
0
        if (sb->buf == NULL
935
0
      && !bfd_malloc_and_get_section (s->owner, s, &sb->buf))
936
0
    sb->name = NULL;
937
0
        if (sb->buf != NULL)
938
0
    {
939
0
      ent = bfd_get_64 (s->owner, sb->buf + (vma - s->vma));
940
0
      if (ent != 0)
941
0
        sym = (*info->symbol_at_address_func) (ent, info);
942
0
    }
943
0
      }
944
0
    (*info->fprintf_styled_func) (info->stream, dis_style_text, " [");
945
0
    if (sym != NULL)
946
0
      {
947
0
        (*info->fprintf_styled_func) (info->stream, dis_style_symbol,
948
0
              "%s", bfd_asymbol_name (sym));
949
0
        (*info->fprintf_styled_func) (info->stream, dis_style_text, "@");
950
0
        (*info->fprintf_styled_func) (info->stream, dis_style_symbol,
951
0
              "%s", sb->name + 1);
952
0
      }
953
0
    else
954
0
      {
955
0
        (*info->fprintf_styled_func) (info->stream, dis_style_address,
956
0
              "%" PRIx64, ent);
957
0
        (*info->fprintf_styled_func) (info->stream, dis_style_text, "@");
958
0
        (*info->fprintf_styled_func) (info->stream, dis_style_symbol,
959
0
              "%s", sb->name + 1);
960
0
      }
961
0
    (*info->fprintf_styled_func) (info->stream, dis_style_text, "]");
962
0
    return true;
963
0
  }
964
0
    }
965
0
  return false;
966
0
}
967
968
/* Print a PowerPC or POWER instruction.  */
969
970
static int
971
print_insn_powerpc (bfd_vma memaddr,
972
        struct disassemble_info *info,
973
        int bigendian,
974
        ppc_cpu_t dialect)
975
940k
{
976
940k
  bfd_byte buffer[4];
977
940k
  int status;
978
940k
  uint64_t insn;
979
940k
  const struct powerpc_opcode *opcode;
980
940k
  int insn_length = 4;  /* Assume we have a normal 4-byte instruction.  */
981
982
940k
  status = (*info->read_memory_func) (memaddr, buffer, 4, info);
983
984
  /* The final instruction may be a 2-byte VLE insn.  */
985
940k
  if (status != 0 && (dialect & PPC_OPCODE_VLE) != 0)
986
1
    {
987
      /* Clear buffer so unused bytes will not have garbage in them.  */
988
1
      buffer[2] = buffer[3] = 0;
989
1
      status = (*info->read_memory_func) (memaddr, buffer, 2, info);
990
1
      insn_length = 2;
991
1
    }
992
993
940k
  if (status != 0)
994
655
    {
995
655
      (*info->memory_error_func) (status, memaddr, info);
996
655
      return -1;
997
655
    }
998
999
940k
  if (bigendian)
1000
367k
    insn = bfd_getb32 (buffer);
1001
572k
  else
1002
572k
    insn = bfd_getl32 (buffer);
1003
1004
  /* Get the major opcode of the insn.  */
1005
940k
  opcode = NULL;
1006
940k
  if ((dialect & PPC_OPCODE_POWER10) != 0
1007
775k
      && PPC_OP (insn) == 0x1)
1008
21.8k
    {
1009
21.8k
      uint64_t temp_insn, suffix;
1010
21.8k
      status = (*info->read_memory_func) (memaddr + 4, buffer, 4, info);
1011
21.8k
      if (status == 0)
1012
21.8k
  {
1013
21.8k
    if (bigendian)
1014
8.41k
      suffix = bfd_getb32 (buffer);
1015
13.4k
    else
1016
13.4k
      suffix = bfd_getl32 (buffer);
1017
21.8k
    temp_insn = (insn << 32) | suffix;
1018
21.8k
    opcode = lookup_prefix (temp_insn, dialect & ~PPC_OPCODE_ANY);
1019
21.8k
    if (opcode == NULL && (dialect & PPC_OPCODE_ANY) != 0)
1020
20.2k
      opcode = lookup_prefix (temp_insn, dialect);
1021
21.8k
    if (opcode != NULL)
1022
1.68k
      {
1023
1.68k
        insn = temp_insn;
1024
1.68k
        insn_length = 8;
1025
1.68k
        if ((info->flags & WIDE_OUTPUT) != 0)
1026
0
    info->bytes_per_line = 8;
1027
1.68k
      }
1028
21.8k
  }
1029
21.8k
    }
1030
940k
  if (opcode == NULL && (dialect & PPC_OPCODE_VLE) != 0)
1031
9
    {
1032
9
      opcode = lookup_vle (insn, dialect);
1033
9
      if (opcode != NULL && PPC_OP_SE_VLE (opcode->mask))
1034
1
  {
1035
    /* The operands will be fetched out of the 16-bit instruction.  */
1036
1
    insn >>= 16;
1037
1
    insn_length = 2;
1038
1
  }
1039
9
    }
1040
940k
  if (opcode == NULL && insn_length == 4)
1041
938k
    {
1042
938k
      if ((dialect & PPC_OPCODE_LSP) != 0)
1043
0
  opcode = lookup_lsp (insn, dialect);
1044
938k
      if ((dialect & PPC_OPCODE_SPE2) != 0)
1045
130k
  opcode = lookup_spe2 (insn, dialect);
1046
938k
      if (opcode == NULL)
1047
933k
  opcode = lookup_powerpc (insn, dialect & ~PPC_OPCODE_ANY);
1048
938k
      if (opcode == NULL && (dialect & PPC_OPCODE_ANY) != 0)
1049
358k
  opcode = lookup_powerpc (insn, dialect);
1050
938k
      if (opcode == NULL && (dialect & PPC_OPCODE_ANY) != 0)
1051
305k
  opcode = lookup_spe2 (insn, dialect);
1052
938k
      if (opcode == NULL && (dialect & PPC_OPCODE_ANY) != 0)
1053
302k
  opcode = lookup_lsp (insn, dialect);
1054
938k
    }
1055
1056
940k
  if (opcode != NULL)
1057
546k
    {
1058
546k
      const ppc_opindex_t *opindex;
1059
546k
      const struct powerpc_operand *operand;
1060
546k
      enum {
1061
546k
  need_comma = 0,
1062
546k
  need_1space = 1,
1063
546k
  need_2spaces = 2,
1064
546k
  need_3spaces = 3,
1065
546k
  need_4spaces = 4,
1066
546k
  need_5spaces = 5,
1067
546k
  need_6spaces = 6,
1068
546k
  need_7spaces = 7,
1069
546k
  need_paren
1070
546k
      } op_separator;
1071
546k
      bool skip_optional;
1072
546k
      bool is_pcrel;
1073
546k
      uint64_t d34;
1074
546k
      int blanks;
1075
1076
546k
      (*info->fprintf_styled_func) (info->stream, dis_style_mnemonic,
1077
546k
            "%s", opcode->name);
1078
      /* gdb fprintf_styled_func doesn't return count printed.  */
1079
546k
      blanks = 8 - strlen (opcode->name);
1080
546k
      if (blanks <= 0)
1081
18.8k
  blanks = 1;
1082
1083
      /* Now extract and print the operands.  */
1084
546k
      op_separator = blanks;
1085
546k
      skip_optional = false;
1086
546k
      is_pcrel = false;
1087
546k
      d34 = 0;
1088
2.26M
      for (opindex = opcode->operands; *opindex != 0; opindex++)
1089
1.71M
  {
1090
1.71M
    int64_t value;
1091
1092
1.71M
    operand = powerpc_operands + *opindex;
1093
1094
    /* If all of the optional operands past this one have their
1095
       default value, then don't print any of them.  Except in
1096
       raw mode, print them all.  */
1097
1.71M
    if ((operand->flags & PPC_OPERAND_OPTIONAL) != 0
1098
61.0k
        && (dialect & PPC_OPCODE_RAW) == 0)
1099
61.0k
      {
1100
61.0k
        if (!skip_optional)
1101
60.6k
    skip_optional = skip_optional_operands (opindex, insn,
1102
60.6k
              dialect, &is_pcrel);
1103
61.0k
        if (skip_optional)
1104
7.93k
    continue;
1105
61.0k
      }
1106
1107
1.71M
    value = operand_value_powerpc (operand, insn, dialect);
1108
1109
1.71M
    if (op_separator == need_comma)
1110
985k
      (*info->fprintf_styled_func) (info->stream, dis_style_text, ",");
1111
725k
    else if (op_separator == need_paren)
1112
182k
      (*info->fprintf_styled_func) (info->stream, dis_style_text, "(");
1113
542k
    else
1114
542k
      (*info->fprintf_styled_func) (info->stream, dis_style_text, "%*s",
1115
542k
            op_separator, " ");
1116
1117
    /* Print the operand as directed by the flags.  */
1118
1.71M
    if ((operand->flags & PPC_OPERAND_GPR) != 0
1119
1.08M
        || ((operand->flags & PPC_OPERAND_GPR_0) != 0 && value != 0))
1120
788k
      (*info->fprintf_styled_func) (info->stream, dis_style_register,
1121
788k
            "r%" PRId64, value);
1122
921k
    else if ((operand->flags & PPC_OPERAND_FPR) != 0)
1123
202k
      (*info->fprintf_styled_func) (info->stream, dis_style_register,
1124
202k
            "f%" PRId64, value);
1125
718k
    else if ((operand->flags & PPC_OPERAND_VR) != 0)
1126
42.0k
      (*info->fprintf_styled_func) (info->stream, dis_style_register,
1127
42.0k
            "v%" PRId64, value);
1128
676k
    else if ((operand->flags & PPC_OPERAND_VSR) != 0)
1129
33.9k
      (*info->fprintf_styled_func) (info->stream, dis_style_register,
1130
33.9k
            "vs%" PRId64, value);
1131
642k
    else if ((operand->flags & PPC_OPERAND_DMR) != 0)
1132
161
      (*info->fprintf_styled_func) (info->stream, dis_style_register,
1133
161
            "dm%" PRId64, value);
1134
642k
    else if ((operand->flags & PPC_OPERAND_ACC) != 0)
1135
162
      (*info->fprintf_styled_func) (info->stream, dis_style_register,
1136
162
            "a%" PRId64, value);
1137
642k
    else if ((operand->flags & PPC_OPERAND_RELATIVE) != 0)
1138
16.6k
      (*info->print_address_func) (memaddr + value, info);
1139
625k
    else if ((operand->flags & PPC_OPERAND_ABSOLUTE) != 0)
1140
24.6k
      (*info->print_address_func) ((bfd_vma) value & 0xffffffff, info);
1141
601k
    else if ((operand->flags & PPC_OPERAND_FSL) != 0)
1142
0
      (*info->fprintf_styled_func) (info->stream, dis_style_register,
1143
0
            "fsl%" PRId64, value);
1144
601k
    else if ((operand->flags & PPC_OPERAND_FCR) != 0)
1145
81
      (*info->fprintf_styled_func) (info->stream, dis_style_register,
1146
81
            "fcr%" PRId64, value);
1147
601k
    else if ((operand->flags & PPC_OPERAND_UDI) != 0)
1148
480
      (*info->fprintf_styled_func) (info->stream, dis_style_register,
1149
480
            "%" PRId64, value);
1150
600k
    else if ((operand->flags & PPC_OPERAND_CR_REG) != 0
1151
22.4k
       && (operand->flags & PPC_OPERAND_CR_BIT) == 0
1152
22.3k
       && (((dialect & PPC_OPCODE_PPC) != 0)
1153
549
           || ((dialect & PPC_OPCODE_VLE) != 0)))
1154
21.8k
      (*info->fprintf_styled_func) (info->stream, dis_style_register,
1155
21.8k
            "cr%" PRId64, value);
1156
578k
    else if ((operand->flags & PPC_OPERAND_CR_BIT) != 0
1157
26.3k
       && (operand->flags & PPC_OPERAND_CR_REG) == 0
1158
26.3k
       && (((dialect & PPC_OPCODE_PPC) != 0)
1159
535
           || ((dialect & PPC_OPCODE_VLE) != 0)))
1160
25.7k
      {
1161
25.7k
        static const char *cbnames[4] = { "lt", "gt", "eq", "so" };
1162
25.7k
        int cr;
1163
25.7k
        int cc;
1164
1165
25.7k
        cr = value >> 2;
1166
25.7k
        cc = value & 3;
1167
25.7k
        if (cr != 0)
1168
6.11k
    {
1169
6.11k
      (*info->fprintf_styled_func) (info->stream, dis_style_text,
1170
6.11k
            "4*");
1171
6.11k
      (*info->fprintf_styled_func) (info->stream,
1172
6.11k
            dis_style_register,
1173
6.11k
            "cr%d", cr);
1174
6.11k
      (*info->fprintf_styled_func) (info->stream, dis_style_text,
1175
6.11k
            "+");
1176
6.11k
    }
1177
1178
25.7k
        (*info->fprintf_styled_func) (info->stream,
1179
25.7k
              dis_style_sub_mnemonic,
1180
25.7k
              "%s", cbnames[cc]);
1181
25.7k
      }
1182
553k
    else
1183
553k
      {
1184
        /* An immediate, but what style?  */
1185
553k
        enum disassembler_style style;
1186
1187
553k
        if ((operand->flags & PPC_OPERAND_PARENS) != 0)
1188
182k
    style = dis_style_address_offset;
1189
370k
        else
1190
370k
    style = dis_style_immediate;
1191
1192
553k
        (*info->fprintf_styled_func) (info->stream, style,
1193
553k
              "%" PRId64, value);
1194
553k
      }
1195
1196
1.71M
    if (operand->shift == 52)
1197
124
      is_pcrel = value != 0;
1198
1.71M
    else if (operand->bitm == UINT64_C (0x3ffffffff))
1199
1.20k
      d34 = value;
1200
1201
1.71M
    if (op_separator == need_paren)
1202
182k
      (*info->fprintf_styled_func) (info->stream, dis_style_text, ")");
1203
1204
1.71M
    op_separator = need_comma;
1205
1.71M
    if ((operand->flags & PPC_OPERAND_PARENS) != 0)
1206
182k
      op_separator = need_paren;
1207
1.71M
  }
1208
1209
546k
      if (is_pcrel)
1210
430
  {
1211
430
    d34 += memaddr;
1212
430
    (*info->fprintf_styled_func) (info->stream,
1213
430
          dis_style_comment_start,
1214
430
          "\t# %" PRIx64, d34);
1215
430
    asymbol *sym = (*info->symbol_at_address_func) (d34, info);
1216
430
    if (sym)
1217
0
      (*info->fprintf_styled_func) (info->stream, dis_style_text,
1218
0
            " <%s>", bfd_asymbol_name (sym));
1219
1220
430
    if (info->private_data != NULL
1221
430
        && info->section != NULL
1222
2
        && info->section->owner != NULL
1223
2
        && (bfd_get_file_flags (info->section->owner)
1224
2
      & (EXEC_P | DYNAMIC)) != 0
1225
0
        && ((insn & ((-1ULL << 50) | (0x3fULL << 26)))
1226
0
      == ((1ULL << 58) | (1ULL << 52) | (57ULL << 26)) /* pld */))
1227
0
      {
1228
0
        for (int i = 0; i < 2; i++)
1229
0
    if (print_got_plt (private_data (info)->special + i, d34, info))
1230
0
      break;
1231
0
      }
1232
430
  }
1233
1234
      /* We have found and printed an instruction.  */
1235
546k
      return insn_length;
1236
546k
    }
1237
1238
  /* We could not find a match.  */
1239
393k
  if (insn_length == 4)
1240
393k
    (*info->fprintf_styled_func) (info->stream,
1241
393k
          dis_style_assembler_directive, ".long");
1242
0
  else
1243
0
    {
1244
0
      (*info->fprintf_styled_func) (info->stream,
1245
0
            dis_style_assembler_directive, ".word");
1246
0
      insn >>= 16;
1247
0
    }
1248
393k
  (*info->fprintf_styled_func) (info->stream, dis_style_text, " ");
1249
393k
  (*info->fprintf_styled_func) (info->stream, dis_style_immediate, "0x%x",
1250
393k
        (unsigned int) insn);
1251
1252
1253
393k
  return insn_length;
1254
940k
}
1255
1256
const disasm_options_and_args_t *
1257
disassembler_options_powerpc (void)
1258
0
{
1259
0
  static disasm_options_and_args_t *opts_and_args;
1260
1261
0
  if (opts_and_args == NULL)
1262
0
    {
1263
0
      size_t i, num_options = ARRAY_SIZE (ppc_opts);
1264
0
      disasm_options_t *opts;
1265
1266
0
      opts_and_args = XNEW (disasm_options_and_args_t);
1267
0
      opts_and_args->args = NULL;
1268
1269
0
      opts = &opts_and_args->options;
1270
0
      opts->name = XNEWVEC (const char *, num_options + 1);
1271
0
      opts->description = NULL;
1272
0
      opts->arg = NULL;
1273
0
      for (i = 0; i < num_options; i++)
1274
0
  opts->name[i] = ppc_opts[i].opt;
1275
      /* The array we return must be NULL terminated.  */
1276
0
      opts->name[i] = NULL;
1277
0
    }
1278
1279
0
  return opts_and_args;
1280
0
}
1281
1282
void
1283
print_ppc_disassembler_options (FILE *stream)
1284
0
{
1285
0
  unsigned int i, col;
1286
1287
0
  fprintf (stream, _("\n\
1288
0
The following PPC specific disassembler options are supported for use with\n\
1289
0
the -M switch:\n"));
1290
1291
0
  for (col = 0, i = 0; i < ARRAY_SIZE (ppc_opts); i++)
1292
0
    {
1293
0
      col += fprintf (stream, " %s,", ppc_opts[i].opt);
1294
0
      if (col > 66)
1295
0
  {
1296
0
    fprintf (stream, "\n");
1297
0
    col = 0;
1298
0
  }
1299
0
    }
1300
0
  fprintf (stream, "\n");
1301
0
}