Coverage Report

Created: 2025-07-08 11:15

/src/binutils-gdb/opcodes/ppc-dis.c
Line
Count
Source (jump to first uncovered line)
1
/* ppc-dis.c -- Disassemble PowerPC instructions
2
   Copyright (C) 1994-2025 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
14.2M
{
55
14.2M
  return (struct dis_private *) info->private_data;
56
14.2M
}
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
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
14.2M
{
304
14.2M
  ppc_cpu_t dialect = 0;
305
306
14.2M
  if (info->private_data)
307
14.2M
    dialect = private_data (info)->dialect;
308
309
  /* Disassemble according to the section headers flags for VLE-mode.  */
310
14.2M
  if (dialect & PPC_OPCODE_VLE
311
14.2M
      && info->section != NULL && info->section->owner != NULL
312
14.2M
      && bfd_get_flavour (info->section->owner) == bfd_target_elf_flavour
313
14.2M
      && elf_object_id (info->section->owner) == PPC32_ELF_DATA
314
14.2M
      && (elf_section_flags (info->section) & SHF_PPC_VLE) != 0)
315
0
    return dialect;
316
14.2M
  else
317
14.2M
    return dialect & ~ PPC_OPCODE_VLE;
318
14.2M
}
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
857
{
325
857
  unsigned int i;
326
327
42.9k
  for (i = 0; i < ARRAY_SIZE (ppc_opts); i++)
328
42.9k
    if (disassembler_options_cmp (ppc_opts[i].opt, arg) == 0)
329
857
      {
330
857
  if (ppc_opts[i].sticky)
331
116
    {
332
116
      *sticky |= ppc_opts[i].sticky;
333
116
      if ((ppc_cpu & ~*sticky) != 0)
334
0
        break;
335
116
    }
336
857
  ppc_cpu = ppc_opts[i].cpu;
337
857
  break;
338
857
      }
339
857
  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
857
  if ((ppc_opts[i].sticky & PPC_OPCODE_LSP) != 0)
346
0
    *sticky &= ~(PPC_OPCODE_SPE | PPC_OPCODE_SPE2);
347
857
  else if ((ppc_opts[i].sticky & (PPC_OPCODE_SPE | PPC_OPCODE_SPE2)) != 0)
348
0
    *sticky &= ~PPC_OPCODE_LSP;
349
857
  ppc_cpu |= *sticky;
350
351
857
  return ppc_cpu;
352
857
}
353
354
/* Determine which set of machines to disassemble for.  */
355
356
static void
357
powerpc_init_dialect (struct disassemble_info *info)
358
857
{
359
857
  ppc_cpu_t dialect = 0;
360
857
  ppc_cpu_t sticky = 0;
361
857
  struct dis_private *priv = calloc (1, sizeof (*priv));
362
363
857
  if (priv == NULL)
364
0
    return;
365
366
857
  switch (info->mach)
367
857
    {
368
1
    case bfd_mach_ppc_403:
369
1
    case bfd_mach_ppc_403gc:
370
1
      dialect = ppc_parse_cpu (dialect, &sticky, "403");
371
1
      break;
372
0
    case bfd_mach_ppc_405:
373
0
      dialect = ppc_parse_cpu (dialect, &sticky, "405");
374
0
      break;
375
0
    case bfd_mach_ppc_601:
376
0
      dialect = ppc_parse_cpu (dialect, &sticky, "601");
377
0
      break;
378
0
    case bfd_mach_ppc_750:
379
0
      dialect = ppc_parse_cpu (dialect, &sticky, "750cl");
380
0
      break;
381
1
    case bfd_mach_ppc_a35:
382
2
    case bfd_mach_ppc_rs64ii:
383
3
    case bfd_mach_ppc_rs64iii:
384
3
      dialect = ppc_parse_cpu (dialect, &sticky, "pwr2") | PPC_OPCODE_64;
385
3
      break;
386
1
    case bfd_mach_ppc_e500:
387
1
      dialect = ppc_parse_cpu (dialect, &sticky, "e500");
388
1
      break;
389
0
    case bfd_mach_ppc_e500mc:
390
0
      dialect = ppc_parse_cpu (dialect, &sticky, "e500mc");
391
0
      break;
392
0
    case bfd_mach_ppc_e500mc64:
393
0
      dialect = ppc_parse_cpu (dialect, &sticky, "e500mc64");
394
0
      break;
395
0
    case bfd_mach_ppc_e5500:
396
0
      dialect = ppc_parse_cpu (dialect, &sticky, "e5500");
397
0
      break;
398
4
    case bfd_mach_ppc_e6500:
399
4
      dialect = ppc_parse_cpu (dialect, &sticky, "e6500");
400
4
      break;
401
1
    case bfd_mach_ppc_titan:
402
1
      dialect = ppc_parse_cpu (dialect, &sticky, "titan");
403
1
      break;
404
116
    case bfd_mach_ppc_vle:
405
116
      dialect = ppc_parse_cpu (dialect, &sticky, "vle");
406
116
      break;
407
731
    default:
408
731
      if (info->arch == bfd_arch_powerpc)
409
676
  dialect = ppc_parse_cpu (dialect, &sticky, "power11") | PPC_OPCODE_ANY;
410
55
      else
411
55
  dialect = ppc_parse_cpu (dialect, &sticky, "pwr");
412
731
      break;
413
857
    }
414
415
857
  const char *opt;
416
857
  FOR_EACH_DISASSEMBLER_OPTION (opt, info->disassembler_options)
417
0
    {
418
0
      ppc_cpu_t new_cpu = 0;
419
420
0
      if (disassembler_options_cmp (opt, "32") == 0)
421
0
  dialect &= ~(ppc_cpu_t) PPC_OPCODE_64;
422
0
      else if (disassembler_options_cmp (opt, "64") == 0)
423
0
  dialect |= PPC_OPCODE_64;
424
0
      else if ((new_cpu = ppc_parse_cpu (dialect, &sticky, opt)) != 0)
425
0
  dialect = new_cpu;
426
0
      else
427
  /* xgettext: c-format */
428
0
  opcodes_error_handler (_("warning: ignoring unknown -M%s option"), opt);
429
0
    }
430
431
857
  info->private_data = priv;
432
857
  private_data (info)->dialect = dialect;
433
857
}
434
435
989
#define PPC_OPCD_SEGS (1 + PPC_OP (-1))
436
static unsigned short powerpc_opcd_indices[PPC_OPCD_SEGS + 1];
437
68
#define PREFIX_OPCD_SEGS (1 + PPC_PREFIX_SEG (-1))
438
static unsigned short prefix_opcd_indices[PREFIX_OPCD_SEGS + 1];
439
68
#define VLE_OPCD_SEGS (1 + VLE_OP_TO_SEG (VLE_OP (-1, 0xffff)))
440
static unsigned short vle_opcd_indices[VLE_OPCD_SEGS + 1];
441
68
#define LSP_OPCD_SEGS (1 + LSP_OP_TO_SEG (-1))
442
static unsigned short lsp_opcd_indices[LSP_OPCD_SEGS + 1];
443
36
#define SPE2_OPCD_SEGS (1 + SPE2_XOP_TO_SEG (SPE2_XOP (-1)))
444
static unsigned short spe2_opcd_indices[SPE2_OPCD_SEGS + 1];
445
446
static bool
447
ppc_symbol_is_valid (asymbol *sym,
448
         struct disassemble_info *info ATTRIBUTE_UNUSED)
