OpenCores
URL https://opencores.org/ocsvn/openrisc_me/openrisc_me/trunk

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [gnu-src/] [binutils-2.18.50/] [opcodes/] [mep-dis.c] - Blame information for rev 156

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 38 julius
/* Disassembler interface for targets using CGEN. -*- C -*-
2
   CGEN: Cpu tools GENerator
3
 
4
   THIS FILE IS MACHINE GENERATED WITH CGEN.
5
   - the resultant file is machine generated, cgen-dis.in isn't
6
 
7
   Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2005, 2007
8
   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 "dis-asm.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
#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 print_tpreg (CGEN_CPU_DESC, PTR, CGEN_KEYWORD *, long, unsigned int);
69
static void print_spreg (CGEN_CPU_DESC, PTR, CGEN_KEYWORD *, long, unsigned int);
70
 
71
static void
72
print_tpreg (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED, PTR dis_info,
73
             CGEN_KEYWORD *table ATTRIBUTE_UNUSED, long val ATTRIBUTE_UNUSED,
74
             unsigned int flags ATTRIBUTE_UNUSED)
75
{
76
  disassemble_info *info = (disassemble_info *) dis_info;
77
 
78
  (*info->fprintf_func) (info->stream, "$tp");
79
}
80
 
81
static void
82
print_spreg (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED, PTR dis_info,
83
             CGEN_KEYWORD *table ATTRIBUTE_UNUSED, long val ATTRIBUTE_UNUSED,
84
             unsigned int flags ATTRIBUTE_UNUSED)
85
{
86
  disassemble_info *info = (disassemble_info *) dis_info;
87
 
88
  (*info->fprintf_func) (info->stream, "$sp");
89
}
90
 
91
/* begin-cop-ip-print-handlers */
92
static void
93
print_fmax_cr (CGEN_CPU_DESC cd,
94
        void *dis_info,
95
        CGEN_KEYWORD *keyword_table ATTRIBUTE_UNUSED,
96
        long value,
97
        unsigned int attrs)
98
{
99
  print_keyword (cd, dis_info, & mep_cgen_opval_h_cr_fmax, value, attrs);
100
}
101
static void
102
print_fmax_ccr (CGEN_CPU_DESC cd,
103
        void *dis_info,
104
        CGEN_KEYWORD *keyword_table ATTRIBUTE_UNUSED,
105
        long value,
106
        unsigned int attrs)
107
{
108
  print_keyword (cd, dis_info, & mep_cgen_opval_h_ccr_fmax, value, attrs);
109
}
110
/* end-cop-ip-print-handlers */
111
 
112
/************************************************************\
113
*********************** Experimental *************************
114
\************************************************************/
115
 
116
#undef  CGEN_PRINT_INSN
117
#define CGEN_PRINT_INSN mep_print_insn
118
 
119
static int
120
mep_print_vliw_insns (CGEN_CPU_DESC cd, bfd_vma pc, disassemble_info *info,
121
                      bfd_byte *buf, int corelength, int copro1length,
122
                      int copro2length ATTRIBUTE_UNUSED)
123
{
124
  int i;
125
  int status = 0;
126
  /* char insnbuf[CGEN_MAX_INSN_SIZE]; */
127
  bfd_byte insnbuf[64];
128
 
129
  /* If corelength > 0 then there is a core insn present. It
130
     will be at the beginning of the buffer.  After printing
131
     the core insn, we need to print the + on the next line.  */
132
  if (corelength > 0)
133
    {
134
      int my_status = 0;
135
 
136
      for (i = 0; i < corelength; i++ )
137
        insnbuf[i] = buf[i];
138
      cd->isas = & MEP_CORE_ISA;
139
 
140
      my_status = print_insn (cd, pc, info, insnbuf, corelength);
141
      if (my_status != corelength)
142
        {
143
          (*info->fprintf_func) (info->stream, UNKNOWN_INSN_MSG);
144
          my_status = corelength;
145
        }
146
      status += my_status;
147
 
148
      /* Print the + to indicate that the following copro insn is   */
149
      /* part of a vliw group.                                      */
150
      if (copro1length > 0)
151
        (*info->fprintf_func) (info->stream, " + ");
152
    }
153
 
154
  /* Now all that is left to be processed is the coprocessor insns
155
     In vliw mode, there will always be one.  Its positioning will
156
     be from byte corelength to byte corelength+copro1length -1.
157
     No need to check for existence.   Also, the first vliw insn,
158
     will, as spec'd, always be at least as long as the core insn
159
     so we don't need to flush the buffer.  */
160
  if (copro1length > 0)
161
    {
162
      int my_status = 0;
163
 
164
      for (i = corelength; i < corelength + copro1length; i++ )
165
        insnbuf[i - corelength] = buf[i];
166
 
167
      switch (copro1length)
168
        {
169
        case 0:
170
          break;
171
        case 2:
172
          cd->isas = & MEP_COP16_ISA;
173
          break;
174
        case 4:
175
          cd->isas = & MEP_COP32_ISA;
176
          break;
177
        case 6:
178
          cd->isas = & MEP_COP48_ISA;
179
          break;
180
        case 8:
181
          cd->isas = & MEP_COP64_ISA;
182
          break;
183
        default:
184
          /* Shouldn't be anything but 16,32,48,64.  */
185
          break;
186
        }
187
 
188
      my_status = print_insn (cd, pc, info, insnbuf, copro1length);
189
 
190
      if (my_status != copro1length)
191
        {
192
          (*info->fprintf_func) (info->stream, UNKNOWN_INSN_MSG);
193
          my_status = copro1length;
194
        }
195
      status += my_status;
196
    }
197
 
198
#if 0
199
  /* Now we need to process the second copro insn if it exists. We
200
     have no guarantee that the second copro insn will be longer
201
     than the first, so we have to flush the buffer if we are have
202
     a second copro insn to process.  If present, this insn will
203
     be in the position from byte corelength+copro1length to byte
204
     corelength+copro1length+copro2length-1 (which better equal 8
205
     or else we're in big trouble.  */
206
  if (copro2length > 0)
207
    {
208
      int my_status = 0;
209
 
210
      for (i = 0; i < 64 ; i++)
211
        insnbuf[i] = 0;
212
 
213
      for (i = corelength + copro1length; i < 64; i++)
214
        insnbuf[i - (corelength + copro1length)] = buf[i];
215
 
216
      switch (copro2length)
217
        {
218
        case 2:
219
          cd->isas = 1 << ISA_EXT_COP1_16;
220
          break;
221
        case 4:
222
          cd->isas = 1 << ISA_EXT_COP1_32;
223
          break;
224
        case 6:
225
          cd->isas = 1 << ISA_EXT_COP1_48;
226
          break;
227
        case 8:
228
          cd->isas = 1 << ISA_EXT_COP1_64;
229
          break;
230
        default:
231
          /* Shouldn't be anything but 16,32,48,64.  */
232
          break;
233
        }
234
 
235
      my_status = print_insn (cd, pc, info, insnbuf, copro2length);
236
 
237
      if (my_status != copro2length)
238
        {
239
          (*info->fprintf_func) (info->stream, UNKNOWN_INSN_MSG);
240
          my_status = copro2length;
241
        }
242
 
243
      status += my_status;
244
    }
245
#endif
246
 
247
  /* Status should now be the number of bytes that were printed
248
     which should be 4 for VLIW32 mode and 64 for VLIW64 mode.  */
249
 
250
  if ((!MEP_VLIW64 && (status != 4)) || (MEP_VLIW64 && (status != 8)))
251
    return -1;
252
  else
253
    return status;
254
}
255
 
