Coverage Report

Created: 2026-03-10 08:46

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
682k
{
55
682k
  return (struct dis_private *) info->private_data;
56
682k
}
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
678k
{
304
678k
  ppc_cpu_t dialect = 0;
305
306
678k
  if (info->private_data)
307
678k
    dialect = private_data (info)->dialect;
308
309
  /* Disassemble according to the section headers flags for VLE-mode.  */
310
678k
  if (dialect & PPC_OPCODE_VLE
311
64.9k
      && info->section != NULL && info->section->owner != NULL
312
0
      && bfd_get_flavour (info->section->owner) == bfd_target_elf_flavour
313
0
      && elf_object_id (info->section->owner) == PPC32_ELF_DATA
314
0
      && (elf_section_flags (info->section) & SHF_PPC_VLE) != 0)
315
0
    return dialect;
316
678k
  else
317
678k
    return dialect & ~ PPC_OPCODE_VLE;
318
678k
}
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
746
{
325
746
  unsigned int i;
326
327
37.0k
  for (i = 0; i < ARRAY_SIZE (ppc_opts); i++)
328
37.0k
    if (strcmp (ppc_opts[i].opt, arg) == 0)
329
746
      {
330
746
  if (ppc_opts[i].sticky)
331
96
    {
332
96
      *sticky |= ppc_opts[i].sticky;
333
96
      if ((ppc_cpu & ~*sticky) != 0)
334
0
        break;
335
96
    }
336
746
  ppc_cpu = ppc_opts[i].cpu;
337
746
  break;
338
746
      }
339
746
  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
746
  if ((ppc_opts[i].sticky & PPC_OPCODE_LSP) != 0)
346
0
    *sticky &= ~(PPC_OPCODE_SPE | PPC_OPCODE_SPE2);
347
746
  else if ((ppc_opts[i].sticky & (PPC_OPCODE_SPE | PPC_OPCODE_SPE2)) != 0)
348
0
    *sticky &= ~PPC_OPCODE_LSP;
349
746
  ppc_cpu |= *sticky;
350
351
746
  return ppc_cpu;
352
746
}
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
746
{
383
746
  struct ppc_parse_data out = { 0, 0 };
384
746
  struct dis_private *priv = calloc (1, sizeof (*priv));
385
386
746
  if (priv == NULL)
387
0
    return;
388
389
746
  switch (info->mach)
390
746
    {
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
1
    case bfd_mach_ppc_750:
402
1
      out.dialect = ppc_parse_cpu (out.dialect, &out.sticky, "750cl");
403
1
      break;
404
2
    case bfd_mach_ppc_a35:
405
3
    case bfd_mach_ppc_rs64ii:
406
5
    case bfd_mach_ppc_rs64iii:
407
5
      out.dialect = (ppc_parse_cpu (out.dialect, &out.sticky, "pwr2")
408
5
         | PPC_OPCODE_64);
409
5
      break;
410
9
    case bfd_mach_ppc_e500:
411
9
      out.dialect = ppc_parse_cpu (out.dialect, &out.sticky, "e500");
412
9
      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
2
    case bfd_mach_ppc_e6500:
423
2
      out.dialect = ppc_parse_cpu (out.dialect, &out.sticky, "e6500");
424
2
      break;
425
1
    case bfd_mach_ppc_titan:
426
1
      out.dialect = ppc_parse_cpu (out.dialect, &out.sticky, "titan");
427
1
      break;
428
96
    case bfd_mach_ppc_vle:
429
96
      out.dialect = ppc_parse_cpu (out.dialect, &out.sticky, "vle");
430
96
      break;
431
629
    default:
432
629
      if (info->arch == bfd_arch_powerpc)
433
582
  out.dialect = (ppc_parse_cpu (out.dialect, &out.sticky, "power11")
434
582
           | PPC_OPCODE_ANY);
435
47
      else
436
47
  out.dialect = ppc_parse_cpu (out.dialect, &out.sticky, "pwr");
437
629
      break;
438
746
    }
439
440
746
  for_each_disassembler_option (info, ppc_parse_option, &out);
441
442
746
  info->private_data = priv;
443
746
  private_data (info)->dialect = out.dialect;
444
746
}
445
446
878
#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
389
{
461
389
  elf_symbol_type * est;
462
463
389
  if (sym == NULL)
464
0
    return false;
465
466
389
  est = elf_symbol_from (sym);
467
468
  /* Ignore ELF hidden, local, no-type symbols.
469
     These are generated by annobin.  */
470
389
  if (est != NULL
471
389
      && 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
389
  return true;
477
389
}
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
746
{
485
746
  info->symbol_is_valid = ppc_symbol_is_valid;
486
487
746
  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
746
  powerpc_init_dialect (info);
544
746
  if (info->private_data != NULL)
545
746
    {
546
746
      private_data (info)->special[0].name = ".got";
547
746
      private_data (info)->special[1].name = ".plt";
548
746
    }
549
746
}
550
551
void
552
disassemble_free_powerpc (struct disassemble_info *info)
553
699
{
554
699
  if (info->private_data != NULL)
555
699
    {
556
699
      free (private_data (info)->special[0].buf);
557
699
      free (private_data (info)->special[1].buf);
558
699
    }
559
699
}
560
561
/* Print a big endian PowerPC instruction.  */
562
563
int
564
print_insn_big_powerpc (bfd_vma memaddr, struct disassemble_info *info)
565
328k
{
566
328k
  return print_insn_powerpc (memaddr, info, 1, get_powerpc_dialect (info));
567
328k
}
568
569
/* Print a little endian PowerPC instruction.  */
570
571
int
572
print_insn_little_powerpc (bfd_vma memaddr, struct disassemble_info *info)
573
350k
{
574
350k
  return print_insn_powerpc (memaddr, info, 0, get_powerpc_dialect (info));
575
350k
}
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.27M
{
583
1.27M
  int64_t value;
584
1.27M
  int invalid = 0;
585
  /* Extract the value from the instruction.  */
586
1.27M
  if (operand->extract)
587
116k
    value = (*operand->extract) (insn, dialect, &invalid);
588
1.16M
  else
589
1.16M
    {
590
1.16M
      if (operand->shift >= 0)
591
1.16M
  value = (insn >> operand->shift) & operand->bitm;
592
0
      else
593
0
  value = (insn << -operand->shift) & operand->bitm;
594
1.16M
      if ((operand->flags & PPC_OPERAND_SIGNED) != 0)
595
240k
  {
596
    /* BITM is always some number of zeros followed by some
597
       number of ones, followed by some number of zeros.  */
598
240k
    uint64_t top = operand->bitm;
599
    /* top & -top gives the rightmost 1 bit, so this
600
       fills in any trailing zeros.  */
601
240k
    top |= (top & -top) - 1;
602
240k
    top &= ~(top >> 1);
603
240k
    value = (value ^ top) - top;
604
240k
  }
605
1.16M
    }
606
607
1.27M
  if ((operand->flags & PPC_OPERAND_NONZERO) != 0)
608
0
    ++value;
609
610
1.27M
  return value;
611
1.27M
}
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
47.7k
{
619
47.7k
  const struct powerpc_operand *operand;
620
47.7k
  int num_optional;
621
622
64.4k
  for (num_optional = 0; *opindex != 0; opindex++)
623
58.0k
    {
624
58.0k
      operand = &powerpc_operands[*opindex];
625
58.0k
      if ((operand->flags & PPC_OPERAND_NEXT) != 0)
626
26.0k
  return false;
627
32.0k
      if ((operand->flags & PPC_OPERAND_OPTIONAL) != 0)
628
22.0k
  {
629
22.0k
    int64_t value = operand_value_powerpc (operand, insn, dialect);
630
631
22.0k
    if (operand->shift == 52)
632
1.29k
      *is_pcrel = value != 0;
633
634
    /* Negative count is used as a flag to extract function.  */
635
22.0k
    --num_optional;
636
22.0k
    if (value != ppc_optional_operand_value (operand, insn, dialect,
637
22.0k
               num_optional))
638
15.2k
      return false;
639
22.0k
  }
640
32.0k
    }
641
642
6.44k
  return true;
643
47.7k
}
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
946k
{
650
946k
  const struct powerpc_opcode *opcode, *opcode_end;
651
946k
  unsigned long op;
652
653
  /* Get the major opcode of the instruction.  */
654
946k
  op = PPC_OP (insn);
655
656
  /* Find the first match in the opcode table for this major opcode.  */
657
946k
  opcode_end = powerpc_opcodes + powerpc_opcd_indices[op + 1];
658
946k
  for (opcode = powerpc_opcodes + powerpc_opcd_indices[op];
659
59.2M
       opcode < opcode_end;
660
58.2M
       ++opcode)
661
58.6M
    {
662
58.6M
      const ppc_opindex_t *opindex;
663
58.6M
      const struct powerpc_operand *operand;
664
58.6M
      int invalid;
665
666
58.6M
      if ((insn & opcode->mask) != opcode->opcode
667
554k
    || ((dialect & PPC_OPCODE_ANY) == 0
668
503k
        && ((opcode->flags & dialect) == 0
669
419k
      || (opcode->deprecated & dialect) != 0))
670
454k
    || (opcode->deprecated & dialect & PPC_OPCODE_RAW) != 0)
671
58.1M
  continue;
672
673
      /* Check validity of operands.  */
674
454k
      invalid = 0;
675
1.87M
      for (opindex = opcode->operands; *opindex != 0; opindex++)
676
1.41M
  {
677
1.41M
    operand = powerpc_operands + *opindex;
678
1.41M
    if (operand->extract)
679
203k
      (*operand->extract) (insn, dialect, &invalid);
680
1.41M
  }
681
454k
      if (invalid)
682
58.2k
  continue;
683
684
396k
      return opcode;
685
454k
    }
686
687
550k
  return NULL;
688
946k
}
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
27.9k
{
695
27.9k
  const struct powerpc_opcode *opcode, *opcode_end;
696
27.9k
  unsigned long seg;
697
698
  /* Get the opcode segment of the instruction.  */
699
27.9k
  seg = PPC_PREFIX_SEG (insn);
700
701
  /* Find the first match in the opcode table for this major opcode.  */
702
27.9k
  opcode_end = prefix_opcodes + prefix_opcd_indices[seg + 1];
703
27.9k
  for (opcode = prefix_opcodes + prefix_opcd_indices[seg];
704
77.3k
       opcode < opcode_end;
705
49.3k
       ++opcode)
706
50.5k
    {
707
50.5k
      const ppc_opindex_t *opindex;
708
50.5k
      const struct powerpc_operand *operand;
709
50.5k
      int invalid;
710
711
50.5k
      if ((insn & opcode->mask) != opcode->opcode
712
1.95k
    || ((dialect & PPC_OPCODE_ANY) == 0
713
1.74k
        && (opcode->flags & dialect) == 0)
714
1.67k
    || (opcode->deprecated & dialect) != 0)
715
48.8k
  continue;
716
717
      /* Check validity of operands.  */
718
1.67k
      invalid = 0;
719
8.05k
      for (opindex = opcode->operands; *opindex != 0; opindex++)
720
6.37k
  {
721
6.37k
    operand = powerpc_operands + *opindex;
722
6.37k
    if (operand->extract)
723
3.52k
      (*operand->extract) (insn, dialect, &invalid);
724
6.37k
  }
725
1.67k
      if (invalid)
726
495
  continue;
727
728
1.18k
      return opcode;
729
1.67k
    }
730
731
26.7k
  return NULL;
732
27.9k
}
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.49k
  seg = LSP_OP_TO_SEG (insn);
802
803
  /* Find the first match in the opcode table for this opcode.  */
804
1.49k
  opcode_end = lsp_opcodes + lsp_opcd_indices[seg + 1];
805
1.49k
  for (opcode = lsp_opcodes + lsp_opcd_indices[seg];
806
36.2k
       opcode < opcode_end;
807
34.7k
       ++opcode)
808
34.9k
    {
809
34.9k
      const ppc_opindex_t *opindex;
810
34.9k
      const struct powerpc_operand *operand;
811
34.9k
      int invalid;
812
813
34.9k
      if ((insn & opcode->mask) != opcode->opcode
814
646
    || (opcode->deprecated & dialect) != 0)
815
34.2k
  continue;
816
817
      /* Check validity of operands.  */
818
646
      invalid = 0;
819
2.58k
      for (opindex = opcode->operands; *opindex != 0; ++opindex)
820
1.93k
  {
821
1.93k
    operand = powerpc_operands + *opindex;
822
1.93k
    if (operand->extract)
823
651
      (*operand->extract) (insn, (ppc_cpu_t) 0, &invalid);
824
1.93k
  }
825
646
      if (invalid)
826
482
  continue;
827
828
164
      return opcode;
829
646
    }
830
831
1.33k
  return NULL;
832
1.49k
}
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
298k
{
839
298k
  const struct powerpc_opcode *opcode, *opcode_end;
840
298k
  unsigned op, xop, seg;
841
842
298k
  op = PPC_OP (insn);
843
298k
  if (op != 0x4)
844
291k
    {
845
      /* This is not SPE2 insn.
846
       * All SPE2 instructions have OP=4 and differs by XOP  */
847
291k
      return NULL;
848
291k
    }
849
6.92k
  xop = SPE2_XOP (insn);
850
6.92k
  seg = SPE2_XOP_TO_SEG (xop);
851
852
  /* Find the first match in the opcode table for this opcode.  */
853
6.92k
  opcode_end = spe2_opcodes + spe2_opcd_indices[seg + 1];
854
6.92k
  for (opcode = spe2_opcodes + spe2_opcd_indices[seg];
855
317k
       opcode < opcode_end;
856
310k
       ++opcode)
857
313k
    {
858
313k
      uint64_t table_opcd = opcode->opcode;
859
313k
      uint64_t table_mask = opcode->mask;
860
313k
      uint64_t insn2;
861
313k
      const ppc_opindex_t *opindex;
862
313k
      const struct powerpc_operand *operand;
863
313k
      int invalid;
864
865
313k
      insn2 = insn;
866
313k
      if ((insn2 & table_mask) != table_opcd
867
3.62k
    || (opcode->deprecated & dialect) != 0)
868
310k
  continue;
869
870
      /* Check validity of operands.  */
871
3.62k
      invalid = 0;
872
14.5k
      for (opindex = opcode->operands; *opindex != 0; ++opindex)
873
10.9k
  {
874
10.9k
    operand = powerpc_operands + *opindex;
875
10.9k
    if (operand->extract)
876
828
      (*operand->extract) (insn, (ppc_cpu_t)0, &invalid);
877
10.9k
  }
878
3.62k
      if (invalid)
879
438
  continue;
880
881
3.19k
      return opcode;
882
3.62k
    }
883
884
3.73k
  return NULL;
885
6.92k
}
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
678k
{
976
678k
  bfd_byte buffer[4];
977
678k
  int status;
978
678k
  uint64_t insn;
979
678k
  const struct powerpc_opcode *opcode;
980
678k
  int insn_length = 4;  /* Assume we have a normal 4-byte instruction.  */
981
982
678k
  status = (*info->read_memory_func) (memaddr, buffer, 4, info);
983
984
  /* The final instruction may be a 2-byte VLE insn.  */
985
678k
  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
678k
  if (status != 0)
994
563
    {
995
563
      (*info->memory_error_func) (status, memaddr, info);
996
563
      return -1;
997
563
    }
998
999
678k
  if (bigendian)
1000
328k
    insn = bfd_getb32 (buffer);
1001
349k
  else
1002
349k
    insn = bfd_getl32 (buffer);
1003
1004
  /* Get the major opcode of the insn.  */
1005
678k
  opcode = NULL;
1006
678k
  if ((dialect & PPC_OPCODE_POWER10) != 0
1007
590k
      && PPC_OP (insn) == 0x1)
1008
14.5k
    {
1009
14.5k
      uint64_t temp_insn, suffix;
1010
14.5k
      status = (*info->read_memory_func) (memaddr + 4, buffer, 4, info);
1011
14.5k
      if (status == 0)
1012
14.5k
  {
1013
14.5k
    if (bigendian)
1014
7.64k
      suffix = bfd_getb32 (buffer);
1015
6.87k
    else
1016
6.87k
      suffix = bfd_getl32 (buffer);
1017
14.5k
    temp_insn = (insn << 32) | suffix;
1018
14.5k
    opcode = lookup_prefix (temp_insn, dialect & ~PPC_OPCODE_ANY);
1019
14.5k
    if (opcode == NULL && (dialect & PPC_OPCODE_ANY) != 0)
1020
13.4k
      opcode = lookup_prefix (temp_insn, dialect);
1021
14.5k
    if (opcode != NULL)
1022
1.18k
      {
1023
1.18k
        insn = temp_insn;
1024
1.18k
        insn_length = 8;
1025
1.18k
        if ((info->flags & WIDE_OUTPUT) != 0)
1026
0
    info->bytes_per_line = 8;
1027
1.18k
      }
1028
14.5k
  }
1029
14.5k
    }
1030
678k
  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
678k
  if (opcode == NULL && insn_length == 4)
1041
676k
    {
1042
676k
      if ((dialect & PPC_OPCODE_LSP) != 0)
1043
0
  opcode = lookup_lsp (insn, dialect);
1044
676k
      if ((dialect & PPC_OPCODE_SPE2) != 0)
1045
64.9k
  opcode = lookup_spe2 (insn, dialect);
1046
676k
      if (opcode == NULL)
1047
675k
  opcode = lookup_powerpc (insn, dialect & ~PPC_OPCODE_ANY);
1048
676k
      if (opcode == NULL && (dialect & PPC_OPCODE_ANY) != 0)
1049
270k
  opcode = lookup_powerpc (insn, dialect);
1050
676k
      if (opcode == NULL && (dialect & PPC_OPCODE_ANY) != 0)
1051
233k
  opcode = lookup_spe2 (insn, dialect);
1052
676k
      if (opcode == NULL && (dialect & PPC_OPCODE_ANY) != 0)
1053
231k
  opcode = lookup_lsp (insn, dialect);
1054
676k
    }
1055
1056
678k
  if (opcode != NULL)
1057
400k
    {
1058
400k
      const ppc_opindex_t *opindex;
1059
400k
      const struct powerpc_operand *operand;
1060
400k
      enum {
1061
400k
  need_comma = 0,
1062
400k
  need_1space = 1,
1063
400k
  need_2spaces = 2,
1064
400k
  need_3spaces = 3,
1065
400k
  need_4spaces = 4,
1066
400k
  need_5spaces = 5,
1067
400k
  need_6spaces = 6,
1068
400k
  need_7spaces = 7,
1069
400k
  need_paren
1070
400k
      } op_separator;
1071
400k
      bool skip_optional;
1072
400k
      bool is_pcrel;
1073
400k
      uint64_t d34;
1074
400k
      int blanks;
1075
1076
400k
      (*info->fprintf_styled_func) (info->stream, dis_style_mnemonic,
1077
400k
            "%s", opcode->name);
1078
      /* gdb fprintf_styled_func doesn't return count printed.  */
1079
400k
      blanks = 8 - strlen (opcode->name);
1080
400k
      if (blanks <= 0)
1081
10.6k
  blanks = 1;
1082
1083
      /* Now extract and print the operands.  */
1084
400k
      op_separator = blanks;
1085
400k
      skip_optional = false;
1086
400k
      is_pcrel = false;
1087
400k
      d34 = 0;
1088
1.66M
      for (opindex = opcode->operands; *opindex != 0; opindex++)
1089
1.26M
  {
1090
1.26M
    int64_t value;
1091
1092
1.26M
    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.26M
    if ((operand->flags & PPC_OPERAND_OPTIONAL) != 0
1098
47.8k
        && (dialect & PPC_OPCODE_RAW) == 0)
1099
47.8k
      {
1100
47.8k
        if (!skip_optional)
1101
47.7k
    skip_optional = skip_optional_operands (opindex, insn,
1102
47.7k
              dialect, &is_pcrel);
1103
47.8k
        if (skip_optional)
1104
6.57k
    continue;
1105
47.8k
      }
1106
1107
1.25M
    value = operand_value_powerpc (operand, insn, dialect);
1108
1109
1.25M
    if (op_separator == need_comma)
1110
719k
      (*info->fprintf_styled_func) (info->stream, dis_style_text, ",");
1111
536k
    else if (op_separator == need_paren)
1112
139k
      (*info->fprintf_styled_func) (info->stream, dis_style_text, "(");
1113
397k
    else
1114
397k
      (*info->fprintf_styled_func) (info->stream, dis_style_text, "%*s",
1115
397k
            op_separator, " ");
1116
1117
    /* Print the operand as directed by the flags.  */
1118
1.25M
    if ((operand->flags & PPC_OPERAND_GPR) != 0
1119
815k
        || ((operand->flags & PPC_OPERAND_GPR_0) != 0 && value != 0))
1120
568k
      (*info->fprintf_styled_func) (info->stream, dis_style_register,
1121
568k
            "r%" PRId64, value);
1122
688k
    else if ((operand->flags & PPC_OPERAND_FPR) != 0)
1123
143k
      (*info->fprintf_styled_func) (info->stream, dis_style_register,
1124
143k
            "f%" PRId64, value);
1125
544k
    else if ((operand->flags & PPC_OPERAND_VR) != 0)
1126
37.8k
      (*info->fprintf_styled_func) (info->stream, dis_style_register,
1127
37.8k
            "v%" PRId64, value);
1128
506k
    else if ((operand->flags & PPC_OPERAND_VSR) != 0)
1129
26.6k
      (*info->fprintf_styled_func) (info->stream, dis_style_register,
1130
26.6k
            "vs%" PRId64, value);
1131
480k
    else if ((operand->flags & PPC_OPERAND_DMR) != 0)
1132
79
      (*info->fprintf_styled_func) (info->stream, dis_style_register,
1133
79
            "dm%" PRId64, value);
1134
480k
    else if ((operand->flags & PPC_OPERAND_ACC) != 0)
1135
34
      (*info->fprintf_styled_func) (info->stream, dis_style_register,
1136
34
            "a%" PRId64, value);
1137
480k
    else if ((operand->flags & PPC_OPERAND_RELATIVE) != 0)
1138
10.5k
      (*info->print_address_func) (memaddr + value, info);
1139
469k
    else if ((operand->flags & PPC_OPERAND_ABSOLUTE) != 0)
1140
20.7k
      (*info->print_address_func) ((bfd_vma) value & 0xffffffff, info);
1141
448k
    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
448k
    else if ((operand->flags & PPC_OPERAND_FCR) != 0)
1145
19
      (*info->fprintf_styled_func) (info->stream, dis_style_register,
1146
19
            "fcr%" PRId64, value);
1147
448k
    else if ((operand->flags & PPC_OPERAND_UDI) != 0)
1148
189
      (*info->fprintf_styled_func) (info->stream, dis_style_register,
1149
189
            "%" PRId64, value);
1150
448k
    else if ((operand->flags & PPC_OPERAND_CR_REG) != 0
1151
17.4k
       && (operand->flags & PPC_OPERAND_CR_BIT) == 0
1152
17.4k
       && (((dialect & PPC_OPCODE_PPC) != 0)
1153
947
           || ((dialect & PPC_OPCODE_VLE) != 0)))
1154
16.5k
      (*info->fprintf_styled_func) (info->stream, dis_style_register,
1155
16.5k
            "cr%" PRId64, value);
1156
432k
    else if ((operand->flags & PPC_OPERAND_CR_BIT) != 0
1157
20.9k
       && (operand->flags & PPC_OPERAND_CR_REG) == 0
1158
20.9k
       && (((dialect & PPC_OPCODE_PPC) != 0)
1159
617
           || ((dialect & PPC_OPCODE_VLE) != 0)))
1160
20.3k
      {
1161
20.3k
        static const char *cbnames[4] = { "lt", "gt", "eq", "so" };
1162
20.3k
        int cr;
1163
20.3k
        int cc;
1164
1165
20.3k
        cr = value >> 2;
1166
20.3k
        cc = value & 3;
1167
20.3k
        if (cr != 0)
1168
4.30k
    {
1169
4.30k
      (*info->fprintf_styled_func) (info->stream, dis_style_text,
1170
4.30k
            "4*");
1171
4.30k
      (*info->fprintf_styled_func) (info->stream,
1172
4.30k
            dis_style_register,
1173
4.30k
            "cr%d", cr);
1174
4.30k
      (*info->fprintf_styled_func) (info->stream, dis_style_text,
1175
4.30k
            "+");
1176
4.30k
    }
1177
1178
20.3k
        (*info->fprintf_styled_func) (info->stream,
1179
20.3k
              dis_style_sub_mnemonic,
1180
20.3k
              "%s", cbnames[cc]);
1181
20.3k
      }
1182
411k
    else
1183
411k
      {
1184
        /* An immediate, but what style?  */
1185
411k
        enum disassembler_style style;
1186
1187
411k
        if ((operand->flags & PPC_OPERAND_PARENS) != 0)
1188
139k
    style = dis_style_address_offset;
1189
272k
        else
1190
272k
    style = dis_style_immediate;
1191
1192
411k
        (*info->fprintf_styled_func) (info->stream, style,
1193
411k
              "%" PRId64, value);
1194
411k
      }
1195
1196
1.25M
    if (operand->shift == 52)
1197
87
      is_pcrel = value != 0;
1198
1.25M
    else if (operand->bitm == UINT64_C (0x3ffffffff))
1199
986
      d34 = value;
1200
1201
1.25M
    if (op_separator == need_paren)
1202
139k
      (*info->fprintf_styled_func) (info->stream, dis_style_text, ")");
1203
1204
1.25M
    op_separator = need_comma;
1205
1.25M
    if ((operand->flags & PPC_OPERAND_PARENS) != 0)
1206
139k
      op_separator = need_paren;
1207
1.25M
  }
1208
1209
400k
      if (is_pcrel)
1210
212
  {
1211
212
    d34 += memaddr;
1212
212
    (*info->fprintf_styled_func) (info->stream,
1213
212
          dis_style_comment_start,
1214
212
          "\t# %" PRIx64, d34);
1215
212
    asymbol *sym = (*info->symbol_at_address_func) (d34, info);
1216
212
    if (sym)
1217
0
      (*info->fprintf_styled_func) (info->stream, dis_style_text,
1218
0
            " <%s>", bfd_asymbol_name (sym));
1219
1220
212
    if (info->private_data != NULL
1221
212
        && 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
212
  }
1233
1234
      /* We have found and printed an instruction.  */
1235
400k
      return insn_length;
1236
400k
    }
1237
1238
  /* We could not find a match.  */
1239
277k
  if (insn_length == 4)
1240
277k
    (*info->fprintf_styled_func) (info->stream,
1241
277k
          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
277k
  (*info->fprintf_styled_func) (info->stream, dis_style_text, " ");
1249
277k
  (*info->fprintf_styled_func) (info->stream, dis_style_immediate, "0x%x",
1250
277k
        (unsigned int) insn);
1251
1252
1253
277k
  return insn_length;
1254
678k
}
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
}