Coverage Report

Created: 2026-05-11 07:54

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
705k
{
55
705k
  return (struct dis_private *) info->private_data;
56
705k
}
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
702k
{
304
702k
  ppc_cpu_t dialect = 0;
305
306
702k
  if (info->private_data)
307
702k
    dialect = private_data (info)->dialect;
308
309
  /* Disassemble according to the section headers flags for VLE-mode.  */
310
702k
  if (dialect & PPC_OPCODE_VLE
311
85.1k
      && info->section != NULL && info->section->owner != NULL
312
2.60k
      && bfd_get_flavour (info->section->owner) == bfd_target_elf_flavour
313
2.60k
      && elf_object_id (info->section->owner) == PPC32_ELF_DATA
314
2.60k
      && (elf_section_flags (info->section) & SHF_PPC_VLE) != 0)
315
0
    return dialect;
316
702k
  else
317
702k
    return dialect & ~ PPC_OPCODE_VLE;
318
702k
}
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
744
{
325
744
  unsigned int i;
326
327
37.2k
  for (i = 0; i < ARRAY_SIZE (ppc_opts); i++)
328
37.2k
    if (strcmp (ppc_opts[i].opt, arg) == 0)
329
744
      {
330
744
  if (ppc_opts[i].sticky)
331
99
    {
332
99
      *sticky |= ppc_opts[i].sticky;
333
99
      if ((ppc_cpu & ~*sticky) != 0)
334
0
        break;
335
99
    }
336
744
  ppc_cpu = ppc_opts[i].cpu;
337
744
  break;
338
744
      }
339
744
  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
744
  if ((ppc_opts[i].sticky & PPC_OPCODE_LSP) != 0)
346
0
    *sticky &= ~(PPC_OPCODE_SPE | PPC_OPCODE_SPE2);
347
744
  else if ((ppc_opts[i].sticky & (PPC_OPCODE_SPE | PPC_OPCODE_SPE2)) != 0)
348
0
    *sticky &= ~PPC_OPCODE_LSP;
349
744
  ppc_cpu |= *sticky;
350
351
744
  return ppc_cpu;
352
744
}
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
744
{
383
744
  struct ppc_parse_data out = { 0, 0 };
384
744
  struct dis_private *priv = calloc (1, sizeof (*priv));
385
386
744
  if (priv == NULL)
387
0
    return;
388
389
744
  switch (info->mach)
390
744
    {
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
0
    case bfd_mach_ppc_750:
402
0
      out.dialect = ppc_parse_cpu (out.dialect, &out.sticky, "750cl");
403
0
      break;
404
5
    case bfd_mach_ppc_a35:
405
6
    case bfd_mach_ppc_rs64ii:
406
8
    case bfd_mach_ppc_rs64iii:
407
8
      out.dialect = (ppc_parse_cpu (out.dialect, &out.sticky, "pwr2")
408
8
         | PPC_OPCODE_64);
409
8
      break;
410
7
    case bfd_mach_ppc_e500:
411
7
      out.dialect = ppc_parse_cpu (out.dialect, &out.sticky, "e500");
412
7
      break;
413
0
    case bfd_mach_ppc_e500mc:
414
0
      out.dialect = ppc_parse_cpu (out.dialect, &out.sticky, "e500mc");
415
0
      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
1
    case bfd_mach_ppc_e6500:
423
1
      out.dialect = ppc_parse_cpu (out.dialect, &out.sticky, "e6500");
424
1
      break;
425
2
    case bfd_mach_ppc_titan:
426
2
      out.dialect = ppc_parse_cpu (out.dialect, &out.sticky, "titan");
427
2
      break;
428
99
    case bfd_mach_ppc_vle:
429
99
      out.dialect = ppc_parse_cpu (out.dialect, &out.sticky, "vle");
430
99
      break;
431
624
    default:
432
624
      if (info->arch == bfd_arch_powerpc)
433
574
  out.dialect = (ppc_parse_cpu (out.dialect, &out.sticky, "power11")
434
574
           | PPC_OPCODE_ANY);
435
50
      else
436
50
  out.dialect = ppc_parse_cpu (out.dialect, &out.sticky, "pwr");
437
624
      break;
438
744
    }
439
440
744
  for_each_disassembler_option (info, ppc_parse_option, &out);
441
442
744
  info->private_data = priv;
443
744
  private_data (info)->dialect = out.dialect;
444
744
}
445
446
876
#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
0
{
461
0
  elf_symbol_type * est;
462
463
0
  if (sym == NULL)
464
0
    return false;
465
466
0
  est = elf_symbol_from (sym);
467
468
  /* Ignore ELF hidden, local, no-type symbols.
469
     These are generated by annobin.  */
470
0
  if (est != NULL
471
0
      && 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
0
  return true;
477
0
}
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
744
{
485
744
  info->symbol_is_valid = ppc_symbol_is_valid;
486
487
744
  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
744
  powerpc_init_dialect (info);
544
744
  if (info->private_data != NULL)
545
744
    {
546
744
      private_data (info)->special[0].name = ".got";
547
744
      private_data (info)->special[1].name = ".plt";
548
744
    }
549
744
}
550
551
void
552
disassemble_free_powerpc (struct disassemble_info *info)
553
694
{
554
694
  if (info->private_data != NULL)
555
694
    {
556
694
      free (private_data (info)->special[0].buf);
557
694
      free (private_data (info)->special[1].buf);
558
694
    }
559
694
}
560
561
/* Print a big endian PowerPC instruction.  */
562
563
int
564
print_insn_big_powerpc (bfd_vma memaddr, struct disassemble_info *info)
565
277k
{
566
277k
  return print_insn_powerpc (memaddr, info, 1, get_powerpc_dialect (info));
567
277k
}
568
569
/* Print a little endian PowerPC instruction.  */
570
571
int
572
print_insn_little_powerpc (bfd_vma memaddr, struct disassemble_info *info)
573
425k
{
574
425k
  return print_insn_powerpc (memaddr, info, 0, get_powerpc_dialect (info));
575
425k
}
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.31M
{
583
1.31M
  int64_t value;
584
1.31M
  int invalid = 0;
585
  /* Extract the value from the instruction.  */
586
1.31M
  if (operand->extract)
587
118k
    value = (*operand->extract) (insn, dialect, &invalid);
588
1.19M
  else
589
1.19M
    {
590
1.19M
      if (operand->shift >= 0)
591
1.19M
  value = (insn >> operand->shift) & operand->bitm;
592
0
      else
593
0
  value = (insn << -operand->shift) & operand->bitm;
594
1.19M
      if ((operand->flags & PPC_OPERAND_SIGNED) != 0)
595
248k
  {
596
    /* BITM is always some number of zeros followed by some
597
       number of ones, followed by some number of zeros.  */
598
248k
    uint64_t top = operand->bitm;
599
    /* top & -top gives the rightmost 1 bit, so this
600
       fills in any trailing zeros.  */
601
248k
    top |= (top & -top) - 1;
602
248k
    top &= ~(top >> 1);
603
248k
    value = (value ^ top) - top;
604
248k
  }
605
1.19M
    }
606
607
1.31M
  if ((operand->flags & PPC_OPERAND_NONZERO) != 0)
608
0
    ++value;
609
610
1.31M
  return value;
611
1.31M
}
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
46.9k
{
619
46.9k
  const struct powerpc_operand *operand;
620
46.9k
  int num_optional;
621
622
60.4k
  for (num_optional = 0; *opindex != 0; opindex++)
623
55.1k
    {
624
55.1k
      operand = &powerpc_operands[*opindex];
625
55.1k
      if ((operand->flags & PPC_OPERAND_NEXT) != 0)
626
26.7k
  return false;
627
28.3k
      if ((operand->flags & PPC_OPERAND_OPTIONAL) != 0)
628
20.6k
  {
629
20.6k
    int64_t value = operand_value_powerpc (operand, insn, dialect);
630
631
20.6k
    if (operand->shift == 52)
632
1.25k
      *is_pcrel = value != 0;
633
634
    /* Negative count is used as a flag to extract function.  */
635
20.6k
    --num_optional;
636
20.6k
    if (value != ppc_optional_operand_value (operand, insn, dialect,
637
20.6k
               num_optional))
638
14.9k
      return false;
639
20.6k
  }
640
28.3k
    }
641
642
5.31k
  return true;
643
46.9k
}
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
971k
{
650
971k
  const struct powerpc_opcode *opcode, *opcode_end;
651
971k
  unsigned long op;
652
653
  /* Get the major opcode of the instruction.  */
654
971k
  op = PPC_OP (insn);
655
656
  /* Find the first match in the opcode table for this major opcode.  */
657
971k
  opcode_end = powerpc_opcodes + powerpc_opcd_indices[op + 1];
658
971k
  for (opcode = powerpc_opcodes + powerpc_opcd_indices[op];
659
61.2M
       opcode < opcode_end;
660
60.3M
       ++opcode)
661
60.7M
    {
662
60.7M
      const ppc_opindex_t *opindex;
663
60.7M
      const struct powerpc_operand *operand;
664
60.7M
      int invalid;
665
666
60.7M
      if ((insn & opcode->mask) != opcode->opcode
667
580k
    || ((dialect & PPC_OPCODE_ANY) == 0
668
525k
        && ((opcode->flags & dialect) == 0
669
433k
      || (opcode->deprecated & dialect) != 0))
670
469k
    || (opcode->deprecated & dialect & PPC_OPCODE_RAW) != 0)
671
60.2M
  continue;
672
673
      /* Check validity of operands.  */
674
469k
      invalid = 0;
675
1.93M
      for (opindex = opcode->operands; *opindex != 0; opindex++)
676
1.46M
  {
677
1.46M
    operand = powerpc_operands + *opindex;
678
1.46M
    if (operand->extract)
679
209k
      (*operand->extract) (insn, dialect, &invalid);
680
1.46M
  }
681
469k
      if (invalid)
682
62.4k
  continue;
683
684
406k
      return opcode;
685
469k
    }
686
687
564k
  return NULL;
688
971k
}
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
29.6k
{
695
29.6k
  const struct powerpc_opcode *opcode, *opcode_end;
696
29.6k
  unsigned long seg;
697
698
  /* Get the opcode segment of the instruction.  */
699
29.6k
  seg = PPC_PREFIX_SEG (insn);
700
701
  /* Find the first match in the opcode table for this major opcode.  */
702
29.6k
  opcode_end = prefix_opcodes + prefix_opcd_indices[seg + 1];
703
29.6k
  for (opcode = prefix_opcodes + prefix_opcd_indices[seg];
704
87.3k
       opcode < opcode_end;
705
57.6k
       ++opcode)
706
58.8k
    {
707
58.8k
      const ppc_opindex_t *opindex;
708
58.8k
      const struct powerpc_operand *operand;
709
58.8k
      int invalid;
710
711
58.8k
      if ((insn & opcode->mask) != opcode->opcode
712
2.08k
    || ((dialect & PPC_OPCODE_ANY) == 0
713
1.75k
        && (opcode->flags & dialect) == 0)
714
1.75k
    || (opcode->deprecated & dialect) != 0)
715
57.1k
  continue;
716
717
      /* Check validity of operands.  */
718
1.75k
      invalid = 0;
719
8.05k
      for (opindex = opcode->operands; *opindex != 0; opindex++)
720
6.30k
  {
721
6.30k
    operand = powerpc_operands + *opindex;
722
6.30k
    if (operand->extract)
723
3.52k
      (*operand->extract) (insn, dialect, &invalid);
724
6.30k
  }
725
1.75k
      if (invalid)
726
533
  continue;
727
728
1.21k
      return opcode;
729
1.75k
    }
730
731
28.4k
  return NULL;
732
29.6k
}
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
0
{
739
0
  const struct powerpc_opcode *opcode;
740
0
  const struct powerpc_opcode *opcode_end;
741
0
  unsigned op, seg;
742
743
0
  op = PPC_OP (insn);
744
0
  if (op >= 0x20 && op <= 0x37)
745
0
    {
746
      /* This insn has a 4-bit opcode.  */
747
0
      op &= 0x3c;
748
0
    }
749
0
  seg = VLE_OP_TO_SEG (op);
750
751
  /* Find the first match in the opcode table for this major opcode.  */
752
0
  opcode_end = vle_opcodes + vle_opcd_indices[seg + 1];
753
0
  for (opcode = vle_opcodes + vle_opcd_indices[seg];
754
0
       opcode < opcode_end;
755
0
       ++opcode)
756
0
    {
757
0
      uint64_t table_opcd = opcode->opcode;
758
0
      uint64_t table_mask = opcode->mask;
759
0
      bool table_op_is_short = PPC_OP_SE_VLE(table_mask);
760
0
      uint64_t insn2;
761
0
      const ppc_opindex_t *opindex;
762
0
      const struct powerpc_operand *operand;
763
0
      int invalid;
764
765
0
      insn2 = insn;
766
0
      if (table_op_is_short)
767
0
  insn2 >>= 16;
768
0
      if ((insn2 & table_mask) != table_opcd
769
0
    || (opcode->deprecated & dialect) != 0)
770
0
  continue;
771
772
      /* Check validity of operands.  */
773
0
      invalid = 0;
774
0
      for (opindex = opcode->operands; *opindex != 0; ++opindex)
775
0
  {
776
0
    operand = powerpc_operands + *opindex;
777
0
    if (operand->extract)
778
0
      (*operand->extract) (insn, (ppc_cpu_t)0, &invalid);
779
0
  }
780
0
      if (invalid)
781
0
  continue;
782
783
0
      return opcode;
784
0
    }
785
786
0
  return NULL;
787
0
}
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
231k
{
794
231k
  const struct powerpc_opcode *opcode, *opcode_end;
795
231k
  unsigned op, seg;
796
797
231k
  op = PPC_OP (insn);
798
231k
  if (op != 0x4)
799
229k
    return NULL;
800
801
1.61k
  seg = LSP_OP_TO_SEG (insn);
802
803
  /* Find the first match in the opcode table for this opcode.  */
804
1.61k
  opcode_end = lsp_opcodes + lsp_opcd_indices[seg + 1];
805
1.61k
  for (opcode = lsp_opcodes + lsp_opcd_indices[seg];
806
37.4k
       opcode < opcode_end;
807
35.7k
       ++opcode)
808
36.1k
    {
809
36.1k
      const ppc_opindex_t *opindex;
810
36.1k
      const struct powerpc_operand *operand;
811
36.1k
      int invalid;
812
813
36.1k
      if ((insn & opcode->mask) != opcode->opcode
814
813
    || (opcode->deprecated & dialect) != 0)
815
35.3k
  continue;
816
817
      /* Check validity of operands.  */
818
813
      invalid = 0;
819
3.25k
      for (opindex = opcode->operands; *opindex != 0; ++opindex)
820
2.43k
  {
821
2.43k
    operand = powerpc_operands + *opindex;
822
2.43k
    if (operand->extract)
823
718
      (*operand->extract) (insn, (ppc_cpu_t) 0, &invalid);
824
2.43k
  }
825
813
      if (invalid)
826
484
  continue;
827
828
329
      return opcode;
829
813
    }
830
831
1.28k
  return NULL;
832
1.61k
}
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
318k
{
839
318k
  const struct powerpc_opcode *opcode, *opcode_end;
840
318k
  unsigned op, xop, seg;
841
842
318k
  op = PPC_OP (insn);
843
318k
  if (op != 0x4)
844
310k
    {
845
      /* This is not SPE2 insn.
846
       * All SPE2 instructions have OP=4 and differs by XOP  */
847
310k
      return NULL;
848
310k
    }
849
8.13k
  xop = SPE2_XOP (insn);
850
8.13k
  seg = SPE2_XOP_TO_SEG (xop);
851
852
  /* Find the first match in the opcode table for this opcode.  */
853
8.13k
  opcode_end = spe2_opcodes + spe2_opcd_indices[seg + 1];
854
8.13k
  for (opcode = spe2_opcodes + spe2_opcd_indices[seg];
855
360k
       opcode < opcode_end;
856
352k
       ++opcode)
857
356k
    {
858
356k
      uint64_t table_opcd = opcode->opcode;
859
356k
      uint64_t table_mask = opcode->mask;
860
356k
      uint64_t insn2;
861
356k
      const ppc_opindex_t *opindex;
862
356k
      const struct powerpc_operand *operand;
863
356k
      int invalid;
864
865
356k
      insn2 = insn;
866
356k
      if ((insn2 & table_mask) != table_opcd
867
4.10k
    || (opcode->deprecated & dialect) != 0)
868
352k
  continue;
869
870
      /* Check validity of operands.  */
871
4.10k
      invalid = 0;
872
16.5k
      for (opindex = opcode->operands; *opindex != 0; ++opindex)
873
12.4k
  {
874
12.4k
    operand = powerpc_operands + *opindex;
875
12.4k
    if (operand->extract)
876
1.10k
      (*operand->extract) (insn, (ppc_cpu_t)0, &invalid);
877
12.4k
  }
878
4.10k
      if (invalid)
879
643
  continue;
880
881
3.45k
      return opcode;
882
4.10k
    }
883
884
4.67k
  return NULL;
885
8.13k
}
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
702k
{
976
702k
  bfd_byte buffer[4];
977
702k
  int status;
978
702k
  uint64_t insn;
979
702k
  const struct powerpc_opcode *opcode;
980
702k
  int insn_length = 4;  /* Assume we have a normal 4-byte instruction.  */
981
982
702k
  status = (*info->read_memory_func) (memaddr, buffer, 4, info);
983
984
  /* The final instruction may be a 2-byte VLE insn.  */
985
702k
  if (status != 0 && (dialect & PPC_OPCODE_VLE) != 0)
986
0
    {
987
      /* Clear buffer so unused bytes will not have garbage in them.  */
988
0
      buffer[2] = buffer[3] = 0;
989
0
      status = (*info->read_memory_func) (memaddr, buffer, 2, info);
990
0
      insn_length = 2;
991
0
    }
992
993
702k
  if (status != 0)
994
495
    {
995
495
      (*info->memory_error_func) (status, memaddr, info);
996
495
      return -1;
997
495
    }
998
999
701k
  if (bigendian)
1000
276k
    insn = bfd_getb32 (buffer);
1001
424k
  else
1002
424k
    insn = bfd_getl32 (buffer);
1003
1004
  /* Get the major opcode of the insn.  */
1005
701k
  opcode = NULL;
1006
701k
  if ((dialect & PPC_OPCODE_POWER10) != 0
1007
592k
      && PPC_OP (insn) == 0x1)
1008
15.4k
    {
1009
15.4k
      uint64_t temp_insn, suffix;
1010
15.4k
      status = (*info->read_memory_func) (memaddr + 4, buffer, 4, info);
1011
15.4k
      if (status == 0)
1012
15.4k
  {
1013
15.4k
    if (bigendian)
1014
6.01k
      suffix = bfd_getb32 (buffer);
1015
9.39k
    else
1016
9.39k
      suffix = bfd_getl32 (buffer);
1017
15.4k
    temp_insn = (insn << 32) | suffix;
1018
15.4k
    opcode = lookup_prefix (temp_insn, dialect & ~PPC_OPCODE_ANY);
1019
15.4k
    if (opcode == NULL && (dialect & PPC_OPCODE_ANY) != 0)
1020
14.2k
      opcode = lookup_prefix (temp_insn, dialect);
1021
15.4k
    if (opcode != NULL)
1022
1.21k
      {
1023
1.21k
        insn = temp_insn;
1024
1.21k
        insn_length = 8;
1025
1.21k
        if ((info->flags & WIDE_OUTPUT) != 0)
1026
0
    info->bytes_per_line = 8;
1027
1.21k
      }
1028
15.4k
  }
1029
15.4k
    }
1030
701k
  if (opcode == NULL && (dialect & PPC_OPCODE_VLE) != 0)
1031
0
    {
1032
0
      opcode = lookup_vle (insn, dialect);
1033
0
      if (opcode != NULL && PPC_OP_SE_VLE (opcode->mask))
1034
0
  {
1035
    /* The operands will be fetched out of the 16-bit instruction.  */
1036
0
    insn >>= 16;
1037
0
    insn_length = 2;
1038
0
  }
1039
0
    }
1040
701k
  if (opcode == NULL && insn_length == 4)
1041
700k
    {
1042
700k
      if ((dialect & PPC_OPCODE_LSP) != 0)
1043
0
  opcode = lookup_lsp (insn, dialect);
1044
700k
      if ((dialect & PPC_OPCODE_SPE2) != 0)
1045
85.0k
  opcode = lookup_spe2 (insn, dialect);
1046
700k
      if (opcode == NULL)
1047
698k
  opcode = lookup_powerpc (insn, dialect & ~PPC_OPCODE_ANY);
1048
700k
      if (opcode == NULL && (dialect & PPC_OPCODE_ANY) != 0)
1049
272k
  opcode = lookup_powerpc (insn, dialect);
1050
700k
      if (opcode == NULL && (dialect & PPC_OPCODE_ANY) != 0)
1051
233k
  opcode = lookup_spe2 (insn, dialect);
1052
700k
      if (opcode == NULL && (dialect & PPC_OPCODE_ANY) != 0)
1053
231k
  opcode = lookup_lsp (insn, dialect);
1054
700k
    }
1055
1056
701k
  if (opcode != NULL)
1057
411k
    {
1058
411k
      const ppc_opindex_t *opindex;
1059
411k
      const struct powerpc_operand *operand;
1060
411k
      enum {
1061
411k
  need_comma = 0,
1062
411k
  need_1space = 1,
1063
411k
  need_2spaces = 2,
1064
411k
  need_3spaces = 3,
1065
411k
  need_4spaces = 4,
1066
411k
  need_5spaces = 5,
1067
411k
  need_6spaces = 6,
1068
411k
  need_7spaces = 7,
1069
411k
  need_paren
1070
411k
      } op_separator;
1071
411k
      bool skip_optional;
1072
411k
      bool is_pcrel;
1073
411k
      uint64_t d34;
1074
411k
      int blanks;
1075
1076
411k
      (*info->fprintf_styled_func) (info->stream, dis_style_mnemonic,
1077
411k
            "%s", opcode->name);
1078
      /* gdb fprintf_styled_func doesn't return count printed.  */
1079
411k
      blanks = 8 - strlen (opcode->name);
1080
411k
      if (blanks <= 0)
1081
10.9k
  blanks = 1;
1082
1083
      /* Now extract and print the operands.  */
1084
411k
      op_separator = blanks;
1085
411k
      skip_optional = false;
1086
411k
      is_pcrel = false;
1087
411k
      d34 = 0;
1088
1.71M
      for (opindex = opcode->operands; *opindex != 0; opindex++)
1089
1.30M
  {
1090
1.30M
    int64_t value;
1091
1092
1.30M
    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.30M
    if ((operand->flags & PPC_OPERAND_OPTIONAL) != 0
1098
47.1k
        && (dialect & PPC_OPCODE_RAW) == 0)
1099
47.1k
      {
1100
47.1k
        if (!skip_optional)
1101
46.9k
    skip_optional = skip_optional_operands (opindex, insn,
1102
46.9k
              dialect, &is_pcrel);
1103
47.1k
        if (skip_optional)
1104
5.52k
    continue;
1105
47.1k
      }
1106
1107
1.29M
    value = operand_value_powerpc (operand, insn, dialect);
1108
1109
1.29M
    if (op_separator == need_comma)
1110
743k
      (*info->fprintf_styled_func) (info->stream, dis_style_text, ",");
1111
551k
    else if (op_separator == need_paren)
1112
143k
      (*info->fprintf_styled_func) (info->stream, dis_style_text, "(");
1113
408k
    else
1114
408k
      (*info->fprintf_styled_func) (info->stream, dis_style_text, "%*s",
1115
408k
            op_separator, " ");
1116
1117
    /* Print the operand as directed by the flags.  */
1118
1.29M
    if ((operand->flags & PPC_OPERAND_GPR) != 0
1119
834k
        || ((operand->flags & PPC_OPERAND_GPR_0) != 0 && value != 0))
1120
591k
      (*info->fprintf_styled_func) (info->stream, dis_style_register,
1121
591k
            "r%" PRId64, value);
1122
703k
    else if ((operand->flags & PPC_OPERAND_FPR) != 0)
1123
151k
      (*info->fprintf_styled_func) (info->stream, dis_style_register,
1124
151k
            "f%" PRId64, value);
1125
552k
    else if ((operand->flags & PPC_OPERAND_VR) != 0)
1126
32.9k
      (*info->fprintf_styled_func) (info->stream, dis_style_register,
1127
32.9k
            "v%" PRId64, value);
1128
519k
    else if ((operand->flags & PPC_OPERAND_VSR) != 0)
1129
30.1k
      (*info->fprintf_styled_func) (info->stream, dis_style_register,
1130
30.1k
            "vs%" PRId64, value);
1131
489k
    else if ((operand->flags & PPC_OPERAND_DMR) != 0)
1132
95
      (*info->fprintf_styled_func) (info->stream, dis_style_register,
1133
95
            "dm%" PRId64, value);
1134
489k
    else if ((operand->flags & PPC_OPERAND_ACC) != 0)
1135
106
      (*info->fprintf_styled_func) (info->stream, dis_style_register,
1136
106
            "a%" PRId64, value);
1137
488k
    else if ((operand->flags & PPC_OPERAND_RELATIVE) != 0)
1138
11.2k
      (*info->print_address_func) (memaddr + value, info);
1139
477k
    else if ((operand->flags & PPC_OPERAND_ABSOLUTE) != 0)
1140
18.4k
      (*info->print_address_func) ((bfd_vma) value & 0xffffffff, info);
1141
459k
    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
459k
    else if ((operand->flags & PPC_OPERAND_FCR) != 0)
1145
66
      (*info->fprintf_styled_func) (info->stream, dis_style_register,
1146
66
            "fcr%" PRId64, value);
1147
459k
    else if ((operand->flags & PPC_OPERAND_UDI) != 0)
1148
243
      (*info->fprintf_styled_func) (info->stream, dis_style_register,
1149
243
            "%" PRId64, value);
1150
458k
    else if ((operand->flags & PPC_OPERAND_CR_REG) != 0
1151
16.9k
       && (operand->flags & PPC_OPERAND_CR_BIT) == 0
1152
16.9k
       && (((dialect & PPC_OPCODE_PPC) != 0)
1153
1.04k
           || ((dialect & PPC_OPCODE_VLE) != 0)))
1154
15.9k
      (*info->fprintf_styled_func) (info->stream, dis_style_register,
1155
15.9k
            "cr%" PRId64, value);
1156
443k
    else if ((operand->flags & PPC_OPERAND_CR_BIT) != 0
1157
19.5k
       && (operand->flags & PPC_OPERAND_CR_REG) == 0
1158
19.5k
       && (((dialect & PPC_OPCODE_PPC) != 0)
1159
725
           || ((dialect & PPC_OPCODE_VLE) != 0)))
1160
18.7k
      {
1161
18.7k
        static const char *cbnames[4] = { "lt", "gt", "eq", "so" };
1162
18.7k
        int cr;
1163
18.7k
        int cc;
1164
1165
18.7k
        cr = value >> 2;
1166
18.7k
        cc = value & 3;
1167
18.7k
        if (cr != 0)
1168
4.26k
    {
1169
4.26k
      (*info->fprintf_styled_func) (info->stream, dis_style_text,
1170
4.26k
            "4*");
1171
4.26k
      (*info->fprintf_styled_func) (info->stream,
1172
4.26k
            dis_style_register,
1173
4.26k
            "cr%d", cr);
1174
4.26k
      (*info->fprintf_styled_func) (info->stream, dis_style_text,
1175
4.26k
            "+");
1176
4.26k
    }
1177
1178
18.7k
        (*info->fprintf_styled_func) (info->stream,
1179
18.7k
              dis_style_sub_mnemonic,
1180
18.7k
              "%s", cbnames[cc]);
1181
18.7k
      }
1182
424k
    else
1183
424k
      {
1184
        /* An immediate, but what style?  */
1185
424k
        enum disassembler_style style;
1186
1187
424k
        if ((operand->flags & PPC_OPERAND_PARENS) != 0)
1188
143k
    style = dis_style_address_offset;
1189
280k
        else
1190
280k
    style = dis_style_immediate;
1191
1192
424k
        (*info->fprintf_styled_func) (info->stream, style,
1193
424k
              "%" PRId64, value);
1194
424k
      }
1195
1196
1.29M
    if (operand->shift == 52)
1197
42
      is_pcrel = value != 0;
1198
1.29M
    else if (operand->bitm == UINT64_C (0x3ffffffff))
1199
964
      d34 = value;
1200
1201
1.29M
    if (op_separator == need_paren)
1202
143k
      (*info->fprintf_styled_func) (info->stream, dis_style_text, ")");
1203
1204
1.29M
    op_separator = need_comma;
1205
1.29M
    if ((operand->flags & PPC_OPERAND_PARENS) != 0)
1206
143k
      op_separator = need_paren;
1207
1.29M
  }
1208
1209
411k
      if (is_pcrel)
1210
242
  {
1211
242
    d34 += memaddr;
1212
242
    (*info->fprintf_styled_func) (info->stream,
1213
242
          dis_style_comment_start,
1214
242
          "\t# %" PRIx64, d34);
1215
242
    asymbol *sym = (*info->symbol_at_address_func) (d34, info);
1216
242
    if (sym)
1217
0
      (*info->fprintf_styled_func) (info->stream, dis_style_text,
1218
0
            " <%s>", bfd_asymbol_name (sym));
1219
1220
242
    if (info->private_data != NULL
1221
242
        && info->section != NULL
1222
0
        && info->section->owner != NULL
1223
0
        && (bfd_get_file_flags (info->section->owner)
1224
0
      & (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
242
  }
1233
1234
      /* We have found and printed an instruction.  */
1235
411k
      return insn_length;
1236
411k
    }
1237
1238
  /* We could not find a match.  */
1239
290k
  if (insn_length == 4)
1240
290k
    (*info->fprintf_styled_func) (info->stream,
1241
290k
          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
290k
  (*info->fprintf_styled_func) (info->stream, dis_style_text, " ");
1249
290k
  (*info->fprintf_styled_func) (info->stream, dis_style_immediate, "0x%x",
1250
290k
        (unsigned int) insn);
1251
1252
1253
290k
  return insn_length;
1254
701k
}
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
}