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

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [gnu-src/] [gdb-6.8/] [opcodes/] [mep-dis.c] - Blame information for rev 294

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

Line No. Rev Author Line
1 24 jeremybenn
/* Disassembler interface for targets using CGEN. -*- C -*-
2
   CGEN: Cpu tools GENerator
3
 
4
   THIS FILE IS MACHINE GENERATED WITH CGEN.
5
   - the resultant file is machine generated, cgen-dis.in isn't
6
 
7 225 jeremybenn
   Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2005, 2007,
8
   2008  Free Software Foundation, Inc.
9 24 jeremybenn
 
10
   This file is part of libopcodes.
11
 
12
   This library is free software; you can redistribute it and/or modify
13
   it under the terms of the GNU General Public License as published by
14
   the Free Software Foundation; either version 3, or (at your option)
15
   any later version.
16
 
17
   It is distributed in the hope that it will be useful, but WITHOUT
18
   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
19
   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
20
   License for more details.
21
 
22
   You should have received a copy of the GNU General Public License
23
   along with this program; if not, write to the Free Software Foundation, Inc.,
24
   51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.  */
25
 
26
/* ??? Eventually more and more of this stuff can go to cpu-independent files.
27
   Keep that in mind.  */
28
 
29
#include "sysdep.h"
30
#include <stdio.h>
31
#include "ansidecl.h"
32
#include "dis-asm.h"
33
#include "bfd.h"
34
#include "symcat.h"
35
#include "libiberty.h"
36
#include "mep-desc.h"
37
#include "mep-opc.h"
38
#include "opintl.h"
39
 
40
/* Default text to print if an instruction isn't recognized.  */
41
#define UNKNOWN_INSN_MSG _("*unknown*")
42
 
43
static void print_normal
44
  (CGEN_CPU_DESC, void *, long, unsigned int, bfd_vma, int);
45
static void print_address
46
  (CGEN_CPU_DESC, void *, bfd_vma, unsigned int, bfd_vma, int) ATTRIBUTE_UNUSED;
47
static void print_keyword
48
  (CGEN_CPU_DESC, void *, CGEN_KEYWORD *, long, unsigned int) ATTRIBUTE_UNUSED;
49
static void print_insn_normal
50
  (CGEN_CPU_DESC, void *, const CGEN_INSN *, CGEN_FIELDS *, bfd_vma, int);
51
static int print_insn
52
  (CGEN_CPU_DESC, bfd_vma,  disassemble_info *, bfd_byte *, unsigned);
53
static int default_print_insn
54
  (CGEN_CPU_DESC, bfd_vma, disassemble_info *) ATTRIBUTE_UNUSED;
55
static int read_insn
56
  (CGEN_CPU_DESC, bfd_vma, disassemble_info *, bfd_byte *, int, CGEN_EXTRACT_INFO *,
57
   unsigned long *);
58
 
59
/* -- disassembler routines inserted here.  */
60
 
61
/* -- dis.c */
62
 
63
#include "elf/mep.h"
64
#include "elf-bfd.h"
65
 
66
#define CGEN_VALIDATE_INSN_SUPPORTED
67
 
68
static void print_tpreg (CGEN_CPU_DESC, PTR, CGEN_KEYWORD *, long, unsigned int);
69
static void print_spreg (CGEN_CPU_DESC, PTR, CGEN_KEYWORD *, long, unsigned int);
70
 
71
static void
72
print_tpreg (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED, PTR dis_info,
73
             CGEN_KEYWORD *table ATTRIBUTE_UNUSED, long val ATTRIBUTE_UNUSED,
74
             unsigned int flags ATTRIBUTE_UNUSED)
75
{
76
  disassemble_info *info = (disassemble_info *) dis_info;
77
 
78
  (*info->fprintf_func) (info->stream, "$tp");
79
}
80
 
81
static void
82
print_spreg (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED, PTR dis_info,
83
             CGEN_KEYWORD *table ATTRIBUTE_UNUSED, long val ATTRIBUTE_UNUSED,
84
             unsigned int flags ATTRIBUTE_UNUSED)
85
{
86
  disassemble_info *info = (disassemble_info *) dis_info;
87
 
88
  (*info->fprintf_func) (info->stream, "$sp");
89
}
90
 
91
/* begin-cop-ip-print-handlers */
92
static void
93 225 jeremybenn
print_ivc2_cr (CGEN_CPU_DESC,
94
        void *,
95
        CGEN_KEYWORD *,
96
        long,
97
        unsigned int) ATTRIBUTE_UNUSED;
98
static void
99
print_ivc2_cr (CGEN_CPU_DESC cd,
100 24 jeremybenn
        void *dis_info,
101
        CGEN_KEYWORD *keyword_table ATTRIBUTE_UNUSED,
102
        long value,
103
        unsigned int attrs)
104
{
105 225 jeremybenn
  print_keyword (cd, dis_info, & mep_cgen_opval_h_cr_ivc2, value, attrs);
106 24 jeremybenn
}
107
static void
108 225 jeremybenn
print_ivc2_ccr (CGEN_CPU_DESC,
109
        void *,
110
        CGEN_KEYWORD *,
111
        long,
112
        unsigned int) ATTRIBUTE_UNUSED;
113
static void
114
print_ivc2_ccr (CGEN_CPU_DESC cd,
115 24 jeremybenn
        void *dis_info,
116
        CGEN_KEYWORD *keyword_table ATTRIBUTE_UNUSED,
117
        long value,
118
        unsigned int attrs)
119
{
120 225 jeremybenn
  print_keyword (cd, dis_info, & mep_cgen_opval_h_ccr_ivc2, value, attrs);
121 24 jeremybenn
}
122
/* end-cop-ip-print-handlers */
123
 
124
/************************************************************\
125
*********************** Experimental *************************
126
\************************************************************/
127
 
128
#undef  CGEN_PRINT_INSN
129
#define CGEN_PRINT_INSN mep_print_insn
130
 
131
static int
132
mep_print_vliw_insns (CGEN_CPU_DESC cd, bfd_vma pc, disassemble_info *info,
133
                      bfd_byte *buf, int corelength, int copro1length,
134
                      int copro2length ATTRIBUTE_UNUSED)
135
{
136
  int i;
137
  int status = 0;
138
  /* char insnbuf[CGEN_MAX_INSN_SIZE]; */
139
  bfd_byte insnbuf[64];
140
 
141
  /* If corelength > 0 then there is a core insn present. It
142
     will be at the beginning of the buffer.  After printing
143
     the core insn, we need to print the + on the next line.  */
144
  if (corelength > 0)
145
    {
146
      int my_status = 0;
147
 
148
      for (i = 0; i < corelength; i++ )
149
        insnbuf[i] = buf[i];
150
      cd->isas = & MEP_CORE_ISA;
151
 
152
      my_status = print_insn (cd, pc, info, insnbuf, corelength);
153
      if (my_status != corelength)
154
        {
155
          (*info->fprintf_func) (info->stream, UNKNOWN_INSN_MSG);
156
          my_status = corelength;
157
        }
158
      status += my_status;
159
 
160
      /* Print the + to indicate that the following copro insn is   */
161
      /* part of a vliw group.                                      */
162
      if (copro1length > 0)
163
        (*info->fprintf_func) (info->stream, " + ");
164
    }
165
 
166
  /* Now all that is left to be processed is the coprocessor insns
167
     In vliw mode, there will always be one.  Its positioning will
168
     be from byte corelength to byte corelength+copro1length -1.
169
     No need to check for existence.   Also, the first vliw insn,
170
     will, as spec'd, always be at least as long as the core insn
171
     so we don't need to flush the buffer.  */
172
  if (copro1length > 0)
173
    {
174
      int my_status = 0;
175
 
176
      for (i = corelength; i < corelength + copro1length; i++ )
177
        insnbuf[i - corelength] = buf[i];
178
 
179
      switch (copro1length)
180
        {
181
        case 0:
182
          break;
183
        case 2:
184
          cd->isas = & MEP_COP16_ISA;
185
          break;
186
        case 4:
187
          cd->isas = & MEP_COP32_ISA;
188
          break;
189
        case 6:
190
          cd->isas = & MEP_COP48_ISA;
191
          break;
192
        case 8:
193
          cd->isas = & MEP_COP64_ISA;
194
          break;
195
        default:
196
          /* Shouldn't be anything but 16,32,48,64.  */
197
          break;
198
        }
199
 
200
      my_status = print_insn (cd, pc, info, insnbuf, copro1length);
201
 
202
      if (my_status != copro1length)
203
        {
204
          (*info->fprintf_func) (info->stream, UNKNOWN_INSN_MSG);
205
          my_status = copro1length;
206
        }
207
      status += my_status;
208
    }
209
 
210
#if 0
211
  /* Now we need to process the second copro insn if it exists. We
212
     have no guarantee that the second copro insn will be longer
213
     than the first, so we have to flush the buffer if we are have
214
     a second copro insn to process.  If present, this insn will
215
     be in the position from byte corelength+copro1length to byte
216
     corelength+copro1length+copro2length-1 (which better equal 8
217
     or else we're in big trouble.  */
218
  if (copro2length > 0)
219
    {
220
      int my_status = 0;
221
 
222
      for (i = 0; i < 64 ; i++)
223
        insnbuf[i] = 0;
224
 
225
      for (i = corelength + copro1length; i < 64; i++)
226
        insnbuf[i - (corelength + copro1length)] = buf[i];
227
 
228
      switch (copro2length)
229
        {
230
        case 2:
231
          cd->isas = 1 << ISA_EXT_COP1_16;
232
          break;
233
        case 4:
234
          cd->isas = 1 << ISA_EXT_COP1_32;
235
          break;
236
        case 6:
237
          cd->isas = 1 << ISA_EXT_COP1_48;
238
          break;
239
        case 8:
240
          cd->isas = 1 << ISA_EXT_COP1_64;
241
          break;
242
        default:
243
          /* Shouldn't be anything but 16,32,48,64.  */
244
          break;
245
        }
246
 
247
      my_status = print_insn (cd, pc, info, insnbuf, copro2length);
248
 
249
      if (my_status != copro2length)
250
        {
251
          (*info->fprintf_func) (info->stream, UNKNOWN_INSN_MSG);
252
          my_status = copro2length;
253
        }
254
 
255
      status += my_status;
256
    }
257
#endif
258
 
259
  /* Status should now be the number of bytes that were printed
260
     which should be 4 for VLIW32 mode and 64 for VLIW64 mode.  */
261
 
262
  if ((!MEP_VLIW64 && (status != 4)) || (MEP_VLIW64 && (status != 8)))
263
    return -1;
264
  else
265
    return status;
266
}
267
 
