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

Subversion Repositories or1k_old

[/] [or1k_old/] [trunk/] [gdb-5.3/] [opcodes/] [mips-dis.c] - Blame information for rev 1782

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1181 sfurman
/* Print mips instructions for GDB, the GNU debugger, or for objdump.
2
   Copyright 1989, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
3
   2000, 2001, 2002
4
   Free Software Foundation, Inc.
5
   Contributed by Nobuyuki Hikichi(hikichi@sra.co.jp).
6
 
7
This file is part of GDB, GAS, and the GNU binutils.
8
 
9
This program is free software; you can redistribute it and/or modify
10
it under the terms of the GNU General Public License as published by
11
the Free Software Foundation; either version 2 of the License, or
12
(at your option) any later version.
13
 
14
This program is distributed in the hope that it will be useful,
15
but WITHOUT ANY WARRANTY; without even the implied warranty of
16
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17
GNU General Public License for more details.
18
 
19
You should have received a copy of the GNU General Public License
20
along with this program; if not, write to the Free Software
21
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
22
 
23
#include "sysdep.h"
24
#include "dis-asm.h"
25
#include "opcode/mips.h"
26
#include "opintl.h"
27
 
28
/* FIXME: These are needed to figure out if the code is mips16 or
29
   not. The low bit of the address is often a good indicator.  No
30
   symbol table is available when this code runs out in an embedded
31
   system as when it is used for disassembler support in a monitor.  */
32
 
33
#if !defined(EMBEDDED_ENV)
34
#define SYMTAB_AVAILABLE 1
35
#include "elf-bfd.h"
36
#include "elf/mips.h"
37
#endif
38
 
39
/* Mips instructions are at maximum this many bytes long.  */
40
#define INSNLEN 4
41
 
42
static int _print_insn_mips
43
  PARAMS ((bfd_vma, struct disassemble_info *, enum bfd_endian));
44
static int print_insn_mips
45
  PARAMS ((bfd_vma, unsigned long int, struct disassemble_info *));
46
static void print_insn_arg
47
  PARAMS ((const char *, unsigned long, bfd_vma, struct disassemble_info *));
48
static void mips_isa_type
49
  PARAMS ((int, int *, int *));
50
static int print_insn_mips16
51
  PARAMS ((bfd_vma, struct disassemble_info *));
52
static int is_newabi
53
  PARAMS ((Elf_Internal_Ehdr *));
54
static void print_mips16_insn_arg
55
  PARAMS ((int, const struct mips_opcode *, int, boolean, int, bfd_vma,
56
           struct disassemble_info *));
57
 
58
/* FIXME: These should be shared with gdb somehow.  */
59
 
60
/* The mips16 register names.  */
61
static const char * const mips16_reg_names[] = {
62
  "s0", "s1", "v0", "v1", "a0", "a1", "a2", "a3"
63
};
64
 
65
static const char * const mips32_reg_names[] = {
66
  "zero", "at",   "v0",  "v1",   "a0",    "a1",    "a2",   "a3",
67
  "t0",   "t1",   "t2",  "t3",   "t4",    "t5",    "t6",   "t7",
68
  "s0",   "s1",   "s2",  "s3",   "s4",    "s5",    "s6",   "s7",
69
  "t8",   "t9",   "k0",  "k1",   "gp",    "sp",    "s8",   "ra",
70
  "sr",   "lo",   "hi",  "bad",  "cause", "pc",
71
  "fv0",  "$f1",  "fv1", "$f3",  "ft0",   "$f5",   "ft1",  "$f7",
72
  "ft2",  "$f9",  "ft3", "$f11", "fa0",   "$f13",  "fa1",  "$f15",
73
  "ft4",  "f17",  "ft5", "f19",  "fs0",   "f21",   "fs1",  "f23",
74
  "fs2",  "$f25", "fs3", "$f27", "fs4",   "$f29",  "fs5",  "$f31",
75
  "fsr",  "fir",  "fp",  "inx",  "rand",  "tlblo", "ctxt", "tlbhi",
76
  "epc",  "prid"
77
};
78
 
79
static const char * const mips64_reg_names[] = {
80
  "zero", "at",   "v0",   "v1",   "a0",    "a1",    "a2",   "a3",
81
  "a4",   "a5",   "a6",   "a7",   "t0",    "t1",    "t2",   "t3",
82
  "s0",   "s1",   "s2",   "s3",   "s4",    "s5",    "s6",   "s7",
83
  "t8",   "t9",   "k0",   "k1",   "gp",    "sp",    "s8",   "ra",
84
  "sr",   "lo",   "hi",   "bad",  "cause", "pc",
85
  "fv0",  "$f1",  "fv1",  "$f3",  "ft0",   "ft1",   "ft2",  "ft3",
86
  "ft4",  "ft5",  "ft6",  "ft7",  "fa0",   "fa1",   "fa2",  "fa3",
87
  "fa4",  "fa5",  "fa6",  "fa7",  "ft8",   "ft9",   "ft10", "ft11",
88
  "fs0",  "fs1",  "fs2",  "fs3",  "fs4",   "fs5",   "fs6",  "fs7",
89
  "fsr",  "fir",  "fp",   "inx",  "rand",  "tlblo", "ctxt", "tlbhi",
90
  "epc",  "prid"
91
};
92
 
93
/* Scalar register names. _print_insn_mips() decides which register name
94
   table to use.  */
95
static const char * const *reg_names = NULL;
96
 
97
/* Print insn arguments for 32/64-bit code.  */
98
 
99
static void
100
print_insn_arg (d, l, pc, info)
101
     const char *d;
102
     register unsigned long int l;
103
     bfd_vma pc;
104
     struct disassemble_info *info;
