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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [gdb-5.3/] [opcodes/] [hppa-dis.c] - Blame information for rev 1777

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

Line No. Rev Author Line
1 1181 sfurman
/* Disassembler for the PA-RISC. Somewhat derived from sparc-pinsn.c.
2
   Copyright 1989, 1990, 1992, 1993, 1994, 1995, 1998, 1999, 2000, 2001
3
   Free Software Foundation, Inc.
4
 
5
   Contributed by the Center for Software Science at the
6
   University of Utah (pa-gdb-bugs@cs.utah.edu).
7
 
8
This program 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 2 of the License, or
11
(at your option) any later version.
12
 
13
This program is distributed in the hope that it will be useful,
14
but WITHOUT ANY WARRANTY; without even the implied warranty of
15
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
GNU General Public 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
21
 
22
#include "sysdep.h"
23
#include "dis-asm.h"
24
#include "libhppa.h"
25
#include "opcode/hppa.h"
26
 
27
/* Integer register names, indexed by the numbers which appear in the
28
   opcodes.  */
29
static const char *const reg_names[] =
30
 {"flags", "r1", "rp", "r3", "r4", "r5", "r6", "r7", "r8", "r9",
31
  "r10", "r11", "r12", "r13", "r14", "r15", "r16", "r17", "r18", "r19",
32
  "r20", "r21", "r22", "r23", "r24", "r25", "r26", "dp", "ret0", "ret1",
33
  "sp", "r31"};
34
 
35
/* Floating point register names, indexed by the numbers which appear in the
36
   opcodes.  */
37
static const char *const fp_reg_names[] =
38
 {"fpsr", "fpe2", "fpe4", "fpe6",
39
  "fr4", "fr5", "fr6", "fr7", "fr8",
40
  "fr9", "fr10", "fr11", "fr12", "fr13", "fr14", "fr15",
41
  "fr16", "fr17", "fr18", "fr19", "fr20", "fr21", "fr22", "fr23",
42
  "fr24", "fr25", "fr26", "fr27", "fr28", "fr29", "fr30", "fr31"};
43
 
44
typedef unsigned int CORE_ADDR;
45
 
46
/* Get at various relevent fields of an instruction word.  */
47
 
48
#define MASK_5 0x1f
49
#define MASK_10 0x3ff
50
#define MASK_11 0x7ff
51
#define MASK_14 0x3fff
52
#define MASK_16 0xffff
53
#define MASK_21 0x1fffff
54
 
55
/* These macros get bit fields using HP's numbering (MSB = 0) */
56
 
57
#define GET_FIELD(X, FROM, TO) \
58
  ((X) >> (31 - (TO)) & ((1 << ((TO) - (FROM) + 1)) - 1))
59
 
60
#define GET_BIT(X, WHICH) \
61
  GET_FIELD (X, WHICH, WHICH)
62
 
63
/* Some of these have been converted to 2-d arrays because they
64
   consume less storage this way.  If the maintenance becomes a
65
   problem, convert them back to const 1-d pointer arrays.  */
66
static const char *const control_reg[] = {
67
  "rctr", "cr1", "cr2", "cr3", "cr4", "cr5", "cr6", "cr7",
68
  "pidr1", "pidr2", "ccr", "sar", "pidr3", "pidr4",
69
  "iva", "eiem", "itmr", "pcsq", "pcoq", "iir", "isr",
70
  "ior", "ipsw", "eirr", "tr0", "tr1", "tr2", "tr3",
71
  "tr4", "tr5", "tr6", "tr7"
72
};
73
 
74
static const char *const compare_cond_names[] = {
75
  "", ",=", ",<", ",<=", ",<<", ",<<=", ",sv", ",od",
76
  ",tr", ",<>", ",>=", ",>", ",>>=", ",>>", ",nsv", ",ev"
77
};
78
static const char *const compare_cond_64_names[] = {
79
  "", ",*=", ",*<", ",*<=", ",*<<", ",*<<=", ",*sv", ",*od",
80
  ",*tr", ",*<>", ",*>=", ",*>", ",*>>=", ",*>>", ",*nsv", ",*ev"
81
};
82
static const char *const cmpib_cond_64_names[] = {
83
  ",*<<", ",*=", ",*<", ",*<=", ",*>>=", ",*<>", ",*>=", ",*>"
84
};
85
static const char *const add_cond_names[] = {
86
  "", ",=", ",<", ",<=", ",nuv", ",znv", ",sv", ",od",
87
  ",tr", ",<>", ",>=", ",>", ",uv", ",vnz", ",nsv", ",ev"
88
};
89
static const char *const add_cond_64_names[] = {
90
  "", ",*=", ",*<", ",*<=", ",*nuv", ",*znv", ",*sv", ",*od",
91
  ",*tr", ",*<>", ",*>=", ",*>", ",*uv", ",*vnz", ",*nsv", ",*ev"
92
};
93
static const char *const wide_add_cond_names[] = {
94
  "", ",=", ",<", ",<=", ",nuv", ",*=", ",*<", ",*<=",
95
  ",tr", ",<>", ",>=", ",>", ",uv", ",*<>", ",*>=", ",*>"
96
};
97
static const char *const logical_cond_names[] = {
98
  "", ",=", ",<", ",<=", 0, 0, 0, ",od",
99
  ",tr", ",<>", ",>=", ",>", 0, 0, 0, ",ev"};
100
static const char *const logical_cond_64_names[] = {
101
  "", ",*=", ",*<", ",*<=", 0, 0, 0, ",*od",
102
  ",*tr", ",*<>", ",*>=", ",*>", 0, 0, 0, ",*ev"};