449
177k
{
450
177k
  elf_symbol_type * est;
451
452
177k
  if (sym == NULL)
453
0
    return false;
454
455
177k
  est = elf_symbol_from (sym);
456
457
  /* Ignore ELF hidden, local, no-type symbols.
458
     These are generated by annobin.  */
459
177k
  if (est != NULL
460
177k
      && ELF_ST_VISIBILITY (est->internal_elf_sym.st_other) == STV_HIDDEN
461
177k
      && ELF_ST_BIND (est->internal_elf_sym.st_info) == STB_LOCAL
462
177k
      && ELF_ST_TYPE (est->internal_elf_sym.st_info) == STT_NOTYPE)
463
0
    return false;
464
465
177k
  return true;
466
177k
}
467
468
/* Calculate opcode table indices to speed up disassembly,
469
   and init dialect.  */
470
471
void
472
disassemble_init_powerpc (struct disassemble_info *info)
473
857
{
474
857
  info->symbol_is_valid = ppc_symbol_is_valid;
475
476
857
  if (powerpc_opcd_indices[PPC_OPCD_SEGS] == 0)
477
2
    {
478
2
      unsigned seg, idx, op;
479
480
      /* PPC opcodes */
481
132
      for (seg = 0, idx = 0; seg <= PPC_OPCD_SEGS; seg++)
482
130
  {
483
130
    powerpc_opcd_indices[seg] = idx;
484
8.20k
    for (; idx < powerpc_num_opcodes; idx++)
485
8.19k
      if (seg < PPC_OP (powerpc_opcodes[idx].opcode))
486
126
        break;
487
130
  }
488
489
      /* 64-bit prefix opcodes */
490
68
      for (seg = 0, idx = 0; seg <= PREFIX_OPCD_SEGS; seg++)
491
66
  {
492
66
    prefix_opcd_indices[seg] = idx;
493
290
    for (; idx < prefix_num_opcodes; idx++)
494
286
      if (seg < PPC_PREFIX_SEG (prefix_opcodes[idx].opcode))
495
62
        break;
496
66
  }
497
498
      /* VLE opcodes */
499
68
      for (seg = 0, idx = 0; seg <= VLE_OPCD_SEGS; seg++)
500
66
  {
501
66
    vle_opcd_indices[seg] = idx;
502
512
    for (; idx < vle_num_opcodes; idx++)
503
504
      {
504
504
        op = VLE_OP (vle_opcodes[idx].opcode, vle_opcodes[idx].mask);
505
504
        if (seg < VLE_OP_TO_SEG (op))
506
58
    break;
507
504
      }
508
66
  }
509
510
      /* LSP opcodes */
511
68
      for (seg = 0, idx = 0; seg <= LSP_OPCD_SEGS; seg++)
512
66
  {
513
66
    lsp_opcd_indices[seg] = idx;
514
1.42k
    for (; idx < lsp_num_opcodes; idx++)
515
1.41k
      if (seg < LSP_OP_TO_SEG (lsp_opcodes[idx].opcode))
516
54
        break;
517
66
  }
518
519
      /* SPE2 opcodes */
520
36
      for (seg = 0, idx = 0; seg <= SPE2_OPCD_SEGS; seg++)
521
34
  {
522
34
    spe2_opcd_indices[seg] = idx;
523
1.61k
    for (; idx < spe2_num_opcodes; idx++)
524
1.60k
      {
525
1.60k
        op = SPE2_XOP (spe2_opcodes[idx].opcode);
526
1.60k
        if (seg < SPE2_XOP_TO_SEG (op))
527
24
    break;
528
1.60k
      }
529
34
  }
530
2
    }
531
532
857
  powerpc_init_dialect (info);
533
857
  if (info->private_data != NULL)
534
857
    {
535
857
      private_data (info)->special[0].name = ".got";
536
857
      private_data (info)->special[1].name = ".plt";
537
857
    }
538
857
}
539
540
void
541
disassemble_free_powerpc (struct disassemble_info *info)
542
802
{
543
802
  if (info->private_data != NULL)
544
802
    {
545
802
      free (private_data (info)->special[0].buf);
546
802
      free (private_data (info)->special[1].buf);
547
802
    }
548
802
}
549
550
/* Print a big endian PowerPC instruction.  */
551
552
int
553
print_insn_big_powerpc (bfd_vma memaddr, struct disassemble_info *info)
554
13.8M
{
555
13.8M
  return print_insn_powerpc (memaddr, info, 1, get_powerpc_dialect (info));
556
13.8M
}
557
558
/* Print a little endian PowerPC instruction.  */
559
560
int
561
print_insn_little_powerpc (bfd_vma memaddr, struct disassemble_info *info)
562
361k
{
563
361k
  return print_insn_powerpc (memaddr, info, 0, get_powerpc_dialect (info));
564
361k
}
565
566
/* Extract the operand value from the PowerPC or POWER instruction.  */
567
568
static int64_t
569
operand_value_powerpc (const struct powerpc_operand *operand,
570
           uint64_t insn, ppc_cpu_t dialect)