105
{
106
  int delta;
107
 
108
  switch (*d)
109
    {
110
    case ',':
111
    case '(':
112
    case ')':
113
      (*info->fprintf_func) (info->stream, "%c", *d);
114
      break;
115
 
116
    case 's':
117
    case 'b':
118
    case 'r':
119
    case 'v':
120
      (*info->fprintf_func) (info->stream, "%s",
121
                             reg_names[(l >> OP_SH_RS) & OP_MASK_RS]);
122
      break;
123
 
124
    case 't':
125
    case 'w':
126
      (*info->fprintf_func) (info->stream, "%s",
127
                             reg_names[(l >> OP_SH_RT) & OP_MASK_RT]);
128
      break;
129
 
130
    case 'i':
131
    case 'u':
132
      (*info->fprintf_func) (info->stream, "0x%x",
133
                             (l >> OP_SH_IMMEDIATE) & OP_MASK_IMMEDIATE);
134
      break;
135
 
136
    case 'j': /* Same as i, but sign-extended.  */
137
    case 'o':
138
      delta = (l >> OP_SH_DELTA) & OP_MASK_DELTA;
139
      if (delta & 0x8000)
140
        delta |= ~0xffff;
141
      (*info->fprintf_func) (info->stream, "%d",
142
                             delta);
143
      break;
144
 
145
    case 'h':
146
      (*info->fprintf_func) (info->stream, "0x%x",
147
                             (unsigned int) ((l >> OP_SH_PREFX)
148
                                             & OP_MASK_PREFX));
149
      break;
150
 
151
    case 'k':
152
      (*info->fprintf_func) (info->stream, "0x%x",
153
                             (unsigned int) ((l >> OP_SH_CACHE)
154
                                             & OP_MASK_CACHE));
155
      break;
156
 
157
    case 'a':
158
      info->target = (((pc + 4) & ~(bfd_vma) 0x0fffffff)
159
                      | (((l >> OP_SH_TARGET) & OP_MASK_TARGET) << 2));
160
      (*info->print_address_func) (info->target, info);
161
      break;
162
 
163
    case 'p':
164
      /* Sign extend the displacement.  */
165
      delta = (l >> OP_SH_DELTA) & OP_MASK_DELTA;
166
      if (delta & 0x8000)
167
        delta |= ~0xffff;
168
      info->target = (delta << 2) + pc + INSNLEN;
169
      (*info->print_address_func) (info->target, info);
170
      break;
171
 
172
    case 'd':
173
      (*info->fprintf_func) (info->stream, "%s",
174
                             reg_names[(l >> OP_SH_RD) & OP_MASK_RD]);
175
      break;
176
 
177
    case 'U':
178
      {
179
        /* First check for both rd and rt being equal.  */
180
        unsigned int reg = (l >> OP_SH_RD) & OP_MASK_RD;
181
        if (reg == ((l >> OP_SH_RT) & OP_MASK_RT))
182
          (*info->fprintf_func) (info->stream, "%s",
183
                                 reg_names[reg]);
184
        else
185
          {
186
            /* If one is zero use the other.  */
187
            if (reg == 0)
188
              (*info->fprintf_func) (info->stream, "%s",
189
                                     reg_names[(l >> OP_SH_RT) & OP_MASK_RT]);
190
            else if (((l >> OP_SH_RT) & OP_MASK_RT) == 0)
191
              (*info->fprintf_func) (info->stream, "%s",
192
                                     reg_names[reg]);
193
            else /* Bogus, result depends on processor.  */
194
              (*info->fprintf_func) (info->stream, "%s or %s",
195
                                     reg_names[reg],
196
                                     reg_names[(l >> OP_SH_RT) & OP_MASK_RT]);
197
          }
198
      }
199
      break;
200
 
201
    case 'z':
202
      (*info->fprintf_func) (info->stream, "%s", reg_names[0]);
203
      break;
204
 
205
    case '<':
206
      (*info->fprintf_func) (info->stream, "0x%x",
207
                             (l >> OP_SH_SHAMT) & OP_MASK_SHAMT);
208
      break;
209
 
210
    case 'c':
211
      (*info->fprintf_func) (info->stream, "0x%x",
212
                             (l >> OP_SH_CODE) & OP_MASK_CODE);
213
      break;
214
 
215
    case 'q':
216
      (*info->fprintf_func) (info->stream, "0x%x",
217
                             (l >> OP_SH_CODE2) & OP_MASK_CODE2);
218
      break;
219
 
220
    case 'C':
221
      (*info->fprintf_func) (info->stream, "0x%x",
222
                             (l >> OP_SH_COPZ) & OP_MASK_COPZ);
223
      break;
224
 
225
    case 'B':
226
      (*info->fprintf_func) (info->stream, "0x%x",
227
                             (l >> OP_SH_CODE20) & OP_MASK_CODE20);
228
      break;
229
 
230
    case 'J':
231
      (*info->fprintf_func) (info->stream, "0x%x",
232
                             (l >> OP_SH_CODE19) & OP_MASK_CODE19);
233
      break;
234
 
235
    case 'S':
236
    case 'V':
237
      (*info->fprintf_func) (info->stream, "$f%d",
238
                             (l >> OP_SH_FS) & OP_MASK_FS);
239
      break;
240
 
241
    case 'T':
242
    case 'W':
243
      (*info->fprintf_func) (info->stream, "$f%d",
244
                             (l >> OP_SH_FT) & OP_MASK_FT);
245
      break;
246
 
247
    case 'D':
248
      (*info->fprintf_func) (info->stream, "$f%d",
249
                             (l >> OP_SH_FD) & OP_MASK_FD);
250
      break;
251
 
252
    case 'R':
253
      (*info->fprintf_func) (info->stream, "$f%d",
254
                             (l >> OP_SH_FR) & OP_MASK_FR);
255
      break;
256
 
257
    case 'E':
258
      (*info->fprintf_func) (info->stream, "$%d",
259
                             (l >> OP_SH_RT) & OP_MASK_RT);
260
      break;
261
 
262
    case 'G':
263
      (*info->fprintf_func) (info->stream, "$%d",
264
                             (l >> OP_SH_RD) & OP_MASK_RD);
265
      break;
266
 
267
    case 'N':
268
      (*info->fprintf_func) (info->stream, "$fcc%d",
269
                             (l >> OP_SH_BCC) & OP_MASK_BCC);
270
      break;
271
 
272
    case 'M':
273
      (*info->fprintf_func) (info->stream, "$fcc%d",
274
                             (l >> OP_SH_CCC) & OP_MASK_CCC);
275
      break;
276
 
277
    case 'P':
278
      (*info->fprintf_func) (info->stream, "%d",
279
                             (l >> OP_SH_PERFREG) & OP_MASK_PERFREG);
280
      break;
281
 
282
    case 'H':
283
      (*info->fprintf_func) (info->stream, "%d",
284
                             (l >> OP_SH_SEL) & OP_MASK_SEL);
285
      break;
286
 
287
    case 'O':
288
      (*info->fprintf_func) (info->stream, "%d",
289
                             (l >> OP_SH_ALN) & OP_MASK_ALN);
290
      break;
291
 
292
    case 'Q':
293
      {
294
        unsigned int vsel = (l >> OP_SH_VSEL) & OP_MASK_VSEL;
295
        if ((vsel & 0x10) == 0)
296
          {
297
            int fmt;
298
            vsel &= 0x0f;
299
            for (fmt = 0; fmt < 3; fmt++, vsel >>= 1)
300
              if ((vsel & 1) == 0)
301
                break;
302
            (*info->fprintf_func) (info->stream, "$v%d[%d]",
303
                                   (l >> OP_SH_FT) & OP_MASK_FT,
304
                                   vsel >> 1);
305
          }
306
        else if ((vsel & 0x08) == 0)
307
          {
308
            (*info->fprintf_func) (info->stream, "$v%d",
309
                                   (l >> OP_SH_FT) & OP_MASK_FT);
310
          }
311
        else
312
          {
313
            (*info->fprintf_func) (info->stream, "0x%x",
314
                                   (l >> OP_SH_FT) & OP_MASK_FT);
315
          }
316
      }
317
      break;
318
 
319
    case 'X':
320
      (*info->fprintf_func) (info->stream, "$v%d",
321
                             (l >> OP_SH_FD) & OP_MASK_FD);
322
      break;
323
 
324
    case 'Y':
325
      (*info->fprintf_func) (info->stream, "$v%d",
326
                             (l >> OP_SH_FS) & OP_MASK_FS);
327
      break;
328
 
329
    case 'Z':
330
      (*info->fprintf_func) (info->stream, "$v%d",
331
                             (l >> OP_SH_FT) & OP_MASK_FT);
332
      break;
333
 
334
    default:
335
      /* xgettext:c-format */
336
      (*info->fprintf_func) (info->stream,
337
                             _("# internal error, undefined modifier(%c)"),
338
                             *d);
339
      break;
340
    }
341
}
342
 
