Coverage Report

Created: 2026-07-12 09:22

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.7k
#define UNKNOWN_INSN_MSG _("*unknown*")
42
43
static void print_normal
44
  (CGEN_CPU_DESC, void *, long, unsigned int, bfd_vma, int);
45
static void print_address
46
  (CGEN_CPU_DESC, void *, bfd_vma, unsigned int, bfd_vma, int) ATTRIBUTE_UNUSED;
47
static void print_keyword
48
  (CGEN_CPU_DESC, void *, CGEN_KEYWORD *, long, unsigned int) ATTRIBUTE_UNUSED;
49
static void print_insn_normal
50
  (CGEN_CPU_DESC, void *, const CGEN_INSN *, CGEN_FIELDS *, bfd_vma, int);
51
static int print_insn
52
  (CGEN_CPU_DESC, bfd_vma,  disassemble_info *, bfd_byte *, unsigned);
53
static int default_print_insn
54
  (CGEN_CPU_DESC, bfd_vma, disassemble_info *) ATTRIBUTE_UNUSED;
55
static int read_insn
56
  (CGEN_CPU_DESC, bfd_vma, disassemble_info *, bfd_byte *, int, CGEN_EXTRACT_INFO *,
57
   unsigned long *);
58

59
/* -- disassembler routines inserted here.  */
60
61
/* -- dis.c */
62
63
#include "elf/mep.h"
64
#include "elf-bfd.h"
65
66
#define CGEN_VALIDATE_INSN_SUPPORTED
67
68
static void
69
print_tpreg (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED, void *dis_info,
70
       CGEN_KEYWORD *table ATTRIBUTE_UNUSED, long val ATTRIBUTE_UNUSED,
71
       unsigned int flags ATTRIBUTE_UNUSED)
72
0
{
73
0
  disassemble_info *info = (disassemble_info *) dis_info;
74
75
0
  (*info->fprintf_func) (info->stream, "$tp");
76
0
}
77
78
static void
79
print_spreg (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED, void *dis_info,
80
       CGEN_KEYWORD *table ATTRIBUTE_UNUSED, long val ATTRIBUTE_UNUSED,
81
       unsigned int flags ATTRIBUTE_UNUSED)
82
0
{
83
0
  disassemble_info *info = (disassemble_info *) dis_info;
84
85
0
  (*info->fprintf_func) (info->stream, "$sp");
86
0
}
87
88
/* begin-cop-ip-print-handlers */
89
static void
90
print_ivc2_cr (CGEN_CPU_DESC,
91
  void *,
92
  CGEN_KEYWORD *,
93
  long,
94
  unsigned int) ATTRIBUTE_UNUSED;
95
static void
96
print_ivc2_cr (CGEN_CPU_DESC cd,
97
  void *dis_info,
98
  CGEN_KEYWORD *keyword_table ATTRIBUTE_UNUSED,
99
  long value,
100
  unsigned int attrs)
101
0
{
102
0
  print_keyword (cd, dis_info, & mep_cgen_opval_h_cr_ivc2, value, attrs);
103
0
}
104
static void
105
print_ivc2_ccr (CGEN_CPU_DESC,
106
  void *,
107
  CGEN_KEYWORD *,
108
  long,
109
  unsigned int) ATTRIBUTE_UNUSED;
110
static void
111
print_ivc2_ccr (CGEN_CPU_DESC cd,
112
  void *dis_info,
113
  CGEN_KEYWORD *keyword_table ATTRIBUTE_UNUSED,
114
  long value,
115
  unsigned int attrs)
116
0
{
117
0
  print_keyword (cd, dis_info, & mep_cgen_opval_h_ccr_ivc2, value, attrs);
118
0
}
119
/* end-cop-ip-print-handlers */
120
121
/************************************************************\
122
*********************** Experimental *************************
123
\************************************************************/
124
125
#undef  CGEN_PRINT_INSN
126
41.7k
#define CGEN_PRINT_INSN mep_print_insn
127
128
static int
129
mep_print_vliw_insns (CGEN_CPU_DESC cd, bfd_vma pc, disassemble_info *info,
130
          bfd_byte *buf, int corelength, int copro1length,
131
          int copro2length ATTRIBUTE_UNUSED)