571
28.0M
{
572
28.0M
  int64_t value;
573
28.0M
  int invalid = 0;
574
  /* Extract the value from the instruction.  */
575
28.0M
  if (operand->extract)
576
1.98M
    value = (*operand->extract) (insn, dialect, &invalid);
577
26.0M
  else
578
26.0M
    {
579
26.0M
      if (operand->shift >= 0)
580
26.0M
  value = (insn >> operand->shift) & operand->bitm;
581
0
      else
582
0
  value = (insn << -operand->shift) & operand->bitm;
583
26.0M
      if ((operand->flags & PPC_OPERAND_SIGNED) != 0)
584
6.46M
  {
585
    /* BITM is always some number of zeros followed by some
586
       number of ones, followed by some number of zeros.  */
587
6.46M
    uint64_t top = operand->bitm;
588
    /* top & -top gives the rightmost 1 bit, so this
589
       fills in any trailing zeros.  */
590
6.46M
    top |= (top & -top) - 1;
591
6.46M
    top &= ~(top >> 1);
592
6.46M
    value = (value ^ top) - top;
593
6.46M
  }
594
26.0M
    }
595
596
28.0M
  if ((operand->flags & PPC_OPERAND_NONZERO) != 0)
597
0
    ++value;
598
599
28.0M
  return value;
600
28.0M
}
601
602
/* Determine whether the optional operand(s) should be printed.  */
603
604
static bool
605
skip_optional_operands (const ppc_opindex_t *opindex,
606
      uint64_t insn, ppc_cpu_t dialect, bool *is_pcrel)
