Coverage Report

Created: 2026-10-02 09:53

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
57.0k
#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
180
{
73
180
  disassemble_info *info = (disassemble_info *) dis_info;
74
75
180
  (*info->fprintf_func) (info->stream, "$tp");
76
180
}
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
60.3k
#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
305
{
133
305
  int i;
134
305
  int status = 0;
135
305
  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
305
  if (corelength > 0)
141
283
    {
142
283
      int my_status = 0;
143
144
919
      for (i = 0; i < corelength; i++ )
145
636
  insnbuf[i] = buf[i];
146
283
      cd->isas = & MEP_CORE_ISA;
147
148
283
      my_status = print_insn (cd, pc, info, insnbuf, corelength);
149
283
      if (my_status != corelength)
150
19
  {
151
19
    (*info->fprintf_func) (info->stream, UNKNOWN_INSN_MSG);
152
19
    my_status = corelength;
153
19
  }
154
283
      status += my_status;
155
156
      /* Print the + to indicate that the following copro insn is
157
   part of a vliw group.  */
158
283
      if (copro1length > 0)
159
283
  (*info->fprintf_func) (info->stream, " + ");
160
283
    }
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
305
  if (copro1length > 0)
169
305
    {
170
305
      int my_status = 0;
171
172
2.10k
      for (i = corelength; i < corelength + copro1length; i++ )
173
1.80k
  insnbuf[i - corelength] = buf[i];
174
175
305
      switch (copro1length)
176
305
  {
177
0
  case 0:
178
0
    break;
179
0
  case 2:
180
0
    cd->isas = & MEP_COP16_ISA;
181
0
    break;
182
35
  case 4:
183
35
    cd->isas = & MEP_COP32_ISA;
184
35
    break;
185
248
  case 6:
186
248
    cd->isas = & MEP_COP48_ISA;
187
248
    break;
188
22
  case 8:
189
22
    cd->isas = & MEP_COP64_ISA;
190
22
    break;
191
0
  default:
192
    /* Shouldn't be anything but 16,32,48,64.  */
193
0
    break;
194
305
  }
195
196
305
      my_status = print_insn (cd, pc, info, insnbuf, copro1length);
197
198
305
      if (my_status != copro1length)
199
305
  {
200
305
    (*info->fprintf_func) (info->stream, UNKNOWN_INSN_MSG);
201
305
    my_status = copro1length;
202
305
  }
203
305
      status += my_status;
204
305
    }
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
305
  if ((!MEP_VLIW64 && (status != 4)) || (MEP_VLIW64 && (status != 8)))
259
0
    return -1;
260
305
  else
261
305
    return status;
262
305
}
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
306
{
367
306
  int status;
368
306
  int buflength;
369
306
  int corebuflength;
370
306
  int cop1buflength;
371
306
  int cop2buflength;
372
306
  bfd_byte buf[8];
373
306
  char indicator16[1];
374
306
  char indicator64[4];
375
376
  /* At this time we're not supporting internally parallel
377
     coprocessors, so cop2buflength will always be 0.  */
378
306
  cop2buflength = 0;
379
380
  /* Read in 64 bits.  */
381
306
  buflength = sizeof (buf);
382
306
  status = (*info->read_memory_func) (pc, buf, buflength, info);
383
384
306
  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
305
  if (info->endian == BFD_ENDIAN_BIG)
403
305
    {
404
305
      indicator16[0] = buf[0];
405
305
      indicator64[0] = buf[0];
406
305
      indicator64[1] = buf[1];
407
305
      indicator64[2] = buf[2];
408
305
      indicator64[3] = buf[3];
409
305
    }
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
305
  if ((indicator16[0] & 0x80) && (indicator16[0] & 0x40))
423
57
    {
424
57
      if ((indicator64[0] & 0xf0) == 0xf0 && (indicator64[1] & 0x07) == 0x07
425
22
    && ((indicator64[2] & 0xfe) != 0xf0 || (indicator64[3] & 0xf4) != 0))
426
22
  {
427
    /* We have a 64 bit copro insn.  */
428
22
    corebuflength = 0;
429
    /* All 8 bytes are one copro insn.  */
430
22
    cop1buflength = 8;
431
22
  }
432
35
      else
433
35
  {
434
    /* We have a 32 bit core insn and a 32 bit copro insn.  */
435
35
    corebuflength = 4;
436
35
    cop1buflength = 4;
437
35
  }
438
57
    }
439
248
  else
440
248
    {
441
      /* We have a 16 bit core insn and a 48 bit copro insn.  */
442
248
      corebuflength = 2;
443
248
      cop1buflength = 6;
444
248
    }
445
446
  /* Now we have the distrubution set.  Print them out. */
447
305
  status = mep_print_vliw_insns (cd, pc, info, buf, corebuflength,
448
305
         cop1buflength, cop2buflength);
449
450
305
  return status;
451
306
}
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
60.3k
{
629
60.3k
  int status;
630
60.3k
  int cop_type;
631
60.3k
  int ivc2 = 0;
632
60.3k
  static CGEN_ATTR_VALUE_BITSET_TYPE *ivc2_core_isa = NULL;
633
634
60.3k
  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
60.3k
  if (info->section && info->section->owner)
644
3.71k
    {
645
3.71k
      bfd *abfd = info->section->owner;
646
3.71k
      if (bfd_get_flavour (abfd) == bfd_target_elf_flavour)
647
3.71k
  {
648
3.71k
    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.71k
    int i;
655
8.26k
    for (i = 0; i <= mep_config_index; i++)
656
4.55k
      if (mep_config_map[i].name == NULL)
657
12
        break;
658
659
3.71k
    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.71k
    cop_type = abfd->tdata.elf_obj_data->elf_header->e_flags & EF_MEP_COP_MASK;
666
3.71k
    if (cop_type == EF_MEP_COP_IVC2)
667
0
      ivc2 = 1;
668
3.71k
  }
669
3.71k
    }
670
671
  /* Picking the right ISA bitmask for the current context is tricky.  */
672
60.3k
  if (info->section)
673
3.71k
    {
674
3.71k
      if (info->section->flags & SEC_MEP_VLIW)
675
306
  {
676
306
#ifdef MEP_IVC2_SUPPORTED
677
306
    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
306
    else
684
306
#endif
685
      /* Are we in 32 or 64 bit vliw mode?  */
686
306
      if (MEP_VLIW64)
687
306
        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
306
  }
692
3.40k
      else
693
3.40k
  {
694
3.40k
    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.40k
    else
702
3.40k
      cd->isas = & MEP_CORE_ISA;
703
3.40k
    status = default_print_insn (cd, pc, info);
704
3.40k
  }
705
3.71k
    }
706
56.5k
  else /* sid or gdb */
707
56.5k
    {
708
56.5k
#ifdef MEP_IVC2_SUPPORTED
709
56.5k
      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
56.5k
#endif
724
725
56.5k
      status = default_print_insn (cd, pc, info);
726
56.5k
    }
727
728
60.3k
  return status;
729
60.3k
}
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.93k
{
761
4.93k
  disassemble_info *info = (disassemble_info *) xinfo;
762
763
4.93k
  switch (opindex)
764
4.93k
    {
765
32
    case MEP_OPERAND_ADDR24A4 :
766
32
      print_normal (cd, info, fields->f_24u8a4n, 0|(1<<CGEN_OPERAND_VIRTUAL), pc, length);
767
32
      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
29
    case MEP_OPERAND_CIMM4 :
799
29
      print_normal (cd, info, fields->f_rn, 0, pc, length);
800
29
      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
133
    case MEP_OPERAND_CRN :
814
133
      print_keyword (cd, info, & mep_cgen_opval_h_cr, fields->f_crn, 0);
815
133
      break;
816
177
    case MEP_OPERAND_CRN64 :
817
177
      print_keyword (cd, info, & mep_cgen_opval_h_cr64, fields->f_crn, 0);
818
177
      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
5
    case MEP_OPERAND_CROP :
829
5
      print_keyword (cd, info, & mep_cgen_opval_h_cr64, fields->f_ivc2_5u23, 0);
830
5
      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
11
    case MEP_OPERAND_CRPP :
835
11
      print_keyword (cd, info, & mep_cgen_opval_h_cr64, fields->f_ivc2_5u18, 0);
836
11
      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
11
    case MEP_OPERAND_CRQP :
841
11
      print_keyword (cd, info, & mep_cgen_opval_h_cr64, fields->f_ivc2_5u13, 0);
842
11
      break;
843
21
    case MEP_OPERAND_CSRN :
844
21
      print_keyword (cd, info, & mep_cgen_opval_h_csr, fields->f_csrn, 0|(1<<CGEN_OPERAND_VIRTUAL));
845
21
      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
5
    case MEP_OPERAND_IMM3P5 :
877
5
      print_normal (cd, info, fields->f_ivc2_3u5, 0, pc, length);
878
5
      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
9
    case MEP_OPERAND_PCABS24A2 :
1045
9
      print_address (cd, info, fields->f_24u5a2n, 0|(1<<CGEN_OPERAND_ABS_ADDR)|(1<<CGEN_OPERAND_VIRTUAL), pc, length);
1046
9
      break;
1047
126
    case MEP_OPERAND_PCREL12A2 :
1048
126
      print_address (cd, info, fields->f_12s4a2, 0|(1<<CGEN_OPERAND_SIGNED)|(1<<CGEN_OPERAND_RELAX)|(1<<CGEN_OPERAND_PCREL_ADDR), pc, length);
1049
126
      break;
1050
38
    case MEP_OPERAND_PCREL17A2 :
1051
38
      print_address (cd, info, fields->f_17s16a2, 0|(1<<CGEN_OPERAND_SIGNED)|(1<<CGEN_OPERAND_RELAX)|(1<<CGEN_OPERAND_PCREL_ADDR), pc, length);
1052
38
      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
82
    case MEP_OPERAND_PCREL8A2 :
1057
82
      print_address (cd, info, fields->f_8s8a2, 0|(1<<CGEN_OPERAND_SIGNED)|(1<<CGEN_OPERAND_RELAX)|(1<<CGEN_OPERAND_PCREL_ADDR), pc, length);
1058
82
      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
57
    case MEP_OPERAND_RL :
1069
57
      print_keyword (cd, info, & mep_cgen_opval_h_gpr, fields->f_rl, 0);
1070
57
      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
532
    case MEP_OPERAND_RM :
1075
532
      print_keyword (cd, info, & mep_cgen_opval_h_gpr, fields->f_rm, 0);
1076
532
      break;
1077
671
    case MEP_OPERAND_RMA :
1078
671
      print_keyword (cd, info, & mep_cgen_opval_h_gpr, fields->f_rm, 0);
1079
671
      break;
1080
1.02k
    case MEP_OPERAND_RN :
1081
1.02k
      print_keyword (cd, info, & mep_cgen_opval_h_gpr, fields->f_rn, 0);
1082
1.02k
      break;
1083
69
    case MEP_OPERAND_RN3 :
1084
69
      print_keyword (cd, info, & mep_cgen_opval_h_gpr, fields->f_rn3, 0);
1085
69
      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
95
    case MEP_OPERAND_RN3S :
1093
95
      print_keyword (cd, info, & mep_cgen_opval_h_gpr, fields->f_rn3, 0);
1094
95
      break;
1095
42
    case MEP_OPERAND_RN3UC :
1096
42
      print_keyword (cd, info, & mep_cgen_opval_h_gpr, fields->f_rn3, 0);
1097
42
      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
70
    case MEP_OPERAND_RNC :
1105
70
      print_keyword (cd, info, & mep_cgen_opval_h_gpr, fields->f_rn, 0);
1106
70
      break;
1107
214
    case MEP_OPERAND_RNL :
1108
214
      print_keyword (cd, info, & mep_cgen_opval_h_gpr, fields->f_rn, 0);
1109
214
      break;
1110
58
    case MEP_OPERAND_RNS :
1111
58
      print_keyword (cd, info, & mep_cgen_opval_h_gpr, fields->f_rn, 0);
1112
58
      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
43
    case MEP_OPERAND_RNUS :
1120
43
      print_keyword (cd, info, & mep_cgen_opval_h_gpr, fields->f_rn, 0);
1121
43
      break;
1122
0
    case MEP_OPERAND_SAR :
1123
0
      print_keyword (cd, info, & mep_cgen_opval_h_csr, 0, 0);
1124
0
      break;
1125
191
    case MEP_OPERAND_SDISP16 :
1126
191
      print_normal (cd, info, fields->f_16s16, 0|(1<<CGEN_OPERAND_SIGNED), pc, length);
1127
191
      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
93
    case MEP_OPERAND_SIMM6 :
1135
93
      print_normal (cd, info, fields->f_6s8, 0|(1<<CGEN_OPERAND_SIGNED), pc, length);
1136
93
      break;
1137
127
    case MEP_OPERAND_SIMM8 :
1138
127
      print_normal (cd, info, fields->f_8s8, 0|(1<<CGEN_OPERAND_SIGNED)|(1<<CGEN_OPERAND_RELOC_IMPLIES_OVERFLOW), pc, length);
1139
127
      break;
1140
6
    case MEP_OPERAND_SIMM8P0 :
1141
6
      print_normal (cd, info, fields->f_ivc2_8s0, 0|(1<<CGEN_OPERAND_SIGNED), pc, length);
1142
6
      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
180
    case MEP_OPERAND_TPR :
1159
180
      print_tpreg (cd, info, & mep_cgen_opval_h_gpr, 0, 0);
1160
180
      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
62
    case MEP_OPERAND_UDISP7 :
1165
62
      print_normal (cd, info, fields->f_7u9, 0, pc, length);
1166
62
      break;
1167
100
    case MEP_OPERAND_UDISP7A2 :
1168
100
      print_normal (cd, info, fields->f_7u9a2, 0, pc, length);
1169
100
      break;
1170
117
    case MEP_OPERAND_UDISP7A4 :
1171
117
      print_normal (cd, info, fields->f_7u9a4, 0, pc, length);
1172
117
      break;
1173
34
    case MEP_OPERAND_UIMM16 :
1174
34
      print_normal (cd, info, fields->f_16u16, 0, pc, length);
1175
34
      break;
1176
0
    case MEP_OPERAND_UIMM2 :
1177
0
      print_normal (cd, info, fields->f_2u10, 0, pc, length);
1178
0
      break;
1179
69
    case MEP_OPERAND_UIMM24 :
1180
69
      print_normal (cd, info, fields->f_24u8n, 0|(1<<CGEN_OPERAND_VIRTUAL), pc, length);
1181
69
      break;
1182
54
    case MEP_OPERAND_UIMM3 :
1183
54
      print_normal (cd, info, fields->f_3u5, 0, pc, length);
1184
54
      break;
1185
23
    case MEP_OPERAND_UIMM4 :
1186
23
      print_normal (cd, info, fields->f_4u8, 0, pc, length);
1187
23
      break;
1188
108
    case MEP_OPERAND_UIMM5 :
1189
108
      print_normal (cd, info, fields->f_5u8, 0, pc, length);
1190
108
      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.93k
  }
1205
4.93k
}
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
1.09k
{
1233
1.09k
  disassemble_info *info = (disassemble_info *) dis_info;
1234
1235
  /* Print the operand as directed by the attributes.  */
1236
1.09k
  if (CGEN_BOOL_ATTR (attrs, CGEN_OPERAND_SEM_ONLY))
1237
0
    ; /* nothing to do */
1238
1.09k
  else if (CGEN_BOOL_ATTR (attrs, CGEN_OPERAND_SIGNED))
1239
427
    (*info->fprintf_func) (info->stream, "%ld", value);
1240
665
  else
1241
665
    (*info->fprintf_func) (info->stream, "0x%lx", value);
1242
1.09k
}
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
255
{
1254
255
  disassemble_info *info = (disassemble_info *) dis_info;
1255
1256
  /* Print the operand as directed by the attributes.  */
1257
255
  if (CGEN_BOOL_ATTR (attrs, CGEN_OPERAND_SEM_ONLY))
1258
0
    ; /* Nothing to do.  */
1259
255
  else if (CGEN_BOOL_ATTR (attrs, CGEN_OPERAND_PCREL_ADDR))
1260
246
    (*info->print_address_func) (value, info);
1261
9
  else if (CGEN_BOOL_ATTR (attrs, CGEN_OPERAND_ABS_ADDR))
1262
9
    (*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
255
}
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
3.28k
{
1278
3.28k
  disassemble_info *info = (disassemble_info *) dis_info;
1279
3.28k
  const CGEN_KEYWORD_ENTRY *ke;
1280
1281
3.28k
  ke = cgen_keyword_lookup_value (keyword_table, value);
1282
3.28k
  if (ke != NULL)
1283
3.28k
    (*info->fprintf_func) (info->stream, "%s", ke->name);
1284
2
  else
1285
2
    (*info->fprintf_func) (info->stream, "???");
1286
3.28k
}
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.52k
{
1301
3.52k
  const CGEN_SYNTAX *syntax = CGEN_INSN_SYNTAX (insn);
1302
3.52k
  disassemble_info *info = (disassemble_info *) dis_info;
1303
3.52k
  const CGEN_SYNTAX_CHAR_TYPE *syn;
1304
1305
3.52k
  CGEN_INIT_PRINT (cd);
1306
1307
18.9k
  for (syn = CGEN_SYNTAX_STRING (syntax); *syn; ++syn)
1308
15.4k
    {
1309
15.4k
      if (CGEN_SYNTAX_MNEMONIC_P (*syn))
1310
3.52k
  {
1311
3.52k
    (*info->fprintf_func) (info->stream, "%s", CGEN_INSN_MNEMONIC (insn));
1312
3.52k
    continue;
1313
3.52k
  }
1314
11.9k
      if (CGEN_SYNTAX_CHAR_P (*syn))
1315
6.99k
  {
1316
6.99k
    (*info->fprintf_func) (info->stream, "%c", CGEN_SYNTAX_CHAR (*syn));
1317
6.99k
    continue;
1318
6.99k
  }
1319
1320
      /* We have an operand.  */
1321
4.93k
      mep_cgen_print_operand (cd, CGEN_SYNTAX_FIELD (*syn), info,
1322
4.93k
         fields, CGEN_INSN_ATTRS (insn), pc, length);
1323
4.93k
    }
1324
3.52k
}
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
60.5k
{
1368
60.5k
  CGEN_INSN_INT insn_value;
1369
60.5k
  const CGEN_INSN_LIST *insn_list;
1370
60.5k
  CGEN_EXTRACT_INFO ex_info;
1371
60.5k
  int basesize;
1372
1373
  /* Extract base part of instruction, just in case CGEN_DIS_* uses it. */
1374
60.5k
  basesize = cd->base_insn_bitsize < buflen * 8 ?
1375
60.2k
                                     cd->base_insn_bitsize : buflen * 8;
1376
60.5k
  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
60.5k
  ex_info.valid = (1 << buflen) - 1;
1383
60.5k
  ex_info.dis_info = info;
1384
60.5k
  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
60.5k
  insn_list = CGEN_DIS_LOOKUP_INSN (cd, (char *) buf, insn_value);
1390
54.7M
  while (insn_list != NULL)
1391
54.7M
    {
1392
54.7M
      const CGEN_INSN *insn = insn_list->insn;
1393
54.7M
      CGEN_FIELDS fields;
1394
54.7M
      int length;
1395
54.7M
      unsigned long insn_value_cropped;
1396
1397
54.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
54.7M
      if (! mep_cgen_insn_supported (cd, insn))
1401
54.2M
        {
1402
54.2M
          insn_list = CGEN_DIS_NEXT_INSN (insn_list);
1403
54.2M
    continue;
1404
54.2M
        }
1405
477k
#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
477k
      if ((unsigned) (CGEN_INSN_BITSIZE (insn) / 8) < buflen &&
1414
235k
    (unsigned) (CGEN_INSN_BITSIZE (insn) / 8) <= sizeof (unsigned long))
1415
235k
  insn_value_cropped = bfd_get_bits (buf, CGEN_INSN_BITSIZE (insn),
1416
235k
             info->endian == BFD_ENDIAN_BIG);
1417
241k
      else
1418
241k
  insn_value_cropped = insn_value;
1419
1420
477k
      if ((insn_value_cropped & CGEN_INSN_BASE_MASK (insn))
1421
477k
    == CGEN_INSN_BASE_VALUE (insn))
1422
3.52k
  {
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.52k
    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.52k
    else
1442
3.52k
      length = CGEN_EXTRACT_FN (cd, insn)
1443
3.52k
        (cd, insn, &ex_info, insn_value_cropped, &fields, pc);
1444
1445
    /* Length < 0 -> error.  */
1446
3.52k
    if (length < 0)
1447
0
      return length;
1448
3.52k
    if (length > 0)
1449
3.52k
      {
1450
3.52k
        CGEN_PRINT_FN (cd, insn) (cd, info, insn, &fields, pc, length);
1451
        /* Length is in bits, result is in bytes.  */
1452
3.52k
        return length / 8;
1453
3.52k
      }
1454
3.52k
  }
1455
1456
474k
      insn_list = CGEN_DIS_NEXT_INSN (insn_list);
1457
474k
    }
1458
1459
56.9k
  return 0;
1460
60.5k
}
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
60.0k
{
1473
60.0k
  bfd_byte buf[CGEN_MAX_INSN_SIZE];
1474
60.0k
  int buflen;
1475
60.0k
  int status;
1476
1477
  /* Attempt to read the base part of the insn.  */
1478
60.0k
  buflen = cd->base_insn_bitsize / 8;
1479
60.0k
  status = (*info->read_memory_func) (pc, buf, buflen, info);
1480
1481
  /* Try again with the minimum part, if min < base.  */
1482
60.0k
  if (status != 0 && (cd->min_insn_bitsize < cd->base_insn_bitsize))
1483
253
    {
1484
253
      buflen = cd->min_insn_bitsize / 8;
1485
253
      status = (*info->read_memory_func) (pc, buf, buflen, info);
1486
253
    }
1487
1488
60.0k
  if (status != 0)
1489
74
    {
1490
74
      (*info->memory_error_func) (status, pc, info);
1491
74
      return -1;
1492
74
    }
1493
1494
59.9k
  return print_insn (cd, pc, info, buf, buflen);
1495
60.0k
}
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
60.3k
{
1514
60.3k
  static cpu_desc_list *cd_list = 0;
1515
60.3k
  cpu_desc_list *cl = 0;
1516
60.3k
  static CGEN_CPU_DESC cd = 0;
1517
60.3k
  static CGEN_BITSET *prev_isa;
1518
60.3k
  static int prev_mach;
1519
60.3k
  static int prev_endian;
1520
60.3k
  static int prev_insn_endian;
1521
60.3k
  int length;
1522
60.3k
  CGEN_BITSET *isa;
1523
60.3k
  int mach;
1524
60.3k
  int endian = (info->endian == BFD_ENDIAN_BIG
1525
60.3k
    ? CGEN_ENDIAN_BIG
1526
60.3k
    : CGEN_ENDIAN_LITTLE);
1527
60.3k
  int insn_endian = (info->endian_code == BFD_ENDIAN_BIG
1528
60.3k
                     ? CGEN_ENDIAN_BIG
1529
60.3k
                     : CGEN_ENDIAN_LITTLE);
1530
60.3k
  enum bfd_architecture arch;
1531
1532
  /* ??? gdb will set mach but leave the architecture as "unknown" */
1533
60.3k
#ifndef CGEN_BFD_ARCH
1534
60.3k
#define CGEN_BFD_ARCH bfd_arch_mep
1535
60.3k
#endif
1536
60.3k
  arch = info->arch;
1537
60.3k
  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
60.3k
  mach = info->mach;
1546
60.3k
#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
60.3k
  isa = info->private_data;
1560
60.3k
#endif
1561
1562
  /* If we've switched cpu's, try to find a handle we've used before */
1563
60.3k
  if (cd
1564
60.3k
      && (cgen_bitset_compare (isa, prev_isa) != 0
1565
60.3k
    || mach != prev_mach
1566
13.2k
    || endian != prev_endian))
1567
47.0k
    {
1568
47.0k
      cd = 0;
1569
170k
      for (cl = cd_list; cl; cl = cl->next)
1570
170k
  {
1571
170k
    if (cgen_bitset_compare (cl->isa, isa) == 0 &&
1572
170k
        cl->mach == mach &&
1573
47.0k
        cl->endian == endian)
1574
47.0k
      {
1575
47.0k
        cd = cl->cd;
1576
47.0k
        prev_isa = cd->isas;
1577
47.0k
        break;
1578
47.0k
      }
1579
170k
  }
1580
47.0k
    }
1581
1582
  /* If we haven't initialized yet, initialize the opcode table.  */
1583
60.3k
  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
60.3k
  length = CGEN_PRINT_INSN (cd, pc, info);
1622
60.3k
  if (length > 0)
1623
3.48k
    return length;
1624
56.8k
  if (length < 0)
1625
75
    return -1;
1626
1627
56.7k
  (*info->fprintf_func) (info->stream, UNKNOWN_INSN_MSG);
1628
56.7k
  return cd->default_insn_bitsize / 8;
1629
56.8k
}