103
static const char *const unit_cond_names[] = {
104
  "", ",swz", ",sbz", ",shz", ",sdc", ",swc", ",sbc", ",shc",
105
  ",tr", ",nwz", ",nbz", ",nhz", ",ndc", ",nwc", ",nbc", ",nhc"
106
};
107
static const char *const unit_cond_64_names[] = {
108
  "", ",*swz", ",*sbz", ",*shz", ",*sdc", ",*swc", ",*sbc", ",*shc",
109
  ",*tr", ",*nwz", ",*nbz", ",*nhz", ",*ndc", ",*nwc", ",*nbc", ",*nhc"
110
};
111
static const char *const shift_cond_names[] = {
112
  "", ",=", ",<", ",od", ",tr", ",<>", ",>=", ",ev"
113
};
114
static const char *const shift_cond_64_names[] = {
115
  "", ",*=", ",*<", ",*od", ",*tr", ",*<>", ",*>=", ",*ev"
116
};
117
static const char *const bb_cond_64_names[] = {
118
  ",*<", ",*>="
119
};
120
static const char *const index_compl_names[] = {"", ",m", ",s", ",sm"};
121
static const char *const short_ldst_compl_names[] = {"", ",ma", "", ",mb"};
122
static const char *const short_bytes_compl_names[] = {
123
  "", ",b,m", ",e", ",e,m"
124
};
125
static const char *const float_format_names[] = {",sgl", ",dbl", "", ",quad"};
126
static const char *const float_comp_names[] =
127
{
128
  ",false?", ",false", ",?", ",!<=>", ",=", ",=t", ",?=", ",!<>",
129
  ",!?>=", ",<", ",?<", ",!>=", ",!?>", ",<=", ",?<=", ",!>",
130
  ",!?<=", ",>", ",?>", ",!<=", ",!?<", ",>=", ",?>=", ",!<",
131
  ",!?=", ",<>", ",!=", ",!=t", ",!?", ",<=>", ",true?", ",true"
132
};
133
static const char *const signed_unsigned_names[] = {",u", ",s"};
134
static const char *const mix_half_names[] = {",l", ",r"};
135
static const char *const saturation_names[] = {",us", ",ss", 0, ""};
136
static const char *const read_write_names[] = {",r", ",w"};
137
static const char *const add_compl_names[] = { 0, "", ",l", ",tsv" };
138
 
139
/* For a bunch of different instructions form an index into a
140
   completer name table.  */
141
#define GET_COMPL(insn) (GET_FIELD (insn, 26, 26) | \
142
                         GET_FIELD (insn, 18, 18) << 1)
143
 
144
#define GET_COND(insn) (GET_FIELD ((insn), 16, 18) + \
145
                        (GET_FIELD ((insn), 19, 19) ? 8 : 0))
146
 
147
static void fput_reg PARAMS ((unsigned int, disassemble_info *));
148
static void fput_fp_reg PARAMS ((unsigned int, disassemble_info *));
149
static void fput_fp_reg_r PARAMS ((unsigned int, disassemble_info *));
150
static void fput_creg PARAMS ((unsigned int, disassemble_info *));
151
static void fput_const PARAMS ((unsigned int, disassemble_info *));
152
static int extract_3 PARAMS ((unsigned int));
153
static int extract_5_load PARAMS ((unsigned int));
154
static int extract_5_store PARAMS ((unsigned int));
155
static unsigned extract_5r_store PARAMS ((unsigned int));
156
static unsigned extract_5R_store PARAMS ((unsigned int));
157
static unsigned extract_10U_store PARAMS ((unsigned int));
158
static unsigned extract_5Q_store PARAMS ((unsigned int));
159
static int extract_11 PARAMS ((unsigned int));
160
static int extract_14 PARAMS ((unsigned int));
161
static int extract_16 PARAMS ((unsigned int));
162
static int extract_21 PARAMS ((unsigned int));
163
static int extract_12 PARAMS ((unsigned int));
164
static int extract_17 PARAMS ((unsigned int));
165
static int extract_22 PARAMS ((unsigned int));
166
 
167
/* Utility function to print registers.  Put these first, so gcc's function
168
   inlining can do its stuff.  */
169
 
170
#define fputs_filtered(STR,F)   (*info->fprintf_func) (info->stream, "%s", STR)
171
 
172
static void
173
fput_reg (reg, info)
174
     unsigned reg;
175
     disassemble_info *info;
176
{
177
  (*info->fprintf_func) (info->stream, reg ? reg_names[reg] : "r0");
178
}
179
 
180
static void
181
fput_fp_reg (reg, info)
182
     unsigned reg;
183
     disassemble_info *info;
184
{
185
  (*info->fprintf_func) (info->stream, reg ? fp_reg_names[reg] : "fr0");
186
}
187
 
188
static void
189
fput_fp_reg_r (reg, info)
190
     unsigned reg;
191
     disassemble_info *info;
192
{
193
  /* Special case floating point exception registers.  */
194
  if (reg < 4)
195
    (*info->fprintf_func) (info->stream, "fpe%d", reg * 2 + 1);
196
  else
197
    (*info->fprintf_func) (info->stream, "%sR", reg ? fp_reg_names[reg]
198
                                                    : "fr0");
199
}
200
 
201
static void
202
fput_creg (reg, info)
203
     unsigned reg;
204
     disassemble_info *info;
205
{
206
  (*info->fprintf_func) (info->stream, control_reg[reg]);
207
}
208
 
209
/* Print constants with sign.  */
210
 
211
static void
212
fput_const (num, info)
213
     unsigned num;
214
     disassemble_info *info;
215
{
216
  if ((int)num < 0)
217
    (*info->fprintf_func) (info->stream, "-%x", -(int)num);
218
  else
219
    (*info->fprintf_func) (info->stream, "%x", num);
220
}
221
 
222
/* Routines to extract various sized constants out of hppa
223
   instructions.  */
224
 
225
/* Extract a 3-bit space register number from a be, ble, mtsp or mfsp.  */
226
static int
227
extract_3 (word)
228
     unsigned word;
229
{
230
  return GET_FIELD (word, 18, 18) << 2 | GET_FIELD (word, 16, 17);
231
}
232
 
233
static int
234
extract_5_load (word)
235
     unsigned word;