607
1.22M
{
608
1.22M
  const struct powerpc_operand *operand;
609
1.22M
  int num_optional;
610
611
1.68M
  for (num_optional = 0; *opindex != 0; opindex++)
612
1.46M
    {
613
1.46M
      operand = &powerpc_operands[*opindex];
614
1.46M
      if ((operand->flags & PPC_OPERAND_NEXT) != 0)
615
313k
  return false;
616
1.14M
      if ((operand->flags & PPC_OPERAND_OPTIONAL) != 0)
617
916k
  {
618
916k
    int64_t value = operand_value_powerpc (operand, insn, dialect);
619
620
916k
    if (operand->shift == 52)
621
6.89k
      *is_pcrel = value != 0;
622
623
    /* Negative count is used as a flag to extract function.  */
624
916k
    --num_optional;
625
916k
    if (value != ppc_optional_operand_value (operand, insn, dialect,
626
916k
               num_optional))
627
689k
      return false;
628
916k
  }
629
1.14M
    }
630
631
223k
  return true;
632
1.22M
}
633
634
/* Find a match for INSN in the opcode table, given machine DIALECT.  */
635
636
static const struct powerpc_opcode *
637
lookup_powerpc (uint64_t insn, ppc_cpu_t dialect)
638
18.7M
{
639
18.7M
  const struct powerpc_opcode *opcode, *opcode_end;
640
18.7M
  unsigned long op;
641
642
  /* Get the major opcode of the instruction.  */
643
18.7M
  op = PPC_OP (insn);
644
645
  /* Find the first match in the opcode table for this major opcode.  */
646
18.7M
  opcode_end = powerpc_opcodes + powerpc_opcd_indices[op + 1];
647
18.7M
  for (opcode = powerpc_opcodes + powerpc_opcd_indices[op];
648
958M
       opcode < opcode_end;
649
940M
       ++opcode)
650
949M
    {
651
949M
      const ppc_opindex_t *opindex;
652
949M
      const struct powerpc_operand *operand;
653
949M
      int invalid;
654
655
949M
      if ((insn & opcode->mask) != opcode->opcode
656
949M
    || ((dialect & PPC_OPCODE_ANY) == 0
657
12.1M
        && ((opcode->flags & dialect) == 0
658
11.4M
      || (opcode->deprecated & dialect) != 0))
659
949M
    || (opcode->deprecated & dialect & PPC_OPCODE_RAW) != 0)
660
938M
  continue;
661
662
      /* Check validity of operands.  */
663
11.2M
      invalid = 0;
664
42.0M
      for (opindex = opcode->operands; *opindex != 0; opindex++)
665
30.8M
  {
666
30.8M
    operand = powerpc_operands + *opindex;
667
30.8M
    if (operand->extract)
668
3.53M
      (*operand->extract) (insn, dialect, &invalid);
669
30.8M
  }
670
11.2M
      if (invalid)
671
1.41M
  continue;
672
673
9.79M
      return opcode;
674
11.2M
    }
675
676
9.00M
  return NULL;
677
18.7M
}
678
679
/* Find a match for INSN in the PREFIX opcode table.  */
680
681
static const struct powerpc_opcode *
682
lookup_prefix (uint64_t insn, ppc_cpu_t dialect)
683
707k
{
684
707k
  const struct powerpc_opcode *opcode, *opcode_end;
685
707k
  unsigned long seg;
686
687
  /* Get the opcode segment of the instruction.  */
688
707k
  seg = PPC_PREFIX_SEG (insn);
689
690
  /* Find the first match in the opcode table for this major opcode.  */
691
707k
  opcode_end = prefix_opcodes + prefix_opcd_indices[seg + 1];
692
707k
  for (opcode = prefix_opcodes + prefix_opcd_indices[seg];
693
2.29M
       opcode < opcode_end;
694
1.58M
       ++opcode)
695
1.58M
    {
696
1.58M
      const ppc_opindex_t *opindex;
697
1.58M
      const struct powerpc_operand *operand;
698
1.58M
      int invalid;
699
700
1.58M
      if ((insn & opcode->mask) != opcode->opcode
701
1.58M
    || ((dialect & PPC_OPCODE_ANY) == 0
702
7.40k
        && (opcode->flags & dialect) == 0)
703
1.58M
    || (opcode->deprecated & dialect) != 0)
704
1.58M
  continue;
705
706
      /* Check validity of operands.  */
707
7.27k
      invalid = 0;
708
30.1k
      for (opindex = opcode->operands; *opindex != 0; opindex++)
709
22.8k
  {
710
22.8k
    operand = powerpc_operands + *opindex;
711
22.8k
    if (operand->extract)
712
12.6k
      (*operand->extract) (insn, dialect, &invalid);
713
22.8k
  }
714
7.27k
      if (invalid)
715
415
  continue;
716
717
6.85k
      return opcode;
718
7.27k
    }
719
720
700k
  return NULL;
721
707k
}
722
723
/* Find a match for INSN in the VLE opcode table.  */
724
725
static const struct powerpc_opcode *
726
lookup_vle (uint64_t insn, ppc_cpu_t dialect)
727
0
{
728
0
  const struct powerpc_opcode *opcode;
729
0
  const struct powerpc_opcode *opcode_end;
730
0
  unsigned op, seg;
731
732
0
  op = PPC_OP (insn);
733
0
  if (op >= 0x20 && op <= 0x37)
734
0
    {
735
      /* This insn has a 4-bit opcode.  */
736
0
      op &= 0x3c;
737
0
    }
738
0
  seg = VLE_OP_TO_SEG (op);
739
740
  /* Find the first match in the opcode table for this major opcode.  */
741
0
  opcode_end = vle_opcodes + vle_opcd_indices[seg + 1];
742
0
  for (opcode = vle_opcodes + vle_opcd_indices[seg];
743
0
       opcode < opcode_end;
744
0
       ++opcode)
745
0
    {
746
0
      uint64_t table_opcd = opcode->opcode;
747
0
      uint64_t table_mask = opcode->mask;
748
0
      bool table_op_is_short = PPC_OP_SE_VLE(table_mask);
749
0
      uint64_t insn2;
750
0
      const ppc_opindex_t *opindex;
751
0
      const struct powerpc_operand *operand;
752
0
      int invalid;
753
754
0
      insn2 = insn;
755
0
      if (table_op_is_short)
756
0
  insn2 >>= 16;
757
0
      if ((insn2 & table_mask) != table_opcd
758
0
    || (opcode->deprecated & dialect) != 0)
759
0
  continue;
760
761
      /* Check validity of operands.  */
762
0
      invalid = 0;
763
0
      for (opindex = opcode->operands; *opindex != 0; ++opindex)
764
0
  {
765
0
    operand = powerpc_operands + *opindex;
766
0
    if (operand->extract)
767
0
      (*operand->extract) (insn, (ppc_cpu_t)0, &invalid);
768
0
  }
769
0
      if (invalid)
770
0
  continue;
771
772
0
      return opcode;
773
0
    }
774
775
0
  return NULL;
776
0
}
777
778
/* Find a match for INSN in the LSP opcode table.  */
779
780
static const struct powerpc_opcode *
781
lookup_lsp (uint64_t insn, ppc_cpu_t dialect)
782
4.20M
{
783
4.20M
  const struct powerpc_opcode *opcode, *opcode_end;
784
4.20M
  unsigned op, seg;
785
786
4.20M
  op = PPC_OP (insn);
787
4.20M
  if (op != 0x4)
788
4.19M
    return NULL;
789
790
11.1k
  seg = LSP_OP_TO_SEG (insn);
791
792
  /* Find the first match in the opcode table for this opcode.  */
793
11.1k
  opcode_end = lsp_opcodes + lsp_opcd_indices[seg + 1];
794
11.1k
  for (opcode = lsp_opcodes + lsp_opcd_indices[seg];
795
91.8k
       opcode < opcode_end;
796
80.7k
       ++opcode)
797
81.7k
    {
798
81.7k
      const ppc_opindex_t *opindex;
799
81.7k
      const struct powerpc_operand *operand;
800
81.7k
      int invalid;
801
802
81.7k
      if ((insn & opcode->mask) != opcode->opcode
803
81.7k
    || (opcode->deprecated & dialect) != 0)
804
80.3k
  continue;
805
806
      /* Check validity of operands.  */
807
1.43k
      invalid = 0;
808
5.72k
      for (opindex = opcode->operands; *opindex != 0; ++opindex)
809
4.29k
  {
810
4.29k
    operand = powerpc_operands + *opindex;
811
4.29k
    if (operand->extract)
812
877
      (*operand->extract) (insn, (ppc_cpu_t) 0, &invalid);
813
4.29k
  }
814
1.43k
      if (invalid)
815
348
  continue;
816
817
1.08k
      return opcode;
818
1.43k
    }
819
820
10.0k
  return NULL;
821
11.1k
}
822
823
/* Find a match for INSN in the SPE2 opcode table.  */
824
825
static const struct powerpc_opcode *
826
lookup_spe2 (uint64_t insn, ppc_cpu_t dialect)
827
4.27M
{
828
4.27M
  const struct powerpc_opcode *opcode, *opcode_end;
829
4.27M
  unsigned op, xop, seg;
830
831
4.27M
  op = PPC_OP (insn);
832
4.27M
  if (op != 0x4)
833
4.25M
    {
834
      /* This is not SPE2 insn.
835
       * All SPE2 instructions have OP=4 and differs by XOP  */
836
4.25M
      return NULL;
837
4.25M
    }
838
18.7k
  xop = SPE2_XOP (insn);
839
18.7k
  seg = SPE2_XOP_TO_SEG (xop);
840
841
  /* Find the first match in the opcode table for this opcode.  */
842
18.7k
  opcode_end = spe2_opcodes + spe2_opcd_indices[seg + 1];
843
18.7k
  for (opcode = spe2_opcodes + spe2_opcd_indices[seg];
844
537k
       opcode < opcode_end;
845
519k
       ++opcode)
846
525k
    {
847
525k
      uint64_t table_opcd = opcode->opcode;
848
525k
      uint64_t table_mask = opcode->mask;
849
525k
      uint64_t insn2;
850
525k
      const ppc_opindex_t *opindex;
851
525k
      const struct powerpc_operand *operand;
852
525k
      int invalid;
853
854
525k
      insn2 = insn;
855
525k
      if ((insn2 & table_mask) != table_opcd
856
525k
    || (opcode->deprecated & dialect) != 0)
857
518k
  continue;
858
859
      /* Check validity of operands.  */
860
6.83k
      invalid = 0;
861
27.3k
      for (opindex = opcode->operands; *opindex != 0; ++opindex)
862
20.5k
  {
863
20.5k
    operand = powerpc_operands + *opindex;
864
20.5k
    if (operand->extract)
865
1.05k
      (*operand->extract) (insn, (ppc_cpu_t)0, &invalid);
866
20.5k
  }
867
6.83k
      if (invalid)
868
449
  continue;
869
870
6.38k
      return opcode;
871
6.83k
    }
872
873
12.3k
  return NULL;
874
18.7k
}
875
876
static arelent *
877
bsearch_reloc (arelent **lo, arelent **hi, bfd_vma vma)
878
0
{
879
0
  while (lo < hi)
880
0
    {
881
0
      arelent **mid = lo + (hi - lo) / 2;
882
0
      arelent *rel = *mid;
883
884
0
      if (vma < rel->address)
885
0
  hi = mid;
886
0
      else if (vma > rel->address)
887
0
  lo = mid + 1;
888
0
      else
889
0
  return rel;
890
0
    }
891
0
  return NULL;
892
0
}
893
894
static bool
895
print_got_plt (struct sec_buf *sb, uint64_t vma, struct disassemble_info *info)
896
0
{
897
0
  if (sb->name != NULL)
898
0
    {
899
0
      asection *s = sb->sec;
900
0
      if (s == NULL)
901
0
  {
902
0
    s = bfd_get_section_by_name (info->section->owner, sb->name);
903
0
    sb->sec = s;
904
0
    if (s == NULL)
905
0
      sb->name = NULL;
906
0
  }
907
0
      if (s != NULL
908
0
    && vma >= s->vma
909
0
    && vma < s->vma + s->size)
910
0
  {
911
0
    asymbol *sym = NULL;
912
0
    uint64_t ent = 0;
913
0
    if (info->dynrelcount > 0)
914
0
      {
915
0
        arelent **lo = info->dynrelbuf;
916
0
        arelent **hi = lo + info->dynrelcount;
917
0
        arelent *rel = bsearch_reloc (lo, hi, vma);
918
0
        if (rel != NULL && rel->sym_ptr_ptr != NULL)
919
0
    sym = *rel->sym_ptr_ptr;
920
0
      }
921
0
    if (sym == NULL && (s->flags & SEC_HAS_CONTENTS) != 0)
922
0
      {
923
0
        if (sb->buf == NULL
924
0
      && !bfd_malloc_and_get_section (s->owner, s, &sb->buf))
925
0
    sb->name = NULL;
926
0
        if (sb->buf != NULL)
927
0
    {
928
0
      ent = bfd_get_64 (s->owner, sb->buf + (vma - s->vma));
929
0
      if (ent != 0)
930
0
        sym = (*info->symbol_at_address_func) (ent, info);
931
0
    }
932
0
      }
933
0
    (*info->fprintf_styled_func) (info->stream, dis_style_text, " [");
934
0
    if (sym != NULL)
935
0
      {
936
0
        (*info->fprintf_styled_func) (info->stream, dis_style_symbol,
937
0
              "%s", bfd_asymbol_name (sym));
938
0
        (*info->fprintf_styled_func) (info->stream, dis_style_text, "@");
939
0
        (*info->fprintf_styled_func) (info->stream, dis_style_symbol,
940
0
              "%s", sb->name + 1);
941
0
      }
942
0
    else
943
0
      {
944
0
        (*info->fprintf_styled_func) (info->stream, dis_style_address,
945
0
              "%" PRIx64, ent);
946
0
        (*info->fprintf_styled_func) (info->stream, dis_style_text, "@");
947
0
        (*info->fprintf_styled_func) (info->stream, dis_style_symbol,
948
0
              "%s", sb->name + 1);
949
0
      }
950
0
    (*info->fprintf_styled_func) (info->stream, dis_style_text, "]");
951
0
    return true;
952
0
  }
953
0
    }
954
0
  return false;
955
0
}
956
957
/* Print a PowerPC or POWER instruction.  */
958
959
static int
960
print_insn_powerpc (bfd_vma memaddr,
961
        struct disassemble_info *info,
962
        int bigendian,
963
        ppc_cpu_t dialect)
