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