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

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [gnu-src/] [binutils-2.18.50/] [opcodes/] [m10200-dis.c] - Blame information for rev 156

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 38 julius
/* Disassemble MN10200 instructions.
2
   Copyright 1996, 1997, 1998, 2000, 2005, 2007 Free Software Foundation, Inc.
3
 
4
   This file is part of the GNU opcodes library.
5
 
6
   This library is free software; you can redistribute it and/or modify
7
   it under the terms of the GNU General Public License as published by
8
   the Free Software Foundation; either version 3, or (at your option)
9
   any later version.
10
 
11
   It is distributed in the hope that it will be useful, but WITHOUT
12
   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13
   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
14
   License for more details.
15
 
16
   You should have received a copy of the GNU General Public License
17
   along with this program; if not, write to the Free Software
18
   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
19
   MA 02110-1301, USA.  */
20
 
21
#include <stdio.h>
22
 
23
#include "sysdep.h"
24
#include "opcode/mn10200.h" 
25
#include "dis-asm.h"
26
#include "opintl.h"
27
 
28
static void
29
disassemble (bfd_vma memaddr,
30
             struct disassemble_info *info,
31
             unsigned long insn,
32
             unsigned long extension,
33
             unsigned int size)
34
{
35
  struct mn10200_opcode *op = (struct mn10200_opcode *)mn10200_opcodes;
36
  const struct mn10200_operand *operand;
37
  int match = 0;
38
 
39
  /* Find the opcode.  */
40
  while (op->name)
41
    {
42
      int mysize, extra_shift;
43
 
44
      if (op->format == FMT_1)
45
        mysize = 1;
46
      else if (op->format == FMT_2
47
               || op->format == FMT_4)
48
        mysize = 2;
49
      else if (op->format == FMT_3
50
               || op->format == FMT_5)
51
        mysize = 3;
52
      else if (op->format == FMT_6)
53
        mysize = 4;
54
      else if (op->format == FMT_7)
55
        mysize = 5;
56
      else
57
        abort ();
58
 
59
      if (op->format == FMT_2 || op->format == FMT_5)
60
        extra_shift = 8;
61
      else if (op->format == FMT_3
62
               || op->format == FMT_6
63
               || op->format == FMT_7)
64
        extra_shift = 16;
65
      else
66
        extra_shift = 0;
67
 
68
      if ((op->mask & insn) == op->opcode
69
          && size == (unsigned int) mysize)
70
        {
71
          const unsigned char *opindex_ptr;
72
          unsigned int nocomma;
73
          int paren = 0;
74
 
75
          match = 1;
76
          (*info->fprintf_func) (info->stream, "%s\t", op->name);
77
 
78
          /* Now print the operands.  */
79
          for (opindex_ptr = op->operands, nocomma = 1;
80
               *opindex_ptr != 0;
81
               opindex_ptr++)
82
            {
83
              unsigned long value;
84
 
85
              operand = &mn10200_operands[*opindex_ptr];
86
 
87
              if ((operand->flags & MN10200_OPERAND_EXTENDED) != 0)
88
                {
89
                  value = (insn & 0xffff) << 8;
90
                  value |= extension;
91
                }
92
              else
93
                {
94
                  value = ((insn >> (operand->shift))
95
                           & ((1L << operand->bits) - 1L));
96
                }
97
 
98
              if ((operand->flags & MN10200_OPERAND_SIGNED) != 0)
99
                value = ((long)(value << (32 - operand->bits))
100
                          >> (32 - operand->bits));
101
 
102
              if (!nocomma
103
                  && (!paren
104
                      || ((operand->flags & MN10200_OPERAND_PAREN) == 0)))
105
                (*info->fprintf_func) (info->stream, ",");
106
 
107
              nocomma = 0;
108
 
109
              if ((operand->flags & MN10200_OPERAND_DREG) != 0)
110
                {
111
                  value = ((insn >> (operand->shift + extra_shift))
112
                           & ((1 << operand->bits) - 1));
113
                  (*info->fprintf_func) (info->stream, "d%ld", value);
114
                }
115
 
116
              else if ((operand->flags & MN10200_OPERAND_AREG) != 0)
117
                {
118
                  value = ((insn >> (operand->shift + extra_shift))
119
                           & ((1 << operand->bits) - 1));
120
                  (*info->fprintf_func) (info->stream, "a%ld", value);
121
                }
122
 
123
              else if ((operand->flags & MN10200_OPERAND_PSW) != 0)
124
                (*info->fprintf_func) (info->stream, "psw");
125
 
126
              else if ((operand->flags & MN10200_OPERAND_MDR) != 0)
127
                (*info->fprintf_func) (info->stream, "mdr");
128
 
129
              else if ((operand->flags & MN10200_OPERAND_PAREN) != 0)
130
                {
131
                  if (paren)
132
                    (*info->fprintf_func) (info->stream, ")");
133
                  else
134
                    {
135
                      (*info->fprintf_func) (info->stream, "(");
136
                      nocomma = 1;
137
                    }
138
                  paren = !paren;
139
                }
140
 
141
              else if ((operand->flags & MN10200_OPERAND_PCREL) != 0)
142
                (*info->print_address_func)
143
                  ((value + memaddr + mysize) & 0xffffff, info);
144
 
145
              else if ((operand->flags & MN10200_OPERAND_MEMADDR) != 0)
146
                (*info->print_address_func) (value, info);
147
 
148
              else
149
                (*info->fprintf_func) (info->stream, "%ld", value);
150
            }
151
          /* All done. */
152
          break;
153
        }
154
      op++;
155
    }
156
 
157
  if (!match)
158
    (*info->fprintf_func) (info->stream, _("unknown\t0x%04lx"), insn);
159
}
160
 