236
{
237
  return low_sign_extend (word >> 16 & MASK_5, 5);
238
}
239
 
240
/* Extract the immediate field from a st{bhw}s instruction.  */
241
static int
242
extract_5_store (word)
243
     unsigned word;
244
{
245
  return low_sign_extend (word & MASK_5, 5);
246
}
247
 
248
/* Extract the immediate field from a break instruction.  */
249
static unsigned
250
extract_5r_store (word)
251
     unsigned word;
252
{
253
  return (word & MASK_5);
254
}
255
 
256
/* Extract the immediate field from a {sr}sm instruction.  */
257
static unsigned
258
extract_5R_store (word)
259
     unsigned word;
260
{
261
  return (word >> 16 & MASK_5);
262
}
263
 
264
/* Extract the 10 bit immediate field from a {sr}sm instruction.  */
265
static unsigned
266
extract_10U_store (word)
267
     unsigned word;
268
{
269
  return (word >> 16 & MASK_10);
270
}
271
 
272
/* Extract the immediate field from a bb instruction.  */
273
static unsigned
274
extract_5Q_store (word)
275
     unsigned word;
276
{
277
  return (word >> 21 & MASK_5);
278
}
279
 
280
/* Extract an 11 bit immediate field.  */
281
static int
282
extract_11 (word)
283
     unsigned word;
284
{
285
  return low_sign_extend (word & MASK_11, 11);
286
}
287
 
288
/* Extract a 14 bit immediate field.  */
289
static int
290
extract_14 (word)
291
     unsigned word;
292
{
293
  return low_sign_extend (word & MASK_14, 14);
294
}
295
 
296
/* Extract a 16 bit immediate field (PA2.0 wide only).  */
297
static int
298
extract_16 (word)
299
     unsigned word;
300
{
301
  int m15, m0, m1;
302
  m0 = GET_BIT (word, 16);
303
  m1 = GET_BIT (word, 17);
304
  m15 = GET_BIT (word, 31);
305
  word = (word >> 1) & 0x1fff;
306
  word = word | (m15 << 15) | ((m15 ^ m0) << 14) | ((m15 ^ m1) << 13);
307
  return sign_extend (word, 16);
308
}
309
 
310
/* Extract a 21 bit constant.  */
311
 
312
static int
313
extract_21 (word)
314
     unsigned word;
315
{
316
  int val;
317
 
318
  word &= MASK_21;
319
  word <<= 11;
320
  val = GET_FIELD (word, 20, 20);
321
  val <<= 11;
322
  val |= GET_FIELD (word, 9, 19);
323
  val <<= 2;
324
  val |= GET_FIELD (word, 5, 6);
325
  val <<= 5;
326
  val |= GET_FIELD (word, 0, 4);
327
  val <<= 2;
328
  val |= GET_FIELD (word, 7, 8);
329
  return sign_extend (val, 21) << 11;
330
}
331
 
332
/* Extract a 12 bit constant from branch instructions.  */
333
 
334
static int
335
extract_12 (word)
336
     unsigned word;
337
{
338
  return sign_extend (GET_FIELD (word, 19, 28) |
339
                      GET_FIELD (word, 29, 29) << 10 |
340
                      (word & 0x1) << 11, 12) << 2;
341
}
342
 
343
/* Extract a 17 bit constant from branch instructions, returning the
344
   19 bit signed value.  */
345
 
346
static int
347
extract_17 (word)
348
     unsigned word;
349
{
350
  return sign_extend (GET_FIELD (word, 19, 28) |
351
                      GET_FIELD (word, 29, 29) << 10 |
352
                      GET_FIELD (word, 11, 15) << 11 |
353
                      (word & 0x1) << 16, 17) << 2;
354
}
355
 
356
static int
357
extract_22 (word)
358
     unsigned word;
359
{
360
  return sign_extend (GET_FIELD (word, 19, 28) |
361
                      GET_FIELD (word, 29, 29) << 10 |
362
                      GET_FIELD (word, 11, 15) << 11 |
363
                      GET_FIELD (word, 6, 10) << 16 |
364
                      (word & 0x1) << 21, 22) << 2;
365
}
366
 
367
/* Print one instruction.  */
368
int
369
print_insn_hppa (memaddr, info)
370
     bfd_vma memaddr;
371
     disassemble_info *info;
