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

Subversion Repositories open8_urisc

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

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

Line No. Rev Author Line
1 18 khays
/* Disassemble Motorola M*Core instructions.
2
   Copyright 1993, 1999, 2000, 2001, 2002, 2005, 2007, 2009
3
   Free Software Foundation, Inc.
4
 
5
   This file is part of the GNU opcodes library.
6
 
7
   This library is free software; you can redistribute it and/or modify
8
   it under the terms of the GNU General Public License as published by
9
   the Free Software Foundation; either version 3, or (at your option)
10
   any later version.
11
 
12
   It is distributed in the hope that it will be useful, but WITHOUT
13
   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14
   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
15
   License for more details.
16
 
17
   You should have received a copy of the GNU General Public License
18
   along with this program; if not, write to the Free Software
19
   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
20
   MA 02110-1301, USA.  */
21
 
22
#include "sysdep.h"
23
#include <stdio.h>
24
#define STATIC_TABLE
25
#define DEFINE_TABLE
26
 
27
#include "mcore-opc.h"
28
#include "dis-asm.h"
29
 
30
/* Mask for each mcore_opclass: */
31
static const unsigned short imsk[] = {
32
    /* O0  */ 0xFFFF,
33
    /* OT  */ 0xFFFC,
34
    /* O1  */ 0xFFF0,
35
    /* OC  */ 0xFE00,
36
    /* O2  */ 0xFF00,
37
    /* X1  */ 0xFFF0,
38
    /* OI  */ 0xFE00,
39
    /* OB  */ 0xFE00,
40
 
41
    /* OMa */ 0xFFF0,
42
    /* SI  */ 0xFE00,
43
    /* I7  */ 0xF800,
44
    /* LS  */ 0xF000,
45
    /* BR  */ 0xF800,
46
    /* BL  */ 0xFF00,
47
    /* LR  */ 0xF000,
48
    /* LJ  */ 0xFF00,
49
 
50
    /* RM  */ 0xFFF0,
51
    /* RQ  */ 0xFFF0,
52
    /* JSR */ 0xFFF0,
53
    /* JMP */ 0xFFF0,
54
    /* OBRa*/ 0xFFF0,
55
    /* OBRb*/ 0xFF80,
56
    /* OBRc*/ 0xFF00,
57
    /* OBR2*/ 0xFE00,
58
 
59
    /* O1R1*/ 0xFFF0,
60
    /* OMb */ 0xFF80,
61
    /* OMc */ 0xFF00,
62
    /* SIa */ 0xFE00,
63
 
64
  /* MULSH */ 0xFF00,
65
  /* OPSR  */ 0xFFF8,   /* psrset/psrclr */
66
 
67
    /* JC  */ 0,         /* JC,JU,JL don't appear in object */
68
    /* JU  */ 0,
69
    /* JL  */ 0,
70
    /* RSI */ 0,
71
    /* DO21*/ 0,
72
    /* OB2 */ 0          /* OB2 won't appear in object.  */
73
};
74
 
75
static const char *grname[] = {
76
 "r0",  "r1",  "r2",  "r3",  "r4",  "r5",  "r6",  "r7",
77
 "r8",  "r9", "r10", "r11", "r12", "r13", "r14", "r15"
78
};
79
 
80
static const char X[] = "??";
81
 
82
static const char *crname[] = {
83
  "psr",  "vbr", "epsr", "fpsr", "epc",  "fpc",  "ss0",  "ss1",
84
  "ss2",  "ss3", "ss4",  "gcr",  "gsr",     X,      X,      X,
85
     X,      X,      X,      X,      X,     X,      X,      X,
86
     X,      X,      X,      X,      X,     X,      X,      X
87
};
88
 
89
static const unsigned isiz[] = { 2, 0, 1, 0 };
90
 
91
int
92
print_insn_mcore (memaddr, info)
93
     bfd_vma memaddr;
94
     struct disassemble_info *info;
