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

Subversion Repositories open8_urisc

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

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

Line No. Rev Author Line
1 18 khays
/* Disassembler code for CRX.
2 166 khays
   Copyright 2004, 2005, 2006, 2007, 2012 Free Software Foundation, Inc.
3 18 khays
   Contributed by Tomer Levi, NSC, Israel.
4
   Written by Tomer Levi.
5
 
6
   This file is part of the GNU opcodes library.
7
 
8
   This library is free software; you can redistribute it and/or modify
9
   it under the terms of the GNU General Public License as published by
10
   the Free Software Foundation; either version 3, or (at your option)
11
   any later version.
12
 
13
   It is distributed in the hope that it will be useful, but WITHOUT
14
   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
15
   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
16
   License for more details.
17
 
18
   You should have received a copy of the GNU General Public License
19
   along with this program; if not, write to the Free Software
20
   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
21
   MA 02110-1301, USA.  */
22
 
23
#include "dis-asm.h"
24
#include "sysdep.h"
25
#include "opcode/crx.h"
26
 
27
/* String to print when opcode was not matched.  */
28
#define ILLEGAL "illegal"
29
  /* Escape to 16-bit immediate.  */
30
#define ESCAPE_16_BIT  0xE
31
 
32
/* Extract 'n_bits' from 'a' starting from offset 'offs'.  */
33
#define EXTRACT(a, offs, n_bits)            \
34
  (n_bits == 32 ? (((a) >> (offs)) & 0xffffffffL)   \
35
  : (((a) >> (offs)) & ((1 << (n_bits)) -1)))
36
 
37
/* Set Bit Mask - a mask to set all bits starting from offset 'offs'.  */
38
#define SBM(offs)  ((((1 << (32 - offs)) -1) << (offs)))
39
 
40
typedef unsigned long dwordU;
41
typedef unsigned short wordU;
42
 
43
typedef struct
44
{
45
  dwordU val;
46
  int nbits;
47
} parameter;
48
 
49
/* Structure to hold valid 'cinv' instruction options.  */
50
 
51
typedef struct
52
  {
53
    /* Cinv printed string.  */
54
    char *str;
55
    /* Value corresponding to the string.  */
56
    unsigned int value;
57
  }
58
cinv_entry;
59
 
60
/* CRX 'cinv' options.  */
61
const cinv_entry crx_cinvs[] =
62
{
63
  {"[i]", 2}, {"[i,u]", 3}, {"[d]", 4}, {"[d,u]", 5},
64
  {"[d,i]", 6}, {"[d,i,u]", 7}, {"[b]", 8},
65
  {"[b,i]", 10}, {"[b,i,u]", 11}, {"[b,d]", 12},
66
  {"[b,d,u]", 13}, {"[b,d,i]", 14}, {"[b,d,i,u]", 15}
67
};
68
 
69
/* Enum to distinguish different registers argument types.  */
70
typedef enum REG_ARG_TYPE
71
  {
72
    /* General purpose register (r<N>).  */
73
    REG_ARG = 0,
74
    /* User register (u<N>).  */
75
    USER_REG_ARG,
76
    /* CO-Processor register (c<N>).  */
77
    COP_ARG,
78
    /* CO-Processor special register (cs<N>).  */
79
    COPS_ARG
80
  }
81
REG_ARG_TYPE;
82
 
83
/* Number of valid 'cinv' instruction options.  */
84
int NUMCINVS = ((sizeof crx_cinvs)/(sizeof crx_cinvs[0]));
85
/* Current opcode table entry we're disassembling.  */
86
const inst *instruction;
87
/* Current instruction we're disassembling.  */
88
ins currInsn;
89
/* The current instruction is read into 3 consecutive words.  */
90
wordU words[3];
91
/* Contains all words in appropriate order.  */
92
ULONGLONG allWords;
93
/* Holds the current processed argument number.  */
94
int processing_argument_number;
95
/* Nonzero means a CST4 instruction.  */
96
int cst4flag;
97
/* Nonzero means the instruction's original size is
98
   incremented (escape sequence is used).  */
99
int size_changed;
100
 