372
{
373
  bfd_byte buffer[4];
374
  unsigned int insn, i;
375
 
376
  {
377
    int status =
378
      (*info->read_memory_func) (memaddr, buffer, sizeof (buffer), info);
379
    if (status != 0)
380
      {
381
        (*info->memory_error_func) (status, memaddr, info);
382
        return -1;
383
      }
384
  }
385
 
386
  insn = bfd_getb32 (buffer);
387
 
388
  for (i = 0; i < NUMOPCODES; ++i)
389
    {
390
      const struct pa_opcode *opcode = &pa_opcodes[i];
391
      if ((insn & opcode->mask) == opcode->match)
392
        {
393
          register const char *s;
394
#ifndef BFD64
395
          if (opcode->arch == pa20w)
396
            continue;
397
#endif
398
          (*info->fprintf_func) (info->stream, "%s", opcode->name);
399
 
400
          if (!strchr ("cfCY?-+nHNZFIuv", opcode->args[0]))
401
            (*info->fprintf_func) (info->stream, " ");
402
          for (s = opcode->args; *s != '\0'; ++s)
403
            {
404
              switch (*s)
405
                {
406
                case 'x':
407
                  fput_reg (GET_FIELD (insn, 11, 15), info);
408
                  break;
409
                case 'a':
410
                case 'b':
411
                  fput_reg (GET_FIELD (insn, 6, 10), info);
412
                  break;
413
                case '^':
414
                  fput_creg (GET_FIELD (insn, 6, 10), info);
415
                  break;
416
                case 't':
417
                  fput_reg (GET_FIELD (insn, 27, 31), info);
418
                  break;
419
 
420
                /* Handle floating point registers.  */
421
                case 'f':
422
                  switch (*++s)
423
                    {
424
                    case 't':
425
                      fput_fp_reg (GET_FIELD (insn, 27, 31), info);
426
                      break;
427
                    case 'T':
428
                      if (GET_FIELD (insn, 25, 25))
429
                        fput_fp_reg_r (GET_FIELD (insn, 27, 31), info);
430
                      else
431
                        fput_fp_reg (GET_FIELD (insn, 27, 31), info);
432
                      break;
433
                    case 'a':
434
                      if (GET_FIELD (insn, 25, 25))
435
                        fput_fp_reg_r (GET_FIELD (insn, 6, 10), info);
436
                      else
437
                        fput_fp_reg (GET_FIELD (insn, 6, 10), info);
438
                      break;
439
 
440
                    /* 'fA' will not generate a space before the regsiter
441
                        name.  Normally that is fine.  Except that it
442
                        causes problems with xmpyu which has no FP format
443
                        completer.  */
444
                    case 'X':
445
                      fputs_filtered (" ", info);
446
 
447
                    /* FALLTHRU */
448
 
449
                    case 'A':
450
                      if (GET_FIELD (insn, 24, 24))
451
                        fput_fp_reg_r (GET_FIELD (insn, 6, 10), info);
452
                      else
453
                        fput_fp_reg (GET_FIELD (insn, 6, 10), info);
454
 
455
                      break;
456
                    case 'b':
457
                      if (GET_FIELD (insn, 25, 25))
458
                        fput_fp_reg_r (GET_FIELD (insn, 11, 15), info);
459
                      else
460
                        fput_fp_reg (GET_FIELD (insn, 11, 15), info);
461
                      break;
462
                    case 'B':
463
                      if (GET_FIELD (insn, 19, 19))
464
                        fput_fp_reg_r (GET_FIELD (insn, 11, 15), info);
465
                      else
466
                        fput_fp_reg (GET_FIELD (insn, 11, 15), info);
467
                      break;
468
                    case 'C':
469
                      {
470
                        int reg = GET_FIELD (insn, 21, 22);
471
                        reg |= GET_FIELD (insn, 16, 18) << 2;
472
                        if (GET_FIELD (insn, 23, 23) != 0)
473
                          fput_fp_reg_r (reg, info);
474
                        else
475
                          fput_fp_reg (reg, info);
476
                        break;
477
                      }
478
                    case 'i':
479
                      {
480
                        int reg = GET_FIELD (insn, 6, 10);
481
 
482
                        reg |= (GET_FIELD (insn, 26, 26) << 4);
483
                        fput_fp_reg (reg, info);
484
                        break;
485
                      }
486
                    case 'j':
487
                      {
488
                        int reg = GET_FIELD (insn, 11, 15);
489
 
490
                        reg |= (GET_FIELD (insn, 26, 26) << 4);
491
                        fput_fp_reg (reg, info);
492
                        break;
493
                      }
494
                    case 'k':
495
                      {
496
                        int reg = GET_FIELD (insn, 27, 31);
497
 
498
                        reg |= (GET_FIELD (insn, 26, 26) << 4);
499
                        fput_fp_reg (reg, info);
500
                        break;
501
                      }
502
                    case 'l':
503
                      {
504
                        int reg = GET_FIELD (insn, 21, 25);
505
 
506
                        reg |= (GET_FIELD (insn, 26, 26) << 4);
507
                        fput_fp_reg (reg, info);
508
                        break;
509
                      }
510
                    case 'm':
511
                      {
512
                        int reg = GET_FIELD (insn, 16, 20);
513
 
514
                        reg |= (GET_FIELD (insn, 26, 26) << 4);
515
                        fput_fp_reg (reg, info);
516
                        break;
517
                      }
518
 
519
                    /* 'fe' will not generate a space before the register
520
                        name.  Normally that is fine.  Except that it
521
                        causes problems with fstw fe,y(b) which has no FP
522
                        format completer.  */
523
                    case 'E':
524
                      fputs_filtered (" ", info);
525
 
526
                    /* FALLTHRU */
527
 
528
                    case 'e':
529
                      if (GET_FIELD (insn, 30, 30))
530
                        fput_fp_reg_r (GET_FIELD (insn, 11, 15), info);
531
                      else
532
                        fput_fp_reg (GET_FIELD (insn, 11, 15), info);
533
                      break;
534
                    case 'x':
535
                      fput_fp_reg (GET_FIELD (insn, 11, 15), info);
536
                      break;
537
                    }
538
                  break;
539
 
540
                case '5':
541
                  fput_const (extract_5_load (insn), info);
542
                  break;
543
                case 's':
544
                  (*info->fprintf_func) (info->stream,
545
                                         "sr%d", GET_FIELD (insn, 16, 17));
546
                  break;
547
 
548
                case 'S':
549
                  (*info->fprintf_func) (info->stream, "sr%d", extract_3 (insn));
550
                  break;
551
 
552
                /* Handle completers.  */
553
                case 'c':
554
                  switch (*++s)
555
                    {
556
                    case 'x':
557
                      (*info->fprintf_func) (info->stream, "%s",
558
                                             index_compl_names[GET_COMPL (insn)]);
559
                      break;
560
                    case 'X':
561
                      (*info->fprintf_func) (info->stream, "%s ",
562
                                             index_compl_names[GET_COMPL (insn)]);
563
                      break;
564
                    case 'm':
565
                      (*info->fprintf_func) (info->stream, "%s",
566
                                             short_ldst_compl_names[GET_COMPL (insn)]);
567
                      break;
568
                    case 'M':
569
                      (*info->fprintf_func) (info->stream, "%s ",
570
                                             short_ldst_compl_names[GET_COMPL (insn)]);
571
                      break;
572
                    case 'A':
573
                      (*info->fprintf_func) (info->stream, "%s ",
574
                                             short_bytes_compl_names[GET_COMPL (insn)]);
575
                      break;
576
                    case 's':
577
                      (*info->fprintf_func) (info->stream, "%s",
578
                                             short_bytes_compl_names[GET_COMPL (insn)]);
579
                      break;
580
                    case 'c':
581
                    case 'C':
582
                      switch (GET_FIELD (insn, 20, 21))
583
                        {
584
                        case 1:
585
                          (*info->fprintf_func) (info->stream, ",bc ");
586
                          break;
587
                        case 2:
588
                          (*info->fprintf_func) (info->stream, ",sl ");
589
                          break;
590
                        default:
591
                          (*info->fprintf_func) (info->stream, " ");
592
                        }
593
                      break;
594
                    case 'd':
595
                      switch (GET_FIELD (insn, 20, 21))
596
                        {
597
                        case 1:
598
                          (*info->fprintf_func) (info->stream, ",co ");
599
                          break;
600
                        default:
601
                          (*info->fprintf_func) (info->stream, " ");
602
                        }
603
                      break;
604
                    case 'o':
605
                      (*info->fprintf_func) (info->stream, ",o");
606
                      break;
607
                    case 'g':
608
                      (*info->fprintf_func) (info->stream, ",gate");
609
                      break;
610
                    case 'p':
611
                      (*info->fprintf_func) (info->stream, ",l,push");
612
                      break;
613
                    case 'P':
614
                      (*info->fprintf_func) (info->stream, ",pop");
615
                      break;
616
                    case 'l':
617
                    case 'L':
618
                      (*info->fprintf_func) (info->stream, ",l");
619
                      break;
620
                    case 'w':
621
                      (*info->fprintf_func) (info->stream, "%s ",
622
                                             read_write_names[GET_FIELD (insn, 25, 25)]);
623
                      break;
624
                    case 'W':
625
                      (*info->fprintf_func) (info->stream, ",w");
626
                      break;
627
                    case 'r':
628
                      if (GET_FIELD (insn, 23, 26) == 5)
629
                        (*info->fprintf_func) (info->stream, ",r");
630
                      break;
631
                    case 'Z':
632
                      if (GET_FIELD (insn, 26, 26))
633
                        (*info->fprintf_func) (info->stream, ",m ");
634
                      else
635
                        (*info->fprintf_func) (info->stream, " ");
636
                      break;
637
                    case 'i':
638
                      if (GET_FIELD (insn, 25, 25))
639
                        (*info->fprintf_func) (info->stream, ",i");
640
                      break;
641
                    case 'z':
642
                      if (!GET_FIELD (insn, 21, 21))
643
                        (*info->fprintf_func) (info->stream, ",z");
644
                      break;
645
                    case 'a':
646
                      (*info->fprintf_func)
647
                        (info->stream, "%s", add_compl_names[GET_FIELD
648
                                                            (insn, 20, 21)]);
649
                      break;
650
                    case 'Y':
651
                      (*info->fprintf_func)
652
                        (info->stream, ",dc%s", add_compl_names[GET_FIELD
653
                                                               (insn, 20, 21)]);
654
                      break;
655
                    case 'y':
656
                      (*info->fprintf_func)
657
                        (info->stream, ",c%s", add_compl_names[GET_FIELD
658
                                                              (insn, 20, 21)]);
659
                      break;
660
                    case 'v':
661
                      if (GET_FIELD (insn, 20, 20))
662
                        (*info->fprintf_func) (info->stream, ",tsv");
663
                      break;
664
                    case 't':
665
                      (*info->fprintf_func) (info->stream, ",tc");
666
                      if (GET_FIELD (insn, 20, 20))
667
                        (*info->fprintf_func) (info->stream, ",tsv");
668
                      break;
669
                    case 'B':
670
                      (*info->fprintf_func) (info->stream, ",db");
671
                      if (GET_FIELD (insn, 20, 20))
672
                        (*info->fprintf_func) (info->stream, ",tsv");
673
                      break;
674
                    case 'b':
675
                      (*info->fprintf_func) (info->stream, ",b");
676
                      if (GET_FIELD (insn, 20, 20))
677
                        (*info->fprintf_func) (info->stream, ",tsv");
678
                      break;
679
                    case 'T':
680
                      if (GET_FIELD (insn, 25, 25))
681
                        (*info->fprintf_func) (info->stream, ",tc");
682
                      break;
683
                    case 'S':
684
                      /* EXTRD/W has a following condition.  */
685
                      if (*(s + 1) == '?')
686
                        (*info->fprintf_func)
687
                          (info->stream, "%s", signed_unsigned_names[GET_FIELD
688
                                                                    (insn, 21, 21)]);
689
                      else
690
                        (*info->fprintf_func)
691
                          (info->stream, "%s ", signed_unsigned_names[GET_FIELD
692
                                                                     (insn, 21, 21)]);
693
                      break;
694
                    case 'h':
695
                      (*info->fprintf_func)
696
                          (info->stream, "%s", mix_half_names[GET_FIELD
697
                                                             (insn, 17, 17)]);
698
                      break;
699
                    case 'H':
700
                      (*info->fprintf_func)
701
                          (info->stream, "%s ", saturation_names[GET_FIELD
702
                                                               (insn, 24, 25)]);
703
                      break;
704
                    case '*':
705
                      (*info->fprintf_func)
706
                          (info->stream, ",%d%d%d%d ",
707
                           GET_FIELD (insn, 17, 18), GET_FIELD (insn, 20, 21),
708
                           GET_FIELD (insn, 22, 23), GET_FIELD (insn, 24, 25));
709
                      break;
710
 
711
                    case 'q':
712
                      {
713
                        int m, a;
714
 
715
                        m = GET_FIELD (insn, 28, 28);
716
                        a = GET_FIELD (insn, 29, 29);
717
 
718
                        if (m && !a)
719
                          fputs_filtered (",ma ", info);
720
                        else if (m && a)
721
                          fputs_filtered (",mb ", info);
722
                        else
723
                          fputs_filtered (" ", info);
724
                        break;
725
                      }
726
 
727
                    case 'J':
728
                      {
729
                        int opc = GET_FIELD (insn, 0, 5);
730
 
731
                        if (opc == 0x16 || opc == 0x1e)
732
                          {
733
                            if (GET_FIELD (insn, 29, 29) == 0)
734
                              fputs_filtered (",ma ", info);
735
                            else
736
                              fputs_filtered (",mb ", info);
737
                          }
738
                        else
739
                          fputs_filtered (" ", info);
740
                        break;
741
                      }
742
 
743
                    case 'e':
744
                      {
745
                        int opc = GET_FIELD (insn, 0, 5);
746
 
747
                        if (opc == 0x13 || opc == 0x1b)
748
                          {
749
                            if (GET_FIELD (insn, 18, 18) == 1)
750
                              fputs_filtered (",mb ", info);
751
                            else
752
                              fputs_filtered (",ma ", info);
753
                          }
754
                        else if (opc == 0x17 || opc == 0x1f)
755
                          {
756
                            if (GET_FIELD (insn, 31, 31) == 1)
757
                              fputs_filtered (",ma ", info);
758
                            else
759
                              fputs_filtered (",mb ", info);
760
                          }
761
                        else
762
                          fputs_filtered (" ", info);
763
 
764
                        break;
765
                      }
766
                    }
767
                  break;
768
 
769
                /* Handle conditions.  */
770
                case '?':
771
                  {
772
                    s++;
773
                    switch (*s)
774
                      {
775
                      case 'f':
776
                        (*info->fprintf_func) (info->stream, "%s ",
777
                                               float_comp_names[GET_FIELD
778
                                                               (insn, 27, 31)]);
779
                        break;
780
 
781
                      /* these four conditions are for the set of instructions
782
                           which distinguish true/false conditions by opcode
783
                           rather than by the 'f' bit (sigh): comb, comib,
784
                           addb, addib */
785
                      case 't':
786
                        fputs_filtered (compare_cond_names[GET_FIELD (insn, 16, 18)],
787
                                        info);
788
                        break;
789
                      case 'n':
790
                        fputs_filtered (compare_cond_names[GET_FIELD (insn, 16, 18)
791
                                        + GET_FIELD (insn, 4, 4) * 8], info);
792
                        break;
793
                      case 'N':
794
                        fputs_filtered (compare_cond_64_names[GET_FIELD (insn, 16, 18)
795
                                        + GET_FIELD (insn, 2, 2) * 8], info);
796
                        break;
797
                      case 'Q':
798
                        fputs_filtered (cmpib_cond_64_names[GET_FIELD (insn, 16, 18)],
799
                                        info);
800
                        break;
801
                      case '@':
802
                        fputs_filtered (add_cond_names[GET_FIELD (insn, 16, 18)
803
                                        + GET_FIELD (insn, 4, 4) * 8], info);
804
                        break;
805
                      case 's':
806
                        (*info->fprintf_func) (info->stream, "%s ",
807
                                               compare_cond_names[GET_COND (insn)]);
808
                        break;
809
                      case 'S':
810
                        (*info->fprintf_func) (info->stream, "%s ",
811
                                               compare_cond_64_names[GET_COND (insn)]);
812
                        break;
813
                      case 'a':
814
                        (*info->fprintf_func) (info->stream, "%s ",
815
                                               add_cond_names[GET_COND (insn)]);
816
                        break;
817
                      case 'A':
818
                        (*info->fprintf_func) (info->stream, "%s ",
819
                                               add_cond_64_names[GET_COND (insn)]);
820
                        break;
821
                      case 'd':
822
                        (*info->fprintf_func) (info->stream, "%s",
823
                                               add_cond_names[GET_FIELD (insn, 16, 18)]);
824
                        break;
825
 
826
                      case 'W':
827
                        (*info->fprintf_func)
828
                          (info->stream, "%s",
829
                           wide_add_cond_names[GET_FIELD (insn, 16, 18) +
830
                                              GET_FIELD (insn, 4, 4) * 8]);
831
                        break;
832
 
833
                      case 'l':
834
                        (*info->fprintf_func) (info->stream, "%s ",
835
                                               logical_cond_names[GET_COND (insn)]);
836
                        break;
837
                      case 'L':
838
                        (*info->fprintf_func) (info->stream, "%s ",
839
                                               logical_cond_64_names[GET_COND (insn)]);
840
                        break;
841
                      case 'u':
842
                        (*info->fprintf_func) (info->stream, "%s ",
843
                                               unit_cond_names[GET_COND (insn)]);
844
                        break;
845
                      case 'U':
846
                        (*info->fprintf_func) (info->stream, "%s ",
847
                                               unit_cond_64_names[GET_COND (insn)]);
848
                        break;
849
                      case 'y':
850
                      case 'x':
851
                      case 'b':
852
                        (*info->fprintf_func)
853
                          (info->stream, "%s",
854
                           shift_cond_names[GET_FIELD (insn, 16, 18)]);
855
 
856
                        /* If the next character in args is 'n', it will handle
857
                           putting out the space.  */
858
                        if (s[1] != 'n')
859
                          (*info->fprintf_func) (info->stream, " ");
860
                        break;
861
                      case 'X':
862
                        (*info->fprintf_func) (info->stream, "%s ",
863
                                               shift_cond_64_names[GET_FIELD (insn, 16, 18)]);
864
                        break;
865
                      case 'B':
866
                        (*info->fprintf_func)
867
                          (info->stream, "%s",
868
                           bb_cond_64_names[GET_FIELD (insn, 16, 16)]);
869
 
870
                        /* If the next character in args is 'n', it will handle
871
                           putting out the space.  */
872
                        if (s[1] != 'n')
873
                          (*info->fprintf_func) (info->stream, " ");
874
                        break;
875
                      }
876
                    break;
877
                  }
878
 
879
                case 'V':
880
                  fput_const (extract_5_store (insn), info);
881
                  break;
882
                case 'r':
883
                  fput_const (extract_5r_store (insn), info);
884
                  break;
885
                case 'R':
886
                  fput_const (extract_5R_store (insn), info);
887
                  break;
888
                case 'U':
889
                  fput_const (extract_10U_store (insn), info);
890
                  break;
891
                case 'B':
892
                case 'Q':
893
                  fput_const (extract_5Q_store (insn), info);
894
                  break;
895
                case 'i':
896
                  fput_const (extract_11 (insn), info);
897
                  break;
898
                case 'j':
899
                  fput_const (extract_14 (insn), info);
900
                  break;
901
                case 'k':
902
                  fput_const (extract_21 (insn), info);
903
                  break;
904
                case '<':
905
                case 'l':
906
                  /* 16-bit long disp., PA2.0 wide only.  */
907
                  fput_const (extract_16 (insn), info);
908
                  break;
909
                case 'n':
910
                  if (insn & 0x2)
911
                    (*info->fprintf_func) (info->stream, ",n ");
912
                  else
913
                    (*info->fprintf_func) (info->stream, " ");
914
                  break;
915
                case 'N':
916
                  if ((insn & 0x20) && s[1])
917
                    (*info->fprintf_func) (info->stream, ",n ");
918
                  else if (insn & 0x20)
919
                    (*info->fprintf_func) (info->stream, ",n");
920
                  else if (s[1])
921
                    (*info->fprintf_func) (info->stream, " ");
922
                  break;
923
                case 'w':
924
                  (*info->print_address_func) (memaddr + 8 + extract_12 (insn),
925
                                               info);
926
                  break;
927
                case 'W':
928
                  /* 17 bit PC-relative branch.  */
929
                  (*info->print_address_func) ((memaddr + 8
930
                                                + extract_17 (insn)),
931
                                               info);
932
                  break;
933
                case 'z':
934
                  /* 17 bit displacement.  This is an offset from a register
935
                     so it gets disasssembled as just a number, not any sort
936
                     of address.  */
937
                  fput_const (extract_17 (insn), info);
938
                  break;
939
 
940
                case 'Z':
941
                  /* addil %r1 implicit output.  */
942
                  (*info->fprintf_func) (info->stream, "%%r1");
943
                  break;
944
 
945
                case 'Y':
946
                  /* be,l %sr0,%r31 implicit output.  */
947
                  (*info->fprintf_func) (info->stream, "%%sr0,%%r31");
948
                  break;
949
 
950
                case '@':
951
                  (*info->fprintf_func) (info->stream, "0");
952
                  break;
953
 
954
                case '.':
955
                  (*info->fprintf_func) (info->stream, "%d",
956
                                    GET_FIELD (insn, 24, 25));
957
                  break;
958
                case '*':
959
                  (*info->fprintf_func) (info->stream, "%d",
960
                                    GET_FIELD (insn, 22, 25));
961
                  break;
962
                case '!':
963
                  (*info->fprintf_func) (info->stream, "%%sar");
964
                  break;
965
                case 'p':
966
                  (*info->fprintf_func) (info->stream, "%d",
967
                                    31 - GET_FIELD (insn, 22, 26));
968
                  break;
969
                case '~':
970
                  {
971
                    int num;
972
                    num = GET_FIELD (insn, 20, 20) << 5;
973
                    num |= GET_FIELD (insn, 22, 26);
974
                    (*info->fprintf_func) (info->stream, "%d", 63 - num);
975
                    break;
976
                  }
977
                case 'P':
978
                  (*info->fprintf_func) (info->stream, "%d",
979
                                    GET_FIELD (insn, 22, 26));
980
                  break;
981
                case 'q':
982
                  {
983
                    int num;
984
                    num = GET_FIELD (insn, 20, 20) << 5;
985
                    num |= GET_FIELD (insn, 22, 26);
986
                    (*info->fprintf_func) (info->stream, "%d", num);
987
                    break;
988
                  }
989
                case 'T':
990
                  (*info->fprintf_func) (info->stream, "%d",
991
                                    32 - GET_FIELD (insn, 27, 31));
992
                  break;
993
                case '%':
994
                  {
995
                    int num;
996
                    num = (GET_FIELD (insn, 23, 23) + 1) * 32;
997
                    num -= GET_FIELD (insn, 27, 31);
998
                    (*info->fprintf_func) (info->stream, "%d", num);
999
                    break;
1000
                  }
1001
                case '|':
1002
                  {
1003
                    int num;
1004
                    num = (GET_FIELD (insn, 19, 19) + 1) * 32;
1005
                    num -= GET_FIELD (insn, 27, 31);
1006
                    (*info->fprintf_func) (info->stream, "%d", num);
1007
                    break;
1008
                  }
1009
                case '$':
1010
                  fput_const (GET_FIELD (insn, 20, 28), info);
1011
                  break;
1012
                case 'A':
1013
                  fput_const (GET_FIELD (insn, 6, 18), info);
1014
                  break;
1015
                case 'D':
1016
                  fput_const (GET_FIELD (insn, 6, 31), info);
1017
                  break;
1018
                case 'v':
1019
                  (*info->fprintf_func) (info->stream, ",%d", GET_FIELD (insn, 23, 25));
1020
                  break;
1021
                case 'O':
1022
                  fput_const ((GET_FIELD (insn, 6,20) << 5 |
1023
                               GET_FIELD (insn, 27, 31)), info);
1024
                  break;
1025
                case 'o':
1026
                  fput_const (GET_FIELD (insn, 6, 20), info);
1027
                  break;
1028
                case '2':
1029
                  fput_const ((GET_FIELD (insn, 6, 22) << 5 |
1030
                               GET_FIELD (insn, 27, 31)), info);
1031
                  break;
1032
                case '1':
1033
                  fput_const ((GET_FIELD (insn, 11, 20) << 5 |
1034
                               GET_FIELD (insn, 27, 31)), info);
1035
                  break;
1036
                case '0':
1037
                  fput_const ((GET_FIELD (insn, 16, 20) << 5 |
1038
                               GET_FIELD (insn, 27, 31)), info);
1039
                  break;
1040
                case 'u':
1041
                  (*info->fprintf_func) (info->stream, ",%d", GET_FIELD (insn, 23, 25));
1042
                  break;
1043
                case 'F':
1044
                  /* if no destination completer and not before a completer
1045
                     for fcmp, need a space here */
1046
                  if (s[1] == 'G' || s[1] == '?')
1047
                    fputs_filtered (float_format_names[GET_FIELD (insn, 19, 20)],
1048
                                    info);
1049
                  else
1050
                    (*info->fprintf_func) (info->stream, "%s ",
1051
                                           float_format_names[GET_FIELD
1052
                                                              (insn, 19, 20)]);
1053
                  break;
1054
                case 'G':
1055
                  (*info->fprintf_func) (info->stream, "%s ",
1056
                                    float_format_names[GET_FIELD (insn,
1057
                                                                  17, 18)]);
1058
                  break;
1059
                case 'H':
1060
                  if (GET_FIELD (insn, 26, 26) == 1)
1061
                    (*info->fprintf_func) (info->stream, "%s ",
1062
                                    float_format_names[0]);
1063
                  else
1064
                    (*info->fprintf_func) (info->stream, "%s ",
1065
                                    float_format_names[1]);
1066
                  break;
1067
                case 'I':
1068
                  /* if no destination completer and not before a completer
1069
                     for fcmp, need a space here */
1070
                  if (s[1] == '?')
1071
                    fputs_filtered (float_format_names[GET_FIELD (insn, 20, 20)],
1072
                                    info);
1073
                  else
1074
                    (*info->fprintf_func) (info->stream, "%s ",
1075
                                           float_format_names[GET_FIELD
1076
                                                              (insn, 20, 20)]);
1077
                  break;
1078
 
1079
                case 'J':
1080
                  fput_const (extract_14 (insn), info);
1081
                  break;
1082
 
1083
                case '#':
1084
                  {
1085
                    int sign = GET_FIELD (insn, 31, 31);
1086
                    int imm10 = GET_FIELD (insn, 18, 27);
1087
                    int disp;
1088
 
1089
                    if (sign)
1090
                      disp = (-1 << 10) | imm10;
1091
                    else
1092
                      disp = imm10;
1093
 
1094
                    disp <<= 3;
1095
                    fput_const (disp, info);
1096
                    break;
1097
                  }
1098
                case 'K':
1099
                case 'd':
1100
                  {
1101
                    int sign = GET_FIELD (insn, 31, 31);
1102
                    int imm11 = GET_FIELD (insn, 18, 28);
1103
                    int disp;
1104
 
1105
                    if (sign)
1106
                      disp = (-1 << 11) | imm11;
1107
                    else
1108
                      disp = imm11;
1109
 
1110
                    disp <<= 2;
1111
                    fput_const (disp, info);
1112
                    break;
1113
                  }
1114
 
1115
                case '>':
1116
                case 'y':
1117
                  {
1118
                    /* 16-bit long disp., PA2.0 wide only.  */
1119
                    int disp = extract_16 (insn);
1120
                    disp &= ~3;
1121
                    fput_const (disp, info);
1122
                    break;
1123
                  }
1124
 
1125
                case '&':
1126
                  {
1127
                    /* 16-bit long disp., PA2.0 wide only.  */
1128
                    int disp = extract_16 (insn);
1129
                    disp &= ~7;
1130
                    fput_const (disp, info);
1131
                    break;
1132
                  }
1133
 
1134
                /* ?!? FIXME */
1135
                case '_':
1136
                case '{':
1137
                  fputs_filtered ("Disassembler botch.\n", info);
1138
                  break;
1139
 
1140
                case 'm':
1141
                  {
1142
                    int y = GET_FIELD (insn, 16, 18);
1143
 
1144
                    if (y != 1)
1145
                      fput_const ((y ^ 1) - 1, info);
1146
                  }
1147
                  break;
1148
 
1149
                case 'h':
1150
                  {
1151
                    int cbit;
1152
 
1153
                    cbit = GET_FIELD (insn, 16, 18);
1154
 
1155
                    if (cbit > 0)
1156
                      (*info->fprintf_func) (info->stream, ",%d", cbit - 1);
1157
                    break;
1158
                  }
1159
 
1160
                case '=':
1161
                  {
1162
                    int cond = GET_FIELD (insn, 27, 31);
1163
 
1164
                    if (cond == 0)
1165
                      fputs_filtered (" ", info);
1166
                    else if (cond == 1)
1167
                      fputs_filtered ("acc ", info);
1168
                    else if (cond == 2)
1169
                      fputs_filtered ("rej ", info);
1170
                    else if (cond == 5)
1171
                      fputs_filtered ("acc8 ", info);
1172
                    else if (cond == 6)
1173
                      fputs_filtered ("rej8 ", info);
1174
                    else if (cond == 9)
1175
                      fputs_filtered ("acc6 ", info);
1176
                    else if (cond == 13)
1177
                      fputs_filtered ("acc4 ", info);
1178
                    else if (cond == 17)
1179
                      fputs_filtered ("acc2 ", info);
1180
                    break;
1181
                  }
1182
 
1183
                case 'X':
1184
                  (*info->print_address_func) ((memaddr + 8
1185
                                                + extract_22 (insn)),
1186
                                               info);
1187
                  break;
1188
                case 'L':
1189
                  fputs_filtered (",%r2", info);
1190
                  break;
1191
                default:
1192
                  (*info->fprintf_func) (info->stream, "%c", *s);
1193
                  break;
1194
                }
1195
            }
1196
          return sizeof(insn);
1197
        }
1198
    }
1199
  (*info->fprintf_func) (info->stream, "#%8x", insn);
1200
  return sizeof(insn);
1201
}

powered by: WebSVN 2.1.0

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