268
/* The two functions mep_examine_vliw[32,64]_insns are used find out
269
   which vliw combinaion (16 bit core with 48 bit copro, 32 bit core
270
   with 32 bit copro, etc.) is present.  Later on, when internally
271
   parallel coprocessors are handled, only these functions should
272
   need to be changed.
273
 
274
   At this time only the following combinations are supported:
275
 
276
   VLIW32 Mode:
277
   16 bit core insn (core) and 16 bit coprocessor insn (cop1)
278
   32 bit core insn (core)
279
   32 bit coprocessor insn (cop1)
280
   Note: As of this time, I do not believe we have enough information
281
         to distinguish a 32 bit core insn from a 32 bit cop insn. Also,
282
         no 16 bit coprocessor insns have been specified.
283
 
284
   VLIW64 Mode:
285
   16 bit core insn (core) and 48 bit coprocessor insn (cop1)
286
   32 bit core insn (core) and 32 bit coprocessor insn (cop1)
287
   64 bit coprocessor insn (cop1)
288
 
289
   The framework for an internally parallel coprocessor is also
290
   present (2nd coprocessor insn is cop2), but at this time it
291
   is not used.  This only appears to be valid in VLIW64 mode.  */
292
 
293
static int
294
mep_examine_vliw32_insns (CGEN_CPU_DESC cd, bfd_vma pc, disassemble_info *info)
295
{
296
  int status;
297
  int buflength;
298
  int corebuflength;
299
  int cop1buflength;
300
  int cop2buflength;
301
  bfd_byte buf[CGEN_MAX_INSN_SIZE];
302
  char indicator16[1];
303
  char indicatorcop32[2];
304
 
305
  /* At this time we're not supporting internally parallel coprocessors,
306
     so cop2buflength will always be 0.  */
307
  cop2buflength = 0;
308
 
309
  /* Read in 32 bits.  */
310
  buflength = 4; /* VLIW insn spans 4 bytes.  */
311
  status = (*info->read_memory_func) (pc, buf, buflength, info);
312
 
313
  if (status != 0)
314
    {
315
      (*info->memory_error_func) (status, pc, info);
316
      return -1;
317
    }
318
 
319
  /* Put the big endian representation of the bytes to be examined
320
     in the temporary buffers for examination.  */
321
 
322
  if (info->endian == BFD_ENDIAN_BIG)
323
    {
324
      indicator16[0] = buf[0];
325
      indicatorcop32[0] = buf[0];
326
      indicatorcop32[1] = buf[1];
327
    }
328
  else
329
    {
330
      indicator16[0] = buf[1];
331
      indicatorcop32[0] = buf[1];
332
      indicatorcop32[1] = buf[0];
333
    }
334
 
335
  /* If the two high order bits are 00, 01 or 10, we have a 16 bit
336
     core insn and a 48 bit copro insn.  */
337
 
338
  if ((indicator16[0] & 0x80) && (indicator16[0] & 0x40))
339
    {
340
      if ((indicatorcop32[0] & 0xf0) == 0xf0 && (indicatorcop32[1] & 0x07) == 0x07)
341
        {
342
          /* We have a 32 bit copro insn.  */
343
          corebuflength = 0;
344
          /* All 4 4ytes are one copro insn. */
345
          cop1buflength = 4;
346
        }
347
      else
348
        {
349
          /* We have a 32 bit core.  */
350
          corebuflength = 4;
351
          cop1buflength = 0;
352
        }
353
    }
354
  else
355
    {
356
      /* We have a 16 bit core insn and a 16 bit copro insn.  */
357
      corebuflength = 2;
358
      cop1buflength = 2;
359
    }
360
 
361
  /* Now we have the distrubution set.  Print them out.  */
362
  status = mep_print_vliw_insns (cd, pc, info, buf, corebuflength,
363
                                 cop1buflength, cop2buflength);
364
 
365
  return status;
366
}
367
 
368
static int
369
mep_examine_vliw64_insns (CGEN_CPU_DESC cd, bfd_vma pc, disassemble_info *info)
370
{
371
  int status;
372
  int buflength;
373
  int corebuflength;
374
  int cop1buflength;
375
  int cop2buflength;
376
  bfd_byte buf[CGEN_MAX_INSN_SIZE];
377
  char indicator16[1];
378
  char indicator64[4];
379
 
380
  /* At this time we're not supporting internally parallel
381
     coprocessors, so cop2buflength will always be 0.  */
382
  cop2buflength = 0;
383
 
384
  /* Read in 64 bits.  */
385
  buflength = 8; /* VLIW insn spans 8 bytes.  */
386
  status = (*info->read_memory_func) (pc, buf, buflength, info);
387
 
388
  if (status != 0)
389
    {
390
      (*info->memory_error_func) (status, pc, info);
391
      return -1;
392
    }
393
 
394
  /* We have all 64 bits in the buffer now.  We have to figure out
395
     what combination of instruction sizes are present.  The two
396
     high order bits will indicate whether or not we have a 16 bit
397
     core insn or not.  If not, then we have to look at the 7,8th
398
     bytes to tell whether we have 64 bit copro insn or a 32 bit
399
     core insn with a 32 bit copro insn.  Endianness will make a
400
     difference here.  */
401
 
402
  /* Put the big endian representation of the bytes to be examined
403
     in the temporary buffers for examination.  */
404
 
405
  /* indicator16[0] = buf[0];  */
406
  if (info->endian == BFD_ENDIAN_BIG)
407
    {
408
      indicator16[0] = buf[0];
409
      indicator64[0] = buf[0];
410
      indicator64[1] = buf[1];
411
      indicator64[2] = buf[2];
412
      indicator64[3] = buf[3];
413
    }
414
  else
415
    {
416
      indicator16[0] = buf[1];
417
      indicator64[0] = buf[1];
418
      indicator64[1] = buf[0];
419
      indicator64[2] = buf[3];
420
      indicator64[3] = buf[2];
421
    }
422
 
423
  /* If the two high order bits are 00, 01 or 10, we have a 16 bit
424
     core insn and a 48 bit copro insn.  */
425
 
426
  if ((indicator16[0] & 0x80) && (indicator16[0] & 0x40))
427
    {
428
      if ((indicator64[0] & 0xf0) == 0xf0 && (indicator64[1] & 0x07) == 0x07
429
          && ((indicator64[2] & 0xfe) != 0xf0 || (indicator64[3] & 0xf4) != 0))
430
        {
431
          /* We have a 64 bit copro insn.  */
432
          corebuflength = 0;
433
          /* All 8 bytes are one copro insn.  */
434
          cop1buflength = 8;
435
        }
436
      else
437
        {
438
          /* We have a 32 bit core insn and a 32 bit copro insn.  */
439
          corebuflength = 4;
440
          cop1buflength = 4;
441
        }
442
    }
443
  else
444
    {
445
      /* We have a 16 bit core insn and a 48 bit copro insn.  */
446
      corebuflength = 2;
447
      cop1buflength = 6;
448
    }
449
 
450
  /* Now we have the distrubution set.  Print them out. */
451
  status = mep_print_vliw_insns (cd, pc, info, buf, corebuflength,
452
                                 cop1buflength, cop2buflength);
453
 
454
  return status;
455
}
456
 
457 225 jeremybenn
#ifdef MEP_IVC2_SUPPORTED
458
 
459 24 jeremybenn
static int
460 225 jeremybenn
print_slot_insn (CGEN_CPU_DESC cd,
461
                 bfd_vma pc,
462
                 disassemble_info *info,
463
                 SLOTS_ATTR slot,
464
                 bfd_byte *buf)
465
{
466
  const CGEN_INSN_LIST *insn_list;
467
  CGEN_INSN_INT insn_value;
468
  CGEN_EXTRACT_INFO ex_info;
469
 
470
  insn_value = cgen_get_insn_value (cd, buf, 32);
471
 
472
  /* Fill in ex_info fields like read_insn would.  Don't actually call
473
     read_insn, since the incoming buffer is already read (and possibly
474
     modified a la m32r).  */
475
  ex_info.valid = (1 << 8) - 1;
476
  ex_info.dis_info = info;
477
  ex_info.insn_bytes = buf;
478
 
479
  /* The instructions are stored in hash lists.
480
     Pick the first one and keep trying until we find the right one.  */
481
 
482
  insn_list = CGEN_DIS_LOOKUP_INSN (cd, (char *) buf, insn_value);
483
  while (insn_list != NULL)
484
    {
485
      const CGEN_INSN *insn = insn_list->insn;
486
      CGEN_FIELDS fields;
487
      int length;
488
 
489
      if ((CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_CONFIG)
490
           && CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_CONFIG) != MEP_CONFIG)
491
          || ! (CGEN_ATTR_CGEN_INSN_SLOTS_VALUE (CGEN_INSN_ATTRS (insn)) & (1 << slot)))
