Coverage Report

Created: 2025-06-24 06:45

/src/binutils-gdb/opcodes/sparc-dis.c
Line
Count
Source (jump to first uncovered line)
1
/* Print SPARC instructions.
2
   Copyright (C) 1989-2025 Free Software Foundation, Inc.
3
4
   This file is part of the GNU opcodes library.
5
6
   This library is free software; you can redistribute it and/or modify
7
   it under the terms of the GNU General Public License as published by
8
   the Free Software Foundation; either version 3, or (at your option)
9
   any later version.
10
11
   It is distributed in the hope that it will be useful, but WITHOUT
12
   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13
   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
14
   License for more details.
15
16
   You should have received a copy of the GNU General Public License
17
   along with this program; if not, write to the Free Software
18
   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
19
   MA 02110-1301, USA.  */
20
21
#include "sysdep.h"
22
#include <stdio.h>
23
#include "opcode/sparc.h"
24
#include "dis-asm.h"
25
#include "libiberty.h"
26
#include "opintl.h"
27
28
/* Bitmask of v9 architectures.  */
29
#define MASK_V9 ((1 << SPARC_OPCODE_ARCH_V9) \
30
     | (1 << SPARC_OPCODE_ARCH_V9A) \
31
     | (1 << SPARC_OPCODE_ARCH_V9B) \
32
     | (1 << SPARC_OPCODE_ARCH_V9C) \
33
     | (1 << SPARC_OPCODE_ARCH_V9D) \
34
     | (1 << SPARC_OPCODE_ARCH_V9E) \
35
     | (1 << SPARC_OPCODE_ARCH_V9V) \
36
     | (1 << SPARC_OPCODE_ARCH_V9M) \
37
     | (1 << SPARC_OPCODE_ARCH_M8))
38
/* 1 if INSN is for v9 only.  */
39
#define V9_ONLY_P(insn) (! ((insn)->architecture & ~MASK_V9))
40
/* 1 if INSN is for v9.  */
41
#define V9_P(insn) (((insn)->architecture & MASK_V9) != 0)
42
43
/* The sorted opcode table.  */
44
static const sparc_opcode **sorted_opcodes;
45
46
/* For faster lookup, after insns are sorted they are hashed.  */
47
/* ??? I think there is room for even more improvement.  */
48
49
910
#define HASH_SIZE 256
50
/* It is important that we only look at insn code bits as that is how the
51
   opcode table is hashed.  OPCODE_BITS is a table of valid bits for each
52
   of the main types (0,1,2,3).  */
53
static int opcode_bits[4] = { 0x01c00000, 0x0, 0x01f80000, 0x01f80000 };
54
#define HASH_INSN(INSN) \
55
2.93M
  ((((INSN) >> 24) & 0xc0) | (((INSN) & opcode_bits[((INSN) >> 30) & 3]) >> 19))
56
typedef struct sparc_opcode_hash
57
{
58
  struct sparc_opcode_hash *next;
59
  const sparc_opcode *opcode;
60
} sparc_opcode_hash;
61
62
static sparc_opcode_hash *opcode_hash_table[HASH_SIZE];
63
64
/* Sign-extend a value which is N bits long.  */
65
#define SEX(value, bits) \
66
727k
  ((int) (((value & ((1u << (bits - 1) << 1) - 1))  \
67
727k
     ^ (1u << (bits - 1))) - (1u << (bits - 1))))
68
69
static  char *reg_names[] =
70
{ "g0", "g1", "g2", "g3", "g4", "g5", "g6", "g7",
71
  "o0", "o1", "o2", "o3", "o4", "o5", "sp", "o7",
72
  "l0", "l1", "l2", "l3", "l4", "l5", "l6", "l7",
73
  "i0", "i1", "i2", "i3", "i4", "i5", "fp", "i7",
74
  "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
75
  "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
76
  "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
77
  "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
78
  "f32", "f33", "f34", "f35", "f36", "f37", "f38", "f39",
79
  "f40", "f41", "f42", "f43", "f44", "f45", "f46", "f47",
80
  "f48", "f49", "f50", "f51", "f52", "f53", "f54", "f55",
81
  "f56", "f57", "f58", "f59", "f60", "f61", "f62", "f63",
82
/* psr, wim, tbr, fpsr, cpsr are v8 only.  */
83
  "y", "psr", "wim", "tbr", "pc", "npc", "fpsr", "cpsr"
84
};
85
86
22.5k
#define freg_names  (&reg_names[4 * 8])
87
88
/* These are ordered according to there register number in
89
   rdpr and wrpr insns.  */
90
static char *v9_priv_reg_names[] =
91
{
92
  "tpc", "tnpc", "tstate", "tt", "tick", "tba", "pstate", "tl",
93
  "pil", "cwp", "cansave", "canrestore", "cleanwin", "otherwin",
94
  "wstate", "fq", "gl"
95
  /* "ver" and "pmcdper" - special cased */
96
};
97
98
/* These are ordered according to there register number in
99
   rdhpr and wrhpr insns.  */
100
static char *v9_hpriv_reg_names[] =
101
{
102
  "hpstate", "htstate", "resv2", "hintp", "resv4", "htba", "hver",
103
  "resv7", "resv8", "resv9", "resv10", "resv11", "resv12", "resv13",
104
  "resv14", "resv15", "resv16", "resv17", "resv18", "resv19", "resv20",
105
  "resv21", "resv22", "hmcdper", "hmcddfr", "resv25", "resv26", "hva_mask_nz",
106
  "hstick_offset", "hstick_enable", "resv30", "hstick_cmpr"
107
};
108
109
/* These are ordered according to there register number in
110
   rd and wr insns (-16).  */
111
static char *v9a_asr_reg_names[] =
112
{
113
  "pcr", "pic", "dcr", "gsr", "softint_set", "softint_clear",
114
  "softint", "tick_cmpr", "stick", "stick_cmpr", "cfr",
115
  "pause", "mwait"
116
};
117
118
/* Macros used to extract instruction fields.  Not all fields have
119
   macros defined here, only those which are actually used.  */