101
static int get_number_of_operands (void);
102
static argtype getargtype     (operand_type);
103
static int getbits            (operand_type);
104
static char *getregname       (reg);
105
static char *getcopregname    (copreg, reg_type);
106
static char * getprocregname  (int);
107
static char *gettrapstring    (unsigned);
108
static char *getcinvstring    (unsigned);
109
static void getregliststring  (int, char *, enum REG_ARG_TYPE);
110
static wordU get_word_at_PC   (bfd_vma, struct disassemble_info *);
111
static void get_words_at_PC   (bfd_vma, struct disassemble_info *);
112
static unsigned long build_mask (void);
113
static int powerof2           (int);
114
static int match_opcode       (void);
115
static void make_instruction  (void);
116
static void print_arguments   (ins *, bfd_vma, struct disassemble_info *);
117
static void print_arg         (argument *, bfd_vma, struct disassemble_info *);
118
 
119
/* Retrieve the number of operands for the current assembled instruction.  */
120
 
121
static int
122
get_number_of_operands (void)
123
{
124
  int i;
125
 
126
  for (i = 0; instruction->operands[i].op_type && i < MAX_OPERANDS; i++)
127
    ;
128
 
129
  return i;
130
}
131
 
132
/* Return the bit size for a given operand.  */
133
 
134
static int
135
getbits (operand_type op)
136
{
137
  if (op < MAX_OPRD)
138
    return crx_optab[op].bit_size;
139
  else
140
    return 0;
141
}
142
 
143
/* Return the argument type of a given operand.  */
144
 
145
static argtype
146
getargtype (operand_type op)
147
{
148
  if (op < MAX_OPRD)
149
    return crx_optab[op].arg_type;
150
  else
151
    return nullargs;
152
}
153
 
154
/* Given the trap index in dispatch table, return its name.
155
   This routine is used when disassembling the 'excp' instruction.  */
156
 
157
static char *
158
gettrapstring (unsigned int trap_index)
159
{
160
  const trap_entry *trap;
161
 
162
  for (trap = crx_traps; trap < crx_traps + NUMTRAPS; trap++)
163
    if (trap->entry == trap_index)
164
      return trap->name;
165
 
166
  return ILLEGAL;
167
}
168
 
169
/* Given a 'cinv' instruction constant operand, return its corresponding string.
170
   This routine is used when disassembling the 'cinv' instruction.  */
171
 
172
static char *
173
getcinvstring (unsigned int num)
174
{
175
  const cinv_entry *cinv;
176
 
177
  for (cinv = crx_cinvs; cinv < (crx_cinvs + NUMCINVS); cinv++)
178
    if (cinv->value == num)
179
      return cinv->str;
180
 
181
  return ILLEGAL;
182
}
183
 
184
/* Given a register enum value, retrieve its name.  */
185
 
186
char *
187
getregname (reg r)
188
{
189
  const reg_entry * regentry = &crx_regtab[r];
190
 
191
  if (regentry->type != CRX_R_REGTYPE)
192
    return ILLEGAL;
193
  else
194
    return regentry->name;
195
}
196
 
197
/* Given a coprocessor register enum value, retrieve its name.  */
198
 
199
char *
200
getcopregname (copreg r, reg_type type)
201
{
202
  const reg_entry * regentry;
203
 
204
  if (type == CRX_C_REGTYPE)
205
    regentry = &crx_copregtab[r];
206
  else if (type == CRX_CS_REGTYPE)
207
    regentry = &crx_copregtab[r+(cs0-c0)];
208
  else
209
    return ILLEGAL;
210
 
211
  return regentry->name;
212
}
213
 
214
 
215
/* Getting a processor register name.  */
216
 
217
static char *
218
getprocregname (int reg_index)
219
{
220
  const reg_entry *r;
221
 
222
  for (r = crx_regtab; r < crx_regtab + NUMREGS; r++)
223
    if (r->image == reg_index)
224
      return r->name;
225
 
226
  return "ILLEGAL REGISTER";
227
}
228
 
229
/* Get the power of two for a given integer.  */
230
 
231
static int
232
powerof2 (int x)
233
{
234
  int product, i;
235
 
236
  for (i = 0, product = 1; i < x; i++)
237
    product *= 2;
238
 
239
  return product;
240
}
241
 
242
/* Transform a register bit mask to a register list.  */
243
 