492
        {
493
          insn_list = CGEN_DIS_NEXT_INSN (insn_list);
494
          continue;
495
        }
496
 
497
      if ((insn_value & CGEN_INSN_BASE_MASK (insn))
498
          == CGEN_INSN_BASE_VALUE (insn))
499
        {
500
          /* Printing is handled in two passes.  The first pass parses the
501
             machine insn and extracts the fields.  The second pass prints
502
             them.  */
503
 
504
          length = CGEN_EXTRACT_FN (cd, insn)
505
            (cd, insn, &ex_info, insn_value, &fields, pc);
506
 
507
          /* Length < 0 -> error.  */
508
          if (length < 0)
509
            return length;
510
          if (length > 0)
511
            {
512
              CGEN_PRINT_FN (cd, insn) (cd, info, insn, &fields, pc, length);
513
              /* Length is in bits, result is in bytes.  */
514
              return length / 8;
515
            }
516
        }
517
 
518
      insn_list = CGEN_DIS_NEXT_INSN (insn_list);
519
    }
520
 
521
  if (slot == SLOTS_P0S)
522
    (*info->fprintf_func) (info->stream, "*unknown-p0s*");
523
  else if (slot == SLOTS_P0)
524
    (*info->fprintf_func) (info->stream, "*unknown-p0*");
525
  else if (slot == SLOTS_P1)
526
    (*info->fprintf_func) (info->stream, "*unknown-p1*");
527
  else if (slot == SLOTS_C3)
528
    (*info->fprintf_func) (info->stream, "*unknown-c3*");
529
  return 0;
530
}
531
 
532
static int
533
mep_examine_ivc2_insns (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED, bfd_vma pc ATTRIBUTE_UNUSED, disassemble_info *info ATTRIBUTE_UNUSED)
534
{
535
  int status;
536
  int buflength;
537
  int cop2buflength;
538
  bfd_byte buf[8];
539
  bfd_byte insn[8];
540
  int e;
541
 
542
  /* At this time we're not supporting internally parallel
543
     coprocessors, so cop2buflength will always be 0.  */
544
  cop2buflength = 0;
545
 
546
  /* Read in 64 bits.  */
547
  buflength = 8; /* VLIW insn spans 8 bytes.  */
548
  status = (*info->read_memory_func) (pc, buf, buflength, info);
549
 
550
  if (status != 0)
551
    {
552
      (*info->memory_error_func) (status, pc, info);
553
      return -1;
554
    }
555
 
556
  if (info->endian == BFD_ENDIAN_LITTLE)
557
    e = 1;
558
  else
559
    e = 0;
560
 
561
  if (((unsigned char)buf[0^e] & 0xf0) < 0xc0)
562
    {
563
      /*      <--00--><--11--><--22--><--33--><--44--><--55--><--66--><--77--> */
564
      /* V1   [-----core-----][--------p0s-------][------------p1------------] */
565
 
566
      print_insn (cd, pc, info, buf, 2);
567
 
568
      insn[0^e] = 0;
569
      insn[1^e] = buf[2^e];
570
      insn[2^e] = buf[3^e];
571
      insn[3^e] = buf[4^e] & 0xf0;
572
      (*info->fprintf_func) (info->stream, " + ");
573
      print_slot_insn (cd, pc, info, SLOTS_P0S, insn);
574
 
575
      insn[0^e] = buf[4^e] << 4 | buf[5^e] >> 4;
576
      insn[1^e] = buf[5^e] << 4 | buf[6^e] >> 4;
577
      insn[2^e] = buf[6^e] << 4 | buf[7^e] >> 4;
578
      insn[3^e] = buf[7^e] << 4;
579
      (*info->fprintf_func) (info->stream, " + ");
580
      print_slot_insn (cd, pc, info, SLOTS_P1, insn);
581
    }
582
  else if ((buf[0^e] & 0xf0) == 0xf0 && (buf[1^e] & 0x0f) == 0x07)
583
    {
584
      /*      <--00--><--11--><--22--><--33--><--44--><--55--><--66--><--77--> */
585
      /* V3   1111[--p0--]0111[--------p0--------][------------p1------------] */
586
      /*                                          00000000111111112222222233333333 */
587
 
588
      insn[0^e] = buf[0^e] << 4 | buf[1^e] >> 4;
589
      insn[1^e] = buf[2^e];
590
      insn[2^e] = buf[3^e];
591
      insn[3^e] = buf[4^e] & 0xf0;
592
      print_slot_insn (cd, pc, info, SLOTS_P0, insn);
593
 
594
      insn[0^e] = buf[4^e] << 4 | buf[5^e] >> 4;
595
      insn[1^e] = buf[5^e] << 4 | buf[6^e] >> 4;
596
      insn[2^e] = buf[6^e] << 4 | buf[7^e] >> 4;
597
      insn[3^e] = buf[7^e] << 4;
598
      (*info->fprintf_func) (info->stream, " + ");
599
      print_slot_insn (cd, pc, info, SLOTS_P1, insn);
600
    }
601
  else
602
    {
603
      /*      <--00--><--11--><--22--><--33--><--44--><--55--><--66--><--77--> */
604
      /* V2   [-------------core-------------]xxxx[------------p1------------] */
605
      print_insn (cd, pc, info, buf, 4);
606
 
607
      insn[0^e] = buf[4^e] << 4 | buf[5^e] >> 4;
608
      insn[1^e] = buf[5^e] << 4 | buf[6^e] >> 4;
609
      insn[2^e] = buf[6^e] << 4 | buf[7^e] >> 4;
610
      insn[3^e] = buf[7^e] << 4;
611
      (*info->fprintf_func) (info->stream, " + ");
612
      print_slot_insn (cd, pc, info, SLOTS_P1, insn);
613
    }
614
 
615
  return 8;
616
}
617
 
618
#endif /* MEP_IVC2_SUPPORTED */
619
 
620
/* This is a hack.  SID calls this to update the disassembler as the
621
   CPU changes modes.  */
622
static int mep_ivc2_disassemble_p = 0;
623
static int mep_ivc2_vliw_disassemble_p = 0;
624
 
625
void
626
mep_print_insn_set_ivc2_mode (int ivc2_p, int vliw_p, int cfg_idx);
627
void
628
mep_print_insn_set_ivc2_mode (int ivc2_p, int vliw_p, int cfg_idx)
629
{
630
  mep_ivc2_disassemble_p = ivc2_p;
631
  mep_ivc2_vliw_disassemble_p = vliw_p;
632
  mep_config_index = cfg_idx;
633
}
634
 
635
static int
636 24 jeremybenn
mep_print_insn (CGEN_CPU_DESC cd, bfd_vma pc, disassemble_info *info)
637
{
638
  int status;
639 225 jeremybenn
  int cop_type;
640
  int ivc2 = 0;
641
  static CGEN_ATTR_VALUE_BITSET_TYPE *ivc2_core_isa = NULL;
642 24 jeremybenn
 
643 225 jeremybenn
  if (ivc2_core_isa == NULL)
644
    {
645
      /* IVC2 has some core-only coprocessor instructions.  We
646
         use COP32 to flag those, and COP64 for the VLIW ones,
647
         since they have the same names.  */
648
      ivc2_core_isa = cgen_bitset_create (MAX_ISAS);
649
    }
650
 
651 24 jeremybenn
  /* Extract and adapt to configuration number, if available. */
652
  if (info->section && info->section->owner)
653
    {
654
      bfd *abfd = info->section->owner;
655
      mep_config_index = abfd->tdata.elf_obj_data->elf_header->e_flags & EF_MEP_INDEX_MASK;
656
      /* This instantly redefines MEP_CONFIG, MEP_OMASK, .... MEP_VLIW64 */
657 225 jeremybenn
 
658
      cop_type = abfd->tdata.elf_obj_data->elf_header->e_flags & EF_MEP_COP_MASK;
659
      if (cop_type == EF_MEP_COP_IVC2)
660
        ivc2 = 1;
661 24 jeremybenn
    }
662
 
663
  /* Picking the right ISA bitmask for the current context is tricky.  */
664
  if (info->section)
665
    {
666
      if (info->section->flags & SEC_MEP_VLIW)
667
        {
668 225 jeremybenn
#ifdef MEP_IVC2_SUPPORTED
669
          if (ivc2)
670
            {
671
              /* ivc2 has its own way of selecting its functions.  */
672
              cd->isas = & MEP_CORE_ISA;
673
              status = mep_examine_ivc2_insns (cd, pc, info);
674
            }
675 24 jeremybenn
          else
676 225 jeremybenn
#endif
677
            /* Are we in 32 or 64 bit vliw mode?  */
678
            if (MEP_VLIW64)
679
              status = mep_examine_vliw64_insns (cd, pc, info);
680
            else
681
              status = mep_examine_vliw32_insns (cd, pc, info);
682 24 jeremybenn
          /* Both the above branches set their own isa bitmasks.  */
683
        }
684
      else
685
        {
686 225 jeremybenn
          if (ivc2)
687
            {
688
              cgen_bitset_clear (ivc2_core_isa);
689
              cgen_bitset_union (ivc2_core_isa, &MEP_CORE_ISA, ivc2_core_isa);
690
              cgen_bitset_union (ivc2_core_isa, &MEP_COP32_ISA, ivc2_core_isa);
691
              cd->isas = ivc2_core_isa;
692
            }
693
          else
694
            cd->isas = & MEP_CORE_ISA;
695 24 jeremybenn
          status = default_print_insn (cd, pc, info);
696
        }
697
    }
698
  else /* sid or gdb */
699
    {
700 225 jeremybenn
#ifdef MEP_IVC2_SUPPORTED
701
      if (mep_ivc2_disassemble_p)
702
        {
703
          if (mep_ivc2_vliw_disassemble_p)
704
            {
705
              cd->isas = & MEP_CORE_ISA;
706
              status = mep_examine_ivc2_insns (cd, pc, info);
707
              return status;
708
            }
709
          else
710
            {
711
              if (ivc2)
712
                cd->isas = ivc2_core_isa;
713
            }
714
        }
715
#endif
716
 
717 24 jeremybenn
      status = default_print_insn (cd, pc, info);
718
    }
719
 
720
  return status;
721
}
722
 
