Coverage Report

Created: 2023-08-28 06:23

/src/binutils-gdb/opcodes/sparc-dis.c
Line
Count
Source (jump to first uncovered line)
1
/* Print SPARC instructions.
2
   Copyright (C) 1989-2023 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
0
#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
0
  ((((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
0
  ((int) (((value & ((1u << (bits - 1) << 1) - 1))  \
67
0
     ^ (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
0
#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
0
#define X_RD(i)      (((i) >> 25) & 0x1f)
122
0
#define X_RS1(i)     (((i) >> 14) & 0x1f)
123
0
#define X_LDST_I(i)  (((i) >> 13) & 1)
124
0
#define X_ASI(i)     (((i) >> 5) & 0xff)
125
0
#define X_RS2(i)     (((i) >> 0) & 0x1f)
126
0
#define X_RS3(i)     (((i) >> 9) & 0x1f)
127
0
#define X_IMM(i,n)   (((i) >> 0) & ((1 << (n)) - 1))
128
0
#define X_SIMM(i,n)  SEX (X_IMM ((i), (n)), (n))
129
0
#define X_DISP22(i)  (((i) >> 0) & 0x3fffff)
130
0
#define X_IMM22(i)   X_DISP22 (i)
131
#define X_DISP30(i)  (((i) >> 0) & 0x3fffffff)
132
0
#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
0
{
203
0
  sparc_opcode_hash *op;
204
205
0
  for (op = opcode_hash_table[HASH_INSN (insn)]; op; op = op->next)
206
0
    {
207
0
      const sparc_opcode *opcode = op->opcode;
208
209
0
      if ((opcode->match & insn) == opcode->match
210
0
    && (opcode->lose & insn) == 0)
211
0
  return opcode->flags & F_DELAYED;
212
0
    }
213
0
  return 0;
214
0
}
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
0
{
227
0
  switch (mach)
228
0
    {
229
0
    case 0 :
230
0
    case bfd_mach_sparc :
231
0
      return (SPARC_OPCODE_ARCH_MASK (SPARC_OPCODE_ARCH_V8)
232
0
              | SPARC_OPCODE_ARCH_MASK (SPARC_OPCODE_ARCH_LEON));
233
0
    case bfd_mach_sparc_sparclet :
234
0
      return SPARC_OPCODE_ARCH_MASK (SPARC_OPCODE_ARCH_SPARCLET);
235
0
    case bfd_mach_sparc_sparclite :
236
0
    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
0
      return (SPARC_OPCODE_ARCH_MASK (SPARC_OPCODE_ARCH_SPARCLITE)
241
0
        | SPARC_OPCODE_ARCH_MASK (SPARC_OPCODE_ARCH_V8));
242
0
    case bfd_mach_sparc_v8plus :
243
0
    case bfd_mach_sparc_v9 :
244
0
      return SPARC_OPCODE_ARCH_MASK (SPARC_OPCODE_ARCH_V9);
245
0
    case bfd_mach_sparc_v8plusa :
246
0
    case bfd_mach_sparc_v9a :
247
0
      return SPARC_OPCODE_ARCH_MASK (SPARC_OPCODE_ARCH_V9A);
248
0
    case bfd_mach_sparc_v8plusb :
249
0
    case bfd_mach_sparc_v9b :
250
0
      return SPARC_OPCODE_ARCH_MASK (SPARC_OPCODE_ARCH_V9B);
251
0
    case bfd_mach_sparc_v8plusc :
252
0
    case bfd_mach_sparc_v9c :
253
0
      return SPARC_OPCODE_ARCH_MASK (SPARC_OPCODE_ARCH_V9C);
254
0
    case bfd_mach_sparc_v8plusd :
255
0
    case bfd_mach_sparc_v9d :
256
0
      return SPARC_OPCODE_ARCH_MASK (SPARC_OPCODE_ARCH_V9D);
257
0
    case bfd_mach_sparc_v8pluse :
258
0
    case bfd_mach_sparc_v9e :
259
0
      return SPARC_OPCODE_ARCH_MASK (SPARC_OPCODE_ARCH_V9E);
260
0
    case bfd_mach_sparc_v8plusv :
261
0
    case bfd_mach_sparc_v9v :
262
0
      return SPARC_OPCODE_ARCH_MASK (SPARC_OPCODE_ARCH_V9V);
263
0
    case bfd_mach_sparc_v8plusm :
264
0
    case bfd_mach_sparc_v9m :
265
0
      return SPARC_OPCODE_ARCH_MASK (SPARC_OPCODE_ARCH_V9M);
266
0
    case bfd_mach_sparc_v8plusm8 :
267
0
    case bfd_mach_sparc_v9m8 :
268
0
      return SPARC_OPCODE_ARCH_MASK (SPARC_OPCODE_ARCH_M8);
269
0
    }
270
0
  abort ();
271
0
}
272
273
/* Compare opcodes A and B.  */
274
275
static int
276
compare_opcodes (const void * a, const void * b)
277
0
{
278
0
  sparc_opcode *op0 = * (sparc_opcode **) a;
279
0
  sparc_opcode *op1 = * (sparc_opcode **) b;
280
0
  unsigned long int match0 = op0->match, match1 = op1->match;
281
0
  unsigned long int lose0 = op0->lose, lose1 = op1->lose;
282
0
  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
0
  if (op0->architecture & current_arch_mask)
290
0
    {
291
0
      if (! (op1->architecture & current_arch_mask))
292
0
  return -1;
293
0
    }
294
0
  else
295
0
    {
296
0
      if (op1->architecture & current_arch_mask)
297
0
  return 1;
298
0
      else if (op0->architecture != op1->architecture)
299
0
  return op0->architecture - op1->architecture;
300
0
    }
301
302
  /* If a bit is set in both match and lose, there is something
303
     wrong with the opcode table.  */
304
0
  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
0
  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
0
  for (i = 0; i < 32; ++i)
327
0
    {
328
0
      unsigned long int x = 1ul << i;
329
0
      int x0 = (match0 & x) != 0;
330
0
      int x1 = (match1 & x) != 0;
331
332
0
      if (x0 != x1)
333
0
  return x1 - x0;
334
0
    }
335
336
0
  for (i = 0; i < 32; ++i)
337
0
    {
338
0
      unsigned long int x = 1ul << i;
339
0
      int x0 = (lose0 & x) != 0;
340
0
      int x1 = (lose1 & x) != 0;
341
342
0
      if (x0 != x1)
343
0
  return x1 - x0;
344
0
    }
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
0
  {
351
0
    int alias_diff = (op0->flags & F_ALIAS) - (op1->flags & F_ALIAS);
352
353
0
    if (alias_diff != 0)
354
      /* Put the one that isn't an alias first.  */
355
0
      return alias_diff;
356
0
  }
357
358
  /* Except for aliases, two "identical" instructions had
359
     better have the same opcode.  This is a sanity check on the table.  */
360
0
  i = strcmp (op0->name, op1->name);
361
0
  if (i)
362
0
    {
363
0
      if (op0->flags & F_ALIAS)
364
0
  {
365
0
    if (op0->flags & F_PREFERRED)
366
0
      return -1;
367
0
    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
0
    return i;
373
0
  }
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
0
    }
380
381
  /* Fewer arguments are preferred.  */
382
0
  {
383
0
    int length_diff = strlen (op0->args) - strlen (op1->args);
384
385
0
    if (length_diff != 0)
386
      /* Put the one with fewer arguments first.  */
387
0
      return length_diff;
388
0
  }
389
390
  /* Put 1+i before i+1.  */
391
0
  {
392
0
    char *p0 = (char *) strchr (op0->args, '+');
393
0
    char *p1 = (char *) strchr (op1->args, '+');
394
395
0
    if (p0 && p1)
396
0
      {
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
0
  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
0
  if (p0[1] == 'i' && p1[-1] == 'i')
404
    /* op0 is 1+i and op1 is i+1, so op0 goes first.  */
405
0
    return -1;
406
0
      }
407
0
  }
408
409
  /* Put 1,i before i,1.  */
410
0
  {
411
0
    int i0 = strncmp (op0->args, "i,1", 3) == 0;
412
0
    int i1 = strncmp (op1->args, "i,1", 3) == 0;
413
414
0
    if (i0 ^ i1)
415
0
      return i0 - i1;
416
0
  }
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
0
  return 0;
425
0
}
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
0
{
435
0
  int i;
436
0
  int hash_count[HASH_SIZE];
437
0
  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
0
  memset (hash_table, 0, HASH_SIZE * sizeof (hash_table[0]));
443
0
  memset (hash_count, 0, HASH_SIZE * sizeof (hash_count[0]));
444
0
  free (hash_buf);
445
0
  hash_buf = xmalloc (sizeof (* hash_buf) * num_opcodes);
446
0
  for (i = num_opcodes - 1; i >= 0; --i)
447
0
    {
448
0
      int hash = HASH_INSN (opcode_table[i]->match);
449
0
      sparc_opcode_hash *h = &hash_buf[i];
450
451
0
      h->next = hash_table[hash];
452
0
      h->opcode = opcode_table[i];
453
0
      hash_table[hash] = h;
454
0
      ++hash_count[hash];
455
0
    }
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
0
}
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
0
{
488
0
  FILE *stream = info->stream;
489
0
  bfd_byte buffer[4];
490
0
  unsigned long insn;
491
0
  sparc_opcode_hash *op;
492
  /* Nonzero of opcode table has been initialized.  */
493
0
  static int opcodes_initialized = 0;
494
  /* bfd mach number of last call.  */
495
0
  static unsigned long current_mach = 0;
496
0
  bfd_vma (*getword) (const void *);
497
498
0
  if (!opcodes_initialized
499
0
      || info->mach != current_mach)
500
0
    {
501
0
      int i;
502
503
0
      current_arch_mask = compute_arch_mask (info->mach);
504
505
0
      if (!opcodes_initialized)
506
0
  sorted_opcodes =
507
0
    xmalloc (sparc_num_opcodes * sizeof (sparc_opcode *));
508
      /* Reset the sorted table so we can resort it.  */
509
0
      for (i = 0; i < sparc_num_opcodes; ++i)
510
0
  sorted_opcodes[i] = &sparc_opcodes[i];
511
0
      qsort ((char *) sorted_opcodes, sparc_num_opcodes,
512
0
       sizeof (sorted_opcodes[0]), compare_opcodes);
513
514
0
      build_hash_table (sorted_opcodes, opcode_hash_table, sparc_num_opcodes);
515
0
      current_mach = info->mach;
516
0
      opcodes_initialized = 1;
517
0
    }
518
519
0
  {
520
0
    int status =
521
0
      (*info->read_memory_func) (memaddr, buffer, sizeof (buffer), info);
522
523
0
    if (status != 0)
524
0
      {
525
0
  (*info->memory_error_func) (status, memaddr, info);
526
0
  return -1;
527
0
      }
528
0
  }
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
0
  if (info->endian == BFD_ENDIAN_BIG || info->mach == bfd_mach_sparc_sparclite)
533
0
    getword = bfd_getb32;
534
0
  else
535
0
    getword = bfd_getl32;
536
537
0
  insn = getword (buffer);
538
539
0
  info->insn_info_valid = 1;      /* We do return this info.  */
540
0
  info->insn_type = dis_nonbranch;    /* Assume non branch insn.  */
541
0
  info->branch_delay_insns = 0;     /* Assume no delay.  */
542
0
  info->target = 0;       /* Assume no target known.  */
543
544
0
  for (op = opcode_hash_table[HASH_INSN (insn)]; op; op = op->next)
545
0
    {
546
0
      const sparc_opcode *opcode = op->opcode;
547
548
      /* If the insn isn't supported by the current architecture, skip it.  */
549
0
      if (! (opcode->architecture & current_arch_mask))
550
0
  continue;
551
552
0
      if ((opcode->match & insn) == opcode->match
553
0
    && (opcode->lose & insn) == 0)
554
0
  {
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
0
    int imm_added_to_rs1 = 0;
558
0
    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
0
    int found_plus = 0;
563
564
    /* Nonzero means we have an annulled branch.  */
565
0
    int is_annulled = 0;
566
567
    /* Do we have an `add' or `or' instruction combining an
568
             immediate with rs1?  */
569
0
    if (opcode->match == 0x80102000) /* or */
570
0
      imm_ored_to_rs1 = 1;
571
0
    if (opcode->match == 0x80002000) /* add */
572
0
      imm_added_to_rs1 = 1;
573
574
0
    if (X_RS1 (insn) != X_RD (insn)
575
0
        && strchr (opcode->args, 'r') != 0)
576
        /* Can't do simple format if source and dest are different.  */
577
0
        continue;
578
0
    if (X_RS2 (insn) != X_RD (insn)
579
0
        && strchr (opcode->args, 'O') != 0)
580
        /* Can't do simple format if source and dest are different.  */
581
0
        continue;
582
583
0
    (*info->fprintf_func) (stream, "%s", opcode->name);
584
585
0
    {
586
0
      const char *s;
587
588
0
      if (opcode->args[0] != ',')
589
0
        (*info->fprintf_func) (stream, " ");
590
591
0
      for (s = opcode->args; *s != '\0'; ++s)
592
0
        {
593
0
    while (*s == ',')
594
0
      {
595
0
        (*info->fprintf_func) (stream, ",");
596
0
        ++s;
597
0
        switch (*s)
598
0
          {
599
0
          case 'a':
600
0
      (*info->fprintf_func) (stream, "a");
601
0
      is_annulled = 1;
602
0
      ++s;
603
0
      continue;
604
0
          case 'N':
605
0
      (*info->fprintf_func) (stream, "pn");
606
0
      ++s;
607
0
      continue;
608
609
0
          case 'T':
610
0
      (*info->fprintf_func) (stream, "pt");
611
0
      ++s;
612
0
      continue;
613
614
0
          default:
615
0
      break;
616
0
          }
617
0
      }
618
619
0
    (*info->fprintf_func) (stream, " ");
620
621
0
    switch (*s)
622
0
      {
623
0
      case '+':
624
0
        found_plus = 1;
625
        /* Fall through.  */
626
627
0
      default:
628
0
        (*info->fprintf_func) (stream, "%c", *s);
629
0
        break;
630
631
0
      case '#':
632
0
        (*info->fprintf_func) (stream, "0");
633
0
        break;
634
635
0
#define reg(n)  (*info->fprintf_func) (stream, "%%%s", reg_names[n])
636
0
      case '1':
637
0
      case 'r':
638
0
        reg (X_RS1 (insn));
639
0
        break;
640
641
0
      case '2':
642
0
      case 'O':
643
0
        reg (X_RS2 (insn));
644
0
        break;
645
646
0
      case 'd':
647
0
        reg (X_RD (insn));
648
0
        break;
649
0
#undef  reg
650
651
0
#define freg(n)   (*info->fprintf_func) (stream, "%%%s", freg_names[n])
652
0
#define fregx(n)  (*info->fprintf_func) (stream, "%%%s", freg_names[((n) & ~1) | (((n) & 1) << 5)])
653
0
      case 'e':
654
0
        freg (X_RS1 (insn));
655
0
        break;
656
0
      case 'v': /* Double/even.  */
657
0
      case 'V': /* Quad/multiple of 4.  */
658
0
                  case ';': /* Double/even multiple of 8 doubles.  */
659
0
        fregx (X_RS1 (insn));
660
0
        break;
661
662
0
      case 'f':
663
0
        freg (X_RS2 (insn));
664
0
        break;
665
0
      case 'B': /* Double/even.  */
666
0
      case 'R': /* Quad/multiple of 4.  */
667
0
                  case ':': /* Double/even multiple of 8 doubles.  */
668
0
        fregx (X_RS2 (insn));
669
0
        break;
670
671
0
      case '4':
672
0
        freg (X_RS3 (insn));
673
0
        break;
674
0
      case '5': /* Double/even.  */
675
0
        fregx (X_RS3 (insn));
676
0
        break;
677
678
0
      case 'g':
679
0
        freg (X_RD (insn));
680
0
        break;
681
0
      case 'H': /* Double/even.  */
682
0
      case 'J': /* Quad/multiple of 4.  */
683
0
      case '}':     /* Double/even.  */
684
0
        fregx (X_RD (insn));
685
0
        break;
686
                    
687
0
                  case '^': /* Double/even multiple of 8 doubles.  */
688
0
                    fregx (X_RD (insn) & ~0x6);
689
0
                    break;
690
                    
691
0
                  case '\'':  /* Double/even in FPCMPSHL.  */
692
0
                    fregx (X_RS2 (insn | 0x11));
693
0
                    break;
694
                    
695
0
#undef  freg
696
0
#undef  fregx
697
698
0
#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
0
      case 'D':
708
0
        creg (X_RD (insn));
709
0
        break;
710
0
#undef  creg
711
712
0
      case 'h':
713
0
        (*info->fprintf_func) (stream, "%%hi(%#x)",
714
0
             (unsigned) X_IMM22 (insn) << 10);
715
0
        break;
716
717
0
      case 'i': /* 13 bit immediate.  */
718
0
      case 'I': /* 11 bit immediate.  */
719
0
      case 'j': /* 10 bit immediate.  */
720
0
        {
721
0
          int imm;
722
723
0
          if (*s == 'i')
724
0
            imm = X_SIMM (insn, 13);
725
0
          else if (*s == 'I')
726
0
      imm = X_SIMM (insn, 11);
727
0
          else
728
0
      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
0
          if (found_plus)
738
0
      imm_added_to_rs1 = 1;
739
740
0
          if (imm <= 9)
741
0
      (*info->fprintf_func) (stream, "%d", imm);
742
0
          else
743
0
      (*info->fprintf_func) (stream, "%#x", imm);
744
0
        }
745
0
        break;
746
747
0
      case ')': /* 5 bit unsigned immediate from RS3.  */
748
0
        (info->fprintf_func) (stream, "%#x", (unsigned int) X_RS3 (insn));
749
0
        break;
750
751
0
      case 'X': /* 5 bit unsigned immediate.  */
752
0
      case 'Y': /* 6 bit unsigned immediate.  */
753
0
        {
754
0
          int imm = X_IMM (insn, *s == 'X' ? 5 : 6);
755
756
0
          if (imm <= 9)
757
0
      (info->fprintf_func) (stream, "%d", imm);
758
0
          else
759
0
      (info->fprintf_func) (stream, "%#x", (unsigned) imm);
760
0
        }
761
0
        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
0
        }
790
791
0
      case '=':
792
0
        info->target = memaddr + SEX (X_DISP10 (insn), 10) * 4;
793
0
        (*info->print_address_func) (info->target, info);
794
0
        break;
795
796
0
      case 'k':
797
0
        info->target = memaddr + SEX (X_DISP16 (insn), 16) * 4;
798
0
        (*info->print_address_func) (info->target, info);
799
0
        break;
800
801
0
      case 'G':
802
0
        info->target = memaddr + SEX (X_DISP19 (insn), 19) * 4;
803
0
        (*info->print_address_func) (info->target, info);
804
0
        break;
805
806
0
      case '6':
807
0
      case '7':
808
0
      case '8':
809
0
      case '9':
810
0
        (*info->fprintf_func) (stream, "%%fcc%c", *s - '6' + '0');
811
0
        break;
812
813
0
      case 'z':
814
0
        (*info->fprintf_func) (stream, "%%icc");
815
0
        break;
816
817
0
      case 'Z':
818
0
        (*info->fprintf_func) (stream, "%%xcc");
819
0
        break;
820
821
0
      case 'E':
822
0
        (*info->fprintf_func) (stream, "%%ccr");
823
0
        break;
824
825
0
      case 's':
826
0
        (*info->fprintf_func) (stream, "%%fprs");
827
0
        break;
828
829
0
      case '{':
830
0
        (*info->fprintf_func) (stream, "%%mcdper");
831
0
        break;
832
833
0
                  case '&':
834
0
                    (*info->fprintf_func) (stream, "%%entropy");
835
0
                    break;
836
837
0
      case 'o':
838
0
        (*info->fprintf_func) (stream, "%%asi");
839
0
        break;
840
841
0
      case 'W':
842
0
        (*info->fprintf_func) (stream, "%%tick");
843
0
        break;
844
845
0
      case 'P':
846
0
        (*info->fprintf_func) (stream, "%%pc");
847
0
        break;
848
849
0
      case '?':
850
0
        if (X_RS1 (insn) == 31)
851
0
          (*info->fprintf_func) (stream, "%%ver");
852
0
        else if (X_RS1 (insn) == 23)
853
0
          (*info->fprintf_func) (stream, "%%pmcdper");
854
0
        else if ((unsigned) X_RS1 (insn) < 17)
855
0
          (*info->fprintf_func) (stream, "%%%s",
856
0
               v9_priv_reg_names[X_RS1 (insn)]);
857
0
        else
858
0
          (*info->fprintf_func) (stream, "%%reserved");
859
0
        break;
860
861
0
      case '!':
862
0
                    if (X_RD (insn) == 31)
863
0
                      (*info->fprintf_func) (stream, "%%ver");
864
0
        else if (X_RD (insn) == 23)
865
0
          (*info->fprintf_func) (stream, "%%pmcdper");
866
0
        else if ((unsigned) X_RD (insn) < 17)
867
0
          (*info->fprintf_func) (stream, "%%%s",
868
0
               v9_priv_reg_names[X_RD (insn)]);
869
0
        else
870
0
          (*info->fprintf_func) (stream, "%%reserved");
871
0
        break;
872
873
0
      case '$':
874
0
        if ((unsigned) X_RS1 (insn) < 32)
875
0
          (*info->fprintf_func) (stream, "%%%s",
876
0
               v9_hpriv_reg_names[X_RS1 (insn)]);
877
0
        else
878
0
          (*info->fprintf_func) (stream, "%%reserved");
879
0
        break;
880
881
0
      case '%':
882
0
        if ((unsigned) X_RD (insn) < 32)
883
0
          (*info->fprintf_func) (stream, "%%%s",
884
0
               v9_hpriv_reg_names[X_RD (insn)]);
885
0
        else
886
0
          (*info->fprintf_func) (stream, "%%reserved");
887
0
        break;
888
889
0
      case '/':
890
0
        if (X_RS1 (insn) < 16 || X_RS1 (insn) > 28)
891
0
          (*info->fprintf_func) (stream, "%%reserved");
892
0
        else
893
0
          (*info->fprintf_func) (stream, "%%%s",
894
0
               v9a_asr_reg_names[X_RS1 (insn)-16]);
895
0
        break;
896
897
0
      case '_':
898
0
        if (X_RD (insn) < 16 || X_RD (insn) > 28)
899
0
          (*info->fprintf_func) (stream, "%%reserved");
900
0
        else
901
0
          (*info->fprintf_func) (stream, "%%%s",
902
0
               v9a_asr_reg_names[X_RD (insn)-16]);
903
0
        break;
904
905
0
      case '*':
906
0
        {
907
0
          const char *name = sparc_decode_prefetch (X_RD (insn));
908
909
0
          if (name)
910
0
      (*info->fprintf_func) (stream, "%s", name);
911
0
          else
912
0
      (*info->fprintf_func) (stream, "%ld", X_RD (insn));
913
0
          break;
914
0
        }
915
916
0
      case 'M':
917
0
        (*info->fprintf_func) (stream, "%%asr%ld", X_RS1 (insn));
918
0
        break;
919
920
0
      case 'm':
921
0
        (*info->fprintf_func) (stream, "%%asr%ld", X_RD (insn));
922
0
        break;
923
924
0
      case 'L':
925
0
        info->target = memaddr + SEX (X_DISP30 (insn), 30) * 4;
926
0
        (*info->print_address_func) (info->target, info);
927
0
        break;
928
929
0
      case 'n':
930
0
        (*info->fprintf_func)
931
0
          (stream, "%#x", SEX (X_DISP22 (insn), 22));
932
0
        break;
933
934
0
      case 'l':
935
0
        info->target = memaddr + SEX (X_DISP22 (insn), 22) * 4;
936
0
        (*info->print_address_func) (info->target, info);
937
0
        break;
938
939
0
      case 'A':
940
0
        {
941
0
          const char *name = sparc_decode_asi (X_ASI (insn));
942
943
0
          if (name)
944
0
      (*info->fprintf_func) (stream, "%s", name);
945
0
          else
946
0
      (*info->fprintf_func) (stream, "(%ld)", X_ASI (insn));
947
0
          break;
948
0
        }
949
950
0
      case 'C':
951
0
        (*info->fprintf_func) (stream, "%%csr");
952
0
        break;
953
954
0
      case 'F':
955
0
        (*info->fprintf_func) (stream, "%%fsr");
956
0
        break;
957
958
0
      case '(':
959
0
        (*info->fprintf_func) (stream, "%%efsr");
960
0
        break;
961
962
0
      case 'p':
963
0
        (*info->fprintf_func) (stream, "%%psr");
964
0
        break;
965
966
0
      case 'q':
967
0
        (*info->fprintf_func) (stream, "%%fq");
968
0
        break;
969
970
0
      case 'Q':
971
0
        (*info->fprintf_func) (stream, "%%cq");
972
0
        break;
973
974
0
      case 't':
975
0
        (*info->fprintf_func) (stream, "%%tbr");
976
0
        break;
977
978
0
      case 'w':
979
0
        (*info->fprintf_func) (stream, "%%wim");
980
0
        break;
981
982
0
      case 'x':
983
0
        (*info->fprintf_func) (stream, "%ld",
984
0
             ((X_LDST_I (insn) << 8)
985
0
              + X_ASI (insn)));
986
0
        break;
987
988
0
                  case '|': /* 2-bit immediate  */
989
0
                    (*info->fprintf_func) (stream, "%ld", X_IMM2 (insn));
990
0
                    break;
991
992
0
      case 'y':
993
0
        (*info->fprintf_func) (stream, "%%y");
994
0
        break;
995
996
0
      case 'u':
997
0
      case 'U':
998
0
        {
999
0
          int val = *s == 'U' ? X_RS1 (insn) : X_RD (insn);
1000
0
          const char *name = sparc_decode_sparclet_cpreg (val);
1001
1002
0
          if (name)
1003
0
      (*info->fprintf_func) (stream, "%s", name);
1004
0
          else
1005
0
      (*info->fprintf_func) (stream, "%%cpreg(%d)", val);
1006
0
          break;
1007
0
        }
1008
0
      }
1009
0
        }
1010
0
    }
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
0
    if (imm_ored_to_rs1 || imm_added_to_rs1)
1019
0
      {
1020
0
        unsigned long prev_insn;
1021
0
        int errcode;
1022
1023
0
        if (memaddr >= 4)
1024
0
    errcode =
1025
0
      (*info->read_memory_func)
1026
0
      (memaddr - 4, buffer, sizeof (buffer), info);
1027
0
        else
1028
0
    errcode = 1;
1029
1030
0
        prev_insn = getword (buffer);
1031
1032
0
        if (errcode == 0)
1033
0
    {
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
0
      if (is_delayed_branch (prev_insn))
1043
0
        {
1044
0
          if (memaddr >= 8)
1045
0
      errcode = (*info->read_memory_func)
1046
0
        (memaddr - 8, buffer, sizeof (buffer), info);
1047
0
          else
1048
0
      errcode = 1;
1049
1050
0
          prev_insn = getword (buffer);
1051
0
        }
1052
0
    }
1053
1054
        /* If there was a problem reading memory, then assume
1055
     the previous instruction was not sethi.  */
1056
0
        if (errcode == 0)
1057
0
    {
1058
      /* Is it sethi to the same register?  */
1059
0
      if ((prev_insn & 0xc1c00000) == 0x01000000
1060
0
          && X_RD (prev_insn) == X_RS1 (insn))
1061
0
        {
1062
0
          (*info->fprintf_func) (stream, "\t! ");
1063
0
          info->target = (unsigned) X_IMM22 (prev_insn) << 10;
1064
0
          if (imm_added_to_rs1)
1065
0
      info->target += X_SIMM (insn, 13);
1066
0
          else
1067
0
      info->target |= X_SIMM (insn, 13);
1068
0
          (*info->print_address_func) (info->target, info);
1069
0
          info->insn_type = dis_dref;
1070
0
          info->data_size = 4;  /* FIXME!!! */
1071
0
        }
1072
0
    }
1073
0
      }
1074
1075
0
    if (opcode->flags & (F_UNBR|F_CONDBR|F_JSR))
1076
0
      {
1077
        /* FIXME -- check is_annulled flag.  */
1078
0
        (void) is_annulled;
1079
0
        if (opcode->flags & F_UNBR)
1080
0
    info->insn_type = dis_branch;
1081
0
        if (opcode->flags & F_CONDBR)
1082
0
    info->insn_type = dis_condbranch;
1083
0
        if (opcode->flags & F_JSR)
1084
0
    info->insn_type = dis_jsr;
1085
0
        if (opcode->flags & F_DELAYED)
1086
0
    info->branch_delay_insns = 1;
1087
0
      }
1088
1089
0
    return sizeof (buffer);
1090
0
  }
1091
0
    }
1092
1093
0
  info->insn_type = dis_noninsn;  /* Mark as non-valid instruction.  */
1094
0
  (*info->fprintf_func) (stream, _("unknown"));
1095
0
  return sizeof (buffer);
1096
0
}