964
14.2M
{
965
14.2M
  bfd_byte buffer[4];
966
14.2M
  int status;
967
14.2M
  uint64_t insn;
968
14.2M
  const struct powerpc_opcode *opcode;
969
14.2M
  int insn_length = 4;  /* Assume we have a normal 4-byte instruction.  */
970
971
14.2M
  status = (*info->read_memory_func) (memaddr, buffer, 4, info);
972
973
  /* The final instruction may be a 2-byte VLE insn.  */
974
14.2M
  if (status != 0 && (dialect & PPC_OPCODE_VLE) != 0)
975
0
    {
976
      /* Clear buffer so unused bytes will not have garbage in them.  */
977
0
      buffer[2] = buffer[3] = 0;
978
0
      status = (*info->read_memory_func) (memaddr, buffer, 2, info);
979
0
      insn_length = 2;
980
0
    }
981
982
14.2M
  if (status != 0)
983
610
    {
984
610
      (*info->memory_error_func) (status, memaddr, info);
985
610
      return -1;
986
610
    }
987
988
14.2M
  if (bigendian)
989
13.8M
    insn = bfd_getb32 (buffer);
990
360k
  else
991
360k
    insn = bfd_getl32 (buffer);
992
993
  /* Get the major opcode of the insn.  */
994
14.2M
  opcode = NULL;
995
14.2M
  if ((dialect & PPC_OPCODE_POWER10) != 0
996
14.2M
      && PPC_OP (insn) == 0x1)
997
357k
    {
998
357k
      uint64_t temp_insn, suffix;
999
357k
      status = (*info->read_memory_func) (memaddr + 4, buffer, 4, info);
1000
357k
      if (status == 0)
1001
357k
  {
1002
357k
    if (bigendian)
1003
345k
      suffix = bfd_getb32 (buffer);
1004
11.3k
    else
1005
11.3k
      suffix = bfd_getl32 (buffer);
1006
357k
    temp_insn = (insn << 32) | suffix;
1007
357k
    opcode = lookup_prefix (temp_insn, dialect & ~PPC_OPCODE_ANY);
1008
357k
    if (opcode == NULL && (dialect & PPC_OPCODE_ANY) != 0)
1009
350k
      opcode = lookup_prefix (temp_insn, dialect);
1010
357k
    if (opcode != NULL)
1011
6.85k
      {
1012
6.85k
        insn = temp_insn;
1013
6.85k
        insn_length = 8;
1014
6.85k
        if ((info->flags & WIDE_OUTPUT) != 0)
1015
0
    info->bytes_per_line = 8;
1016
6.85k
      }
1017
357k
  }
1018
357k
    }
1019
14.2M
  if (opcode == NULL && (dialect & PPC_OPCODE_VLE) != 0)
1020
0
    {
1021
0
      opcode = lookup_vle (insn, dialect);
1022
0
      if (opcode != NULL && PPC_OP_SE_VLE (opcode->mask))
1023
0
  {
1024
    /* The operands will be fetched out of the 16-bit instruction.  */
1025
0
    insn >>= 16;
1026
0
    insn_length = 2;
1027
0
  }
1028
0
    }
1029
14.2M
  if (opcode == NULL && insn_length == 4)
1030
14.2M
    {
1031
14.2M
      if ((dialect & PPC_OPCODE_LSP) != 0)
1032
0
  opcode = lookup_lsp (insn, dialect);
1033
14.2M
      if ((dialect & PPC_OPCODE_SPE2) != 0)
1034
63.5k
  opcode = lookup_spe2 (insn, dialect);
1035
14.2M
      if (opcode == NULL)
1036
14.2M
  opcode = lookup_powerpc (insn, dialect & ~PPC_OPCODE_ANY);
1037
14.2M
      if (opcode == NULL && (dialect & PPC_OPCODE_ANY) != 0)
1038
4.58M
  opcode = lookup_powerpc (insn, dialect);
1039
14.2M
      if (opcode == NULL && (dialect & PPC_OPCODE_ANY) != 0)
1040
4.20M
  opcode = lookup_spe2 (insn, dialect);
1041
14.2M
      if (opcode == NULL && (dialect & PPC_OPCODE_ANY) != 0)
1042
4.20M
  opcode = lookup_lsp (insn, dialect);
1043
14.2M
    }
1044
1045
14.2M
  if (opcode != NULL)
1046
9.80M
    {
1047
9.80M
      const ppc_opindex_t *opindex;
1048
9.80M
      const struct powerpc_operand *operand;
1049
9.80M
      enum {
1050
9.80M
  need_comma = 0,
1051
9.80M
  need_1space = 1,
1052
9.80M
  need_2spaces = 2,
1053
9.80M
  need_3spaces = 3,
1054
9.80M
  need_4spaces = 4,
1055
9.80M
  need_5spaces = 5,
1056
9.80M
  need_6spaces = 6,
1057
9.80M
  need_7spaces = 7,
1058
9.80M
  need_paren
1059
9.80M
      } op_separator;
1060
9.80M
      bool skip_optional;
1061
9.80M
      bool is_pcrel;
1062
9.80M
      uint64_t d34;
1063
9.80M
      int blanks;
1064
1065
9.80M
      (*info->fprintf_styled_func) (info->stream, dis_style_mnemonic,
1066
9.80M
            "%s", opcode->name);
1067
      /* gdb fprintf_styled_func doesn't return count printed.  */
1068
9.80M
      blanks = 8 - strlen (opcode->name);
1069
9.80M
      if (blanks <= 0)
1070
76.1k
  blanks = 1;
1071
1072
      /* Now extract and print the operands.  */
1073
9.80M
      op_separator = blanks;
1074
9.80M
      skip_optional = false;
1075
9.80M
      is_pcrel = false;
1076
9.80M
      d34 = 0;
1077
37.1M
      for (opindex = opcode->operands; *opindex != 0; opindex++)
1078
27.3M
  {
1079
27.3M
    int64_t value;
1080
1081
27.3M
    operand = powerpc_operands + *opindex;
1082
1083
    /* If all of the optional operands past this one have their
1084
       default value, then don't print any of them.  Except in
1085
       raw mode, print them all.  */
1086
27.3M
    if ((operand->flags & PPC_OPERAND_OPTIONAL) != 0
1087
27.3M
        && (dialect & PPC_OPCODE_RAW) == 0)
1088
1.22M
      {
1089
1.22M
        if (!skip_optional)
1090
1.22M
    skip_optional = skip_optional_operands (opindex, insn,
1091
1.22M
              dialect, &is_pcrel);
1092
1.22M
        if (skip_optional)
1093
225k
    continue;
1094
1.22M
      }
1095
1096
27.1M
    value = operand_value_powerpc (operand, insn, dialect);
1097
1098
27.1M
    if (op_separator == need_comma)
1099
14.6M
      (*info->fprintf_styled_func) (info->stream, dis_style_text, ",");
1100
12.5M
    else if (op_separator == need_paren)
1101
2.81M
      (*info->fprintf_styled_func) (info->stream, dis_style_text, "(");
1102
9.70M
    else
1103
9.70M
      (*info->fprintf_styled_func) (info->stream, dis_style_text, "%*s",
1104
9.70M
            op_separator, " ");
1105
1106
    /* Print the operand as directed by the flags.  */
1107
27.1M
    if ((operand->flags & PPC_OPERAND_GPR) != 0
1108
27.1M
        || ((operand->flags & PPC_OPERAND_GPR_0) != 0 && value != 0))
1109
14.3M
      (*info->fprintf_styled_func) (info->stream, dis_style_register,
1110
14.3M
            "r%" PRId64, value);
1111
12.7M
    else if ((operand->flags & PPC_OPERAND_FPR) != 0)
1112
1.10M
      (*info->fprintf_styled_func) (info->stream, dis_style_register,
1113
1.10M
            "f%" PRId64, value);
1114
11.6M
    else if ((operand->flags & PPC_OPERAND_VR) != 0)
1115
396k
      (*info->fprintf_styled_func) (info->stream, dis_style_register,
1116
396k
            "v%" PRId64, value);
1117
11.2M
    else if ((operand->flags & PPC_OPERAND_VSR) != 0)
1118
297k
      (*info->fprintf_styled_func) (info->stream, dis_style_register,
1119
297k
            "vs%" PRId64, value);
1120
10.9M
    else if ((operand->flags & PPC_OPERAND_DMR) != 0)
1121
280
      (*info->fprintf_styled_func) (info->stream, dis_style_register,
1122
280
            "dm%" PRId64, value);
1123
10.9M
    else if ((operand->flags & PPC_OPERAND_ACC) != 0)
1124
345
      (*info->fprintf_styled_func) (info->stream, dis_style_register,
1125
345
            "a%" PRId64, value);
1126
10.9M
    else if ((operand->flags & PPC_OPERAND_RELATIVE) != 0)
1127
1.08M
      (*info->print_address_func) (memaddr + value, info);
1128
9.90M
    else if ((operand->flags & PPC_OPERAND_ABSOLUTE) != 0)
1129
96.2k
      (*info->print_address_func) ((bfd_vma) value & 0xffffffff, info);
1130
9.80M
    else if ((operand->flags & PPC_OPERAND_FSL) != 0)
1131
0
      (*info->fprintf_styled_func) (info->stream, dis_style_register,
1132
0
            "fsl%" PRId64, value);
1133
9.80M
    else if ((operand->flags & PPC_OPERAND_FCR) != 0)
1134
170
      (*info->fprintf_styled_func) (info->stream, dis_style_register,
1135
170
            "fcr%" PRId64, value);
1136
9.80M
    else if ((operand->flags & PPC_OPERAND_UDI) != 0)
1137
1.97k
      (*info->fprintf_styled_func) (info->stream, dis_style_register,
1138
1.97k
            "%" PRId64, value);
1139
9.80M
    else if ((operand->flags & PPC_OPERAND_CR_REG) != 0
1140
9.80M
       && (operand->flags & PPC_OPERAND_CR_BIT) == 0
1141
9.80M
       && (((dialect & PPC_OPCODE_PPC) != 0)
1142
726k
           || ((dialect & PPC_OPCODE_VLE) != 0)))
1143
716k
      (*info->fprintf_styled_func) (info->stream, dis_style_register,
1144
716k
            "cr%" PRId64, value);
1145
9.09M
    else if ((operand->flags & PPC_OPERAND_CR_BIT) != 0
1146
9.09M
       && (operand->flags & PPC_OPERAND_CR_REG) == 0
1147
9.09M
       && (((dialect & PPC_OPCODE_PPC) != 0)
1148
133k
           || ((dialect & PPC_OPCODE_VLE) != 0)))
1149
131k
      {
1150
131k
        static const char *cbnames[4] = { "lt", "gt", "eq", "so" };
1151
131k
        int cr;
1152
131k
        int cc;
1153
1154
131k
        cr = value >> 2;
1155
131k
        cc = value & 3;
1156
131k
        if (cr != 0)
1157
76.0k
    {
1158
76.0k
      (*info->fprintf_styled_func) (info->stream, dis_style_text,
1159
76.0k
            "4*");
1160
76.0k
      (*info->fprintf_styled_func) (info->stream,
1161
76.0k
            dis_style_register,
1162
76.0k
            "cr%d", cr);
1163
76.0k
      (*info->fprintf_styled_func) (info->stream, dis_style_text,
1164
76.0k
            "+");
1165
76.0k
    }
1166
1167
131k
        (*info->fprintf_styled_func) (info->stream,
1168
131k
              dis_style_sub_mnemonic,
1169
131k
              "%s", cbnames[cc]);
1170
131k
      }
1171
8.95M
    else
1172
8.95M
      {
1173
        /* An immediate, but what style?  */
1174
8.95M
        enum disassembler_style style;
1175
1176
8.95M
        if ((operand->flags & PPC_OPERAND_PARENS) != 0)
1177
2.81M
    style = dis_style_address_offset;
1178
6.14M
        else
1179
6.14M
    style = dis_style_immediate;
1180
1181
8.95M
        (*info->fprintf_styled_func) (info->stream, style,
1182
8.95M
              "%" PRId64, value);
1183
8.95M
      }
1184
1185
27.1M
    if (operand->shift == 52)
1186
4
      is_pcrel = value != 0;
1187
27.1M
    else if (operand->bitm == UINT64_C (0x3ffffffff))
1188
5.12k
      d34 = value;
1189
1190
27.1M
    if (op_separator == need_paren)
1191
2.81M
      (*info->fprintf_styled_func) (info->stream, dis_style_text, ")");
1192
1193
27.1M
    op_separator = need_comma;
1194
27.1M
    if ((operand->flags & PPC_OPERAND_PARENS) != 0)
1195
2.81M
      op_separator = need_paren;
1196
27.1M
  }
1197
1198
9.80M
      if (is_pcrel)
1199
62
  {
1200
62
    d34 += memaddr;
1201
62
    (*info->fprintf_styled_func) (info->stream,
1202
62
          dis_style_comment_start,
1203
62
          "\t# %" PRIx64, d34);
1204
62
    asymbol *sym = (*info->symbol_at_address_func) (d34, info);
1205
62
    if (sym)
1206
0
      (*info->fprintf_styled_func) (info->stream, dis_style_text,
1207
0
            " <%s>", bfd_asymbol_name (sym));
1208
1209
62
    if (info->private_data != NULL
1210
62
        && info->section != NULL
1211
62
        && info->section->owner != NULL
1212
62
        && (bfd_get_file_flags (info->section->owner)
1213
23
      & (EXEC_P | DYNAMIC)) != 0
1214
62
        && ((insn & ((-1ULL << 50) | (0x3fULL << 26)))
1215
22
      == ((1ULL << 58) | (1ULL << 52) | (57ULL << 26)) /* pld */))
1216
0
      {
1217
0
        for (int i = 0; i < 2; i++)
1218
0
    if (print_got_plt (private_data (info)->special + i, d34, info))
1219
0
      break;
1220
0
      }
1221
62
  }
1222
1223
      /* We have found and printed an instruction.  */
1224
9.80M
      return insn_length;
1225
9.80M
    }
1226
1227
  /* We could not find a match.  */
1228
4.41M
  if (insn_length == 4)
1229
4.41M
    (*info->fprintf_styled_func) (info->stream,
1230
4.41M
          dis_style_assembler_directive, ".long");
1231
0
  else
1232
0
    {
1233
0
      (*info->fprintf_styled_func) (info->stream,
1234
0
            dis_style_assembler_directive, ".word");
1235
0
      insn >>= 16;
1236
0
    }
1237
4.41M
  (*info->fprintf_styled_func) (info->stream, dis_style_text, " ");
1238
4.41M
  (*info->fprintf_styled_func) (info->stream, dis_style_immediate, "0x%x",
1239
4.41M
        (unsigned int) insn);
1240
1241
1242
4.41M
  return insn_length;
1243
14.2M
}
1244
1245
const disasm_options_and_args_t *
1246
disassembler_options_powerpc (void)
1247
0
{
1248
0
  static disasm_options_and_args_t *opts_and_args;
1249
1250
0
  if (opts_and_args == NULL)
1251
0
    {
1252
0
      size_t i, num_options = ARRAY_SIZE (ppc_opts);
1253
0
      disasm_options_t *opts;
1254
1255
0
      opts_and_args = XNEW (disasm_options_and_args_t);
1256
0
      opts_and_args->args = NULL;
1257
1258
0
      opts = &opts_and_args->options;
1259
0
      opts->name = XNEWVEC (const char *, num_options + 1);
1260
0
      opts->description = NULL;
1261
0
      opts->arg = NULL;
1262
0
      for (i = 0; i < num_options; i++)
1263
0
  opts->name[i] = ppc_opts[i].opt;
1264
      /* The array we return must be NULL terminated.  */
1265
0
      opts->name[i] = NULL;
1266
0
    }
1267
1268
0
  return opts_and_args;
1269
0
}
1270
1271
void
1272
print_ppc_disassembler_options (FILE *stream)
1273
0
{
1274
0
  unsigned int i, col;
1275
1276
0
  fprintf (stream, _("\n\
1277
0
The following PPC specific disassembler options are supported for use with\n\
1278
0
the -M switch:\n"));
1279
1280
0
  for (col = 0, i = 0; i < ARRAY_SIZE (ppc_opts); i++)
1281
0
    {
1282
0
      col += fprintf (stream, " %s,", ppc_opts[i].opt);
1283
0
      if (col > 66)
1284
0
  {
1285
0
    fprintf (stream, "\n");
1286
0
    col = 0;
1287
0
  }
1288
0
    }
1289
0
  fprintf (stream, "\n");
1290
0
}