95
{
96
  unsigned char ibytes[4];
97
  fprintf_ftype print_func = info->fprintf_func;
98
  void *stream = info->stream;
99
  unsigned short inst;
100
  const mcore_opcode_info *op;
101
  int status;
102
 
103
  info->bytes_per_chunk = 2;
104
 
105
  status = info->read_memory_func (memaddr, ibytes, 2, info);
106
 
107
  if (status != 0)
108
    {
109
      info->memory_error_func (status, memaddr, info);
110
      return -1;
111
    }
112
 
113
  if (info->endian == BFD_ENDIAN_BIG)
114
    inst = (ibytes[0] << 8) | ibytes[1];
115
  else if (info->endian == BFD_ENDIAN_LITTLE)
116
    inst = (ibytes[1] << 8) | ibytes[0];
117
  else
118
    abort ();
119
 
120
  /* Just a linear search of the table.  */
121
  for (op = mcore_table; op->name != 0; op++)
122
    if (op->inst == (inst & imsk[op->opclass]))
123
      break;
124
 
125
  if (op->name == 0)
126
    (*print_func) (stream, ".short 0x%04x", inst);
127
  else
128
    {
129
      const char *name = grname[inst & 0x0F];
130
 
131
      (*print_func) (stream, "%s", op->name);
132
 
133
      switch (op->opclass)
134
        {
135
        case O0:
136
          break;
137
 
138
        case OT:
139
          (*print_func) (stream, "\t%d", inst & 0x3);
140
          break;
141
 
142
        case O1:
143
        case JMP:
144
        case JSR:
145
          (*print_func) (stream, "\t%s", name);
146
          break;
147
 
148
        case OC:
149
          (*print_func) (stream, "\t%s, %s", name, crname[(inst >> 4) & 0x1F]);
150
          break;
151
 
152
        case O1R1:
153
          (*print_func) (stream, "\t%s, r1", name);
154
          break;
155
 
156
        case MULSH:
157
        case O2:
158
          (*print_func) (stream, "\t%s, %s", name, grname[(inst >> 4) & 0xF]);
159
          break;
160
 
161
        case X1:
162
          (*print_func) (stream, "\tr1, %s", name);
163
          break;
164
 
165
        case OI:
166
          (*print_func) (stream, "\t%s, %d", name, ((inst >> 4) & 0x1F) + 1);
167
          break;
168
 
169
        case RM:
170
          (*print_func) (stream, "\t%s-r15, (r0)", name);
171
          break;
172
 
173
        case RQ:
174
          (*print_func) (stream, "\tr4-r7, (%s)", name);
175
          break;
176
 
177
        case OB:
178
        case OBRa:
179
        case OBRb:
180
        case OBRc:
181
        case SI:
182
        case SIa:
183
        case OMa:
184
        case OMb:
185
        case OMc:
186
          (*print_func) (stream, "\t%s, %d", name, (inst >> 4) & 0x1F);
187
          break;
188
 
189
        case I7:
190
          (*print_func) (stream, "\t%s, %d", name, (inst >> 4) & 0x7F);
191
          break;
192
 
193
        case LS:
194
          (*print_func) (stream, "\t%s, (%s, %d)", grname[(inst >> 8) & 0xF],
195
                         name, ((inst >> 4) & 0xF) << isiz[(inst >> 13) & 3]);
196
          break;
197
 
198
        case BR:
199
          {
200
            long val = inst & 0x3FF;
201
 
202
            if (inst & 0x400)
203
              val |= 0xFFFFFC00;
204
 
205
            (*print_func) (stream, "\t0x%lx", (long)(memaddr + 2 + (val << 1)));
206
 
207
            if (strcmp (op->name, "bsr") == 0)
208
              {
209
                /* For bsr, we'll try to get a symbol for the target.  */
210
                val = memaddr + 2 + (val << 1);
211
 
212
                if (info->print_address_func && val != 0)
213
                  {
214
                    (*print_func) (stream, "\t// ");
215
                    info->print_address_func (val, info);
216
                  }
217
              }
218
          }
219
          break;
220
 
221
        case BL:
222
          {
223
            long val;
224
            val = (inst & 0x000F);
225
            (*print_func) (stream, "\t%s, 0x%lx",
226
                           grname[(inst >> 4) & 0xF],
227
                           (long) (memaddr - (val << 1)));
228
          }
229
          break;
230
 
231
        case LR:
232
          {
233
            unsigned long val;
234
 
235
            val = (memaddr + 2 + ((inst & 0xFF) << 2)) & 0xFFFFFFFC;
236
 
237
            status = info->read_memory_func (val, ibytes, 4, info);
238
            if (status != 0)
239
              {
240
                info->memory_error_func (status, memaddr, info);
241
                break;
242
              }
243
 
244
            if (info->endian == BFD_ENDIAN_LITTLE)
245
              val = (ibytes[3] << 24) | (ibytes[2] << 16)
246
                | (ibytes[1] << 8) | (ibytes[0]);
247
            else
248
              val = (ibytes[0] << 24) | (ibytes[1] << 16)
249
                | (ibytes[2] << 8) | (ibytes[3]);
250
 
251
            /* Removed [] around literal value to match ABI syntax 12/95.  */
252
            (*print_func) (stream, "\t%s, 0x%lX", grname[(inst >> 8) & 0xF], val);
253
 
254
            if (val == 0)
255
              (*print_func) (stream, "\t// from address pool at 0x%lx",
256
                             (long) (memaddr + 2
257
                                     + ((inst & 0xFF) << 2)) & 0xFFFFFFFC);
258
          }
259
          break;
260
 
261
        case LJ:
262
          {
263
            unsigned long val;
264
 
265
            val = (memaddr + 2 + ((inst & 0xFF) << 2)) & 0xFFFFFFFC;
266
 
267
            status = info->read_memory_func (val, ibytes, 4, info);
268
            if (status != 0)
269
              {
270
                info->memory_error_func (status, memaddr, info);
271
                break;
272
              }
273
 
274
            if (info->endian == BFD_ENDIAN_LITTLE)
275
              val = (ibytes[3] << 24) | (ibytes[2] << 16)
276
                | (ibytes[1] << 8) | (ibytes[0]);
277
            else
278
              val = (ibytes[0] << 24) | (ibytes[1] << 16)
279
                | (ibytes[2] << 8) | (ibytes[3]);
280
 
281
            /* Removed [] around literal value to match ABI syntax 12/95.  */
282
            (*print_func) (stream, "\t0x%lX", val);
283
            /* For jmpi/jsri, we'll try to get a symbol for the target.  */
284
            if (info->print_address_func && val != 0)
285
              {
286
                (*print_func) (stream, "\t// ");
287
                info->print_address_func (val, info);
288
              }
289
            else
290
              {
291
                (*print_func) (stream, "\t// from address pool at 0x%lx",
292
                               (long) (memaddr + 2
293
                                       + ((inst & 0xFF) << 2)) & 0xFFFFFFFC);
294
              }
295
          }
296
          break;
297
 
298
        case OPSR:
299
          {
300
            static char *fields[] = {
301
              "af", "ie",    "fe",    "fe,ie",
302
              "ee", "ee,ie", "ee,fe", "ee,fe,ie"
303
            };
304
 
305
            (*print_func) (stream, "\t%s", fields[inst & 0x7]);
306
          }
307
          break;
308
 
309
        default:
310
          /* If the disassembler lags the instruction set.  */
311
          (*print_func) (stream, "\tundecoded operands, inst is 0x%04x", inst);
312
          break;
313
        }
314
    }
315
 
316
  /* Say how many bytes we consumed.  */
317
  return 2;
318
}

powered by: WebSVN 2.1.0

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