343
/* Figure out the MIPS ISA and CPU based on the machine number.  */
344
 
345
static void
346
mips_isa_type (mach, isa, cputype)
347
     int mach;
348
     int *isa;
349
     int *cputype;
350
{
351
  switch (mach)
352
    {
353
    case bfd_mach_mips3000:
354
      *cputype = CPU_R3000;
355
      *isa = ISA_MIPS1;
356
      break;
357
    case bfd_mach_mips3900:
358
      *cputype = CPU_R3900;
359
      *isa = ISA_MIPS1;
360
      break;
361
    case bfd_mach_mips4000:
362
      *cputype = CPU_R4000;
363
      *isa = ISA_MIPS3;
364
      break;
365
    case bfd_mach_mips4010:
366
      *cputype = CPU_R4010;
367
      *isa = ISA_MIPS2;
368
      break;
369
    case bfd_mach_mips4100:
370
      *cputype = CPU_VR4100;
371
      *isa = ISA_MIPS3;
372
      break;
373
    case bfd_mach_mips4111:
374
      *cputype = CPU_R4111;
375
      *isa = ISA_MIPS3;
376
      break;
377
    case bfd_mach_mips4300:
378
      *cputype = CPU_R4300;
379
      *isa = ISA_MIPS3;
380
      break;
381
    case bfd_mach_mips4400:
382
      *cputype = CPU_R4400;
383
      *isa = ISA_MIPS3;
384
      break;
385
    case bfd_mach_mips4600:
386
      *cputype = CPU_R4600;
387
      *isa = ISA_MIPS3;
388
      break;
389
    case bfd_mach_mips4650:
390
      *cputype = CPU_R4650;
391
      *isa = ISA_MIPS3;
392
      break;
393
    case bfd_mach_mips5000:
394
      *cputype = CPU_R5000;
395
      *isa = ISA_MIPS4;
396
      break;
397
    case bfd_mach_mips6000:
398
      *cputype = CPU_R6000;
399
      *isa = ISA_MIPS2;
400
      break;
401
    case bfd_mach_mips8000:
402
      *cputype = CPU_R8000;
403
      *isa = ISA_MIPS4;
404
      break;
405
    case bfd_mach_mips10000:
406
      *cputype = CPU_R10000;
407
      *isa = ISA_MIPS4;
408
      break;
409
    case bfd_mach_mips12000:
410
      *cputype = CPU_R12000;
411
      *isa = ISA_MIPS4;
412
      break;
413
    case bfd_mach_mips16:
414
      *cputype = CPU_MIPS16;
415
      *isa = ISA_MIPS3 | INSN_MIPS16;
416
      break;
417
    case bfd_mach_mips5:
418
      *cputype = CPU_MIPS5;
419
      *isa = ISA_MIPS5;
420
      break;
421
    case bfd_mach_mips_sb1:
422
      *cputype = CPU_SB1;
423
      *isa = ISA_MIPS64 | INSN_MIPS3D | INSN_SB1;
424
      break;
425
    case bfd_mach_mipsisa32:
426
      *cputype = CPU_MIPS32;
427
      /* For stock MIPS32, disassemble all applicable MIPS-specified ASEs.
428
         Note that MIPS-3D and MDMX are not applicable to MIPS32.  (See
429
         _MIPS32 Architecture For Programmers Volume I: Introduction to the
430
         MIPS32 Architecture_ (MIPS Document Number MD00082, Revision 0.95),
431
         page 1.  */
432
      *isa = ISA_MIPS32 | INSN_MIPS16;
433
      break;
434
    case bfd_mach_mipsisa64:
435
      *cputype = CPU_MIPS64;
436
      /* For stock MIPS64, disassemble all applicable MIPS-specified ASEs.  */
437
      *isa = ISA_MIPS64 | INSN_MIPS16 | INSN_MIPS3D | INSN_MDMX;
438
      break;
439
 
440
    default:
441
      *cputype = CPU_R3000;
442
      *isa = ISA_MIPS3;
443
      break;
444
    }
445
}
446
 