120
121
3.90M
#define X_RD(i)      (((i) >> 25) & 0x1f)
122
988k
#define X_RS1(i)     (((i) >> 14) & 0x1f)
123
454
#define X_LDST_I(i)  (((i) >> 13) & 1)
124
27.6k
#define X_ASI(i)     (((i) >> 5) & 0xff)
125
967k
#define X_RS2(i)     (((i) >> 0) & 0x1f)
126
151
#define X_RS3(i)     (((i) >> 9) & 0x1f)
127
10.4k
#define X_IMM(i,n)   (((i) >> 0) & ((1 << (n)) - 1))
128
172k
#define X_SIMM(i,n)  SEX (X_IMM ((i), (n)), (n))
129
96.6k
#define X_DISP22(i)  (((i) >> 0) & 0x3fffff)
130
96.6k
#define X_IMM22(i)   X_DISP22 (i)
131
#define X_DISP30(i)  (((i) >> 0) & 0x3fffffff)
132
127
#define X_IMM2(i)    (((i & 0x10) >> 3) | (i & 0x1))
133
134
/* These are for v9.  */
135
#define X_DISP16(i)  (((((i) >> 20) & 3) << 14) | (((i) >> 0) & 0x3fff))
136
#define X_DISP10(i)  (((((i) >> 19) & 3) << 8) | (((i) >> 5) & 0xff))
137
#define X_DISP19(i)  (((i) >> 0) & 0x7ffff)
138
0
#define X_MEMBAR(i)  ((i) & 0x7f)
139
140
/* Here is the union which was used to extract instruction fields
141
   before the shift and mask macros were written.
142
143
   union sparc_insn
144
     {
145
       unsigned long int code;
146
       struct
147
   {
148
     unsigned int anop:2;
149
     #define  op  ldst.anop
150
     unsigned int anrd:5;
151
     #define  rd  ldst.anrd
152
     unsigned int op3:6;
153
     unsigned int anrs1:5;
154
     #define  rs1 ldst.anrs1
155
     unsigned int i:1;
156
     unsigned int anasi:8;
157
     #define  asi ldst.anasi
158
     unsigned int anrs2:5;
159
     #define  rs2 ldst.anrs2
160
     #define  shcnt rs2
161
   } ldst;
162
       struct
163
   {
164
     unsigned int anop:2, anrd:5, op3:6, anrs1:5, i:1;
165
     unsigned int IMM13:13;
166
     #define  imm13 IMM13.IMM13
167
   } IMM13;
168
       struct
169
   {
170
     unsigned int anop:2;
171
     unsigned int a:1;
172
     unsigned int cond:4;
173
     unsigned int op2:3;
174
     unsigned int DISP22:22;
175
     #define  disp22  branch.DISP22
176
     #define  imm22 disp22
177
   } branch;
178
       struct
179
   {
180
     unsigned int anop:2;
181
     unsigned int a:1;
182
     unsigned int z:1;
183
     unsigned int rcond:3;
184
     unsigned int op2:3;
185
     unsigned int DISP16HI:2;
186
     unsigned int p:1;
187
     unsigned int _rs1:5;
188
     unsigned int DISP16LO:14;
189
   } branch16;
190
       struct
191
   {
192
     unsigned int anop:2;
193
     unsigned int adisp30:30;
194
     #define  disp30  call.adisp30
195
   } call;
196
     };  */
197
198
/* Nonzero if INSN is the opcode for a delayed branch.  */
199
200
static int
201
is_delayed_branch (unsigned long insn)
202
100k
{
203
100k
  sparc_opcode_hash *op;
204
205
2.86M
  for (op = opcode_hash_table[HASH_INSN (insn)]; op; op = op->next)
206
2.86M
    {
207
2.86M
      const sparc_opcode *opcode = op->opcode;
208
209
2.86M
      if ((opcode->match & insn) == opcode->match
210
2.86M
    && (opcode->lose & insn) == 0)
211
95.5k
  return opcode->flags & F_DELAYED;
212
2.86M
    }
213
4.51k
  return 0;
214
100k
}
215
216
/* extern void qsort (); */
217
218
/* Records current mask of SPARC_OPCODE_ARCH_FOO values, used to pass value
219
   to compare_opcodes.  */