256
/* The two functions mep_examine_vliw[32,64]_insns are used find out
257
   which vliw combinaion (16 bit core with 48 bit copro, 32 bit core
258
   with 32 bit copro, etc.) is present.  Later on, when internally
259
   parallel coprocessors are handled, only these functions should
260
   need to be changed.
261
 
262
   At this time only the following combinations are supported:
263
 
264
   VLIW32 Mode:
265
   16 bit core insn (core) and 16 bit coprocessor insn (cop1)
266
   32 bit core insn (core)
267
   32 bit coprocessor insn (cop1)
268
   Note: As of this time, I do not believe we have enough information
269
         to distinguish a 32 bit core insn from a 32 bit cop insn. Also,
270
         no 16 bit coprocessor insns have been specified.
271
 
272
   VLIW64 Mode:
273
   16 bit core insn (core) and 48 bit coprocessor insn (cop1)
274
   32 bit core insn (core) and 32 bit coprocessor insn (cop1)
275
   64 bit coprocessor insn (cop1)
276
 
277
   The framework for an internally parallel coprocessor is also
278
   present (2nd coprocessor insn is cop2), but at this time it
279
   is not used.  This only appears to be valid in VLIW64 mode.  */
280
 
281
static int
282
mep_examine_vliw32_insns (CGEN_CPU_DESC cd, bfd_vma pc, disassemble_info *info)
283
{
284
  int status;
285
  int buflength;
286
  int corebuflength;
287
  int cop1buflength;
288
  int cop2buflength;
289
  bfd_byte buf[CGEN_MAX_INSN_SIZE];
290
  char indicator16[1];
291
  char indicatorcop32[2];
292
 
293
  /* At this time we're not supporting internally parallel coprocessors,
294
     so cop2buflength will always be 0.  */
295
  cop2buflength = 0;
296
 
297
  /* Read in 32 bits.  */
298
  buflength = 4; /* VLIW insn spans 4 bytes.  */
299
  status = (*info->read_memory_func) (pc, buf, buflength, info);
300
 
301
  if (status != 0)
302
    {
303
      (*info->memory_error_func) (status, pc, info);
304
      return -1;
305
    }
306
 
307
  /* Put the big endian representation of the bytes to be examined
308
     in the temporary buffers for examination.  */
309
 
310
  if (info->endian == BFD_ENDIAN_BIG)
311
    {
312
      indicator16[0] = buf[0];
313
      indicatorcop32[0] = buf[0];
314
      indicatorcop32[1] = buf[1];
315
    }
316
  else
317
    {
318
      indicator16[0] = buf[1];
319
      indicatorcop32[0] = buf[1];
320
      indicatorcop32[1] = buf[0];
321
    }
322
 
323
  /* If the two high order bits are 00, 01 or 10, we have a 16 bit
324
     core insn and a 48 bit copro insn.  */
325
 
326
  if ((indicator16[0] & 0x80) && (indicator16[0] & 0x40))
327
    {
328
      if ((indicatorcop32[0] & 0xf0) == 0xf0 && (indicatorcop32[1] & 0x07) == 0x07)
329
        {
330
          /* We have a 32 bit copro insn.  */
331
          corebuflength = 0;
332
          /* All 4 4ytes are one copro insn. */
333
          cop1buflength = 4;
334
        }
335
      else
336
        {
337
          /* We have a 32 bit core.  */
338
          corebuflength = 4;
339
          cop1buflength = 0;
340
        }
341
    }
342
  else
343
    {
344
      /* We have a 16 bit core insn and a 16 bit copro insn.  */
345
      corebuflength = 2;
346
      cop1buflength = 2;
347
    }
348
 
349
  /* Now we have the distrubution set.  Print them out.  */
350
  status = mep_print_vliw_insns (cd, pc, info, buf, corebuflength,
351
                                 cop1buflength, cop2buflength);
352
 
353
  return status;
354
}
355
 