723
 
724
/* -- opc.c */
725
 
726
void mep_cgen_print_operand
727
  (CGEN_CPU_DESC, int, PTR, CGEN_FIELDS *, void const *, bfd_vma, int);
728
 
729
/* Main entry point for printing operands.
730
   XINFO is a `void *' and not a `disassemble_info *' to not put a requirement
731
   of dis-asm.h on cgen.h.
732
 
733
   This function is basically just a big switch statement.  Earlier versions
734
   used tables to look up the function to use, but
735
   - if the table contains both assembler and disassembler functions then
736
     the disassembler contains much of the assembler and vice-versa,
737
   - there's a lot of inlining possibilities as things grow,
738
   - using a switch statement avoids the function call overhead.
739
 
740
   This function could be moved into `print_insn_normal', but keeping it
741
   separate makes clear the interface between `print_insn_normal' and each of
742
   the handlers.  */
743
 
744
void
745
mep_cgen_print_operand (CGEN_CPU_DESC cd,
746
                           int opindex,
747
                           void * xinfo,
748
                           CGEN_FIELDS *fields,
749
                           void const *attrs ATTRIBUTE_UNUSED,
750
                           bfd_vma pc,
751
                           int length)
752
{
753
  disassemble_info *info = (disassemble_info *) xinfo;
754
 
755
  switch (opindex)
756
    {
757
    case MEP_OPERAND_ADDR24A4 :
758
      print_normal (cd, info, fields->f_24u8a4n, 0|(1<<CGEN_OPERAND_VIRTUAL), pc, length);
759
      break;
760 225 jeremybenn
    case MEP_OPERAND_C5RMUIMM20 :
761
      print_normal (cd, info, fields->f_c5_rmuimm20, 0|(1<<CGEN_OPERAND_VIRTUAL), pc, length);
762
      break;
763
    case MEP_OPERAND_C5RNMUIMM24 :
764
      print_normal (cd, info, fields->f_c5_rnmuimm24, 0|(1<<CGEN_OPERAND_VIRTUAL), pc, length);
765
      break;
766 24 jeremybenn
    case MEP_OPERAND_CALLNUM :
767
      print_normal (cd, info, fields->f_callnum, 0|(1<<CGEN_OPERAND_VIRTUAL), pc, length);
768
      break;
769
    case MEP_OPERAND_CCCC :
770
      print_normal (cd, info, fields->f_rm, 0, pc, length);
771
      break;
772
    case MEP_OPERAND_CCRN :
773
      print_keyword (cd, info, & mep_cgen_opval_h_ccr, fields->f_ccrn, 0|(1<<CGEN_OPERAND_VIRTUAL));
774
      break;
775 225 jeremybenn
    case MEP_OPERAND_CDISP10 :
776
      print_normal (cd, info, fields->f_cdisp10, 0|(1<<CGEN_OPERAND_SIGNED), pc, length);
777 24 jeremybenn
      break;
778 225 jeremybenn
    case MEP_OPERAND_CDISP10A2 :
779
      print_normal (cd, info, fields->f_cdisp10, 0|(1<<CGEN_OPERAND_SIGNED), pc, length);
780 24 jeremybenn
      break;
781 225 jeremybenn
    case MEP_OPERAND_CDISP10A4 :
782
      print_normal (cd, info, fields->f_cdisp10, 0|(1<<CGEN_OPERAND_SIGNED), pc, length);
783 24 jeremybenn
      break;
784 225 jeremybenn
    case MEP_OPERAND_CDISP10A8 :
785
      print_normal (cd, info, fields->f_cdisp10, 0|(1<<CGEN_OPERAND_SIGNED), pc, length);
786 24 jeremybenn
      break;
787 225 jeremybenn
    case MEP_OPERAND_CDISP12 :
788
      print_normal (cd, info, fields->f_12s20, 0|(1<<CGEN_OPERAND_SIGNED), pc, length);
789
      break;
790 24 jeremybenn
    case MEP_OPERAND_CIMM4 :
791
      print_normal (cd, info, fields->f_rn, 0, pc, length);
792
      break;
793
    case MEP_OPERAND_CIMM5 :
794
      print_normal (cd, info, fields->f_5u24, 0, pc, length);
795
      break;
796
    case MEP_OPERAND_CODE16 :
797
      print_normal (cd, info, fields->f_16u16, 0, pc, length);
798
      break;
799
    case MEP_OPERAND_CODE24 :
800
      print_normal (cd, info, fields->f_24u4n, 0|(1<<CGEN_OPERAND_VIRTUAL), pc, length);
801
      break;
802
    case MEP_OPERAND_CP_FLAG :
803
      print_keyword (cd, info, & mep_cgen_opval_h_ccr, 0, 0);
804
      break;
805
    case MEP_OPERAND_CRN :
806
      print_keyword (cd, info, & mep_cgen_opval_h_cr, fields->f_crn, 0);
807
      break;
808
    case MEP_OPERAND_CRN64 :
809
      print_keyword (cd, info, & mep_cgen_opval_h_cr64, fields->f_crn, 0);
810
      break;
811
    case MEP_OPERAND_CRNX :
812
      print_keyword (cd, info, & mep_cgen_opval_h_cr, fields->f_crnx, 0|(1<<CGEN_OPERAND_VIRTUAL));
813
      break;
814
    case MEP_OPERAND_CRNX64 :
815
      print_keyword (cd, info, & mep_cgen_opval_h_cr64, fields->f_crnx, 0|(1<<CGEN_OPERAND_VIRTUAL));
816
      break;
817 225 jeremybenn
    case MEP_OPERAND_CROC :
818
      print_keyword (cd, info, & mep_cgen_opval_h_cr64, fields->f_ivc2_5u7, 0);
819
      break;
820
    case MEP_OPERAND_CROP :
821
      print_keyword (cd, info, & mep_cgen_opval_h_cr64, fields->f_ivc2_5u23, 0);
822
      break;
823
    case MEP_OPERAND_CRPC :
824
      print_keyword (cd, info, & mep_cgen_opval_h_cr64, fields->f_ivc2_5u26, 0);
825
      break;
826
    case MEP_OPERAND_CRPP :
827
      print_keyword (cd, info, & mep_cgen_opval_h_cr64, fields->f_ivc2_5u18, 0);
828
      break;
829
    case MEP_OPERAND_CRQC :
830
      print_keyword (cd, info, & mep_cgen_opval_h_cr64, fields->f_ivc2_5u21, 0);
831
      break;
832
    case MEP_OPERAND_CRQP :
833
      print_keyword (cd, info, & mep_cgen_opval_h_cr64, fields->f_ivc2_5u13, 0);
834
      break;
835 24 jeremybenn
    case MEP_OPERAND_CSRN :
836
      print_keyword (cd, info, & mep_cgen_opval_h_csr, fields->f_csrn, 0|(1<<CGEN_OPERAND_VIRTUAL));
837
      break;
838
    case MEP_OPERAND_CSRN_IDX :
839
      print_normal (cd, info, fields->f_csrn, 0|(1<<CGEN_OPERAND_VIRTUAL), pc, length);
840
      break;
841
    case MEP_OPERAND_DBG :
842
      print_keyword (cd, info, & mep_cgen_opval_h_csr, 0, 0);
843
      break;
844
    case MEP_OPERAND_DEPC :
845
      print_keyword (cd, info, & mep_cgen_opval_h_csr, 0, 0);
846
      break;
847
    case MEP_OPERAND_EPC :
848
      print_keyword (cd, info, & mep_cgen_opval_h_csr, 0, 0);
849
      break;
850
    case MEP_OPERAND_EXC :
851
      print_keyword (cd, info, & mep_cgen_opval_h_csr, 0, 0);
852
      break;
853 225 jeremybenn
    case MEP_OPERAND_HI :
854
      print_keyword (cd, info, & mep_cgen_opval_h_csr, 0, 0);
855 24 jeremybenn
      break;
856 225 jeremybenn
    case MEP_OPERAND_IMM16P0 :
857
      print_normal (cd, info, fields->f_ivc2_imm16p0, 0|(1<<CGEN_OPERAND_VIRTUAL), pc, length);
858 24 jeremybenn
      break;
859 225 jeremybenn
    case MEP_OPERAND_IMM3P12 :
860
      print_normal (cd, info, fields->f_ivc2_3u12, 0, pc, length);
861 24 jeremybenn
      break;
862 225 jeremybenn
    case MEP_OPERAND_IMM3P25 :
863
      print_normal (cd, info, fields->f_ivc2_3u25, 0, pc, length);
864 24 jeremybenn
      break;
865 225 jeremybenn
    case MEP_OPERAND_IMM3P4 :
866
      print_normal (cd, info, fields->f_ivc2_3u4, 0, pc, length);
867 24 jeremybenn
      break;
868 225 jeremybenn
    case MEP_OPERAND_IMM3P5 :
869
      print_normal (cd, info, fields->f_ivc2_3u5, 0, pc, length);
870 24 jeremybenn
      break;
871 225 jeremybenn
    case MEP_OPERAND_IMM3P9 :
872
      print_normal (cd, info, fields->f_ivc2_3u9, 0, pc, length);
873 24 jeremybenn
      break;
874 225 jeremybenn
    case MEP_OPERAND_IMM4P10 :
875
      print_normal (cd, info, fields->f_ivc2_4u10, 0, pc, length);
876 24 jeremybenn
      break;
877 225 jeremybenn
    case MEP_OPERAND_IMM4P4 :
878
      print_normal (cd, info, fields->f_ivc2_4u4, 0, pc, length);
879
      break;
880
    case MEP_OPERAND_IMM4P8 :
881
      print_normal (cd, info, fields->f_ivc2_4u8, 0, pc, length);
882
      break;
883
    case MEP_OPERAND_IMM5P23 :
884
      print_normal (cd, info, fields->f_ivc2_5u23, 0, pc, length);
885
      break;
886
    case MEP_OPERAND_IMM5P3 :
887
      print_normal (cd, info, fields->f_ivc2_5u3, 0, pc, length);
888
      break;
889
    case MEP_OPERAND_IMM5P7 :
890
      print_normal (cd, info, fields->f_ivc2_5u7, 0, pc, length);
891
      break;
892
    case MEP_OPERAND_IMM5P8 :
893
      print_normal (cd, info, fields->f_ivc2_5u8, 0, pc, length);
894
      break;
895
    case MEP_OPERAND_IMM6P2 :
896
      print_normal (cd, info, fields->f_ivc2_6u2, 0, pc, length);
897
      break;
898
    case MEP_OPERAND_IMM6P6 :
899
      print_normal (cd, info, fields->f_ivc2_6u6, 0, pc, length);
900
      break;
901
    case MEP_OPERAND_IMM8P0 :
902
      print_normal (cd, info, fields->f_ivc2_8u0, 0, pc, length);
903
      break;
904
    case MEP_OPERAND_IMM8P20 :
905
      print_normal (cd, info, fields->f_ivc2_8u20, 0, pc, length);
906
      break;
907
    case MEP_OPERAND_IMM8P4 :
908
      print_normal (cd, info, fields->f_ivc2_8u4, 0, pc, length);
909
      break;
910
    case MEP_OPERAND_IVC_X_0_2 :
911
      print_normal (cd, info, fields->f_ivc2_2u0, 0, pc, length);
912
      break;
913
    case MEP_OPERAND_IVC_X_0_3 :
914
      print_normal (cd, info, fields->f_ivc2_3u0, 0, pc, length);
915
      break;
916
    case MEP_OPERAND_IVC_X_0_4 :
917
      print_normal (cd, info, fields->f_ivc2_4u0, 0, pc, length);
918
      break;
919
    case MEP_OPERAND_IVC_X_0_5 :
920
      print_normal (cd, info, fields->f_ivc2_5u0, 0, pc, length);
921
      break;
922
    case MEP_OPERAND_IVC_X_6_1 :
923
      print_normal (cd, info, fields->f_ivc2_1u6, 0, pc, length);
924
      break;
925
    case MEP_OPERAND_IVC_X_6_2 :
926
      print_normal (cd, info, fields->f_ivc2_2u6, 0, pc, length);
927
      break;
928
    case MEP_OPERAND_IVC_X_6_3 :
929
      print_normal (cd, info, fields->f_ivc2_3u6, 0, pc, length);
930
      break;
931
    case MEP_OPERAND_IVC2_ACC0_0 :
932
      print_keyword (cd, info, & mep_cgen_opval_h_ccr_ivc2, 0, 0);
933
      break;
934
    case MEP_OPERAND_IVC2_ACC0_1 :
935
      print_keyword (cd, info, & mep_cgen_opval_h_ccr_ivc2, 0, 0);
936
      break;
937
    case MEP_OPERAND_IVC2_ACC0_2 :
938
      print_keyword (cd, info, & mep_cgen_opval_h_ccr_ivc2, 0, 0);
939
      break;
940
    case MEP_OPERAND_IVC2_ACC0_3 :
941
      print_keyword (cd, info, & mep_cgen_opval_h_ccr_ivc2, 0, 0);
942
      break;
943
    case MEP_OPERAND_IVC2_ACC0_4 :
944
      print_keyword (cd, info, & mep_cgen_opval_h_ccr_ivc2, 0, 0);
945
      break;
946
    case MEP_OPERAND_IVC2_ACC0_5 :
947
      print_keyword (cd, info, & mep_cgen_opval_h_ccr_ivc2, 0, 0);
948
      break;
949
    case MEP_OPERAND_IVC2_ACC0_6 :
950
      print_keyword (cd, info, & mep_cgen_opval_h_ccr_ivc2, 0, 0);
951
      break;
952
    case MEP_OPERAND_IVC2_ACC0_7 :
953
      print_keyword (cd, info, & mep_cgen_opval_h_ccr_ivc2, 0, 0);
954
      break;
955
    case MEP_OPERAND_IVC2_ACC1_0 :
956
      print_keyword (cd, info, & mep_cgen_opval_h_ccr_ivc2, 0, 0);
957
      break;
958
    case MEP_OPERAND_IVC2_ACC1_1 :
959
      print_keyword (cd, info, & mep_cgen_opval_h_ccr_ivc2, 0, 0);
960
      break;
961
    case MEP_OPERAND_IVC2_ACC1_2 :
962
      print_keyword (cd, info, & mep_cgen_opval_h_ccr_ivc2, 0, 0);
963
      break;
964
    case MEP_OPERAND_IVC2_ACC1_3 :
965
      print_keyword (cd, info, & mep_cgen_opval_h_ccr_ivc2, 0, 0);
966
      break;
967
    case MEP_OPERAND_IVC2_ACC1_4 :
968
      print_keyword (cd, info, & mep_cgen_opval_h_ccr_ivc2, 0, 0);
969
      break;
970
    case MEP_OPERAND_IVC2_ACC1_5 :
971
      print_keyword (cd, info, & mep_cgen_opval_h_ccr_ivc2, 0, 0);
972
      break;
973
    case MEP_OPERAND_IVC2_ACC1_6 :
974
      print_keyword (cd, info, & mep_cgen_opval_h_ccr_ivc2, 0, 0);
975
      break;
976
    case MEP_OPERAND_IVC2_ACC1_7 :
977
      print_keyword (cd, info, & mep_cgen_opval_h_ccr_ivc2, 0, 0);
978
      break;
979
    case MEP_OPERAND_IVC2_CC :
980
      print_keyword (cd, info, & mep_cgen_opval_h_ccr_ivc2, 0, 0);
981
      break;
982
    case MEP_OPERAND_IVC2_COFA0 :
983
      print_keyword (cd, info, & mep_cgen_opval_h_ccr_ivc2, 0, 0);
984
      break;
985
    case MEP_OPERAND_IVC2_COFA1 :
986
      print_keyword (cd, info, & mep_cgen_opval_h_ccr_ivc2, 0, 0);
987
      break;
988
    case MEP_OPERAND_IVC2_COFR0 :
989
      print_keyword (cd, info, & mep_cgen_opval_h_ccr_ivc2, 0, 0);
990
      break;
991
    case MEP_OPERAND_IVC2_COFR1 :
992
      print_keyword (cd, info, & mep_cgen_opval_h_ccr_ivc2, 0, 0);
993
      break;
994
    case MEP_OPERAND_IVC2_CSAR0 :
995
      print_keyword (cd, info, & mep_cgen_opval_h_ccr_ivc2, 0, 0);
996
      break;
997
    case MEP_OPERAND_IVC2_CSAR1 :
998
      print_keyword (cd, info, & mep_cgen_opval_h_ccr_ivc2, 0, 0);
999
      break;
1000
    case MEP_OPERAND_IVC2C3CCRN :
1001
      print_keyword (cd, info, & mep_cgen_opval_h_ccr_ivc2, fields->f_ivc2_ccrn_c3, 0|(1<<CGEN_OPERAND_VIRTUAL));
1002
      break;
1003
    case MEP_OPERAND_IVC2CCRN :
1004
      print_keyword (cd, info, & mep_cgen_opval_h_ccr_ivc2, fields->f_ivc2_ccrn, 0|(1<<CGEN_OPERAND_VIRTUAL));
1005
      break;
1006
    case MEP_OPERAND_IVC2CRN :
1007
      print_keyword (cd, info, & mep_cgen_opval_h_cr64, fields->f_ivc2_crnx, 0|(1<<CGEN_OPERAND_VIRTUAL));
1008
      break;
1009
    case MEP_OPERAND_IVC2RM :
1010
      print_keyword (cd, info, & mep_cgen_opval_h_gpr, fields->f_ivc2_crm, 0);
1011
      break;
1012 24 jeremybenn
    case MEP_OPERAND_LO :
1013
      print_keyword (cd, info, & mep_cgen_opval_h_csr, 0, 0);
1014
      break;
1015
    case MEP_OPERAND_LP :
1016
      print_keyword (cd, info, & mep_cgen_opval_h_csr, 0, 0);
1017
      break;
1018
    case MEP_OPERAND_MB0 :
1019
      print_keyword (cd, info, & mep_cgen_opval_h_csr, 0, 0);
1020
      break;
1021
    case MEP_OPERAND_MB1 :
1022
      print_keyword (cd, info, & mep_cgen_opval_h_csr, 0, 0);
1023
      break;
1024
    case MEP_OPERAND_ME0 :
1025
      print_keyword (cd, info, & mep_cgen_opval_h_csr, 0, 0);
1026
      break;
1027
    case MEP_OPERAND_ME1 :
1028
      print_keyword (cd, info, & mep_cgen_opval_h_csr, 0, 0);
1029
      break;
1030
    case MEP_OPERAND_NPC :
1031
      print_keyword (cd, info, & mep_cgen_opval_h_csr, 0, 0);
1032
      break;
1033
    case MEP_OPERAND_OPT :
1034
      print_keyword (cd, info, & mep_cgen_opval_h_csr, 0, 0);
1035
      break;
1036
    case MEP_OPERAND_PCABS24A2 :
1037
      print_address (cd, info, fields->f_24u5a2n, 0|(1<<CGEN_OPERAND_ABS_ADDR)|(1<<CGEN_OPERAND_VIRTUAL), pc, length);
1038
      break;
1039
    case MEP_OPERAND_PCREL12A2 :
1040
      print_address (cd, info, fields->f_12s4a2, 0|(1<<CGEN_OPERAND_SIGNED)|(1<<CGEN_OPERAND_RELAX)|(1<<CGEN_OPERAND_PCREL_ADDR), pc, length);
1041
      break;
1042
    case MEP_OPERAND_PCREL17A2 :
1043
      print_address (cd, info, fields->f_17s16a2, 0|(1<<CGEN_OPERAND_SIGNED)|(1<<CGEN_OPERAND_RELAX)|(1<<CGEN_OPERAND_PCREL_ADDR), pc, length);
1044
      break;
1045
    case MEP_OPERAND_PCREL24A2 :
1046
      print_address (cd, info, fields->f_24s5a2n, 0|(1<<CGEN_OPERAND_SIGNED)|(1<<CGEN_OPERAND_PCREL_ADDR)|(1<<CGEN_OPERAND_VIRTUAL), pc, length);
1047
      break;
1048
    case MEP_OPERAND_PCREL8A2 :
1049
      print_address (cd, info, fields->f_8s8a2, 0|(1<<CGEN_OPERAND_SIGNED)|(1<<CGEN_OPERAND_RELAX)|(1<<CGEN_OPERAND_PCREL_ADDR), pc, length);
1050
      break;
1051
    case MEP_OPERAND_PSW :
1052
      print_keyword (cd, info, & mep_cgen_opval_h_csr, 0, 0);
1053
      break;
1054
    case MEP_OPERAND_R0 :
1055
      print_keyword (cd, info, & mep_cgen_opval_h_gpr, 0, 0);
1056
      break;
1057
    case MEP_OPERAND_R1 :
1058
      print_keyword (cd, info, & mep_cgen_opval_h_gpr, 0, 0);
1059
      break;
1060
    case MEP_OPERAND_RL :
1061
      print_keyword (cd, info, & mep_cgen_opval_h_gpr, fields->f_rl, 0);
1062
      break;
1063 225 jeremybenn
    case MEP_OPERAND_RL5 :
1064
      print_keyword (cd, info, & mep_cgen_opval_h_gpr, fields->f_rl5, 0);
1065
      break;
1066 24 jeremybenn
    case MEP_OPERAND_RM :
1067
      print_keyword (cd, info, & mep_cgen_opval_h_gpr, fields->f_rm, 0);
1068
      break;
1069
    case MEP_OPERAND_RMA :
1070
      print_keyword (cd, info, & mep_cgen_opval_h_gpr, fields->f_rm, 0);
1071
      break;
1072
    case MEP_OPERAND_RN :
1073
      print_keyword (cd, info, & mep_cgen_opval_h_gpr, fields->f_rn, 0);
1074
      break;
1075
    case MEP_OPERAND_RN3 :
1076
      print_keyword (cd, info, & mep_cgen_opval_h_gpr, fields->f_rn3, 0);
1077
      break;
1078
    case MEP_OPERAND_RN3C :
1079
      print_keyword (cd, info, & mep_cgen_opval_h_gpr, fields->f_rn3, 0);
1080
      break;
1081
    case MEP_OPERAND_RN3L :
1082
      print_keyword (cd, info, & mep_cgen_opval_h_gpr, fields->f_rn3, 0);
1083
      break;
1084
    case MEP_OPERAND_RN3S :
1085
      print_keyword (cd, info, & mep_cgen_opval_h_gpr, fields->f_rn3, 0);
1086
      break;
1087
    case MEP_OPERAND_RN3UC :
1088
      print_keyword (cd, info, & mep_cgen_opval_h_gpr, fields->f_rn3, 0);
1089
      break;
1090
    case MEP_OPERAND_RN3UL :
1091
      print_keyword (cd, info, & mep_cgen_opval_h_gpr, fields->f_rn3, 0);
1092
      break;
1093
    case MEP_OPERAND_RN3US :
1094
      print_keyword (cd, info, & mep_cgen_opval_h_gpr, fields->f_rn3, 0);
1095
      break;
1096
    case MEP_OPERAND_RNC :
1097
      print_keyword (cd, info, & mep_cgen_opval_h_gpr, fields->f_rn, 0);
1098
      break;
1099
    case MEP_OPERAND_RNL :
1100
      print_keyword (cd, info, & mep_cgen_opval_h_gpr, fields->f_rn, 0);
1101
      break;
1102
    case MEP_OPERAND_RNS :
1103
      print_keyword (cd, info, & mep_cgen_opval_h_gpr, fields->f_rn, 0);
1104
      break;
1105
    case MEP_OPERAND_RNUC :
1106
      print_keyword (cd, info, & mep_cgen_opval_h_gpr, fields->f_rn, 0);
1107
      break;
1108
    case MEP_OPERAND_RNUL :
1109
      print_keyword (cd, info, & mep_cgen_opval_h_gpr, fields->f_rn, 0);
1110
      break;
1111
    case MEP_OPERAND_RNUS :
1112
      print_keyword (cd, info, & mep_cgen_opval_h_gpr, fields->f_rn, 0);
1113
      break;
1114
    case MEP_OPERAND_SAR :
1115
      print_keyword (cd, info, & mep_cgen_opval_h_csr, 0, 0);
1116
      break;
1117
    case MEP_OPERAND_SDISP16 :
1118
      print_normal (cd, info, fields->f_16s16, 0|(1<<CGEN_OPERAND_SIGNED), pc, length);
1119
      break;
1120
    case MEP_OPERAND_SIMM16 :
1121
      print_normal (cd, info, fields->f_16s16, 0|(1<<CGEN_OPERAND_SIGNED), pc, length);
1122
      break;
1123 225 jeremybenn
    case MEP_OPERAND_SIMM16P0 :
1124
      print_normal (cd, info, fields->f_ivc2_simm16p0, 0|(1<<CGEN_OPERAND_SIGNED)|(1<<CGEN_OPERAND_VIRTUAL), pc, length);
1125
      break;
1126 24 jeremybenn
    case MEP_OPERAND_SIMM6 :
1127
      print_normal (cd, info, fields->f_6s8, 0|(1<<CGEN_OPERAND_SIGNED), pc, length);
1128
      break;
1129
    case MEP_OPERAND_SIMM8 :
1130
      print_normal (cd, info, fields->f_8s8, 0|(1<<CGEN_OPERAND_SIGNED)|(1<<CGEN_OPERAND_RELOC_IMPLIES_OVERFLOW), pc, length);
1131
      break;
1132 225 jeremybenn
    case MEP_OPERAND_SIMM8P0 :
1133
      print_normal (cd, info, fields->f_ivc2_8s0, 0|(1<<CGEN_OPERAND_SIGNED), pc, length);
1134
      break;
1135
    case MEP_OPERAND_SIMM8P20 :
1136
      print_normal (cd, info, fields->f_ivc2_8s20, 0|(1<<CGEN_OPERAND_SIGNED), pc, length);
1137
      break;
1138
    case MEP_OPERAND_SIMM8P4 :
1139
      print_normal (cd, info, fields->f_ivc2_8s4, 0|(1<<CGEN_OPERAND_SIGNED), pc, length);
1140
      break;
1141 24 jeremybenn
    case MEP_OPERAND_SP :
1142
      print_keyword (cd, info, & mep_cgen_opval_h_gpr, 0, 0);
1143
      break;
1144
    case MEP_OPERAND_SPR :
1145
      print_spreg (cd, info, & mep_cgen_opval_h_gpr, 0, 0);
1146
      break;
1147
    case MEP_OPERAND_TP :
1148
      print_keyword (cd, info, & mep_cgen_opval_h_gpr, 0, 0);
1149
      break;
1150
    case MEP_OPERAND_TPR :
1151
      print_tpreg (cd, info, & mep_cgen_opval_h_gpr, 0, 0);
1152
      break;
1153
    case MEP_OPERAND_UDISP2 :
1154
      print_normal (cd, info, fields->f_2u6, 0|(1<<CGEN_OPERAND_SIGNED), pc, length);
1155
      break;
1156
    case MEP_OPERAND_UDISP7 :
1157
      print_normal (cd, info, fields->f_7u9, 0, pc, length);
1158
      break;
1159
    case MEP_OPERAND_UDISP7A2 :
1160
      print_normal (cd, info, fields->f_7u9a2, 0, pc, length);
1161
      break;
1162
    case MEP_OPERAND_UDISP7A4 :
1163
      print_normal (cd, info, fields->f_7u9a4, 0, pc, length);
1164
      break;
1165
    case MEP_OPERAND_UIMM16 :
1166
      print_normal (cd, info, fields->f_16u16, 0, pc, length);
1167
      break;
1168
    case MEP_OPERAND_UIMM2 :
1169
      print_normal (cd, info, fields->f_2u10, 0, pc, length);
1170
      break;
1171
    case MEP_OPERAND_UIMM24 :
1172
      print_normal (cd, info, fields->f_24u8n, 0|(1<<CGEN_OPERAND_VIRTUAL), pc, length);
1173
      break;
1174
    case MEP_OPERAND_UIMM3 :
1175
      print_normal (cd, info, fields->f_3u5, 0, pc, length);
1176
      break;
1177
    case MEP_OPERAND_UIMM4 :
1178
      print_normal (cd, info, fields->f_4u8, 0, pc, length);
1179
      break;
1180
    case MEP_OPERAND_UIMM5 :
1181
      print_normal (cd, info, fields->f_5u8, 0, pc, length);
1182
      break;
1183
    case MEP_OPERAND_UIMM7A4 :
1184
      print_normal (cd, info, fields->f_7u9a4, 0, pc, length);
1185
      break;
1186
    case MEP_OPERAND_ZERO :
1187
      print_normal (cd, info, 0, 0|(1<<CGEN_OPERAND_SIGNED), pc, length);
1188
      break;
1189
 
1190
    default :
1191
      /* xgettext:c-format */
1192
      fprintf (stderr, _("Unrecognized field %d while printing insn.\n"),
1193
               opindex);
1194
    abort ();
1195
  }
1196
}
1197
 