447
/* Check if the object uses NewABI conventions.  */
448
 
449
static int
450
is_newabi (header)
451
     Elf_Internal_Ehdr *header;
452
{
453
  /* There are no old-style ABIs which use 64-bit ELF.  */
454
  if (header->e_ident[EI_CLASS] == ELFCLASS64)
455
    return 1;
456
 
457
  /* If a 32-bit ELF file, n32 is a new-style ABI.  */
458
  if ((header->e_flags & EF_MIPS_ABI2) != 0)
459
    return 1;
460
 
461
  return 0;
462
}
463
 
464
/* Print the mips instruction at address MEMADDR in debugged memory,
465
   on using INFO.  Returns length of the instruction, in bytes, which is
466
   always INSNLEN.  BIGENDIAN must be 1 if this is big-endian code, 0 if
467
   this is little-endian code.  */
468
 
469
static int
470
print_insn_mips (memaddr, word, info)
471
     bfd_vma memaddr;
472
     unsigned long int word;
473
     struct disassemble_info *info;
474
{
475
  register const struct mips_opcode *op;
476
  int target_processor, mips_isa;
477
  static boolean init = 0;
478
  static const struct mips_opcode *mips_hash[OP_MASK_OP + 1];
479
 
480
  /* Build a hash table to shorten the search time.  */
481
  if (! init)
482
    {
483
      unsigned int i;
484
 
485
      for (i = 0; i <= OP_MASK_OP; i++)
486
        {
487
          for (op = mips_opcodes; op < &mips_opcodes[NUMOPCODES]; op++)
488
            {
489
              if (op->pinfo == INSN_MACRO)
490
                continue;
491
              if (i == ((op->match >> OP_SH_OP) & OP_MASK_OP))
492
                {
493
                  mips_hash[i] = op;
494
                  break;
495
                }
496
            }
497
        }
498
 
499
      init = 1;
500
    }
501
 
502
#if ! SYMTAB_AVAILABLE
503
  /* This is running out on a target machine, not in a host tool.
504
     FIXME: Where does mips_target_info come from?  */
505
  target_processor = mips_target_info.processor;
506
  mips_isa = mips_target_info.isa;
507
#else
508
  mips_isa_type (info->mach, &mips_isa, &target_processor);
509
#endif
510
 
511
  info->bytes_per_chunk = INSNLEN;
512
  info->display_endian = info->endian;
513
  info->insn_info_valid = 1;
514
  info->branch_delay_insns = 0;
515
  info->data_size = 0;
516
  info->insn_type = dis_nonbranch;
517
  info->target = 0;
518
  info->target2 = 0;
519
 
520
  op = mips_hash[(word >> OP_SH_OP) & OP_MASK_OP];
521
  if (op != NULL)
522
    {
523
      for (; op < &mips_opcodes[NUMOPCODES]; op++)
524
        {
525
          if (op->pinfo != INSN_MACRO && (word & op->mask) == op->match)
526
            {
527
              register const char *d;
528
 
529
              if (! OPCODE_IS_MEMBER (op, mips_isa, target_processor))
530
                continue;
531
 
532
              /* Figure out instruction type and branch delay information.  */
533
              if ((op->pinfo & INSN_UNCOND_BRANCH_DELAY) != 0)
534
                {
535
                  if ((info->insn_type & INSN_WRITE_GPR_31) != 0)
536
                    info->insn_type = dis_jsr;
537
                  else
538
                    info->insn_type = dis_branch;
539
                  info->branch_delay_insns = 1;
540
                }
541
              else if ((op->pinfo & (INSN_COND_BRANCH_DELAY
542
                                     | INSN_COND_BRANCH_LIKELY)) != 0)
543
                {
544
                  if ((info->insn_type & INSN_WRITE_GPR_31) != 0)
545
                    info->insn_type = dis_condjsr;
546
                  else
547
                    info->insn_type = dis_condbranch;
548
                  info->branch_delay_insns = 1;
549
                }
550
              else if ((op->pinfo & (INSN_STORE_MEMORY
551
                                     | INSN_LOAD_MEMORY_DELAY)) != 0)
552
                info->insn_type = dis_dref;
553
 
554
              (*info->fprintf_func) (info->stream, "%s", op->name);
555
 
556
              d = op->args;
557
              if (d != NULL && *d != '\0')
558
                {
559
                  (*info->fprintf_func) (info->stream, "\t");
560
                  for (; *d != '\0'; d++)
561
                    print_insn_arg (d, word, memaddr, info);
562
                }
563
 
564
              return INSNLEN;
565
            }
566
        }
567
    }
568
 
569
  /* Handle undefined instructions.  */
570
  info->insn_type = dis_noninsn;
571
  (*info->fprintf_func) (info->stream, "0x%x", word);
572
  return INSNLEN;
573
}
574
 