356
static int
357
mep_examine_vliw64_insns (CGEN_CPU_DESC cd, bfd_vma pc, disassemble_info *info)
358
{
359
  int status;
360
  int buflength;
361
  int corebuflength;
362
  int cop1buflength;
363
  int cop2buflength;
364
  bfd_byte buf[CGEN_MAX_INSN_SIZE];
365
  char indicator16[1];
366
  char indicator64[4];
367
 
368
  /* At this time we're not supporting internally parallel
369
     coprocessors, so cop2buflength will always be 0.  */
370
  cop2buflength = 0;
371
 
372
  /* Read in 64 bits.  */
373
  buflength = 8; /* VLIW insn spans 8 bytes.  */
374
  status = (*info->read_memory_func) (pc, buf, buflength, info);
375
 
376
  if (status != 0)
377
    {
378
      (*info->memory_error_func) (status, pc, info);
379
      return -1;
380
    }
381
 
382
  /* We have all 64 bits in the buffer now.  We have to figure out
383
     what combination of instruction sizes are present.  The two
384
     high order bits will indicate whether or not we have a 16 bit
385
     core insn or not.  If not, then we have to look at the 7,8th
386
     bytes to tell whether we have 64 bit copro insn or a 32 bit
387
     core insn with a 32 bit copro insn.  Endianness will make a
388
     difference here.  */
389
 
390
  /* Put the big endian representation of the bytes to be examined
391
     in the temporary buffers for examination.  */
392
 
393
  /* indicator16[0] = buf[0];  */
394
  if (info->endian == BFD_ENDIAN_BIG)
395
    {
396
      indicator16[0] = buf[0];
397
      indicator64[0] = buf[0];
398
      indicator64[1] = buf[1];
399
      indicator64[2] = buf[2];
400
      indicator64[3] = buf[3];
401
    }
402
  else
403
    {
404
      indicator16[0] = buf[1];
405
      indicator64[0] = buf[1];
406
      indicator64[1] = buf[0];
407
      indicator64[2] = buf[3];
408
      indicator64[3] = buf[2];
409
    }
410
 
411
  /* If the two high order bits are 00, 01 or 10, we have a 16 bit
412
     core insn and a 48 bit copro insn.  */
413
 
414
  if ((indicator16[0] & 0x80) && (indicator16[0] & 0x40))
415
    {
416
      if ((indicator64[0] & 0xf0) == 0xf0 && (indicator64[1] & 0x07) == 0x07
417
          && ((indicator64[2] & 0xfe) != 0xf0 || (indicator64[3] & 0xf4) != 0))
418
        {
419
          /* We have a 64 bit copro insn.  */
420
          corebuflength = 0;
421
          /* All 8 bytes are one copro insn.  */
422
          cop1buflength = 8;
423
        }
424
      else
425
        {
426
          /* We have a 32 bit core insn and a 32 bit copro insn.  */
427
          corebuflength = 4;
428
          cop1buflength = 4;
429
        }
430
    }
431
  else
432
    {
433
      /* We have a 16 bit core insn and a 48 bit copro insn.  */
434
      corebuflength = 2;
435
      cop1buflength = 6;
436
    }
437
 
438
  /* Now we have the distrubution set.  Print them out. */
439
  status = mep_print_vliw_insns (cd, pc, info, buf, corebuflength,
440
                                 cop1buflength, cop2buflength);
441
 
442
  return status;
443
}
444
 
445
static int
446
mep_print_insn (CGEN_CPU_DESC cd, bfd_vma pc, disassemble_info *info)
447
{
448
  int status;
449
 
450
  /* Extract and adapt to configuration number, if available. */
451
  if (info->section && info->section->owner)
452
    {
453
      bfd *abfd = info->section->owner;
454
      mep_config_index = abfd->tdata.elf_obj_data->elf_header->e_flags & EF_MEP_INDEX_MASK;
455
      /* This instantly redefines MEP_CONFIG, MEP_OMASK, .... MEP_VLIW64 */
456
    }
457
 
458
  /* Picking the right ISA bitmask for the current context is tricky.  */
459
  if (info->section)
460
    {
461
      if (info->section->flags & SEC_MEP_VLIW)
462
        {
463
          /* Are we in 32 or 64 bit vliw mode?  */
464
          if (MEP_VLIW64)
465
            status = mep_examine_vliw64_insns (cd, pc, info);
466
          else
467
            status = mep_examine_vliw32_insns (cd, pc, info);
468
          /* Both the above branches set their own isa bitmasks.  */
469
        }
470
      else
471
        {
472
          cd->isas = & MEP_CORE_ISA;
473
          status = default_print_insn (cd, pc, info);
474
        }
475
    }
476
  else /* sid or gdb */
477
    {
478
      status = default_print_insn (cd, pc, info);
479
    }
480
 
481
  return status;
482
}
483
 
484
 
485
/* -- opc.c */
486
 
487
void mep_cgen_print_operand
488
  (CGEN_CPU_DESC, int, PTR, CGEN_FIELDS *, void const *, bfd_vma, int);
489
 
490
/* Main entry point for printing operands.
491
   XINFO is a `void *' and not a `disassemble_info *' to not put a requirement
492
   of dis-asm.h on cgen.h.
493
 
494
   This function is basically just a big switch statement.  Earlier versions
495
   used tables to look up the function to use, but
496
   - if the table contains both assembler and disassembler functions then
497
     the disassembler contains much of the assembler and vice-versa,
498
   - there's a lot of inlining possibilities as things grow,
499
   - using a switch statement avoids the function call overhead.
500
 
501
   This function could be moved into `print_insn_normal', but keeping it
502
   separate makes clear the interface between `print_insn_normal' and each of
503
   the handlers.  */
504
 
505
void
506
mep_cgen_print_operand (CGEN_CPU_DESC cd,
507
                           int opindex,
508
                           void * xinfo,
509
                           CGEN_FIELDS *fields,
510
                           void const *attrs ATTRIBUTE_UNUSED,
511
                           bfd_vma pc,
512
                           int length)
