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

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [gnu-src/] [binutils-2.20.1/] [opcodes/] [sparc-dis.c] - Blame information for rev 252

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

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

powered by: WebSVN 2.1.0

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