220
static unsigned int current_arch_mask;
221
222
/* Given BFD mach number, return a mask of SPARC_OPCODE_ARCH_FOO values.  */
223
224
static int
225
compute_arch_mask (unsigned long mach)
226
455
{
227
455
  switch (mach)
228
455
    {
229
92
    case 0 :
230
103
    case bfd_mach_sparc :
231
103
      return (SPARC_OPCODE_ARCH_MASK (SPARC_OPCODE_ARCH_V8)
232
103
              | SPARC_OPCODE_ARCH_MASK (SPARC_OPCODE_ARCH_LEON));
233
30
    case bfd_mach_sparc_sparclet :
234
30
      return SPARC_OPCODE_ARCH_MASK (SPARC_OPCODE_ARCH_SPARCLET);
235
9
    case bfd_mach_sparc_sparclite :
236
12
    case bfd_mach_sparc_sparclite_le :
237
      /* sparclites insns are recognized by default (because that's how
238
   they've always been treated, for better or worse).  Kludge this by
239
   indicating generic v8 is also selected.  */
240
12
      return (SPARC_OPCODE_ARCH_MASK (SPARC_OPCODE_ARCH_SPARCLITE)
241
12
        | SPARC_OPCODE_ARCH_MASK (SPARC_OPCODE_ARCH_V8));
242
59
    case bfd_mach_sparc_v8plus :
243
62
    case bfd_mach_sparc_v9 :
244
62
      return SPARC_OPCODE_ARCH_MASK (SPARC_OPCODE_ARCH_V9);
245
21
    case bfd_mach_sparc_v8plusa :
246
24
    case bfd_mach_sparc_v9a :
247
24
      return SPARC_OPCODE_ARCH_MASK (SPARC_OPCODE_ARCH_V9A);
248
7
    case bfd_mach_sparc_v8plusb :
249
13
    case bfd_mach_sparc_v9b :
250
13
      return SPARC_OPCODE_ARCH_MASK (SPARC_OPCODE_ARCH_V9B);
251
0
    case bfd_mach_sparc_v8plusc :
252
3
    case bfd_mach_sparc_v9c :
253
3
      return SPARC_OPCODE_ARCH_MASK (SPARC_OPCODE_ARCH_V9C);
254
0
    case bfd_mach_sparc_v8plusd :
255
22
    case bfd_mach_sparc_v9d :
256
22
      return SPARC_OPCODE_ARCH_MASK (SPARC_OPCODE_ARCH_V9D);
257
14
    case bfd_mach_sparc_v8pluse :
258
54
    case bfd_mach_sparc_v9e :
259
54
      return SPARC_OPCODE_ARCH_MASK (SPARC_OPCODE_ARCH_V9E);
260
32
    case bfd_mach_sparc_v8plusv :
261
33
    case bfd_mach_sparc_v9v :
262
33
      return SPARC_OPCODE_ARCH_MASK (SPARC_OPCODE_ARCH_V9V);
263
2
    case bfd_mach_sparc_v8plusm :
264
2
    case bfd_mach_sparc_v9m :
265
2
      return SPARC_OPCODE_ARCH_MASK (SPARC_OPCODE_ARCH_V9M);
266
68
    case bfd_mach_sparc_v8plusm8 :
267
97
    case bfd_mach_sparc_v9m8 :
268
97
      return SPARC_OPCODE_ARCH_MASK (SPARC_OPCODE_ARCH_M8);
269
455
    }
270
0
  abort ();
271
455
}
272
273
/* Compare opcodes A and B.  */
274
275
static int
276
compare_opcodes (const void * a, const void * b)
277
16.0M
{
278
16.0M
  sparc_opcode *op0 = * (sparc_opcode **) a;
279
16.0M
  sparc_opcode *op1 = * (sparc_opcode **) b;
280
16.0M
  unsigned long int match0 = op0->match, match1 = op1->match;
281
16.0M
  unsigned long int lose0 = op0->lose, lose1 = op1->lose;
282
16.0M
  register unsigned int i;
283
284
  /* If one (and only one) insn isn't supported by the current architecture,
285
     prefer the one that is.  If neither are supported, but they're both for
286
     the same architecture, continue processing.  Otherwise (both unsupported
287
     and for different architectures), prefer lower numbered arch's (fudged
288
     by comparing the bitmasks).  */
289
16.0M
  if (op0->architecture & current_arch_mask)
290
10.9M
    {
291
10.9M
      if (! (op1->architecture & current_arch_mask))
292
288k
  return -1;
293
10.9M
    }
294
5.16M
  else
295
5.16M
    {
296
5.16M
      if (op1->architecture & current_arch_mask)
297
185k
  return 1;
298
4.98M
      else if (op0->architecture != op1->architecture)
299
673k
  return op0->architecture - op1->architecture;
300
5.16M
    }
301
302
  /* If a bit is set in both match and lose, there is something
303
     wrong with the opcode table.  */
304
14.9M
  if (match0 & lose0)
305
0
    {
306
0
      opcodes_error_handler
307
  /* xgettext:c-format */
308
0
  (_("internal error: bad sparc-opcode.h: \"%s\", %#.8lx, %#.8lx\n"),
309
0
   op0->name, match0, lose0);
310
0
      op0->lose &= ~op0->match;
311
0
      lose0 = op0->lose;
312
0
    }
313
314
14.9M
  if (match1 & lose1)
315
0
    {
316
0
      opcodes_error_handler
317
  /* xgettext:c-format */
318
0
  (_("internal error: bad sparc-opcode.h: \"%s\", %#.8lx, %#.8lx\n"),
319
0
   op1->name, match1, lose1);
320
0
      op1->lose &= ~op1->match;
321
0
      lose1 = op1->lose;
322
0
    }
323
324
  /* Because the bits that are variable in one opcode are constant in
325
     another, it is important to order the opcodes in the right order.  */
326
296M
  for (i = 0; i < 32; ++i)
327
295M
    {
328
295M
      unsigned long int x = 1ul << i;
329
295M
      int x0 = (match0 & x) != 0;
330
295M
      int x1 = (match1 & x) != 0;
331
332
295M
      if (x0 != x1)
333
13.8M
  return x1 - x0;
334
295M
    }
335
336
22.6M
  for (i = 0; i < 32; ++i)
337
22.0M
    {
338
22.0M
      unsigned long int x = 1ul << i;
339
22.0M
      int x0 = (lose0 & x) != 0;
340
22.0M
      int x1 = (lose1 & x) != 0;
341
342
22.0M
      if (x0 != x1)
343
484k
  return x1 - x0;
344
22.0M
    }
345
346
  /* They are functionally equal.  So as long as the opcode table is
347
     valid, we can put whichever one first we want, on aesthetic grounds.  */
348
349
  /* Our first aesthetic ground is that aliases defer to real insns.  */
350
573k
  {
351
573k
    int alias_diff = (op0->flags & F_ALIAS) - (op1->flags & F_ALIAS);
352
353
573k
    if (alias_diff != 0)
354
      /* Put the one that isn't an alias first.  */
355
292k
      return alias_diff;
356
573k
  }
357
358
  /* Except for aliases, two "identical" instructions had
359
     better have the same opcode.  This is a sanity check on the table.  */
360
281k
  i = strcmp (op0->name, op1->name);
361
281k
  if (i)
362
71.3k
    {
363
71.3k
      if (op0->flags & F_ALIAS)
364
71.3k
  {
365
71.3k
    if (op0->flags & F_PREFERRED)
366
8.19k
      return -1;
367
63.1k
    if (op1->flags & F_PREFERRED)
368
0
      return 1;
369
370
    /* If they're both aliases, and neither is marked as preferred,
371
       be arbitrary.  */
372
63.1k
    return i;
373
63.1k
  }
374
0
      else
375
0
  opcodes_error_handler
376
    /* xgettext:c-format */
377
0
    (_("internal error: bad sparc-opcode.h: \"%s\" == \"%s\"\n"),
378
0
     op0->name, op1->name);
379
71.3k
    }
380
381
  /* Fewer arguments are preferred.  */
382
209k
  {
383
209k
    int length_diff = strlen (op0->args) - strlen (op1->args);
384
385
209k
    if (length_diff != 0)
386
      /* Put the one with fewer arguments first.  */
387
135k
      return length_diff;
388
209k
  }
389
390
  /* Put 1+i before i+1.  */
391
74.1k
  {
392
74.1k
    char *p0 = (char *) strchr (op0->args, '+');
393
74.1k
    char *p1 = (char *) strchr (op1->args, '+');
394
395
74.1k
    if (p0 && p1)
396
58.6k
      {
397
  /* There is a plus in both operands.  Note that a plus
398
     sign cannot be the first character in args,
399
     so the following [-1]'s are valid.  */
400
58.6k
  if (p0[-1] == 'i' && p1[1] == 'i')
401
    /* op0 is i+1 and op1 is 1+i, so op1 goes first.  */
402
0
    return 1;
403
58.6k
  if (p0[1] == 'i' && p1[-1] == 'i')
404
    /* op0 is 1+i and op1 is i+1, so op0 goes first.  */
405
52.7k
    return -1;
406
58.6k
      }
407
74.1k
  }
408
409
  /* Put 1,i before i,1.  */
410
21.3k
  {
411
21.3k
    int i0 = strncmp (op0->args, "i,1", 3) == 0;
412
21.3k
    int i1 = strncmp (op1->args, "i,1", 3) == 0;
413
414
21.3k
    if (i0 ^ i1)
415
14.1k
      return i0 - i1;
416
21.3k
  }
417
418
  /* They are, as far as we can tell, identical.
419
     Since qsort may have rearranged the table partially, there is
420
     no way to tell which one was first in the opcode table as
421
     written, so just say there are equal.  */
422
  /* ??? This is no longer true now that we sort a vector of pointers,
423
     not the table itself.  */
424
7.28k
  return 0;
425
21.3k
}
426
427
/* Build a hash table from the opcode table.
428
   OPCODE_TABLE is a sorted list of pointers into the opcode table.  */