513
{
514
  disassemble_info *info = (disassemble_info *) xinfo;
515
 
516
  switch (opindex)
517
    {
518
    case MEP_OPERAND_ADDR24A4 :
519
      print_normal (cd, info, fields->f_24u8a4n, 0|(1<<CGEN_OPERAND_VIRTUAL), pc, length);
520
      break;
521
    case MEP_OPERAND_CALLNUM :
522
      print_normal (cd, info, fields->f_callnum, 0|(1<<CGEN_OPERAND_VIRTUAL), pc, length);
523
      break;
524
    case MEP_OPERAND_CCCC :
525
      print_normal (cd, info, fields->f_rm, 0, pc, length);
526
      break;
527
    case MEP_OPERAND_CCRN :
528
      print_keyword (cd, info, & mep_cgen_opval_h_ccr, fields->f_ccrn, 0|(1<<CGEN_OPERAND_VIRTUAL));
529
      break;
530
    case MEP_OPERAND_CDISP8 :
531
      print_normal (cd, info, fields->f_8s24, 0|(1<<CGEN_OPERAND_SIGNED), pc, length);
532
      break;
533
    case MEP_OPERAND_CDISP8A2 :
534
      print_normal (cd, info, fields->f_8s24a2, 0|(1<<CGEN_OPERAND_SIGNED), pc, length);
535
      break;
536
    case MEP_OPERAND_CDISP8A4 :
537
      print_normal (cd, info, fields->f_8s24a4, 0|(1<<CGEN_OPERAND_SIGNED), pc, length);
538
      break;
539
    case MEP_OPERAND_CDISP8A8 :
540
      print_normal (cd, info, fields->f_8s24a8, 0|(1<<CGEN_OPERAND_SIGNED), pc, length);
541
      break;
542
    case MEP_OPERAND_CIMM4 :
543
      print_normal (cd, info, fields->f_rn, 0, pc, length);
544
      break;
545
    case MEP_OPERAND_CIMM5 :
546
      print_normal (cd, info, fields->f_5u24, 0, pc, length);
547
      break;
548
    case MEP_OPERAND_CODE16 :
549
      print_normal (cd, info, fields->f_16u16, 0, pc, length);
550
      break;
551
    case MEP_OPERAND_CODE24 :
552
      print_normal (cd, info, fields->f_24u4n, 0|(1<<CGEN_OPERAND_VIRTUAL), pc, length);
553
      break;
554
    case MEP_OPERAND_CP_FLAG :
555
      print_keyword (cd, info, & mep_cgen_opval_h_ccr, 0, 0);
556
      break;
557
    case MEP_OPERAND_CRN :
558
      print_keyword (cd, info, & mep_cgen_opval_h_cr, fields->f_crn, 0);
559
      break;
560
    case MEP_OPERAND_CRN64 :
561
      print_keyword (cd, info, & mep_cgen_opval_h_cr64, fields->f_crn, 0);
562
      break;
563
    case MEP_OPERAND_CRNX :
564
      print_keyword (cd, info, & mep_cgen_opval_h_cr, fields->f_crnx, 0|(1<<CGEN_OPERAND_VIRTUAL));
565
      break;
566
    case MEP_OPERAND_CRNX64 :
567
      print_keyword (cd, info, & mep_cgen_opval_h_cr64, fields->f_crnx, 0|(1<<CGEN_OPERAND_VIRTUAL));
568
      break;
569
    case MEP_OPERAND_CSRN :
570
      print_keyword (cd, info, & mep_cgen_opval_h_csr, fields->f_csrn, 0|(1<<CGEN_OPERAND_VIRTUAL));
571
      break;
572
    case MEP_OPERAND_CSRN_IDX :
573
      print_normal (cd, info, fields->f_csrn, 0|(1<<CGEN_OPERAND_VIRTUAL), pc, length);
574
      break;
575
    case MEP_OPERAND_DBG :
576
      print_keyword (cd, info, & mep_cgen_opval_h_csr, 0, 0);
577
      break;
578
    case MEP_OPERAND_DEPC :
579
      print_keyword (cd, info, & mep_cgen_opval_h_csr, 0, 0);
580
      break;
581
    case MEP_OPERAND_EPC :
582
      print_keyword (cd, info, & mep_cgen_opval_h_csr, 0, 0);
583
      break;
584
    case MEP_OPERAND_EXC :
585
      print_keyword (cd, info, & mep_cgen_opval_h_csr, 0, 0);
586
      break;
587
    case MEP_OPERAND_FMAX_CCRN :
588
      print_fmax_ccr (cd, info, & mep_cgen_opval_h_ccr, fields->f_fmax_4_4, 0);
589
      break;
590
    case MEP_OPERAND_FMAX_FRD :
591
      print_fmax_cr (cd, info, & mep_cgen_opval_h_cr, fields->f_fmax_frd, 0|(1<<CGEN_OPERAND_VIRTUAL));
592
      break;
593
    case MEP_OPERAND_FMAX_FRD_INT :
594
      print_fmax_cr (cd, info, & mep_cgen_opval_h_cr, fields->f_fmax_frd, 0|(1<<CGEN_OPERAND_VIRTUAL));
595
      break;
596
    case MEP_OPERAND_FMAX_FRM :
597
      print_fmax_cr (cd, info, & mep_cgen_opval_h_cr, fields->f_fmax_frm, 0|(1<<CGEN_OPERAND_VIRTUAL));
598
      break;
599
    case MEP_OPERAND_FMAX_FRN :
600
      print_fmax_cr (cd, info, & mep_cgen_opval_h_cr, fields->f_fmax_frn, 0|(1<<CGEN_OPERAND_VIRTUAL));
601
      break;
602
    case MEP_OPERAND_FMAX_FRN_INT :
603
      print_fmax_cr (cd, info, & mep_cgen_opval_h_cr, fields->f_fmax_frn, 0|(1<<CGEN_OPERAND_VIRTUAL));
604
      break;
605
    case MEP_OPERAND_FMAX_RM :
606
      print_keyword (cd, info, & mep_cgen_opval_h_gpr, fields->f_fmax_rm, 0);
607
      break;
608
    case MEP_OPERAND_HI :
609
      print_keyword (cd, info, & mep_cgen_opval_h_csr, 0, 0);
610
      break;
611
    case MEP_OPERAND_LO :
612
      print_keyword (cd, info, & mep_cgen_opval_h_csr, 0, 0);
613
      break;
614
    case MEP_OPERAND_LP :
615
      print_keyword (cd, info, & mep_cgen_opval_h_csr, 0, 0);
616
      break;
617
    case MEP_OPERAND_MB0 :
618
      print_keyword (cd, info, & mep_cgen_opval_h_csr, 0, 0);
619
      break;
620
    case MEP_OPERAND_MB1 :
621
      print_keyword (cd, info, & mep_cgen_opval_h_csr, 0, 0);
622
      break;
623
    case MEP_OPERAND_ME0 :
624
      print_keyword (cd, info, & mep_cgen_opval_h_csr, 0, 0);
625
      break;
626
    case MEP_OPERAND_ME1 :
627
      print_keyword (cd, info, & mep_cgen_opval_h_csr, 0, 0);
628
      break;
629
    case MEP_OPERAND_NPC :
630
      print_keyword (cd, info, & mep_cgen_opval_h_csr, 0, 0);
631
      break;
632
    case MEP_OPERAND_OPT :
633
      print_keyword (cd, info, & mep_cgen_opval_h_csr, 0, 0);
634
      break;
635
    case MEP_OPERAND_PCABS24A2 :
636
      print_address (cd, info, fields->f_24u5a2n, 0|(1<<CGEN_OPERAND_ABS_ADDR)|(1<<CGEN_OPERAND_VIRTUAL), pc, length);
637
      break;
638
    case MEP_OPERAND_PCREL12A2 :
639
      print_address (cd, info, fields->f_12s4a2, 0|(1<<CGEN_OPERAND_SIGNED)|(1<<CGEN_OPERAND_RELAX)|(1<<CGEN_OPERAND_PCREL_ADDR), pc, length);
640
      break;
641
    case MEP_OPERAND_PCREL17A2 :
642
      print_address (cd, info, fields->f_17s16a2, 0|(1<<CGEN_OPERAND_SIGNED)|(1<<CGEN_OPERAND_RELAX)|(1<<CGEN_OPERAND_PCREL_ADDR), pc, length);
643
      break;
644
    case MEP_OPERAND_PCREL24A2 :
645
      print_address (cd, info, fields->f_24s5a2n, 0|(1<<CGEN_OPERAND_SIGNED)|(1<<CGEN_OPERAND_PCREL_ADDR)|(1<<CGEN_OPERAND_VIRTUAL), pc, length);
646
      break;
647
    case MEP_OPERAND_PCREL8A2 :
648
      print_address (cd, info, fields->f_8s8a2, 0|(1<<CGEN_OPERAND_SIGNED)|(1<<CGEN_OPERAND_RELAX)|(1<<CGEN_OPERAND_PCREL_ADDR), pc, length);
649
      break;
650
    case MEP_OPERAND_PSW :
651
      print_keyword (cd, info, & mep_cgen_opval_h_csr, 0, 0);
652
      break;
653
    case MEP_OPERAND_R0 :
654
      print_keyword (cd, info, & mep_cgen_opval_h_gpr, 0, 0);
655
      break;
656
    case MEP_OPERAND_R1 :
657
      print_keyword (cd, info, & mep_cgen_opval_h_gpr, 0, 0);
658
      break;
659
    case MEP_OPERAND_RL :
660
      print_keyword (cd, info, & mep_cgen_opval_h_gpr, fields->f_rl, 0);
661
      break;
662
    case MEP_OPERAND_RM :
663
      print_keyword (cd, info, & mep_cgen_opval_h_gpr, fields->f_rm, 0);
664
      break;
665
    case MEP_OPERAND_RMA :
666
      print_keyword (cd, info, & mep_cgen_opval_h_gpr, fields->f_rm, 0);
667
      break;
668
    case MEP_OPERAND_RN :
669
      print_keyword (cd, info, & mep_cgen_opval_h_gpr, fields->f_rn, 0);
670
      break;
671
    case MEP_OPERAND_RN3 :
672
      print_keyword (cd, info, & mep_cgen_opval_h_gpr, fields->f_rn3, 0);
673
      break;
674
    case MEP_OPERAND_RN3C :
675
      print_keyword (cd, info, & mep_cgen_opval_h_gpr, fields->f_rn3, 0);
676
      break;
677
    case MEP_OPERAND_RN3L :
678
      print_keyword (cd, info, & mep_cgen_opval_h_gpr, fields->f_rn3, 0);
679
      break;
680
    case MEP_OPERAND_RN3S :
681
      print_keyword (cd, info, & mep_cgen_opval_h_gpr, fields->f_rn3, 0);
682
      break;
683
    case MEP_OPERAND_RN3UC :
684
      print_keyword (cd, info, & mep_cgen_opval_h_gpr, fields->f_rn3, 0);
685
      break;
686
    case MEP_OPERAND_RN3UL :
687
      print_keyword (cd, info, & mep_cgen_opval_h_gpr, fields->f_rn3, 0);
688
      break;
689
    case MEP_OPERAND_RN3US :
690
      print_keyword (cd, info, & mep_cgen_opval_h_gpr, fields->f_rn3, 0);
691
      break;
692
    case MEP_OPERAND_RNC :
693
      print_keyword (cd, info, & mep_cgen_opval_h_gpr, fields->f_rn, 0);
694
      break;
695
    case MEP_OPERAND_RNL :
696
      print_keyword (cd, info, & mep_cgen_opval_h_gpr, fields->f_rn, 0);
697
      break;
698
    case MEP_OPERAND_RNS :
699
      print_keyword (cd, info, & mep_cgen_opval_h_gpr, fields->f_rn, 0);
700
      break;
701
    case MEP_OPERAND_RNUC :
702
      print_keyword (cd, info, & mep_cgen_opval_h_gpr, fields->f_rn, 0);
703
      break;
704
    case MEP_OPERAND_RNUL :
705
      print_keyword (cd, info, & mep_cgen_opval_h_gpr, fields->f_rn, 0);
706
      break;
707
    case MEP_OPERAND_RNUS :
708
      print_keyword (cd, info, & mep_cgen_opval_h_gpr, fields->f_rn, 0);
709
      break;
710
    case MEP_OPERAND_SAR :
711
      print_keyword (cd, info, & mep_cgen_opval_h_csr, 0, 0);
712
      break;
713
    case MEP_OPERAND_SDISP16 :
714
      print_normal (cd, info, fields->f_16s16, 0|(1<<CGEN_OPERAND_SIGNED), pc, length);
715
      break;
716
    case MEP_OPERAND_SIMM16 :
717
      print_normal (cd, info, fields->f_16s16, 0|(1<<CGEN_OPERAND_SIGNED), pc, length);
718
      break;
719
    case MEP_OPERAND_SIMM6 :
720
      print_normal (cd, info, fields->f_6s8, 0|(1<<CGEN_OPERAND_SIGNED), pc, length);
721
      break;
722
    case MEP_OPERAND_SIMM8 :
723
      print_normal (cd, info, fields->f_8s8, 0|(1<<CGEN_OPERAND_SIGNED)|(1<<CGEN_OPERAND_RELOC_IMPLIES_OVERFLOW), pc, length);
724
      break;
725
    case MEP_OPERAND_SP :
726
      print_keyword (cd, info, & mep_cgen_opval_h_gpr, 0, 0);
727
      break;
728
    case MEP_OPERAND_SPR :
729
      print_spreg (cd, info, & mep_cgen_opval_h_gpr, 0, 0);
730
      break;
731
    case MEP_OPERAND_TP :
732
      print_keyword (cd, info, & mep_cgen_opval_h_gpr, 0, 0);
733
      break;
734
    case MEP_OPERAND_TPR :
735
      print_tpreg (cd, info, & mep_cgen_opval_h_gpr, 0, 0);
736
      break;
737
    case MEP_OPERAND_UDISP2 :
738
      print_normal (cd, info, fields->f_2u6, 0|(1<<CGEN_OPERAND_SIGNED), pc, length);
739
      break;
740
    case MEP_OPERAND_UDISP7 :
741
      print_normal (cd, info, fields->f_7u9, 0, pc, length);
742
      break;
743
    case MEP_OPERAND_UDISP7A2 :
744
      print_normal (cd, info, fields->f_7u9a2, 0, pc, length);
745
      break;
746
    case MEP_OPERAND_UDISP7A4 :
747
      print_normal (cd, info, fields->f_7u9a4, 0, pc, length);
748
      break;
749
    case MEP_OPERAND_UIMM16 :
750
      print_normal (cd, info, fields->f_16u16, 0, pc, length);
751
      break;
752
    case MEP_OPERAND_UIMM2 :
753
      print_normal (cd, info, fields->f_2u10, 0, pc, length);
754
      break;
755
    case MEP_OPERAND_UIMM24 :
756
      print_normal (cd, info, fields->f_24u8n, 0|(1<<CGEN_OPERAND_VIRTUAL), pc, length);
757
      break;
758
    case MEP_OPERAND_UIMM3 :
759
      print_normal (cd, info, fields->f_3u5, 0, pc, length);
760
      break;
761
    case MEP_OPERAND_UIMM4 :
762
      print_normal (cd, info, fields->f_4u8, 0, pc, length);
763
      break;
764
    case MEP_OPERAND_UIMM5 :
765
      print_normal (cd, info, fields->f_5u8, 0, pc, length);
766
      break;
767
    case MEP_OPERAND_UIMM7A4 :
768
      print_normal (cd, info, fields->f_7u9a4, 0, pc, length);
769
      break;
770
    case MEP_OPERAND_ZERO :
771
      print_normal (cd, info, 0, 0|(1<<CGEN_OPERAND_SIGNED), pc, length);
772
      break;
773
 
774
    default :
775
      /* xgettext:c-format */
776
      fprintf (stderr, _("Unrecognized field %d while printing insn.\n"),
777
               opindex);
778
    abort ();
779
  }
780
}
781
 