575
/* In an environment where we do not know the symbol type of the
576
   instruction we are forced to assume that the low order bit of the
577
   instructions' address may mark it as a mips16 instruction.  If we
578
   are single stepping, or the pc is within the disassembled function,
579
   this works.  Otherwise, we need a clue.  Sometimes.  */
580
 
581
static int
582
_print_insn_mips (memaddr, info, endianness)
583
     bfd_vma memaddr;
584
     struct disassemble_info *info;
585
     enum bfd_endian endianness;
586
{
587
  bfd_byte buffer[INSNLEN];
588
  int status;
589
 
590
#if 1
591
  /* FIXME: If odd address, this is CLEARLY a mips 16 instruction.  */
592
  /* Only a few tools will work this way.  */
593
  if (memaddr & 0x01)
594
    return print_insn_mips16 (memaddr, info);
595
#endif
596
 
597
#if SYMTAB_AVAILABLE
598
  if (info->mach == bfd_mach_mips16
599
      || (info->flavour == bfd_target_elf_flavour
600
          && info->symbols != NULL
601
          && ((*(elf_symbol_type **) info->symbols)->internal_elf_sym.st_other
602
              == STO_MIPS16)))
603
    return print_insn_mips16 (memaddr, info);
604
#endif
605
 
606
  /* Use mips64_reg_names for new ABI.  */
607
  reg_names = mips32_reg_names;
608
 
609
  if (info->flavour == bfd_target_elf_flavour && info->symbols != NULL)
610
    {
611
      Elf_Internal_Ehdr *header;
612
 
613
      header = elf_elfheader (bfd_asymbol_bfd (*(info->symbols)));
614
      if (is_newabi (header))
615
        reg_names = mips64_reg_names;
616
    }
617
 
618
  status = (*info->read_memory_func) (memaddr, buffer, INSNLEN, info);
619
  if (status == 0)
620
    {
621
      unsigned long insn;
622
 
623
      if (endianness == BFD_ENDIAN_BIG)
624
        insn = (unsigned long) bfd_getb32 (buffer);
625
      else
626
        insn = (unsigned long) bfd_getl32 (buffer);
627
 
628
      return print_insn_mips (memaddr, insn, info);
629
    }
630
  else
631
    {
632
      (*info->memory_error_func) (status, memaddr, info);
633
      return -1;
634
    }
635
}
636
 
637
int
638
print_insn_big_mips (memaddr, info)
639
     bfd_vma memaddr;
640
     struct disassemble_info *info;
641
{
642
  return _print_insn_mips (memaddr, info, BFD_ENDIAN_BIG);
643
}
644
 
645
int
646
print_insn_little_mips (memaddr, info)
647
     bfd_vma memaddr;
648
     struct disassemble_info *info;
649
{
650
  return _print_insn_mips (memaddr, info, BFD_ENDIAN_LITTLE);
651
}
652
 
653
/* Disassemble mips16 instructions.  */
654
 
655
static int
656
print_insn_mips16 (memaddr, info)
657
     bfd_vma memaddr;
658
     struct disassemble_info *info;