1198
cgen_print_fn * const mep_cgen_print_handlers[] =
1199
{
1200
  print_insn_normal,
1201
};
1202
 
1203
 
1204
void
1205
mep_cgen_init_dis (CGEN_CPU_DESC cd)
1206
{
1207
  mep_cgen_init_opcode_table (cd);
1208
  mep_cgen_init_ibld_table (cd);
1209
  cd->print_handlers = & mep_cgen_print_handlers[0];
1210
  cd->print_operand = mep_cgen_print_operand;
1211
}
1212
 
1213
 
1214
/* Default print handler.  */
1215
 
1216
static void
1217
print_normal (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
1218
              void *dis_info,
1219
              long value,
1220
              unsigned int attrs,
1221
              bfd_vma pc ATTRIBUTE_UNUSED,
1222
              int length ATTRIBUTE_UNUSED)
1223
{
1224
  disassemble_info *info = (disassemble_info *) dis_info;
1225
 
1226
#ifdef CGEN_PRINT_NORMAL
1227
  CGEN_PRINT_NORMAL (cd, info, value, attrs, pc, length);
1228
#endif
1229
 
1230
  /* Print the operand as directed by the attributes.  */
1231
  if (CGEN_BOOL_ATTR (attrs, CGEN_OPERAND_SEM_ONLY))
1232
    ; /* nothing to do */
1233
  else if (CGEN_BOOL_ATTR (attrs, CGEN_OPERAND_SIGNED))
1234
    (*info->fprintf_func) (info->stream, "%ld", value);
1235
  else
1236
    (*info->fprintf_func) (info->stream, "0x%lx", value);
1237
}
1238
 