244
void
245
getregliststring (int mask, char *string, enum REG_ARG_TYPE core_cop)
246
{
247
  char temp_string[5];
248
  int i;
249
 
250
  string[0] = '{';
251
  string[1] = '\0';
252
 
253
 
254
  /* A zero mask means HI/LO registers.  */
255
  if (mask == 0)
256
    {
257
      if (core_cop == USER_REG_ARG)
258
        strcat (string, "ulo,uhi");
259
      else
260
        strcat (string, "lo,hi");
261
    }
262
  else
263
    {
264
      for (i = 0; i < 16; i++)
265
        {
266
          if (mask & 0x1)
267
            {
268
              switch (core_cop)
269
              {
270
              case REG_ARG:
271
                sprintf (temp_string, "r%d", i);
272
                break;
273
              case USER_REG_ARG:
274
                sprintf (temp_string, "u%d", i);
275
                break;
276
              case COP_ARG:
277
                sprintf (temp_string, "c%d", i);
278
                break;
279
              case COPS_ARG:
280
                sprintf (temp_string, "cs%d", i);
281
                break;
282
              default:
283
                break;
284
              }
285
              strcat (string, temp_string);
286
              if (mask & 0xfffe)
287
                strcat (string, ",");
288
            }
289
          mask >>= 1;
290
        }
291
    }
292
 
293
  strcat (string, "}");
294
}
295
 
296
/* START and END are relating 'allWords' struct, which is 48 bits size.
297
 
298
                          START|--------|END
299
            +---------+---------+---------+---------+
300
            |         |    V    |     A   |   L     |
301
            +---------+---------+---------+---------+
302
 
303
    words                 [0]       [1]       [2]       */
304
 
305
static parameter
306
makelongparameter (ULONGLONG val, int start, int end)
307
{
308
  parameter p;
309
 
310
  p.val = (dwordU) EXTRACT(val, 48 - end, end - start);
311
  p.nbits = end - start;
312
  return p;
313
}
314
 
315
/* Build a mask of the instruction's 'constant' opcode,
316
   based on the instruction's printing flags.  */
317
 
318
static unsigned long
319
build_mask (void)
320
{
321
  unsigned int print_flags;
322
  unsigned long mask;
323
 
324
  print_flags = instruction->flags & FMT_CRX;
325
  switch (print_flags)
326
    {
327
      case FMT_1:
328
        mask = 0xF0F00000;
329
        break;
330
      case FMT_2:
331
        mask = 0xFFF0FF00;
332
        break;
333
      case FMT_3:
334
        mask = 0xFFF00F00;
335
        break;
336
      case FMT_4:
337
        mask = 0xFFF0F000;
338
        break;
339
      case FMT_5:
340
        mask = 0xFFF0FFF0;
341
        break;
342
      default:
343
        mask = SBM(instruction->match_bits);
344
        break;
345
    }
346
 
347
  return mask;
348
}
349
 
350
/* Search for a matching opcode. Return 1 for success, 0 for failure.  */
351
 
352
static int
353
match_opcode (void)
354
{
355
  unsigned long mask;
356
 
357
  /* The instruction 'constant' opcode doewsn't exceed 32 bits.  */
358
  unsigned long doubleWord = (words[1] + (words[0] << 16)) & 0xffffffff;
359
 
360
  /* Start searching from end of instruction table.  */
361
  instruction = &crx_instruction[NUMOPCODES - 2];
362
 
363
  /* Loop over instruction table until a full match is found.  */
364
  while (instruction >= crx_instruction)
365
    {
366
      mask = build_mask ();
367
      if ((doubleWord & mask) == BIN(instruction->match, instruction->match_bits))
368
        return 1;
369
      else
370
        instruction--;
371
    }
372
  return 0;
373
}
374
 
375
/* Set the proper parameter value for different type of arguments.  */
376
 
