xref: /netbsd-src/external/gpl3/binutils.old/dist/opcodes/mep-dis.c (revision e992f068c547fd6e84b3f104dc2340adcc955732)
1ede78133Schristos /* DO NOT EDIT!  -*- buffer-read-only: t -*- vi:set ro:  */
275fd0b74Schristos /* Disassembler interface for targets using CGEN. -*- C -*-
375fd0b74Schristos    CGEN: Cpu tools GENerator
475fd0b74Schristos 
575fd0b74Schristos    THIS FILE IS MACHINE GENERATED WITH CGEN.
675fd0b74Schristos    - the resultant file is machine generated, cgen-dis.in isn't
775fd0b74Schristos 
8*e992f068Schristos    Copyright (C) 1996-2022 Free Software Foundation, Inc.
975fd0b74Schristos 
1075fd0b74Schristos    This file is part of libopcodes.
1175fd0b74Schristos 
1275fd0b74Schristos    This library is free software; you can redistribute it and/or modify
1375fd0b74Schristos    it under the terms of the GNU General Public License as published by
1475fd0b74Schristos    the Free Software Foundation; either version 3, or (at your option)
1575fd0b74Schristos    any later version.
1675fd0b74Schristos 
1775fd0b74Schristos    It is distributed in the hope that it will be useful, but WITHOUT
1875fd0b74Schristos    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
1975fd0b74Schristos    or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
2075fd0b74Schristos    License for more details.
2175fd0b74Schristos 
2275fd0b74Schristos    You should have received a copy of the GNU General Public License
2375fd0b74Schristos    along with this program; if not, write to the Free Software Foundation, Inc.,
2475fd0b74Schristos    51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.  */
2575fd0b74Schristos 
2675fd0b74Schristos /* ??? Eventually more and more of this stuff can go to cpu-independent files.
2775fd0b74Schristos    Keep that in mind.  */
2875fd0b74Schristos 
2975fd0b74Schristos #include "sysdep.h"
3075fd0b74Schristos #include <stdio.h>
3175fd0b74Schristos #include "ansidecl.h"
32ede78133Schristos #include "disassemble.h"
3375fd0b74Schristos #include "bfd.h"
3475fd0b74Schristos #include "symcat.h"
3575fd0b74Schristos #include "libiberty.h"
3675fd0b74Schristos #include "mep-desc.h"
3775fd0b74Schristos #include "mep-opc.h"
3875fd0b74Schristos #include "opintl.h"
3975fd0b74Schristos 
4075fd0b74Schristos /* Default text to print if an instruction isn't recognized.  */
4175fd0b74Schristos #define UNKNOWN_INSN_MSG _("*unknown*")
4275fd0b74Schristos 
4375fd0b74Schristos static void print_normal
4475fd0b74Schristos   (CGEN_CPU_DESC, void *, long, unsigned int, bfd_vma, int);
4575fd0b74Schristos static void print_address
4675fd0b74Schristos   (CGEN_CPU_DESC, void *, bfd_vma, unsigned int, bfd_vma, int) ATTRIBUTE_UNUSED;
4775fd0b74Schristos static void print_keyword
4875fd0b74Schristos   (CGEN_CPU_DESC, void *, CGEN_KEYWORD *, long, unsigned int) ATTRIBUTE_UNUSED;
4975fd0b74Schristos static void print_insn_normal
5075fd0b74Schristos   (CGEN_CPU_DESC, void *, const CGEN_INSN *, CGEN_FIELDS *, bfd_vma, int);
5175fd0b74Schristos static int print_insn
5275fd0b74Schristos   (CGEN_CPU_DESC, bfd_vma,  disassemble_info *, bfd_byte *, unsigned);
5375fd0b74Schristos static int default_print_insn
5475fd0b74Schristos   (CGEN_CPU_DESC, bfd_vma, disassemble_info *) ATTRIBUTE_UNUSED;
5575fd0b74Schristos static int read_insn
5675fd0b74Schristos   (CGEN_CPU_DESC, bfd_vma, disassemble_info *, bfd_byte *, int, CGEN_EXTRACT_INFO *,
5775fd0b74Schristos    unsigned long *);
5875fd0b74Schristos 
5975fd0b74Schristos /* -- disassembler routines inserted here.  */
6075fd0b74Schristos 
6175fd0b74Schristos /* -- dis.c */
6275fd0b74Schristos 
6375fd0b74Schristos #include "elf/mep.h"
6475fd0b74Schristos #include "elf-bfd.h"
6575fd0b74Schristos 
6675fd0b74Schristos #define CGEN_VALIDATE_INSN_SUPPORTED
6775fd0b74Schristos 
6875fd0b74Schristos 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*e992f068Schristos print_tpreg (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED, void *dis_info,
7075fd0b74Schristos 	     CGEN_KEYWORD *table ATTRIBUTE_UNUSED, long val ATTRIBUTE_UNUSED,
7175fd0b74Schristos 	     unsigned int flags ATTRIBUTE_UNUSED)
7275fd0b74Schristos {
7375fd0b74Schristos   disassemble_info *info = (disassemble_info *) dis_info;
7475fd0b74Schristos 
7575fd0b74Schristos   (*info->fprintf_func) (info->stream, "$tp");
7675fd0b74Schristos }
7775fd0b74Schristos 
7875fd0b74Schristos 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*e992f068Schristos print_spreg (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED, void *dis_info,
8075fd0b74Schristos 	     CGEN_KEYWORD *table ATTRIBUTE_UNUSED, long val ATTRIBUTE_UNUSED,
8175fd0b74Schristos 	     unsigned int flags ATTRIBUTE_UNUSED)
8275fd0b74Schristos {
8375fd0b74Schristos   disassemble_info *info = (disassemble_info *) dis_info;
8475fd0b74Schristos 
8575fd0b74Schristos   (*info->fprintf_func) (info->stream, "$sp");
8675fd0b74Schristos }
8775fd0b74Schristos 
8875fd0b74Schristos /* begin-cop-ip-print-handlers */
8975fd0b74Schristos static void
9075fd0b74Schristos print_ivc2_cr (CGEN_CPU_DESC,
9175fd0b74Schristos 	void *,
9275fd0b74Schristos 	CGEN_KEYWORD *,
9375fd0b74Schristos 	long,
9475fd0b74Schristos 	unsigned int) ATTRIBUTE_UNUSED;
9575fd0b74Schristos static void
print_ivc2_cr(CGEN_CPU_DESC cd,void * dis_info,CGEN_KEYWORD * keyword_table ATTRIBUTE_UNUSED,long value,unsigned int attrs)9675fd0b74Schristos print_ivc2_cr (CGEN_CPU_DESC cd,
9775fd0b74Schristos 	void *dis_info,
9875fd0b74Schristos 	CGEN_KEYWORD *keyword_table ATTRIBUTE_UNUSED,
9975fd0b74Schristos 	long value,
10075fd0b74Schristos 	unsigned int attrs)
10175fd0b74Schristos {
10275fd0b74Schristos   print_keyword (cd, dis_info, & mep_cgen_opval_h_cr_ivc2, value, attrs);
10375fd0b74Schristos }
10475fd0b74Schristos static void
10575fd0b74Schristos print_ivc2_ccr (CGEN_CPU_DESC,
10675fd0b74Schristos 	void *,
10775fd0b74Schristos 	CGEN_KEYWORD *,
10875fd0b74Schristos 	long,
10975fd0b74Schristos 	unsigned int) ATTRIBUTE_UNUSED;
11075fd0b74Schristos static void
print_ivc2_ccr(CGEN_CPU_DESC cd,void * dis_info,CGEN_KEYWORD * keyword_table ATTRIBUTE_UNUSED,long value,unsigned int attrs)11175fd0b74Schristos print_ivc2_ccr (CGEN_CPU_DESC cd,
11275fd0b74Schristos 	void *dis_info,
11375fd0b74Schristos 	CGEN_KEYWORD *keyword_table ATTRIBUTE_UNUSED,
11475fd0b74Schristos 	long value,
11575fd0b74Schristos 	unsigned int attrs)
11675fd0b74Schristos {
11775fd0b74Schristos   print_keyword (cd, dis_info, & mep_cgen_opval_h_ccr_ivc2, value, attrs);
11875fd0b74Schristos }
11975fd0b74Schristos /* end-cop-ip-print-handlers */
12075fd0b74Schristos 
12175fd0b74Schristos /************************************************************\
12275fd0b74Schristos *********************** Experimental *************************
12375fd0b74Schristos \************************************************************/
12475fd0b74Schristos 
12575fd0b74Schristos #undef  CGEN_PRINT_INSN
12675fd0b74Schristos #define CGEN_PRINT_INSN mep_print_insn
12775fd0b74Schristos 
12875fd0b74Schristos 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)12975fd0b74Schristos mep_print_vliw_insns (CGEN_CPU_DESC cd, bfd_vma pc, disassemble_info *info,
13075fd0b74Schristos 		      bfd_byte *buf, int corelength, int copro1length,
13175fd0b74Schristos 		      int copro2length ATTRIBUTE_UNUSED)
13275fd0b74Schristos {
13375fd0b74Schristos   int i;
13475fd0b74Schristos   int status = 0;
13575fd0b74Schristos   /* char insnbuf[CGEN_MAX_INSN_SIZE]; */
13675fd0b74Schristos   bfd_byte insnbuf[64];
13775fd0b74Schristos 
13875fd0b74Schristos   /* If corelength > 0 then there is a core insn present. It
13975fd0b74Schristos      will be at the beginning of the buffer.  After printing
14075fd0b74Schristos      the core insn, we need to print the + on the next line.  */
14175fd0b74Schristos   if (corelength > 0)
14275fd0b74Schristos     {
14375fd0b74Schristos       int my_status = 0;
14475fd0b74Schristos 
14575fd0b74Schristos       for (i = 0; i < corelength; i++ )
14675fd0b74Schristos 	insnbuf[i] = buf[i];
14775fd0b74Schristos       cd->isas = & MEP_CORE_ISA;
14875fd0b74Schristos 
14975fd0b74Schristos       my_status = print_insn (cd, pc, info, insnbuf, corelength);
15075fd0b74Schristos       if (my_status != corelength)
15175fd0b74Schristos 	{
15275fd0b74Schristos 	  (*info->fprintf_func) (info->stream, UNKNOWN_INSN_MSG);
15375fd0b74Schristos 	  my_status = corelength;
15475fd0b74Schristos 	}
15575fd0b74Schristos       status += my_status;
15675fd0b74Schristos 
15775fd0b74Schristos       /* Print the + to indicate that the following copro insn is   */
15875fd0b74Schristos       /* part of a vliw group.                                      */
15975fd0b74Schristos       if (copro1length > 0)
16075fd0b74Schristos 	(*info->fprintf_func) (info->stream, " + ");
16175fd0b74Schristos     }
16275fd0b74Schristos 
16375fd0b74Schristos   /* Now all that is left to be processed is the coprocessor insns
16475fd0b74Schristos      In vliw mode, there will always be one.  Its positioning will
16575fd0b74Schristos      be from byte corelength to byte corelength+copro1length -1.
16675fd0b74Schristos      No need to check for existence.   Also, the first vliw insn,
16775fd0b74Schristos      will, as spec'd, always be at least as long as the core insn
16875fd0b74Schristos      so we don't need to flush the buffer.  */
16975fd0b74Schristos   if (copro1length > 0)
17075fd0b74Schristos     {
17175fd0b74Schristos       int my_status = 0;
17275fd0b74Schristos 
17375fd0b74Schristos       for (i = corelength; i < corelength + copro1length; i++ )
17475fd0b74Schristos 	insnbuf[i - corelength] = buf[i];
17575fd0b74Schristos 
17675fd0b74Schristos       switch (copro1length)
17775fd0b74Schristos 	{
17875fd0b74Schristos 	case 0:
17975fd0b74Schristos 	  break;
18075fd0b74Schristos 	case 2:
18175fd0b74Schristos 	  cd->isas = & MEP_COP16_ISA;
18275fd0b74Schristos 	  break;
18375fd0b74Schristos 	case 4:
18475fd0b74Schristos 	  cd->isas = & MEP_COP32_ISA;
18575fd0b74Schristos 	  break;
18675fd0b74Schristos 	case 6:
18775fd0b74Schristos 	  cd->isas = & MEP_COP48_ISA;
18875fd0b74Schristos 	  break;
18975fd0b74Schristos 	case 8:
19075fd0b74Schristos 	  cd->isas = & MEP_COP64_ISA;
19175fd0b74Schristos 	  break;
19275fd0b74Schristos 	default:
19375fd0b74Schristos 	  /* Shouldn't be anything but 16,32,48,64.  */
19475fd0b74Schristos 	  break;
19575fd0b74Schristos 	}
19675fd0b74Schristos 
19775fd0b74Schristos       my_status = print_insn (cd, pc, info, insnbuf, copro1length);
19875fd0b74Schristos 
19975fd0b74Schristos       if (my_status != copro1length)
20075fd0b74Schristos 	{
20175fd0b74Schristos 	  (*info->fprintf_func) (info->stream, UNKNOWN_INSN_MSG);
20275fd0b74Schristos 	  my_status = copro1length;
20375fd0b74Schristos 	}
20475fd0b74Schristos       status += my_status;
20575fd0b74Schristos     }
20675fd0b74Schristos 
20775fd0b74Schristos #if 0
20875fd0b74Schristos   /* Now we need to process the second copro insn if it exists. We
20975fd0b74Schristos      have no guarantee that the second copro insn will be longer
21075fd0b74Schristos      than the first, so we have to flush the buffer if we are have
21175fd0b74Schristos      a second copro insn to process.  If present, this insn will
21275fd0b74Schristos      be in the position from byte corelength+copro1length to byte
21375fd0b74Schristos      corelength+copro1length+copro2length-1 (which better equal 8
21475fd0b74Schristos      or else we're in big trouble.  */
21575fd0b74Schristos   if (copro2length > 0)
21675fd0b74Schristos     {
21775fd0b74Schristos       int my_status = 0;
21875fd0b74Schristos 
21975fd0b74Schristos       for (i = 0; i < 64 ; i++)
22075fd0b74Schristos 	insnbuf[i] = 0;
22175fd0b74Schristos 
22275fd0b74Schristos       for (i = corelength + copro1length; i < 64; i++)
22375fd0b74Schristos 	insnbuf[i - (corelength + copro1length)] = buf[i];
22475fd0b74Schristos 
22575fd0b74Schristos       switch (copro2length)
22675fd0b74Schristos 	{
22775fd0b74Schristos 	case 2:
22875fd0b74Schristos 	  cd->isas = 1 << ISA_EXT_COP1_16;
22975fd0b74Schristos 	  break;
23075fd0b74Schristos 	case 4:
23175fd0b74Schristos 	  cd->isas = 1 << ISA_EXT_COP1_32;
23275fd0b74Schristos 	  break;
23375fd0b74Schristos 	case 6:
23475fd0b74Schristos 	  cd->isas = 1 << ISA_EXT_COP1_48;
23575fd0b74Schristos 	  break;
23675fd0b74Schristos 	case 8:
23775fd0b74Schristos 	  cd->isas = 1 << ISA_EXT_COP1_64;
23875fd0b74Schristos 	  break;
23975fd0b74Schristos 	default:
24075fd0b74Schristos 	  /* Shouldn't be anything but 16,32,48,64.  */
24175fd0b74Schristos 	  break;
24275fd0b74Schristos 	}
24375fd0b74Schristos 
24475fd0b74Schristos       my_status = print_insn (cd, pc, info, insnbuf, copro2length);
24575fd0b74Schristos 
24675fd0b74Schristos       if (my_status != copro2length)
24775fd0b74Schristos 	{
24875fd0b74Schristos 	  (*info->fprintf_func) (info->stream, UNKNOWN_INSN_MSG);
24975fd0b74Schristos 	  my_status = copro2length;
25075fd0b74Schristos 	}
25175fd0b74Schristos 
25275fd0b74Schristos       status += my_status;
25375fd0b74Schristos     }
25475fd0b74Schristos #endif
25575fd0b74Schristos 
25675fd0b74Schristos   /* Status should now be the number of bytes that were printed
25775fd0b74Schristos      which should be 4 for VLIW32 mode and 64 for VLIW64 mode.  */
25875fd0b74Schristos 
25975fd0b74Schristos   if ((!MEP_VLIW64 && (status != 4)) || (MEP_VLIW64 && (status != 8)))
26075fd0b74Schristos     return -1;
26175fd0b74Schristos   else
26275fd0b74Schristos     return status;
26375fd0b74Schristos }
26475fd0b74Schristos 
26575fd0b74Schristos /* The two functions mep_examine_vliw[32,64]_insns are used find out
26675fd0b74Schristos    which vliw combinaion (16 bit core with 48 bit copro, 32 bit core
26775fd0b74Schristos    with 32 bit copro, etc.) is present.  Later on, when internally
26875fd0b74Schristos    parallel coprocessors are handled, only these functions should
26975fd0b74Schristos    need to be changed.
27075fd0b74Schristos 
27175fd0b74Schristos    At this time only the following combinations are supported:
27275fd0b74Schristos 
27375fd0b74Schristos    VLIW32 Mode:
27475fd0b74Schristos    16 bit core insn (core) and 16 bit coprocessor insn (cop1)
27575fd0b74Schristos    32 bit core insn (core)
27675fd0b74Schristos    32 bit coprocessor insn (cop1)
27775fd0b74Schristos    Note: As of this time, I do not believe we have enough information
27875fd0b74Schristos          to distinguish a 32 bit core insn from a 32 bit cop insn. Also,
27975fd0b74Schristos          no 16 bit coprocessor insns have been specified.
28075fd0b74Schristos 
28175fd0b74Schristos    VLIW64 Mode:
28275fd0b74Schristos    16 bit core insn (core) and 48 bit coprocessor insn (cop1)
28375fd0b74Schristos    32 bit core insn (core) and 32 bit coprocessor insn (cop1)
28475fd0b74Schristos    64 bit coprocessor insn (cop1)
28575fd0b74Schristos 
28675fd0b74Schristos    The framework for an internally parallel coprocessor is also
28775fd0b74Schristos    present (2nd coprocessor insn is cop2), but at this time it
28875fd0b74Schristos    is not used.  This only appears to be valid in VLIW64 mode.  */
28975fd0b74Schristos 
29075fd0b74Schristos static int
mep_examine_vliw32_insns(CGEN_CPU_DESC cd,bfd_vma pc,disassemble_info * info)29175fd0b74Schristos mep_examine_vliw32_insns (CGEN_CPU_DESC cd, bfd_vma pc, disassemble_info *info)
29275fd0b74Schristos {
29375fd0b74Schristos   int status;
29475fd0b74Schristos   int buflength;
29575fd0b74Schristos   int corebuflength;
29675fd0b74Schristos   int cop1buflength;
29775fd0b74Schristos   int cop2buflength;
29875fd0b74Schristos   bfd_byte buf[CGEN_MAX_INSN_SIZE];
29975fd0b74Schristos   char indicator16[1];
30075fd0b74Schristos   char indicatorcop32[2];
30175fd0b74Schristos 
30275fd0b74Schristos   /* At this time we're not supporting internally parallel coprocessors,
30375fd0b74Schristos      so cop2buflength will always be 0.  */
30475fd0b74Schristos   cop2buflength = 0;
30575fd0b74Schristos 
30675fd0b74Schristos   /* Read in 32 bits.  */
30775fd0b74Schristos   buflength = 4; /* VLIW insn spans 4 bytes.  */
30875fd0b74Schristos   status = (*info->read_memory_func) (pc, buf, buflength, info);
30975fd0b74Schristos 
31075fd0b74Schristos   if (status != 0)
31175fd0b74Schristos     {
31275fd0b74Schristos       (*info->memory_error_func) (status, pc, info);
31375fd0b74Schristos       return -1;
31475fd0b74Schristos     }
31575fd0b74Schristos 
31675fd0b74Schristos   /* Put the big endian representation of the bytes to be examined
31775fd0b74Schristos      in the temporary buffers for examination.  */
31875fd0b74Schristos 
31975fd0b74Schristos   if (info->endian == BFD_ENDIAN_BIG)
32075fd0b74Schristos     {
32175fd0b74Schristos       indicator16[0] = buf[0];
32275fd0b74Schristos       indicatorcop32[0] = buf[0];
32375fd0b74Schristos       indicatorcop32[1] = buf[1];
32475fd0b74Schristos     }
32575fd0b74Schristos   else
32675fd0b74Schristos     {
32775fd0b74Schristos       indicator16[0] = buf[1];
32875fd0b74Schristos       indicatorcop32[0] = buf[1];
32975fd0b74Schristos       indicatorcop32[1] = buf[0];
33075fd0b74Schristos     }
33175fd0b74Schristos 
33275fd0b74Schristos   /* If the two high order bits are 00, 01 or 10, we have a 16 bit
33375fd0b74Schristos      core insn and a 48 bit copro insn.  */
33475fd0b74Schristos 
33575fd0b74Schristos   if ((indicator16[0] & 0x80) && (indicator16[0] & 0x40))
33675fd0b74Schristos     {
33775fd0b74Schristos       if ((indicatorcop32[0] & 0xf0) == 0xf0 && (indicatorcop32[1] & 0x07) == 0x07)
33875fd0b74Schristos 	{
33975fd0b74Schristos           /* We have a 32 bit copro insn.  */
34075fd0b74Schristos           corebuflength = 0;
34175fd0b74Schristos 	  /* All 4 4ytes are one copro insn. */
34275fd0b74Schristos           cop1buflength = 4;
34375fd0b74Schristos 	}
34475fd0b74Schristos       else
34575fd0b74Schristos 	{
34675fd0b74Schristos           /* We have a 32 bit core.  */
34775fd0b74Schristos           corebuflength = 4;
34875fd0b74Schristos           cop1buflength = 0;
34975fd0b74Schristos 	}
35075fd0b74Schristos     }
35175fd0b74Schristos   else
35275fd0b74Schristos     {
35375fd0b74Schristos       /* We have a 16 bit core insn and a 16 bit copro insn.  */
35475fd0b74Schristos       corebuflength = 2;
35575fd0b74Schristos       cop1buflength = 2;
35675fd0b74Schristos     }
35775fd0b74Schristos 
35875fd0b74Schristos   /* Now we have the distrubution set.  Print them out.  */
35975fd0b74Schristos   status = mep_print_vliw_insns (cd, pc, info, buf, corebuflength,
36075fd0b74Schristos 				 cop1buflength, cop2buflength);
36175fd0b74Schristos 
36275fd0b74Schristos   return status;
36375fd0b74Schristos }
36475fd0b74Schristos 
36575fd0b74Schristos static int
mep_examine_vliw64_insns(CGEN_CPU_DESC cd,bfd_vma pc,disassemble_info * info)36675fd0b74Schristos mep_examine_vliw64_insns (CGEN_CPU_DESC cd, bfd_vma pc, disassemble_info *info)
36775fd0b74Schristos {
36875fd0b74Schristos   int status;
36975fd0b74Schristos   int buflength;
37075fd0b74Schristos   int corebuflength;
37175fd0b74Schristos   int cop1buflength;
37275fd0b74Schristos   int cop2buflength;
37375fd0b74Schristos   bfd_byte buf[CGEN_MAX_INSN_SIZE];
37475fd0b74Schristos   char indicator16[1];
37575fd0b74Schristos   char indicator64[4];
37675fd0b74Schristos 
37775fd0b74Schristos   /* At this time we're not supporting internally parallel
37875fd0b74Schristos      coprocessors, so cop2buflength will always be 0.  */
37975fd0b74Schristos   cop2buflength = 0;
38075fd0b74Schristos 
38175fd0b74Schristos   /* Read in 64 bits.  */
38275fd0b74Schristos   buflength = 8; /* VLIW insn spans 8 bytes.  */
38375fd0b74Schristos   status = (*info->read_memory_func) (pc, buf, buflength, info);
38475fd0b74Schristos 
38575fd0b74Schristos   if (status != 0)
38675fd0b74Schristos     {
38775fd0b74Schristos       (*info->memory_error_func) (status, pc, info);
38875fd0b74Schristos       return -1;
38975fd0b74Schristos     }
39075fd0b74Schristos 
39175fd0b74Schristos   /* We have all 64 bits in the buffer now.  We have to figure out
39275fd0b74Schristos      what combination of instruction sizes are present.  The two
39375fd0b74Schristos      high order bits will indicate whether or not we have a 16 bit
39475fd0b74Schristos      core insn or not.  If not, then we have to look at the 7,8th
39575fd0b74Schristos      bytes to tell whether we have 64 bit copro insn or a 32 bit
39675fd0b74Schristos      core insn with a 32 bit copro insn.  Endianness will make a
39775fd0b74Schristos      difference here.  */
39875fd0b74Schristos 
39975fd0b74Schristos   /* Put the big endian representation of the bytes to be examined
40075fd0b74Schristos      in the temporary buffers for examination.  */
40175fd0b74Schristos 
40275fd0b74Schristos   /* indicator16[0] = buf[0];  */
40375fd0b74Schristos   if (info->endian == BFD_ENDIAN_BIG)
40475fd0b74Schristos     {
40575fd0b74Schristos       indicator16[0] = buf[0];
40675fd0b74Schristos       indicator64[0] = buf[0];
40775fd0b74Schristos       indicator64[1] = buf[1];
40875fd0b74Schristos       indicator64[2] = buf[2];
40975fd0b74Schristos       indicator64[3] = buf[3];
41075fd0b74Schristos     }
41175fd0b74Schristos   else
41275fd0b74Schristos     {
41375fd0b74Schristos       indicator16[0] = buf[1];
41475fd0b74Schristos       indicator64[0] = buf[1];
41575fd0b74Schristos       indicator64[1] = buf[0];
41675fd0b74Schristos       indicator64[2] = buf[3];
41775fd0b74Schristos       indicator64[3] = buf[2];
41875fd0b74Schristos     }
41975fd0b74Schristos 
42075fd0b74Schristos   /* If the two high order bits are 00, 01 or 10, we have a 16 bit
42175fd0b74Schristos      core insn and a 48 bit copro insn.  */
42275fd0b74Schristos 
42375fd0b74Schristos   if ((indicator16[0] & 0x80) && (indicator16[0] & 0x40))
42475fd0b74Schristos     {
42575fd0b74Schristos       if ((indicator64[0] & 0xf0) == 0xf0 && (indicator64[1] & 0x07) == 0x07
42675fd0b74Schristos 	  && ((indicator64[2] & 0xfe) != 0xf0 || (indicator64[3] & 0xf4) != 0))
42775fd0b74Schristos 	{
42875fd0b74Schristos           /* We have a 64 bit copro insn.  */
42975fd0b74Schristos           corebuflength = 0;
43075fd0b74Schristos 	  /* All 8 bytes are one copro insn.  */
43175fd0b74Schristos           cop1buflength = 8;
43275fd0b74Schristos 	}
43375fd0b74Schristos       else
43475fd0b74Schristos 	{
43575fd0b74Schristos           /* We have a 32 bit core insn and a 32 bit copro insn.  */
43675fd0b74Schristos           corebuflength = 4;
43775fd0b74Schristos           cop1buflength = 4;
43875fd0b74Schristos 	}
43975fd0b74Schristos     }
44075fd0b74Schristos   else
44175fd0b74Schristos     {
44275fd0b74Schristos       /* We have a 16 bit core insn and a 48 bit copro insn.  */
44375fd0b74Schristos       corebuflength = 2;
44475fd0b74Schristos       cop1buflength = 6;
44575fd0b74Schristos     }
44675fd0b74Schristos 
44775fd0b74Schristos   /* Now we have the distrubution set.  Print them out. */
44875fd0b74Schristos   status = mep_print_vliw_insns (cd, pc, info, buf, corebuflength,
44975fd0b74Schristos 				 cop1buflength, cop2buflength);
45075fd0b74Schristos 
45175fd0b74Schristos   return status;
45275fd0b74Schristos }
45375fd0b74Schristos 
45475fd0b74Schristos #ifdef MEP_IVC2_SUPPORTED
45575fd0b74Schristos 
45675fd0b74Schristos static int
print_slot_insn(CGEN_CPU_DESC cd,bfd_vma pc,disassemble_info * info,SLOTS_ATTR slot,bfd_byte * buf)45775fd0b74Schristos print_slot_insn (CGEN_CPU_DESC cd,
45875fd0b74Schristos 		 bfd_vma pc,
45975fd0b74Schristos 		 disassemble_info *info,
46075fd0b74Schristos 		 SLOTS_ATTR slot,
46175fd0b74Schristos 		 bfd_byte *buf)
46275fd0b74Schristos {
46375fd0b74Schristos   const CGEN_INSN_LIST *insn_list;
46475fd0b74Schristos   CGEN_INSN_INT insn_value;
46575fd0b74Schristos   CGEN_EXTRACT_INFO ex_info;
46675fd0b74Schristos 
467*e992f068Schristos   insn_value = cgen_get_insn_value (cd, buf, 32, cd->insn_endian);
46875fd0b74Schristos 
46975fd0b74Schristos   /* Fill in ex_info fields like read_insn would.  Don't actually call
47075fd0b74Schristos      read_insn, since the incoming buffer is already read (and possibly
47175fd0b74Schristos      modified a la m32r).  */
47275fd0b74Schristos   ex_info.valid = (1 << 8) - 1;
47375fd0b74Schristos   ex_info.dis_info = info;
47475fd0b74Schristos   ex_info.insn_bytes = buf;
47575fd0b74Schristos 
47675fd0b74Schristos   /* The instructions are stored in hash lists.
47775fd0b74Schristos      Pick the first one and keep trying until we find the right one.  */
47875fd0b74Schristos 
47975fd0b74Schristos   insn_list = CGEN_DIS_LOOKUP_INSN (cd, (char *) buf, insn_value);
48075fd0b74Schristos   while (insn_list != NULL)
48175fd0b74Schristos     {
48275fd0b74Schristos       const CGEN_INSN *insn = insn_list->insn;
48375fd0b74Schristos       CGEN_FIELDS fields;
48475fd0b74Schristos       int length;
48575fd0b74Schristos 
48675fd0b74Schristos       if ((CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_CONFIG)
48775fd0b74Schristos 	   && CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_CONFIG) != MEP_CONFIG)
48875fd0b74Schristos 	  || ! (CGEN_ATTR_CGEN_INSN_SLOTS_VALUE (CGEN_INSN_ATTRS (insn)) & (1 << slot)))
48975fd0b74Schristos         {
49075fd0b74Schristos           insn_list = CGEN_DIS_NEXT_INSN (insn_list);
49175fd0b74Schristos 	  continue;
49275fd0b74Schristos         }
49375fd0b74Schristos 
49475fd0b74Schristos       if ((insn_value & CGEN_INSN_BASE_MASK (insn))
49575fd0b74Schristos 	  == CGEN_INSN_BASE_VALUE (insn))
49675fd0b74Schristos 	{
49775fd0b74Schristos 	  /* Printing is handled in two passes.  The first pass parses the
49875fd0b74Schristos 	     machine insn and extracts the fields.  The second pass prints
49975fd0b74Schristos 	     them.  */
50075fd0b74Schristos 
50175fd0b74Schristos 	  length = CGEN_EXTRACT_FN (cd, insn)
50275fd0b74Schristos 	    (cd, insn, &ex_info, insn_value, &fields, pc);
50375fd0b74Schristos 
50475fd0b74Schristos 	  /* Length < 0 -> error.  */
50575fd0b74Schristos 	  if (length < 0)
50675fd0b74Schristos 	    return length;
50775fd0b74Schristos 	  if (length > 0)
50875fd0b74Schristos 	    {
50975fd0b74Schristos 	      CGEN_PRINT_FN (cd, insn) (cd, info, insn, &fields, pc, length);
51075fd0b74Schristos 	      /* Length is in bits, result is in bytes.  */
51175fd0b74Schristos 	      return length / 8;
51275fd0b74Schristos 	    }
51375fd0b74Schristos 	}
51475fd0b74Schristos 
51575fd0b74Schristos       insn_list = CGEN_DIS_NEXT_INSN (insn_list);
51675fd0b74Schristos     }
51775fd0b74Schristos 
51875fd0b74Schristos   if (slot == SLOTS_P0S)
51975fd0b74Schristos     (*info->fprintf_func) (info->stream, "*unknown-p0s*");
52075fd0b74Schristos   else if (slot == SLOTS_P0)
52175fd0b74Schristos     (*info->fprintf_func) (info->stream, "*unknown-p0*");
52275fd0b74Schristos   else if (slot == SLOTS_P1)
52375fd0b74Schristos     (*info->fprintf_func) (info->stream, "*unknown-p1*");
52475fd0b74Schristos   else if (slot == SLOTS_C3)
52575fd0b74Schristos     (*info->fprintf_func) (info->stream, "*unknown-c3*");
52675fd0b74Schristos   return 0;
52775fd0b74Schristos }
52875fd0b74Schristos 
52975fd0b74Schristos static int
mep_examine_ivc2_insns(CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,bfd_vma pc ATTRIBUTE_UNUSED,disassemble_info * info ATTRIBUTE_UNUSED)53075fd0b74Schristos mep_examine_ivc2_insns (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED, bfd_vma pc ATTRIBUTE_UNUSED, disassemble_info *info ATTRIBUTE_UNUSED)
53175fd0b74Schristos {
53275fd0b74Schristos   int status;
53375fd0b74Schristos   int buflength;
53475fd0b74Schristos   bfd_byte buf[8];
53575fd0b74Schristos   bfd_byte insn[8];
53675fd0b74Schristos   int e;
53775fd0b74Schristos 
53875fd0b74Schristos   /* Read in 64 bits.  */
53975fd0b74Schristos   buflength = 8; /* VLIW insn spans 8 bytes.  */
54075fd0b74Schristos   status = (*info->read_memory_func) (pc, buf, buflength, info);
54175fd0b74Schristos 
54275fd0b74Schristos   if (status != 0)
54375fd0b74Schristos     {
54475fd0b74Schristos       (*info->memory_error_func) (status, pc, info);
54575fd0b74Schristos       return -1;
54675fd0b74Schristos     }
54775fd0b74Schristos 
54875fd0b74Schristos   if (info->endian == BFD_ENDIAN_LITTLE)
54975fd0b74Schristos     e = 1;
55075fd0b74Schristos   else
55175fd0b74Schristos     e = 0;
55275fd0b74Schristos 
55375fd0b74Schristos   if (((unsigned char)buf[0^e] & 0xf0) < 0xc0)
55475fd0b74Schristos     {
55575fd0b74Schristos       /*      <--00--><--11--><--22--><--33--><--44--><--55--><--66--><--77--> */
55675fd0b74Schristos       /* V1   [-----core-----][--------p0s-------][------------p1------------] */
55775fd0b74Schristos 
55875fd0b74Schristos       print_insn (cd, pc, info, buf, 2);
55975fd0b74Schristos 
56075fd0b74Schristos       insn[0^e] = 0;
56175fd0b74Schristos       insn[1^e] = buf[2^e];
56275fd0b74Schristos       insn[2^e] = buf[3^e];
56375fd0b74Schristos       insn[3^e] = buf[4^e] & 0xf0;
56475fd0b74Schristos       (*info->fprintf_func) (info->stream, " + ");
56575fd0b74Schristos       print_slot_insn (cd, pc, info, SLOTS_P0S, insn);
56675fd0b74Schristos 
56775fd0b74Schristos       insn[0^e] = buf[4^e] << 4 | buf[5^e] >> 4;
56875fd0b74Schristos       insn[1^e] = buf[5^e] << 4 | buf[6^e] >> 4;
56975fd0b74Schristos       insn[2^e] = buf[6^e] << 4 | buf[7^e] >> 4;
57075fd0b74Schristos       insn[3^e] = buf[7^e] << 4;
57175fd0b74Schristos       (*info->fprintf_func) (info->stream, " + ");
57275fd0b74Schristos       print_slot_insn (cd, pc, info, SLOTS_P1, insn);
57375fd0b74Schristos     }
57475fd0b74Schristos   else if ((buf[0^e] & 0xf0) == 0xf0 && (buf[1^e] & 0x0f) == 0x07)
57575fd0b74Schristos     {
57675fd0b74Schristos       /*      <--00--><--11--><--22--><--33--><--44--><--55--><--66--><--77--> */
57775fd0b74Schristos       /* V3   1111[--p0--]0111[--------p0--------][------------p1------------] */
57875fd0b74Schristos       /*                                          00000000111111112222222233333333 */
57975fd0b74Schristos 
58075fd0b74Schristos       insn[0^e] = buf[0^e] << 4 | buf[1^e] >> 4;
58175fd0b74Schristos       insn[1^e] = buf[2^e];
58275fd0b74Schristos       insn[2^e] = buf[3^e];
58375fd0b74Schristos       insn[3^e] = buf[4^e] & 0xf0;
58475fd0b74Schristos       print_slot_insn (cd, pc, info, SLOTS_P0, insn);
58575fd0b74Schristos 
58675fd0b74Schristos       insn[0^e] = buf[4^e] << 4 | buf[5^e] >> 4;
58775fd0b74Schristos       insn[1^e] = buf[5^e] << 4 | buf[6^e] >> 4;
58875fd0b74Schristos       insn[2^e] = buf[6^e] << 4 | buf[7^e] >> 4;
58975fd0b74Schristos       insn[3^e] = buf[7^e] << 4;
59075fd0b74Schristos       (*info->fprintf_func) (info->stream, " + ");
59175fd0b74Schristos       print_slot_insn (cd, pc, info, SLOTS_P1, insn);
59275fd0b74Schristos     }
59375fd0b74Schristos   else
59475fd0b74Schristos     {
59575fd0b74Schristos       /*      <--00--><--11--><--22--><--33--><--44--><--55--><--66--><--77--> */
59675fd0b74Schristos       /* V2   [-------------core-------------]xxxx[------------p1------------] */
59775fd0b74Schristos       print_insn (cd, pc, info, buf, 4);
59875fd0b74Schristos 
59975fd0b74Schristos       insn[0^e] = buf[4^e] << 4 | buf[5^e] >> 4;
60075fd0b74Schristos       insn[1^e] = buf[5^e] << 4 | buf[6^e] >> 4;
60175fd0b74Schristos       insn[2^e] = buf[6^e] << 4 | buf[7^e] >> 4;
60275fd0b74Schristos       insn[3^e] = buf[7^e] << 4;
60375fd0b74Schristos       (*info->fprintf_func) (info->stream, " + ");
60475fd0b74Schristos       print_slot_insn (cd, pc, info, SLOTS_P1, insn);
60575fd0b74Schristos     }
60675fd0b74Schristos 
60775fd0b74Schristos   return 8;
60875fd0b74Schristos }
60975fd0b74Schristos 
61075fd0b74Schristos #endif /* MEP_IVC2_SUPPORTED */
61175fd0b74Schristos 
61275fd0b74Schristos /* This is a hack.  SID calls this to update the disassembler as the
61375fd0b74Schristos    CPU changes modes.  */
61475fd0b74Schristos static int mep_ivc2_disassemble_p = 0;
61575fd0b74Schristos static int mep_ivc2_vliw_disassemble_p = 0;
61675fd0b74Schristos 
61775fd0b74Schristos void
61875fd0b74Schristos mep_print_insn_set_ivc2_mode (int ivc2_p, int vliw_p, int cfg_idx);
61975fd0b74Schristos void
mep_print_insn_set_ivc2_mode(int ivc2_p,int vliw_p,int cfg_idx)62075fd0b74Schristos mep_print_insn_set_ivc2_mode (int ivc2_p, int vliw_p, int cfg_idx)
62175fd0b74Schristos {
62275fd0b74Schristos   mep_ivc2_disassemble_p = ivc2_p;
62375fd0b74Schristos   mep_ivc2_vliw_disassemble_p = vliw_p;
62475fd0b74Schristos   mep_config_index = cfg_idx;
62575fd0b74Schristos }
62675fd0b74Schristos 
62775fd0b74Schristos static int
mep_print_insn(CGEN_CPU_DESC cd,bfd_vma pc,disassemble_info * info)62875fd0b74Schristos mep_print_insn (CGEN_CPU_DESC cd, bfd_vma pc, disassemble_info *info)
62975fd0b74Schristos {
63075fd0b74Schristos   int status;
63175fd0b74Schristos   int cop_type;
63275fd0b74Schristos   int ivc2 = 0;
63375fd0b74Schristos   static CGEN_ATTR_VALUE_BITSET_TYPE *ivc2_core_isa = NULL;
63475fd0b74Schristos 
63575fd0b74Schristos   if (ivc2_core_isa == NULL)
63675fd0b74Schristos     {
63775fd0b74Schristos       /* IVC2 has some core-only coprocessor instructions.  We
63875fd0b74Schristos 	 use COP32 to flag those, and COP64 for the VLIW ones,
63975fd0b74Schristos 	 since they have the same names.  */
64075fd0b74Schristos       ivc2_core_isa = cgen_bitset_create (MAX_ISAS);
64175fd0b74Schristos     }
64275fd0b74Schristos 
64375fd0b74Schristos   /* Extract and adapt to configuration number, if available. */
64475fd0b74Schristos   if (info->section && info->section->owner)
64575fd0b74Schristos     {
64675fd0b74Schristos       bfd *abfd = info->section->owner;
647*e992f068Schristos       if (bfd_get_flavour (abfd) == bfd_target_elf_flavour)
648*e992f068Schristos 	{
64975fd0b74Schristos 	  mep_config_index = abfd->tdata.elf_obj_data->elf_header->e_flags & EF_MEP_INDEX_MASK;
65075fd0b74Schristos 	  /* This instantly redefines MEP_CONFIG, MEP_OMASK, .... MEP_VLIW64 */
65175fd0b74Schristos 
65275fd0b74Schristos 	  cop_type = abfd->tdata.elf_obj_data->elf_header->e_flags & EF_MEP_COP_MASK;
65375fd0b74Schristos 	  if (cop_type == EF_MEP_COP_IVC2)
65475fd0b74Schristos 	    ivc2 = 1;
65575fd0b74Schristos 	}
656*e992f068Schristos     }
65775fd0b74Schristos 
65875fd0b74Schristos   /* Picking the right ISA bitmask for the current context is tricky.  */
65975fd0b74Schristos   if (info->section)
66075fd0b74Schristos     {
66175fd0b74Schristos       if (info->section->flags & SEC_MEP_VLIW)
66275fd0b74Schristos 	{
66375fd0b74Schristos #ifdef MEP_IVC2_SUPPORTED
66475fd0b74Schristos 	  if (ivc2)
66575fd0b74Schristos 	    {
66675fd0b74Schristos 	      /* ivc2 has its own way of selecting its functions.  */
66775fd0b74Schristos 	      cd->isas = & MEP_CORE_ISA;
66875fd0b74Schristos 	      status = mep_examine_ivc2_insns (cd, pc, info);
66975fd0b74Schristos 	    }
67075fd0b74Schristos 	  else
67175fd0b74Schristos #endif
67275fd0b74Schristos 	    /* Are we in 32 or 64 bit vliw mode?  */
67375fd0b74Schristos 	    if (MEP_VLIW64)
67475fd0b74Schristos 	      status = mep_examine_vliw64_insns (cd, pc, info);
67575fd0b74Schristos 	    else
67675fd0b74Schristos 	      status = mep_examine_vliw32_insns (cd, pc, info);
67775fd0b74Schristos 	  /* Both the above branches set their own isa bitmasks.  */
67875fd0b74Schristos 	}
67975fd0b74Schristos       else
68075fd0b74Schristos 	{
68175fd0b74Schristos 	  if (ivc2)
68275fd0b74Schristos 	    {
68375fd0b74Schristos 	      cgen_bitset_clear (ivc2_core_isa);
68475fd0b74Schristos 	      cgen_bitset_union (ivc2_core_isa, &MEP_CORE_ISA, ivc2_core_isa);
68575fd0b74Schristos 	      cgen_bitset_union (ivc2_core_isa, &MEP_COP32_ISA, ivc2_core_isa);
68675fd0b74Schristos 	      cd->isas = ivc2_core_isa;
68775fd0b74Schristos 	    }
68875fd0b74Schristos 	  else
68975fd0b74Schristos 	    cd->isas = & MEP_CORE_ISA;
69075fd0b74Schristos 	  status = default_print_insn (cd, pc, info);
69175fd0b74Schristos 	}
69275fd0b74Schristos     }
69375fd0b74Schristos   else /* sid or gdb */
69475fd0b74Schristos     {
69575fd0b74Schristos #ifdef MEP_IVC2_SUPPORTED
69675fd0b74Schristos       if (mep_ivc2_disassemble_p)
69775fd0b74Schristos 	{
69875fd0b74Schristos 	  if (mep_ivc2_vliw_disassemble_p)
69975fd0b74Schristos 	    {
70075fd0b74Schristos 	      cd->isas = & MEP_CORE_ISA;
70175fd0b74Schristos 	      status = mep_examine_ivc2_insns (cd, pc, info);
70275fd0b74Schristos 	      return status;
70375fd0b74Schristos 	    }
70475fd0b74Schristos 	  else
70575fd0b74Schristos 	    {
70675fd0b74Schristos 	      if (ivc2)
70775fd0b74Schristos 		cd->isas = ivc2_core_isa;
70875fd0b74Schristos 	    }
70975fd0b74Schristos 	}
71075fd0b74Schristos #endif
71175fd0b74Schristos 
71275fd0b74Schristos       status = default_print_insn (cd, pc, info);
71375fd0b74Schristos     }
71475fd0b74Schristos 
71575fd0b74Schristos   return status;
71675fd0b74Schristos }
71775fd0b74Schristos 
71875fd0b74Schristos 
71975fd0b74Schristos /* -- opc.c */
72075fd0b74Schristos 
72175fd0b74Schristos void mep_cgen_print_operand
722*e992f068Schristos   (CGEN_CPU_DESC, int, void *, CGEN_FIELDS *, void const *, bfd_vma, int);
72375fd0b74Schristos 
72475fd0b74Schristos /* Main entry point for printing operands.
72575fd0b74Schristos    XINFO is a `void *' and not a `disassemble_info *' to not put a requirement
72675fd0b74Schristos    of dis-asm.h on cgen.h.
72775fd0b74Schristos 
72875fd0b74Schristos    This function is basically just a big switch statement.  Earlier versions
72975fd0b74Schristos    used tables to look up the function to use, but
73075fd0b74Schristos    - if the table contains both assembler and disassembler functions then
73175fd0b74Schristos      the disassembler contains much of the assembler and vice-versa,
73275fd0b74Schristos    - there's a lot of inlining possibilities as things grow,
73375fd0b74Schristos    - using a switch statement avoids the function call overhead.
73475fd0b74Schristos 
73575fd0b74Schristos    This function could be moved into `print_insn_normal', but keeping it
73675fd0b74Schristos    separate makes clear the interface between `print_insn_normal' and each of
73775fd0b74Schristos    the handlers.  */
73875fd0b74Schristos 
73975fd0b74Schristos 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)74075fd0b74Schristos mep_cgen_print_operand (CGEN_CPU_DESC cd,
74175fd0b74Schristos 			   int opindex,
74275fd0b74Schristos 			   void * xinfo,
74375fd0b74Schristos 			   CGEN_FIELDS *fields,
74475fd0b74Schristos 			   void const *attrs ATTRIBUTE_UNUSED,
74575fd0b74Schristos 			   bfd_vma pc,
74675fd0b74Schristos 			   int length)
74775fd0b74Schristos {
74875fd0b74Schristos   disassemble_info *info = (disassemble_info *) xinfo;
74975fd0b74Schristos 
75075fd0b74Schristos   switch (opindex)
75175fd0b74Schristos     {
75275fd0b74Schristos     case MEP_OPERAND_ADDR24A4 :
75375fd0b74Schristos       print_normal (cd, info, fields->f_24u8a4n, 0|(1<<CGEN_OPERAND_VIRTUAL), pc, length);
75475fd0b74Schristos       break;
75575fd0b74Schristos     case MEP_OPERAND_C5RMUIMM20 :
75675fd0b74Schristos       print_normal (cd, info, fields->f_c5_rmuimm20, 0|(1<<CGEN_OPERAND_VIRTUAL), pc, length);
75775fd0b74Schristos       break;
75875fd0b74Schristos     case MEP_OPERAND_C5RNMUIMM24 :
75975fd0b74Schristos       print_normal (cd, info, fields->f_c5_rnmuimm24, 0|(1<<CGEN_OPERAND_VIRTUAL), pc, length);
76075fd0b74Schristos       break;
76175fd0b74Schristos     case MEP_OPERAND_CALLNUM :
76275fd0b74Schristos       print_normal (cd, info, fields->f_callnum, 0|(1<<CGEN_OPERAND_VIRTUAL), pc, length);
76375fd0b74Schristos       break;
76475fd0b74Schristos     case MEP_OPERAND_CCCC :
76575fd0b74Schristos       print_normal (cd, info, fields->f_rm, 0, pc, length);
76675fd0b74Schristos       break;
76775fd0b74Schristos     case MEP_OPERAND_CCRN :
76875fd0b74Schristos       print_keyword (cd, info, & mep_cgen_opval_h_ccr, fields->f_ccrn, 0|(1<<CGEN_OPERAND_VIRTUAL));
76975fd0b74Schristos       break;
77075fd0b74Schristos     case MEP_OPERAND_CDISP10 :
77175fd0b74Schristos       print_normal (cd, info, fields->f_cdisp10, 0|(1<<CGEN_OPERAND_SIGNED), pc, length);
77275fd0b74Schristos       break;
77375fd0b74Schristos     case MEP_OPERAND_CDISP10A2 :
77475fd0b74Schristos       print_normal (cd, info, fields->f_cdisp10, 0|(1<<CGEN_OPERAND_SIGNED), pc, length);
77575fd0b74Schristos       break;
77675fd0b74Schristos     case MEP_OPERAND_CDISP10A4 :
77775fd0b74Schristos       print_normal (cd, info, fields->f_cdisp10, 0|(1<<CGEN_OPERAND_SIGNED), pc, length);
77875fd0b74Schristos       break;
77975fd0b74Schristos     case MEP_OPERAND_CDISP10A8 :
78075fd0b74Schristos       print_normal (cd, info, fields->f_cdisp10, 0|(1<<CGEN_OPERAND_SIGNED), pc, length);
78175fd0b74Schristos       break;
78275fd0b74Schristos     case MEP_OPERAND_CDISP12 :
78375fd0b74Schristos       print_normal (cd, info, fields->f_12s20, 0|(1<<CGEN_OPERAND_SIGNED), pc, length);
78475fd0b74Schristos       break;
78575fd0b74Schristos     case MEP_OPERAND_CIMM4 :
78675fd0b74Schristos       print_normal (cd, info, fields->f_rn, 0, pc, length);
78775fd0b74Schristos       break;
78875fd0b74Schristos     case MEP_OPERAND_CIMM5 :
78975fd0b74Schristos       print_normal (cd, info, fields->f_5u24, 0, pc, length);
79075fd0b74Schristos       break;
79175fd0b74Schristos     case MEP_OPERAND_CODE16 :
79275fd0b74Schristos       print_normal (cd, info, fields->f_16u16, 0, pc, length);
79375fd0b74Schristos       break;
79475fd0b74Schristos     case MEP_OPERAND_CODE24 :
79575fd0b74Schristos       print_normal (cd, info, fields->f_24u4n, 0|(1<<CGEN_OPERAND_VIRTUAL), pc, length);
79675fd0b74Schristos       break;
79775fd0b74Schristos     case MEP_OPERAND_CP_FLAG :
79875fd0b74Schristos       print_keyword (cd, info, & mep_cgen_opval_h_ccr, 0, 0);
79975fd0b74Schristos       break;
80075fd0b74Schristos     case MEP_OPERAND_CRN :
80175fd0b74Schristos       print_keyword (cd, info, & mep_cgen_opval_h_cr, fields->f_crn, 0);
80275fd0b74Schristos       break;
80375fd0b74Schristos     case MEP_OPERAND_CRN64 :
80475fd0b74Schristos       print_keyword (cd, info, & mep_cgen_opval_h_cr64, fields->f_crn, 0);
80575fd0b74Schristos       break;
80675fd0b74Schristos     case MEP_OPERAND_CRNX :
80775fd0b74Schristos       print_keyword (cd, info, & mep_cgen_opval_h_cr, fields->f_crnx, 0|(1<<CGEN_OPERAND_VIRTUAL));
80875fd0b74Schristos       break;
80975fd0b74Schristos     case MEP_OPERAND_CRNX64 :
81075fd0b74Schristos       print_keyword (cd, info, & mep_cgen_opval_h_cr64, fields->f_crnx, 0|(1<<CGEN_OPERAND_VIRTUAL));
81175fd0b74Schristos       break;
81275fd0b74Schristos     case MEP_OPERAND_CROC :
81375fd0b74Schristos       print_keyword (cd, info, & mep_cgen_opval_h_cr64, fields->f_ivc2_5u7, 0);
81475fd0b74Schristos       break;
81575fd0b74Schristos     case MEP_OPERAND_CROP :
81675fd0b74Schristos       print_keyword (cd, info, & mep_cgen_opval_h_cr64, fields->f_ivc2_5u23, 0);
81775fd0b74Schristos       break;
81875fd0b74Schristos     case MEP_OPERAND_CRPC :
81975fd0b74Schristos       print_keyword (cd, info, & mep_cgen_opval_h_cr64, fields->f_ivc2_5u26, 0);
82075fd0b74Schristos       break;
82175fd0b74Schristos     case MEP_OPERAND_CRPP :
82275fd0b74Schristos       print_keyword (cd, info, & mep_cgen_opval_h_cr64, fields->f_ivc2_5u18, 0);
82375fd0b74Schristos       break;
82475fd0b74Schristos     case MEP_OPERAND_CRQC :
82575fd0b74Schristos       print_keyword (cd, info, & mep_cgen_opval_h_cr64, fields->f_ivc2_5u21, 0);
82675fd0b74Schristos       break;
82775fd0b74Schristos     case MEP_OPERAND_CRQP :
82875fd0b74Schristos       print_keyword (cd, info, & mep_cgen_opval_h_cr64, fields->f_ivc2_5u13, 0);
82975fd0b74Schristos       break;
83075fd0b74Schristos     case MEP_OPERAND_CSRN :
83175fd0b74Schristos       print_keyword (cd, info, & mep_cgen_opval_h_csr, fields->f_csrn, 0|(1<<CGEN_OPERAND_VIRTUAL));
83275fd0b74Schristos       break;
83375fd0b74Schristos     case MEP_OPERAND_CSRN_IDX :
83475fd0b74Schristos       print_normal (cd, info, fields->f_csrn, 0|(1<<CGEN_OPERAND_VIRTUAL), pc, length);
83575fd0b74Schristos       break;
83675fd0b74Schristos     case MEP_OPERAND_DBG :
83775fd0b74Schristos       print_keyword (cd, info, & mep_cgen_opval_h_csr, 0, 0);
83875fd0b74Schristos       break;
83975fd0b74Schristos     case MEP_OPERAND_DEPC :
84075fd0b74Schristos       print_keyword (cd, info, & mep_cgen_opval_h_csr, 0, 0);
84175fd0b74Schristos       break;
84275fd0b74Schristos     case MEP_OPERAND_EPC :
84375fd0b74Schristos       print_keyword (cd, info, & mep_cgen_opval_h_csr, 0, 0);
84475fd0b74Schristos       break;
84575fd0b74Schristos     case MEP_OPERAND_EXC :
84675fd0b74Schristos       print_keyword (cd, info, & mep_cgen_opval_h_csr, 0, 0);
84775fd0b74Schristos       break;
84875fd0b74Schristos     case MEP_OPERAND_HI :
84975fd0b74Schristos       print_keyword (cd, info, & mep_cgen_opval_h_csr, 0, 0);
85075fd0b74Schristos       break;
85175fd0b74Schristos     case MEP_OPERAND_IMM16P0 :
85275fd0b74Schristos       print_normal (cd, info, fields->f_ivc2_imm16p0, 0|(1<<CGEN_OPERAND_VIRTUAL), pc, length);
85375fd0b74Schristos       break;
85475fd0b74Schristos     case MEP_OPERAND_IMM3P12 :
85575fd0b74Schristos       print_normal (cd, info, fields->f_ivc2_3u12, 0, pc, length);
85675fd0b74Schristos       break;
85775fd0b74Schristos     case MEP_OPERAND_IMM3P25 :
85875fd0b74Schristos       print_normal (cd, info, fields->f_ivc2_3u25, 0, pc, length);
85975fd0b74Schristos       break;
86075fd0b74Schristos     case MEP_OPERAND_IMM3P4 :
86175fd0b74Schristos       print_normal (cd, info, fields->f_ivc2_3u4, 0, pc, length);
86275fd0b74Schristos       break;
86375fd0b74Schristos     case MEP_OPERAND_IMM3P5 :
86475fd0b74Schristos       print_normal (cd, info, fields->f_ivc2_3u5, 0, pc, length);
86575fd0b74Schristos       break;
86675fd0b74Schristos     case MEP_OPERAND_IMM3P9 :
86775fd0b74Schristos       print_normal (cd, info, fields->f_ivc2_3u9, 0, pc, length);
86875fd0b74Schristos       break;
86975fd0b74Schristos     case MEP_OPERAND_IMM4P10 :
87075fd0b74Schristos       print_normal (cd, info, fields->f_ivc2_4u10, 0, pc, length);
87175fd0b74Schristos       break;
87275fd0b74Schristos     case MEP_OPERAND_IMM4P4 :
87375fd0b74Schristos       print_normal (cd, info, fields->f_ivc2_4u4, 0, pc, length);
87475fd0b74Schristos       break;
87575fd0b74Schristos     case MEP_OPERAND_IMM4P8 :
87675fd0b74Schristos       print_normal (cd, info, fields->f_ivc2_4u8, 0, pc, length);
87775fd0b74Schristos       break;
87875fd0b74Schristos     case MEP_OPERAND_IMM5P23 :
87975fd0b74Schristos       print_normal (cd, info, fields->f_ivc2_5u23, 0, pc, length);
88075fd0b74Schristos       break;
88175fd0b74Schristos     case MEP_OPERAND_IMM5P3 :
88275fd0b74Schristos       print_normal (cd, info, fields->f_ivc2_5u3, 0, pc, length);
88375fd0b74Schristos       break;
88475fd0b74Schristos     case MEP_OPERAND_IMM5P7 :
88575fd0b74Schristos       print_normal (cd, info, fields->f_ivc2_5u7, 0, pc, length);
88675fd0b74Schristos       break;
88775fd0b74Schristos     case MEP_OPERAND_IMM5P8 :
88875fd0b74Schristos       print_normal (cd, info, fields->f_ivc2_5u8, 0, pc, length);
88975fd0b74Schristos       break;
89075fd0b74Schristos     case MEP_OPERAND_IMM6P2 :
89175fd0b74Schristos       print_normal (cd, info, fields->f_ivc2_6u2, 0, pc, length);
89275fd0b74Schristos       break;
89375fd0b74Schristos     case MEP_OPERAND_IMM6P6 :
89475fd0b74Schristos       print_normal (cd, info, fields->f_ivc2_6u6, 0, pc, length);
89575fd0b74Schristos       break;
89675fd0b74Schristos     case MEP_OPERAND_IMM8P0 :
89775fd0b74Schristos       print_normal (cd, info, fields->f_ivc2_8u0, 0, pc, length);
89875fd0b74Schristos       break;
89975fd0b74Schristos     case MEP_OPERAND_IMM8P20 :
90075fd0b74Schristos       print_normal (cd, info, fields->f_ivc2_8u20, 0, pc, length);
90175fd0b74Schristos       break;
90275fd0b74Schristos     case MEP_OPERAND_IMM8P4 :
90375fd0b74Schristos       print_normal (cd, info, fields->f_ivc2_8u4, 0, pc, length);
90475fd0b74Schristos       break;
90575fd0b74Schristos     case MEP_OPERAND_IVC_X_0_2 :
90675fd0b74Schristos       print_normal (cd, info, fields->f_ivc2_2u0, 0, pc, length);
90775fd0b74Schristos       break;
90875fd0b74Schristos     case MEP_OPERAND_IVC_X_0_3 :
90975fd0b74Schristos       print_normal (cd, info, fields->f_ivc2_3u0, 0, pc, length);
91075fd0b74Schristos       break;
91175fd0b74Schristos     case MEP_OPERAND_IVC_X_0_4 :
91275fd0b74Schristos       print_normal (cd, info, fields->f_ivc2_4u0, 0, pc, length);
91375fd0b74Schristos       break;
91475fd0b74Schristos     case MEP_OPERAND_IVC_X_0_5 :
91575fd0b74Schristos       print_normal (cd, info, fields->f_ivc2_5u0, 0, pc, length);
91675fd0b74Schristos       break;
91775fd0b74Schristos     case MEP_OPERAND_IVC_X_6_1 :
91875fd0b74Schristos       print_normal (cd, info, fields->f_ivc2_1u6, 0, pc, length);
91975fd0b74Schristos       break;
92075fd0b74Schristos     case MEP_OPERAND_IVC_X_6_2 :
92175fd0b74Schristos       print_normal (cd, info, fields->f_ivc2_2u6, 0, pc, length);
92275fd0b74Schristos       break;
92375fd0b74Schristos     case MEP_OPERAND_IVC_X_6_3 :
92475fd0b74Schristos       print_normal (cd, info, fields->f_ivc2_3u6, 0, pc, length);
92575fd0b74Schristos       break;
92675fd0b74Schristos     case MEP_OPERAND_IVC2_ACC0_0 :
92775fd0b74Schristos       print_keyword (cd, info, & mep_cgen_opval_h_ccr_ivc2, 0, 0);
92875fd0b74Schristos       break;
92975fd0b74Schristos     case MEP_OPERAND_IVC2_ACC0_1 :
93075fd0b74Schristos       print_keyword (cd, info, & mep_cgen_opval_h_ccr_ivc2, 0, 0);
93175fd0b74Schristos       break;
93275fd0b74Schristos     case MEP_OPERAND_IVC2_ACC0_2 :
93375fd0b74Schristos       print_keyword (cd, info, & mep_cgen_opval_h_ccr_ivc2, 0, 0);
93475fd0b74Schristos       break;
93575fd0b74Schristos     case MEP_OPERAND_IVC2_ACC0_3 :
93675fd0b74Schristos       print_keyword (cd, info, & mep_cgen_opval_h_ccr_ivc2, 0, 0);
93775fd0b74Schristos       break;
93875fd0b74Schristos     case MEP_OPERAND_IVC2_ACC0_4 :
93975fd0b74Schristos       print_keyword (cd, info, & mep_cgen_opval_h_ccr_ivc2, 0, 0);
94075fd0b74Schristos       break;
94175fd0b74Schristos     case MEP_OPERAND_IVC2_ACC0_5 :
94275fd0b74Schristos       print_keyword (cd, info, & mep_cgen_opval_h_ccr_ivc2, 0, 0);
94375fd0b74Schristos       break;
94475fd0b74Schristos     case MEP_OPERAND_IVC2_ACC0_6 :
94575fd0b74Schristos       print_keyword (cd, info, & mep_cgen_opval_h_ccr_ivc2, 0, 0);
94675fd0b74Schristos       break;
94775fd0b74Schristos     case MEP_OPERAND_IVC2_ACC0_7 :
94875fd0b74Schristos       print_keyword (cd, info, & mep_cgen_opval_h_ccr_ivc2, 0, 0);
94975fd0b74Schristos       break;
95075fd0b74Schristos     case MEP_OPERAND_IVC2_ACC1_0 :
95175fd0b74Schristos       print_keyword (cd, info, & mep_cgen_opval_h_ccr_ivc2, 0, 0);
95275fd0b74Schristos       break;
95375fd0b74Schristos     case MEP_OPERAND_IVC2_ACC1_1 :
95475fd0b74Schristos       print_keyword (cd, info, & mep_cgen_opval_h_ccr_ivc2, 0, 0);
95575fd0b74Schristos       break;
95675fd0b74Schristos     case MEP_OPERAND_IVC2_ACC1_2 :
95775fd0b74Schristos       print_keyword (cd, info, & mep_cgen_opval_h_ccr_ivc2, 0, 0);
95875fd0b74Schristos       break;
95975fd0b74Schristos     case MEP_OPERAND_IVC2_ACC1_3 :
96075fd0b74Schristos       print_keyword (cd, info, & mep_cgen_opval_h_ccr_ivc2, 0, 0);
96175fd0b74Schristos       break;
96275fd0b74Schristos     case MEP_OPERAND_IVC2_ACC1_4 :
96375fd0b74Schristos       print_keyword (cd, info, & mep_cgen_opval_h_ccr_ivc2, 0, 0);
96475fd0b74Schristos       break;
96575fd0b74Schristos     case MEP_OPERAND_IVC2_ACC1_5 :
96675fd0b74Schristos       print_keyword (cd, info, & mep_cgen_opval_h_ccr_ivc2, 0, 0);
96775fd0b74Schristos       break;
96875fd0b74Schristos     case MEP_OPERAND_IVC2_ACC1_6 :
96975fd0b74Schristos       print_keyword (cd, info, & mep_cgen_opval_h_ccr_ivc2, 0, 0);
97075fd0b74Schristos       break;
97175fd0b74Schristos     case MEP_OPERAND_IVC2_ACC1_7 :
97275fd0b74Schristos       print_keyword (cd, info, & mep_cgen_opval_h_ccr_ivc2, 0, 0);
97375fd0b74Schristos       break;
97475fd0b74Schristos     case MEP_OPERAND_IVC2_CC :
97575fd0b74Schristos       print_keyword (cd, info, & mep_cgen_opval_h_ccr_ivc2, 0, 0);
97675fd0b74Schristos       break;
97775fd0b74Schristos     case MEP_OPERAND_IVC2_COFA0 :
97875fd0b74Schristos       print_keyword (cd, info, & mep_cgen_opval_h_ccr_ivc2, 0, 0);
97975fd0b74Schristos       break;
98075fd0b74Schristos     case MEP_OPERAND_IVC2_COFA1 :
98175fd0b74Schristos       print_keyword (cd, info, & mep_cgen_opval_h_ccr_ivc2, 0, 0);
98275fd0b74Schristos       break;
98375fd0b74Schristos     case MEP_OPERAND_IVC2_COFR0 :
98475fd0b74Schristos       print_keyword (cd, info, & mep_cgen_opval_h_ccr_ivc2, 0, 0);
98575fd0b74Schristos       break;
98675fd0b74Schristos     case MEP_OPERAND_IVC2_COFR1 :
98775fd0b74Schristos       print_keyword (cd, info, & mep_cgen_opval_h_ccr_ivc2, 0, 0);
98875fd0b74Schristos       break;
98975fd0b74Schristos     case MEP_OPERAND_IVC2_CSAR0 :
99075fd0b74Schristos       print_keyword (cd, info, & mep_cgen_opval_h_ccr_ivc2, 0, 0);
99175fd0b74Schristos       break;
99275fd0b74Schristos     case MEP_OPERAND_IVC2_CSAR1 :
99375fd0b74Schristos       print_keyword (cd, info, & mep_cgen_opval_h_ccr_ivc2, 0, 0);
99475fd0b74Schristos       break;
99575fd0b74Schristos     case MEP_OPERAND_IVC2C3CCRN :
99675fd0b74Schristos       print_keyword (cd, info, & mep_cgen_opval_h_ccr_ivc2, fields->f_ivc2_ccrn_c3, 0|(1<<CGEN_OPERAND_VIRTUAL));
99775fd0b74Schristos       break;
99875fd0b74Schristos     case MEP_OPERAND_IVC2CCRN :
99975fd0b74Schristos       print_keyword (cd, info, & mep_cgen_opval_h_ccr_ivc2, fields->f_ivc2_ccrn, 0|(1<<CGEN_OPERAND_VIRTUAL));
100075fd0b74Schristos       break;
100175fd0b74Schristos     case MEP_OPERAND_IVC2CRN :
100275fd0b74Schristos       print_keyword (cd, info, & mep_cgen_opval_h_cr64, fields->f_ivc2_crnx, 0|(1<<CGEN_OPERAND_VIRTUAL));
100375fd0b74Schristos       break;
100475fd0b74Schristos     case MEP_OPERAND_IVC2RM :
100575fd0b74Schristos       print_keyword (cd, info, & mep_cgen_opval_h_gpr, fields->f_ivc2_crm, 0);
100675fd0b74Schristos       break;
100775fd0b74Schristos     case MEP_OPERAND_LO :
100875fd0b74Schristos       print_keyword (cd, info, & mep_cgen_opval_h_csr, 0, 0);
100975fd0b74Schristos       break;
101075fd0b74Schristos     case MEP_OPERAND_LP :
101175fd0b74Schristos       print_keyword (cd, info, & mep_cgen_opval_h_csr, 0, 0);
101275fd0b74Schristos       break;
101375fd0b74Schristos     case MEP_OPERAND_MB0 :
101475fd0b74Schristos       print_keyword (cd, info, & mep_cgen_opval_h_csr, 0, 0);
101575fd0b74Schristos       break;
101675fd0b74Schristos     case MEP_OPERAND_MB1 :
101775fd0b74Schristos       print_keyword (cd, info, & mep_cgen_opval_h_csr, 0, 0);
101875fd0b74Schristos       break;
101975fd0b74Schristos     case MEP_OPERAND_ME0 :
102075fd0b74Schristos       print_keyword (cd, info, & mep_cgen_opval_h_csr, 0, 0);
102175fd0b74Schristos       break;
102275fd0b74Schristos     case MEP_OPERAND_ME1 :
102375fd0b74Schristos       print_keyword (cd, info, & mep_cgen_opval_h_csr, 0, 0);
102475fd0b74Schristos       break;
102575fd0b74Schristos     case MEP_OPERAND_NPC :
102675fd0b74Schristos       print_keyword (cd, info, & mep_cgen_opval_h_csr, 0, 0);
102775fd0b74Schristos       break;
102875fd0b74Schristos     case MEP_OPERAND_OPT :
102975fd0b74Schristos       print_keyword (cd, info, & mep_cgen_opval_h_csr, 0, 0);
103075fd0b74Schristos       break;
103175fd0b74Schristos     case MEP_OPERAND_PCABS24A2 :
103275fd0b74Schristos       print_address (cd, info, fields->f_24u5a2n, 0|(1<<CGEN_OPERAND_ABS_ADDR)|(1<<CGEN_OPERAND_VIRTUAL), pc, length);
103375fd0b74Schristos       break;
103475fd0b74Schristos     case MEP_OPERAND_PCREL12A2 :
103575fd0b74Schristos       print_address (cd, info, fields->f_12s4a2, 0|(1<<CGEN_OPERAND_SIGNED)|(1<<CGEN_OPERAND_RELAX)|(1<<CGEN_OPERAND_PCREL_ADDR), pc, length);
103675fd0b74Schristos       break;
103775fd0b74Schristos     case MEP_OPERAND_PCREL17A2 :
103875fd0b74Schristos       print_address (cd, info, fields->f_17s16a2, 0|(1<<CGEN_OPERAND_SIGNED)|(1<<CGEN_OPERAND_RELAX)|(1<<CGEN_OPERAND_PCREL_ADDR), pc, length);
103975fd0b74Schristos       break;
104075fd0b74Schristos     case MEP_OPERAND_PCREL24A2 :
104175fd0b74Schristos       print_address (cd, info, fields->f_24s5a2n, 0|(1<<CGEN_OPERAND_SIGNED)|(1<<CGEN_OPERAND_PCREL_ADDR)|(1<<CGEN_OPERAND_VIRTUAL), pc, length);
104275fd0b74Schristos       break;
104375fd0b74Schristos     case MEP_OPERAND_PCREL8A2 :
104475fd0b74Schristos       print_address (cd, info, fields->f_8s8a2, 0|(1<<CGEN_OPERAND_SIGNED)|(1<<CGEN_OPERAND_RELAX)|(1<<CGEN_OPERAND_PCREL_ADDR), pc, length);
104575fd0b74Schristos       break;
104675fd0b74Schristos     case MEP_OPERAND_PSW :
104775fd0b74Schristos       print_keyword (cd, info, & mep_cgen_opval_h_csr, 0, 0);
104875fd0b74Schristos       break;
104975fd0b74Schristos     case MEP_OPERAND_R0 :
105075fd0b74Schristos       print_keyword (cd, info, & mep_cgen_opval_h_gpr, 0, 0);
105175fd0b74Schristos       break;
105275fd0b74Schristos     case MEP_OPERAND_R1 :
105375fd0b74Schristos       print_keyword (cd, info, & mep_cgen_opval_h_gpr, 0, 0);
105475fd0b74Schristos       break;
105575fd0b74Schristos     case MEP_OPERAND_RL :
105675fd0b74Schristos       print_keyword (cd, info, & mep_cgen_opval_h_gpr, fields->f_rl, 0);
105775fd0b74Schristos       break;
105875fd0b74Schristos     case MEP_OPERAND_RL5 :
105975fd0b74Schristos       print_keyword (cd, info, & mep_cgen_opval_h_gpr, fields->f_rl5, 0);
106075fd0b74Schristos       break;
106175fd0b74Schristos     case MEP_OPERAND_RM :
106275fd0b74Schristos       print_keyword (cd, info, & mep_cgen_opval_h_gpr, fields->f_rm, 0);
106375fd0b74Schristos       break;
106475fd0b74Schristos     case MEP_OPERAND_RMA :
106575fd0b74Schristos       print_keyword (cd, info, & mep_cgen_opval_h_gpr, fields->f_rm, 0);
106675fd0b74Schristos       break;
106775fd0b74Schristos     case MEP_OPERAND_RN :
106875fd0b74Schristos       print_keyword (cd, info, & mep_cgen_opval_h_gpr, fields->f_rn, 0);
106975fd0b74Schristos       break;
107075fd0b74Schristos     case MEP_OPERAND_RN3 :
107175fd0b74Schristos       print_keyword (cd, info, & mep_cgen_opval_h_gpr, fields->f_rn3, 0);
107275fd0b74Schristos       break;
107375fd0b74Schristos     case MEP_OPERAND_RN3C :
107475fd0b74Schristos       print_keyword (cd, info, & mep_cgen_opval_h_gpr, fields->f_rn3, 0);
107575fd0b74Schristos       break;
107675fd0b74Schristos     case MEP_OPERAND_RN3L :
107775fd0b74Schristos       print_keyword (cd, info, & mep_cgen_opval_h_gpr, fields->f_rn3, 0);
107875fd0b74Schristos       break;
107975fd0b74Schristos     case MEP_OPERAND_RN3S :
108075fd0b74Schristos       print_keyword (cd, info, & mep_cgen_opval_h_gpr, fields->f_rn3, 0);
108175fd0b74Schristos       break;
108275fd0b74Schristos     case MEP_OPERAND_RN3UC :
108375fd0b74Schristos       print_keyword (cd, info, & mep_cgen_opval_h_gpr, fields->f_rn3, 0);
108475fd0b74Schristos       break;
108575fd0b74Schristos     case MEP_OPERAND_RN3UL :
108675fd0b74Schristos       print_keyword (cd, info, & mep_cgen_opval_h_gpr, fields->f_rn3, 0);
108775fd0b74Schristos       break;
108875fd0b74Schristos     case MEP_OPERAND_RN3US :
108975fd0b74Schristos       print_keyword (cd, info, & mep_cgen_opval_h_gpr, fields->f_rn3, 0);
109075fd0b74Schristos       break;
109175fd0b74Schristos     case MEP_OPERAND_RNC :
109275fd0b74Schristos       print_keyword (cd, info, & mep_cgen_opval_h_gpr, fields->f_rn, 0);
109375fd0b74Schristos       break;
109475fd0b74Schristos     case MEP_OPERAND_RNL :
109575fd0b74Schristos       print_keyword (cd, info, & mep_cgen_opval_h_gpr, fields->f_rn, 0);
109675fd0b74Schristos       break;
109775fd0b74Schristos     case MEP_OPERAND_RNS :
109875fd0b74Schristos       print_keyword (cd, info, & mep_cgen_opval_h_gpr, fields->f_rn, 0);
109975fd0b74Schristos       break;
110075fd0b74Schristos     case MEP_OPERAND_RNUC :
110175fd0b74Schristos       print_keyword (cd, info, & mep_cgen_opval_h_gpr, fields->f_rn, 0);
110275fd0b74Schristos       break;
110375fd0b74Schristos     case MEP_OPERAND_RNUL :
110475fd0b74Schristos       print_keyword (cd, info, & mep_cgen_opval_h_gpr, fields->f_rn, 0);
110575fd0b74Schristos       break;
110675fd0b74Schristos     case MEP_OPERAND_RNUS :
110775fd0b74Schristos       print_keyword (cd, info, & mep_cgen_opval_h_gpr, fields->f_rn, 0);
110875fd0b74Schristos       break;
110975fd0b74Schristos     case MEP_OPERAND_SAR :
111075fd0b74Schristos       print_keyword (cd, info, & mep_cgen_opval_h_csr, 0, 0);
111175fd0b74Schristos       break;
111275fd0b74Schristos     case MEP_OPERAND_SDISP16 :
111375fd0b74Schristos       print_normal (cd, info, fields->f_16s16, 0|(1<<CGEN_OPERAND_SIGNED), pc, length);
111475fd0b74Schristos       break;
111575fd0b74Schristos     case MEP_OPERAND_SIMM16 :
111675fd0b74Schristos       print_normal (cd, info, fields->f_16s16, 0|(1<<CGEN_OPERAND_SIGNED), pc, length);
111775fd0b74Schristos       break;
111875fd0b74Schristos     case MEP_OPERAND_SIMM16P0 :
111975fd0b74Schristos       print_normal (cd, info, fields->f_ivc2_simm16p0, 0|(1<<CGEN_OPERAND_SIGNED)|(1<<CGEN_OPERAND_VIRTUAL), pc, length);
112075fd0b74Schristos       break;
112175fd0b74Schristos     case MEP_OPERAND_SIMM6 :
112275fd0b74Schristos       print_normal (cd, info, fields->f_6s8, 0|(1<<CGEN_OPERAND_SIGNED), pc, length);
112375fd0b74Schristos       break;
112475fd0b74Schristos     case MEP_OPERAND_SIMM8 :
112575fd0b74Schristos       print_normal (cd, info, fields->f_8s8, 0|(1<<CGEN_OPERAND_SIGNED)|(1<<CGEN_OPERAND_RELOC_IMPLIES_OVERFLOW), pc, length);
112675fd0b74Schristos       break;
112775fd0b74Schristos     case MEP_OPERAND_SIMM8P0 :
112875fd0b74Schristos       print_normal (cd, info, fields->f_ivc2_8s0, 0|(1<<CGEN_OPERAND_SIGNED), pc, length);
112975fd0b74Schristos       break;
113075fd0b74Schristos     case MEP_OPERAND_SIMM8P20 :
113175fd0b74Schristos       print_normal (cd, info, fields->f_ivc2_8s20, 0|(1<<CGEN_OPERAND_SIGNED), pc, length);
113275fd0b74Schristos       break;
113375fd0b74Schristos     case MEP_OPERAND_SIMM8P4 :
113475fd0b74Schristos       print_normal (cd, info, fields->f_ivc2_8s4, 0|(1<<CGEN_OPERAND_SIGNED), pc, length);
113575fd0b74Schristos       break;
113675fd0b74Schristos     case MEP_OPERAND_SP :
113775fd0b74Schristos       print_keyword (cd, info, & mep_cgen_opval_h_gpr, 0, 0);
113875fd0b74Schristos       break;
113975fd0b74Schristos     case MEP_OPERAND_SPR :
114075fd0b74Schristos       print_spreg (cd, info, & mep_cgen_opval_h_gpr, 0, 0);
114175fd0b74Schristos       break;
114275fd0b74Schristos     case MEP_OPERAND_TP :
114375fd0b74Schristos       print_keyword (cd, info, & mep_cgen_opval_h_gpr, 0, 0);
114475fd0b74Schristos       break;
114575fd0b74Schristos     case MEP_OPERAND_TPR :
114675fd0b74Schristos       print_tpreg (cd, info, & mep_cgen_opval_h_gpr, 0, 0);
114775fd0b74Schristos       break;
114875fd0b74Schristos     case MEP_OPERAND_UDISP2 :
114975fd0b74Schristos       print_normal (cd, info, fields->f_2u6, 0|(1<<CGEN_OPERAND_SIGNED), pc, length);
115075fd0b74Schristos       break;
115175fd0b74Schristos     case MEP_OPERAND_UDISP7 :
115275fd0b74Schristos       print_normal (cd, info, fields->f_7u9, 0, pc, length);
115375fd0b74Schristos       break;
115475fd0b74Schristos     case MEP_OPERAND_UDISP7A2 :
115575fd0b74Schristos       print_normal (cd, info, fields->f_7u9a2, 0, pc, length);
115675fd0b74Schristos       break;
115775fd0b74Schristos     case MEP_OPERAND_UDISP7A4 :
115875fd0b74Schristos       print_normal (cd, info, fields->f_7u9a4, 0, pc, length);
115975fd0b74Schristos       break;
116075fd0b74Schristos     case MEP_OPERAND_UIMM16 :
116175fd0b74Schristos       print_normal (cd, info, fields->f_16u16, 0, pc, length);
116275fd0b74Schristos       break;
116375fd0b74Schristos     case MEP_OPERAND_UIMM2 :
116475fd0b74Schristos       print_normal (cd, info, fields->f_2u10, 0, pc, length);
116575fd0b74Schristos       break;
116675fd0b74Schristos     case MEP_OPERAND_UIMM24 :
116775fd0b74Schristos       print_normal (cd, info, fields->f_24u8n, 0|(1<<CGEN_OPERAND_VIRTUAL), pc, length);
116875fd0b74Schristos       break;
116975fd0b74Schristos     case MEP_OPERAND_UIMM3 :
117075fd0b74Schristos       print_normal (cd, info, fields->f_3u5, 0, pc, length);
117175fd0b74Schristos       break;
117275fd0b74Schristos     case MEP_OPERAND_UIMM4 :
117375fd0b74Schristos       print_normal (cd, info, fields->f_4u8, 0, pc, length);
117475fd0b74Schristos       break;
117575fd0b74Schristos     case MEP_OPERAND_UIMM5 :
117675fd0b74Schristos       print_normal (cd, info, fields->f_5u8, 0, pc, length);
117775fd0b74Schristos       break;
117875fd0b74Schristos     case MEP_OPERAND_UIMM7A4 :
117975fd0b74Schristos       print_normal (cd, info, fields->f_7u9a4, 0, pc, length);
118075fd0b74Schristos       break;
118175fd0b74Schristos     case MEP_OPERAND_ZERO :
118275fd0b74Schristos       print_normal (cd, info, 0, 0|(1<<CGEN_OPERAND_SIGNED), pc, length);
118375fd0b74Schristos       break;
118475fd0b74Schristos 
118575fd0b74Schristos     default :
118675fd0b74Schristos       /* xgettext:c-format */
1187ede78133Schristos       opcodes_error_handler
1188ede78133Schristos 	(_("internal error: unrecognized field %d while printing insn"),
118975fd0b74Schristos 	 opindex);
119075fd0b74Schristos       abort ();
119175fd0b74Schristos   }
119275fd0b74Schristos }
119375fd0b74Schristos 
119475fd0b74Schristos cgen_print_fn * const mep_cgen_print_handlers[] =
119575fd0b74Schristos {
119675fd0b74Schristos   print_insn_normal,
119775fd0b74Schristos };
119875fd0b74Schristos 
119975fd0b74Schristos 
120075fd0b74Schristos void
mep_cgen_init_dis(CGEN_CPU_DESC cd)120175fd0b74Schristos mep_cgen_init_dis (CGEN_CPU_DESC cd)
120275fd0b74Schristos {
120375fd0b74Schristos   mep_cgen_init_opcode_table (cd);
120475fd0b74Schristos   mep_cgen_init_ibld_table (cd);
120575fd0b74Schristos   cd->print_handlers = & mep_cgen_print_handlers[0];
120675fd0b74Schristos   cd->print_operand = mep_cgen_print_operand;
120775fd0b74Schristos }
120875fd0b74Schristos 
120975fd0b74Schristos 
121075fd0b74Schristos /* Default print handler.  */
121175fd0b74Schristos 
121275fd0b74Schristos 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)121375fd0b74Schristos print_normal (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
121475fd0b74Schristos 	      void *dis_info,
121575fd0b74Schristos 	      long value,
121675fd0b74Schristos 	      unsigned int attrs,
121775fd0b74Schristos 	      bfd_vma pc ATTRIBUTE_UNUSED,
121875fd0b74Schristos 	      int length ATTRIBUTE_UNUSED)
121975fd0b74Schristos {
122075fd0b74Schristos   disassemble_info *info = (disassemble_info *) dis_info;
122175fd0b74Schristos 
122275fd0b74Schristos   /* Print the operand as directed by the attributes.  */
122375fd0b74Schristos   if (CGEN_BOOL_ATTR (attrs, CGEN_OPERAND_SEM_ONLY))
122475fd0b74Schristos     ; /* nothing to do */
122575fd0b74Schristos   else if (CGEN_BOOL_ATTR (attrs, CGEN_OPERAND_SIGNED))
122675fd0b74Schristos     (*info->fprintf_func) (info->stream, "%ld", value);
122775fd0b74Schristos   else
122875fd0b74Schristos     (*info->fprintf_func) (info->stream, "0x%lx", value);
122975fd0b74Schristos }
123075fd0b74Schristos 
123175fd0b74Schristos /* Default address handler.  */
123275fd0b74Schristos 
123375fd0b74Schristos 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)123475fd0b74Schristos print_address (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
123575fd0b74Schristos 	       void *dis_info,
123675fd0b74Schristos 	       bfd_vma value,
123775fd0b74Schristos 	       unsigned int attrs,
123875fd0b74Schristos 	       bfd_vma pc ATTRIBUTE_UNUSED,
123975fd0b74Schristos 	       int length ATTRIBUTE_UNUSED)
124075fd0b74Schristos {
124175fd0b74Schristos   disassemble_info *info = (disassemble_info *) dis_info;
124275fd0b74Schristos 
124375fd0b74Schristos   /* Print the operand as directed by the attributes.  */
124475fd0b74Schristos   if (CGEN_BOOL_ATTR (attrs, CGEN_OPERAND_SEM_ONLY))
124575fd0b74Schristos     ; /* Nothing to do.  */
124675fd0b74Schristos   else if (CGEN_BOOL_ATTR (attrs, CGEN_OPERAND_PCREL_ADDR))
124775fd0b74Schristos     (*info->print_address_func) (value, info);
124875fd0b74Schristos   else if (CGEN_BOOL_ATTR (attrs, CGEN_OPERAND_ABS_ADDR))
124975fd0b74Schristos     (*info->print_address_func) (value, info);
125075fd0b74Schristos   else if (CGEN_BOOL_ATTR (attrs, CGEN_OPERAND_SIGNED))
125175fd0b74Schristos     (*info->fprintf_func) (info->stream, "%ld", (long) value);
125275fd0b74Schristos   else
125375fd0b74Schristos     (*info->fprintf_func) (info->stream, "0x%lx", (long) value);
125475fd0b74Schristos }
125575fd0b74Schristos 
125675fd0b74Schristos /* Keyword print handler.  */
125775fd0b74Schristos 
125875fd0b74Schristos static void
print_keyword(CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,void * dis_info,CGEN_KEYWORD * keyword_table,long value,unsigned int attrs ATTRIBUTE_UNUSED)125975fd0b74Schristos print_keyword (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
126075fd0b74Schristos 	       void *dis_info,
126175fd0b74Schristos 	       CGEN_KEYWORD *keyword_table,
126275fd0b74Schristos 	       long value,
126375fd0b74Schristos 	       unsigned int attrs ATTRIBUTE_UNUSED)
126475fd0b74Schristos {
126575fd0b74Schristos   disassemble_info *info = (disassemble_info *) dis_info;
126675fd0b74Schristos   const CGEN_KEYWORD_ENTRY *ke;
126775fd0b74Schristos 
126875fd0b74Schristos   ke = cgen_keyword_lookup_value (keyword_table, value);
126975fd0b74Schristos   if (ke != NULL)
127075fd0b74Schristos     (*info->fprintf_func) (info->stream, "%s", ke->name);
127175fd0b74Schristos   else
127275fd0b74Schristos     (*info->fprintf_func) (info->stream, "???");
127375fd0b74Schristos }
127475fd0b74Schristos 
127575fd0b74Schristos /* Default insn printer.
127675fd0b74Schristos 
127775fd0b74Schristos    DIS_INFO is defined as `void *' so the disassembler needn't know anything
127875fd0b74Schristos    about disassemble_info.  */
127975fd0b74Schristos 
128075fd0b74Schristos static void
print_insn_normal(CGEN_CPU_DESC cd,void * dis_info,const CGEN_INSN * insn,CGEN_FIELDS * fields,bfd_vma pc,int length)128175fd0b74Schristos print_insn_normal (CGEN_CPU_DESC cd,
128275fd0b74Schristos 		   void *dis_info,
128375fd0b74Schristos 		   const CGEN_INSN *insn,
128475fd0b74Schristos 		   CGEN_FIELDS *fields,
128575fd0b74Schristos 		   bfd_vma pc,
128675fd0b74Schristos 		   int length)
128775fd0b74Schristos {
128875fd0b74Schristos   const CGEN_SYNTAX *syntax = CGEN_INSN_SYNTAX (insn);
128975fd0b74Schristos   disassemble_info *info = (disassemble_info *) dis_info;
129075fd0b74Schristos   const CGEN_SYNTAX_CHAR_TYPE *syn;
129175fd0b74Schristos 
129275fd0b74Schristos   CGEN_INIT_PRINT (cd);
129375fd0b74Schristos 
129475fd0b74Schristos   for (syn = CGEN_SYNTAX_STRING (syntax); *syn; ++syn)
129575fd0b74Schristos     {
129675fd0b74Schristos       if (CGEN_SYNTAX_MNEMONIC_P (*syn))
129775fd0b74Schristos 	{
129875fd0b74Schristos 	  (*info->fprintf_func) (info->stream, "%s", CGEN_INSN_MNEMONIC (insn));
129975fd0b74Schristos 	  continue;
130075fd0b74Schristos 	}
130175fd0b74Schristos       if (CGEN_SYNTAX_CHAR_P (*syn))
130275fd0b74Schristos 	{
130375fd0b74Schristos 	  (*info->fprintf_func) (info->stream, "%c", CGEN_SYNTAX_CHAR (*syn));
130475fd0b74Schristos 	  continue;
130575fd0b74Schristos 	}
130675fd0b74Schristos 
130775fd0b74Schristos       /* We have an operand.  */
130875fd0b74Schristos       mep_cgen_print_operand (cd, CGEN_SYNTAX_FIELD (*syn), info,
130975fd0b74Schristos 				 fields, CGEN_INSN_ATTRS (insn), pc, length);
131075fd0b74Schristos     }
131175fd0b74Schristos }
131275fd0b74Schristos 
131375fd0b74Schristos /* Subroutine of print_insn. Reads an insn into the given buffers and updates
131475fd0b74Schristos    the extract info.
131575fd0b74Schristos    Returns 0 if all is well, non-zero otherwise.  */
131675fd0b74Schristos 
131775fd0b74Schristos 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)131875fd0b74Schristos read_insn (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
131975fd0b74Schristos 	   bfd_vma pc,
132075fd0b74Schristos 	   disassemble_info *info,
132175fd0b74Schristos 	   bfd_byte *buf,
132275fd0b74Schristos 	   int buflen,
132375fd0b74Schristos 	   CGEN_EXTRACT_INFO *ex_info,
132475fd0b74Schristos 	   unsigned long *insn_value)
132575fd0b74Schristos {
132675fd0b74Schristos   int status = (*info->read_memory_func) (pc, buf, buflen, info);
132775fd0b74Schristos 
132875fd0b74Schristos   if (status != 0)
132975fd0b74Schristos     {
133075fd0b74Schristos       (*info->memory_error_func) (status, pc, info);
133175fd0b74Schristos       return -1;
133275fd0b74Schristos     }
133375fd0b74Schristos 
133475fd0b74Schristos   ex_info->dis_info = info;
133575fd0b74Schristos   ex_info->valid = (1 << buflen) - 1;
133675fd0b74Schristos   ex_info->insn_bytes = buf;
133775fd0b74Schristos 
133875fd0b74Schristos   *insn_value = bfd_get_bits (buf, buflen * 8, info->endian == BFD_ENDIAN_BIG);
133975fd0b74Schristos   return 0;
134075fd0b74Schristos }
134175fd0b74Schristos 
134275fd0b74Schristos /* Utility to print an insn.
134375fd0b74Schristos    BUF is the base part of the insn, target byte order, BUFLEN bytes long.
134475fd0b74Schristos    The result is the size of the insn in bytes or zero for an unknown insn
134575fd0b74Schristos    or -1 if an error occurs fetching data (memory_error_func will have
134675fd0b74Schristos    been called).  */
134775fd0b74Schristos 
134875fd0b74Schristos static int
print_insn(CGEN_CPU_DESC cd,bfd_vma pc,disassemble_info * info,bfd_byte * buf,unsigned int buflen)134975fd0b74Schristos print_insn (CGEN_CPU_DESC cd,
135075fd0b74Schristos 	    bfd_vma pc,
135175fd0b74Schristos 	    disassemble_info *info,
135275fd0b74Schristos 	    bfd_byte *buf,
135375fd0b74Schristos 	    unsigned int buflen)
135475fd0b74Schristos {
135575fd0b74Schristos   CGEN_INSN_INT insn_value;
135675fd0b74Schristos   const CGEN_INSN_LIST *insn_list;
135775fd0b74Schristos   CGEN_EXTRACT_INFO ex_info;
135875fd0b74Schristos   int basesize;
135975fd0b74Schristos 
136075fd0b74Schristos   /* Extract base part of instruction, just in case CGEN_DIS_* uses it. */
136175fd0b74Schristos   basesize = cd->base_insn_bitsize < buflen * 8 ?
136275fd0b74Schristos                                      cd->base_insn_bitsize : buflen * 8;
1363*e992f068Schristos   insn_value = cgen_get_insn_value (cd, buf, basesize, cd->insn_endian);
136475fd0b74Schristos 
136575fd0b74Schristos 
136675fd0b74Schristos   /* Fill in ex_info fields like read_insn would.  Don't actually call
136775fd0b74Schristos      read_insn, since the incoming buffer is already read (and possibly
136875fd0b74Schristos      modified a la m32r).  */
136975fd0b74Schristos   ex_info.valid = (1 << buflen) - 1;
137075fd0b74Schristos   ex_info.dis_info = info;
137175fd0b74Schristos   ex_info.insn_bytes = buf;
137275fd0b74Schristos 
137375fd0b74Schristos   /* The instructions are stored in hash lists.
137475fd0b74Schristos      Pick the first one and keep trying until we find the right one.  */
137575fd0b74Schristos 
137675fd0b74Schristos   insn_list = CGEN_DIS_LOOKUP_INSN (cd, (char *) buf, insn_value);
137775fd0b74Schristos   while (insn_list != NULL)
137875fd0b74Schristos     {
137975fd0b74Schristos       const CGEN_INSN *insn = insn_list->insn;
138075fd0b74Schristos       CGEN_FIELDS fields;
138175fd0b74Schristos       int length;
138275fd0b74Schristos       unsigned long insn_value_cropped;
138375fd0b74Schristos 
138475fd0b74Schristos #ifdef CGEN_VALIDATE_INSN_SUPPORTED
138575fd0b74Schristos       /* Not needed as insn shouldn't be in hash lists if not supported.  */
138675fd0b74Schristos       /* Supported by this cpu?  */
138775fd0b74Schristos       if (! mep_cgen_insn_supported (cd, insn))
138875fd0b74Schristos         {
138975fd0b74Schristos           insn_list = CGEN_DIS_NEXT_INSN (insn_list);
139075fd0b74Schristos 	  continue;
139175fd0b74Schristos         }
139275fd0b74Schristos #endif
139375fd0b74Schristos 
139475fd0b74Schristos       /* Basic bit mask must be correct.  */
139575fd0b74Schristos       /* ??? May wish to allow target to defer this check until the extract
139675fd0b74Schristos 	 handler.  */
139775fd0b74Schristos 
139875fd0b74Schristos       /* Base size may exceed this instruction's size.  Extract the
139975fd0b74Schristos          relevant part from the buffer. */
140075fd0b74Schristos       if ((unsigned) (CGEN_INSN_BITSIZE (insn) / 8) < buflen &&
140175fd0b74Schristos 	  (unsigned) (CGEN_INSN_BITSIZE (insn) / 8) <= sizeof (unsigned long))
140275fd0b74Schristos 	insn_value_cropped = bfd_get_bits (buf, CGEN_INSN_BITSIZE (insn),
140375fd0b74Schristos 					   info->endian == BFD_ENDIAN_BIG);
140475fd0b74Schristos       else
140575fd0b74Schristos 	insn_value_cropped = insn_value;
140675fd0b74Schristos 
140775fd0b74Schristos       if ((insn_value_cropped & CGEN_INSN_BASE_MASK (insn))
140875fd0b74Schristos 	  == CGEN_INSN_BASE_VALUE (insn))
140975fd0b74Schristos 	{
141075fd0b74Schristos 	  /* Printing is handled in two passes.  The first pass parses the
141175fd0b74Schristos 	     machine insn and extracts the fields.  The second pass prints
141275fd0b74Schristos 	     them.  */
141375fd0b74Schristos 
141475fd0b74Schristos 	  /* Make sure the entire insn is loaded into insn_value, if it
141575fd0b74Schristos 	     can fit.  */
141675fd0b74Schristos 	  if (((unsigned) CGEN_INSN_BITSIZE (insn) > cd->base_insn_bitsize) &&
141775fd0b74Schristos 	      (unsigned) (CGEN_INSN_BITSIZE (insn) / 8) <= sizeof (unsigned long))
141875fd0b74Schristos 	    {
141975fd0b74Schristos 	      unsigned long full_insn_value;
142075fd0b74Schristos 	      int rc = read_insn (cd, pc, info, buf,
142175fd0b74Schristos 				  CGEN_INSN_BITSIZE (insn) / 8,
142275fd0b74Schristos 				  & ex_info, & full_insn_value);
142375fd0b74Schristos 	      if (rc != 0)
142475fd0b74Schristos 		return rc;
142575fd0b74Schristos 	      length = CGEN_EXTRACT_FN (cd, insn)
142675fd0b74Schristos 		(cd, insn, &ex_info, full_insn_value, &fields, pc);
142775fd0b74Schristos 	    }
142875fd0b74Schristos 	  else
142975fd0b74Schristos 	    length = CGEN_EXTRACT_FN (cd, insn)
143075fd0b74Schristos 	      (cd, insn, &ex_info, insn_value_cropped, &fields, pc);
143175fd0b74Schristos 
143275fd0b74Schristos 	  /* Length < 0 -> error.  */
143375fd0b74Schristos 	  if (length < 0)
143475fd0b74Schristos 	    return length;
143575fd0b74Schristos 	  if (length > 0)
143675fd0b74Schristos 	    {
143775fd0b74Schristos 	      CGEN_PRINT_FN (cd, insn) (cd, info, insn, &fields, pc, length);
143875fd0b74Schristos 	      /* Length is in bits, result is in bytes.  */
143975fd0b74Schristos 	      return length / 8;
144075fd0b74Schristos 	    }
144175fd0b74Schristos 	}
144275fd0b74Schristos 
144375fd0b74Schristos       insn_list = CGEN_DIS_NEXT_INSN (insn_list);
144475fd0b74Schristos     }
144575fd0b74Schristos 
144675fd0b74Schristos   return 0;
144775fd0b74Schristos }
144875fd0b74Schristos 
144975fd0b74Schristos /* Default value for CGEN_PRINT_INSN.
145075fd0b74Schristos    The result is the size of the insn in bytes or zero for an unknown insn
145175fd0b74Schristos    or -1 if an error occured fetching bytes.  */
145275fd0b74Schristos 
145375fd0b74Schristos #ifndef CGEN_PRINT_INSN
145475fd0b74Schristos #define CGEN_PRINT_INSN default_print_insn
145575fd0b74Schristos #endif
145675fd0b74Schristos 
145775fd0b74Schristos static int
default_print_insn(CGEN_CPU_DESC cd,bfd_vma pc,disassemble_info * info)145875fd0b74Schristos default_print_insn (CGEN_CPU_DESC cd, bfd_vma pc, disassemble_info *info)
145975fd0b74Schristos {
146075fd0b74Schristos   bfd_byte buf[CGEN_MAX_INSN_SIZE];
146175fd0b74Schristos   int buflen;
146275fd0b74Schristos   int status;
146375fd0b74Schristos 
146475fd0b74Schristos   /* Attempt to read the base part of the insn.  */
146575fd0b74Schristos   buflen = cd->base_insn_bitsize / 8;
146675fd0b74Schristos   status = (*info->read_memory_func) (pc, buf, buflen, info);
146775fd0b74Schristos 
146875fd0b74Schristos   /* Try again with the minimum part, if min < base.  */
146975fd0b74Schristos   if (status != 0 && (cd->min_insn_bitsize < cd->base_insn_bitsize))
147075fd0b74Schristos     {
147175fd0b74Schristos       buflen = cd->min_insn_bitsize / 8;
147275fd0b74Schristos       status = (*info->read_memory_func) (pc, buf, buflen, info);
147375fd0b74Schristos     }
147475fd0b74Schristos 
147575fd0b74Schristos   if (status != 0)
147675fd0b74Schristos     {
147775fd0b74Schristos       (*info->memory_error_func) (status, pc, info);
147875fd0b74Schristos       return -1;
147975fd0b74Schristos     }
148075fd0b74Schristos 
148175fd0b74Schristos   return print_insn (cd, pc, info, buf, buflen);
148275fd0b74Schristos }
148375fd0b74Schristos 
148475fd0b74Schristos /* Main entry point.
148575fd0b74Schristos    Print one instruction from PC on INFO->STREAM.
148675fd0b74Schristos    Return the size of the instruction (in bytes).  */
148775fd0b74Schristos 
148875fd0b74Schristos typedef struct cpu_desc_list
148975fd0b74Schristos {
149075fd0b74Schristos   struct cpu_desc_list *next;
149175fd0b74Schristos   CGEN_BITSET *isa;
149275fd0b74Schristos   int mach;
149375fd0b74Schristos   int endian;
1494*e992f068Schristos   int insn_endian;
149575fd0b74Schristos   CGEN_CPU_DESC cd;
149675fd0b74Schristos } cpu_desc_list;
149775fd0b74Schristos 
149875fd0b74Schristos int
print_insn_mep(bfd_vma pc,disassemble_info * info)149975fd0b74Schristos print_insn_mep (bfd_vma pc, disassemble_info *info)
150075fd0b74Schristos {
150175fd0b74Schristos   static cpu_desc_list *cd_list = 0;
150275fd0b74Schristos   cpu_desc_list *cl = 0;
150375fd0b74Schristos   static CGEN_CPU_DESC cd = 0;
150475fd0b74Schristos   static CGEN_BITSET *prev_isa;
150575fd0b74Schristos   static int prev_mach;
150675fd0b74Schristos   static int prev_endian;
1507*e992f068Schristos   static int prev_insn_endian;
150875fd0b74Schristos   int length;
150975fd0b74Schristos   CGEN_BITSET *isa;
151075fd0b74Schristos   int mach;
151175fd0b74Schristos   int endian = (info->endian == BFD_ENDIAN_BIG
151275fd0b74Schristos 		? CGEN_ENDIAN_BIG
151375fd0b74Schristos 		: CGEN_ENDIAN_LITTLE);
1514*e992f068Schristos   int insn_endian = (info->endian_code == BFD_ENDIAN_BIG
1515*e992f068Schristos                      ? CGEN_ENDIAN_BIG
1516*e992f068Schristos                      : CGEN_ENDIAN_LITTLE);
151775fd0b74Schristos   enum bfd_architecture arch;
151875fd0b74Schristos 
151975fd0b74Schristos   /* ??? gdb will set mach but leave the architecture as "unknown" */
152075fd0b74Schristos #ifndef CGEN_BFD_ARCH
152175fd0b74Schristos #define CGEN_BFD_ARCH bfd_arch_mep
152275fd0b74Schristos #endif
152375fd0b74Schristos   arch = info->arch;
152475fd0b74Schristos   if (arch == bfd_arch_unknown)
152575fd0b74Schristos     arch = CGEN_BFD_ARCH;
152675fd0b74Schristos 
152775fd0b74Schristos   /* There's no standard way to compute the machine or isa number
152875fd0b74Schristos      so we leave it to the target.  */
152975fd0b74Schristos #ifdef CGEN_COMPUTE_MACH
153075fd0b74Schristos   mach = CGEN_COMPUTE_MACH (info);
153175fd0b74Schristos #else
153275fd0b74Schristos   mach = info->mach;
153375fd0b74Schristos #endif
153475fd0b74Schristos 
153575fd0b74Schristos #ifdef CGEN_COMPUTE_ISA
153675fd0b74Schristos   {
153775fd0b74Schristos     static CGEN_BITSET *permanent_isa;
153875fd0b74Schristos 
153975fd0b74Schristos     if (!permanent_isa)
154075fd0b74Schristos       permanent_isa = cgen_bitset_create (MAX_ISAS);
154175fd0b74Schristos     isa = permanent_isa;
154275fd0b74Schristos     cgen_bitset_clear (isa);
154375fd0b74Schristos     cgen_bitset_add (isa, CGEN_COMPUTE_ISA (info));
154475fd0b74Schristos   }
154575fd0b74Schristos #else
1546012573ebSchristos   isa = info->private_data;
154775fd0b74Schristos #endif
154875fd0b74Schristos 
154975fd0b74Schristos   /* If we've switched cpu's, try to find a handle we've used before */
155075fd0b74Schristos   if (cd
155175fd0b74Schristos       && (cgen_bitset_compare (isa, prev_isa) != 0
155275fd0b74Schristos 	  || mach != prev_mach
155375fd0b74Schristos 	  || endian != prev_endian))
155475fd0b74Schristos     {
155575fd0b74Schristos       cd = 0;
155675fd0b74Schristos       for (cl = cd_list; cl; cl = cl->next)
155775fd0b74Schristos 	{
155875fd0b74Schristos 	  if (cgen_bitset_compare (cl->isa, isa) == 0 &&
155975fd0b74Schristos 	      cl->mach == mach &&
156075fd0b74Schristos 	      cl->endian == endian)
156175fd0b74Schristos 	    {
156275fd0b74Schristos 	      cd = cl->cd;
156375fd0b74Schristos  	      prev_isa = cd->isas;
156475fd0b74Schristos 	      break;
156575fd0b74Schristos 	    }
156675fd0b74Schristos 	}
156775fd0b74Schristos     }
156875fd0b74Schristos 
156975fd0b74Schristos   /* If we haven't initialized yet, initialize the opcode table.  */
157075fd0b74Schristos   if (! cd)
157175fd0b74Schristos     {
157275fd0b74Schristos       const bfd_arch_info_type *arch_type = bfd_lookup_arch (arch, mach);
157375fd0b74Schristos       const char *mach_name;
157475fd0b74Schristos 
157575fd0b74Schristos       if (!arch_type)
157675fd0b74Schristos 	abort ();
157775fd0b74Schristos       mach_name = arch_type->printable_name;
157875fd0b74Schristos 
157975fd0b74Schristos       prev_isa = cgen_bitset_copy (isa);
158075fd0b74Schristos       prev_mach = mach;
158175fd0b74Schristos       prev_endian = endian;
1582*e992f068Schristos       prev_insn_endian = insn_endian;
158375fd0b74Schristos       cd = mep_cgen_cpu_open (CGEN_CPU_OPEN_ISAS, prev_isa,
158475fd0b74Schristos 				 CGEN_CPU_OPEN_BFDMACH, mach_name,
158575fd0b74Schristos 				 CGEN_CPU_OPEN_ENDIAN, prev_endian,
1586*e992f068Schristos                                  CGEN_CPU_OPEN_INSN_ENDIAN, prev_insn_endian,
158775fd0b74Schristos 				 CGEN_CPU_OPEN_END);
158875fd0b74Schristos       if (!cd)
158975fd0b74Schristos 	abort ();
159075fd0b74Schristos 
159175fd0b74Schristos       /* Save this away for future reference.  */
159275fd0b74Schristos       cl = xmalloc (sizeof (struct cpu_desc_list));
159375fd0b74Schristos       cl->cd = cd;
159475fd0b74Schristos       cl->isa = prev_isa;
159575fd0b74Schristos       cl->mach = mach;
159675fd0b74Schristos       cl->endian = endian;
159775fd0b74Schristos       cl->next = cd_list;
159875fd0b74Schristos       cd_list = cl;
159975fd0b74Schristos 
160075fd0b74Schristos       mep_cgen_init_dis (cd);
160175fd0b74Schristos     }
160275fd0b74Schristos 
160375fd0b74Schristos   /* We try to have as much common code as possible.
160475fd0b74Schristos      But at this point some targets need to take over.  */
160575fd0b74Schristos   /* ??? Some targets may need a hook elsewhere.  Try to avoid this,
160675fd0b74Schristos      but if not possible try to move this hook elsewhere rather than
160775fd0b74Schristos      have two hooks.  */
160875fd0b74Schristos   length = CGEN_PRINT_INSN (cd, pc, info);
160975fd0b74Schristos   if (length > 0)
161075fd0b74Schristos     return length;
161175fd0b74Schristos   if (length < 0)
161275fd0b74Schristos     return -1;
161375fd0b74Schristos 
161475fd0b74Schristos   (*info->fprintf_func) (info->stream, UNKNOWN_INSN_MSG);
161575fd0b74Schristos   return cd->default_insn_bitsize / 8;
161675fd0b74Schristos }
1617