Coverage Report

Created: 2026-09-14 08:07

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