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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [insight/] [opcodes/] [sparc-dis.c] - Blame information for rev 1780

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

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

powered by: WebSVN 2.1.0

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