429
430
static void
431
build_hash_table (const sparc_opcode **opcode_table,
432
      sparc_opcode_hash **hash_table,
433
      int num_opcodes)
434
455
{
435
455
  int i;
436
455
  int hash_count[HASH_SIZE];
437
455
  static sparc_opcode_hash *hash_buf = NULL;
438
439
  /* Start at the end of the table and work backwards so that each
440
     chain is sorted.  */
441
442
455
  memset (hash_table, 0, HASH_SIZE * sizeof (hash_table[0]));
443
455
  memset (hash_count, 0, HASH_SIZE * sizeof (hash_count[0]));
444
455
  free (hash_buf);
445
455
  hash_buf = xmalloc (sizeof (* hash_buf) * num_opcodes);
446
1.60M
  for (i = num_opcodes - 1; i >= 0; --i)
447
1.60M
    {
448
1.60M
      int hash = HASH_INSN (opcode_table[i]->match);
449
1.60M
      sparc_opcode_hash *h = &hash_buf[i];
450
451
1.60M
      h->next = hash_table[hash];
452
1.60M
      h->opcode = opcode_table[i];
453
1.60M
      hash_table[hash] = h;
454
1.60M
      ++hash_count[hash];
455
1.60M
    }
456
457
#if 0 /* for debugging */
458
  {
459
    int min_count = num_opcodes, max_count = 0;
460
    int total;
461
462
    for (i = 0; i < HASH_SIZE; ++i)
463
      {
464
        if (hash_count[i] < min_count)
465
    min_count = hash_count[i];
466
  if (hash_count[i] > max_count)
467
    max_count = hash_count[i];
468
  total += hash_count[i];
469
      }
470
471
    printf ("Opcode hash table stats: min %d, max %d, ave %f\n",
472
      min_count, max_count, (double) total / HASH_SIZE);
473
  }
474
#endif
475
455
}
476
477
/* Print one instruction from MEMADDR on INFO->STREAM.
478
479
   We suffix the instruction with a comment that gives the absolute
480
   address involved, as well as its symbolic form, if the instruction
481
   is preceded by a findable `sethi' and it either adds an immediate
482
   displacement to that register, or it is an `add' or `or' instruction
483
   on that register.  */