782
cgen_print_fn * const mep_cgen_print_handlers[] =
783
{
784
  print_insn_normal,
785
};
786
 
787
 
788
void
789
mep_cgen_init_dis (CGEN_CPU_DESC cd)
790
{
791
  mep_cgen_init_opcode_table (cd);
792
  mep_cgen_init_ibld_table (cd);
793
  cd->print_handlers = & mep_cgen_print_handlers[0];
794
  cd->print_operand = mep_cgen_print_operand;
795
}
796
 
797
 
798
/* Default print handler.  */
799
 
800
static void
801
print_normal (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
802
              void *dis_info,
803
              long value,
804
              unsigned int attrs,
805
              bfd_vma pc ATTRIBUTE_UNUSED,
806
              int length ATTRIBUTE_UNUSED)
807
{
808
  disassemble_info *info = (disassemble_info *) dis_info;
809
 
810
#ifdef CGEN_PRINT_NORMAL
811
  CGEN_PRINT_NORMAL (cd, info, value, attrs, pc, length);
812
#endif
813
 
814
  /* Print the operand as directed by the attributes.  */
815
  if (CGEN_BOOL_ATTR (attrs, CGEN_OPERAND_SEM_ONLY))
816
    ; /* nothing to do */
817
  else if (CGEN_BOOL_ATTR (attrs, CGEN_OPERAND_SIGNED))
818
    (*info->fprintf_func) (info->stream, "%ld", value);
819
  else
820
    (*info->fprintf_func) (info->stream, "0x%lx", value);
821
}
822
 