161
int
162
print_insn_mn10200 (bfd_vma memaddr, struct disassemble_info *info)
163
{
164
  int status;
165
  bfd_byte buffer[4];
166
  unsigned long insn;
167
  unsigned long extension = 0;
168
  unsigned int consume;
169
 
170
  /* First figure out how big the opcode is.  */
171
  status = (*info->read_memory_func) (memaddr, buffer, 1, info);
172
  if (status != 0)
173
    {
174
      (*info->memory_error_func) (status, memaddr, info);
175
      return -1;
176
    }
177
 
178
  insn = *(unsigned char *) buffer;
179
 
180
  /* These are one byte insns.  */
181
  if ((insn & 0xf0) == 0x00
182
      || (insn & 0xf0) == 0x10
183
      || (insn & 0xf0) == 0x20
184
      || (insn & 0xf0) == 0x30
185
      || ((insn & 0xf0) == 0x80
186
          && (insn & 0x0c) >> 2 != (insn & 0x03))
187
      || (insn & 0xf0) == 0x90
188
      || (insn & 0xf0) == 0xa0
189
      || (insn & 0xf0) == 0xb0
190
      || (insn & 0xff) == 0xeb
191
      || (insn & 0xff) == 0xf6
192
      || (insn & 0xff) == 0xfe
193
      || (insn & 0xff) == 0xff)
194
    {
195
      extension = 0;
196
      consume = 1;
197
    }
198
 
199
  /* These are two byte insns.  */
200
  else if ((insn & 0xf0) == 0x40
201
           || (insn & 0xf0) == 0x50
202
           || (insn & 0xf0) == 0x60
203
           || (insn & 0xf0) == 0x70
204
           || (insn & 0xf0) == 0x80
205
           || (insn & 0xfc) == 0xd0
206
           || (insn & 0xfc) == 0xd4
207
           || (insn & 0xfc) == 0xd8
208
           || (insn & 0xfc) == 0xe0
209
           || (insn & 0xfc) == 0xe4
210
           || (insn & 0xff) == 0xe8
211
           || (insn & 0xff) == 0xe9
212
           || (insn & 0xff) == 0xea
213
           || (insn & 0xff) == 0xf0
214
           || (insn & 0xff) == 0xf1
215
           || (insn & 0xff) == 0xf2
216
           || (insn & 0xff) == 0xf3)
217
    {
218
      status = (*info->read_memory_func) (memaddr, buffer, 2, info);
219
      if (status != 0)
220
        {
221
          (*info->memory_error_func) (status, memaddr, info);
222
           return -1;
223
        }
224
      insn = bfd_getb16 (buffer);
225
      consume = 2;
226
    }
227
 
228
  /* These are three byte insns with a 16bit operand in little
229
     endian form.  */
230
  else if ((insn & 0xf0) == 0xc0
231
           || (insn & 0xfc) == 0xdc
232
           || (insn & 0xfc) == 0xec
233
           || (insn & 0xff) == 0xf8
234
           || (insn & 0xff) == 0xf9
235
           || (insn & 0xff) == 0xfa
236
           || (insn & 0xff) == 0xfb
237
           || (insn & 0xff) == 0xfc
238
           || (insn & 0xff) == 0xfd)
239
    {
240
      status = (*info->read_memory_func) (memaddr + 1, buffer, 2, info);
241
      if (status != 0)
242
        {
243
          (*info->memory_error_func) (status, memaddr, info);
244
          return -1;
245
        }
246
      insn <<= 16;
247
      insn |= bfd_getl16 (buffer);
248
      extension = 0;
249
      consume = 3;
250
    }
251
  /* These are three byte insns too, but we don't have to mess with
252
     endianness stuff.  */
253
  else if ((insn & 0xff) == 0xf5)
254
    {
255
      status = (*info->read_memory_func) (memaddr + 1, buffer, 2, info);
256
      if (status != 0)
257
        {
258
          (*info->memory_error_func) (status, memaddr, info);
259
          return -1;
260
        }
261
      insn <<= 16;
262
      insn |= bfd_getb16 (buffer);
263
      extension = 0;
264
      consume = 3;
265
    }
266
 
267
  /* These are four byte insns.  */
268
  else if ((insn & 0xff) == 0xf7)
269
    {
270
      status = (*info->read_memory_func) (memaddr, buffer, 2, info);
271
      if (status != 0)
272
        {
273
          (*info->memory_error_func) (status, memaddr, info);
274
          return -1;
275
        }
276
      insn = bfd_getb16 (buffer);
277
      insn <<= 16;
278
      status = (*info->read_memory_func) (memaddr + 2, buffer, 2, info);
279
      if (status != 0)
280
        {
281
          (*info->memory_error_func) (status, memaddr, info);
282
          return -1;
283
        }
284
      insn |= bfd_getl16 (buffer);
285
      extension = 0;
286
      consume = 4;
287
    }
288
 
289
  /* These are five byte insns.  */
290
  else if ((insn & 0xff) == 0xf4)
291
    {
292
      status = (*info->read_memory_func) (memaddr, buffer, 2, info);
293
      if (status != 0)
294
        {
295
          (*info->memory_error_func) (status, memaddr, info);
296
          return -1;
297
        }
298
      insn = bfd_getb16 (buffer);
299
      insn <<= 16;
300
 
301
      status = (*info->read_memory_func) (memaddr + 4, buffer, 1, info);
302
      if (status != 0)
303
        {
304
          (*info->memory_error_func) (status, memaddr, info);
305
          return -1;
306
        }
307
      insn |= (*(unsigned char *)buffer << 8) & 0xff00;
308
 
309
      status = (*info->read_memory_func) (memaddr + 3, buffer, 1, info);
310
      if (status != 0)
311
        {
312
          (*info->memory_error_func) (status, memaddr, info);
313
          return -1;
314
        }
315
      insn |= (*(unsigned char *)buffer) & 0xff;
316
 
317
      status = (*info->read_memory_func) (memaddr + 2, buffer, 1, info);
318
      if (status != 0)
319
        {
320
          (*info->memory_error_func) (status, memaddr, info);
321
          return -1;
322
        }
323
      extension = (*(unsigned char *)buffer) & 0xff;
324
      consume = 5;
325
    }
326
  else
327
    {
328
      (*info->fprintf_func) (info->stream, _("unknown\t0x%02lx"), insn);
329
      return 1;
330
    }
331
 
332
  disassemble (memaddr, info, insn, extension, consume);
333
 
334
  return consume;
335
}

powered by: WebSVN 2.1.0

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