OpenCores
URL https://opencores.org/ocsvn/scarts/scarts/trunk

Subversion Repositories scarts

[/] [scarts/] [trunk/] [toolchain/] [scarts-binutils/] [binutils-2.19.1/] [opcodes/] [sparc-dis.c] - Blame information for rev 7

Go to most recent revision | Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.