1239
/* Default address handler.  */
1240
 
1241
static void
1242
print_address (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
1243
               void *dis_info,
1244
               bfd_vma value,
1245
               unsigned int attrs,
1246
               bfd_vma pc ATTRIBUTE_UNUSED,
1247
               int length ATTRIBUTE_UNUSED)
1248
{
1249
  disassemble_info *info = (disassemble_info *) dis_info;
1250
 
1251
#ifdef CGEN_PRINT_ADDRESS
1252
  CGEN_PRINT_ADDRESS (cd, info, value, attrs, pc, length);
1253
#endif
1254
 
1255
  /* Print the operand as directed by the attributes.  */
1256
  if (CGEN_BOOL_ATTR (attrs, CGEN_OPERAND_SEM_ONLY))
1257
    ; /* Nothing to do.  */
1258
  else if (CGEN_BOOL_ATTR (attrs, CGEN_OPERAND_PCREL_ADDR))
1259
    (*info->print_address_func) (value, info);
1260
  else if (CGEN_BOOL_ATTR (attrs, CGEN_OPERAND_ABS_ADDR))
1261
    (*info->print_address_func) (value, info);
1262
  else if (CGEN_BOOL_ATTR (attrs, CGEN_OPERAND_SIGNED))
1263
    (*info->fprintf_func) (info->stream, "%ld", (long) value);
1264
  else
1265
    (*info->fprintf_func) (info->stream, "0x%lx", (long) value);
1266
}
1267
 