659
{
660
  int status;
661
  bfd_byte buffer[2];
662
  int length;
663
  int insn;
664
  boolean use_extend;
665
  int extend = 0;
666
  const struct mips_opcode *op, *opend;
667
 
668
  info->bytes_per_chunk = 2;
669
  info->display_endian = info->endian;
670
  info->insn_info_valid = 1;
671
  info->branch_delay_insns = 0;
672
  info->data_size = 0;
673
  info->insn_type = dis_nonbranch;
674
  info->target = 0;
675
  info->target2 = 0;
676
 
677
  status = (*info->read_memory_func) (memaddr, buffer, 2, info);
678
  if (status != 0)
679
    {
680
      (*info->memory_error_func) (status, memaddr, info);
681
      return -1;
682
    }
683
 
684
  length = 2;
685
 
686
  if (info->endian == BFD_ENDIAN_BIG)
687
    insn = bfd_getb16 (buffer);
688
  else
689
    insn = bfd_getl16 (buffer);
690
 
691
  /* Handle the extend opcode specially.  */
692
  use_extend = false;
693
  if ((insn & 0xf800) == 0xf000)
694
    {
695
      use_extend = true;
696
      extend = insn & 0x7ff;
697
 
698
      memaddr += 2;
699
 
700
      status = (*info->read_memory_func) (memaddr, buffer, 2, info);
701
      if (status != 0)
702
        {
703
          (*info->fprintf_func) (info->stream, "extend 0x%x",
704
                                 (unsigned int) extend);
705
          (*info->memory_error_func) (status, memaddr, info);
706
          return -1;
707
        }
708
 
709
      if (info->endian == BFD_ENDIAN_BIG)
710
        insn = bfd_getb16 (buffer);
711
      else
712
        insn = bfd_getl16 (buffer);
713
 
714
      /* Check for an extend opcode followed by an extend opcode.  */
715
      if ((insn & 0xf800) == 0xf000)
716
        {
717
          (*info->fprintf_func) (info->stream, "extend 0x%x",
718
                                 (unsigned int) extend);
719
          info->insn_type = dis_noninsn;
720
          return length;
721
        }
722
 
723
      length += 2;
724
    }
725
 
726
  /* FIXME: Should probably use a hash table on the major opcode here.  */
727
 
728
  opend = mips16_opcodes + bfd_mips16_num_opcodes;
729
  for (op = mips16_opcodes; op < opend; op++)
730
    {
731
      if (op->pinfo != INSN_MACRO && (insn & op->mask) == op->match)
732
        {
733
          const char *s;
734
 
735
          if (strchr (op->args, 'a') != NULL)
736
            {
737
              if (use_extend)
738
                {
739
                  (*info->fprintf_func) (info->stream, "extend 0x%x",
740
                                         (unsigned int) extend);
741
                  info->insn_type = dis_noninsn;
742
                  return length - 2;
743
                }
744
 
745
              use_extend = false;
746
 
747
              memaddr += 2;
748
 
749
              status = (*info->read_memory_func) (memaddr, buffer, 2,
750
                                                  info);
751
              if (status == 0)
752
                {
753
                  use_extend = true;
754
                  if (info->endian == BFD_ENDIAN_BIG)
755
                    extend = bfd_getb16 (buffer);
756
                  else
757
                    extend = bfd_getl16 (buffer);
758
                  length += 2;
759
                }
760
            }
761
 
762
          (*info->fprintf_func) (info->stream, "%s", op->name);
763
          if (op->args[0] != '\0')
764
            (*info->fprintf_func) (info->stream, "\t");
765
 
766
          for (s = op->args; *s != '\0'; s++)
767
            {
768
              if (*s == ','
769
                  && s[1] == 'w'
770
                  && (((insn >> MIPS16OP_SH_RX) & MIPS16OP_MASK_RX)
771
                      == ((insn >> MIPS16OP_SH_RY) & MIPS16OP_MASK_RY)))
772
                {
773
                  /* Skip the register and the comma.  */
774
                  ++s;
775
                  continue;
776
                }
777
              if (*s == ','
778
                  && s[1] == 'v'
779
                  && (((insn >> MIPS16OP_SH_RZ) & MIPS16OP_MASK_RZ)
780
                      == ((insn >> MIPS16OP_SH_RX) & MIPS16OP_MASK_RX)))
781
                {
782
                  /* Skip the register and the comma.  */
783
                  ++s;
784
                  continue;
785
                }
786
              print_mips16_insn_arg (*s, op, insn, use_extend, extend, memaddr,
787
                                     info);
788
            }
789
 
790
          if ((op->pinfo & INSN_UNCOND_BRANCH_DELAY) != 0)
791
            {
792
              info->branch_delay_insns = 1;
793
              if (info->insn_type != dis_jsr)
794
                info->insn_type = dis_branch;
795
            }
796
 
797
          return length;
798
        }
799
    }
800
 
801
  if (use_extend)
802
    (*info->fprintf_func) (info->stream, "0x%x", extend | 0xf000);
803
  (*info->fprintf_func) (info->stream, "0x%x", insn);
804
  info->insn_type = dis_noninsn;
805
 
806
  return length;
807
}
808
 
809
/* Disassemble an operand for a mips16 instruction.  */
810
 
811
static void
812
print_mips16_insn_arg (type, op, l, use_extend, extend, memaddr, info)
813
     char type;
814
     const struct mips_opcode *op;
815
     int l;
816
     boolean use_extend;
817
     int extend;
818
     bfd_vma memaddr;
819
     struct disassemble_info *info;
