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

Subversion Repositories open8_urisc

[/] [open8_urisc/] [trunk/] [gnu/] [binutils/] [opcodes/] [sparc-dis.c] - Blame information for rev 160

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

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

powered by: WebSVN 2.1.0

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