377
static void
378
make_argument (argument * a, int start_bits)
379
{
380
  int inst_bit_size, total_size;
381
  parameter p;
382
 
383
  if ((instruction->size == 3) && a->size >= 16)
384
    inst_bit_size = 48;
385
  else
386
    inst_bit_size = 32;
387
 
388
  switch (a->type)
389
    {
390
    case arg_copr:
391
    case arg_copsr:
392
      p = makelongparameter (allWords, inst_bit_size - (start_bits + a->size),
393
                             inst_bit_size - start_bits);
394
      a->cr = p.val;
395
      break;
396
 
397
    case arg_r:
398
      p = makelongparameter (allWords, inst_bit_size - (start_bits + a->size),
399
                             inst_bit_size - start_bits);
400
      a->r = p.val;
401
      break;
402
 
403
    case arg_ic:
404
      p = makelongparameter (allWords, inst_bit_size - (start_bits + a->size),
405
                             inst_bit_size - start_bits);
406
 
407
      if ((p.nbits == 4) && cst4flag)
408
        {
409
          if (IS_INSN_TYPE (CMPBR_INS) && (p.val == ESCAPE_16_BIT))
410
            {
411
              /* A special case, where the value is actually stored
412
                 in the last 4 bits.  */
413
              p = makelongparameter (allWords, 44, 48);
414
              /* The size of the instruction should be incremented.  */
415
              size_changed = 1;
416
            }
417
 
418
          if (p.val == 6)
419
            p.val = -1;
420
          else if (p.val == 13)
421
            p.val = 48;
422
          else if (p.val == 5)
423
            p.val = -4;
424
          else if (p.val == 10)
425
            p.val = 32;
426
          else if (p.val == 11)
427
            p.val = 20;
428
          else if (p.val == 9)
429
            p.val = 16;
430
        }
431
 
432
      a->constant = p.val;
433
      break;
434
 
435
    case arg_idxr:
436
      a->scale = 0;
437
      total_size = a->size + 10;  /* sizeof(rbase + ridx + scl2) = 10.  */
438
      p = makelongparameter (allWords, inst_bit_size - total_size,
439
                             inst_bit_size - (total_size - 4));
440
      a->r = p.val;
441
      p = makelongparameter (allWords, inst_bit_size - (total_size - 4),
442
                             inst_bit_size - (total_size - 8));
443
      a->i_r = p.val;
444
      p = makelongparameter (allWords, inst_bit_size - (total_size - 8),
445
                             inst_bit_size - (total_size - 10));
446
      a->scale = p.val;
447
      p = makelongparameter (allWords, inst_bit_size - (total_size - 10),
448
                             inst_bit_size);
449
      a->constant = p.val;
450
      break;
451
 
452
    case arg_rbase:
453
      p = makelongparameter (allWords, inst_bit_size - (start_bits + 4),
454
                             inst_bit_size - start_bits);
455
      a->r = p.val;
456
      break;
457
 
458
    case arg_cr:
459
      if (a->size <= 8)
460
        {
461
          p = makelongparameter (allWords, inst_bit_size - (start_bits + 4),
462
                                 inst_bit_size - start_bits);
463
          a->r = p.val;
464
          /* Case for opc4 r dispu rbase.  */
465
          p = makelongparameter (allWords, inst_bit_size - (start_bits + 8),
466
                                 inst_bit_size - (start_bits + 4));
467
        }
468
      else
469
        {
470
          /* The 'rbase' start_bits is always relative to a 32-bit data type.  */
471
          p = makelongparameter (allWords, 32 - (start_bits + 4),
472
                                 32 - start_bits);
473
          a->r = p.val;
474
          p = makelongparameter (allWords, 32 - start_bits,
475
                                 inst_bit_size);
476
        }
477
      if ((p.nbits == 4) && cst4flag)
478
        {
479
          if (instruction->flags & DISPUW4)
480
            p.val *= 2;
481
          else if (instruction->flags & DISPUD4)
482
            p.val *= 4;
483
        }
484
      a->constant = p.val;
485
      break;
486
 
487
    case arg_c:
488
      p = makelongparameter (allWords, inst_bit_size - (start_bits + a->size),
489
                             inst_bit_size - start_bits);
490
      a->constant = p.val;
491
      break;
492
    default:
493
      break;
494
    }
495
}
496
 
497
/*  Print a single argument.  */
498
 