820
{
821
  switch (type)
822
    {
823
    case ',':
824
    case '(':
825
    case ')':
826
      (*info->fprintf_func) (info->stream, "%c", type);
827
      break;
828
 
829
    case 'y':
830
    case 'w':
831
      (*info->fprintf_func) (info->stream, "%s",
832
                             mips16_reg_names[((l >> MIPS16OP_SH_RY)
833
                                               & MIPS16OP_MASK_RY)]);
834
      break;
835
 
836
    case 'x':
837
    case 'v':
838
      (*info->fprintf_func) (info->stream, "%s",
839
                             mips16_reg_names[((l >> MIPS16OP_SH_RX)
840
                                               & MIPS16OP_MASK_RX)]);
841
      break;
842
 
843
    case 'z':
844
      (*info->fprintf_func) (info->stream, "%s",
845
                             mips16_reg_names[((l >> MIPS16OP_SH_RZ)
846
                                               & MIPS16OP_MASK_RZ)]);
847
      break;
848
 
849
    case 'Z':
850
      (*info->fprintf_func) (info->stream, "%s",
851
                             mips16_reg_names[((l >> MIPS16OP_SH_MOVE32Z)
852
                                               & MIPS16OP_MASK_MOVE32Z)]);
853
      break;
854
 
855
    case '0':
856
      (*info->fprintf_func) (info->stream, "%s", mips32_reg_names[0]);
857
      break;
858
 
859
    case 'S':
860
      (*info->fprintf_func) (info->stream, "%s", mips32_reg_names[29]);
861
      break;
862
 
863
    case 'P':
864
      (*info->fprintf_func) (info->stream, "$pc");
865
      break;
866
 
867
    case 'R':
868
      (*info->fprintf_func) (info->stream, "%s", mips32_reg_names[31]);
869
      break;
870
 
871
    case 'X':
872
      (*info->fprintf_func) (info->stream, "%s",
873
                             mips32_reg_names[((l >> MIPS16OP_SH_REGR32)
874
                                               & MIPS16OP_MASK_REGR32)]);
875
      break;
876
 
877
    case 'Y':
878
      (*info->fprintf_func) (info->stream, "%s",
879
                             mips32_reg_names[MIPS16OP_EXTRACT_REG32R (l)]);
880
      break;
881
 
882
    case '<':
883
    case '>':
884
    case '[':
885
    case ']':
886
    case '4':
887
    case '5':
888
    case 'H':
889
    case 'W':
890
    case 'D':
891
    case 'j':
892
    case '6':
893
    case '8':
894
    case 'V':
895
    case 'C':
896
    case 'U':
897
    case 'k':
898
    case 'K':
899
    case 'p':
900
    case 'q':
901
    case 'A':
902
    case 'B':
903
    case 'E':
904
      {
905
        int immed, nbits, shift, signedp, extbits, pcrel, extu, branch;
906
 
907
        shift = 0;
908
        signedp = 0;
909
        extbits = 16;
910
        pcrel = 0;
911
        extu = 0;
912
        branch = 0;
913
        switch (type)
914
          {
915
          case '<':
916
            nbits = 3;
917
            immed = (l >> MIPS16OP_SH_RZ) & MIPS16OP_MASK_RZ;
918
            extbits = 5;
919
            extu = 1;
920
            break;
921
          case '>':
922
            nbits = 3;
923
            immed = (l >> MIPS16OP_SH_RX) & MIPS16OP_MASK_RX;
924
            extbits = 5;
925
            extu = 1;
926
            break;
927
          case '[':
928
            nbits = 3;
929
            immed = (l >> MIPS16OP_SH_RZ) & MIPS16OP_MASK_RZ;
930
            extbits = 6;
931
            extu = 1;
932
            break;
933
          case ']':
934
            nbits = 3;
935
            immed = (l >> MIPS16OP_SH_RX) & MIPS16OP_MASK_RX;
936
            extbits = 6;
937
            extu = 1;
938
            break;
939
          case '4':
940
            nbits = 4;
941
            immed = (l >> MIPS16OP_SH_IMM4) & MIPS16OP_MASK_IMM4;
942
            signedp = 1;
943
            extbits = 15;
944
            break;
945
          case '5':
946
            nbits = 5;
947
            immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
948
            info->insn_type = dis_dref;
949
            info->data_size = 1;
950
            break;
951
          case 'H':
952
            nbits = 5;
953
            shift = 1;
954
            immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
955
            info->insn_type = dis_dref;
956
            info->data_size = 2;
957
            break;
958
          case 'W':
959
            nbits = 5;
960
            shift = 2;
961
            immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
962
            if ((op->pinfo & MIPS16_INSN_READ_PC) == 0
963
                && (op->pinfo & MIPS16_INSN_READ_SP) == 0)
964
              {
965
                info->insn_type = dis_dref;
966
                info->data_size = 4;
967
              }
968
            break;
969
          case 'D':
970
            nbits = 5;
971
            shift = 3;
972
            immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
973
            info->insn_type = dis_dref;
974
            info->data_size = 8;
975
            break;
976
          case 'j':
977
            nbits = 5;
978
            immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
979
            signedp = 1;
980
            break;
981
          case '6':
982
            nbits = 6;
983
            immed = (l >> MIPS16OP_SH_IMM6) & MIPS16OP_MASK_IMM6;
984
            break;
985
          case '8':
986
            nbits = 8;
987
            immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
988
            break;
989
          case 'V':
990
            nbits = 8;
991
            shift = 2;
992
            immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
993
            /* FIXME: This might be lw, or it might be addiu to $sp or
994
               $pc.  We assume it's load.  */
995
            info->insn_type = dis_dref;
996
            info->data_size = 4;
997
            break;
998
          case 'C':
999
            nbits = 8;
1000
            shift = 3;
1001
            immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
1002
            info->insn_type = dis_dref;
1003
            info->data_size = 8;
1004
            break;
1005
          case 'U':
1006
            nbits = 8;
1007
            immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
1008
            extu = 1;
1009
            break;
1010
          case 'k':
1011
            nbits = 8;
1012
            immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
1013
            signedp = 1;
1014
            break;
1015
          case 'K':
1016
            nbits = 8;
1017
            shift = 3;
1018
            immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
1019
            signedp = 1;
1020
            break;
1021
          case 'p':
1022
            nbits = 8;
1023
            immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
1024
            signedp = 1;
1025
            pcrel = 1;
1026
            branch = 1;
1027
            info->insn_type = dis_condbranch;
1028
            break;
1029
          case 'q':
1030
            nbits = 11;
1031
            immed = (l >> MIPS16OP_SH_IMM11) & MIPS16OP_MASK_IMM11;
1032
            signedp = 1;
1033
            pcrel = 1;
1034
            branch = 1;
1035
            info->insn_type = dis_branch;
1036
            break;
1037
          case 'A':
1038
            nbits = 8;
1039
            shift = 2;
1040
            immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8;
1041
            pcrel = 1;
1042
            /* FIXME: This can be lw or la.  We assume it is lw.  */
1043
            info->insn_type = dis_dref;
1044
            info->data_size = 4;
1045
            break;
1046
          case 'B':
1047
            nbits = 5;
1048
            shift = 3;
1049
            immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
1050
            pcrel = 1;
1051
            info->insn_type = dis_dref;
1052
            info->data_size = 8;
1053
            break;
1054
          case 'E':
1055
            nbits = 5;
1056
            shift = 2;
1057
            immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5;
1058
            pcrel = 1;
1059
            break;
1060
          default:
1061
            abort ();
1062
          }
1063
 
1064
        if (! use_extend)
1065
          {
1066
            if (signedp && immed >= (1 << (nbits - 1)))
1067
              immed -= 1 << nbits;
1068
            immed <<= shift;
1069
            if ((type == '<' || type == '>' || type == '[' || type == ']')
1070
                && immed == 0)
1071
              immed = 8;
1072
          }
1073
        else
1074
          {
1075
            if (extbits == 16)
1076
              immed |= ((extend & 0x1f) << 11) | (extend & 0x7e0);
1077
            else if (extbits == 15)
1078
              immed |= ((extend & 0xf) << 11) | (extend & 0x7f0);
1079
            else
1080
              immed = ((extend >> 6) & 0x1f) | (extend & 0x20);
1081
            immed &= (1 << extbits) - 1;
1082
            if (! extu && immed >= (1 << (extbits - 1)))
1083
              immed -= 1 << extbits;
1084
          }
1085
 
1086
        if (! pcrel)
1087
          (*info->fprintf_func) (info->stream, "%d", immed);
1088
        else
1089
          {
1090
            bfd_vma baseaddr;
1091
 
1092
            if (branch)
1093
              {
1094
                immed *= 2;
1095
                baseaddr = memaddr + 2;
1096
              }
1097
            else if (use_extend)
1098
              baseaddr = memaddr - 2;
1099
            else
1100
              {
1101
                int status;
1102
                bfd_byte buffer[2];
1103
 
1104
                baseaddr = memaddr;
1105
 
1106
                /* If this instruction is in the delay slot of a jr
1107
                   instruction, the base address is the address of the
1108
                   jr instruction.  If it is in the delay slot of jalr
1109
                   instruction, the base address is the address of the
1110
                   jalr instruction.  This test is unreliable: we have
1111
                   no way of knowing whether the previous word is
1112
                   instruction or data.  */
1113
                status = (*info->read_memory_func) (memaddr - 4, buffer, 2,
1114
                                                    info);
1115
                if (status == 0
1116
                    && (((info->endian == BFD_ENDIAN_BIG
1117
                          ? bfd_getb16 (buffer)
1118
                          : bfd_getl16 (buffer))
1119
                         & 0xf800) == 0x1800))
1120
                  baseaddr = memaddr - 4;
1121
                else
1122
                  {
1123
                    status = (*info->read_memory_func) (memaddr - 2, buffer,
1124
                                                        2, info);
1125
                    if (status == 0
1126
                        && (((info->endian == BFD_ENDIAN_BIG
1127
                              ? bfd_getb16 (buffer)
1128
                              : bfd_getl16 (buffer))
1129
                             & 0xf81f) == 0xe800))
1130
                      baseaddr = memaddr - 2;
1131
                  }
1132
              }
1133
            info->target = (baseaddr & ~((1 << shift) - 1)) + immed;
1134
            (*info->print_address_func) (info->target, info);
1135
          }
1136
      }
1137
      break;
1138
 
1139
    case 'a':
1140
      if (! use_extend)
1141
        extend = 0;
1142
      l = ((l & 0x1f) << 23) | ((l & 0x3e0) << 13) | (extend << 2);
1143
      info->target = ((memaddr + 4) & ~(bfd_vma) 0x0fffffff) | l;
1144
      (*info->print_address_func) (info->target, info);
1145
      info->insn_type = dis_jsr;
1146
      info->branch_delay_insns = 1;
1147
      break;
1148
 
1149
    case 'l':
1150
    case 'L':
1151
      {
1152
        int need_comma, amask, smask;
1153
 
1154
        need_comma = 0;
1155
 
1156
        l = (l >> MIPS16OP_SH_IMM6) & MIPS16OP_MASK_IMM6;
1157
 
1158
        amask = (l >> 3) & 7;
1159
 
1160
        if (amask > 0 && amask < 5)
1161
          {
1162
            (*info->fprintf_func) (info->stream, "%s", mips32_reg_names[4]);
1163
            if (amask > 1)
1164
              (*info->fprintf_func) (info->stream, "-%s",
1165
                                     mips32_reg_names[amask + 3]);
1166
            need_comma = 1;
1167
          }
1168
 
1169
        smask = (l >> 1) & 3;
1170
        if (smask == 3)
1171
          {
1172
            (*info->fprintf_func) (info->stream, "%s??",
1173
                                   need_comma ? "," : "");
1174
            need_comma = 1;
1175
          }
1176
        else if (smask > 0)
1177
          {
1178
            (*info->fprintf_func) (info->stream, "%s%s",
1179
                                   need_comma ? "," : "",
1180
                                   mips32_reg_names[16]);
1181
            if (smask > 1)
1182
              (*info->fprintf_func) (info->stream, "-%s",
1183
                                     mips32_reg_names[smask + 15]);
1184
            need_comma = 1;
1185
          }
1186
 
1187
        if (l & 1)
1188
          {
1189
            (*info->fprintf_func) (info->stream, "%s%s",
1190
                                   need_comma ? "," : "",
1191
                                   mips32_reg_names[31]);
1192
            need_comma = 1;
1193
          }
1194
 
1195
        if (amask == 5 || amask == 6)
1196
          {
1197
            (*info->fprintf_func) (info->stream, "%s$f0",
1198
                                   need_comma ? "," : "");
1199
            if (amask == 6)
1200
              (*info->fprintf_func) (info->stream, "-$f1");
1201
          }
1202
      }
1203
      break;
1204
 
1205
    default:
1206
      /* xgettext:c-format */
1207
      (*info->fprintf_func)
1208
        (info->stream,
1209
         _("# internal disassembler error, unrecognised modifier (%c)"),
1210
         type);
1211
      abort ();
1212
    }
1213
}

powered by: WebSVN 2.1.0

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