Coverage Report

Created: 2025-06-24 06:45

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