823
/* Default address handler.  */
824
 
825
static void
826
print_address (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
827
               void *dis_info,
828
               bfd_vma value,
829
               unsigned int attrs,
830
               bfd_vma pc ATTRIBUTE_UNUSED,
831
               int length ATTRIBUTE_UNUSED)
832
{
833
  disassemble_info *info = (disassemble_info *) dis_info;
834
 
835
#ifdef CGEN_PRINT_ADDRESS
836
  CGEN_PRINT_ADDRESS (cd, info, value, attrs, pc, length);
837
#endif
838
 
839
  /* Print the operand as directed by the attributes.  */
840
  if (CGEN_BOOL_ATTR (attrs, CGEN_OPERAND_SEM_ONLY))
841
    ; /* Nothing to do.  */
842
  else if (CGEN_BOOL_ATTR (attrs, CGEN_OPERAND_PCREL_ADDR))
843
    (*info->print_address_func) (value, info);
844
  else if (CGEN_BOOL_ATTR (attrs, CGEN_OPERAND_ABS_ADDR))
845
    (*info->print_address_func) (value, info);
846
  else if (CGEN_BOOL_ATTR (attrs, CGEN_OPERAND_SIGNED))
847
    (*info->fprintf_func) (info->stream, "%ld", (long) value);
848
  else
849
    (*info->fprintf_func) (info->stream, "0x%lx", (long) value);
850
}
851
 
852
/* Keyword print handler.  */
853
 
854
static void
855
print_keyword (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
856
               void *dis_info,
857
               CGEN_KEYWORD *keyword_table,
858
               long value,
859
               unsigned int attrs ATTRIBUTE_UNUSED)
860
{
861
  disassemble_info *info = (disassemble_info *) dis_info;
862
  const CGEN_KEYWORD_ENTRY *ke;
863
 
864
  ke = cgen_keyword_lookup_value (keyword_table, value);
865
  if (ke != NULL)
866
    (*info->fprintf_func) (info->stream, "%s", ke->name);
867
  else
868
    (*info->fprintf_func) (info->stream, "???");
869
}
870
 
871
/* Default insn printer.
872
 
873
   DIS_INFO is defined as `void *' so the disassembler needn't know anything
874
   about disassemble_info.  */
875
 
876
static void
877
print_insn_normal (CGEN_CPU_DESC cd,
878
                   void *dis_info,
879
                   const CGEN_INSN *insn,
880
                   CGEN_FIELDS *fields,
881
                   bfd_vma pc,
882
                   int length)