499
static void
500
print_arg (argument *a, bfd_vma memaddr, struct disassemble_info *info)
501
{
502
  LONGLONG longdisp, mask;
503
  int sign_flag = 0;
504
  int relative = 0;
505
  bfd_vma number;
506
  int op_index = 0;
507
  char string[200];
508
  PTR stream = info->stream;
509
  fprintf_ftype func = info->fprintf_func;
510
 
511
  switch (a->type)
512
    {
513
    case arg_copr:
514
      func (stream, "%s", getcopregname (a->cr, CRX_C_REGTYPE));
515
      break;
516
 
517
    case arg_copsr:
518
      func (stream, "%s", getcopregname (a->cr, CRX_CS_REGTYPE));
519
      break;
520
 
521
    case arg_r:
522
      if (IS_INSN_MNEMONIC ("mtpr") || IS_INSN_MNEMONIC ("mfpr"))
523
        func (stream, "%s", getprocregname (a->r));
524
      else
525
        func (stream, "%s", getregname (a->r));
526
      break;
527
 
528
    case arg_ic:
529
      if (IS_INSN_MNEMONIC ("excp"))
530
        func (stream, "%s", gettrapstring (a->constant));
531
 
532
      else if (IS_INSN_MNEMONIC ("cinv"))
533
        func (stream, "%s", getcinvstring (a->constant));
534
 
535
      else if (INST_HAS_REG_LIST)
536
        {
537
          REG_ARG_TYPE reg_arg_type = IS_INSN_TYPE (COP_REG_INS) ?
538
                                 COP_ARG : IS_INSN_TYPE (COPS_REG_INS) ?
539
                                 COPS_ARG : (instruction->flags & USER_REG) ?
540
                                 USER_REG_ARG : REG_ARG;
541
 
542
          if ((reg_arg_type == COP_ARG) || (reg_arg_type == COPS_ARG))
543
            {
544
                /*  Check for proper argument number.  */
545
                if (processing_argument_number == 2)
546
                  {
547
                    getregliststring (a->constant, string, reg_arg_type);
548
                    func (stream, "%s", string);
549
                  }
550
                else
551 166 khays
                  func (stream, "$0x%lx", a->constant & 0xffffffff);
552 18 khays
            }
553
          else
554
            {
555
              getregliststring (a->constant, string, reg_arg_type);
556
              func (stream, "%s", string);
557
            }
558
        }
559
      else
560 166 khays
        func (stream, "$0x%lx", a->constant & 0xffffffff);
561 18 khays
      break;
562
 
563
    case arg_idxr:
564 166 khays
      func (stream, "0x%lx(%s,%s,%d)", a->constant & 0xffffffff,
565
            getregname (a->r), getregname (a->i_r), powerof2 (a->scale));
566 18 khays
      break;
567
 
568
    case arg_rbase:
569
      func (stream, "(%s)", getregname (a->r));
570
      break;
571
 
572
    case arg_cr:
573 166 khays
      func (stream, "0x%lx(%s)", a->constant & 0xffffffff, getregname (a->r));
574 18 khays
 
575
      if (IS_INSN_TYPE (LD_STOR_INS_INC))
576
        func (stream, "+");
577
      break;
578
 
579
    case arg_c:
580
      /* Removed the *2 part as because implicit zeros are no more required.
581
         Have to fix this as this needs a bit of extension in terms of branchins.
582
         Have to add support for cmp and branch instructions.  */
583
      if (IS_INSN_TYPE (BRANCH_INS) || IS_INSN_MNEMONIC ("bal")
584
          || IS_INSN_TYPE (CMPBR_INS) || IS_INSN_TYPE (DCR_BRANCH_INS)
585
          || IS_INSN_TYPE (COP_BRANCH_INS))
586
        {
587
          relative = 1;
588
          longdisp = a->constant;
589
          longdisp <<= 1;
590
 
591
          switch (a->size)
592
            {
593
            case 8:
594
            case 16:
595
            case 24:
596
            case 32:
597
              mask = ((LONGLONG)1 << a->size) - 1;
598
              if (longdisp & ((LONGLONG)1 << a->size))
599
                {
600
                  sign_flag = 1;
601
                  longdisp = ~(longdisp) + 1;
602
                }
603
              a->constant = (unsigned long int) (longdisp & mask);
604
              break;
605
            default:
606
              func (stream,
607
                    "Wrong offset used in branch/bal instruction");
608
              break;
609
            }
610
 
611
        }
612
      /* For branch Neq instruction it is 2*offset + 2.  */
613
      else if (IS_INSN_TYPE (BRANCH_NEQ_INS))
614
        a->constant = 2 * a->constant + 2;
615
      else if (IS_INSN_TYPE (LD_STOR_INS_INC)
616
          || IS_INSN_TYPE (LD_STOR_INS)
617
          || IS_INSN_TYPE (STOR_IMM_INS)
618
          || IS_INSN_TYPE (CSTBIT_INS))
619
        {
620
          op_index = instruction->flags & REVERSE_MATCH ? 0 : 1;
621
          if (instruction->operands[op_index].op_type == abs16)
622
            a->constant |= 0xFFFF0000;
623
        }
624
      func (stream, "%s", "0x");
625
      number = (relative ? memaddr : 0)
626
               + (sign_flag ? -a->constant : a->constant);
627
      (*info->print_address_func) (number, info);
628
      break;
629
    default:
630
      break;
631
    }
632
}
633
 