132
0
{
133
0
  int i;
134
0
  int status = 0;
135
0
  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
0
  if (corelength > 0)
141
0
    {
142
0
      int my_status = 0;
143
144
0
      for (i = 0; i < corelength; i++ )
145
0
  insnbuf[i] = buf[i];
146
0
      cd->isas = & MEP_CORE_ISA;
147
148
0
      my_status = print_insn (cd, pc, info, insnbuf, corelength);
149
0
      if (my_status != corelength)
150
0
  {
151
0
    (*info->fprintf_func) (info->stream, UNKNOWN_INSN_MSG);
152
0
    my_status = corelength;
153
0
  }
154
0
      status += my_status;
155
156
      /* Print the + to indicate that the following copro insn is
157
   part of a vliw group.  */
158
0
      if (copro1length > 0)
159
0
  (*info->fprintf_func) (info->stream, " + ");
160
0
    }
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
0
  if (copro1length > 0)
169
0
    {
170
0
      int my_status = 0;
171
172
0
      for (i = corelength; i < corelength + copro1length; i++ )
173
0
  insnbuf[i - corelength] = buf[i];
174
175
0
      switch (copro1length)
176
0
  {
177
0
  case 0:
178
0
    break;
179
0
  case 2:
180
0
    cd->isas = & MEP_COP16_ISA;
181
0
    break;
182
0
  case 4:
183
0
    cd->isas = & MEP_COP32_ISA;
184
0
    break;
185
0
  case 6:
186
0
    cd->isas = & MEP_COP48_ISA;
187
0
    break;
188
0
  case 8:
189
0
    cd->isas = & MEP_COP64_ISA;
190
0
    break;
191
0
  default:
192
    /* Shouldn't be anything but 16,32,48,64.  */
193
0
    break;
194
0
  }
195
196
0
      my_status = print_insn (cd, pc, info, insnbuf, copro1length);
197
198
0
      if (my_status != copro1length)
199
0
  {
200
0
    (*info->fprintf_func) (info->stream, UNKNOWN_INSN_MSG);
201
0
    my_status = copro1length;
202
0
  }
203
0
      status += my_status;
204
0
    }
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
0
  if ((!MEP_VLIW64 && (status != 4)) || (MEP_VLIW64 && (status != 8)))
259
0
    return -1;
260
0
  else
261
0
    return status;
262
0
}
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
0
{
367
0
  int status;
368
0
  int buflength;
369
0
  int corebuflength;
370
0
  int cop1buflength;
371
0
  int cop2buflength;
372
0
  bfd_byte buf[8];
373
0
  char indicator16[1];
374
0
  char indicator64[4];
375
376
  /* At this time we're not supporting internally parallel
377
     coprocessors, so cop2buflength will always be 0.  */
378
0
  cop2buflength = 0;
379
380
  /* Read in 64 bits.  */
381
0
  buflength = sizeof (buf);
382
0
  status = (*info->read_memory_func) (pc, buf, buflength, info);
383
384
0
  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
0
  if (info->endian == BFD_ENDIAN_BIG)
403
0
    {
404
0
      indicator16[0] = buf[0];
405
0
      indicator64[0] = buf[0];
406
0
      indicator64[1] = buf[1];
407
0
      indicator64[2] = buf[2];
408
0
      indicator64[3] = buf[3];
409
0
    }
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
0
  if ((indicator16[0] & 0x80) && (indicator16[0] & 0x40))
423
0
    {
424
0
      if ((indicator64[0] & 0xf0) == 0xf0 && (indicator64[1] & 0x07) == 0x07
425
0
    && ((indicator64[2] & 0xfe) != 0xf0 || (indicator64[3] & 0xf4) != 0))
426
0
  {
427
    /* We have a 64 bit copro insn.  */
428
0
    corebuflength = 0;
429
    /* All 8 bytes are one copro insn.  */
430
0
    cop1buflength = 8;
431
0
  }
432
0
      else
433
0
  {
434
    /* We have a 32 bit core insn and a 32 bit copro insn.  */
435
0
    corebuflength = 4;
436
0
    cop1buflength = 4;
437
0
  }
438
0
    }
439
0
  else
440
0
    {
441
      /* We have a 16 bit core insn and a 48 bit copro insn.  */
442
0
      corebuflength = 2;
443
0
      cop1buflength = 6;
444
0
    }
445
446
  /* Now we have the distrubution set.  Print them out. */
447
0
  status = mep_print_vliw_insns (cd, pc, info, buf, corebuflength,
448
0
         cop1buflength, cop2buflength);
449
450
0
  return status;
451
0
}
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
41.7k
{
629
41.7k
  int status;
630
41.7k
  int cop_type;
631
41.7k
  int ivc2 = 0;
632
41.7k
  static CGEN_ATTR_VALUE_BITSET_TYPE *ivc2_core_isa = NULL;
633
634
41.7k
  if (ivc2_core_isa == NULL)
635
2
    {
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
2
      ivc2_core_isa = cgen_bitset_create (MAX_ISAS);
640
2
    }
641
642
  /* Extract and adapt to configuration number, if available. */
643
41.7k
  if (info->section && info->section->owner)
644
0
    {
645
0
      bfd *abfd = info->section->owner;
646
0
      if (bfd_get_flavour (abfd) == bfd_target_elf_flavour)
647
0
  {
648
0
    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
0
    int i;
655
0
    for (i = 0; i <= mep_config_index; i++)
656
0
      if (mep_config_map[i].name == NULL)
657
0
        break;
658
659
0
    if (i < mep_config_index)
660
0
      {
661
0
        opcodes_error_handler (_("illegal MEP INDEX setting '%x' in ELF header e_flags field"), mep_config_index);
662
0
        mep_config_index = 0;
663
0
      }
664
665
0
    cop_type = abfd->tdata.elf_obj_data->elf_header->e_flags & EF_MEP_COP_MASK;
666
0
    if (cop_type == EF_MEP_COP_IVC2)
667
0
      ivc2 = 1;
668
0
  }
669
0
    }
670
671
  /* Picking the right ISA bitmask for the current context is tricky.  */
672
41.7k
  if (info->section)
673
0
    {
674
0
      if (info->section->flags & SEC_MEP_VLIW)
675
0
  {
676
0
#ifdef MEP_IVC2_SUPPORTED
677
0
    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
0
    else
684
0
#endif
685
      /* Are we in 32 or 64 bit vliw mode?  */
686
0
      if (MEP_VLIW64)
687
0
        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
0
  }
692
0
      else
693
0
  {
694
0
    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
0
    else
702
0
      cd->isas = & MEP_CORE_ISA;
703
0
    status = default_print_insn (cd, pc, info);
704
0
  }
705
0
    }
706
41.7k
  else /* sid or gdb */
707
41.7k
    {
708
41.7k
#ifdef MEP_IVC2_SUPPORTED
709
41.7k
      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.7k
#endif
724
725
41.7k
      status = default_print_insn (cd, pc, info);
726
41.7k
    }
727
728
41.7k
  return status;
729
41.7k
}
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
0
{
761
0
  disassemble_info *info = (disassemble_info *) xinfo;
762
763
0
  switch (opindex)
764
0
    {
765
0
    case MEP_OPERAND_ADDR24A4 :
766
0
      print_normal (cd, info, fields->f_24u8a4n, 0|(1<<CGEN_OPERAND_VIRTUAL), pc, length);
767
0
      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
0
    case MEP_OPERAND_CDISP10A4 :
790
0
      print_normal (cd, info, fields->f_cdisp10, 0|(1<<CGEN_OPERAND_SIGNED), pc, length);
791
0
      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
0
    case MEP_OPERAND_CIMM4 :
799
0
      print_normal (cd, info, fields->f_rn, 0, pc, length);
800
0
      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
0
    case MEP_OPERAND_CRN :
814
0
      print_keyword (cd, info, & mep_cgen_opval_h_cr, fields->f_crn, 0);
815
0
      break;
816
0
    case MEP_OPERAND_CRN64 :
817
0
      print_keyword (cd, info, & mep_cgen_opval_h_cr64, fields->f_crn, 0);
818
0
      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
0
    case MEP_OPERAND_CROP :
829
0
      print_keyword (cd, info, & mep_cgen_opval_h_cr64, fields->f_ivc2_5u23, 0);
830
0
      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
0
    case MEP_OPERAND_CRPP :
835
0
      print_keyword (cd, info, & mep_cgen_opval_h_cr64, fields->f_ivc2_5u18, 0);
836
0
      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
0
    case MEP_OPERAND_CRQP :
841
0
      print_keyword (cd, info, & mep_cgen_opval_h_cr64, fields->f_ivc2_5u13, 0);
842
0
      break;
843
0
    case MEP_OPERAND_CSRN :
844
0
      print_keyword (cd, info, & mep_cgen_opval_h_csr, fields->f_csrn, 0|(1<<CGEN_OPERAND_VIRTUAL));
845
0
      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
0
    case MEP_OPERAND_IMM3P5 :
877
0
      print_normal (cd, info, fields->f_ivc2_3u5, 0, pc, length);
878
0
      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
0
    case MEP_OPERAND_PCABS24A2 :
1045
0
      print_address (cd, info, fields->f_24u5a2n, 0|(1<<CGEN_OPERAND_ABS_ADDR)|(1<<CGEN_OPERAND_VIRTUAL), pc, length);
1046
0
      break;
1047
0
    case MEP_OPERAND_PCREL12A2 :
1048
0
      print_address (cd, info, fields->f_12s4a2, 0|(1<<CGEN_OPERAND_SIGNED)|(1<<CGEN_OPERAND_RELAX)|(1<<CGEN_OPERAND_PCREL_ADDR), pc, length);
1049
0
      break;
1050
0
    case MEP_OPERAND_PCREL17A2 :
1051
0
      print_address (cd, info, fields->f_17s16a2, 0|(1<<CGEN_OPERAND_SIGNED)|(1<<CGEN_OPERAND_RELAX)|(1<<CGEN_OPERAND_PCREL_ADDR), pc, length);
1052
0
      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
0
    case MEP_OPERAND_PCREL8A2 :
1057
0
      print_address (cd, info, fields->f_8s8a2, 0|(1<<CGEN_OPERAND_SIGNED)|(1<<CGEN_OPERAND_RELAX)|(1<<CGEN_OPERAND_PCREL_ADDR), pc, length);
1058
0
      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
0
    case MEP_OPERAND_RL :
1069
0
      print_keyword (cd, info, & mep_cgen_opval_h_gpr, fields->f_rl, 0);
1070
0
      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
0
    case MEP_OPERAND_RM :
1075
0
      print_keyword (cd, info, & mep_cgen_opval_h_gpr, fields->f_rm, 0);
1076
0
      break;
1077
0
    case MEP_OPERAND_RMA :
1078
0
      print_keyword (cd, info, & mep_cgen_opval_h_gpr, fields->f_rm, 0);
1079
0
      break;
1080
0
    case MEP_OPERAND_RN :
1081
0
      print_keyword (cd, info, & mep_cgen_opval_h_gpr, fields->f_rn, 0);
1082
0
      break;
1083
0
    case MEP_OPERAND_RN3 :
1084
0
      print_keyword (cd, info, & mep_cgen_opval_h_gpr, fields->f_rn3, 0);
1085
0
      break;
1086
0
    case MEP_OPERAND_RN3C :
1087
0
      print_keyword (cd, info, & mep_cgen_opval_h_gpr, fields->f_rn3, 0);
1088
0
      break;
1089
0
    case MEP_OPERAND_RN3L :
1090
0
      print_keyword (cd, info, & mep_cgen_opval_h_gpr, fields->f_rn3, 0);
1091
0
      break;
1092
0
    case MEP_OPERAND_RN3S :
1093
0
      print_keyword (cd, info, & mep_cgen_opval_h_gpr, fields->f_rn3, 0);
1094
0
      break;
1095
0
    case MEP_OPERAND_RN3UC :
1096
0
      print_keyword (cd, info, & mep_cgen_opval_h_gpr, fields->f_rn3, 0);
1097
0
      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
0
    case MEP_OPERAND_RN3US :
1102
0
      print_keyword (cd, info, & mep_cgen_opval_h_gpr, fields->f_rn3, 0);
1103
0
      break;
1104
0
    case MEP_OPERAND_RNC :
1105
0
      print_keyword (cd, info, & mep_cgen_opval_h_gpr, fields->f_rn, 0);
1106
0
      break;
1107
0
    case MEP_OPERAND_RNL :
1108
0
      print_keyword (cd, info, & mep_cgen_opval_h_gpr, fields->f_rn, 0);
1109
0
      break;
1110
0
    case MEP_OPERAND_RNS :
1111
0
      print_keyword (cd, info, & mep_cgen_opval_h_gpr, fields->f_rn, 0);
1112
0
      break;
1113
0
    case MEP_OPERAND_RNUC :
1114
0
      print_keyword (cd, info, & mep_cgen_opval_h_gpr, fields->f_rn, 0);
1115
0
      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
0
    case MEP_OPERAND_RNUS :
1120
0
      print_keyword (cd, info, & mep_cgen_opval_h_gpr, fields->f_rn, 0);
1121
0
      break;
1122
0
    case MEP_OPERAND_SAR :
1123
0
      print_keyword (cd, info, & mep_cgen_opval_h_csr, 0, 0);
1124
0
      break;
1125
0
    case MEP_OPERAND_SDISP16 :
1126
0
      print_normal (cd, info, fields->f_16s16, 0|(1<<CGEN_OPERAND_SIGNED), pc, length);
1127
0
      break;
1128
0
    case MEP_OPERAND_SIMM16 :
1129
0
      print_normal (cd, info, fields->f_16s16, 0|(1<<CGEN_OPERAND_SIGNED), pc, length);
1130
0
      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
0
    case MEP_OPERAND_SIMM6 :
1135
0
      print_normal (cd, info, fields->f_6s8, 0|(1<<CGEN_OPERAND_SIGNED), pc, length);
1136
0
      break;
1137
0
    case MEP_OPERAND_SIMM8 :
1138
0
      print_normal (cd, info, fields->f_8s8, 0|(1<<CGEN_OPERAND_SIGNED)|(1<<CGEN_OPERAND_RELOC_IMPLIES_OVERFLOW), pc, length);
1139
0
      break;
1140
0
    case MEP_OPERAND_SIMM8P0 :
1141
0
      print_normal (cd, info, fields->f_ivc2_8s0, 0|(1<<CGEN_OPERAND_SIGNED), pc, length);
1142
0
      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
0
    case MEP_OPERAND_SPR :
1153
0
      print_spreg (cd, info, & mep_cgen_opval_h_gpr, 0, 0);
1154
0
      break;
1155
0
    case MEP_OPERAND_TP :
1156
0
      print_keyword (cd, info, & mep_cgen_opval_h_gpr, 0, 0);
1157
0
      break;
1158
0
    case MEP_OPERAND_TPR :
1159
0
      print_tpreg (cd, info, & mep_cgen_opval_h_gpr, 0, 0);
1160
0
      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
0
    case MEP_OPERAND_UDISP7 :
1165
0
      print_normal (cd, info, fields->f_7u9, 0, pc, length);
1166
0
      break;
1167
0
    case MEP_OPERAND_UDISP7A2 :
1168
0
      print_normal (cd, info, fields->f_7u9a2, 0, pc, length);
1169
0
      break;
1170
0
    case MEP_OPERAND_UDISP7A4 :
1171
0
      print_normal (cd, info, fields->f_7u9a4, 0, pc, length);
1172
0
      break;
1173
0
    case MEP_OPERAND_UIMM16 :
1174
0
      print_normal (cd, info, fields->f_16u16, 0, pc, length);
1175
0
      break;
1176
0
    case MEP_OPERAND_UIMM2 :
1177
0
      print_normal (cd, info, fields->f_2u10, 0, pc, length);
1178
0
      break;
1179
0
    case MEP_OPERAND_UIMM24 :
1180
0
      print_normal (cd, info, fields->f_24u8n, 0|(1<<CGEN_OPERAND_VIRTUAL), pc, length);
1181
0
      break;
1182
0
    case MEP_OPERAND_UIMM3 :
1183
0
      print_normal (cd, info, fields->f_3u5, 0, pc, length);
1184
0
      break;
1185
0
    case MEP_OPERAND_UIMM4 :
1186
0
      print_normal (cd, info, fields->f_4u8, 0, pc, length);
1187
0
      break;
1188
0
    case MEP_OPERAND_UIMM5 :
1189
0
      print_normal (cd, info, fields->f_5u8, 0, pc, length);
1190
0
      break;
1191
0
    case MEP_OPERAND_UIMM7A4 :
1192
0
      print_normal (cd, info, fields->f_7u9a4, 0, pc, length);
1193
0
      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
0
  }
1205
0
}
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
0
{
1233
0
  disassemble_info *info = (disassemble_info *) dis_info;
1234
1235
  /* Print the operand as directed by the attributes.  */
1236
0
  if (CGEN_BOOL_ATTR (attrs, CGEN_OPERAND_SEM_ONLY))
1237
0
    ; /* nothing to do */
1238
0
  else if (CGEN_BOOL_ATTR (attrs, CGEN_OPERAND_SIGNED))
1239
0
    (*info->fprintf_func) (info->stream, "%ld", value);
1240
0
  else
1241
0
    (*info->fprintf_func) (info->stream, "0x%lx", value);
1242
0
}
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
0
{
1254
0
  disassemble_info *info = (disassemble_info *) dis_info;
1255
1256
  /* Print the operand as directed by the attributes.  */
1257
0
  if (CGEN_BOOL_ATTR (attrs, CGEN_OPERAND_SEM_ONLY))
1258
0
    ; /* Nothing to do.  */
1259
0
  else if (CGEN_BOOL_ATTR (attrs, CGEN_OPERAND_PCREL_ADDR))
1260
0
    (*info->print_address_func) (value, info);
1261
0
  else if (CGEN_BOOL_ATTR (attrs, CGEN_OPERAND_ABS_ADDR))
1262
0
    (*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
0
}
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
0
{
1278
0
  disassemble_info *info = (disassemble_info *) dis_info;
1279
0
  const CGEN_KEYWORD_ENTRY *ke;
1280
1281
0
  ke = cgen_keyword_lookup_value (keyword_table, value);
1282
0
  if (ke != NULL)
1283
0
    (*info->fprintf_func) (info->stream, "%s", ke->name);
1284
0
  else
1285
0
    (*info->fprintf_func) (info->stream, "???");
1286
0
}
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
0
{
1301
0
  const CGEN_SYNTAX *syntax = CGEN_INSN_SYNTAX (insn);
1302
0
  disassemble_info *info = (disassemble_info *) dis_info;
1303
0
  const CGEN_SYNTAX_CHAR_TYPE *syn;
1304
1305
0
  CGEN_INIT_PRINT (cd);
1306
1307
0
  for (syn = CGEN_SYNTAX_STRING (syntax); *syn; ++syn)
1308
0
    {
1309
0
      if (CGEN_SYNTAX_MNEMONIC_P (*syn))
1310
0
  {
1311
0
    (*info->fprintf_func) (info->stream, "%s", CGEN_INSN_MNEMONIC (insn));
1312
0
    continue;
1313
0
  }
1314
0
      if (CGEN_SYNTAX_CHAR_P (*syn))
1315
0
  {
1316
0
    (*info->fprintf_func) (info->stream, "%c", CGEN_SYNTAX_CHAR (*syn));
1317
0
    continue;
1318
0
  }
1319
1320
      /* We have an operand.  */
1321
0
      mep_cgen_print_operand (cd, CGEN_SYNTAX_FIELD (*syn), info,
1322
0
         fields, CGEN_INSN_ATTRS (insn), pc, length);
1323
0
    }
1324
0
}
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
41.7k
{
1368
41.7k
  CGEN_INSN_INT insn_value;
1369
41.7k
  const CGEN_INSN_LIST *insn_list;
1370
41.7k
  CGEN_EXTRACT_INFO ex_info;
1371
41.7k
  int basesize;
1372
1373
  /* Extract base part of instruction, just in case CGEN_DIS_* uses it. */
1374
41.7k
  basesize = cd->base_insn_bitsize < buflen * 8 ?
1375
41.7k
                                     cd->base_insn_bitsize : buflen * 8;
1376
41.7k
  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
41.7k
  ex_info.valid = (1 << buflen) - 1;
1383
41.7k
  ex_info.dis_info = info;
1384
41.7k
  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
41.7k
  insn_list = CGEN_DIS_LOOKUP_INSN (cd, (char *) buf, insn_value);
1390
38.0M
  while (insn_list != NULL)
1391
38.0M
    {
1392
38.0M
      const CGEN_INSN *insn = insn_list->insn;
1393
38.0M
      CGEN_FIELDS fields;
1394
38.0M
      int length;
1395
38.0M
      unsigned long insn_value_cropped;
1396
1397
38.0M
#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
38.0M
      if (! mep_cgen_insn_supported (cd, insn))
1401
38.0M
        {
1402
38.0M
          insn_list = CGEN_DIS_NEXT_INSN (insn_list);
1403
38.0M
    continue;
1404
38.0M
        }
1405
0
#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
0
      if ((unsigned) (CGEN_INSN_BITSIZE (insn) / 8) < buflen &&
1414
0
    (unsigned) (CGEN_INSN_BITSIZE (insn) / 8) <= sizeof (unsigned long))
1415
0
  insn_value_cropped = bfd_get_bits (buf, CGEN_INSN_BITSIZE (insn),
1416
0
             info->endian == BFD_ENDIAN_BIG);
1417
0
      else
1418
0
  insn_value_cropped = insn_value;
1419
1420
0
      if ((insn_value_cropped & CGEN_INSN_BASE_MASK (insn))
1421
0
    == CGEN_INSN_BASE_VALUE (insn))
1422
0
  {
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
0
    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
0
    else
1442
0
      length = CGEN_EXTRACT_FN (cd, insn)
1443
0
        (cd, insn, &ex_info, insn_value_cropped, &fields, pc);
1444
1445
    /* Length < 0 -> error.  */
1446
0
    if (length < 0)
1447
0
      return length;
1448
0
    if (length > 0)
1449
0
      {
1450
0
        CGEN_PRINT_FN (cd, insn) (cd, info, insn, &fields, pc, length);
1451
        /* Length is in bits, result is in bytes.  */
1452
0
        return length / 8;
1453
0
      }
1454
0
  }
1455
1456
0
      insn_list = CGEN_DIS_NEXT_INSN (insn_list);
1457
0
    }
1458
1459
41.7k
  return 0;
1460
41.7k
}
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
41.7k
{
1473
41.7k
  bfd_byte buf[CGEN_MAX_INSN_SIZE];
1474
41.7k
  int buflen;
1475
41.7k
  int status;
1476
1477
  /* Attempt to read the base part of the insn.  */
1478
41.7k
  buflen = cd->base_insn_bitsize / 8;
1479
41.7k
  status = (*info->read_memory_func) (pc, buf, buflen, info);
1480
1481
  /* Try again with the minimum part, if min < base.  */
1482
41.7k
  if (status != 0 && (cd->min_insn_bitsize < cd->base_insn_bitsize))
1483
184
    {
1484
184
      buflen = cd->min_insn_bitsize / 8;
1485
184
      status = (*info->read_memory_func) (pc, buf, buflen, info);
1486
184
    }
1487
1488
41.7k
  if (status != 0)
1489
71
    {
1490
71
      (*info->memory_error_func) (status, pc, info);
1491
71
      return -1;
1492
71
    }
1493
1494
41.7k
  return print_insn (cd, pc, info, buf, buflen);
1495
41.7k
}
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
41.7k
{
1514
41.7k
  static cpu_desc_list *cd_list = 0;
1515
41.7k
  cpu_desc_list *cl = 0;
1516
41.7k
  static CGEN_CPU_DESC cd = 0;
1517
41.7k
  static CGEN_BITSET *prev_isa;
1518
41.7k
  static int prev_mach;
1519
41.7k
  static int prev_endian;
1520
41.7k
  static int prev_insn_endian;
1521
41.7k
  int length;
1522
41.7k
  CGEN_BITSET *isa;
1523
41.7k
  int mach;
1524
41.7k
  int endian = (info->endian == BFD_ENDIAN_BIG
1525
41.7k
    ? CGEN_ENDIAN_BIG
1526
41.7k
    : CGEN_ENDIAN_LITTLE);
1527
41.7k
  int insn_endian = (info->endian_code == BFD_ENDIAN_BIG
1528
41.7k
                     ? CGEN_ENDIAN_BIG
1529
41.7k
                     : CGEN_ENDIAN_LITTLE);
1530
41.7k
  enum bfd_architecture arch;
1531
1532
  /* ??? gdb will set mach but leave the architecture as "unknown" */
1533
41.7k
#ifndef CGEN_BFD_ARCH
1534
41.7k
#define CGEN_BFD_ARCH bfd_arch_mep
1535
41.7k
#endif
1536
41.7k
  arch = info->arch;
1537
41.7k
  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
41.7k
  mach = info->mach;
1546
41.7k
#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
41.7k
  isa = info->private_data;
1560
41.7k
#endif
1561
1562
  /* If we've switched cpu's, try to find a handle we've used before */
1563
41.7k
  if (cd
1564
41.7k
      && (cgen_bitset_compare (isa, prev_isa) != 0
1565
41.7k
    || mach != prev_mach
1566
3.24k
    || endian != prev_endian))
1567
38.5k
    {
1568
38.5k
      cd = 0;
1569
115k
      for (cl = cd_list; cl; cl = cl->next)
1570
115k
  {
1571
115k
    if (cgen_bitset_compare (cl->isa, isa) == 0 &&
1572
115k
        cl->mach == mach &&
1573
38.5k
        cl->endian == endian)
1574
38.5k
      {
1575
38.5k
        cd = cl->cd;
1576
38.5k
        prev_isa = cd->isas;
1577
38.5k
        break;
1578
38.5k
      }
1579
115k
  }
1580
38.5k
    }
1581
1582
  /* If we haven't initialized yet, initialize the opcode table.  */
1583
41.7k
  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
41.7k
  length = CGEN_PRINT_INSN (cd, pc, info);
1622
41.7k
  if (length > 0)
1623
0
    return length;
1624
41.7k
  if (length < 0)
1625
71
    return -1;
1626
1627
41.7k
  (*info->fprintf_func) (info->stream, UNKNOWN_INSN_MSG);
1628
41.7k
  return cd->default_insn_bitsize / 8;
1629
41.7k
}