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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-stable/] [binutils-2.20.1/] [opcodes/] [m10300-dis.c] - Blame information for rev 861

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

Line No. Rev Author Line
1 205 julius
/* Disassemble MN10300 instructions.
2
   Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2005, 2007
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 <stdio.h>
23
 
24
#include "sysdep.h"
25
#include "opcode/mn10300.h"
26
#include "dis-asm.h"
27
#include "opintl.h"
28
 
29
#define HAVE_AM33_2 (info->mach == AM33_2)
30
#define HAVE_AM33   (info->mach == AM33 || HAVE_AM33_2)
31
#define HAVE_AM30   (info->mach == AM30)
32
 
33
static void
34
disassemble (bfd_vma memaddr,
35
             struct disassemble_info *info,
36
             unsigned long insn,
37
             unsigned int size)
38
{
39
  struct mn10300_opcode *op = (struct mn10300_opcode *) mn10300_opcodes;
40
  const struct mn10300_operand *operand;
41
  bfd_byte buffer[4];
42
  unsigned long extension = 0;
43
  int status, match = 0;
44
 
45
  /* Find the opcode.  */
46
  while (op->name)
47
    {
48
      int mysize, extra_shift;
49
 
50
      if (op->format == FMT_S0)
51
        mysize = 1;
52
      else if (op->format == FMT_S1
53
               || op->format == FMT_D0)
54
        mysize = 2;
55
      else if (op->format == FMT_S2
56
               || op->format == FMT_D1)
57
        mysize = 3;
58
      else if (op->format == FMT_S4)
59
        mysize = 5;
60
      else if (op->format == FMT_D2)
61
        mysize = 4;
62
      else if (op->format == FMT_D3)
63
        mysize = 5;
64
      else if (op->format == FMT_D4)
65
        mysize = 6;
66
      else if (op->format == FMT_D6)
67
        mysize = 3;
68
      else if (op->format == FMT_D7 || op->format == FMT_D10)
69
        mysize = 4;
70
      else if (op->format == FMT_D8)
71
        mysize = 6;
72
      else if (op->format == FMT_D9)
73
        mysize = 7;
74
      else
75
        mysize = 7;
76
 
77
      if ((op->mask & insn) == op->opcode
78
          && size == (unsigned int) mysize
79
          && (op->machine == 0
80
              || (op->machine == AM33_2 && HAVE_AM33_2)
81
              || (op->machine == AM33 && HAVE_AM33)
82
              || (op->machine == AM30 && HAVE_AM30)))
83
        {
84
          const unsigned char *opindex_ptr;
85
          unsigned int nocomma;
86
          int paren = 0;
87
 
88
          if (op->format == FMT_D1 || op->format == FMT_S1)
89
            extra_shift = 8;
90
          else if (op->format == FMT_D2 || op->format == FMT_D4
91
                   || op->format == FMT_S2 || op->format == FMT_S4
92
                   || op->format == FMT_S6 || op->format == FMT_D5)
93
            extra_shift = 16;
94
          else if (op->format == FMT_D7
95
                   || op->format == FMT_D8
96
                   || op->format == FMT_D9)
97
            extra_shift = 8;
98
          else
99
            extra_shift = 0;
100
 
101
          if (size == 1 || size == 2)
102
            extension = 0;
103
 
104
          else if (size == 3
105
                   && (op->format == FMT_D1
106
                       || op->opcode == 0xdf0000
107
                       || op->opcode == 0xde0000))
108
            extension = 0;
109
 
110
          else if (size == 3
111
                   && op->format == FMT_D6)
112
            extension = 0;
113
 
114
          else if (size == 3)
115
            {
116
              insn &= 0xff0000;
117
              status = (*info->read_memory_func) (memaddr + 1, buffer, 2, info);
118
              if (status != 0)
119
                {
120
                  (*info->memory_error_func) (status, memaddr, info);
121
                  return;
122
                }
123
 
124
              insn |= bfd_getl16 (buffer);
125
              extension = 0;
126
            }
127
          else if (size == 4
128
                   && (op->opcode == 0xfaf80000
129
                       || op->opcode == 0xfaf00000
130
                       || op->opcode == 0xfaf40000))
131
            extension = 0;
132
 
133
          else if (size == 4
134
                   && (op->format == FMT_D7
135
                       || op->format == FMT_D10))
136
            extension = 0;
137
 
138
          else if (size == 4)
139
            {
140
              insn &= 0xffff0000;
141
              status = (*info->read_memory_func) (memaddr + 2, buffer, 2, info);
142
              if (status != 0)
143
                {
144
                  (*info->memory_error_func) (status, memaddr, info);
145
                  return;
146
                }
147
 
148
              insn |= bfd_getl16 (buffer);
149
              extension = 0;
150
            }
151
          else if (size == 5 && op->opcode == 0xdc000000)
152
            {
153
              unsigned long temp = 0;
154
 
155
              status = (*info->read_memory_func) (memaddr + 1, buffer, 4, info);
156
              if (status != 0)
157
                {
158
                  (*info->memory_error_func) (status, memaddr, info);
159
                  return;
160
                }
161
              temp |= bfd_getl32 (buffer);
162
 
163
              insn &= 0xff000000;
164
              insn |= (temp & 0xffffff00) >> 8;
165
              extension = temp & 0xff;
166
            }
167
          else if (size == 5 && op->format == FMT_D3)
168
            {
169
              status = (*info->read_memory_func) (memaddr + 2, buffer, 2, info);
170
              if (status != 0)
171
                {
172
                  (*info->memory_error_func) (status, memaddr, info);
173
                  return;
174
                }
175
              insn &= 0xffff0000;
176
              insn |= bfd_getl16 (buffer);
177
 
178
              status = (*info->read_memory_func) (memaddr + 4, buffer, 1, info);
179
              if (status != 0)
180
                {
181
                  (*info->memory_error_func) (status, memaddr, info);
182
                  return;
183
                }
184
              extension = *(unsigned char *) buffer;
185
            }
186
          else if (size == 5)
187
            {
188
              unsigned long temp = 0;
189
 
190
              status = (*info->read_memory_func) (memaddr + 1, buffer, 2, info);
191
              if (status != 0)
192
                {
193
                  (*info->memory_error_func) (status, memaddr, info);
194
                  return;
195
                }
196
              temp |= bfd_getl16 (buffer);
197
 
198
              insn &= 0xff0000ff;
199
              insn |= temp << 8;
200
 
201
              status = (*info->read_memory_func) (memaddr + 4, buffer, 1, info);
202
              if (status != 0)
203
                {
204
                  (*info->memory_error_func) (status, memaddr, info);
205
                  return;
206
                }
207
              extension = *(unsigned char *) buffer;
208
            }
209
          else if (size == 6 && op->format == FMT_D8)
210
            {
211
              insn &= 0xffffff00;
212
              status = (*info->read_memory_func) (memaddr + 5, buffer, 1, info);
213
              if (status != 0)
214
                {
215
                  (*info->memory_error_func) (status, memaddr, info);
216
                  return;
217
                }
218
              insn |= *(unsigned char *) buffer;
219
 
220
              status = (*info->read_memory_func) (memaddr + 3, buffer, 2, info);
221
              if (status != 0)
222
                {
223
                  (*info->memory_error_func) (status, memaddr, info);
224
                  return;
225
                }
226
              extension = bfd_getl16 (buffer);
227
            }
228
          else if (size == 6)
229
            {
230
              unsigned long temp = 0;
231
 
232
              status = (*info->read_memory_func) (memaddr + 2, buffer, 4, info);
233
              if (status != 0)
234
                {
235
                  (*info->memory_error_func) (status, memaddr, info);
236
                  return;
237
                }
238
              temp |= bfd_getl32 (buffer);
239
 
240
              insn &= 0xffff0000;
241
              insn |= (temp >> 16) & 0xffff;
242
              extension = temp & 0xffff;
243
            }
244
          else if (size == 7 && op->format == FMT_D9)
245
            {
246
              insn &= 0xffffff00;
247
              status = (*info->read_memory_func) (memaddr + 3, buffer, 4, info);
248
              if (status != 0)
249
                {
250
                  (*info->memory_error_func) (status, memaddr, info);
251
                  return;
252
                }
253
              extension = bfd_getl32 (buffer);
254
              insn |= (extension & 0xff000000) >> 24;
255
              extension &= 0xffffff;
256
            }
257
          else if (size == 7 && op->opcode == 0xdd000000)
258
            {
259
              unsigned long temp = 0;
260
 
261
              status = (*info->read_memory_func) (memaddr + 1, buffer, 4, info);
262
              if (status != 0)
263
                {
264
                  (*info->memory_error_func) (status, memaddr, info);
265
                  return;
266
                }
267
              temp |= bfd_getl32 (buffer);
268
 
269
              insn &= 0xff000000;
270
              insn |= (temp >> 8) & 0xffffff;
271
              extension = (temp & 0xff) << 16;
272
 
273
              status = (*info->read_memory_func) (memaddr + 5, buffer, 2, info);
274
              if (status != 0)
275
                {
276
                  (*info->memory_error_func) (status, memaddr, info);
277
                  return;
278
                }
279
              extension |= bfd_getb16 (buffer);
280
            }
281
          else if (size == 7)
282
            {
283
              unsigned long temp = 0;
284
 
285
              status = (*info->read_memory_func) (memaddr + 2, buffer, 4, info);
286
              if (status != 0)
287
                {
288
                  (*info->memory_error_func) (status, memaddr, info);
289
                  return;
290
                }
291
              temp |= bfd_getl32 (buffer);
292
 
293
              insn &= 0xffff0000;
294
              insn |= (temp >> 16) & 0xffff;
295
              extension = (temp & 0xffff) << 8;
296
 
297
              status = (*info->read_memory_func) (memaddr + 6, buffer, 1, info);
298
              if (status != 0)
299
                {
300
                  (*info->memory_error_func) (status, memaddr, info);
301
                  return;
302
                }
303
              extension |= *(unsigned char *) buffer;
304
            }
305
 
306
          match = 1;
307
          (*info->fprintf_func) (info->stream, "%s\t", op->name);
308
 
309
          /* Now print the operands.  */
310
          for (opindex_ptr = op->operands, nocomma = 1;
311
               *opindex_ptr != 0;
312
               opindex_ptr++)
313
            {
314
              unsigned long value;
315
 
316
              operand = &mn10300_operands[*opindex_ptr];
317
 
318
              /* If this operand is a PLUS (autoincrement), then do not emit
319
                 a comma before emitting the plus.  */
320
              if ((operand->flags & MN10300_OPERAND_PLUS) != 0)
321
                nocomma = 1;
322
 
323
              if ((operand->flags & MN10300_OPERAND_SPLIT) != 0)
324
                {
325
                  unsigned long temp;
326
 
327
                  value = insn & ((1 << operand->bits) - 1);
328
                  value <<= (32 - operand->bits);
329
                  temp = extension >> operand->shift;
330
                  temp &= ((1 << (32 - operand->bits)) - 1);
331
                  value |= temp;
332
                  value = ((value ^ (((unsigned long) 1) << 31))
333
                           - (((unsigned long) 1) << 31));
334
                }
335
              else if ((operand->flags & MN10300_OPERAND_24BIT) != 0)
336
                {
337
                  unsigned long temp;
338
 
339
                  value = insn & ((1 << operand->bits) - 1);
340
                  value <<= (24 - operand->bits);
341
                  temp = extension >> operand->shift;
342
                  temp &= ((1 << (24 - operand->bits)) - 1);
343
                  value |= temp;
344
                  if ((operand->flags & MN10300_OPERAND_SIGNED) != 0)
345
                    value = ((value & 0xffffff) ^ 0x800000) - 0x800000;
346
                }
347
              else if ((operand->flags & (MN10300_OPERAND_FSREG
348
                                          | MN10300_OPERAND_FDREG)))
349
                {
350
                  /* See m10300-opc.c just before #define FSM0 for an
351
                     explanation of these variables.  Note that
352
                     FMT-implied shifts are not taken into account for
353
                     FP registers.  */
354
                  unsigned long mask_low, mask_high;
355
                  int shl_low, shr_high, shl_high;
356
 
357
                  switch (operand->bits)
358
                    {
359
                    case 5:
360
                      /* Handle regular FP registers.  */
361
                      if (operand->shift >= 0)
362
                        {
363
                          /* This is an `m' register.  */
364
                          shl_low = operand->shift;
365
                          shl_high = 8 + (8 & shl_low) + (shl_low & 4) / 4;
366
                        }
367
                      else
368
                        {
369
                          /* This is an `n' register.  */
370
                          shl_low = -operand->shift;
371
                          shl_high = shl_low / 4;
372
                        }
373
                      mask_low = 0x0f;
374
                      mask_high = 0x10;
375
                      shr_high = 4;
376
                      break;
377
 
378
                    case 3:
379
                      /* Handle accumulators.  */
380
                      shl_low = -operand->shift;
381
                      shl_high = 0;
382
                      mask_low = 0x03;
383
                      mask_high = 0x04;
384
                      shr_high = 2;
385
                      break;
386
 
387
                    default:
388
                      abort ();
389
                    }
390
                  value = ((((insn >> shl_high) << shr_high) & mask_high)
391
                           | ((insn >> shl_low) & mask_low));
392
                }
393
              else if ((operand->flags & MN10300_OPERAND_EXTENDED) != 0)
394
                value = ((extension >> (operand->shift))
395
                         & ((1 << operand->bits) - 1));
396
 
397
              else
398
                value = ((insn >> (operand->shift))
399
                         & ((1 << operand->bits) - 1));
400
 
401
              if ((operand->flags & MN10300_OPERAND_SIGNED) != 0
402
                  /* These are properly extended by the code above.  */
403
                  && ((operand->flags & MN10300_OPERAND_24BIT) == 0))
404
                value = ((value ^ (((unsigned long) 1) << (operand->bits - 1)))
405
                         - (((unsigned long) 1) << (operand->bits - 1)));
406
 
407
              if (!nocomma
408
                  && (!paren
409
                      || ((operand->flags & MN10300_OPERAND_PAREN) == 0)))
410
                (*info->fprintf_func) (info->stream, ",");
411
 
412
              nocomma = 0;
413
 
414
              if ((operand->flags & MN10300_OPERAND_DREG) != 0)
415
                {
416
                  value = ((insn >> (operand->shift + extra_shift))
417
                           & ((1 << operand->bits) - 1));
418
                  (*info->fprintf_func) (info->stream, "d%d", (int) value);
419
                }
420
 
421
              else if ((operand->flags & MN10300_OPERAND_AREG) != 0)
422
                {
423
                  value = ((insn >> (operand->shift + extra_shift))
424
                           & ((1 << operand->bits) - 1));
425
                  (*info->fprintf_func) (info->stream, "a%d", (int) value);
426
                }
427
 
428
              else if ((operand->flags & MN10300_OPERAND_SP) != 0)
429
                (*info->fprintf_func) (info->stream, "sp");
430
 
431
              else if ((operand->flags & MN10300_OPERAND_PSW) != 0)
432
                (*info->fprintf_func) (info->stream, "psw");
433
 
434
              else if ((operand->flags & MN10300_OPERAND_MDR) != 0)
435
                (*info->fprintf_func) (info->stream, "mdr");
436
 
437
              else if ((operand->flags & MN10300_OPERAND_RREG) != 0)
438
                {
439
                  value = ((insn >> (operand->shift + extra_shift))
440
                           & ((1 << operand->bits) - 1));
441
                  if (value < 8)
442
                    (*info->fprintf_func) (info->stream, "r%d", (int) value);
443
                  else if (value < 12)
444
                    (*info->fprintf_func) (info->stream, "a%d", (int) value - 8);
445
                  else
446
                    (*info->fprintf_func) (info->stream, "d%d", (int) value - 12);
447
                }
448
 
449
              else if ((operand->flags & MN10300_OPERAND_XRREG) != 0)
450
                {
451
                  value = ((insn >> (operand->shift + extra_shift))
452
                           & ((1 << operand->bits) - 1));
453
                  if (value == 0)
454
                    (*info->fprintf_func) (info->stream, "sp");
455
                  else
456
                    (*info->fprintf_func) (info->stream, "xr%d", (int) value);
457
                }
458
 
459
              else if ((operand->flags & MN10300_OPERAND_FSREG) != 0)
460
                (*info->fprintf_func) (info->stream, "fs%d", (int) value);
461
 
462
              else if ((operand->flags & MN10300_OPERAND_FDREG) != 0)
463
                (*info->fprintf_func) (info->stream, "fd%d", (int) value);
464
 
465
              else if ((operand->flags & MN10300_OPERAND_FPCR) != 0)
466
                (*info->fprintf_func) (info->stream, "fpcr");
467
 
468
              else if ((operand->flags & MN10300_OPERAND_USP) != 0)
469
                (*info->fprintf_func) (info->stream, "usp");
470
 
471
              else if ((operand->flags & MN10300_OPERAND_SSP) != 0)
472
                (*info->fprintf_func) (info->stream, "ssp");
473
 
474
              else if ((operand->flags & MN10300_OPERAND_MSP) != 0)
475
                (*info->fprintf_func) (info->stream, "msp");
476
 
477
              else if ((operand->flags & MN10300_OPERAND_PC) != 0)
478
                (*info->fprintf_func) (info->stream, "pc");
479
 
480
              else if ((operand->flags & MN10300_OPERAND_EPSW) != 0)
481
                (*info->fprintf_func) (info->stream, "epsw");
482
 
483
              else if ((operand->flags & MN10300_OPERAND_PLUS) != 0)
484
                (*info->fprintf_func) (info->stream, "+");
485
 
486
              else if ((operand->flags & MN10300_OPERAND_PAREN) != 0)
487
                {
488
                  if (paren)
489
                    (*info->fprintf_func) (info->stream, ")");
490
                  else
491
                    {
492
                      (*info->fprintf_func) (info->stream, "(");
493
                      nocomma = 1;
494
                    }
495
                  paren = !paren;
496
                }
497
 
498
              else if ((operand->flags & MN10300_OPERAND_PCREL) != 0)
499
                (*info->print_address_func) ((long) value + memaddr, info);
500
 
501
              else if ((operand->flags & MN10300_OPERAND_MEMADDR) != 0)
502
                (*info->print_address_func) (value, info);
503
 
504
              else if ((operand->flags & MN10300_OPERAND_REG_LIST) != 0)
505
                {
506
                  int comma = 0;
507
 
508
                  (*info->fprintf_func) (info->stream, "[");
509
                  if (value & 0x80)
510
                    {
511
                      (*info->fprintf_func) (info->stream, "d2");
512
                      comma = 1;
513
                    }
514
 
515
                  if (value & 0x40)
516
                    {
517
                      if (comma)
518
                        (*info->fprintf_func) (info->stream, ",");
519
                      (*info->fprintf_func) (info->stream, "d3");
520
                      comma = 1;
521
                    }
522
 
523
                  if (value & 0x20)
524
                    {
525
                      if (comma)
526
                        (*info->fprintf_func) (info->stream, ",");
527
                      (*info->fprintf_func) (info->stream, "a2");
528
                      comma = 1;
529
                    }
530
 
531
                  if (value & 0x10)
532
                    {
533
                      if (comma)
534
                        (*info->fprintf_func) (info->stream, ",");
535
                      (*info->fprintf_func) (info->stream, "a3");
536
                      comma = 1;
537
                    }
538
 
539
                  if (value & 0x08)
540
                    {
541
                      if (comma)
542
                        (*info->fprintf_func) (info->stream, ",");
543
                      (*info->fprintf_func) (info->stream, "other");
544
                      comma = 1;
545
                    }
546
 
547
                  if (value & 0x04)
548
                    {
549
                      if (comma)
550
                        (*info->fprintf_func) (info->stream, ",");
551
                      (*info->fprintf_func) (info->stream, "exreg0");
552
                      comma = 1;
553
                    }
554
                  if (value & 0x02)
555
                    {
556
                      if (comma)
557
                        (*info->fprintf_func) (info->stream, ",");
558
                      (*info->fprintf_func) (info->stream, "exreg1");
559
                      comma = 1;
560
                    }
561
                  if (value & 0x01)
562
                    {
563
                      if (comma)
564
                        (*info->fprintf_func) (info->stream, ",");
565
                      (*info->fprintf_func) (info->stream, "exother");
566
                      comma = 1;
567
                    }
568
                  (*info->fprintf_func) (info->stream, "]");
569
                }
570
 
571
              else
572
                (*info->fprintf_func) (info->stream, "%ld", (long) value);
573
            }
574
          /* All done. */
575
          break;
576
        }
577
      op++;
578
    }