883
{
884
  const CGEN_SYNTAX *syntax = CGEN_INSN_SYNTAX (insn);
885
  disassemble_info *info = (disassemble_info *) dis_info;
886
  const CGEN_SYNTAX_CHAR_TYPE *syn;
887
 
888
  CGEN_INIT_PRINT (cd);
889
 
890
  for (syn = CGEN_SYNTAX_STRING (syntax); *syn; ++syn)
891
    {
892
      if (CGEN_SYNTAX_MNEMONIC_P (*syn))
893
        {
894
          (*info->fprintf_func) (info->stream, "%s", CGEN_INSN_MNEMONIC (insn));
895
          continue;
896
        }
897
      if (CGEN_SYNTAX_CHAR_P (*syn))
898
        {
899
          (*info->fprintf_func) (info->stream, "%c", CGEN_SYNTAX_CHAR (*syn));
900
          continue;
901
        }
902
 
903
      /* We have an operand.  */
904
      mep_cgen_print_operand (cd, CGEN_SYNTAX_FIELD (*syn), info,
905
                                 fields, CGEN_INSN_ATTRS (insn), pc, length);
906
    }
907
}
908
 
909
/* Subroutine of print_insn. Reads an insn into the given buffers and updates
910
   the extract info.
911
   Returns 0 if all is well, non-zero otherwise.  */
912
 
913
static int
914
read_insn (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
915
           bfd_vma pc,
916
           disassemble_info *info,
917
           bfd_byte *buf,
918
           int buflen,
919
           CGEN_EXTRACT_INFO *ex_info,
920
           unsigned long *insn_value)
921
{
922
  int status = (*info->read_memory_func) (pc, buf, buflen, info);
923
 
924
  if (status != 0)
925
    {
926
      (*info->memory_error_func) (status, pc, info);
927
      return -1;
928
    }
929
 
930
  ex_info->dis_info = info;
931
  ex_info->valid = (1 << buflen) - 1;
932
  ex_info->insn_bytes = buf;
933
 
934
  *insn_value = bfd_get_bits (buf, buflen * 8, info->endian == BFD_ENDIAN_BIG);
935
  return 0;
936
}
937
 
938
/* Utility to print an insn.
939
   BUF is the base part of the insn, target byte order, BUFLEN bytes long.
940
   The result is the size of the insn in bytes or zero for an unknown insn
941
   or -1 if an error occurs fetching data (memory_error_func will have
942
   been called).  */
943
 
944
static int
945
print_insn (CGEN_CPU_DESC cd,
946
            bfd_vma pc,
947
            disassemble_info *info,
948
            bfd_byte *buf,
949
            unsigned int buflen)
950
{
951
  CGEN_INSN_INT insn_value;
952
  const CGEN_INSN_LIST *insn_list;
953
  CGEN_EXTRACT_INFO ex_info;
954
  int basesize;
955
 
956
  /* Extract base part of instruction, just in case CGEN_DIS_* uses it. */
957
  basesize = cd->base_insn_bitsize < buflen * 8 ?
958
                                     cd->base_insn_bitsize : buflen * 8;
959
  insn_value = cgen_get_insn_value (cd, buf, basesize);
960
 
961
 
962
  /* Fill in ex_info fields like read_insn would.  Don't actually call
963
     read_insn, since the incoming buffer is already read (and possibly
964
     modified a la m32r).  */
965
  ex_info.valid = (1 << buflen) - 1;
966
  ex_info.dis_info = info;
967
  ex_info.insn_bytes = buf;
968
 
969
  /* The instructions are stored in hash lists.
970
     Pick the first one and keep trying until we find the right one.  */
971
 
972
  insn_list = CGEN_DIS_LOOKUP_INSN (cd, (char *) buf, insn_value);
973
  while (insn_list != NULL)
974
    {
975
      const CGEN_INSN *insn = insn_list->insn;
976
      CGEN_FIELDS fields;
977
      int length;
978
      unsigned long insn_value_cropped;
979
 
980
#ifdef CGEN_VALIDATE_INSN_SUPPORTED 
981
      /* Not needed as insn shouldn't be in hash lists if not supported.  */
982
      /* Supported by this cpu?  */
983
      if (! mep_cgen_insn_supported (cd, insn))
984
        {
985
          insn_list = CGEN_DIS_NEXT_INSN (insn_list);
986
          continue;
987
        }
988
#endif
989
 
990
      /* Basic bit mask must be correct.  */
991
      /* ??? May wish to allow target to defer this check until the extract
992
         handler.  */
993
 
994
      /* Base size may exceed this instruction's size.  Extract the
995
         relevant part from the buffer. */
996
      if ((unsigned) (CGEN_INSN_BITSIZE (insn) / 8) < buflen &&
997
          (unsigned) (CGEN_INSN_BITSIZE (insn) / 8) <= sizeof (unsigned long))
998
        insn_value_cropped = bfd_get_bits (buf, CGEN_INSN_BITSIZE (insn),
999
                                           info->endian == BFD_ENDIAN_BIG);
1000
      else
1001
        insn_value_cropped = insn_value;
1002
 
1003
      if ((insn_value_cropped & CGEN_INSN_BASE_MASK (insn))
1004
          == CGEN_INSN_BASE_VALUE (insn))
1005
        {
1006
          /* Printing is handled in two passes.  The first pass parses the
1007
             machine insn and extracts the fields.  The second pass prints
1008
             them.  */
1009
 
1010
          /* Make sure the entire insn is loaded into insn_value, if it
1011
             can fit.  */
1012
          if (((unsigned) CGEN_INSN_BITSIZE (insn) > cd->base_insn_bitsize) &&
1013
              (unsigned) (CGEN_INSN_BITSIZE (insn) / 8) <= sizeof (unsigned long))
1014
            {
1015
              unsigned long full_insn_value;
1016
              int rc = read_insn (cd, pc, info, buf,
1017
                                  CGEN_INSN_BITSIZE (insn) / 8,
1018
                                  & ex_info, & full_insn_value);
1019
              if (rc != 0)
1020
                return rc;
1021
              length = CGEN_EXTRACT_FN (cd, insn)
1022
                (cd, insn, &ex_info, full_insn_value, &fields, pc);
1023
            }
1024
          else
1025
            length = CGEN_EXTRACT_FN (cd, insn)
1026
              (cd, insn, &ex_info, insn_value_cropped, &fields, pc);
1027
 
1028
          /* Length < 0 -> error.  */
1029
          if (length < 0)
1030
            return length;
1031
          if (length > 0)
1032
            {
1033
              CGEN_PRINT_FN (cd, insn) (cd, info, insn, &fields, pc, length);
1034
              /* Length is in bits, result is in bytes.  */
1035
              return length / 8;
1036
            }
1037
        }
1038
 
1039
      insn_list = CGEN_DIS_NEXT_INSN (insn_list);
1040
    }
1041
 
1042
  return 0;
1043
}
1044
 
