Coverage Report

Created: 2026-07-25 10:20

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
41.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
63
{
73
63
  disassemble_info *info = (disassemble_info *) dis_info;
74
75
63
  (*info->fprintf_func) (info->stream, "$tp");
76
63
}
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
81
{
83
81
  disassemble_info *info = (disassemble_info *) dis_info;
84
85
81
  (*info->fprintf_func) (info->stream, "$sp");
86
81
}
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
43.8k
#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
140
{
133
140
  int i;
134
140
  int status = 0;
135
140
  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
140
  if (corelength > 0)
141
124
    {
142
124
      int my_status = 0;
143
144
408
      for (i = 0; i < corelength; i++ )
145
284
  insnbuf[i] = buf[i];
146
124
      cd->isas = & MEP_CORE_ISA;
147
148
124
      my_status = print_insn (cd, pc, info, insnbuf, corelength);
149
124
      if (my_status != corelength)
150
10
  {
151
10
    (*info->fprintf_func) (info->stream, UNKNOWN_INSN_MSG);
152
10
    my_status = corelength;
153
10
  }
154
124
      status += my_status;
155
156
      /* Print the + to indicate that the following copro insn is
157
   part of a vliw group.  */
158
124
      if (copro1length > 0)
159
124
  (*info->fprintf_func) (info->stream, " + ");
160
124
    }
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
140
  if (copro1length > 0)
169
140
    {
170
140
      int my_status = 0;
171
172
976
      for (i = corelength; i < corelength + copro1length; i++ )
173
836
  insnbuf[i - corelength] = buf[i];
174
175
140
      switch (copro1length)
176
140
  {
177
0
  case 0:
178
0
    break;
179
0
  case 2:
180
0
    cd->isas = & MEP_COP16_ISA;
181
0
    break;
182
18
  case 4:
183
18
    cd->isas = & MEP_COP32_ISA;
184
18
    break;
185
106
  case 6:
186
106
    cd->isas = & MEP_COP48_ISA;
187
106
    break;
188
16
  case 8:
189
16
    cd->isas = & MEP_COP64_ISA;
190
16
    break;
191
0
  default:
192
    /* Shouldn't be anything but 16,32,48,64.  */
193
0
    break;
194
140
  }
195
196
140
      my_status = print_insn (cd, pc, info, insnbuf, copro1length);
197
198
140
      if (my_status != copro1length)
199
140
  {
200
140
    (*info->fprintf_func) (info->stream, UNKNOWN_INSN_MSG);
201
140
    my_status = copro1length;
202
140
  }
203
140
      status += my_status;
204
140
    }
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
140
  if ((!MEP_VLIW64 && (status != 4)) || (MEP_VLIW64 && (status != 8)))
259
0
    return -1;
260
140
  else
261
140
    return status;
262
140
}
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
140
{
367
140
  int status;
368
140
  int buflength;
369
140
  int corebuflength;
370
140
  int cop1buflength;
371
140
  int cop2buflength;
372
140
  bfd_byte buf[8];
373
140
  char indicator16[1];
374
140
  char indicator64[4];
375
376
  /* At this time we're not supporting internally parallel
377
     coprocessors, so cop2buflength will always be 0.  */
378
140
  cop2buflength = 0;
379
380
  /* Read in 64 bits.  */
381
140
  buflength = sizeof (buf);
382
140
  status = (*info->read_memory_func) (pc, buf, buflength, info);
383
384
140
  if (status != 0)
385
0
    {
386
0
      (*info->memory_error_func) (status, pc, info);
387
0
      return -1;
388
0
    }
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
140
  if (info->endian == BFD_ENDIAN_BIG)
403
140
    {
404
140
      indicator16[0] = buf[0];
405
140
      indicator64[0] = buf[0];
406
140
      indicator64[1] = buf[1];
407
140
      indicator64[2] = buf[2];
408
140
      indicator64[3] = buf[3];
409
140
    }
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
140
  if ((indicator16[0] & 0x80) && (indicator16[0] & 0x40))
423
34
    {
424
34
      if ((indicator64[0] & 0xf0) == 0xf0 && (indicator64[1] & 0x07) == 0x07
425
16
    && ((indicator64[2] & 0xfe) != 0xf0 || (indicator64[3] & 0xf4) != 0))
426
16
  {
427
    /* We have a 64 bit copro insn.  */
428
16
    corebuflength = 0;
429
    /* All 8 bytes are one copro insn.  */
430
16
    cop1buflength = 8;
431
16
  }
432
18
      else
433
18
  {
434
    /* We have a 32 bit core insn and a 32 bit copro insn.  */
435
18
    corebuflength = 4;
436
18
    cop1buflength = 4;
437
18
  }
438
34
    }
439
106
  else
440
106
    {
441
      /* We have a 16 bit core insn and a 48 bit copro insn.  */
442
106
      corebuflength = 2;
443
106
      cop1buflength = 6;
444
106
    }
445
446
  /* Now we have the distrubution set.  Print them out. */
447
140
  status = mep_print_vliw_insns (cd, pc, info, buf, corebuflength,
448
140
         cop1buflength, cop2buflength);
449
450
140
  return status;
451
140
}
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
43.8k
{
629
43.8k
  int status;
630
43.8k
  int cop_type;
631
43.8k
  int ivc2 = 0;
632
43.8k
  static CGEN_ATTR_VALUE_BITSET_TYPE *ivc2_core_isa = NULL;
633
634
43.8k
  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
43.8k
  if (info->section && info->section->owner)
644
2.15k
    {
645
2.15k
      bfd *abfd = info->section->owner;
646
2.15k
      if (bfd_get_flavour (abfd) == bfd_target_elf_flavour)
647
2.15k
  {
648
2.15k
    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
2.15k
    int i;
655
4.58k
    for (i = 0; i <= mep_config_index; i++)
656
2.44k
      if (mep_config_map[i].name == NULL)
657
12
        break;
658
659
2.15k
    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
2.15k
    cop_type = abfd->tdata.elf_obj_data->elf_header->e_flags & EF_MEP_COP_MASK;
666
2.15k
    if (cop_type == EF_MEP_COP_IVC2)
667
0
      ivc2 = 1;
668
2.15k
  }
669
2.15k
    }
670
671
  /* Picking the right ISA bitmask for the current context is tricky.  */
672
43.8k
  if (info->section)
673
2.15k
    {
674
2.15k
      if (info->section->flags & SEC_MEP_VLIW)
675
140
  {
676
140
#ifdef MEP_IVC2_SUPPORTED
677
140
    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
140
    else
684
140
#endif
685
      /* Are we in 32 or 64 bit vliw mode?  */
686
140
      if (MEP_VLIW64)
687
140
        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
140
  }
692
2.01k
      else
693
2.01k
  {
694
2.01k
    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
2.01k
    else
702
2.01k
      cd->isas = & MEP_CORE_ISA;
703
2.01k
    status = default_print_insn (cd, pc, info);
704
2.01k
  }
705
2.15k
    }
706
41.6k
  else /* sid or gdb */
707
41.6k
    {
708
41.6k
#ifdef MEP_IVC2_SUPPORTED
709
41.6k
      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
41.6k
#endif
724
725
41.6k
      status = default_print_insn (cd, pc, info);
726
41.6k
    }
727
728
43.8k
  return status;
729
43.8k
}
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
2.76k
{
761
2.76k
  disassemble_info *info = (disassemble_info *) xinfo;
762
763
2.76k
  switch (opindex)
764
2.76k
    {
765
7
    case MEP_OPERAND_ADDR24A4 :
766
7
      print_normal (cd, info, fields->f_24u8a4n, 0|(1<<CGEN_OPERAND_VIRTUAL), pc, length);
767
7
      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
0
    case MEP_OPERAND_CCCC :
778
0
      print_normal (cd, info, fields->f_rm, 0, pc, length);
779
0
      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
40
    case MEP_OPERAND_CIMM4 :
799
40
      print_normal (cd, info, fields->f_rn, 0, pc, length);
800
40
      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
67
    case MEP_OPERAND_CRN :
814
67
      print_keyword (cd, info, & mep_cgen_opval_h_cr, fields->f_crn, 0);
815
67
      break;
816
84
    case MEP_OPERAND_CRN64 :
817
84
      print_keyword (cd, info, & mep_cgen_opval_h_cr64, fields->f_crn, 0);
818
84
      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
8
    case MEP_OPERAND_CRPP :
835
8
      print_keyword (cd, info, & mep_cgen_opval_h_cr64, fields->f_ivc2_5u18, 0);
836
8
      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
8
    case MEP_OPERAND_CRQP :
841
8
      print_keyword (cd, info, & mep_cgen_opval_h_cr64, fields->f_ivc2_5u13, 0);
842
8
      break;
843
8
    case MEP_OPERAND_CSRN :
844
8
      print_keyword (cd, info, & mep_cgen_opval_h_csr, fields->f_csrn, 0|(1<<CGEN_OPERAND_VIRTUAL));
845
8
      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
1
    case MEP_OPERAND_PCABS24A2 :
1045
1
      print_address (cd, info, fields->f_24u5a2n, 0|(1<<CGEN_OPERAND_ABS_ADDR)|(1<<CGEN_OPERAND_VIRTUAL), pc, length);
1046
1
      break;
1047
51
    case MEP_OPERAND_PCREL12A2 :
1048
51
      print_address (cd, info, fields->f_12s4a2, 0|(1<<CGEN_OPERAND_SIGNED)|(1<<CGEN_OPERAND_RELAX)|(1<<CGEN_OPERAND_PCREL_ADDR), pc, length);
1049
51
      break;
1050
10
    case MEP_OPERAND_PCREL17A2 :
1051
10
      print_address (cd, info, fields->f_17s16a2, 0|(1<<CGEN_OPERAND_SIGNED)|(1<<CGEN_OPERAND_RELAX)|(1<<CGEN_OPERAND_PCREL_ADDR), pc, length);
1052
10
      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
22
    case MEP_OPERAND_PCREL8A2 :
1057
22
      print_address (cd, info, fields->f_8s8a2, 0|(1<<CGEN_OPERAND_SIGNED)|(1<<CGEN_OPERAND_RELAX)|(1<<CGEN_OPERAND_PCREL_ADDR), pc, length);
1058
22
      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
12
    case MEP_OPERAND_RL :
1069
12
      print_keyword (cd, info, & mep_cgen_opval_h_gpr, fields->f_rl, 0);
1070
12
      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
274
    case MEP_OPERAND_RM :
1075
274
      print_keyword (cd, info, & mep_cgen_opval_h_gpr, fields->f_rm, 0);
1076
274
      break;
1077
351
    case MEP_OPERAND_RMA :
1078
351
      print_keyword (cd, info, & mep_cgen_opval_h_gpr, fields->f_rm, 0);
1079
351
      break;
1080
515
    case MEP_OPERAND_RN :
1081
515
      print_keyword (cd, info, & mep_cgen_opval_h_gpr, fields->f_rn, 0);
1082
515
      break;
1083
223
    case MEP_OPERAND_RN3 :
1084
223
      print_keyword (cd, info, & mep_cgen_opval_h_gpr, fields->f_rn3, 0);
1085
223
      break;
1086
10
    case MEP_OPERAND_RN3C :
1087
10
      print_keyword (cd, info, & mep_cgen_opval_h_gpr, fields->f_rn3, 0);
1088
10
      break;
1089
9
    case MEP_OPERAND_RN3L :
1090
9
      print_keyword (cd, info, & mep_cgen_opval_h_gpr, fields->f_rn3, 0);
1091
9
      break;
1092
25
    case MEP_OPERAND_RN3S :
1093
25
      print_keyword (cd, info, & mep_cgen_opval_h_gpr, fields->f_rn3, 0);
1094
25
      break;
1095
12
    case MEP_OPERAND_RN3UC :
1096
12
      print_keyword (cd, info, & mep_cgen_opval_h_gpr, fields->f_rn3, 0);
1097
12
      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
7
    case MEP_OPERAND_RN3US :
1102
7
      print_keyword (cd, info, & mep_cgen_opval_h_gpr, fields->f_rn3, 0);
1103
7
      break;
1104
27
    case MEP_OPERAND_RNC :
1105
27
      print_keyword (cd, info, & mep_cgen_opval_h_gpr, fields->f_rn, 0);
1106
27
      break;
1107
100
    case MEP_OPERAND_RNL :
1108
100
      print_keyword (cd, info, & mep_cgen_opval_h_gpr, fields->f_rn, 0);
1109
100
      break;
1110
27
    case MEP_OPERAND_RNS :
1111
27
      print_keyword (cd, info, & mep_cgen_opval_h_gpr, fields->f_rn, 0);
1112
27
      break;
1113
3
    case MEP_OPERAND_RNUC :
1114
3
      print_keyword (cd, info, & mep_cgen_opval_h_gpr, fields->f_rn, 0);
1115
3
      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
24
    case MEP_OPERAND_RNUS :
1120
24
      print_keyword (cd, info, & mep_cgen_opval_h_gpr, fields->f_rn, 0);
1121
24
      break;
1122
0
    case MEP_OPERAND_SAR :
1123
0
      print_keyword (cd, info, & mep_cgen_opval_h_csr, 0, 0);
1124
0
      break;
1125
74
    case MEP_OPERAND_SDISP16 :
1126
74
      print_normal (cd, info, fields->f_16s16, 0|(1<<CGEN_OPERAND_SIGNED), pc, length);
1127
74
      break;
1128
8
    case MEP_OPERAND_SIMM16 :
1129
8
      print_normal (cd, info, fields->f_16s16, 0|(1<<CGEN_OPERAND_SIGNED), pc, length);
1130
8
      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
52
    case MEP_OPERAND_SIMM6 :
1135
52
      print_normal (cd, info, fields->f_6s8, 0|(1<<CGEN_OPERAND_SIGNED), pc, length);
1136
52
      break;
1137
67
    case MEP_OPERAND_SIMM8 :
1138
67
      print_normal (cd, info, fields->f_8s8, 0|(1<<CGEN_OPERAND_SIGNED)|(1<<CGEN_OPERAND_RELOC_IMPLIES_OVERFLOW), pc, length);
1139
67
      break;
1140
4
    case MEP_OPERAND_SIMM8P0 :
1141
4
      print_normal (cd, info, fields->f_ivc2_8s0, 0|(1<<CGEN_OPERAND_SIGNED), pc, length);
1142
4
      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
81
    case MEP_OPERAND_SPR :
1153
81
      print_spreg (cd, info, & mep_cgen_opval_h_gpr, 0, 0);
1154
81
      break;
1155
0
    case MEP_OPERAND_TP :
1156
0
      print_keyword (cd, info, & mep_cgen_opval_h_gpr, 0, 0);
1157
0
      break;
1158
63
    case MEP_OPERAND_TPR :
1159
63
      print_tpreg (cd, info, & mep_cgen_opval_h_gpr, 0, 0);
1160
63
      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
22
    case MEP_OPERAND_UDISP7 :
1165
22
      print_normal (cd, info, fields->f_7u9, 0, pc, length);
1166
22
      break;
1167
32
    case MEP_OPERAND_UDISP7A2 :
1168
32
      print_normal (cd, info, fields->f_7u9a2, 0, pc, length);
1169
32
      break;
1170
70
    case MEP_OPERAND_UDISP7A4 :
1171
70
      print_normal (cd, info, fields->f_7u9a4, 0, pc, length);
1172
70
      break;
1173
6
    case MEP_OPERAND_UIMM16 :
1174
6
      print_normal (cd, info, fields->f_16u16, 0, pc, length);
1175
6
      break;
1176
0
    case MEP_OPERAND_UIMM2 :
1177
0
      print_normal (cd, info, fields->f_2u10, 0, pc, length);
1178
0
      break;
1179
223
    case MEP_OPERAND_UIMM24 :
1180
223
      print_normal (cd, info, fields->f_24u8n, 0|(1<<CGEN_OPERAND_VIRTUAL), pc, length);
1181
223
      break;
1182
40
    case MEP_OPERAND_UIMM3 :
1183
40
      print_normal (cd, info, fields->f_3u5, 0, pc, length);
1184
40
      break;
1185
1
    case MEP_OPERAND_UIMM4 :
1186
1
      print_normal (cd, info, fields->f_4u8, 0, pc, length);
1187
1
      break;
1188
69
    case MEP_OPERAND_UIMM5 :
1189
69
      print_normal (cd, info, fields->f_5u8, 0, pc, length);
1190
69
      break;
1191
20
    case MEP_OPERAND_UIMM7A4 :
1192
20
      print_normal (cd, info, fields->f_7u9a4, 0, pc, length);
1193
20
      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
2.76k
  }
1205
2.76k
}
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
8
{
1216
8
  mep_cgen_init_opcode_table (cd);
1217
8
  mep_cgen_init_ibld_table (cd);
1218
8
  cd->print_handlers = & mep_cgen_print_handlers[0];
1219
8
  cd->print_operand = mep_cgen_print_operand;
1220
8
}
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
740
{
1233
740
  disassemble_info *info = (disassemble_info *) dis_info;
1234
1235
  /* Print the operand as directed by the attributes.  */
1236
740
  if (CGEN_BOOL_ATTR (attrs, CGEN_OPERAND_SEM_ONLY))
1237
0
    ; /* nothing to do */
1238
740
  else if (CGEN_BOOL_ATTR (attrs, CGEN_OPERAND_SIGNED))
1239
206
    (*info->fprintf_func) (info->stream, "%ld", value);
1240
534
  else
1241
534
    (*info->fprintf_func) (info->stream, "0x%lx", value);
1242
740
}
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
84
{
1254
84
  disassemble_info *info = (disassemble_info *) dis_info;
1255
1256
  /* Print the operand as directed by the attributes.  */
1257
84
  if (CGEN_BOOL_ATTR (attrs, CGEN_OPERAND_SEM_ONLY))
1258
0
    ; /* Nothing to do.  */
1259
84
  else if (CGEN_BOOL_ATTR (attrs, CGEN_OPERAND_PCREL_ADDR))
1260
83
    (*info->print_address_func) (value, info);
1261
1
  else if (CGEN_BOOL_ATTR (attrs, CGEN_OPERAND_ABS_ADDR))
1262
1
    (*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
84
}
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
1.79k
{
1278
1.79k
  disassemble_info *info = (disassemble_info *) dis_info;
1279
1.79k
  const CGEN_KEYWORD_ENTRY *ke;
1280
1281
1.79k
  ke = cgen_keyword_lookup_value (keyword_table, value);
1282
1.79k
  if (ke != NULL)
1283
1.79k
    (*info->fprintf_func) (info->stream, "%s", ke->name);
1284
0
  else
1285
0
    (*info->fprintf_func) (info->stream, "???");
1286
1.79k
}
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
2.02k
{
1301
2.02k
  const CGEN_SYNTAX *syntax = CGEN_INSN_SYNTAX (insn);
1302
2.02k
  disassemble_info *info = (disassemble_info *) dis_info;
1303
2.02k
  const CGEN_SYNTAX_CHAR_TYPE *syn;
1304
1305
2.02k
  CGEN_INIT_PRINT (cd);
1306
1307
10.6k
  for (syn = CGEN_SYNTAX_STRING (syntax); *syn; ++syn)
1308
8.64k
    {
1309
8.64k
      if (CGEN_SYNTAX_MNEMONIC_P (*syn))
1310
2.02k
  {
1311
2.02k
    (*info->fprintf_func) (info->stream, "%s", CGEN_INSN_MNEMONIC (insn));
1312
2.02k
    continue;
1313
2.02k
  }
1314
6.61k
      if (CGEN_SYNTAX_CHAR_P (*syn))
1315
3.84k
  {
1316
3.84k
    (*info->fprintf_func) (info->stream, "%c", CGEN_SYNTAX_CHAR (*syn));
1317
3.84k
    continue;
1318
3.84k
  }
1319
1320
      /* We have an operand.  */
1321
2.76k
      mep_cgen_print_operand (cd, CGEN_SYNTAX_FIELD (*syn), info,
1322
2.76k
         fields, CGEN_INSN_ATTRS (insn), pc, length);
1323
2.76k
    }
1324
2.02k
}
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
43.8k
{
1368
43.8k
  CGEN_INSN_INT insn_value;
1369
43.8k
  const CGEN_INSN_LIST *insn_list;
1370
43.8k
  CGEN_EXTRACT_INFO ex_info;
1371
43.8k
  int basesize;
1372
1373
  /* Extract base part of instruction, just in case CGEN_DIS_* uses it. */
1374
43.8k
  basesize = cd->base_insn_bitsize < buflen * 8 ?
1375
43.7k
                                     cd->base_insn_bitsize : buflen * 8;
1376
43.8k
  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
43.8k
  ex_info.valid = (1 << buflen) - 1;
1383
43.8k
  ex_info.dis_info = info;
1384
43.8k
  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
43.8k
  insn_list = CGEN_DIS_LOOKUP_INSN (cd, (char *) buf, insn_value);
1390
39.7M
  while (insn_list != NULL)
1391
39.7M
    {
1392
39.7M
      const CGEN_INSN *insn = insn_list->insn;
1393
39.7M
      CGEN_FIELDS fields;
1394
39.7M
      int length;
1395
39.7M
      unsigned long insn_value_cropped;
1396
1397
39.7M
#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
39.7M
      if (! mep_cgen_insn_supported (cd, insn))
1401
39.4M
        {
1402
39.4M
          insn_list = CGEN_DIS_NEXT_INSN (insn_list);
1403
39.4M
    continue;
1404
39.4M
        }
1405
272k
#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
272k
      if ((unsigned) (CGEN_INSN_BITSIZE (insn) / 8) < buflen &&
1414
135k
    (unsigned) (CGEN_INSN_BITSIZE (insn) / 8) <= sizeof (unsigned long))
1415
135k
  insn_value_cropped = bfd_get_bits (buf, CGEN_INSN_BITSIZE (insn),
1416
135k
             info->endian == BFD_ENDIAN_BIG);
1417
136k
      else
1418
136k
  insn_value_cropped = insn_value;
1419
1420
272k
      if ((insn_value_cropped & CGEN_INSN_BASE_MASK (insn))
1421
272k
    == CGEN_INSN_BASE_VALUE (insn))
1422
2.02k
  {
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
2.02k
    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
2.02k
    else
1442
2.02k
      length = CGEN_EXTRACT_FN (cd, insn)
1443
2.02k
        (cd, insn, &ex_info, insn_value_cropped, &fields, pc);
1444
1445
    /* Length < 0 -> error.  */
1446
2.02k
    if (length < 0)
1447
0
      return length;
1448
2.02k
    if (length > 0)
1449
2.02k
      {
1450
2.02k
        CGEN_PRINT_FN (cd, insn) (cd, info, insn, &fields, pc, length);
1451
        /* Length is in bits, result is in bytes.  */
1452
2.02k
        return length / 8;
1453
2.02k
      }
1454
2.02k
  }
1455
1456
269k
      insn_list = CGEN_DIS_NEXT_INSN (insn_list);
1457
269k
    }
1458
1459
41.8k
  return 0;
1460
43.8k
}
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
43.6k
{
1473
43.6k
  bfd_byte buf[CGEN_MAX_INSN_SIZE];
1474
43.6k
  int buflen;
1475
43.6k
  int status;
1476
1477
  /* Attempt to read the base part of the insn.  */
1478
43.6k
  buflen = cd->base_insn_bitsize / 8;
1479
43.6k
  status = (*info->read_memory_func) (pc, buf, buflen, info);
1480
1481
  /* Try again with the minimum part, if min < base.  */
1482
43.6k
  if (status != 0 && (cd->min_insn_bitsize < cd->base_insn_bitsize))
1483
231
    {
1484
231
      buflen = cd->min_insn_bitsize / 8;
1485
231
      status = (*info->read_memory_func) (pc, buf, buflen, info);
1486
231
    }
1487
1488
43.6k
  if (status != 0)
1489
83
    {
1490
83
      (*info->memory_error_func) (status, pc, info);
1491
83
      return -1;
1492
83
    }
1493
1494
43.5k
  return print_insn (cd, pc, info, buf, buflen);
1495
43.6k
}
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
43.8k
{
1514
43.8k
  static cpu_desc_list *cd_list = 0;
1515
43.8k
  cpu_desc_list *cl = 0;
1516
43.8k
  static CGEN_CPU_DESC cd = 0;
1517
43.8k
  static CGEN_BITSET *prev_isa;
1518
43.8k
  static int prev_mach;
1519
43.8k
  static int prev_endian;
1520
43.8k
  static int prev_insn_endian;
1521
43.8k
  int length;
1522
43.8k
  CGEN_BITSET *isa;
1523
43.8k
  int mach;
1524
43.8k
  int endian = (info->endian == BFD_ENDIAN_BIG
1525
43.8k
    ? CGEN_ENDIAN_BIG
1526
43.8k
    : CGEN_ENDIAN_LITTLE);
1527
43.8k
  int insn_endian = (info->endian_code == BFD_ENDIAN_BIG
1528
43.8k
                     ? CGEN_ENDIAN_BIG
1529
43.8k
                     : CGEN_ENDIAN_LITTLE);
1530
43.8k
  enum bfd_architecture arch;
1531
1532
  /* ??? gdb will set mach but leave the architecture as "unknown" */
1533
43.8k
#ifndef CGEN_BFD_ARCH
1534
43.8k
#define CGEN_BFD_ARCH bfd_arch_mep
1535
43.8k
#endif
1536
43.8k
  arch = info->arch;
1537
43.8k
  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
43.8k
  mach = info->mach;
1546
43.8k
#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
43.8k
  isa = info->private_data;
1560
43.8k
#endif
1561
1562
  /* If we've switched cpu's, try to find a handle we've used before */
1563
43.8k
  if (cd
1564
43.8k
      && (cgen_bitset_compare (isa, prev_isa) != 0
1565
43.8k
    || mach != prev_mach
1566
6.51k
    || endian != prev_endian))
1567
37.2k
    {
1568
37.2k
      cd = 0;
1569
107k
      for (cl = cd_list; cl; cl = cl->next)
1570
107k
  {
1571
107k
    if (cgen_bitset_compare (cl->isa, isa) == 0 &&
1572
107k
        cl->mach == mach &&
1573
37.2k
        cl->endian == endian)
1574
37.2k
      {
1575
37.2k
        cd = cl->cd;
1576
37.2k
        prev_isa = cd->isas;
1577
37.2k
        break;
1578
37.2k
      }
1579
107k
  }
1580
37.2k
    }
1581
1582
  /* If we haven't initialized yet, initialize the opcode table.  */
1583
43.8k
  if (! cd)
1584
8
    {
1585
8
      const bfd_arch_info_type *arch_type = bfd_lookup_arch (arch, mach);
1586
8
      const char *mach_name;
1587
1588
8
      if (!arch_type)
1589
0
  abort ();
1590
8
      mach_name = arch_type->printable_name;
1591
1592
8
      prev_isa = cgen_bitset_copy (isa);
1593
8
      prev_mach = mach;
1594
8
      prev_endian = endian;
1595
8
      prev_insn_endian = insn_endian;
1596
8
      cd = mep_cgen_cpu_open (CGEN_CPU_OPEN_ISAS, prev_isa,
1597
8
         CGEN_CPU_OPEN_BFDMACH, mach_name,
1598
8
         CGEN_CPU_OPEN_ENDIAN, prev_endian,
1599
8
                                 CGEN_CPU_OPEN_INSN_ENDIAN, prev_insn_endian,
1600
8
         CGEN_CPU_OPEN_END);
1601
8
      if (!cd)
1602
0
  abort ();
1603
1604
      /* Save this away for future reference.  */
1605
8
      cl = xmalloc (sizeof (struct cpu_desc_list));
1606
8
      cl->cd = cd;
1607
8
      cl->isa = prev_isa;
1608
8
      cl->mach = mach;
1609
8
      cl->endian = endian;
1610
8
      cl->next = cd_list;
1611
8
      cd_list = cl;
1612
1613
8
      mep_cgen_init_dis (cd);
1614
8
    }
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
43.8k
  length = CGEN_PRINT_INSN (cd, pc, info);
1622
43.8k
  if (length > 0)
1623
2.04k
    return length;
1624
41.7k
  if (length < 0)
1625
83
    return -1;
1626
1627
41.6k
  (*info->fprintf_func) (info->stream, UNKNOWN_INSN_MSG);
1628
41.6k
  return cd->default_insn_bitsize / 8;
1629
41.7k
}