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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [insight/] [opcodes/] [m10200-dis.c] - Blame information for rev 1772

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

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

powered by: WebSVN 2.1.0

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