1045
/* Default value for CGEN_PRINT_INSN.
1046
   The result is the size of the insn in bytes or zero for an unknown insn
1047
   or -1 if an error occured fetching bytes.  */
1048
 
1049
#ifndef CGEN_PRINT_INSN
1050
#define CGEN_PRINT_INSN default_print_insn
1051
#endif
1052
 
1053
static int
1054
default_print_insn (CGEN_CPU_DESC cd, bfd_vma pc, disassemble_info *info)
1055
{
1056
  bfd_byte buf[CGEN_MAX_INSN_SIZE];
1057
  int buflen;
1058
  int status;
1059
 
1060
  /* Attempt to read the base part of the insn.  */
1061
  buflen = cd->base_insn_bitsize / 8;
1062
  status = (*info->read_memory_func) (pc, buf, buflen, info);
1063
 
1064
  /* Try again with the minimum part, if min < base.  */
1065
  if (status != 0 && (cd->min_insn_bitsize < cd->base_insn_bitsize))
1066
    {
1067
      buflen = cd->min_insn_bitsize / 8;
1068
      status = (*info->read_memory_func) (pc, buf, buflen, info);
1069
    }
1070
 
1071
  if (status != 0)
1072
    {
1073
      (*info->memory_error_func) (status, pc, info);
1074
      return -1;
1075
    }
1076
 
1077
  return print_insn (cd, pc, info, buf, buflen);
1078
}
1079
 
1080
/* Main entry point.
1081
   Print one instruction from PC on INFO->STREAM.
1082
   Return the size of the instruction (in bytes).  */
1083
 
1084
typedef struct cpu_desc_list
1085
{
1086
  struct cpu_desc_list *next;
1087
  CGEN_BITSET *isa;
1088
  int mach;
1089
  int endian;
1090
  CGEN_CPU_DESC cd;
1091
} cpu_desc_list;
1092
 
1093
int
1094
print_insn_mep (bfd_vma pc, disassemble_info *info)
1095
{
1096
  static cpu_desc_list *cd_list = 0;
1097
  cpu_desc_list *cl = 0;
1098
  static CGEN_CPU_DESC cd = 0;
1099
  static CGEN_BITSET *prev_isa;
1100
  static int prev_mach;
1101
  static int prev_endian;
1102
  int length;
1103
  CGEN_BITSET *isa;
1104
  int mach;
1105
  int endian = (info->endian == BFD_ENDIAN_BIG
1106
                ? CGEN_ENDIAN_BIG
1107
                : CGEN_ENDIAN_LITTLE);
1108
  enum bfd_architecture arch;
1109
 
1110
  /* ??? gdb will set mach but leave the architecture as "unknown" */
1111
#ifndef CGEN_BFD_ARCH
1112
#define CGEN_BFD_ARCH bfd_arch_mep
1113
#endif
1114
  arch = info->arch;
1115
  if (arch == bfd_arch_unknown)
1116
    arch = CGEN_BFD_ARCH;
1117
 
1118
  /* There's no standard way to compute the machine or isa number
1119
     so we leave it to the target.  */
1120
#ifdef CGEN_COMPUTE_MACH
1121
  mach = CGEN_COMPUTE_MACH (info);
1122
#else
1123
  mach = info->mach;
1124
#endif
1125
 
1126
#ifdef CGEN_COMPUTE_ISA
1127
  {
1128
    static CGEN_BITSET *permanent_isa;
1129
 
1130
    if (!permanent_isa)
1131
      permanent_isa = cgen_bitset_create (MAX_ISAS);
1132
    isa = permanent_isa;
1133
    cgen_bitset_clear (isa);
1134
    cgen_bitset_add (isa, CGEN_COMPUTE_ISA (info));
1135
  }
1136
#else
1137
  isa = info->insn_sets;
1138
#endif
1139
 
1140
  /* If we've switched cpu's, try to find a handle we've used before */
1141
  if (cd
1142
      && (cgen_bitset_compare (isa, prev_isa) != 0
1143
          || mach != prev_mach
1144
          || endian != prev_endian))
1145
    {
1146
      cd = 0;
1147
      for (cl = cd_list; cl; cl = cl->next)
1148
        {
1149
          if (cgen_bitset_compare (cl->isa, isa) == 0 &&
1150
              cl->mach == mach &&
1151
              cl->endian == endian)
1152
            {
1153
              cd = cl->cd;
1154
              prev_isa = cd->isas;
1155
              break;
1156
            }
1157
        }
1158
    }
1159
 
1160
  /* If we haven't initialized yet, initialize the opcode table.  */
1161
  if (! cd)
1162
    {
1163
      const bfd_arch_info_type *arch_type = bfd_lookup_arch (arch, mach);
1164
      const char *mach_name;
1165
 
1166
      if (!arch_type)
1167
        abort ();
1168
      mach_name = arch_type->printable_name;
1169
 
1170
      prev_isa = cgen_bitset_copy (isa);
1171
      prev_mach = mach;
1172
      prev_endian = endian;
1173
      cd = mep_cgen_cpu_open (CGEN_CPU_OPEN_ISAS, prev_isa,
1174
                                 CGEN_CPU_OPEN_BFDMACH, mach_name,
1175
                                 CGEN_CPU_OPEN_ENDIAN, prev_endian,
1176
                                 CGEN_CPU_OPEN_END);
1177
      if (!cd)
1178
        abort ();
1179
 
1180
      /* Save this away for future reference.  */
1181
      cl = xmalloc (sizeof (struct cpu_desc_list));
1182
      cl->cd = cd;
1183
      cl->isa = prev_isa;
1184
      cl->mach = mach;
1185
      cl->endian = endian;
1186
      cl->next = cd_list;
1187
      cd_list = cl;
1188
 
1189
      mep_cgen_init_dis (cd);
1190
    }
1191
 
1192
  /* We try to have as much common code as possible.
1193
     But at this point some targets need to take over.  */
1194
  /* ??? Some targets may need a hook elsewhere.  Try to avoid this,
1195
     but if not possible try to move this hook elsewhere rather than
1196
     have two hooks.  */
1197
  length = CGEN_PRINT_INSN (cd, pc, info);
1198
  if (length > 0)
1199
    return length;
1200
  if (length < 0)
1201
    return -1;
1202
 
1203
  (*info->fprintf_func) (info->stream, UNKNOWN_INSN_MSG);
1204
  return cd->default_insn_bitsize / 8;
1205
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.