484
485
int
486
print_insn_sparc (bfd_vma memaddr, disassemble_info *info)
487
1.22M
{
488
1.22M
  FILE *stream = info->stream;
489
1.22M
  bfd_byte buffer[4];
490
1.22M
  unsigned long insn;
491
1.22M
  sparc_opcode_hash *op;
492
  /* Nonzero of opcode table has been initialized.  */
493
1.22M
  static int opcodes_initialized = 0;
494
  /* bfd mach number of last call.  */
495
1.22M
  static unsigned long current_mach = 0;
496
1.22M
  bfd_vma (*getword) (const void *);
497
498
1.22M
  if (!opcodes_initialized
499
1.22M
      || info->mach != current_mach)
500
455
    {
501
455
      int i;
502
503
455
      current_arch_mask = compute_arch_mask (info->mach);
504
505
455
      if (!opcodes_initialized)
506
2
  sorted_opcodes =
507
2
    xmalloc (sparc_num_opcodes * sizeof (sparc_opcode *));
508
      /* Reset the sorted table so we can resort it.  */
509
1.60M
      for (i = 0; i < sparc_num_opcodes; ++i)
510
1.60M
  sorted_opcodes[i] = &sparc_opcodes[i];
511
455
      qsort ((char *) sorted_opcodes, sparc_num_opcodes,
512
455
       sizeof (sorted_opcodes[0]), compare_opcodes);
513
514
455
      build_hash_table (sorted_opcodes, opcode_hash_table, sparc_num_opcodes);
515
455
      current_mach = info->mach;
516
455
      opcodes_initialized = 1;
517
455
    }
518
519
1.22M
  {
520
1.22M
    int status =
521
1.22M
      (*info->read_memory_func) (memaddr, buffer, sizeof (buffer), info);
522
523
1.22M
    if (status != 0)
524
425
      {
525
425
  (*info->memory_error_func) (status, memaddr, info);
526
425
  return -1;
527
425
      }
528
1.22M
  }
529
530
  /* On SPARClite variants such as DANlite (sparc86x), instructions
531
     are always big-endian even when the machine is in little-endian mode.  */
532
1.22M
  if (info->endian == BFD_ENDIAN_BIG || info->mach == bfd_mach_sparc_sparclite)
533
1.03M
    getword = bfd_getb32;
534
194k
  else
535
194k
    getword = bfd_getl32;
536
537
1.22M
  insn = getword (buffer);
538
539
1.22M
  info->insn_info_valid = 1;      /* We do return this info.  */
540
1.22M
  info->insn_type = dis_nonbranch;    /* Assume non branch insn.  */
541
1.22M
  info->branch_delay_insns = 0;     /* Assume no delay.  */
542
1.22M
  info->target = 0;       /* Assume no target known.  */
543
544
30.0M
  for (op = opcode_hash_table[HASH_INSN (insn)]; op; op = op->next)
545
29.7M
    {
546
29.7M
      const sparc_opcode *opcode = op->opcode;
547
548
      /* If the insn isn't supported by the current architecture, skip it.  */
549
29.7M
      if (! (opcode->architecture & current_arch_mask))
550
9.95M
  continue;
551
552
19.8M
      if ((opcode->match & insn) == opcode->match
553
19.8M
    && (opcode->lose & insn) == 0)
554
970k
  {
555
    /* Nonzero means that we have found an instruction which has
556
       the effect of adding or or'ing the imm13 field to rs1.  */
557
970k
    int imm_added_to_rs1 = 0;
558
970k
    int imm_ored_to_rs1 = 0;
559
560
    /* Nonzero means that we have found a plus sign in the args
561
       field of the opcode table.  */
562
970k
    int found_plus = 0;
563
564
    /* Nonzero means we have an annulled branch.  */
565
970k
    int is_annulled = 0;
566
567
    /* Do we have an `add' or `or' instruction combining an
568
             immediate with rs1?  */
569
970k
    if (opcode->match == 0x80102000) /* or */
570
30.2k
      imm_ored_to_rs1 = 1;
571
970k
    if (opcode->match == 0x80002000) /* add */
572
8.67k
      imm_added_to_rs1 = 1;
573
574
970k
    if (X_RS1 (insn) != X_RD (insn)
575
970k
        && strchr (opcode->args, 'r') != 0)
576
        /* Can't do simple format if source and dest are different.  */
577
2.73k
        continue;
578
967k
    if (X_RS2 (insn) != X_RD (insn)
579
967k
        && strchr (opcode->args, 'O') != 0)
580
        /* Can't do simple format if source and dest are different.  */
581
101
        continue;
582
583
967k
    (*info->fprintf_func) (stream, "%s", opcode->name);
584
585
967k
    {
586
967k
      const char *s;
587
588
967k
      if (opcode->args[0] != ',')
589
910k
        (*info->fprintf_func) (stream, " ");
590
591
2.96M
      for (s = opcode->args; *s != '\0'; ++s)
592
1.99M
        {
593
2.58M
    while (*s == ',')
594
588k
      {
595
588k
        (*info->fprintf_func) (stream, ",");
596
588k
        ++s;
597
588k
        switch (*s)
598
588k
          {
599
33.7k
          case 'a':
600
33.7k
      (*info->fprintf_func) (stream, "a");
601
33.7k
      is_annulled = 1;
602
33.7k
      ++s;
603
33.7k
      continue;
604
34.3k
          case 'N':
605
34.3k
      (*info->fprintf_func) (stream, "pn");
606
34.3k
      ++s;
607
34.3k
      continue;
608
609
0
          case 'T':
610
0
      (*info->fprintf_func) (stream, "pt");
611
0
      ++s;
612
0
      continue;
613
614
520k
          default:
615
520k
      break;
616
588k
          }
617
588k
      }
618
619
1.99M
    (*info->fprintf_func) (stream, " ");
620
621
1.99M
    switch (*s)
622
1.99M
      {
623
97.3k
      case '+':
624
97.3k
        found_plus = 1;
625
        /* Fall through.  */
626
627
400k
      default:
628
400k
        (*info->fprintf_func) (stream, "%c", *s);
629
400k
        break;
630
631
0
      case '#':
632
0
        (*info->fprintf_func) (stream, "0");
633
0
        break;
634
635
649k
#define reg(n)  (*info->fprintf_func) (stream, "%%%s", reg_names[n])
636
247k
      case '1':
637
252k
      case 'r':
638
252k
        reg (X_RS1 (insn));
639
252k
        break;
640
641
85.7k
      case '2':
642
85.8k
      case 'O':
643
85.8k
        reg (X_RS2 (insn));
644
85.8k
        break;
645
646
310k
      case 'd':
647
310k
        reg (X_RD (insn));
648
310k
        break;
649
0
#undef  reg
650
651
14.2k
#define freg(n)   (*info->fprintf_func) (stream, "%%%s", freg_names[n])
652
8.25k
#define fregx(n)  (*info->fprintf_func) (stream, "%%%s", freg_names[((n) & ~1) | (((n) & 1) << 5)])
653
1.05k
      case 'e':
654
1.05k
        freg (X_RS1 (insn));
655
1.05k
        break;
656
821
      case 'v': /* Double/even.  */
657
900
      case 'V': /* Quad/multiple of 4.  */
658
903
                  case ';': /* Double/even multiple of 8 doubles.  */
659
903
        fregx (X_RS1 (insn));
660
903
        break;
661
662
1.32k
      case 'f':
663
1.32k
        freg (X_RS2 (insn));
664
1.32k
        break;
665
785
      case 'B': /* Double/even.  */
666
868
      case 'R': /* Quad/multiple of 4.  */
667
871
                  case ':': /* Double/even multiple of 8 doubles.  */
668
871
        fregx (X_RS2 (insn));
669
871
        break;
670
671
967
      case '4':
672
967
        freg (X_RS3 (insn));
673
967
        break;
674
337
      case '5': /* Double/even.  */
675
337
        fregx (X_RS3 (insn));
676
337
        break;
677
678
10.9k
      case 'g':
679
10.9k
        freg (X_RD (insn));
680
10.9k
        break;
681
3.24k
      case 'H': /* Double/even.  */
682
6.01k
      case 'J': /* Quad/multiple of 4.  */
683
6.01k
      case '}':     /* Double/even.  */
684
6.01k
        fregx (X_RD (insn));
685
6.01k
        break;
686
                    
687
3
                  case '^': /* Double/even multiple of 8 doubles.  */
688
3
                    fregx (X_RD (insn) & ~0x6);
689
3
                    break;
690
                    
691
127
                  case '\'':  /* Double/even in FPCMPSHL.  */
692
127
                    fregx (X_RS2 (insn | 0x11));
693
127
                    break;
694
                    
695
0
#undef  freg
696
0
#undef  fregx
697
698
703
#define creg(n) (*info->fprintf_func) (stream, "%%c%u", (unsigned int) (n))
699
0
      case 'b':
700
0
        creg (X_RS1 (insn));
701
0
        break;
702
703
0
      case 'c':
704
0
        creg (X_RS2 (insn));
705
0
        break;
706
707
703
      case 'D':
708
703
        creg (X_RD (insn));
709
703
        break;
710
0
#undef  creg
711
712
88.4k
      case 'h':
713
88.4k
        (*info->fprintf_func) (stream, "%%hi(%#x)",
714
88.4k
             (unsigned) X_IMM22 (insn) << 10);
715
88.4k
        break;
716
717
162k
      case 'i': /* 13 bit immediate.  */
718
163k
      case 'I': /* 11 bit immediate.  */
719
164k
      case 'j': /* 10 bit immediate.  */
720
164k
        {
721
164k
          int imm;
722
723
164k
          if (*s == 'i')
724
162k
            imm = X_SIMM (insn, 13);
725
1.37k
          else if (*s == 'I')
726
814
      imm = X_SIMM (insn, 11);
727
564
          else
728
564
      imm = X_SIMM (insn, 10);
729
730
          /* Check to see whether we have a 1+i, and take
731
       note of that fact.
732
733
       Note: because of the way we sort the table,
734
       we will be matching 1+i rather than i+1,
735
       so it is OK to assume that i is after +,
736
       not before it.  */
737
164k
          if (found_plus)
738
72.4k
      imm_added_to_rs1 = 1;
739
740
164k
          if (imm <= 9)
741
95.2k
      (*info->fprintf_func) (stream, "%d", imm);
742
68.8k
          else
743
68.8k
      (*info->fprintf_func) (stream, "%#x", imm);
744
164k
        }
745
164k
        break;
746
747
151
      case ')': /* 5 bit unsigned immediate from RS3.  */
748
151
        (info->fprintf_func) (stream, "%#x", (unsigned int) X_RS3 (insn));
749
151
        break;
750
751
5.17k
      case 'X': /* 5 bit unsigned immediate.  */
752
5.20k
      case 'Y': /* 6 bit unsigned immediate.  */
753
5.20k
        {
754
5.20k
          int imm = X_IMM (insn, *s == 'X' ? 5 : 6);
755
756
5.20k
          if (imm <= 9)
757
2.43k
      (info->fprintf_func) (stream, "%d", imm);
758
2.77k
          else
759
2.77k
      (info->fprintf_func) (stream, "%#x", (unsigned) imm);
760
5.20k
        }
761
5.20k
        break;
762
763
0
      case '3':
764
0
        (info->fprintf_func) (stream, "%ld", X_IMM (insn, 3));
765
0
        break;
766
767
0
      case 'K':
768
0
        {
769
0
          int mask = X_MEMBAR (insn);
770
0
          int bit = 0x40, printed_one = 0;
771
0
          const char *name;
772
773
0
          if (mask == 0)
774
0
      (info->fprintf_func) (stream, "0");
775
0
          else
776
0
      while (bit)
777
0
        {
778
0
          if (mask & bit)
779
0
            {
780
0
        if (printed_one)
781
0
          (info->fprintf_func) (stream, "|");
782
0
        name = sparc_decode_membar (bit);
783
0
        (info->fprintf_func) (stream, "%s", name);
784
0
        printed_one = 1;
785
0
            }
786
0
          bit >>= 1;
787
0
        }
788
0
          break;
789
5.17k
        }
790
791
700
      case '=':
792
700
        info->target = memaddr + SEX (X_DISP10 (insn), 10) * 4;
793
700
        (*info->print_address_func) (info->target, info);
794
700
        break;
795
796
3.67k
      case 'k':
797
3.67k
        info->target = memaddr + SEX (X_DISP16 (insn), 16) * 4;
798
3.67k
        (*info->print_address_func) (info->target, info);
799
3.67k
        break;
800
801
63.9k
      case 'G':
802
63.9k
        info->target = memaddr + SEX (X_DISP19 (insn), 19) * 4;
803
63.9k
        (*info->print_address_func) (info->target, info);
804
63.9k
        break;
805
806
2.70k
      case '6':
807
4.94k
      case '7':
808
7.43k
      case '8':
809
10.3k
      case '9':
810
10.3k
        (*info->fprintf_func) (stream, "%%fcc%c", *s - '6' + '0');
811
10.3k
        break;
812
813
33.9k
      case 'z':
814
33.9k
        (*info->fprintf_func) (stream, "%%icc");
815
33.9k
        break;
816
817
20.8k
      case 'Z':
818
20.8k
        (*info->fprintf_func) (stream, "%%xcc");
819
20.8k
        break;
820
821
96
      case 'E':
822
96
        (*info->fprintf_func) (stream, "%%ccr");
823
96
        break;
824
825
113
      case 's':
826
113
        (*info->fprintf_func) (stream, "%%fprs");
827
113
        break;
828
829
105
      case '{':
830
105
        (*info->fprintf_func) (stream, "%%mcdper");
831
105
        break;
832
833
0
                  case '&':
834
0
                    (*info->fprintf_func) (stream, "%%entropy");
835
0
                    break;
836
837
15.5k
      case 'o':
838
15.5k
        (*info->fprintf_func) (stream, "%%asi");
839
15.5k
        break;
840
841
69
      case 'W':
842
69
        (*info->fprintf_func) (stream, "%%tick");
843
69
        break;
844
845
65
      case 'P':
846
65
        (*info->fprintf_func) (stream, "%%pc");
847
65
        break;
848
849
24
      case '?':
850
24
        if (X_RS1 (insn) == 31)
851
0
          (*info->fprintf_func) (stream, "%%ver");
852
24
        else if (X_RS1 (insn) == 23)
853
0
          (*info->fprintf_func) (stream, "%%pmcdper");
854
24
        else if ((unsigned) X_RS1 (insn) < 17)
855
24
          (*info->fprintf_func) (stream, "%%%s",
856
24
               v9_priv_reg_names[X_RS1 (insn)]);
857
0
        else
858
0
          (*info->fprintf_func) (stream, "%%reserved");
859
24
        break;
860
861
1.96k
      case '!':
862
1.96k
                    if (X_RD (insn) == 31)
863
68
                      (*info->fprintf_func) (stream, "%%ver");
864
1.90k
        else if (X_RD (insn) == 23)
865
12
          (*info->fprintf_func) (stream, "%%pmcdper");
866
1.88k
        else if ((unsigned) X_RD (insn) < 17)
867
1.88k
          (*info->fprintf_func) (stream, "%%%s",
868
1.88k
               v9_priv_reg_names[X_RD (insn)]);
869
0
        else
870
0
          (*info->fprintf_func) (stream, "%%reserved");
871
1.96k
        break;
872
873
43
      case '$':
874
43
        if ((unsigned) X_RS1 (insn) < 32)
875
43
          (*info->fprintf_func) (stream, "%%%s",
876
43
               v9_hpriv_reg_names[X_RS1 (insn)]);
877
0
        else
878
0
          (*info->fprintf_func) (stream, "%%reserved");
879
43
        break;
880
881
246
      case '%':
882
246
        if ((unsigned) X_RD (insn) < 32)
883
246
          (*info->fprintf_func) (stream, "%%%s",
884
246
               v9_hpriv_reg_names[X_RD (insn)]);
885
0
        else
886
0
          (*info->fprintf_func) (stream, "%%reserved");
887
246
        break;
888
889
114
      case '/':
890
114
        if (X_RS1 (insn) < 16 || X_RS1 (insn) > 28)
891
0
          (*info->fprintf_func) (stream, "%%reserved");
892
114
        else
893
114
          (*info->fprintf_func) (stream, "%%%s",
894
114
               v9a_asr_reg_names[X_RS1 (insn)-16]);
895
114
        break;
896
897
171
      case '_':
898
171
        if (X_RD (insn) < 16 || X_RD (insn) > 28)
899
0
          (*info->fprintf_func) (stream, "%%reserved");
900
171
        else
901
171
          (*info->fprintf_func) (stream, "%%%s",
902
171
               v9a_asr_reg_names[X_RD (insn)-16]);
903
171
        break;
904
905
3.80k
      case '*':
906
3.80k
        {
907
3.80k
          const char *name = sparc_decode_prefetch (X_RD (insn));
908
909
3.80k
          if (name)
910
2.20k
      (*info->fprintf_func) (stream, "%s", name);
911
1.59k
          else
912
1.59k
      (*info->fprintf_func) (stream, "%ld", X_RD (insn));
913
3.80k
          break;
914
7.43k
        }
915
916
45
      case 'M':
917
45
        (*info->fprintf_func) (stream, "%%asr%ld", X_RS1 (insn));
918
45
        break;
919
920
850
      case 'm':
921
850
        (*info->fprintf_func) (stream, "%%asr%ld", X_RD (insn));
922
850
        break;
923
924
229k
      case 'L':
925
229k
        info->target = memaddr + SEX (X_DISP30 (insn), 30) * 4;
926
229k
        (*info->print_address_func) (info->target, info);
927
229k
        break;
928
929
193k
      case 'n':
930
193k
        (*info->fprintf_func)
931
193k
          (stream, "%#x", SEX (X_DISP22 (insn), 22));
932
193k
        break;
933
934
64.2k
      case 'l':
935
64.2k
        info->target = memaddr + SEX (X_DISP22 (insn), 22) * 4;
936
64.2k
        (*info->print_address_func) (info->target, info);
937
64.2k
        break;
938
939
18.7k
      case 'A':
940
18.7k
        {
941
18.7k
          const char *name = sparc_decode_asi (X_ASI (insn));
942
943
18.7k
          if (name)
944
10.2k
      (*info->fprintf_func) (stream, "%s", name);
945
8.43k
          else
946
8.43k
      (*info->fprintf_func) (stream, "(%ld)", X_ASI (insn));
947
18.7k
          break;
948
7.43k
        }
949
950
235
      case 'C':
951
235
        (*info->fprintf_func) (stream, "%%csr");
952
235
        break;
953
954
170
      case 'F':
955
170
        (*info->fprintf_func) (stream, "%%fsr");
956
170
        break;
957
958
96
      case '(':
959
96
        (*info->fprintf_func) (stream, "%%efsr");
960
96
        break;
961
962
109
      case 'p':
963
109
        (*info->fprintf_func) (stream, "%%psr");
964
109
        break;
965
966
304
      case 'q':
967
304
        (*info->fprintf_func) (stream, "%%fq");
968
304
        break;
969
970
149
      case 'Q':
971
149
        (*info->fprintf_func) (stream, "%%cq");
972
149
        break;
973
974
94
      case 't':
975
94
        (*info->fprintf_func) (stream, "%%tbr");
976
94
        break;
977
978
49
      case 'w':
979
49
        (*info->fprintf_func) (stream, "%%wim");
980
49
        break;
981
982
454
      case 'x':
983
454
        (*info->fprintf_func) (stream, "%ld",
984
454
             ((X_LDST_I (insn) << 8)
985
454
              + X_ASI (insn)));
986
454
        break;
987
988
127
                  case '|': /* 2-bit immediate  */
989
127
                    (*info->fprintf_func) (stream, "%ld", X_IMM2 (insn));
990
127
                    break;
991
992
216
      case 'y':
993
216
        (*info->fprintf_func) (stream, "%%y");
994
216
        break;
995
996
159
      case 'u':
997
273
      case 'U':
998
273
        {
999
273
          int val = *s == 'U' ? X_RS1 (insn) : X_RD (insn);
1000
273
          const char *name = sparc_decode_sparclet_cpreg (val);
1001
1002
273
          if (name)
1003
159
      (*info->fprintf_func) (stream, "%s", name);
1004
114
          else
1005
114
      (*info->fprintf_func) (stream, "%%cpreg(%d)", val);
1006
273
          break;
1007
159
        }
1008
1.99M
      }
1009
1.99M
        }
1010
967k
    }
1011
1012
    /* If we are adding or or'ing something to rs1, then
1013
       check to see whether the previous instruction was
1014
       a sethi to the same register as in the sethi.
1015
       If so, attempt to print the result of the add or
1016
       or (in this context add and or do the same thing)
1017
       and its symbolic value.  */
1018
967k
    if (imm_ored_to_rs1 || imm_added_to_rs1)
1019
111k
      {
1020
111k
        unsigned long prev_insn;
1021
111k
        int errcode;
1022
1023
111k
        if (memaddr >= 4)
1024
111k
    errcode =
1025
111k
      (*info->read_memory_func)
1026
111k
      (memaddr - 4, buffer, sizeof (buffer), info);
1027
2
        else
1028
2
    errcode = 1;
1029
1030
111k
        prev_insn = getword (buffer);
1031
1032
111k
        if (errcode == 0)
1033
100k
    {
1034
      /* If it is a delayed branch, we need to look at the
1035
         instruction before the delayed branch.  This handles
1036
         sequences such as:
1037
1038
         sethi %o1, %hi(_foo), %o1
1039
         call _printf
1040
         or %o1, %lo(_foo), %o1  */
1041
1042
100k
      if (is_delayed_branch (prev_insn))
1043
30.6k
        {
1044
30.6k
          if (memaddr >= 8)
1045
30.6k
      errcode = (*info->read_memory_func)
1046
30.6k
        (memaddr - 8, buffer, sizeof (buffer), info);
1047
0
          else
1048
0
      errcode = 1;
1049
1050
30.6k
          prev_insn = getword (buffer);
1051
30.6k
        }
1052
100k
    }
1053
1054
        /* If there was a problem reading memory, then assume
1055
     the previous instruction was not sethi.  */
1056
111k
        if (errcode == 0)
1057
100k
    {
1058
      /* Is it sethi to the same register?  */
1059
100k
      if ((prev_insn & 0xc1c00000) == 0x01000000
1060
100k
          && X_RD (prev_insn) == X_RS1 (insn))
1061
8.19k
        {
1062
8.19k
          (*info->fprintf_func) (stream, "\t! ");
1063
8.19k
          info->target = (unsigned) X_IMM22 (prev_insn) << 10;
1064
8.19k
          if (imm_added_to_rs1)
1065
5.30k
      info->target += X_SIMM (insn, 13);
1066
2.88k
          else
1067
2.88k
      info->target |= X_SIMM (insn, 13);
1068
8.19k
          (*info->print_address_func) (info->target, info);
1069
8.19k
          info->insn_type = dis_dref;
1070
8.19k
          info->data_size = 4;  /* FIXME!!! */
1071
8.19k
        }
1072
100k
    }
1073
111k
      }
1074
1075
967k
    if (opcode->flags & (F_UNBR|F_CONDBR|F_JSR))
1076
364k
      {
1077
        /* FIXME -- check is_annulled flag.  */
1078
364k
        (void) is_annulled;
1079
364k
        if (opcode->flags & F_UNBR)
1080
28.8k
    info->insn_type = dis_branch;
1081
364k
        if (opcode->flags & F_CONDBR)
1082
104k
    info->insn_type = dis_condbranch;
1083
364k
        if (opcode->flags & F_JSR)
1084
230k
    info->insn_type = dis_jsr;
1085
364k
        if (opcode->flags & F_DELAYED)
1086
363k
    info->branch_delay_insns = 1;
1087
364k
      }
1088
1089
967k
    return sizeof (buffer);
1090
967k
  }
1091
19.8M
    }
1092
1093
261k
  info->insn_type = dis_noninsn;  /* Mark as non-valid instruction.  */
1094
261k
  (*info->fprintf_func) (stream, _("unknown"));
1095
261k
  return sizeof (buffer);
1096
1.22M
}