1268
/* Keyword print handler.  */
1269
 
1270
static void
1271
print_keyword (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
1272
               void *dis_info,
1273
               CGEN_KEYWORD *keyword_table,
1274
               long value,
1275
               unsigned int attrs ATTRIBUTE_UNUSED)
1276
{
1277
  disassemble_info *info = (disassemble_info *) dis_info;
1278
  const CGEN_KEYWORD_ENTRY *ke;
1279
 
1280
  ke = cgen_keyword_lookup_value (keyword_table, value);
1281
  if (ke != NULL)
1282
    (*info->fprintf_func) (info->stream, "%s", ke->name);
1283
  else
1284
    (*info->fprintf_func) (info->stream, "???");
1285
}
1286
 
1287
/* Default insn printer.
1288
 
1289
   DIS_INFO is defined as `void *' so the disassembler needn't know anything
1290
   about disassemble_info.  */
1291
 
1292
static void
1293
print_insn_normal (CGEN_CPU_DESC cd,
1294
                   void *dis_info,
1295
                   const CGEN_INSN *insn,
1296
                   CGEN_FIELDS *fields,
1297
                   bfd_vma pc,
1298
                   int length)
1299
{
1300
  const CGEN_SYNTAX *syntax = CGEN_INSN_SYNTAX (insn);
1301
  disassemble_info *info = (disassemble_info *) dis_info;
1302
  const CGEN_SYNTAX_CHAR_TYPE *syn;
1303
 
1304
  CGEN_INIT_PRINT (cd);
1305
 
1306
  for (syn = CGEN_SYNTAX_STRING (syntax); *syn; ++syn)
1307
    {
1308
      if (CGEN_SYNTAX_MNEMONIC_P (*syn))
1309
        {
1310
          (*info->fprintf_func) (info->stream, "%s", CGEN_INSN_MNEMONIC (insn));
1311
          continue;
1312
        }
1313
      if (CGEN_SYNTAX_CHAR_P (*syn))
1314
        {
1315
          (*info->fprintf_func) (info->stream, "%c", CGEN_SYNTAX_CHAR (*syn));
1316
          continue;
1317
        }
1318
 
1319
      /* We have an operand.  */
1320
      mep_cgen_print_operand (cd, CGEN_SYNTAX_FIELD (*syn), info,
1321
                                 fields, CGEN_INSN_ATTRS (insn), pc, length);
1322
    }
1323
}
1324
 
1325
/* Subroutine of print_insn. Reads an insn into the given buffers and updates
1326
   the extract info.
1327
   Returns 0 if all is well, non-zero otherwise.  */
1328
 
1329
static int
1330
read_insn (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
1331
           bfd_vma pc,
1332
           disassemble_info *info,
1333
           bfd_byte *buf,
1334
           int buflen,
1335
           CGEN_EXTRACT_INFO *ex_info,
1336
           unsigned long *insn_value)
1337
{
1338
  int status = (*info->read_memory_func) (pc, buf, buflen, info);
1339
 
1340
  if (status != 0)
1341
    {
1342
      (*info->memory_error_func) (status, pc, info);
1343
      return -1;
1344
    }
1345
 
1346
  ex_info->dis_info = info;
1347
  ex_info->valid = (1 << buflen) - 1;
1348
  ex_info->insn_bytes = buf;
1349
 
1350
  *insn_value = bfd_get_bits (buf, buflen * 8, info->endian == BFD_ENDIAN_BIG);
1351
  return 0;
1352
}
1353
 
1354
/* Utility to print an insn.
1355
   BUF is the base part of the insn, target byte order, BUFLEN bytes long.
1356
   The result is the size of the insn in bytes or zero for an unknown insn
1357
   or -1 if an error occurs fetching data (memory_error_func will have
1358
   been called).  */
1359
 
1360
static int
1361
print_insn (CGEN_CPU_DESC cd,
1362
            bfd_vma pc,
1363
            disassemble_info *info,
1364
            bfd_byte *buf,
1365
            unsigned int buflen)