634
/* Print all the arguments of CURRINSN instruction.  */
635
 
636
static void
637
print_arguments (ins *currentInsn, bfd_vma memaddr, struct disassemble_info *info)
638
{
639
  int i;
640
 
641
  for (i = 0; i < currentInsn->nargs; i++)
642
    {
643
      processing_argument_number = i;
644
 
645
      print_arg (&currentInsn->arg[i], memaddr, info);
646
 
647
      if (i != currentInsn->nargs - 1)
648
        info->fprintf_func (info->stream, ", ");
649
    }
650
}
651
 
652
/* Build the instruction's arguments.  */
653
 
654
static void
655
make_instruction (void)
656
{
657
  int i;
658
  unsigned int shift;
659
 
660
  for (i = 0; i < currInsn.nargs; i++)
661
    {
662
      argument a;
663
 
664
      memset (&a, 0, sizeof (a));
665
      a.type = getargtype (instruction->operands[i].op_type);
666
      if (instruction->operands[i].op_type == cst4
667
          || instruction->operands[i].op_type == rbase_dispu4)
668
        cst4flag = 1;
669
      a.size = getbits (instruction->operands[i].op_type);
670
      shift = instruction->operands[i].shift;
671
 
672
      make_argument (&a, shift);
673
      currInsn.arg[i] = a;
674
    }
675
 
676
  /* Calculate instruction size (in bytes).  */
677
  currInsn.size = instruction->size + (size_changed ? 1 : 0);
678
  /* Now in bits.  */
679
  currInsn.size *= 2;
680
}
681
 
682
/* Retrieve a single word from a given memory address.  */
683
 
684
static wordU
685
get_word_at_PC (bfd_vma memaddr, struct disassemble_info *info)
686
{
687
  bfd_byte buffer[4];
688
  int status;
689
  wordU insn = 0;
690
 
691
  status = info->read_memory_func (memaddr, buffer, 2, info);
692
 
693
  if (status == 0)
694
    insn = (wordU) bfd_getl16 (buffer);
695
 
696
  return insn;
697
}
698
 
699
/* Retrieve multiple words (3) from a given memory address.  */
700
 
701
static void
702
get_words_at_PC (bfd_vma memaddr, struct disassemble_info *info)
703
{
704
  int i;
705
  bfd_vma mem;
706
 
707
  for (i = 0, mem = memaddr; i < 3; i++, mem += 2)
708
    words[i] = get_word_at_PC (mem, info);
709
 
710
  allWords =
711
    ((ULONGLONG) words[0] << 32) + ((unsigned long) words[1] << 16) + words[2];
712
}
713
 
714
/* Prints the instruction by calling print_arguments after proper matching.  */
715
 
716
int
717
print_insn_crx (memaddr, info)
718
     bfd_vma memaddr;
719
     struct disassemble_info *info;
720
{
721
  int is_decoded;     /* Nonzero means instruction has a match.  */
722
 
723
  /* Initialize global variables.  */
724
  cst4flag = 0;
725
  size_changed = 0;
726
 
727
  /* Retrieve the encoding from current memory location.  */
728
  get_words_at_PC (memaddr, info);
729
  /* Find a matching opcode in table.  */
730
  is_decoded = match_opcode ();
731
  /* If found, print the instruction's mnemonic and arguments.  */
732
  if (is_decoded > 0 && (words[0] << 16 || words[1]) != 0)
733
    {
734
      info->fprintf_func (info->stream, "%s", instruction->mnemonic);
735
      if ((currInsn.nargs = get_number_of_operands ()) != 0)
736
        info->fprintf_func (info->stream, "\t");
737
      make_instruction ();
738
      print_arguments (&currInsn, memaddr, info);
739
      return currInsn.size;
740
    }
741
 
742
  /* No match found.  */
743
  info->fprintf_func (info->stream,"%s ",ILLEGAL);
744
  return 2;
745
}

powered by: WebSVN 2.1.0

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