579
 
580
  if (!match)
581
    /* xgettext:c-format */
582
    (*info->fprintf_func) (info->stream, _("unknown\t0x%04lx"), insn);
583
}
584
 
585
int
586
print_insn_mn10300 (bfd_vma memaddr, struct disassemble_info *info)
587
{
588
  int status;
589
  bfd_byte buffer[4];
590
  unsigned long insn;
591
  unsigned int consume;
592
 
593
  /* First figure out how big the opcode is.  */
594
  status = (*info->read_memory_func) (memaddr, buffer, 1, info);
595
  if (status != 0)
596
    {
597
      (*info->memory_error_func) (status, memaddr, info);
598
      return -1;
599
    }
600
  insn = *(unsigned char *) buffer;
601
 
602
  /* These are one byte insns.  */
603
  if ((insn & 0xf3) == 0x00
604
      || (insn & 0xf0) == 0x10
605
      || (insn & 0xfc) == 0x3c
606
      || (insn & 0xf3) == 0x41
607
      || (insn & 0xf3) == 0x40
608
      || (insn & 0xfc) == 0x50
609
      || (insn & 0xfc) == 0x54
610
      || (insn & 0xf0) == 0x60
611
      || (insn & 0xf0) == 0x70
612
      || ((insn & 0xf0) == 0x80
613
          && (insn & 0x0c) >> 2 != (insn & 0x03))
614
      || ((insn & 0xf0) == 0x90
615
          && (insn & 0x0c) >> 2 != (insn & 0x03))
616
      || ((insn & 0xf0) == 0xa0
617
          && (insn & 0x0c) >> 2 != (insn & 0x03))
618
      || ((insn & 0xf0) == 0xb0
619
          && (insn & 0x0c) >> 2 != (insn & 0x03))
620
      || (insn & 0xff) == 0xcb
621
      || (insn & 0xfc) == 0xd0
622
      || (insn & 0xfc) == 0xd4
623
      || (insn & 0xfc) == 0xd8
624
      || (insn & 0xf0) == 0xe0
625
      || (insn & 0xff) == 0xff)
626
    {
627
      consume = 1;
628
    }
629
 
630
  /* These are two byte insns.  */
631
  else if ((insn & 0xf0) == 0x80
632
           || (insn & 0xf0) == 0x90
633
           || (insn & 0xf0) == 0xa0
634
           || (insn & 0xf0) == 0xb0
635
           || (insn & 0xfc) == 0x20
636
           || (insn & 0xfc) == 0x28
637
           || (insn & 0xf3) == 0x43
638
           || (insn & 0xf3) == 0x42
639
           || (insn & 0xfc) == 0x58
640
           || (insn & 0xfc) == 0x5c
641
           || ((insn & 0xf0) == 0xc0
642
               && (insn & 0xff) != 0xcb
643
               && (insn & 0xff) != 0xcc
644
               && (insn & 0xff) != 0xcd)
645
           || (insn & 0xff) == 0xf0
646
           || (insn & 0xff) == 0xf1
647
           || (insn & 0xff) == 0xf2
648
           || (insn & 0xff) == 0xf3
649
           || (insn & 0xff) == 0xf4
650
           || (insn & 0xff) == 0xf5
651
           || (insn & 0xff) == 0xf6)
652
    {
653
      status = (*info->read_memory_func) (memaddr, buffer, 2, info);
654
      if (status != 0)
655
        {
656
          (*info->memory_error_func) (status, memaddr, info);
657
          return -1;
658
        }
659
      insn = bfd_getb16 (buffer);
660
      consume = 2;
661
    }
662
 
663
  /* These are three byte insns.  */
664
  else if ((insn & 0xff) == 0xf8
665
           || (insn & 0xff) == 0xcc
666
           || (insn & 0xff) == 0xf9
667
           || (insn & 0xf3) == 0x01
668
           || (insn & 0xf3) == 0x02
669
           || (insn & 0xf3) == 0x03
670
           || (insn & 0xfc) == 0x24
671
           || (insn & 0xfc) == 0x2c
672
           || (insn & 0xfc) == 0x30
673
           || (insn & 0xfc) == 0x34
674
           || (insn & 0xfc) == 0x38
675
           || (insn & 0xff) == 0xde
676
           || (insn & 0xff) == 0xdf
677
           || (insn & 0xff) == 0xf9
678
           || (insn & 0xff) == 0xcc)
679
    {
680
      status = (*info->read_memory_func) (memaddr, buffer, 2, info);
681
      if (status != 0)
682
        {
683
          (*info->memory_error_func) (status, memaddr, info);
684
          return -1;
685
        }
686
      insn = bfd_getb16 (buffer);
687
      insn <<= 8;
688
      status = (*info->read_memory_func) (memaddr + 2, buffer, 1, info);
689
      if (status != 0)
690
        {
691
          (*info->memory_error_func) (status, memaddr, info);
692
          return -1;
693
        }
694
      insn |= *(unsigned char *) buffer;
695
      consume = 3;
696
    }
697
 
698
  /* These are four byte insns.  */
699
  else if ((insn & 0xff) == 0xfa
700
           || (insn & 0xff) == 0xf7
701
           || (insn & 0xff) == 0xfb)
702
    {
703
      status = (*info->read_memory_func) (memaddr, buffer, 4, info);
704
      if (status != 0)
705
        {
706
          (*info->memory_error_func) (status, memaddr, info);
707
          return -1;
708
        }
709
      insn = bfd_getb32 (buffer);
710
      consume = 4;
711
    }
712
 
713
  /* These are five byte insns.  */
714
  else if ((insn & 0xff) == 0xcd
715
           || (insn & 0xff) == 0xdc)
716
    {
717
      status = (*info->read_memory_func) (memaddr, buffer, 4, info);
718
      if (status != 0)
719
        {
720
          (*info->memory_error_func) (status, memaddr, info);
721
          return -1;
722
        }
723
      insn = bfd_getb32 (buffer);
724
      consume = 5;
725
    }
726
 
727
  /* These are six byte insns.  */
728
  else if ((insn & 0xff) == 0xfd
729
           || (insn & 0xff) == 0xfc)
730
    {
731
      status = (*info->read_memory_func) (memaddr, buffer, 4, info);
732
      if (status != 0)
733
        {
734
          (*info->memory_error_func) (status, memaddr, info);
735
          return -1;
736
        }
737
 
738
      insn = bfd_getb32 (buffer);
739
      consume = 6;
740
    }
741
 
742
  /* Else its a seven byte insns (in theory).  */
743
  else
744
    {
745
      status = (*info->read_memory_func) (memaddr, buffer, 4, info);
746
      if (status != 0)
747
        {
748
          (*info->memory_error_func) (status, memaddr, info);
749
          return -1;
750
        }
751
 
752
      insn = bfd_getb32 (buffer);
753
      consume = 7;
754
      /* Handle the 5-byte extended instruction codes.  */
755
      if ((insn & 0xfff80000) == 0xfe800000)
756
        consume = 5;
757
    }
758
 
759
  disassemble (memaddr, info, insn, consume);
760
 
761
  return consume;
762
}

powered by: WebSVN 2.1.0

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