1366
{
1367
  CGEN_INSN_INT insn_value;
1368
  const CGEN_INSN_LIST *insn_list;
1369
  CGEN_EXTRACT_INFO ex_info;
1370
  int basesize;
1371
 
1372
  /* Extract base part of instruction, just in case CGEN_DIS_* uses it. */
1373
  basesize = cd->base_insn_bitsize < buflen * 8 ?
1374
                                     cd->base_insn_bitsize : buflen * 8;
1375
  insn_value = cgen_get_insn_value (cd, buf, basesize);
1376
 
1377
 
1378
  /* Fill in ex_info fields like read_insn would.  Don't actually call
1379
     read_insn, since the incoming buffer is already read (and possibly
1380
     modified a la m32r).  */
1381
  ex_info.valid = (1 << buflen) - 1;
1382
  ex_info.dis_info = info;
1383
  ex_info.insn_bytes = buf;
1384
 
1385
  /* The instructions are stored in hash lists.
1386
     Pick the first one and keep trying until we find the right one.  */
1387
 
1388
  insn_list = CGEN_DIS_LOOKUP_INSN (cd, (char *) buf, insn_value);
1389
  while (insn_list != NULL)
1390
    {
1391
      const CGEN_INSN *insn = insn_list->insn;
1392
      CGEN_FIELDS fields;
1393
      int length;
1394
      unsigned long insn_value_cropped;
1395
 
1396
#ifdef CGEN_VALIDATE_INSN_SUPPORTED 
1397
      /* Not needed as insn shouldn't be in hash lists if not supported.  */
1398
      /* Supported by this cpu?  */
1399
      if (! mep_cgen_insn_supported (cd, insn))
1400
        {
1401
          insn_list = CGEN_DIS_NEXT_INSN (insn_list);
1402
          continue;
1403
        }
1404
#endif
1405
 
1406
      /* Basic bit mask must be correct.  */
1407
      /* ??? May wish to allow target to defer this check until the extract
1408
         handler.  */
1409
 
1410
      /* Base size may exceed this instruction's size.  Extract the
1411
         relevant part from the buffer. */
1412
      if ((unsigned) (CGEN_INSN_BITSIZE (insn) / 8) < buflen &&
1413
          (unsigned) (CGEN_INSN_BITSIZE (insn) / 8) <= sizeof (unsigned long))
1414
        insn_value_cropped = bfd_get_bits (buf, CGEN_INSN_BITSIZE (insn),
1415
                                           info->endian == BFD_ENDIAN_BIG);
1416
      else
1417
        insn_value_cropped = insn_value;
1418
 
1419
      if ((insn_value_cropped & CGEN_INSN_BASE_MASK (insn))
1420
          == CGEN_INSN_BASE_VALUE (insn))
1421
        {
1422
          /* Printing is handled in two passes.  The first pass parses the
1423
             machine insn and extracts the fields.  The second pass prints
1424
             them.  */
1425
 
1426
          /* Make sure the entire insn is loaded into insn_value, if it
1427
             can fit.  */
1428
          if (((unsigned) CGEN_INSN_BITSIZE (insn) > cd->base_insn_bitsize) &&
1429
              (unsigned) (CGEN_INSN_BITSIZE (insn) / 8) <= sizeof (unsigned long))
1430
            {
1431
              unsigned long full_insn_value;
1432
              int rc = read_insn (cd, pc, info, buf,
1433
                                  CGEN_INSN_BITSIZE (insn) / 8,
1434
                                  & ex_info, & full_insn_value);
1435
              if (rc != 0)
1436
                return rc;
1437
              length = CGEN_EXTRACT_FN (cd, insn)
1438
                (cd, insn, &ex_info, full_insn_value, &fields, pc);
1439
            }
1440
          else
1441
            length = CGEN_EXTRACT_FN (cd, insn)
1442
              (cd, insn, &ex_info, insn_value_cropped, &fields, pc);
1443
 
1444
          /* Length < 0 -> error.  */
1445
          if (length < 0)
1446
            return length;
1447
          if (length > 0)
1448
            {
1449
              CGEN_PRINT_FN (cd, insn) (cd, info, insn, &fields, pc, length);
1450
              /* Length is in bits, result is in bytes.  */
1451
              return length / 8;
1452
            }
1453
        }
1454
 
1455
      insn_list = CGEN_DIS_NEXT_INSN (insn_list);
1456
    }
1457
 
1458
  return 0;
1459
}
1460
 
1461
/* Default value for CGEN_PRINT_INSN.
1462
   The result is the size of the insn in bytes or zero for an unknown insn
1463
   or -1 if an error occured fetching bytes.  */
1464
 
1465
#ifndef CGEN_PRINT_INSN
1466
#define CGEN_PRINT_INSN default_print_insn
1467
#endif
1468
 
1469
static int
1470
default_print_insn (CGEN_CPU_DESC cd, bfd_vma pc, disassemble_info *info)
1471
{
1472
  bfd_byte buf[CGEN_MAX_INSN_SIZE];
1473
  int buflen;
1474
  int status;
1475
 
1476
  /* Attempt to read the base part of the insn.  */
1477
  buflen = cd->base_insn_bitsize / 8;
1478
  status = (*info->read_memory_func) (pc, buf, buflen, info);
1479
 
1480
  /* Try again with the minimum part, if min < base.  */
1481
  if (status != 0 && (cd->min_insn_bitsize < cd->base_insn_bitsize))
1482
    {
1483
      buflen = cd->min_insn_bitsize / 8;
1484
      status = (*info->read_memory_func) (pc, buf, buflen, info);
1485
    }
1486
 
1487
  if (status != 0)
1488
    {
1489
      (*info->memory_error_func) (status, pc, info);
1490
      return -1;
1491
    }
1492
 
1493
  return print_insn (cd, pc, info, buf, buflen);
1494
}
1495
 
1496
/* Main entry point.
1497
   Print one instruction from PC on INFO->STREAM.
1498
   Return the size of the instruction (in bytes).  */
1499
 
1500
typedef struct cpu_desc_list
1501
{
1502
  struct cpu_desc_list *next;
1503
  CGEN_BITSET *isa;
1504
  int mach;
1505
  int endian;
1506
  CGEN_CPU_DESC cd;
1507
} cpu_desc_list;
1508
 
1509
int
1510
print_insn_mep (bfd_vma pc, disassemble_info *info)
1511
{
1512
  static cpu_desc_list *cd_list = 0;
1513
  cpu_desc_list *cl = 0;
1514
  static CGEN_CPU_DESC cd = 0;
1515
  static CGEN_BITSET *prev_isa;
1516
  static int prev_mach;
1517
  static int prev_endian;
1518
  int length;
1519
  CGEN_BITSET *isa;
1520
  int mach;
1521
  int endian = (info->endian == BFD_ENDIAN_BIG
1522
                ? CGEN_ENDIAN_BIG
1523
                : CGEN_ENDIAN_LITTLE);
1524
  enum bfd_architecture arch;
1525
 
1526
  /* ??? gdb will set mach but leave the architecture as "unknown" */
1527
#ifndef CGEN_BFD_ARCH
1528
#define CGEN_BFD_ARCH bfd_arch_mep
1529
#endif
1530
  arch = info->arch;
1531
  if (arch == bfd_arch_unknown)
1532
    arch = CGEN_BFD_ARCH;
1533
 
1534
  /* There's no standard way to compute the machine or isa number
1535
     so we leave it to the target.  */
1536
#ifdef CGEN_COMPUTE_MACH
1537
  mach = CGEN_COMPUTE_MACH (info);
1538
#else
1539
  mach = info->mach;
1540
#endif
1541
 
1542
#ifdef CGEN_COMPUTE_ISA
1543
  {
1544
    static CGEN_BITSET *permanent_isa;
1545
 
1546
    if (!permanent_isa)
1547
      permanent_isa = cgen_bitset_create (MAX_ISAS);
1548
    isa = permanent_isa;
1549
    cgen_bitset_clear (isa);
1550
    cgen_bitset_add (isa, CGEN_COMPUTE_ISA (info));
1551
  }
1552
#else
1553
  isa = info->insn_sets;
1554
#endif
1555
 
1556
  /* If we've switched cpu's, try to find a handle we've used before */
1557
  if (cd
1558
      && (cgen_bitset_compare (isa, prev_isa) != 0
1559
          || mach != prev_mach
1560
          || endian != prev_endian))
1561
    {
1562
      cd = 0;
1563
      for (cl = cd_list; cl; cl = cl->next)
1564
        {
1565
          if (cgen_bitset_compare (cl->isa, isa) == 0 &&
1566
              cl->mach == mach &&
1567
              cl->endian == endian)
1568
            {
1569
              cd = cl->cd;
1570
              prev_isa = cd->isas;
1571
              break;
1572
            }
1573
        }
1574
    }
1575
 
1576
  /* If we haven't initialized yet, initialize the opcode table.  */
1577
  if (! cd)
1578
    {
1579
      const bfd_arch_info_type *arch_type = bfd_lookup_arch (arch, mach);
1580
      const char *mach_name;
1581
 
1582
      if (!arch_type)
1583
        abort ();
1584
      mach_name = arch_type->printable_name;
1585
 
1586
      prev_isa = cgen_bitset_copy (isa);
1587
      prev_mach = mach;
1588
      prev_endian = endian;
1589
      cd = mep_cgen_cpu_open (CGEN_CPU_OPEN_ISAS, prev_isa,
1590
                                 CGEN_CPU_OPEN_BFDMACH, mach_name,
1591
                                 CGEN_CPU_OPEN_ENDIAN, prev_endian,
1592
                                 CGEN_CPU_OPEN_END);
1593
      if (!cd)
1594
        abort ();
1595
 
1596
      /* Save this away for future reference.  */
1597
      cl = xmalloc (sizeof (struct cpu_desc_list));
1598
      cl->cd = cd;
1599
      cl->isa = prev_isa;
1600
      cl->mach = mach;
1601
      cl->endian = endian;
1602
      cl->next = cd_list;
1603
      cd_list = cl;
1604
 
1605
      mep_cgen_init_dis (cd);
1606
    }
1607
 
1608
  /* We try to have as much common code as possible.
1609
     But at this point some targets need to take over.  */
1610
  /* ??? Some targets may need a hook elsewhere.  Try to avoid this,
1611
     but if not possible try to move this hook elsewhere rather than
1612
     have two hooks.  */
1613
  length = CGEN_PRINT_INSN (cd, pc, info);
1614
  if (length > 0)
1615
    return length;
1616
  if (length < 0)
1617
    return -1;
1618
 
1619
  (*info->fprintf_func) (info->stream, UNKNOWN_INSN_MSG);
1620
  return cd->default_insn_bitsize / 8;
1621
}

powered by: WebSVN 2.1.0

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