From: Dave Brolley Date: Mon, 5 Feb 2007 20:04:22 +0000 (+0000) Subject: 2007-02-05 Dave Brolley X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=bd2f2e55ad54541340e5ea415f1aba65aa80717e;p=binutils-gdb.git 2007-02-05 Dave Brolley * mep-*: New support for Toshiba Media Processor (MeP). * Makefile.am: Add support for MeP. * configure.in: Likewise. * disassemble.c: Likewise. * Makefile.in: Regenerated. * configure: Regenerated. --- diff --git a/opcodes/ChangeLog b/opcodes/ChangeLog index 7f82d70c35c..5ce59698afa 100644 --- a/opcodes/ChangeLog +++ b/opcodes/ChangeLog @@ -1,3 +1,12 @@ +2007-02-05 Dave Brolley + + * mep-*: New support for Toshiba Media Processor (MeP). + * Makefile.am: Add support for MeP. + * configure.in: Likewise. + * disassemble.c: Likewise. + * Makefile.in: Regenerated. + * configure: Regenerated. + 2007-02-05 H.J. Lu * i386-dis.c (OP_J): Undo the last change. Properly handle 64K diff --git a/opcodes/Makefile.am b/opcodes/Makefile.am index ebd252fb7bf..5e710fea041 100644 --- a/opcodes/Makefile.am +++ b/opcodes/Makefile.am @@ -39,6 +39,7 @@ HFILES = \ m32c-desc.h m32c-opc.h \ m32r-desc.h m32r-opc.h \ mcore-opc.h \ + mep-desc.h mep-opc.h \ mt-desc.h mt-opc.h \ openrisc-desc.h openrisc-opc.h \ score-opc.h \ @@ -132,6 +133,11 @@ CFILES = \ m88k-dis.c \ maxq-dis.c \ mcore-dis.c \ + mep-asm.c \ + mep-desc.c \ + mep-dis.c \ + mep-ibld.c \ + mep-opc.c \ mips-dis.c \ mips-opc.c \ mips16-opc.c \ @@ -270,6 +276,11 @@ ALL_MACHINES = \ m10300-opc.lo \ maxq-dis.lo \ mcore-dis.lo \ + mep-asm.lo \ + mep-desc.lo \ + mep-dis.lo \ + mep-ibld.lo \ + mep-opc.lo \ mips-dis.lo \ mips-opc.lo \ mips16-opc.lo \ @@ -399,7 +410,7 @@ uninstall_libopcodes: CLEANFILES = \ stamp-ip2k stamp-m32c stamp-m32r stamp-fr30 stamp-frv \ - stamp-openrisc stamp-iq2000 stamp-mt stamp-xstormy16 stamp-xc16x\ + stamp-openrisc stamp-iq2000 stamp-mep stamp-mt stamp-xstormy16 stamp-xc16x\ libopcodes.a stamp-lib dep.sed DEP DEPA DEP1 DEP2 @@ -415,7 +426,7 @@ CGENDEPS = \ $(CGENDIR)/opc-opinst.scm \ cgen-asm.in cgen-dis.in cgen-ibld.in -CGEN_CPUS = fr30 frv ip2k m32c m32r mt openrisc xc16x xstormy16 +CGEN_CPUS = fr30 frv ip2k m32c m32r mep mt openrisc xc16x xstormy16 if CGEN_MAINT IP2K_DEPS = stamp-ip2k @@ -423,6 +434,7 @@ M32C_DEPS = stamp-m32c M32R_DEPS = stamp-m32r FR30_DEPS = stamp-fr30 FRV_DEPS = stamp-frv +MEP_DEPS = stamp-mep MT_DEPS = stamp-mt OPENRISC_DEPS = stamp-openrisc IQ2000_DEPS = stamp-iq2000 @@ -434,6 +446,7 @@ M32C_DEPS = M32R_DEPS = FR30_DEPS = FRV_DEPS = +MEP_DEPS = MT_DEPS = OPENRISC_DEPS = IQ2000_DEPS = @@ -507,6 +520,12 @@ stamp-frv: $(CGENDEPS) $(srcdir)/../cpu/frv.cpu $(srcdir)/../cpu/frv.opc $(MAKE) run-cgen arch=frv prefix=frv options= \ archfile=$(srcdir)/../cpu/frv.cpu opcfile=$(srcdir)/../cpu/frv.opc extrafiles= +$(srcdir)/mep-desc.h $(srcdir)/mep-desc.c $(srcdir)/mep-opc.h $(srcdir)/mep-opc.c $(srcdir)/mep-ibld.c $(srcdir)/mep-asm.c $(srcdir)/mep-dis.c: $(MEP_DEPS) + @true +stamp-mep: $(CGENDEPS) $(CPUDIR)/mep.cpu $(CPUDIR)/mep-default.cpu $(CPUDIR)/mep-core.cpu $(CPUDIR)/mep-h1.cpu $(CPUDIR)/mep-ext-cop.cpu $(CPUDIR)/mep-sample-ucidsp.cpu $(CPUDIR)/mep-rhcop.cpu $(CPUDIR)/mep-fmax.cpu $(CPUDIR)/mep.opc + $(MAKE) run-cgen arch=mep prefix=mep options= \ + archfile=$(CPUDIR)/mep.cpu opcfile=$(CPUDIR)/mep.opc extrafiles= + $(srcdir)/mt-desc.h $(srcdir)/mt-desc.c $(srcdir)/mt-opc.h $(srcdir)/mt-opc.c $(srcdir)/mt-ibld.c $(srcdir)/mt-asm.c $(srcdir)/mt-dis.c: $(MT_DEPS) @true stamp-mt: $(CGENDEPS) $(srcdir)/../cpu/mt.cpu $(srcdir)/../cpu/mt.opc @@ -928,6 +947,23 @@ maxq-dis.lo: maxq-dis.c sysdep.h config.h $(INCDIR)/ansidecl.h \ mcore-dis.lo: mcore-dis.c sysdep.h config.h $(INCDIR)/ansidecl.h \ mcore-opc.h $(INCDIR)/dis-asm.h $(BFD_H) $(INCDIR)/ansidecl.h \ $(INCDIR)/symcat.h +mep-asm.lo: mep-asm.c sysdep.h config.h $(BFD_H) \ + $(INCDIR)/ansidecl.h $(INCDIR)/symcat.h mep-desc.h \ + $(INCDIR)/opcode/cgen.h mep-opc.h opintl.h +mep-desc.lo: mep-desc.c sysdep.h config.h $(BFD_H) \ + $(INCDIR)/ansidecl.h $(INCDIR)/symcat.h mep-desc.h \ + $(INCDIR)/opcode/cgen.h mep-opc.h opintl.h +mep-dis.lo: mep-dis.c sysdep.h config.h $(INCDIR)/dis-asm.h \ + $(BFD_H) $(INCDIR)/ansidecl.h \ + $(INCDIR)/symcat.h mep-desc.h $(INCDIR)/opcode/cgen.h \ + mep-opc.h opintl.h +mep-ibld.lo: mep-ibld.c sysdep.h config.h $(INCDIR)/dis-asm.h \ + $(BFD_H) $(INCDIR)/ansidecl.h \ + $(INCDIR)/symcat.h mep-desc.h $(INCDIR)/opcode/cgen.h \ + mep-opc.h opintl.h +mep-opc.lo: mep-opc.c sysdep.h config.h $(BFD_H) \ + $(INCDIR)/ansidecl.h $(INCDIR)/symcat.h mep-desc.h \ + $(INCDIR)/opcode/cgen.h mep-opc.h mips-dis.lo: mips-dis.c sysdep.h config.h $(INCDIR)/ansidecl.h \ $(INCDIR)/dis-asm.h $(BFD_H) $(INCDIR)/ansidecl.h $(INCDIR)/symcat.h \ $(INCDIR)/libiberty.h $(INCDIR)/ansidecl.h $(INCDIR)/opcode/mips.h \ diff --git a/opcodes/Makefile.in b/opcodes/Makefile.in index 85003e61a0e..5c8cb90e9d9 100644 --- a/opcodes/Makefile.in +++ b/opcodes/Makefile.in @@ -252,6 +252,7 @@ HFILES = \ m32c-desc.h m32c-opc.h \ m32r-desc.h m32r-opc.h \ mcore-opc.h \ + mep-desc.h mep-opc.h \ mt-desc.h mt-opc.h \ openrisc-desc.h openrisc-opc.h \ score-opc.h \ @@ -346,6 +347,11 @@ CFILES = \ m88k-dis.c \ maxq-dis.c \ mcore-dis.c \ + mep-asm.c \ + mep-desc.c \ + mep-dis.c \ + mep-ibld.c \ + mep-opc.c \ mips-dis.c \ mips-opc.c \ mips16-opc.c \ @@ -484,6 +490,11 @@ ALL_MACHINES = \ m10300-opc.lo \ maxq-dis.lo \ mcore-dis.lo \ + mep-asm.lo \ + mep-desc.lo \ + mep-dis.lo \ + mep-ibld.lo \ + mep-opc.lo \ mips-dis.lo \ mips-opc.lo \ mips16-opc.lo \ @@ -567,7 +578,7 @@ noinst_LIBRARIES = libopcodes.a POTFILES = $(HFILES) $(CFILES) CLEANFILES = \ stamp-ip2k stamp-m32c stamp-m32r stamp-fr30 stamp-frv \ - stamp-openrisc stamp-iq2000 stamp-mt stamp-xstormy16 stamp-xc16x\ + stamp-openrisc stamp-iq2000 stamp-mep stamp-mt stamp-xstormy16 stamp-xc16x\ libopcodes.a stamp-lib dep.sed DEP DEPA DEP1 DEP2 CGENDIR = @cgendir@ @@ -581,7 +592,7 @@ CGENDEPS = \ $(CGENDIR)/opc-opinst.scm \ cgen-asm.in cgen-dis.in cgen-ibld.in -CGEN_CPUS = fr30 frv ip2k m32c m32r mt openrisc xc16x xstormy16 +CGEN_CPUS = fr30 frv ip2k m32c m32r mep mt openrisc xc16x xstormy16 @CGEN_MAINT_FALSE@IP2K_DEPS = @CGEN_MAINT_TRUE@IP2K_DEPS = stamp-ip2k @CGEN_MAINT_FALSE@M32C_DEPS = @@ -592,6 +603,8 @@ CGEN_CPUS = fr30 frv ip2k m32c m32r mt openrisc xc16x xstormy16 @CGEN_MAINT_TRUE@FR30_DEPS = stamp-fr30 @CGEN_MAINT_FALSE@FRV_DEPS = @CGEN_MAINT_TRUE@FRV_DEPS = stamp-frv +@CGEN_MAINT_FALSE@MEP_DEPS = +@CGEN_MAINT_TRUE@MEP_DEPS = stamp-mep @CGEN_MAINT_FALSE@MT_DEPS = @CGEN_MAINT_TRUE@MT_DEPS = stamp-mt @CGEN_MAINT_FALSE@OPENRISC_DEPS = @@ -1044,6 +1057,12 @@ stamp-frv: $(CGENDEPS) $(srcdir)/../cpu/frv.cpu $(srcdir)/../cpu/frv.opc $(MAKE) run-cgen arch=frv prefix=frv options= \ archfile=$(srcdir)/../cpu/frv.cpu opcfile=$(srcdir)/../cpu/frv.opc extrafiles= +$(srcdir)/mep-desc.h $(srcdir)/mep-desc.c $(srcdir)/mep-opc.h $(srcdir)/mep-opc.c $(srcdir)/mep-ibld.c $(srcdir)/mep-asm.c $(srcdir)/mep-dis.c: $(MEP_DEPS) + @true +stamp-mep: $(CGENDEPS) $(CPUDIR)/mep.cpu $(CPUDIR)/mep-default.cpu $(CPUDIR)/mep-core.cpu $(CPUDIR)/mep-h1.cpu $(CPUDIR)/mep-ext-cop.cpu $(CPUDIR)/mep-sample-ucidsp.cpu $(CPUDIR)/mep-rhcop.cpu $(CPUDIR)/mep-fmax.cpu $(CPUDIR)/mep.opc + $(MAKE) run-cgen arch=mep prefix=mep options= \ + archfile=$(CPUDIR)/mep.cpu opcfile=$(CPUDIR)/mep.opc extrafiles= + $(srcdir)/mt-desc.h $(srcdir)/mt-desc.c $(srcdir)/mt-opc.h $(srcdir)/mt-opc.c $(srcdir)/mt-ibld.c $(srcdir)/mt-asm.c $(srcdir)/mt-dis.c: $(MT_DEPS) @true stamp-mt: $(CGENDEPS) $(srcdir)/../cpu/mt.cpu $(srcdir)/../cpu/mt.opc @@ -1465,6 +1484,23 @@ maxq-dis.lo: maxq-dis.c sysdep.h config.h $(INCDIR)/ansidecl.h \ mcore-dis.lo: mcore-dis.c sysdep.h config.h $(INCDIR)/ansidecl.h \ mcore-opc.h $(INCDIR)/dis-asm.h $(BFD_H) $(INCDIR)/ansidecl.h \ $(INCDIR)/symcat.h +mep-asm.lo: mep-asm.c sysdep.h config.h $(BFD_H) \ + $(INCDIR)/ansidecl.h $(INCDIR)/symcat.h mep-desc.h \ + $(INCDIR)/opcode/cgen.h mep-opc.h opintl.h +mep-desc.lo: mep-desc.c sysdep.h config.h $(BFD_H) \ + $(INCDIR)/ansidecl.h $(INCDIR)/symcat.h mep-desc.h \ + $(INCDIR)/opcode/cgen.h mep-opc.h opintl.h +mep-dis.lo: mep-dis.c sysdep.h config.h $(INCDIR)/dis-asm.h \ + $(BFD_H) $(INCDIR)/ansidecl.h \ + $(INCDIR)/symcat.h mep-desc.h $(INCDIR)/opcode/cgen.h \ + mep-opc.h opintl.h +mep-ibld.lo: mep-ibld.c sysdep.h config.h $(INCDIR)/dis-asm.h \ + $(BFD_H) $(INCDIR)/ansidecl.h \ + $(INCDIR)/symcat.h mep-desc.h $(INCDIR)/opcode/cgen.h \ + mep-opc.h opintl.h +mep-opc.lo: mep-opc.c sysdep.h config.h $(BFD_H) \ + $(INCDIR)/ansidecl.h $(INCDIR)/symcat.h mep-desc.h \ + $(INCDIR)/opcode/cgen.h mep-opc.h mips-dis.lo: mips-dis.c sysdep.h config.h $(INCDIR)/ansidecl.h \ $(INCDIR)/dis-asm.h $(BFD_H) $(INCDIR)/ansidecl.h $(INCDIR)/symcat.h \ $(INCDIR)/libiberty.h $(INCDIR)/ansidecl.h $(INCDIR)/opcode/mips.h \ diff --git a/opcodes/configure b/opcodes/configure index 8e3e27ea9e6..f2c25ab489c 100755 --- a/opcodes/configure +++ b/opcodes/configure @@ -6555,6 +6555,7 @@ if test x${all_targets} = xfalse ; then bfd_m88k_arch) ta="$ta m88k-dis.lo" ;; bfd_maxq_arch) ta="$ta maxq-dis.lo" ;; bfd_mcore_arch) ta="$ta mcore-dis.lo" ;; + bfd_mep_arch) ta="$ta mep-asm.lo mep-desc.lo mep-dis.lo mep-ibld.lo mep-opc.lo" using_cgen=yes ;; bfd_mips_arch) ta="$ta mips-dis.lo mips-opc.lo mips16-opc.lo" ;; bfd_mmix_arch) ta="$ta mmix-dis.lo mmix-opc.lo" ;; bfd_mn10200_arch) ta="$ta m10200-dis.lo m10200-opc.lo" ;; diff --git a/opcodes/configure.in b/opcodes/configure.in index d937784491d..864c4b4871c 100644 --- a/opcodes/configure.in +++ b/opcodes/configure.in @@ -184,6 +184,7 @@ if test x${all_targets} = xfalse ; then bfd_m88k_arch) ta="$ta m88k-dis.lo" ;; bfd_maxq_arch) ta="$ta maxq-dis.lo" ;; bfd_mcore_arch) ta="$ta mcore-dis.lo" ;; + bfd_mep_arch) ta="$ta mep-asm.lo mep-desc.lo mep-dis.lo mep-ibld.lo mep-opc.lo" using_cgen=yes ;; bfd_mips_arch) ta="$ta mips-dis.lo mips-opc.lo mips16-opc.lo" ;; bfd_mmix_arch) ta="$ta mmix-dis.lo mmix-opc.lo" ;; bfd_mn10200_arch) ta="$ta m10200-dis.lo m10200-opc.lo" ;; diff --git a/opcodes/disassemble.c b/opcodes/disassemble.c index f86d21c7662..bd40dd69c4f 100644 --- a/opcodes/disassemble.c +++ b/opcodes/disassemble.c @@ -50,6 +50,7 @@ #define ARCH_m88k #define ARCH_maxq #define ARCH_mcore +#define ARCH_mep #define ARCH_mips #define ARCH_mmix #define ARCH_mn10200 @@ -261,6 +262,11 @@ disassembler (abfd) disassemble = print_insn_mcore; break; #endif +#ifdef ARCH_mep + case bfd_arch_mep: + disassemble = print_insn_mep; + break; +#endif #ifdef ARCH_mips case bfd_arch_mips: if (bfd_big_endian (abfd)) @@ -479,6 +485,12 @@ disassemble_init_for_target (struct disassemble_info * info) info->skip_zeroes = 32; break; #endif +#ifdef ARCH_mep + case bfd_arch_mep: + info->skip_zeroes = 256; + info->skip_zeroes_at_end = 0; + break; +#endif #ifdef ARCH_m32c case bfd_arch_m32c: info->endian = BFD_ENDIAN_BIG; diff --git a/opcodes/mep-asm.c b/opcodes/mep-asm.c new file mode 100644 index 00000000000..66f20a7479f --- /dev/null +++ b/opcodes/mep-asm.c @@ -0,0 +1,1398 @@ +/* Assembler interface for targets using CGEN. -*- C -*- + CGEN: Cpu tools GENerator + + THIS FILE IS MACHINE GENERATED WITH CGEN. + - the resultant file is machine generated, cgen-asm.in isn't + + Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2005 + Free Software Foundation, Inc. + + This file is part of the GNU Binutils and GDB, the GNU debugger. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ + +/* ??? Eventually more and more of this stuff can go to cpu-independent files. + Keep that in mind. */ + +#include "sysdep.h" +#include +#include "ansidecl.h" +#include "bfd.h" +#include "symcat.h" +#include "mep-desc.h" +#include "mep-opc.h" +#include "opintl.h" +#include "xregex.h" +#include "libiberty.h" +#include "safe-ctype.h" + +#undef min +#define min(a,b) ((a) < (b) ? (a) : (b)) +#undef max +#define max(a,b) ((a) > (b) ? (a) : (b)) + +static const char * parse_insn_normal + (CGEN_CPU_DESC, const CGEN_INSN *, const char **, CGEN_FIELDS *); + +/* -- assembler routines inserted here. */ + +/* -- asm.c */ + +#define CGEN_VALIDATE_INSN_SUPPORTED + + const char * parse_csrn (CGEN_CPU_DESC, const char **, CGEN_KEYWORD *, long *); + const char * parse_tpreg (CGEN_CPU_DESC, const char **, CGEN_KEYWORD *, long *); + const char * parse_spreg (CGEN_CPU_DESC, const char **, CGEN_KEYWORD *, long *); + const char * parse_mep_align (CGEN_CPU_DESC, const char **, enum cgen_operand_type, long *); + const char * parse_mep_alignu (CGEN_CPU_DESC, const char **, enum cgen_operand_type, unsigned long *); +static const char * parse_signed16 (CGEN_CPU_DESC, const char **, int, long *); +static const char * parse_unsigned16 (CGEN_CPU_DESC, const char **, int, unsigned long *); +static const char * parse_lo16 (CGEN_CPU_DESC, const char **, int, long *, long); +static const char * parse_unsigned7 (CGEN_CPU_DESC, const char **, enum cgen_operand_type, unsigned long *); +static const char * parse_zero (CGEN_CPU_DESC, const char **, int, long *); + +const char * +parse_csrn (CGEN_CPU_DESC cd, const char **strp, + CGEN_KEYWORD *keyword_table, long *field) +{ + const char *err; + unsigned long value; + + err = cgen_parse_keyword (cd, strp, keyword_table, field); + if (!err) + return NULL; + + err = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_CSRN_IDX, & value); + if (err) + return err; + *field = value; + return NULL; +} + +/* begin-cop-ip-parse-handlers */ +static const char * +parse_fmax_cr (CGEN_CPU_DESC cd, + const char **strp, + CGEN_KEYWORD *keyword_table ATTRIBUTE_UNUSED, + long *field) +{ + return cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_cr_fmax, field); +} +static const char * +parse_fmax_ccr (CGEN_CPU_DESC cd, + const char **strp, + CGEN_KEYWORD *keyword_table ATTRIBUTE_UNUSED, + long *field) +{ + return cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_ccr_fmax, field); +} +/* end-cop-ip-parse-handlers */ + +const char * +parse_tpreg (CGEN_CPU_DESC cd, const char ** strp, + CGEN_KEYWORD *keyword_table, long *field) +{ + const char *err; + + err = cgen_parse_keyword (cd, strp, keyword_table, field); + if (err) + return err; + if (*field != 13) + return _("Only $tp or $13 allowed for this opcode"); + return NULL; +} + +const char * +parse_spreg (CGEN_CPU_DESC cd, const char ** strp, + CGEN_KEYWORD *keyword_table, long *field) +{ + const char *err; + + err = cgen_parse_keyword (cd, strp, keyword_table, field); + if (err) + return err; + if (*field != 15) + return _("Only $sp or $15 allowed for this opcode"); + return NULL; +} + +const char * +parse_mep_align (CGEN_CPU_DESC cd, const char ** strp, + enum cgen_operand_type type, long *field) +{ + long lsbs = 0; + const char *err; + + switch (type) + { + case MEP_OPERAND_PCREL8A2: + case MEP_OPERAND_PCREL12A2: + case MEP_OPERAND_PCREL17A2: + case MEP_OPERAND_PCREL24A2: + case MEP_OPERAND_CDISP8A2: + case MEP_OPERAND_CDISP8A4: + case MEP_OPERAND_CDISP8A8: + err = cgen_parse_signed_integer (cd, strp, type, field); + break; + case MEP_OPERAND_PCABS24A2: + case MEP_OPERAND_UDISP7: + case MEP_OPERAND_UDISP7A2: + case MEP_OPERAND_UDISP7A4: + case MEP_OPERAND_UIMM7A4: + case MEP_OPERAND_ADDR24A4: + err = cgen_parse_unsigned_integer (cd, strp, type, (unsigned long *) field); + break; + default: + abort(); + } + if (err) + return err; + switch (type) + { + case MEP_OPERAND_UDISP7: + lsbs = 0; + break; + case MEP_OPERAND_PCREL8A2: + case MEP_OPERAND_PCREL12A2: + case MEP_OPERAND_PCREL17A2: + case MEP_OPERAND_PCREL24A2: + case MEP_OPERAND_PCABS24A2: + case MEP_OPERAND_UDISP7A2: + case MEP_OPERAND_CDISP8A2: + lsbs = *field & 1; + break; + case MEP_OPERAND_UDISP7A4: + case MEP_OPERAND_UIMM7A4: + case MEP_OPERAND_ADDR24A4: + case MEP_OPERAND_CDISP8A4: + lsbs = *field & 3; + break; + case MEP_OPERAND_CDISP8A8: + lsbs = *field & 7; + break; + default: + /* Safe assumption? */ + abort (); + } + if (lsbs) + return "Value is not aligned enough"; + return NULL; +} + +const char * +parse_mep_alignu (CGEN_CPU_DESC cd, const char ** strp, + enum cgen_operand_type type, unsigned long *field) +{ + return parse_mep_align (cd, strp, type, (long *) field); +} + + +/* Handle %lo(), %tpoff(), %sdaoff(), %hi(), and other signed + constants in a signed context. */ + +static const char * +parse_signed16 (CGEN_CPU_DESC cd, + const char **strp, + int opindex, + long *valuep) +{ + return parse_lo16 (cd, strp, opindex, valuep, 1); +} + +static const char * +parse_lo16 (CGEN_CPU_DESC cd, + const char **strp, + int opindex, + long *valuep, + long signedp) +{ + const char *errmsg; + enum cgen_parse_operand_result result_type; + bfd_vma value; + + if (strncasecmp (*strp, "%lo(", 4) == 0) + { + *strp += 4; + errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_MEP_LOW16, + & result_type, & value); + if (**strp != ')') + return _("missing `)'"); + ++*strp; + if (errmsg == NULL + && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER) + value &= 0xffff; + if (signedp) + *valuep = (long)(short) value; + else + *valuep = value; + return errmsg; + } + + if (strncasecmp (*strp, "%hi(", 4) == 0) + { + *strp += 4; + errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_MEP_HI16S, + & result_type, & value); + if (**strp != ')') + return _("missing `)'"); + ++*strp; + if (errmsg == NULL + && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER) + value = (value + 0x8000) >> 16; + *valuep = value; + return errmsg; + } + + if (strncasecmp (*strp, "%uhi(", 5) == 0) + { + *strp += 5; + errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_MEP_HI16U, + & result_type, & value); + if (**strp != ')') + return _("missing `)'"); + ++*strp; + if (errmsg == NULL + && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER) + value = value >> 16; + *valuep = value; + return errmsg; + } + + if (strncasecmp (*strp, "%sdaoff(", 8) == 0) + { + *strp += 8; + errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_MEP_GPREL, + NULL, & value); + if (**strp != ')') + return _("missing `)'"); + ++*strp; + *valuep = value; + return errmsg; + } + + if (strncasecmp (*strp, "%tpoff(", 7) == 0) + { + *strp += 7; + errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_MEP_TPREL, + NULL, & value); + if (**strp != ')') + return _("missing `)'"); + ++*strp; + *valuep = value; + return errmsg; + } + + if (**strp == '%') + return _("invalid %function() here"); + + return cgen_parse_signed_integer (cd, strp, opindex, valuep); +} + +static const char * +parse_unsigned16 (CGEN_CPU_DESC cd, + const char **strp, + int opindex, + unsigned long *valuep) +{ + return parse_lo16 (cd, strp, opindex, (long *) valuep, 0); +} + +/* A special case of parse_signed16 which accepts only the value zero. */ + +static const char * +parse_zero (CGEN_CPU_DESC cd, const char **strp, int opindex, long *valuep) +{ + const char *errmsg; + enum cgen_parse_operand_result result_type; + bfd_vma value; + + /*fprintf(stderr, "dj: signed parse opindex `%s'\n", *strp);*/ + + /* Prevent ($ry) from being attempted as an expression on 'sw $rx,($ry)'. + It will fail and cause ry to be listed as an undefined symbol in the + listing. */ + if (strncmp (*strp, "($", 2) == 0) + return "not zero"; /* any string will do -- will never be seen. */ + + if (strncasecmp (*strp, "%lo(", 4) == 0) + { + *strp += 4; + errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_MEP_LOW16, + &result_type, &value); + if (**strp != ')') + return "missing `)'"; + ++*strp; + if (errmsg == NULL + && (result_type != CGEN_PARSE_OPERAND_RESULT_NUMBER || value != 0)) + return "not zero"; /* any string will do -- will never be seen. */ + *valuep = value; + return errmsg; + } + + if (strncasecmp (*strp, "%hi(", 4) == 0) + { + *strp += 4; + errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_MEP_HI16S, + &result_type, &value); + if (**strp != ')') + return "missing `)'"; + ++*strp; + if (errmsg == NULL + && (result_type != CGEN_PARSE_OPERAND_RESULT_NUMBER || value != 0)) + return "not zero"; /* any string will do -- will never be seen. */ + *valuep = value; + return errmsg; + } + + if (strncasecmp (*strp, "%uhi(", 5) == 0) + { + *strp += 5; + errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_MEP_HI16U, + &result_type, &value); + if (**strp != ')') + return "missing `)'"; + ++*strp; + if (errmsg == NULL + && (result_type != CGEN_PARSE_OPERAND_RESULT_NUMBER || value != 0)) + return "not zero"; /* any string will do -- will never be seen. */ + *valuep = value; + return errmsg; + } + + if (strncasecmp (*strp, "%sdaoff(", 8) == 0) + { + *strp += 8; + errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_MEP_GPREL, + &result_type, &value); + if (**strp != ')') + return "missing `)'"; + ++*strp; + if (errmsg == NULL + && (result_type != CGEN_PARSE_OPERAND_RESULT_NUMBER || value != 0)) + return "not zero"; /* any string will do -- will never be seen. */ + *valuep = value; + return errmsg; + } + + if (strncasecmp (*strp, "%tpoff(", 7) == 0) + { + *strp += 7; + errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_MEP_TPREL, + &result_type, &value); + if (**strp != ')') + return "missing `)'"; + ++*strp; + if (errmsg == NULL + && (result_type != CGEN_PARSE_OPERAND_RESULT_NUMBER || value != 0)) + return "not zero"; /* any string will do -- will never be seen. */ + *valuep = value; + return errmsg; + } + + if (**strp == '%') + return "invalid %function() here"; + + errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_NONE, + &result_type, &value); + if (errmsg == NULL + && (result_type != CGEN_PARSE_OPERAND_RESULT_NUMBER || value != 0)) + return "not zero"; /* any string will do -- will never be seen. */ + + return errmsg; +} + +static const char * +parse_unsigned7 (CGEN_CPU_DESC cd, const char **strp, + enum cgen_operand_type opindex, unsigned long *valuep) +{ + const char *errmsg; + bfd_vma value; + + /* fprintf(stderr, "dj: unsigned7 parse `%s'\n", *strp); */ + + if (strncasecmp (*strp, "%tpoff(", 7) == 0) + { + int reloc; + *strp += 7; + switch (opindex) + { + case MEP_OPERAND_UDISP7: + reloc = BFD_RELOC_MEP_TPREL7; + break; + case MEP_OPERAND_UDISP7A2: + reloc = BFD_RELOC_MEP_TPREL7A2; + break; + case MEP_OPERAND_UDISP7A4: + reloc = BFD_RELOC_MEP_TPREL7A4; + break; + default: + /* Safe assumption? */ + abort (); + } + errmsg = cgen_parse_address (cd, strp, opindex, reloc, + NULL, &value); + if (**strp != ')') + return "missing `)'"; + ++*strp; + *valuep = value; + return errmsg; + } + + if (**strp == '%') + return _("invalid %function() here"); + + return parse_mep_alignu (cd, strp, opindex, valuep); +} + +/* BEGIN LIGHTWEIGHT MACRO PROCESSOR. */ + +#define MAXARGS 9 + +typedef struct +{ + char *name; + char *expansion; +} macro; + +typedef struct +{ + const char *start; + int len; +} arg; + +macro macros[] = +{ + { "sizeof", "(`1.end + (- `1))"}, + { "startof", "(`1 | 0)" }, + { "align4", "(`1&(~3))"}, +/*{ "hi", "(((`1+0x8000)>>16) & 0xffff)" }, */ +/*{ "lo", "(`1 & 0xffff)" }, */ +/*{ "sdaoff", "((`1-__sdabase) & 0x7f)"}, */ +/*{ "tpoff", "((`1-__tpbase) & 0x7f)"}, */ + { 0,0 } +}; + +static char * expand_string (const char *, int); + +static const char * +mep_cgen_expand_macros_and_parse_operand + (CGEN_CPU_DESC, int, const char **, CGEN_FIELDS *); + +static char * +str_append (char *dest, const char *input, int len) +{ + char *new_dest; + int oldlen; + + if (len == 0) + return dest; + /* printf("str_append: <<%s>>, <<%s>>, %d\n", dest, input, len); */ + oldlen = (dest ? strlen(dest) : 0); + new_dest = realloc (dest, oldlen + len + 1); + memset (new_dest + oldlen, 0, len + 1); + return strncat (new_dest, input, len); +} + +static macro * +lookup_macro (const char *name) +{ + macro *m; + + for (m = macros; m->name; ++m) + if (strncmp (m->name, name, strlen(m->name)) == 0) + return m; + + return 0; +} + +static char * +expand_macro (arg *args, int narg, macro *mac) +{ + char *result = 0, *rescanned_result = 0; + char *e = mac->expansion; + char *mark = e; + int arg = 0; + + /* printf("expanding macro %s with %d args\n", mac->name, narg + 1); */ + while (*e) + { + if (*e == '`' && + (*e+1) && + ((*(e + 1) - '1') <= MAXARGS) && + ((*(e + 1) - '1') <= narg)) + { + result = str_append (result, mark, e - mark); + arg = (*(e + 1) - '1'); + /* printf("replacing `%d with %s\n", arg+1, args[arg].start); */ + result = str_append (result, args[arg].start, args[arg].len); + ++e; + mark = e+1; + } + ++e; + } + + if (mark != e) + result = str_append (result, mark, e - mark); + + if (result) + { + rescanned_result = expand_string (result, 0); + free (result); + return rescanned_result; + } + else + return result; +} + +#define IN_TEXT 0 +#define IN_ARGS 1 + +static char * +expand_string (const char *in, int first_only) +{ + int num_expansions = 0; + int depth = 0; + int narg = -1; + arg args[MAXARGS]; + int state = IN_TEXT; + const char *mark = in; + macro *macro = 0; + + char *expansion = 0; + char *result = 0; + + while (*in) + { + switch (state) + { + case IN_TEXT: + if (*in == '%' && *(in + 1) && (!first_only || num_expansions == 0)) + { + macro = lookup_macro (in + 1); + if (macro) + { + /* printf("entering state %d at '%s'...\n", state, in); */ + result = str_append (result, mark, in - mark); + mark = in; + in += 1 + strlen (macro->name); + while (*in == ' ') ++in; + if (*in != '(') + { + state = IN_TEXT; + macro = 0; + } + else + { + state = IN_ARGS; + narg = 0; + args[narg].start = in + 1; + args[narg].len = 0; + mark = in + 1; + } + } + } + break; + case IN_ARGS: + if (depth == 0) + { + switch (*in) + { + case ',': + narg++; + args[narg].start = (in + 1); + args[narg].len = 0; + break; + case ')': + state = IN_TEXT; + /* printf("entering state %d at '%s'...\n", state, in); */ + if (macro) + { + expansion = 0; + expansion = expand_macro (args, narg, macro); + num_expansions++; + if (expansion) + { + result = str_append (result, expansion, strlen (expansion)); + free (expansion); + } + } + else + { + result = str_append (result, mark, in - mark); + } + macro = 0; + mark = in + 1; + break; + case '(': + depth++; + default: + args[narg].len++; + break; + } + } + else + { + if (*in == ')') + depth--; + if (narg > -1) + args[narg].len++; + } + + } + ++in; + } + + if (mark != in) + result = str_append (result, mark, in - mark); + + return result; +} + +#undef IN_ARGS +#undef IN_TEXT +#undef MAXARGS + + +/* END LIGHTWEIGHT MACRO PROCESSOR. */ + +const char * mep_cgen_parse_operand + (CGEN_CPU_DESC, int, const char **, CGEN_FIELDS *); + +const char * +mep_cgen_expand_macros_and_parse_operand (CGEN_CPU_DESC cd, int opindex, + const char ** strp_in, CGEN_FIELDS * fields) +{ + const char * errmsg = NULL; + char *str = 0, *hold = 0; + const char **strp = 0; + + /* Set up a new pointer to macro-expanded string. */ + str = expand_string (*strp_in, 1); + /* fprintf (stderr, " expanded <<%s>> to <<%s>>\n", *strp_in, str); */ + + hold = str; + strp = (const char **)(&str); + + errmsg = mep_cgen_parse_operand (cd, opindex, strp, fields); + + /* Now work out the advance. */ + if (strlen (str) == 0) + *strp_in += strlen (*strp_in); + + else + { + if (strstr (*strp_in, str)) + /* A macro-expansion was pulled off the front. */ + *strp_in = strstr (*strp_in, str); + else + /* A non-macro-expansion was pulled off the front. */ + *strp_in += (str - hold); + } + + if (hold) + free (hold); + + return errmsg; +} + +#define CGEN_ASM_INIT_HOOK (cd->parse_operand = mep_cgen_expand_macros_and_parse_operand); + +/* -- dis.c */ + +const char * mep_cgen_parse_operand + (CGEN_CPU_DESC, int, const char **, CGEN_FIELDS *); + +/* Main entry point for operand parsing. + + This function is basically just a big switch statement. Earlier versions + used tables to look up the function to use, but + - if the table contains both assembler and disassembler functions then + the disassembler contains much of the assembler and vice-versa, + - there's a lot of inlining possibilities as things grow, + - using a switch statement avoids the function call overhead. + + This function could be moved into `parse_insn_normal', but keeping it + separate makes clear the interface between `parse_insn_normal' and each of + the handlers. */ + +const char * +mep_cgen_parse_operand (CGEN_CPU_DESC cd, + int opindex, + const char ** strp, + CGEN_FIELDS * fields) +{ + const char * errmsg = NULL; + /* Used by scalar operands that still need to be parsed. */ + long junk ATTRIBUTE_UNUSED; + + switch (opindex) + { + case MEP_OPERAND_ADDR24A4 : + errmsg = parse_mep_alignu (cd, strp, MEP_OPERAND_ADDR24A4, (unsigned long *) (& fields->f_24u8a4n)); + break; + case MEP_OPERAND_CALLNUM : + errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_CALLNUM, (unsigned long *) (& fields->f_callnum)); + break; + case MEP_OPERAND_CCCC : + errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_CCCC, (unsigned long *) (& fields->f_rm)); + break; + case MEP_OPERAND_CCRN : + errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_ccr, & fields->f_ccrn); + break; + case MEP_OPERAND_CDISP8 : + errmsg = cgen_parse_signed_integer (cd, strp, MEP_OPERAND_CDISP8, (long *) (& fields->f_8s24)); + break; + case MEP_OPERAND_CDISP8A2 : + errmsg = parse_mep_align (cd, strp, MEP_OPERAND_CDISP8A2, (long *) (& fields->f_8s24a2)); + break; + case MEP_OPERAND_CDISP8A4 : + errmsg = parse_mep_align (cd, strp, MEP_OPERAND_CDISP8A4, (long *) (& fields->f_8s24a4)); + break; + case MEP_OPERAND_CDISP8A8 : + errmsg = parse_mep_align (cd, strp, MEP_OPERAND_CDISP8A8, (long *) (& fields->f_8s24a8)); + break; + case MEP_OPERAND_CIMM4 : + errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_CIMM4, (unsigned long *) (& fields->f_rn)); + break; + case MEP_OPERAND_CIMM5 : + errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_CIMM5, (unsigned long *) (& fields->f_5u24)); + break; + case MEP_OPERAND_CODE16 : + errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_CODE16, (unsigned long *) (& fields->f_16u16)); + break; + case MEP_OPERAND_CODE24 : + errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_CODE24, (unsigned long *) (& fields->f_24u4n)); + break; + case MEP_OPERAND_CP_FLAG : + errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_ccr, & junk); + break; + case MEP_OPERAND_CRN : + errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_cr, & fields->f_crn); + break; + case MEP_OPERAND_CRN64 : + errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_cr64, & fields->f_crn); + break; + case MEP_OPERAND_CRNX : + errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_cr, & fields->f_crnx); + break; + case MEP_OPERAND_CRNX64 : + errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_cr64, & fields->f_crnx); + break; + case MEP_OPERAND_CSRN : + errmsg = parse_csrn (cd, strp, & mep_cgen_opval_h_csr, & fields->f_csrn); + break; + case MEP_OPERAND_CSRN_IDX : + errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_CSRN_IDX, (unsigned long *) (& fields->f_csrn)); + break; + case MEP_OPERAND_DBG : + errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_csr, & junk); + break; + case MEP_OPERAND_DEPC : + errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_csr, & junk); + break; + case MEP_OPERAND_EPC : + errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_csr, & junk); + break; + case MEP_OPERAND_EXC : + errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_csr, & junk); + break; + case MEP_OPERAND_FMAX_CCRN : + errmsg = parse_fmax_ccr (cd, strp, & mep_cgen_opval_h_ccr, & fields->f_fmax_4_4); + break; + case MEP_OPERAND_FMAX_FRD : + errmsg = parse_fmax_cr (cd, strp, & mep_cgen_opval_h_cr, & fields->f_fmax_frd); + break; + case MEP_OPERAND_FMAX_FRD_INT : + errmsg = parse_fmax_cr (cd, strp, & mep_cgen_opval_h_cr, & fields->f_fmax_frd); + break; + case MEP_OPERAND_FMAX_FRM : + errmsg = parse_fmax_cr (cd, strp, & mep_cgen_opval_h_cr, & fields->f_fmax_frm); + break; + case MEP_OPERAND_FMAX_FRN : + errmsg = parse_fmax_cr (cd, strp, & mep_cgen_opval_h_cr, & fields->f_fmax_frn); + break; + case MEP_OPERAND_FMAX_FRN_INT : + errmsg = parse_fmax_cr (cd, strp, & mep_cgen_opval_h_cr, & fields->f_fmax_frn); + break; + case MEP_OPERAND_FMAX_RM : + errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_gpr, & fields->f_fmax_rm); + break; + case MEP_OPERAND_HI : + errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_csr, & junk); + break; + case MEP_OPERAND_LO : + errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_csr, & junk); + break; + case MEP_OPERAND_LP : + errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_csr, & junk); + break; + case MEP_OPERAND_MB0 : + errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_csr, & junk); + break; + case MEP_OPERAND_MB1 : + errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_csr, & junk); + break; + case MEP_OPERAND_ME0 : + errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_csr, & junk); + break; + case MEP_OPERAND_ME1 : + errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_csr, & junk); + break; + case MEP_OPERAND_NPC : + errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_csr, & junk); + break; + case MEP_OPERAND_OPT : + errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_csr, & junk); + break; + case MEP_OPERAND_PCABS24A2 : + errmsg = parse_mep_alignu (cd, strp, MEP_OPERAND_PCABS24A2, (unsigned long *) (& fields->f_24u5a2n)); + break; + case MEP_OPERAND_PCREL12A2 : + errmsg = parse_mep_align (cd, strp, MEP_OPERAND_PCREL12A2, (long *) (& fields->f_12s4a2)); + break; + case MEP_OPERAND_PCREL17A2 : + errmsg = parse_mep_align (cd, strp, MEP_OPERAND_PCREL17A2, (long *) (& fields->f_17s16a2)); + break; + case MEP_OPERAND_PCREL24A2 : + errmsg = parse_mep_align (cd, strp, MEP_OPERAND_PCREL24A2, (long *) (& fields->f_24s5a2n)); + break; + case MEP_OPERAND_PCREL8A2 : + errmsg = parse_mep_align (cd, strp, MEP_OPERAND_PCREL8A2, (long *) (& fields->f_8s8a2)); + break; + case MEP_OPERAND_PSW : + errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_csr, & junk); + break; + case MEP_OPERAND_R0 : + errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_gpr, & junk); + break; + case MEP_OPERAND_R1 : + errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_gpr, & junk); + break; + case MEP_OPERAND_RL : + errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_gpr, & fields->f_rl); + break; + case MEP_OPERAND_RM : + errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_gpr, & fields->f_rm); + break; + case MEP_OPERAND_RMA : + errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_gpr, & fields->f_rm); + break; + case MEP_OPERAND_RN : + errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_gpr, & fields->f_rn); + break; + case MEP_OPERAND_RN3 : + errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_gpr, & fields->f_rn3); + break; + case MEP_OPERAND_RN3C : + errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_gpr, & fields->f_rn3); + break; + case MEP_OPERAND_RN3L : + errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_gpr, & fields->f_rn3); + break; + case MEP_OPERAND_RN3S : + errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_gpr, & fields->f_rn3); + break; + case MEP_OPERAND_RN3UC : + errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_gpr, & fields->f_rn3); + break; + case MEP_OPERAND_RN3UL : + errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_gpr, & fields->f_rn3); + break; + case MEP_OPERAND_RN3US : + errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_gpr, & fields->f_rn3); + break; + case MEP_OPERAND_RNC : + errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_gpr, & fields->f_rn); + break; + case MEP_OPERAND_RNL : + errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_gpr, & fields->f_rn); + break; + case MEP_OPERAND_RNS : + errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_gpr, & fields->f_rn); + break; + case MEP_OPERAND_RNUC : + errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_gpr, & fields->f_rn); + break; + case MEP_OPERAND_RNUL : + errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_gpr, & fields->f_rn); + break; + case MEP_OPERAND_RNUS : + errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_gpr, & fields->f_rn); + break; + case MEP_OPERAND_SAR : + errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_csr, & junk); + break; + case MEP_OPERAND_SDISP16 : + errmsg = parse_signed16 (cd, strp, MEP_OPERAND_SDISP16, (long *) (& fields->f_16s16)); + break; + case MEP_OPERAND_SIMM16 : + errmsg = parse_signed16 (cd, strp, MEP_OPERAND_SIMM16, (long *) (& fields->f_16s16)); + break; + case MEP_OPERAND_SIMM6 : + errmsg = cgen_parse_signed_integer (cd, strp, MEP_OPERAND_SIMM6, (long *) (& fields->f_6s8)); + break; + case MEP_OPERAND_SIMM8 : + errmsg = cgen_parse_signed_integer (cd, strp, MEP_OPERAND_SIMM8, (long *) (& fields->f_8s8)); + break; + case MEP_OPERAND_SP : + errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_gpr, & junk); + break; + case MEP_OPERAND_SPR : + errmsg = parse_spreg (cd, strp, & mep_cgen_opval_h_gpr, & junk); + break; + case MEP_OPERAND_TP : + errmsg = cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_gpr, & junk); + break; + case MEP_OPERAND_TPR : + errmsg = parse_tpreg (cd, strp, & mep_cgen_opval_h_gpr, & junk); + break; + case MEP_OPERAND_UDISP2 : + errmsg = cgen_parse_signed_integer (cd, strp, MEP_OPERAND_UDISP2, (long *) (& fields->f_2u6)); + break; + case MEP_OPERAND_UDISP7 : + errmsg = parse_unsigned7 (cd, strp, MEP_OPERAND_UDISP7, (unsigned long *) (& fields->f_7u9)); + break; + case MEP_OPERAND_UDISP7A2 : + errmsg = parse_unsigned7 (cd, strp, MEP_OPERAND_UDISP7A2, (unsigned long *) (& fields->f_7u9a2)); + break; + case MEP_OPERAND_UDISP7A4 : + errmsg = parse_unsigned7 (cd, strp, MEP_OPERAND_UDISP7A4, (unsigned long *) (& fields->f_7u9a4)); + break; + case MEP_OPERAND_UIMM16 : + errmsg = parse_unsigned16 (cd, strp, MEP_OPERAND_UIMM16, (unsigned long *) (& fields->f_16u16)); + break; + case MEP_OPERAND_UIMM2 : + errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_UIMM2, (unsigned long *) (& fields->f_2u10)); + break; + case MEP_OPERAND_UIMM24 : + errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_UIMM24, (unsigned long *) (& fields->f_24u8n)); + break; + case MEP_OPERAND_UIMM3 : + errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_UIMM3, (unsigned long *) (& fields->f_3u5)); + break; + case MEP_OPERAND_UIMM4 : + errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_UIMM4, (unsigned long *) (& fields->f_4u8)); + break; + case MEP_OPERAND_UIMM5 : + errmsg = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_UIMM5, (unsigned long *) (& fields->f_5u8)); + break; + case MEP_OPERAND_UIMM7A4 : + errmsg = parse_mep_alignu (cd, strp, MEP_OPERAND_UIMM7A4, (unsigned long *) (& fields->f_7u9a4)); + break; + case MEP_OPERAND_ZERO : + errmsg = parse_zero (cd, strp, MEP_OPERAND_ZERO, (long *) (& junk)); + break; + + default : + /* xgettext:c-format */ + fprintf (stderr, _("Unrecognized field %d while parsing.\n"), opindex); + abort (); + } + + return errmsg; +} + +cgen_parse_fn * const mep_cgen_parse_handlers[] = +{ + parse_insn_normal, +}; + +void +mep_cgen_init_asm (CGEN_CPU_DESC cd) +{ + mep_cgen_init_opcode_table (cd); + mep_cgen_init_ibld_table (cd); + cd->parse_handlers = & mep_cgen_parse_handlers[0]; + cd->parse_operand = mep_cgen_parse_operand; +#ifdef CGEN_ASM_INIT_HOOK +CGEN_ASM_INIT_HOOK +#endif +} + + + +/* Regex construction routine. + + This translates an opcode syntax string into a regex string, + by replacing any non-character syntax element (such as an + opcode) with the pattern '.*' + + It then compiles the regex and stores it in the opcode, for + later use by mep_cgen_assemble_insn + + Returns NULL for success, an error message for failure. */ + +char * +mep_cgen_build_insn_regex (CGEN_INSN *insn) +{ + CGEN_OPCODE *opc = (CGEN_OPCODE *) CGEN_INSN_OPCODE (insn); + const char *mnem = CGEN_INSN_MNEMONIC (insn); + char rxbuf[CGEN_MAX_RX_ELEMENTS]; + char *rx = rxbuf; + const CGEN_SYNTAX_CHAR_TYPE *syn; + int reg_err; + + syn = CGEN_SYNTAX_STRING (CGEN_OPCODE_SYNTAX (opc)); + + /* Mnemonics come first in the syntax string. */ + if (! CGEN_SYNTAX_MNEMONIC_P (* syn)) + return _("missing mnemonic in syntax string"); + ++syn; + + /* Generate a case sensitive regular expression that emulates case + insensitive matching in the "C" locale. We cannot generate a case + insensitive regular expression because in Turkish locales, 'i' and 'I' + are not equal modulo case conversion. */ + + /* Copy the literal mnemonic out of the insn. */ + for (; *mnem; mnem++) + { + char c = *mnem; + + if (ISALPHA (c)) + { + *rx++ = '['; + *rx++ = TOLOWER (c); + *rx++ = TOUPPER (c); + *rx++ = ']'; + } + else + *rx++ = c; + } + + /* Copy any remaining literals from the syntax string into the rx. */ + for(; * syn != 0 && rx <= rxbuf + (CGEN_MAX_RX_ELEMENTS - 7 - 4); ++syn) + { + if (CGEN_SYNTAX_CHAR_P (* syn)) + { + char c = CGEN_SYNTAX_CHAR (* syn); + + switch (c) + { + /* Escape any regex metacharacters in the syntax. */ + case '.': case '[': case '\\': + case '*': case '^': case '$': + +#ifdef CGEN_ESCAPE_EXTENDED_REGEX + case '?': case '{': case '}': + case '(': case ')': case '*': + case '|': case '+': case ']': +#endif + *rx++ = '\\'; + *rx++ = c; + break; + + default: + if (ISALPHA (c)) + { + *rx++ = '['; + *rx++ = TOLOWER (c); + *rx++ = TOUPPER (c); + *rx++ = ']'; + } + else + *rx++ = c; + break; + } + } + else + { + /* Replace non-syntax fields with globs. */ + *rx++ = '.'; + *rx++ = '*'; + } + } + + /* Trailing whitespace ok. */ + * rx++ = '['; + * rx++ = ' '; + * rx++ = '\t'; + * rx++ = ']'; + * rx++ = '*'; + + /* But anchor it after that. */ + * rx++ = '$'; + * rx = '\0'; + + CGEN_INSN_RX (insn) = xmalloc (sizeof (regex_t)); + reg_err = regcomp ((regex_t *) CGEN_INSN_RX (insn), rxbuf, REG_NOSUB); + + if (reg_err == 0) + return NULL; + else + { + static char msg[80]; + + regerror (reg_err, (regex_t *) CGEN_INSN_RX (insn), msg, 80); + regfree ((regex_t *) CGEN_INSN_RX (insn)); + free (CGEN_INSN_RX (insn)); + (CGEN_INSN_RX (insn)) = NULL; + return msg; + } +} + + +/* Default insn parser. + + The syntax string is scanned and operands are parsed and stored in FIELDS. + Relocs are queued as we go via other callbacks. + + ??? Note that this is currently an all-or-nothing parser. If we fail to + parse the instruction, we return 0 and the caller will start over from + the beginning. Backtracking will be necessary in parsing subexpressions, + but that can be handled there. Not handling backtracking here may get + expensive in the case of the m68k. Deal with later. + + Returns NULL for success, an error message for failure. */ + +static const char * +parse_insn_normal (CGEN_CPU_DESC cd, + const CGEN_INSN *insn, + const char **strp, + CGEN_FIELDS *fields) +{ + /* ??? Runtime added insns not handled yet. */ + const CGEN_SYNTAX *syntax = CGEN_INSN_SYNTAX (insn); + const char *str = *strp; + const char *errmsg; + const char *p; + const CGEN_SYNTAX_CHAR_TYPE * syn; +#ifdef CGEN_MNEMONIC_OPERANDS + /* FIXME: wip */ + int past_opcode_p; +#endif + + /* For now we assume the mnemonic is first (there are no leading operands). + We can parse it without needing to set up operand parsing. + GAS's input scrubber will ensure mnemonics are lowercase, but we may + not be called from GAS. */ + p = CGEN_INSN_MNEMONIC (insn); + while (*p && TOLOWER (*p) == TOLOWER (*str)) + ++p, ++str; + + if (* p) + return _("unrecognized instruction"); + +#ifndef CGEN_MNEMONIC_OPERANDS + if (* str && ! ISSPACE (* str)) + return _("unrecognized instruction"); +#endif + + CGEN_INIT_PARSE (cd); + cgen_init_parse_operand (cd); +#ifdef CGEN_MNEMONIC_OPERANDS + past_opcode_p = 0; +#endif + + /* We don't check for (*str != '\0') here because we want to parse + any trailing fake arguments in the syntax string. */ + syn = CGEN_SYNTAX_STRING (syntax); + + /* Mnemonics come first for now, ensure valid string. */ + if (! CGEN_SYNTAX_MNEMONIC_P (* syn)) + abort (); + + ++syn; + + while (* syn != 0) + { + /* Non operand chars must match exactly. */ + if (CGEN_SYNTAX_CHAR_P (* syn)) + { + /* FIXME: While we allow for non-GAS callers above, we assume the + first char after the mnemonic part is a space. */ + /* FIXME: We also take inappropriate advantage of the fact that + GAS's input scrubber will remove extraneous blanks. */ + if (TOLOWER (*str) == TOLOWER (CGEN_SYNTAX_CHAR (* syn))) + { +#ifdef CGEN_MNEMONIC_OPERANDS + if (CGEN_SYNTAX_CHAR(* syn) == ' ') + past_opcode_p = 1; +#endif + ++ syn; + ++ str; + } + else if (*str) + { + /* Syntax char didn't match. Can't be this insn. */ + static char msg [80]; + + /* xgettext:c-format */ + sprintf (msg, _("syntax error (expected char `%c', found `%c')"), + CGEN_SYNTAX_CHAR(*syn), *str); + return msg; + } + else + { + /* Ran out of input. */ + static char msg [80]; + + /* xgettext:c-format */ + sprintf (msg, _("syntax error (expected char `%c', found end of instruction)"), + CGEN_SYNTAX_CHAR(*syn)); + return msg; + } + continue; + } + + /* We have an operand of some sort. */ + errmsg = cd->parse_operand (cd, CGEN_SYNTAX_FIELD (*syn), + &str, fields); + if (errmsg) + return errmsg; + + /* Done with this operand, continue with next one. */ + ++ syn; + } + + /* If we're at the end of the syntax string, we're done. */ + if (* syn == 0) + { + /* FIXME: For the moment we assume a valid `str' can only contain + blanks now. IE: We needn't try again with a longer version of + the insn and it is assumed that longer versions of insns appear + before shorter ones (eg: lsr r2,r3,1 vs lsr r2,r3). */ + while (ISSPACE (* str)) + ++ str; + + if (* str != '\0') + return _("junk at end of line"); /* FIXME: would like to include `str' */ + + return NULL; + } + + /* We couldn't parse it. */ + return _("unrecognized instruction"); +} + +/* Main entry point. + This routine is called for each instruction to be assembled. + STR points to the insn to be assembled. + We assume all necessary tables have been initialized. + The assembled instruction, less any fixups, is stored in BUF. + Remember that if CGEN_INT_INSN_P then BUF is an int and thus the value + still needs to be converted to target byte order, otherwise BUF is an array + of bytes in target byte order. + The result is a pointer to the insn's entry in the opcode table, + or NULL if an error occured (an error message will have already been + printed). + + Note that when processing (non-alias) macro-insns, + this function recurses. + + ??? It's possible to make this cpu-independent. + One would have to deal with a few minor things. + At this point in time doing so would be more of a curiosity than useful + [for example this file isn't _that_ big], but keeping the possibility in + mind helps keep the design clean. */ + +const CGEN_INSN * +mep_cgen_assemble_insn (CGEN_CPU_DESC cd, + const char *str, + CGEN_FIELDS *fields, + CGEN_INSN_BYTES_PTR buf, + char **errmsg) +{ + const char *start; + CGEN_INSN_LIST *ilist; + const char *parse_errmsg = NULL; + const char *insert_errmsg = NULL; + int recognized_mnemonic = 0; + + /* Skip leading white space. */ + while (ISSPACE (* str)) + ++ str; + + /* The instructions are stored in hashed lists. + Get the first in the list. */ + ilist = CGEN_ASM_LOOKUP_INSN (cd, str); + + /* Keep looking until we find a match. */ + start = str; + for ( ; ilist != NULL ; ilist = CGEN_ASM_NEXT_INSN (ilist)) + { + const CGEN_INSN *insn = ilist->insn; + recognized_mnemonic = 1; + +#ifdef CGEN_VALIDATE_INSN_SUPPORTED + /* Not usually needed as unsupported opcodes + shouldn't be in the hash lists. */ + /* Is this insn supported by the selected cpu? */ + if (! mep_cgen_insn_supported (cd, insn)) + continue; +#endif + /* If the RELAXED attribute is set, this is an insn that shouldn't be + chosen immediately. Instead, it is used during assembler/linker + relaxation if possible. */ + if (CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_RELAXED) != 0) + continue; + + str = start; + + /* Skip this insn if str doesn't look right lexically. */ + if (CGEN_INSN_RX (insn) != NULL && + regexec ((regex_t *) CGEN_INSN_RX (insn), str, 0, NULL, 0) == REG_NOMATCH) + continue; + + /* Allow parse/insert handlers to obtain length of insn. */ + CGEN_FIELDS_BITSIZE (fields) = CGEN_INSN_BITSIZE (insn); + + parse_errmsg = CGEN_PARSE_FN (cd, insn) (cd, insn, & str, fields); + if (parse_errmsg != NULL) + continue; + + /* ??? 0 is passed for `pc'. */ + insert_errmsg = CGEN_INSERT_FN (cd, insn) (cd, insn, fields, buf, + (bfd_vma) 0); + if (insert_errmsg != NULL) + continue; + + /* It is up to the caller to actually output the insn and any + queued relocs. */ + return insn; + } + + { + static char errbuf[150]; +#ifdef CGEN_VERBOSE_ASSEMBLER_ERRORS + const char *tmp_errmsg; + + /* If requesting verbose error messages, use insert_errmsg. + Failing that, use parse_errmsg. */ + tmp_errmsg = (insert_errmsg ? insert_errmsg : + parse_errmsg ? parse_errmsg : + recognized_mnemonic ? + _("unrecognized form of instruction") : + _("unrecognized instruction")); + + if (strlen (start) > 50) + /* xgettext:c-format */ + sprintf (errbuf, "%s `%.50s...'", tmp_errmsg, start); + else + /* xgettext:c-format */ + sprintf (errbuf, "%s `%.50s'", tmp_errmsg, start); +#else + if (strlen (start) > 50) + /* xgettext:c-format */ + sprintf (errbuf, _("bad instruction `%.50s...'"), start); + else + /* xgettext:c-format */ + sprintf (errbuf, _("bad instruction `%.50s'"), start); +#endif + + *errmsg = errbuf; + return NULL; + } +} diff --git a/opcodes/mep-desc.c b/opcodes/mep-desc.c new file mode 100644 index 00000000000..ab0f9bd5185 --- /dev/null +++ b/opcodes/mep-desc.c @@ -0,0 +1,2729 @@ +/* CPU data for mep. + +THIS FILE IS MACHINE GENERATED WITH CGEN. + +Copyright 1996-2005 Free Software Foundation, Inc. + +This file is part of the GNU Binutils and/or GDB, the GNU debugger. + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along +with this program; if not, write to the Free Software Foundation, Inc., +51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. + +*/ + +#include "sysdep.h" +#include +#include +#include "ansidecl.h" +#include "bfd.h" +#include "symcat.h" +#include "mep-desc.h" +#include "mep-opc.h" +#include "opintl.h" +#include "libiberty.h" +#include "xregex.h" + +/* Attributes. */ + +static const CGEN_ATTR_ENTRY bool_attr[] = +{ + { "#f", 0 }, + { "#t", 1 }, + { 0, 0 } +}; + +static const CGEN_ATTR_ENTRY MACH_attr[] ATTRIBUTE_UNUSED = +{ + { "base", MACH_BASE }, + { "mep", MACH_MEP }, + { "h1", MACH_H1 }, + { "max", MACH_MAX }, + { 0, 0 } +}; + +static const CGEN_ATTR_ENTRY ISA_attr[] ATTRIBUTE_UNUSED = +{ + { "mep", ISA_MEP }, + { "ext_core1", ISA_EXT_CORE1 }, + { "ext_core2", ISA_EXT_CORE2 }, + { "ext_cop2_16", ISA_EXT_COP2_16 }, + { "ext_cop2_32", ISA_EXT_COP2_32 }, + { "ext_cop2_48", ISA_EXT_COP2_48 }, + { "ext_cop2_64", ISA_EXT_COP2_64 }, + { "max", ISA_MAX }, + { 0, 0 } +}; + +static const CGEN_ATTR_ENTRY CDATA_attr[] ATTRIBUTE_UNUSED = +{ + { "LABEL", CDATA_LABEL }, + { "REGNUM", CDATA_REGNUM }, + { "FMAX_FLOAT", CDATA_FMAX_FLOAT }, + { "FMAX_INT", CDATA_FMAX_INT }, + { "POINTER", CDATA_POINTER }, + { "LONG", CDATA_LONG }, + { "ULONG", CDATA_ULONG }, + { "SHORT", CDATA_SHORT }, + { "USHORT", CDATA_USHORT }, + { "CHAR", CDATA_CHAR }, + { "UCHAR", CDATA_UCHAR }, + { "CP_DATA_BUS_INT", CDATA_CP_DATA_BUS_INT }, + { 0, 0 } +}; + +static const CGEN_ATTR_ENTRY ALIGN_attr [] ATTRIBUTE_UNUSED = +{ + {"integer", 1}, + { 0, 0 } +}; + +static const CGEN_ATTR_ENTRY LATENCY_attr [] ATTRIBUTE_UNUSED = +{ + {"integer", 0}, + { 0, 0 } +}; + +static const CGEN_ATTR_ENTRY CONFIG_attr[] ATTRIBUTE_UNUSED = +{ + { "NONE", CONFIG_NONE }, + { "simple", CONFIG_SIMPLE }, + { "fmax", CONFIG_FMAX }, + { 0, 0 } +}; + +const CGEN_ATTR_TABLE mep_cgen_ifield_attr_table[] = +{ + { "MACH", & MACH_attr[0], & MACH_attr[0] }, + { "ISA", & ISA_attr[0], & ISA_attr[0] }, + { "VIRTUAL", &bool_attr[0], &bool_attr[0] }, + { "PCREL-ADDR", &bool_attr[0], &bool_attr[0] }, + { "ABS-ADDR", &bool_attr[0], &bool_attr[0] }, + { "RESERVED", &bool_attr[0], &bool_attr[0] }, + { "SIGN-OPT", &bool_attr[0], &bool_attr[0] }, + { "SIGNED", &bool_attr[0], &bool_attr[0] }, + { 0, 0, 0 } +}; + +const CGEN_ATTR_TABLE mep_cgen_hardware_attr_table[] = +{ + { "MACH", & MACH_attr[0], & MACH_attr[0] }, + { "ISA", & ISA_attr[0], & ISA_attr[0] }, + { "VIRTUAL", &bool_attr[0], &bool_attr[0] }, + { "CACHE-ADDR", &bool_attr[0], &bool_attr[0] }, + { "PC", &bool_attr[0], &bool_attr[0] }, + { "PROFILE", &bool_attr[0], &bool_attr[0] }, + { "IS_FLOAT", &bool_attr[0], &bool_attr[0] }, + { 0, 0, 0 } +}; + +const CGEN_ATTR_TABLE mep_cgen_operand_attr_table[] = +{ + { "MACH", & MACH_attr[0], & MACH_attr[0] }, + { "ISA", & ISA_attr[0], & ISA_attr[0] }, + { "CDATA", & CDATA_attr[0], & CDATA_attr[0] }, + { "ALIGN", & ALIGN_attr[0], & ALIGN_attr[0] }, + { "VIRTUAL", &bool_attr[0], &bool_attr[0] }, + { "PCREL-ADDR", &bool_attr[0], &bool_attr[0] }, + { "ABS-ADDR", &bool_attr[0], &bool_attr[0] }, + { "SIGN-OPT", &bool_attr[0], &bool_attr[0] }, + { "SIGNED", &bool_attr[0], &bool_attr[0] }, + { "NEGATIVE", &bool_attr[0], &bool_attr[0] }, + { "RELAX", &bool_attr[0], &bool_attr[0] }, + { "SEM-ONLY", &bool_attr[0], &bool_attr[0] }, + { "RELOC_IMPLIES_OVERFLOW", &bool_attr[0], &bool_attr[0] }, + { 0, 0, 0 } +}; + +const CGEN_ATTR_TABLE mep_cgen_insn_attr_table[] = +{ + { "MACH", & MACH_attr[0], & MACH_attr[0] }, + { "ISA", & ISA_attr[0], & ISA_attr[0] }, + { "LATENCY", & LATENCY_attr[0], & LATENCY_attr[0] }, + { "CONFIG", & CONFIG_attr[0], & CONFIG_attr[0] }, + { "ALIAS", &bool_attr[0], &bool_attr[0] }, + { "VIRTUAL", &bool_attr[0], &bool_attr[0] }, + { "UNCOND-CTI", &bool_attr[0], &bool_attr[0] }, + { "COND-CTI", &bool_attr[0], &bool_attr[0] }, + { "SKIP-CTI", &bool_attr[0], &bool_attr[0] }, + { "DELAY-SLOT", &bool_attr[0], &bool_attr[0] }, + { "RELAXABLE", &bool_attr[0], &bool_attr[0] }, + { "RELAXED", &bool_attr[0], &bool_attr[0] }, + { "NO-DIS", &bool_attr[0], &bool_attr[0] }, + { "PBB", &bool_attr[0], &bool_attr[0] }, + { "OPTIONAL_BIT_INSN", &bool_attr[0], &bool_attr[0] }, + { "OPTIONAL_MUL_INSN", &bool_attr[0], &bool_attr[0] }, + { "OPTIONAL_DIV_INSN", &bool_attr[0], &bool_attr[0] }, + { "OPTIONAL_DEBUG_INSN", &bool_attr[0], &bool_attr[0] }, + { "OPTIONAL_LDZ_INSN", &bool_attr[0], &bool_attr[0] }, + { "OPTIONAL_ABS_INSN", &bool_attr[0], &bool_attr[0] }, + { "OPTIONAL_AVE_INSN", &bool_attr[0], &bool_attr[0] }, + { "OPTIONAL_MINMAX_INSN", &bool_attr[0], &bool_attr[0] }, + { "OPTIONAL_CLIP_INSN", &bool_attr[0], &bool_attr[0] }, + { "OPTIONAL_SAT_INSN", &bool_attr[0], &bool_attr[0] }, + { "OPTIONAL_UCI_INSN", &bool_attr[0], &bool_attr[0] }, + { "OPTIONAL_DSP_INSN", &bool_attr[0], &bool_attr[0] }, + { "OPTIONAL_CP_INSN", &bool_attr[0], &bool_attr[0] }, + { "OPTIONAL_CP64_INSN", &bool_attr[0], &bool_attr[0] }, + { "OPTIONAL_VLIW64", &bool_attr[0], &bool_attr[0] }, + { "MAY_TRAP", &bool_attr[0], &bool_attr[0] }, + { "VLIW_ALONE", &bool_attr[0], &bool_attr[0] }, + { "VLIW_NO_CORE_NOP", &bool_attr[0], &bool_attr[0] }, + { "VLIW_NO_COP_NOP", &bool_attr[0], &bool_attr[0] }, + { "VLIW64_NO_MATCHING_NOP", &bool_attr[0], &bool_attr[0] }, + { "VLIW32_NO_MATCHING_NOP", &bool_attr[0], &bool_attr[0] }, + { "VOLATILE", &bool_attr[0], &bool_attr[0] }, + { 0, 0, 0 } +}; + +/* Instruction set variants. */ + +static const CGEN_ISA mep_cgen_isa_table[] = { + { "mep", 32, 32, 16, 32 }, + { "ext_core1", 32, 32, 16, 32 }, + { "ext_core2", 32, 32, 16, 32 }, + { "ext_cop2_16", 32, 32, 65535, 0 }, + { "ext_cop2_32", 32, 32, 65535, 0 }, + { "ext_cop2_48", 32, 32, 65535, 0 }, + { "ext_cop2_64", 32, 32, 65535, 0 }, + { 0, 0, 0, 0, 0 } +}; + +/* Machine variants. */ + +static const CGEN_MACH mep_cgen_mach_table[] = { + { "mep", "mep", MACH_MEP, 16 }, + { "h1", "h1", MACH_H1, 16 }, + { 0, 0, 0, 0 } +}; + +static CGEN_KEYWORD_ENTRY mep_cgen_opval_h_gpr_entries[] = +{ + { "$0", 0, {0, {{{0, 0}}}}, 0, 0 }, + { "$1", 1, {0, {{{0, 0}}}}, 0, 0 }, + { "$2", 2, {0, {{{0, 0}}}}, 0, 0 }, + { "$3", 3, {0, {{{0, 0}}}}, 0, 0 }, + { "$4", 4, {0, {{{0, 0}}}}, 0, 0 }, + { "$5", 5, {0, {{{0, 0}}}}, 0, 0 }, + { "$6", 6, {0, {{{0, 0}}}}, 0, 0 }, + { "$7", 7, {0, {{{0, 0}}}}, 0, 0 }, + { "$8", 8, {0, {{{0, 0}}}}, 0, 0 }, + { "$9", 9, {0, {{{0, 0}}}}, 0, 0 }, + { "$10", 10, {0, {{{0, 0}}}}, 0, 0 }, + { "$11", 11, {0, {{{0, 0}}}}, 0, 0 }, + { "$fp", 8, {0, {{{0, 0}}}}, 0, 0 }, + { "$tp", 13, {0, {{{0, 0}}}}, 0, 0 }, + { "$gp", 14, {0, {{{0, 0}}}}, 0, 0 }, + { "$sp", 15, {0, {{{0, 0}}}}, 0, 0 }, + { "$12", 12, {0, {{{0, 0}}}}, 0, 0 }, + { "$13", 13, {0, {{{0, 0}}}}, 0, 0 }, + { "$14", 14, {0, {{{0, 0}}}}, 0, 0 }, + { "$15", 15, {0, {{{0, 0}}}}, 0, 0 } +}; + +CGEN_KEYWORD mep_cgen_opval_h_gpr = +{ + & mep_cgen_opval_h_gpr_entries[0], + 20, + 0, 0, 0, 0, "" +}; + +static CGEN_KEYWORD_ENTRY mep_cgen_opval_h_csr_entries[] = +{ + { "$pc", 0, {0, {{{0, 0}}}}, 0, 0 }, + { "$lp", 1, {0, {{{0, 0}}}}, 0, 0 }, + { "$sar", 2, {0, {{{0, 0}}}}, 0, 0 }, + { "$rpb", 4, {0, {{{0, 0}}}}, 0, 0 }, + { "$rpe", 5, {0, {{{0, 0}}}}, 0, 0 }, + { "$rpc", 6, {0, {{{0, 0}}}}, 0, 0 }, + { "$hi", 7, {0, {{{0, 0}}}}, 0, 0 }, + { "$lo", 8, {0, {{{0, 0}}}}, 0, 0 }, + { "$mb0", 12, {0, {{{0, 0}}}}, 0, 0 }, + { "$me0", 13, {0, {{{0, 0}}}}, 0, 0 }, + { "$mb1", 14, {0, {{{0, 0}}}}, 0, 0 }, + { "$me1", 15, {0, {{{0, 0}}}}, 0, 0 }, + { "$psw", 16, {0, {{{0, 0}}}}, 0, 0 }, + { "$id", 17, {0, {{{0, 0}}}}, 0, 0 }, + { "$tmp", 18, {0, {{{0, 0}}}}, 0, 0 }, + { "$epc", 19, {0, {{{0, 0}}}}, 0, 0 }, + { "$exc", 20, {0, {{{0, 0}}}}, 0, 0 }, + { "$cfg", 21, {0, {{{0, 0}}}}, 0, 0 }, + { "$npc", 23, {0, {{{0, 0}}}}, 0, 0 }, + { "$dbg", 24, {0, {{{0, 0}}}}, 0, 0 }, + { "$depc", 25, {0, {{{0, 0}}}}, 0, 0 }, + { "$opt", 26, {0, {{{0, 0}}}}, 0, 0 }, + { "$rcfg", 27, {0, {{{0, 0}}}}, 0, 0 }, + { "$ccfg", 28, {0, {{{0, 0}}}}, 0, 0 } +}; + +CGEN_KEYWORD mep_cgen_opval_h_csr = +{ + & mep_cgen_opval_h_csr_entries[0], + 24, + 0, 0, 0, 0, "" +}; + +static CGEN_KEYWORD_ENTRY mep_cgen_opval_h_cr64_entries[] = +{ + { "$c0", 0, {0, {{{0, 0}}}}, 0, 0 }, + { "$c1", 1, {0, {{{0, 0}}}}, 0, 0 }, + { "$c2", 2, {0, {{{0, 0}}}}, 0, 0 }, + { "$c3", 3, {0, {{{0, 0}}}}, 0, 0 }, + { "$c4", 4, {0, {{{0, 0}}}}, 0, 0 }, + { "$c5", 5, {0, {{{0, 0}}}}, 0, 0 }, + { "$c6", 6, {0, {{{0, 0}}}}, 0, 0 }, + { "$c7", 7, {0, {{{0, 0}}}}, 0, 0 }, + { "$c8", 8, {0, {{{0, 0}}}}, 0, 0 }, + { "$c9", 9, {0, {{{0, 0}}}}, 0, 0 }, + { "$c10", 10, {0, {{{0, 0}}}}, 0, 0 }, + { "$c11", 11, {0, {{{0, 0}}}}, 0, 0 }, + { "$c12", 12, {0, {{{0, 0}}}}, 0, 0 }, + { "$c13", 13, {0, {{{0, 0}}}}, 0, 0 }, + { "$c14", 14, {0, {{{0, 0}}}}, 0, 0 }, + { "$c15", 15, {0, {{{0, 0}}}}, 0, 0 }, + { "$c16", 16, {0, {{{0, 0}}}}, 0, 0 }, + { "$c17", 17, {0, {{{0, 0}}}}, 0, 0 }, + { "$c18", 18, {0, {{{0, 0}}}}, 0, 0 }, + { "$c19", 19, {0, {{{0, 0}}}}, 0, 0 }, + { "$c20", 20, {0, {{{0, 0}}}}, 0, 0 }, + { "$c21", 21, {0, {{{0, 0}}}}, 0, 0 }, + { "$c22", 22, {0, {{{0, 0}}}}, 0, 0 }, + { "$c23", 23, {0, {{{0, 0}}}}, 0, 0 }, + { "$c24", 24, {0, {{{0, 0}}}}, 0, 0 }, + { "$c25", 25, {0, {{{0, 0}}}}, 0, 0 }, + { "$c26", 26, {0, {{{0, 0}}}}, 0, 0 }, + { "$c27", 27, {0, {{{0, 0}}}}, 0, 0 }, + { "$c28", 28, {0, {{{0, 0}}}}, 0, 0 }, + { "$c29", 29, {0, {{{0, 0}}}}, 0, 0 }, + { "$c30", 30, {0, {{{0, 0}}}}, 0, 0 }, + { "$c31", 31, {0, {{{0, 0}}}}, 0, 0 } +}; + +CGEN_KEYWORD mep_cgen_opval_h_cr64 = +{ + & mep_cgen_opval_h_cr64_entries[0], + 32, + 0, 0, 0, 0, "" +}; + +static CGEN_KEYWORD_ENTRY mep_cgen_opval_h_cr_entries[] = +{ + { "$c0", 0, {0, {{{0, 0}}}}, 0, 0 }, + { "$c1", 1, {0, {{{0, 0}}}}, 0, 0 }, + { "$c2", 2, {0, {{{0, 0}}}}, 0, 0 }, + { "$c3", 3, {0, {{{0, 0}}}}, 0, 0 }, + { "$c4", 4, {0, {{{0, 0}}}}, 0, 0 }, + { "$c5", 5, {0, {{{0, 0}}}}, 0, 0 }, + { "$c6", 6, {0, {{{0, 0}}}}, 0, 0 }, + { "$c7", 7, {0, {{{0, 0}}}}, 0, 0 }, + { "$c8", 8, {0, {{{0, 0}}}}, 0, 0 }, + { "$c9", 9, {0, {{{0, 0}}}}, 0, 0 }, + { "$c10", 10, {0, {{{0, 0}}}}, 0, 0 }, + { "$c11", 11, {0, {{{0, 0}}}}, 0, 0 }, + { "$c12", 12, {0, {{{0, 0}}}}, 0, 0 }, + { "$c13", 13, {0, {{{0, 0}}}}, 0, 0 }, + { "$c14", 14, {0, {{{0, 0}}}}, 0, 0 }, + { "$c15", 15, {0, {{{0, 0}}}}, 0, 0 }, + { "$c16", 16, {0, {{{0, 0}}}}, 0, 0 }, + { "$c17", 17, {0, {{{0, 0}}}}, 0, 0 }, + { "$c18", 18, {0, {{{0, 0}}}}, 0, 0 }, + { "$c19", 19, {0, {{{0, 0}}}}, 0, 0 }, + { "$c20", 20, {0, {{{0, 0}}}}, 0, 0 }, + { "$c21", 21, {0, {{{0, 0}}}}, 0, 0 }, + { "$c22", 22, {0, {{{0, 0}}}}, 0, 0 }, + { "$c23", 23, {0, {{{0, 0}}}}, 0, 0 }, + { "$c24", 24, {0, {{{0, 0}}}}, 0, 0 }, + { "$c25", 25, {0, {{{0, 0}}}}, 0, 0 }, + { "$c26", 26, {0, {{{0, 0}}}}, 0, 0 }, + { "$c27", 27, {0, {{{0, 0}}}}, 0, 0 }, + { "$c28", 28, {0, {{{0, 0}}}}, 0, 0 }, + { "$c29", 29, {0, {{{0, 0}}}}, 0, 0 }, + { "$c30", 30, {0, {{{0, 0}}}}, 0, 0 }, + { "$c31", 31, {0, {{{0, 0}}}}, 0, 0 } +}; + +CGEN_KEYWORD mep_cgen_opval_h_cr = +{ + & mep_cgen_opval_h_cr_entries[0], + 32, + 0, 0, 0, 0, "" +}; + +static CGEN_KEYWORD_ENTRY mep_cgen_opval_h_ccr_entries[] = +{ + { "$ccr0", 0, {0, {{{0, 0}}}}, 0, 0 }, + { "$ccr1", 1, {0, {{{0, 0}}}}, 0, 0 }, + { "$ccr2", 2, {0, {{{0, 0}}}}, 0, 0 }, + { "$ccr3", 3, {0, {{{0, 0}}}}, 0, 0 }, + { "$ccr4", 4, {0, {{{0, 0}}}}, 0, 0 }, + { "$ccr5", 5, {0, {{{0, 0}}}}, 0, 0 }, + { "$ccr6", 6, {0, {{{0, 0}}}}, 0, 0 }, + { "$ccr7", 7, {0, {{{0, 0}}}}, 0, 0 }, + { "$ccr8", 8, {0, {{{0, 0}}}}, 0, 0 }, + { "$ccr9", 9, {0, {{{0, 0}}}}, 0, 0 }, + { "$ccr10", 10, {0, {{{0, 0}}}}, 0, 0 }, + { "$ccr11", 11, {0, {{{0, 0}}}}, 0, 0 }, + { "$ccr12", 12, {0, {{{0, 0}}}}, 0, 0 }, + { "$ccr13", 13, {0, {{{0, 0}}}}, 0, 0 }, + { "$ccr14", 14, {0, {{{0, 0}}}}, 0, 0 }, + { "$ccr15", 15, {0, {{{0, 0}}}}, 0, 0 }, + { "$ccr16", 16, {0, {{{0, 0}}}}, 0, 0 }, + { "$ccr17", 17, {0, {{{0, 0}}}}, 0, 0 }, + { "$ccr18", 18, {0, {{{0, 0}}}}, 0, 0 }, + { "$ccr19", 19, {0, {{{0, 0}}}}, 0, 0 }, + { "$ccr20", 20, {0, {{{0, 0}}}}, 0, 0 }, + { "$ccr21", 21, {0, {{{0, 0}}}}, 0, 0 }, + { "$ccr22", 22, {0, {{{0, 0}}}}, 0, 0 }, + { "$ccr23", 23, {0, {{{0, 0}}}}, 0, 0 }, + { "$ccr24", 24, {0, {{{0, 0}}}}, 0, 0 }, + { "$ccr25", 25, {0, {{{0, 0}}}}, 0, 0 }, + { "$ccr26", 26, {0, {{{0, 0}}}}, 0, 0 }, + { "$ccr27", 27, {0, {{{0, 0}}}}, 0, 0 }, + { "$ccr28", 28, {0, {{{0, 0}}}}, 0, 0 }, + { "$ccr29", 29, {0, {{{0, 0}}}}, 0, 0 }, + { "$ccr30", 30, {0, {{{0, 0}}}}, 0, 0 }, + { "$ccr31", 31, {0, {{{0, 0}}}}, 0, 0 }, + { "$ccr32", 32, {0, {{{0, 0}}}}, 0, 0 }, + { "$ccr33", 33, {0, {{{0, 0}}}}, 0, 0 }, + { "$ccr34", 34, {0, {{{0, 0}}}}, 0, 0 }, + { "$ccr35", 35, {0, {{{0, 0}}}}, 0, 0 }, + { "$ccr36", 36, {0, {{{0, 0}}}}, 0, 0 }, + { "$ccr37", 37, {0, {{{0, 0}}}}, 0, 0 }, + { "$ccr38", 38, {0, {{{0, 0}}}}, 0, 0 }, + { "$ccr39", 39, {0, {{{0, 0}}}}, 0, 0 }, + { "$ccr40", 40, {0, {{{0, 0}}}}, 0, 0 }, + { "$ccr41", 41, {0, {{{0, 0}}}}, 0, 0 }, + { "$ccr42", 42, {0, {{{0, 0}}}}, 0, 0 }, + { "$ccr43", 43, {0, {{{0, 0}}}}, 0, 0 }, + { "$ccr44", 44, {0, {{{0, 0}}}}, 0, 0 }, + { "$ccr45", 45, {0, {{{0, 0}}}}, 0, 0 }, + { "$ccr46", 46, {0, {{{0, 0}}}}, 0, 0 }, + { "$ccr47", 47, {0, {{{0, 0}}}}, 0, 0 }, + { "$ccr48", 48, {0, {{{0, 0}}}}, 0, 0 }, + { "$ccr49", 49, {0, {{{0, 0}}}}, 0, 0 }, + { "$ccr50", 50, {0, {{{0, 0}}}}, 0, 0 }, + { "$ccr51", 51, {0, {{{0, 0}}}}, 0, 0 }, + { "$ccr52", 52, {0, {{{0, 0}}}}, 0, 0 }, + { "$ccr53", 53, {0, {{{0, 0}}}}, 0, 0 }, + { "$ccr54", 54, {0, {{{0, 0}}}}, 0, 0 }, + { "$ccr55", 55, {0, {{{0, 0}}}}, 0, 0 }, + { "$ccr56", 56, {0, {{{0, 0}}}}, 0, 0 }, + { "$ccr57", 57, {0, {{{0, 0}}}}, 0, 0 }, + { "$ccr58", 58, {0, {{{0, 0}}}}, 0, 0 }, + { "$ccr59", 59, {0, {{{0, 0}}}}, 0, 0 }, + { "$ccr60", 60, {0, {{{0, 0}}}}, 0, 0 }, + { "$ccr61", 61, {0, {{{0, 0}}}}, 0, 0 }, + { "$ccr62", 62, {0, {{{0, 0}}}}, 0, 0 }, + { "$ccr63", 63, {0, {{{0, 0}}}}, 0, 0 } +}; + +CGEN_KEYWORD mep_cgen_opval_h_ccr = +{ + & mep_cgen_opval_h_ccr_entries[0], + 64, + 0, 0, 0, 0, "" +}; + +static CGEN_KEYWORD_ENTRY mep_cgen_opval_h_cr_fmax_entries[] = +{ + { "$fr0", 0, {0, {{{0, 0}}}}, 0, 0 }, + { "$fr1", 1, {0, {{{0, 0}}}}, 0, 0 }, + { "$fr2", 2, {0, {{{0, 0}}}}, 0, 0 }, + { "$fr3", 3, {0, {{{0, 0}}}}, 0, 0 }, + { "$fr4", 4, {0, {{{0, 0}}}}, 0, 0 }, + { "$fr5", 5, {0, {{{0, 0}}}}, 0, 0 }, + { "$fr6", 6, {0, {{{0, 0}}}}, 0, 0 }, + { "$fr7", 7, {0, {{{0, 0}}}}, 0, 0 }, + { "$fr8", 8, {0, {{{0, 0}}}}, 0, 0 }, + { "$fr9", 9, {0, {{{0, 0}}}}, 0, 0 }, + { "$fr10", 10, {0, {{{0, 0}}}}, 0, 0 }, + { "$fr11", 11, {0, {{{0, 0}}}}, 0, 0 }, + { "$fr12", 12, {0, {{{0, 0}}}}, 0, 0 }, + { "$fr13", 13, {0, {{{0, 0}}}}, 0, 0 }, + { "$fr14", 14, {0, {{{0, 0}}}}, 0, 0 }, + { "$fr15", 15, {0, {{{0, 0}}}}, 0, 0 }, + { "$fr16", 16, {0, {{{0, 0}}}}, 0, 0 }, + { "$fr17", 17, {0, {{{0, 0}}}}, 0, 0 }, + { "$fr18", 18, {0, {{{0, 0}}}}, 0, 0 }, + { "$fr19", 19, {0, {{{0, 0}}}}, 0, 0 }, + { "$fr20", 20, {0, {{{0, 0}}}}, 0, 0 }, + { "$fr21", 21, {0, {{{0, 0}}}}, 0, 0 }, + { "$fr22", 22, {0, {{{0, 0}}}}, 0, 0 }, + { "$fr23", 23, {0, {{{0, 0}}}}, 0, 0 }, + { "$fr24", 24, {0, {{{0, 0}}}}, 0, 0 }, + { "$fr25", 25, {0, {{{0, 0}}}}, 0, 0 }, + { "$fr26", 26, {0, {{{0, 0}}}}, 0, 0 }, + { "$fr27", 27, {0, {{{0, 0}}}}, 0, 0 }, + { "$fr28", 28, {0, {{{0, 0}}}}, 0, 0 }, + { "$fr29", 29, {0, {{{0, 0}}}}, 0, 0 }, + { "$fr30", 30, {0, {{{0, 0}}}}, 0, 0 }, + { "$fr31", 31, {0, {{{0, 0}}}}, 0, 0 }, + { "$c0", 0, {0, {{{0, 0}}}}, 0, 0 }, + { "$c1", 1, {0, {{{0, 0}}}}, 0, 0 }, + { "$c2", 2, {0, {{{0, 0}}}}, 0, 0 }, + { "$c3", 3, {0, {{{0, 0}}}}, 0, 0 }, + { "$c4", 4, {0, {{{0, 0}}}}, 0, 0 }, + { "$c5", 5, {0, {{{0, 0}}}}, 0, 0 }, + { "$c6", 6, {0, {{{0, 0}}}}, 0, 0 }, + { "$c7", 7, {0, {{{0, 0}}}}, 0, 0 }, + { "$c8", 8, {0, {{{0, 0}}}}, 0, 0 }, + { "$c9", 9, {0, {{{0, 0}}}}, 0, 0 }, + { "$c10", 10, {0, {{{0, 0}}}}, 0, 0 }, + { "$c11", 11, {0, {{{0, 0}}}}, 0, 0 }, + { "$c12", 12, {0, {{{0, 0}}}}, 0, 0 }, + { "$c13", 13, {0, {{{0, 0}}}}, 0, 0 }, + { "$c14", 14, {0, {{{0, 0}}}}, 0, 0 }, + { "$c15", 15, {0, {{{0, 0}}}}, 0, 0 }, + { "$c16", 16, {0, {{{0, 0}}}}, 0, 0 }, + { "$c17", 17, {0, {{{0, 0}}}}, 0, 0 }, + { "$c18", 18, {0, {{{0, 0}}}}, 0, 0 }, + { "$c19", 19, {0, {{{0, 0}}}}, 0, 0 }, + { "$c20", 20, {0, {{{0, 0}}}}, 0, 0 }, + { "$c21", 21, {0, {{{0, 0}}}}, 0, 0 }, + { "$c22", 22, {0, {{{0, 0}}}}, 0, 0 }, + { "$c23", 23, {0, {{{0, 0}}}}, 0, 0 }, + { "$c24", 24, {0, {{{0, 0}}}}, 0, 0 }, + { "$c25", 25, {0, {{{0, 0}}}}, 0, 0 }, + { "$c26", 26, {0, {{{0, 0}}}}, 0, 0 }, + { "$c27", 27, {0, {{{0, 0}}}}, 0, 0 }, + { "$c28", 28, {0, {{{0, 0}}}}, 0, 0 }, + { "$c29", 29, {0, {{{0, 0}}}}, 0, 0 }, + { "$c30", 30, {0, {{{0, 0}}}}, 0, 0 }, + { "$c31", 31, {0, {{{0, 0}}}}, 0, 0 } +}; + +CGEN_KEYWORD mep_cgen_opval_h_cr_fmax = +{ + & mep_cgen_opval_h_cr_fmax_entries[0], + 64, + 0, 0, 0, 0, "" +}; + +static CGEN_KEYWORD_ENTRY mep_cgen_opval_h_ccr_fmax_entries[] = +{ + { "$cirr", 0, {0, {{{0, 0}}}}, 0, 0 }, + { "$fcr0", 0, {0, {{{0, 0}}}}, 0, 0 }, + { "$ccr0", 0, {0, {{{0, 0}}}}, 0, 0 }, + { "$cbcr", 1, {0, {{{0, 0}}}}, 0, 0 }, + { "$fcr1", 1, {0, {{{0, 0}}}}, 0, 0 }, + { "$ccr1", 1, {0, {{{0, 0}}}}, 0, 0 }, + { "$cerr", 15, {0, {{{0, 0}}}}, 0, 0 }, + { "$fcr15", 15, {0, {{{0, 0}}}}, 0, 0 }, + { "$ccr15", 15, {0, {{{0, 0}}}}, 0, 0 } +}; + +CGEN_KEYWORD mep_cgen_opval_h_ccr_fmax = +{ + & mep_cgen_opval_h_ccr_fmax_entries[0], + 9, + 0, 0, 0, 0, "" +}; + + +/* The hardware table. */ + +#if defined (__STDC__) || defined (ALMOST_STDC) || defined (HAVE_STRINGIZE) +#define A(a) (1 << CGEN_HW_##a) +#else +#define A(a) (1 << CGEN_HW_/**/a) +#endif + +const CGEN_HW_ENTRY mep_cgen_hw_table[] = +{ + { "h-memory", HW_H_MEMORY, CGEN_ASM_NONE, 0, { 0, { { { (1<name) + { + if (strcmp (name, table->bfd_name) == 0) + return table; + ++table; + } + abort (); +} + +/* Subroutine of mep_cgen_cpu_open to build the hardware table. */ + +static void +build_hw_table (CGEN_CPU_TABLE *cd) +{ + int i; + int machs = cd->machs; + const CGEN_HW_ENTRY *init = & mep_cgen_hw_table[0]; + /* MAX_HW is only an upper bound on the number of selected entries. + However each entry is indexed by it's enum so there can be holes in + the table. */ + const CGEN_HW_ENTRY **selected = + (const CGEN_HW_ENTRY **) xmalloc (MAX_HW * sizeof (CGEN_HW_ENTRY *)); + + cd->hw_table.init_entries = init; + cd->hw_table.entry_size = sizeof (CGEN_HW_ENTRY); + memset (selected, 0, MAX_HW * sizeof (CGEN_HW_ENTRY *)); + /* ??? For now we just use machs to determine which ones we want. */ + for (i = 0; init[i].name != NULL; ++i) + if (CGEN_HW_ATTR_VALUE (&init[i], CGEN_HW_MACH) + & machs) + selected[init[i].type] = &init[i]; + cd->hw_table.entries = selected; + cd->hw_table.num_entries = MAX_HW; +} + +/* Subroutine of mep_cgen_cpu_open to build the hardware table. */ + +static void +build_ifield_table (CGEN_CPU_TABLE *cd) +{ + cd->ifld_table = & mep_cgen_ifld_table[0]; +} + +/* Subroutine of mep_cgen_cpu_open to build the hardware table. */ + +static void +build_operand_table (CGEN_CPU_TABLE *cd) +{ + int i; + int machs = cd->machs; + const CGEN_OPERAND *init = & mep_cgen_operand_table[0]; + /* MAX_OPERANDS is only an upper bound on the number of selected entries. + However each entry is indexed by it's enum so there can be holes in + the table. */ + const CGEN_OPERAND **selected = xmalloc (MAX_OPERANDS * sizeof (* selected)); + + cd->operand_table.init_entries = init; + cd->operand_table.entry_size = sizeof (CGEN_OPERAND); + memset (selected, 0, MAX_OPERANDS * sizeof (CGEN_OPERAND *)); + /* ??? For now we just use mach to determine which ones we want. */ + for (i = 0; init[i].name != NULL; ++i) + if (CGEN_OPERAND_ATTR_VALUE (&init[i], CGEN_OPERAND_MACH) + & machs) + selected[init[i].type] = &init[i]; + cd->operand_table.entries = selected; + cd->operand_table.num_entries = MAX_OPERANDS; +} + +/* Subroutine of mep_cgen_cpu_open to build the hardware table. + ??? This could leave out insns not supported by the specified mach/isa, + but that would cause errors like "foo only supported by bar" to become + "unknown insn", so for now we include all insns and require the app to + do the checking later. + ??? On the other hand, parsing of such insns may require their hardware or + operand elements to be in the table [which they mightn't be]. */ + +static void +build_insn_table (CGEN_CPU_TABLE *cd) +{ + int i; + const CGEN_IBASE *ib = & mep_cgen_insn_table[0]; + CGEN_INSN *insns = xmalloc (MAX_INSNS * sizeof (CGEN_INSN)); + + memset (insns, 0, MAX_INSNS * sizeof (CGEN_INSN)); + for (i = 0; i < MAX_INSNS; ++i) + insns[i].base = &ib[i]; + cd->insn_table.init_entries = insns; + cd->insn_table.entry_size = sizeof (CGEN_IBASE); + cd->insn_table.num_init_entries = MAX_INSNS; +} + +/* Subroutine of mep_cgen_cpu_open to rebuild the tables. */ + +static void +mep_cgen_rebuild_tables (CGEN_CPU_TABLE *cd) +{ + int i; + CGEN_BITSET *isas = cd->isas; + unsigned int machs = cd->machs; + + cd->int_insn_p = CGEN_INT_INSN_P; + + /* Data derived from the isa spec. */ +#define UNSET (CGEN_SIZE_UNKNOWN + 1) + cd->default_insn_bitsize = UNSET; + cd->base_insn_bitsize = UNSET; + cd->min_insn_bitsize = 65535; /* Some ridiculously big number. */ + cd->max_insn_bitsize = 0; + for (i = 0; i < MAX_ISAS; ++i) + if (cgen_bitset_contains (isas, i)) + { + const CGEN_ISA *isa = & mep_cgen_isa_table[i]; + + /* Default insn sizes of all selected isas must be + equal or we set the result to 0, meaning "unknown". */ + if (cd->default_insn_bitsize == UNSET) + cd->default_insn_bitsize = isa->default_insn_bitsize; + else if (isa->default_insn_bitsize == cd->default_insn_bitsize) + ; /* This is ok. */ + else + cd->default_insn_bitsize = CGEN_SIZE_UNKNOWN; + + /* Base insn sizes of all selected isas must be equal + or we set the result to 0, meaning "unknown". */ + if (cd->base_insn_bitsize == UNSET) + cd->base_insn_bitsize = isa->base_insn_bitsize; + else if (isa->base_insn_bitsize == cd->base_insn_bitsize) + ; /* This is ok. */ + else + cd->base_insn_bitsize = CGEN_SIZE_UNKNOWN; + + /* Set min,max insn sizes. */ + if (isa->min_insn_bitsize < cd->min_insn_bitsize) + cd->min_insn_bitsize = isa->min_insn_bitsize; + if (isa->max_insn_bitsize > cd->max_insn_bitsize) + cd->max_insn_bitsize = isa->max_insn_bitsize; + } + + /* Data derived from the mach spec. */ + for (i = 0; i < MAX_MACHS; ++i) + if (((1 << i) & machs) != 0) + { + const CGEN_MACH *mach = & mep_cgen_mach_table[i]; + + if (mach->insn_chunk_bitsize != 0) + { + if (cd->insn_chunk_bitsize != 0 && cd->insn_chunk_bitsize != mach->insn_chunk_bitsize) + { + fprintf (stderr, "mep_cgen_rebuild_tables: conflicting insn-chunk-bitsize values: `%d' vs. `%d'\n", + cd->insn_chunk_bitsize, mach->insn_chunk_bitsize); + abort (); + } + + cd->insn_chunk_bitsize = mach->insn_chunk_bitsize; + } + } + + /* Determine which hw elements are used by MACH. */ + build_hw_table (cd); + + /* Build the ifield table. */ + build_ifield_table (cd); + + /* Determine which operands are used by MACH/ISA. */ + build_operand_table (cd); + + /* Build the instruction table. */ + build_insn_table (cd); +} + +/* Initialize a cpu table and return a descriptor. + It's much like opening a file, and must be the first function called. + The arguments are a set of (type/value) pairs, terminated with + CGEN_CPU_OPEN_END. + + Currently supported values: + CGEN_CPU_OPEN_ISAS: bitmap of values in enum isa_attr + CGEN_CPU_OPEN_MACHS: bitmap of values in enum mach_attr + CGEN_CPU_OPEN_BFDMACH: specify 1 mach using bfd name + CGEN_CPU_OPEN_ENDIAN: specify endian choice + CGEN_CPU_OPEN_END: terminates arguments + + ??? Simultaneous multiple isas might not make sense, but it's not (yet) + precluded. + + ??? We only support ISO C stdargs here, not K&R. + Laziness, plus experiment to see if anything requires K&R - eventually + K&R will no longer be supported - e.g. GDB is currently trying this. */ + +CGEN_CPU_DESC +mep_cgen_cpu_open (enum cgen_cpu_open_arg arg_type, ...) +{ + CGEN_CPU_TABLE *cd = (CGEN_CPU_TABLE *) xmalloc (sizeof (CGEN_CPU_TABLE)); + static int init_p; + CGEN_BITSET *isas = 0; /* 0 = "unspecified" */ + unsigned int machs = 0; /* 0 = "unspecified" */ + enum cgen_endian endian = CGEN_ENDIAN_UNKNOWN; + va_list ap; + + if (! init_p) + { + init_tables (); + init_p = 1; + } + + memset (cd, 0, sizeof (*cd)); + + va_start (ap, arg_type); + while (arg_type != CGEN_CPU_OPEN_END) + { + switch (arg_type) + { + case CGEN_CPU_OPEN_ISAS : + isas = va_arg (ap, CGEN_BITSET *); + break; + case CGEN_CPU_OPEN_MACHS : + machs = va_arg (ap, unsigned int); + break; + case CGEN_CPU_OPEN_BFDMACH : + { + const char *name = va_arg (ap, const char *); + const CGEN_MACH *mach = + lookup_mach_via_bfd_name (mep_cgen_mach_table, name); + + machs |= 1 << mach->num; + break; + } + case CGEN_CPU_OPEN_ENDIAN : + endian = va_arg (ap, enum cgen_endian); + break; + default : + fprintf (stderr, "mep_cgen_cpu_open: unsupported argument `%d'\n", + arg_type); + abort (); /* ??? return NULL? */ + } + arg_type = va_arg (ap, enum cgen_cpu_open_arg); + } + va_end (ap); + + /* Mach unspecified means "all". */ + if (machs == 0) + machs = (1 << MAX_MACHS) - 1; + /* Base mach is always selected. */ + machs |= 1; + if (endian == CGEN_ENDIAN_UNKNOWN) + { + /* ??? If target has only one, could have a default. */ + fprintf (stderr, "mep_cgen_cpu_open: no endianness specified\n"); + abort (); + } + + cd->isas = cgen_bitset_copy (isas); + cd->machs = machs; + cd->endian = endian; + /* FIXME: for the sparc case we can determine insn-endianness statically. + The worry here is where both data and insn endian can be independently + chosen, in which case this function will need another argument. + Actually, will want to allow for more arguments in the future anyway. */ + cd->insn_endian = endian; + + /* Table (re)builder. */ + cd->rebuild_tables = mep_cgen_rebuild_tables; + mep_cgen_rebuild_tables (cd); + + /* Default to not allowing signed overflow. */ + cd->signed_overflow_ok_p = 0; + + return (CGEN_CPU_DESC) cd; +} + +/* Cover fn to mep_cgen_cpu_open to handle the simple case of 1 isa, 1 mach. + MACH_NAME is the bfd name of the mach. */ + +CGEN_CPU_DESC +mep_cgen_cpu_open_1 (const char *mach_name, enum cgen_endian endian) +{ + return mep_cgen_cpu_open (CGEN_CPU_OPEN_BFDMACH, mach_name, + CGEN_CPU_OPEN_ENDIAN, endian, + CGEN_CPU_OPEN_END); +} + +/* Close a cpu table. + ??? This can live in a machine independent file, but there's currently + no place to put this file (there's no libcgen). libopcodes is the wrong + place as some simulator ports use this but they don't use libopcodes. */ + +void +mep_cgen_cpu_close (CGEN_CPU_DESC cd) +{ + unsigned int i; + const CGEN_INSN *insns; + + if (cd->macro_insn_table.init_entries) + { + insns = cd->macro_insn_table.init_entries; + for (i = 0; i < cd->macro_insn_table.num_init_entries; ++i, ++insns) + if (CGEN_INSN_RX ((insns))) + regfree (CGEN_INSN_RX (insns)); + } + + if (cd->insn_table.init_entries) + { + insns = cd->insn_table.init_entries; + for (i = 0; i < cd->insn_table.num_init_entries; ++i, ++insns) + if (CGEN_INSN_RX (insns)) + regfree (CGEN_INSN_RX (insns)); + } + + if (cd->macro_insn_table.init_entries) + free ((CGEN_INSN *) cd->macro_insn_table.init_entries); + + if (cd->insn_table.init_entries) + free ((CGEN_INSN *) cd->insn_table.init_entries); + + if (cd->hw_table.entries) + free ((CGEN_HW_ENTRY *) cd->hw_table.entries); + + if (cd->operand_table.entries) + free ((CGEN_HW_ENTRY *) cd->operand_table.entries); + + free (cd); +} + diff --git a/opcodes/mep-desc.h b/opcodes/mep-desc.h new file mode 100644 index 00000000000..606d347f7b8 --- /dev/null +++ b/opcodes/mep-desc.h @@ -0,0 +1,342 @@ +/* CPU data header for mep. + +THIS FILE IS MACHINE GENERATED WITH CGEN. + +Copyright 1996-2005 Free Software Foundation, Inc. + +This file is part of the GNU Binutils and/or GDB, the GNU debugger. + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along +with this program; if not, write to the Free Software Foundation, Inc., +51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. + +*/ + +#ifndef MEP_CPU_H +#define MEP_CPU_H + +#include "opcode/cgen-bitset.h" + +#define CGEN_ARCH mep + +/* Given symbol S, return mep_cgen_. */ +#if defined (__STDC__) || defined (ALMOST_STDC) || defined (HAVE_STRINGIZE) +#define CGEN_SYM(s) mep##_cgen_##s +#else +#define CGEN_SYM(s) mep/**/_cgen_/**/s +#endif + + +/* Selected cpu families. */ +#define HAVE_CPU_MEPF + +#define CGEN_INSN_LSB0_P 0 + +/* Minimum size of any insn (in bytes). */ +#define CGEN_MIN_INSN_SIZE 2 + +/* Maximum size of any insn (in bytes). */ +#define CGEN_MAX_INSN_SIZE 4 + +#define CGEN_INT_INSN_P 1 + +/* Maximum number of syntax elements in an instruction. */ +#define CGEN_ACTUAL_MAX_SYNTAX_ELEMENTS 17 + +/* CGEN_MNEMONIC_OPERANDS is defined if mnemonics have operands. + e.g. In "b,a foo" the ",a" is an operand. If mnemonics have operands + we can't hash on everything up to the space. */ +#define CGEN_MNEMONIC_OPERANDS + +/* Maximum number of fields in an instruction. */ +#define CGEN_ACTUAL_MAX_IFMT_OPERANDS 11 + +/* Enums. */ + +/* Enum declaration for major opcodes. */ +typedef enum major { + MAJ_0, MAJ_1, MAJ_2, MAJ_3 + , MAJ_4, MAJ_5, MAJ_6, MAJ_7 + , MAJ_8, MAJ_9, MAJ_10, MAJ_11 + , MAJ_12, MAJ_13, MAJ_14, MAJ_15 +} MAJOR; + +/* Enum declaration for condition opcode enum. */ +typedef enum fmax_cond { + FMAX_F, FMAX_U, FMAX_E, FMAX_UE + , FMAX_L, FMAX_UL, FMAX_LE, FMAX_ULE + , FMAX_FI, FMAX_UI, FMAX_EI, FMAX_UEI + , FMAX_LI, FMAX_ULI, FMAX_LEI, FMAX_ULEI +} FMAX_COND; + +/* Attributes. */ + +/* Enum declaration for machine type selection. */ +typedef enum mach_attr { + MACH_BASE, MACH_MEP, MACH_H1, MACH_MAX +} MACH_ATTR; + +/* Enum declaration for instruction set selection. */ +typedef enum isa_attr { + ISA_MEP, ISA_EXT_CORE1, ISA_EXT_CORE2, ISA_EXT_COP2_16 + , ISA_EXT_COP2_32, ISA_EXT_COP2_48, ISA_EXT_COP2_64, ISA_MAX +} ISA_ATTR; + +/* Enum declaration for datatype to use for C intrinsics mapping. */ +typedef enum cdata_attr { + CDATA_LABEL, CDATA_REGNUM, CDATA_FMAX_FLOAT, CDATA_FMAX_INT + , CDATA_POINTER, CDATA_LONG, CDATA_ULONG, CDATA_SHORT + , CDATA_USHORT, CDATA_CHAR, CDATA_UCHAR, CDATA_CP_DATA_BUS_INT +} CDATA_ATTR; + +/* Enum declaration for . */ +typedef enum config_attr { + CONFIG_NONE, CONFIG_SIMPLE, CONFIG_FMAX +} CONFIG_ATTR; + +/* Number of architecture variants. */ +#define MAX_ISAS ((int) ISA_MAX) +#define MAX_MACHS ((int) MACH_MAX) + +/* Ifield support. */ + +/* Ifield attribute indices. */ + +/* Enum declaration for cgen_ifld attrs. */ +typedef enum cgen_ifld_attr { + CGEN_IFLD_VIRTUAL, CGEN_IFLD_PCREL_ADDR, CGEN_IFLD_ABS_ADDR, CGEN_IFLD_RESERVED + , CGEN_IFLD_SIGN_OPT, CGEN_IFLD_SIGNED, CGEN_IFLD_END_BOOLS, CGEN_IFLD_START_NBOOLS = 31 + , CGEN_IFLD_MACH, CGEN_IFLD_ISA, CGEN_IFLD_END_NBOOLS +} CGEN_IFLD_ATTR; + +/* Number of non-boolean elements in cgen_ifld_attr. */ +#define CGEN_IFLD_NBOOL_ATTRS (CGEN_IFLD_END_NBOOLS - CGEN_IFLD_START_NBOOLS - 1) + +/* cgen_ifld attribute accessor macros. */ +#define CGEN_ATTR_CGEN_IFLD_MACH_VALUE(attrs) ((attrs)->nonbool[CGEN_IFLD_MACH-CGEN_IFLD_START_NBOOLS-1].nonbitset) +#define CGEN_ATTR_CGEN_IFLD_ISA_VALUE(attrs) ((attrs)->nonbool[CGEN_IFLD_ISA-CGEN_IFLD_START_NBOOLS-1].bitset) +#define CGEN_ATTR_CGEN_IFLD_VIRTUAL_VALUE(attrs) (((attrs)->bool & (1 << CGEN_IFLD_VIRTUAL)) != 0) +#define CGEN_ATTR_CGEN_IFLD_PCREL_ADDR_VALUE(attrs) (((attrs)->bool & (1 << CGEN_IFLD_PCREL_ADDR)) != 0) +#define CGEN_ATTR_CGEN_IFLD_ABS_ADDR_VALUE(attrs) (((attrs)->bool & (1 << CGEN_IFLD_ABS_ADDR)) != 0) +#define CGEN_ATTR_CGEN_IFLD_RESERVED_VALUE(attrs) (((attrs)->bool & (1 << CGEN_IFLD_RESERVED)) != 0) +#define CGEN_ATTR_CGEN_IFLD_SIGN_OPT_VALUE(attrs) (((attrs)->bool & (1 << CGEN_IFLD_SIGN_OPT)) != 0) +#define CGEN_ATTR_CGEN_IFLD_SIGNED_VALUE(attrs) (((attrs)->bool & (1 << CGEN_IFLD_SIGNED)) != 0) + +/* Enum declaration for mep ifield types. */ +typedef enum ifield_type { + MEP_F_NIL, MEP_F_ANYOF, MEP_F_MAJOR, MEP_F_RN + , MEP_F_RN3, MEP_F_RM, MEP_F_RL, MEP_F_SUB2 + , MEP_F_SUB3, MEP_F_SUB4, MEP_F_EXT, MEP_F_CRN + , MEP_F_CSRN_HI, MEP_F_CSRN_LO, MEP_F_CSRN, MEP_F_CRNX_HI + , MEP_F_CRNX_LO, MEP_F_CRNX, MEP_F_0, MEP_F_1 + , MEP_F_2, MEP_F_3, MEP_F_4, MEP_F_5 + , MEP_F_6, MEP_F_7, MEP_F_8, MEP_F_9 + , MEP_F_10, MEP_F_11, MEP_F_12, MEP_F_13 + , MEP_F_14, MEP_F_15, MEP_F_16, MEP_F_17 + , MEP_F_18, MEP_F_19, MEP_F_20, MEP_F_21 + , MEP_F_22, MEP_F_23, MEP_F_24, MEP_F_25 + , MEP_F_26, MEP_F_27, MEP_F_28, MEP_F_29 + , MEP_F_30, MEP_F_31, MEP_F_8S8A2, MEP_F_12S4A2 + , MEP_F_17S16A2, MEP_F_24S5A2N_HI, MEP_F_24S5A2N_LO, MEP_F_24S5A2N + , MEP_F_24U5A2N_HI, MEP_F_24U5A2N_LO, MEP_F_24U5A2N, MEP_F_2U6 + , MEP_F_7U9, MEP_F_7U9A2, MEP_F_7U9A4, MEP_F_16S16 + , MEP_F_2U10, MEP_F_3U5, MEP_F_4U8, MEP_F_5U8 + , MEP_F_5U24, MEP_F_6S8, MEP_F_8S8, MEP_F_16U16 + , MEP_F_12U16, MEP_F_3U29, MEP_F_8S24, MEP_F_8S24A2 + , MEP_F_8S24A4, MEP_F_8S24A8, MEP_F_24U8A4N_HI, MEP_F_24U8A4N_LO + , MEP_F_24U8A4N, MEP_F_24U8N_HI, MEP_F_24U8N_LO, MEP_F_24U8N + , MEP_F_24U4N_HI, MEP_F_24U4N_LO, MEP_F_24U4N, MEP_F_CALLNUM + , MEP_F_CCRN_HI, MEP_F_CCRN_LO, MEP_F_CCRN, MEP_F_FMAX_0_4 + , MEP_F_FMAX_4_4, MEP_F_FMAX_8_4, MEP_F_FMAX_12_4, MEP_F_FMAX_16_4 + , MEP_F_FMAX_20_4, MEP_F_FMAX_24_4, MEP_F_FMAX_28_1, MEP_F_FMAX_29_1 + , MEP_F_FMAX_30_1, MEP_F_FMAX_31_1, MEP_F_FMAX_FRD, MEP_F_FMAX_FRN + , MEP_F_FMAX_FRM, MEP_F_FMAX_RM, MEP_F_MAX +} IFIELD_TYPE; + +#define MAX_IFLD ((int) MEP_F_MAX) + +/* Hardware attribute indices. */ + +/* Enum declaration for cgen_hw attrs. */ +typedef enum cgen_hw_attr { + CGEN_HW_VIRTUAL, CGEN_HW_CACHE_ADDR, CGEN_HW_PC, CGEN_HW_PROFILE + , CGEN_HW_IS_FLOAT, CGEN_HW_END_BOOLS, CGEN_HW_START_NBOOLS = 31, CGEN_HW_MACH + , CGEN_HW_ISA, CGEN_HW_END_NBOOLS +} CGEN_HW_ATTR; + +/* Number of non-boolean elements in cgen_hw_attr. */ +#define CGEN_HW_NBOOL_ATTRS (CGEN_HW_END_NBOOLS - CGEN_HW_START_NBOOLS - 1) + +/* cgen_hw attribute accessor macros. */ +#define CGEN_ATTR_CGEN_HW_MACH_VALUE(attrs) ((attrs)->nonbool[CGEN_HW_MACH-CGEN_HW_START_NBOOLS-1].nonbitset) +#define CGEN_ATTR_CGEN_HW_ISA_VALUE(attrs) ((attrs)->nonbool[CGEN_HW_ISA-CGEN_HW_START_NBOOLS-1].bitset) +#define CGEN_ATTR_CGEN_HW_VIRTUAL_VALUE(attrs) (((attrs)->bool & (1 << CGEN_HW_VIRTUAL)) != 0) +#define CGEN_ATTR_CGEN_HW_CACHE_ADDR_VALUE(attrs) (((attrs)->bool & (1 << CGEN_HW_CACHE_ADDR)) != 0) +#define CGEN_ATTR_CGEN_HW_PC_VALUE(attrs) (((attrs)->bool & (1 << CGEN_HW_PC)) != 0) +#define CGEN_ATTR_CGEN_HW_PROFILE_VALUE(attrs) (((attrs)->bool & (1 << CGEN_HW_PROFILE)) != 0) +#define CGEN_ATTR_CGEN_HW_IS_FLOAT_VALUE(attrs) (((attrs)->bool & (1 << CGEN_HW_IS_FLOAT)) != 0) + +/* Enum declaration for mep hardware types. */ +typedef enum cgen_hw_type { + HW_H_MEMORY, HW_H_SINT, HW_H_UINT, HW_H_ADDR + , HW_H_IADDR, HW_H_PC, HW_H_GPR, HW_H_CSR + , HW_H_CR64, HW_H_CR, HW_H_CCR, HW_H_CR_FMAX + , HW_H_CCR_FMAX, HW_H_FMAX_COMPARE_I_P, HW_MAX +} CGEN_HW_TYPE; + +#define MAX_HW ((int) HW_MAX) + +/* Operand attribute indices. */ + +/* Enum declaration for cgen_operand attrs. */ +typedef enum cgen_operand_attr { + CGEN_OPERAND_VIRTUAL, CGEN_OPERAND_PCREL_ADDR, CGEN_OPERAND_ABS_ADDR, CGEN_OPERAND_SIGN_OPT + , CGEN_OPERAND_SIGNED, CGEN_OPERAND_NEGATIVE, CGEN_OPERAND_RELAX, CGEN_OPERAND_SEM_ONLY + , CGEN_OPERAND_RELOC_IMPLIES_OVERFLOW, CGEN_OPERAND_END_BOOLS, CGEN_OPERAND_START_NBOOLS = 31, CGEN_OPERAND_MACH + , CGEN_OPERAND_ISA, CGEN_OPERAND_CDATA, CGEN_OPERAND_ALIGN, CGEN_OPERAND_END_NBOOLS +} CGEN_OPERAND_ATTR; + +/* Number of non-boolean elements in cgen_operand_attr. */ +#define CGEN_OPERAND_NBOOL_ATTRS (CGEN_OPERAND_END_NBOOLS - CGEN_OPERAND_START_NBOOLS - 1) + +/* cgen_operand attribute accessor macros. */ +#define CGEN_ATTR_CGEN_OPERAND_MACH_VALUE(attrs) ((attrs)->nonbool[CGEN_OPERAND_MACH-CGEN_OPERAND_START_NBOOLS-1].nonbitset) +#define CGEN_ATTR_CGEN_OPERAND_ISA_VALUE(attrs) ((attrs)->nonbool[CGEN_OPERAND_ISA-CGEN_OPERAND_START_NBOOLS-1].bitset) +#define CGEN_ATTR_CGEN_OPERAND_CDATA_VALUE(attrs) ((attrs)->nonbool[CGEN_OPERAND_CDATA-CGEN_OPERAND_START_NBOOLS-1].nonbitset) +#define CGEN_ATTR_CGEN_OPERAND_ALIGN_VALUE(attrs) ((attrs)->nonbool[CGEN_OPERAND_ALIGN-CGEN_OPERAND_START_NBOOLS-1].nonbitset) +#define CGEN_ATTR_CGEN_OPERAND_VIRTUAL_VALUE(attrs) (((attrs)->bool & (1 << CGEN_OPERAND_VIRTUAL)) != 0) +#define CGEN_ATTR_CGEN_OPERAND_PCREL_ADDR_VALUE(attrs) (((attrs)->bool & (1 << CGEN_OPERAND_PCREL_ADDR)) != 0) +#define CGEN_ATTR_CGEN_OPERAND_ABS_ADDR_VALUE(attrs) (((attrs)->bool & (1 << CGEN_OPERAND_ABS_ADDR)) != 0) +#define CGEN_ATTR_CGEN_OPERAND_SIGN_OPT_VALUE(attrs) (((attrs)->bool & (1 << CGEN_OPERAND_SIGN_OPT)) != 0) +#define CGEN_ATTR_CGEN_OPERAND_SIGNED_VALUE(attrs) (((attrs)->bool & (1 << CGEN_OPERAND_SIGNED)) != 0) +#define CGEN_ATTR_CGEN_OPERAND_NEGATIVE_VALUE(attrs) (((attrs)->bool & (1 << CGEN_OPERAND_NEGATIVE)) != 0) +#define CGEN_ATTR_CGEN_OPERAND_RELAX_VALUE(attrs) (((attrs)->bool & (1 << CGEN_OPERAND_RELAX)) != 0) +#define CGEN_ATTR_CGEN_OPERAND_SEM_ONLY_VALUE(attrs) (((attrs)->bool & (1 << CGEN_OPERAND_SEM_ONLY)) != 0) +#define CGEN_ATTR_CGEN_OPERAND_RELOC_IMPLIES_OVERFLOW_VALUE(attrs) (((attrs)->bool & (1 << CGEN_OPERAND_RELOC_IMPLIES_OVERFLOW)) != 0) + +/* Enum declaration for mep operand types. */ +typedef enum cgen_operand_type { + MEP_OPERAND_PC, MEP_OPERAND_R0, MEP_OPERAND_RN, MEP_OPERAND_RM + , MEP_OPERAND_RL, MEP_OPERAND_RN3, MEP_OPERAND_RMA, MEP_OPERAND_RNC + , MEP_OPERAND_RNUC, MEP_OPERAND_RNS, MEP_OPERAND_RNUS, MEP_OPERAND_RNL + , MEP_OPERAND_RNUL, MEP_OPERAND_RN3C, MEP_OPERAND_RN3UC, MEP_OPERAND_RN3S + , MEP_OPERAND_RN3US, MEP_OPERAND_RN3L, MEP_OPERAND_RN3UL, MEP_OPERAND_LP + , MEP_OPERAND_SAR, MEP_OPERAND_HI, MEP_OPERAND_LO, MEP_OPERAND_MB0 + , MEP_OPERAND_ME0, MEP_OPERAND_MB1, MEP_OPERAND_ME1, MEP_OPERAND_PSW + , MEP_OPERAND_EPC, MEP_OPERAND_EXC, MEP_OPERAND_NPC, MEP_OPERAND_DBG + , MEP_OPERAND_DEPC, MEP_OPERAND_OPT, MEP_OPERAND_R1, MEP_OPERAND_TP + , MEP_OPERAND_SP, MEP_OPERAND_TPR, MEP_OPERAND_SPR, MEP_OPERAND_CSRN + , MEP_OPERAND_CSRN_IDX, MEP_OPERAND_CRN64, MEP_OPERAND_CRN, MEP_OPERAND_CRNX64 + , MEP_OPERAND_CRNX, MEP_OPERAND_CCRN, MEP_OPERAND_CCCC, MEP_OPERAND_PCREL8A2 + , MEP_OPERAND_PCREL12A2, MEP_OPERAND_PCREL17A2, MEP_OPERAND_PCREL24A2, MEP_OPERAND_PCABS24A2 + , MEP_OPERAND_SDISP16, MEP_OPERAND_SIMM16, MEP_OPERAND_UIMM16, MEP_OPERAND_CODE16 + , MEP_OPERAND_UDISP2, MEP_OPERAND_UIMM2, MEP_OPERAND_SIMM6, MEP_OPERAND_SIMM8 + , MEP_OPERAND_ADDR24A4, MEP_OPERAND_CODE24, MEP_OPERAND_CALLNUM, MEP_OPERAND_UIMM3 + , MEP_OPERAND_UIMM4, MEP_OPERAND_UIMM5, MEP_OPERAND_UDISP7, MEP_OPERAND_UDISP7A2 + , MEP_OPERAND_UDISP7A4, MEP_OPERAND_UIMM7A4, MEP_OPERAND_UIMM24, MEP_OPERAND_CIMM4 + , MEP_OPERAND_CIMM5, MEP_OPERAND_CDISP8, MEP_OPERAND_CDISP8A2, MEP_OPERAND_CDISP8A4 + , MEP_OPERAND_CDISP8A8, MEP_OPERAND_ZERO, MEP_OPERAND_CP_FLAG, MEP_OPERAND_FMAX_FRD + , MEP_OPERAND_FMAX_FRN, MEP_OPERAND_FMAX_FRM, MEP_OPERAND_FMAX_FRD_INT, MEP_OPERAND_FMAX_FRN_INT + , MEP_OPERAND_FMAX_CCRN, MEP_OPERAND_FMAX_CIRR, MEP_OPERAND_FMAX_CBCR, MEP_OPERAND_FMAX_CERR + , MEP_OPERAND_FMAX_RM, MEP_OPERAND_FMAX_COMPARE_I_P, MEP_OPERAND_MAX +} CGEN_OPERAND_TYPE; + +/* Number of operands types. */ +#define MAX_OPERANDS 90 + +/* Maximum number of operands referenced by any insn. */ +#define MAX_OPERAND_INSTANCES 8 + +/* Insn attribute indices. */ + +/* Enum declaration for cgen_insn attrs. */ +typedef enum cgen_insn_attr { + CGEN_INSN_ALIAS, CGEN_INSN_VIRTUAL, CGEN_INSN_UNCOND_CTI, CGEN_INSN_COND_CTI + , CGEN_INSN_SKIP_CTI, CGEN_INSN_DELAY_SLOT, CGEN_INSN_RELAXABLE, CGEN_INSN_RELAXED + , CGEN_INSN_NO_DIS, CGEN_INSN_PBB, CGEN_INSN_OPTIONAL_BIT_INSN, CGEN_INSN_OPTIONAL_MUL_INSN + , CGEN_INSN_OPTIONAL_DIV_INSN, CGEN_INSN_OPTIONAL_DEBUG_INSN, CGEN_INSN_OPTIONAL_LDZ_INSN, CGEN_INSN_OPTIONAL_ABS_INSN + , CGEN_INSN_OPTIONAL_AVE_INSN, CGEN_INSN_OPTIONAL_MINMAX_INSN, CGEN_INSN_OPTIONAL_CLIP_INSN, CGEN_INSN_OPTIONAL_SAT_INSN + , CGEN_INSN_OPTIONAL_UCI_INSN, CGEN_INSN_OPTIONAL_DSP_INSN, CGEN_INSN_OPTIONAL_CP_INSN, CGEN_INSN_OPTIONAL_CP64_INSN + , CGEN_INSN_OPTIONAL_VLIW64, CGEN_INSN_MAY_TRAP, CGEN_INSN_VLIW_ALONE, CGEN_INSN_VLIW_NO_CORE_NOP + , CGEN_INSN_VLIW_NO_COP_NOP, CGEN_INSN_VLIW64_NO_MATCHING_NOP, CGEN_INSN_VLIW32_NO_MATCHING_NOP, CGEN_INSN_VOLATILE + , CGEN_INSN_END_BOOLS, CGEN_INSN_START_NBOOLS = 31, CGEN_INSN_MACH, CGEN_INSN_ISA + , CGEN_INSN_LATENCY, CGEN_INSN_CONFIG, CGEN_INSN_END_NBOOLS +} CGEN_INSN_ATTR; + +/* Number of non-boolean elements in cgen_insn_attr. */ +#define CGEN_INSN_NBOOL_ATTRS (CGEN_INSN_END_NBOOLS - CGEN_INSN_START_NBOOLS - 1) + +/* cgen_insn attribute accessor macros. */ +#define CGEN_ATTR_CGEN_INSN_MACH_VALUE(attrs) ((attrs)->nonbool[CGEN_INSN_MACH-CGEN_INSN_START_NBOOLS-1].nonbitset) +#define CGEN_ATTR_CGEN_INSN_ISA_VALUE(attrs) ((attrs)->nonbool[CGEN_INSN_ISA-CGEN_INSN_START_NBOOLS-1].bitset) +#define CGEN_ATTR_CGEN_INSN_LATENCY_VALUE(attrs) ((attrs)->nonbool[CGEN_INSN_LATENCY-CGEN_INSN_START_NBOOLS-1].nonbitset) +#define CGEN_ATTR_CGEN_INSN_CONFIG_VALUE(attrs) ((attrs)->nonbool[CGEN_INSN_CONFIG-CGEN_INSN_START_NBOOLS-1].nonbitset) +#define CGEN_ATTR_CGEN_INSN_ALIAS_VALUE(attrs) (((attrs)->bool & (1 << CGEN_INSN_ALIAS)) != 0) +#define CGEN_ATTR_CGEN_INSN_VIRTUAL_VALUE(attrs) (((attrs)->bool & (1 << CGEN_INSN_VIRTUAL)) != 0) +#define CGEN_ATTR_CGEN_INSN_UNCOND_CTI_VALUE(attrs) (((attrs)->bool & (1 << CGEN_INSN_UNCOND_CTI)) != 0) +#define CGEN_ATTR_CGEN_INSN_COND_CTI_VALUE(attrs) (((attrs)->bool & (1 << CGEN_INSN_COND_CTI)) != 0) +#define CGEN_ATTR_CGEN_INSN_SKIP_CTI_VALUE(attrs) (((attrs)->bool & (1 << CGEN_INSN_SKIP_CTI)) != 0) +#define CGEN_ATTR_CGEN_INSN_DELAY_SLOT_VALUE(attrs) (((attrs)->bool & (1 << CGEN_INSN_DELAY_SLOT)) != 0) +#define CGEN_ATTR_CGEN_INSN_RELAXABLE_VALUE(attrs) (((attrs)->bool & (1 << CGEN_INSN_RELAXABLE)) != 0) +#define CGEN_ATTR_CGEN_INSN_RELAXED_VALUE(attrs) (((attrs)->bool & (1 << CGEN_INSN_RELAXED)) != 0) +#define CGEN_ATTR_CGEN_INSN_NO_DIS_VALUE(attrs) (((attrs)->bool & (1 << CGEN_INSN_NO_DIS)) != 0) +#define CGEN_ATTR_CGEN_INSN_PBB_VALUE(attrs) (((attrs)->bool & (1 << CGEN_INSN_PBB)) != 0) +#define CGEN_ATTR_CGEN_INSN_OPTIONAL_BIT_INSN_VALUE(attrs) (((attrs)->bool & (1 << CGEN_INSN_OPTIONAL_BIT_INSN)) != 0) +#define CGEN_ATTR_CGEN_INSN_OPTIONAL_MUL_INSN_VALUE(attrs) (((attrs)->bool & (1 << CGEN_INSN_OPTIONAL_MUL_INSN)) != 0) +#define CGEN_ATTR_CGEN_INSN_OPTIONAL_DIV_INSN_VALUE(attrs) (((attrs)->bool & (1 << CGEN_INSN_OPTIONAL_DIV_INSN)) != 0) +#define CGEN_ATTR_CGEN_INSN_OPTIONAL_DEBUG_INSN_VALUE(attrs) (((attrs)->bool & (1 << CGEN_INSN_OPTIONAL_DEBUG_INSN)) != 0) +#define CGEN_ATTR_CGEN_INSN_OPTIONAL_LDZ_INSN_VALUE(attrs) (((attrs)->bool & (1 << CGEN_INSN_OPTIONAL_LDZ_INSN)) != 0) +#define CGEN_ATTR_CGEN_INSN_OPTIONAL_ABS_INSN_VALUE(attrs) (((attrs)->bool & (1 << CGEN_INSN_OPTIONAL_ABS_INSN)) != 0) +#define CGEN_ATTR_CGEN_INSN_OPTIONAL_AVE_INSN_VALUE(attrs) (((attrs)->bool & (1 << CGEN_INSN_OPTIONAL_AVE_INSN)) != 0) +#define CGEN_ATTR_CGEN_INSN_OPTIONAL_MINMAX_INSN_VALUE(attrs) (((attrs)->bool & (1 << CGEN_INSN_OPTIONAL_MINMAX_INSN)) != 0) +#define CGEN_ATTR_CGEN_INSN_OPTIONAL_CLIP_INSN_VALUE(attrs) (((attrs)->bool & (1 << CGEN_INSN_OPTIONAL_CLIP_INSN)) != 0) +#define CGEN_ATTR_CGEN_INSN_OPTIONAL_SAT_INSN_VALUE(attrs) (((attrs)->bool & (1 << CGEN_INSN_OPTIONAL_SAT_INSN)) != 0) +#define CGEN_ATTR_CGEN_INSN_OPTIONAL_UCI_INSN_VALUE(attrs) (((attrs)->bool & (1 << CGEN_INSN_OPTIONAL_UCI_INSN)) != 0) +#define CGEN_ATTR_CGEN_INSN_OPTIONAL_DSP_INSN_VALUE(attrs) (((attrs)->bool & (1 << CGEN_INSN_OPTIONAL_DSP_INSN)) != 0) +#define CGEN_ATTR_CGEN_INSN_OPTIONAL_CP_INSN_VALUE(attrs) (((attrs)->bool & (1 << CGEN_INSN_OPTIONAL_CP_INSN)) != 0) +#define CGEN_ATTR_CGEN_INSN_OPTIONAL_CP64_INSN_VALUE(attrs) (((attrs)->bool & (1 << CGEN_INSN_OPTIONAL_CP64_INSN)) != 0) +#define CGEN_ATTR_CGEN_INSN_OPTIONAL_VLIW64_VALUE(attrs) (((attrs)->bool & (1 << CGEN_INSN_OPTIONAL_VLIW64)) != 0) +#define CGEN_ATTR_CGEN_INSN_MAY_TRAP_VALUE(attrs) (((attrs)->bool & (1 << CGEN_INSN_MAY_TRAP)) != 0) +#define CGEN_ATTR_CGEN_INSN_VLIW_ALONE_VALUE(attrs) (((attrs)->bool & (1 << CGEN_INSN_VLIW_ALONE)) != 0) +#define CGEN_ATTR_CGEN_INSN_VLIW_NO_CORE_NOP_VALUE(attrs) (((attrs)->bool & (1 << CGEN_INSN_VLIW_NO_CORE_NOP)) != 0) +#define CGEN_ATTR_CGEN_INSN_VLIW_NO_COP_NOP_VALUE(attrs) (((attrs)->bool & (1 << CGEN_INSN_VLIW_NO_COP_NOP)) != 0) +#define CGEN_ATTR_CGEN_INSN_VLIW64_NO_MATCHING_NOP_VALUE(attrs) (((attrs)->bool & (1 << CGEN_INSN_VLIW64_NO_MATCHING_NOP)) != 0) +#define CGEN_ATTR_CGEN_INSN_VLIW32_NO_MATCHING_NOP_VALUE(attrs) (((attrs)->bool & (1 << CGEN_INSN_VLIW32_NO_MATCHING_NOP)) != 0) +#define CGEN_ATTR_CGEN_INSN_VOLATILE_VALUE(attrs) (((attrs)->bool & (1 << CGEN_INSN_VOLATILE)) != 0) + +/* cgen.h uses things we just defined. */ +#include "opcode/cgen.h" + +extern const struct cgen_ifld mep_cgen_ifld_table[]; + +/* Attributes. */ +extern const CGEN_ATTR_TABLE mep_cgen_hardware_attr_table[]; +extern const CGEN_ATTR_TABLE mep_cgen_ifield_attr_table[]; +extern const CGEN_ATTR_TABLE mep_cgen_operand_attr_table[]; +extern const CGEN_ATTR_TABLE mep_cgen_insn_attr_table[]; + +/* Hardware decls. */ + +extern CGEN_KEYWORD mep_cgen_opval_h_gpr; +extern CGEN_KEYWORD mep_cgen_opval_h_csr; +extern CGEN_KEYWORD mep_cgen_opval_h_cr64; +extern CGEN_KEYWORD mep_cgen_opval_h_cr; +extern CGEN_KEYWORD mep_cgen_opval_h_ccr; +extern CGEN_KEYWORD mep_cgen_opval_h_cr_fmax; +extern CGEN_KEYWORD mep_cgen_opval_h_ccr_fmax; + +extern const CGEN_HW_ENTRY mep_cgen_hw_table[]; + + + +#endif /* MEP_CPU_H */ diff --git a/opcodes/mep-dis.c b/opcodes/mep-dis.c new file mode 100644 index 00000000000..769a80afcd4 --- /dev/null +++ b/opcodes/mep-dis.c @@ -0,0 +1,1205 @@ +/* Disassembler interface for targets using CGEN. -*- C -*- + CGEN: Cpu tools GENerator + + THIS FILE IS MACHINE GENERATED WITH CGEN. + - the resultant file is machine generated, cgen-dis.in isn't + + Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2005 + Free Software Foundation, Inc. + + This file is part of the GNU Binutils and GDB, the GNU debugger. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ + +/* ??? Eventually more and more of this stuff can go to cpu-independent files. + Keep that in mind. */ + +#include "sysdep.h" +#include +#include "ansidecl.h" +#include "dis-asm.h" +#include "bfd.h" +#include "symcat.h" +#include "libiberty.h" +#include "mep-desc.h" +#include "mep-opc.h" +#include "opintl.h" + +/* Default text to print if an instruction isn't recognized. */ +#define UNKNOWN_INSN_MSG _("*unknown*") + +static void print_normal + (CGEN_CPU_DESC, void *, long, unsigned int, bfd_vma, int); +static void print_address + (CGEN_CPU_DESC, void *, bfd_vma, unsigned int, bfd_vma, int) ATTRIBUTE_UNUSED; +static void print_keyword + (CGEN_CPU_DESC, void *, CGEN_KEYWORD *, long, unsigned int) ATTRIBUTE_UNUSED; +static void print_insn_normal + (CGEN_CPU_DESC, void *, const CGEN_INSN *, CGEN_FIELDS *, bfd_vma, int); +static int print_insn + (CGEN_CPU_DESC, bfd_vma, disassemble_info *, bfd_byte *, unsigned); +static int default_print_insn + (CGEN_CPU_DESC, bfd_vma, disassemble_info *) ATTRIBUTE_UNUSED; +static int read_insn + (CGEN_CPU_DESC, bfd_vma, disassemble_info *, bfd_byte *, int, CGEN_EXTRACT_INFO *, + unsigned long *); + +/* -- disassembler routines inserted here. */ + +/* -- dis.c */ + +#include "elf/mep.h" +#include "elf-bfd.h" + +#define CGEN_VALIDATE_INSN_SUPPORTED + +static void print_tpreg (CGEN_CPU_DESC, PTR, CGEN_KEYWORD *, long, unsigned int); +static void print_spreg (CGEN_CPU_DESC, PTR, CGEN_KEYWORD *, long, unsigned int); + +static void +print_tpreg (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED, PTR dis_info, + CGEN_KEYWORD *table ATTRIBUTE_UNUSED, long val ATTRIBUTE_UNUSED, + unsigned int flags ATTRIBUTE_UNUSED) +{ + disassemble_info *info = (disassemble_info *) dis_info; + + (*info->fprintf_func) (info->stream, "$tp"); +} + +static void +print_spreg (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED, PTR dis_info, + CGEN_KEYWORD *table ATTRIBUTE_UNUSED, long val ATTRIBUTE_UNUSED, + unsigned int flags ATTRIBUTE_UNUSED) +{ + disassemble_info *info = (disassemble_info *) dis_info; + + (*info->fprintf_func) (info->stream, "$sp"); +} + +/* begin-cop-ip-print-handlers */ +static void +print_fmax_cr (CGEN_CPU_DESC cd, + void *dis_info, + CGEN_KEYWORD *keyword_table ATTRIBUTE_UNUSED, + long value, + unsigned int attrs) +{ + print_keyword (cd, dis_info, & mep_cgen_opval_h_cr_fmax, value, attrs); +} +static void +print_fmax_ccr (CGEN_CPU_DESC cd, + void *dis_info, + CGEN_KEYWORD *keyword_table ATTRIBUTE_UNUSED, + long value, + unsigned int attrs) +{ + print_keyword (cd, dis_info, & mep_cgen_opval_h_ccr_fmax, value, attrs); +} +/* end-cop-ip-print-handlers */ + +/************************************************************\ +*********************** Experimental ************************* +\************************************************************/ + +#undef CGEN_PRINT_INSN +#define CGEN_PRINT_INSN mep_print_insn + +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) +{ + int i; + int status = 0; + /* char insnbuf[CGEN_MAX_INSN_SIZE]; */ + bfd_byte insnbuf[64]; + + /* If corelength > 0 then there is a core insn present. It + will be at the beginning of the buffer. After printing + the core insn, we need to print the + on the next line. */ + if (corelength > 0) + { + int my_status = 0; + + for (i = 0; i < corelength; i++ ) + insnbuf[i] = buf[i]; + cd->isas = & MEP_CORE_ISA; + + my_status = print_insn (cd, pc, info, insnbuf, corelength); + if (my_status != corelength) + { + (*info->fprintf_func) (info->stream, UNKNOWN_INSN_MSG); + my_status = corelength; + } + status += my_status; + + /* Print the + to indicate that the following copro insn is */ + /* part of a vliw group. */ + if (copro1length > 0) + (*info->fprintf_func) (info->stream, " + "); + } + + /* Now all that is left to be processed is the coprocessor insns + In vliw mode, there will always be one. Its positioning will + be from byte corelength to byte corelength+copro1length -1. + No need to check for existence. Also, the first vliw insn, + will, as spec'd, always be at least as long as the core insn + so we don't need to flush the buffer. */ + if (copro1length > 0) + { + int my_status = 0; + + for (i = corelength; i < corelength + copro1length; i++ ) + insnbuf[i - corelength] = buf[i]; + + switch (copro1length) + { + case 0: + break; + case 2: + cd->isas = & MEP_COP16_ISA; + break; + case 4: + cd->isas = & MEP_COP32_ISA; + break; + case 6: + cd->isas = & MEP_COP48_ISA; + break; + case 8: + cd->isas = & MEP_COP64_ISA; + break; + default: + /* Shouldn't be anything but 16,32,48,64. */ + break; + } + + my_status = print_insn (cd, pc, info, insnbuf, copro1length); + + if (my_status != copro1length) + { + (*info->fprintf_func) (info->stream, UNKNOWN_INSN_MSG); + my_status = copro1length; + } + status += my_status; + } + +#if 0 + /* Now we need to process the second copro insn if it exists. We + have no guarantee that the second copro insn will be longer + than the first, so we have to flush the buffer if we are have + a second copro insn to process. If present, this insn will + be in the position from byte corelength+copro1length to byte + corelength+copro1length+copro2length-1 (which better equal 8 + or else we're in big trouble. */ + if (copro2length > 0) + { + int my_status = 0; + + for (i = 0; i < 64 ; i++) + insnbuf[i] = 0; + + for (i = corelength + copro1length; i < 64; i++) + insnbuf[i - (corelength + copro1length)] = buf[i]; + + switch (copro2length) + { + case 2: + cd->isas = 1 << ISA_EXT_COP1_16; + break; + case 4: + cd->isas = 1 << ISA_EXT_COP1_32; + break; + case 6: + cd->isas = 1 << ISA_EXT_COP1_48; + break; + case 8: + cd->isas = 1 << ISA_EXT_COP1_64; + break; + default: + /* Shouldn't be anything but 16,32,48,64. */ + break; + } + + my_status = print_insn (cd, pc, info, insnbuf, copro2length); + + if (my_status != copro2length) + { + (*info->fprintf_func) (info->stream, UNKNOWN_INSN_MSG); + my_status = copro2length; + } + + status += my_status; + } +#endif + + /* Status should now be the number of bytes that were printed + which should be 4 for VLIW32 mode and 64 for VLIW64 mode. */ + + if ((!MEP_VLIW64 && (status != 4)) || (MEP_VLIW64 && (status != 8))) + return -1; + else + return status; +} + +/* The two functions mep_examine_vliw[32,64]_insns are used find out + which vliw combinaion (16 bit core with 48 bit copro, 32 bit core + with 32 bit copro, etc.) is present. Later on, when internally + parallel coprocessors are handled, only these functions should + need to be changed. + + At this time only the following combinations are supported: + + VLIW32 Mode: + 16 bit core insn (core) and 16 bit coprocessor insn (cop1) + 32 bit core insn (core) + 32 bit coprocessor insn (cop1) + Note: As of this time, I do not believe we have enough information + to distinguish a 32 bit core insn from a 32 bit cop insn. Also, + no 16 bit coprocessor insns have been specified. + + VLIW64 Mode: + 16 bit core insn (core) and 48 bit coprocessor insn (cop1) + 32 bit core insn (core) and 32 bit coprocessor insn (cop1) + 64 bit coprocessor insn (cop1) + + The framework for an internally parallel coprocessor is also + present (2nd coprocessor insn is cop2), but at this time it + is not used. This only appears to be valid in VLIW64 mode. */ + +static int +mep_examine_vliw32_insns (CGEN_CPU_DESC cd, bfd_vma pc, disassemble_info *info) +{ + int status; + int buflength; + int corebuflength; + int cop1buflength; + int cop2buflength; + bfd_byte buf[CGEN_MAX_INSN_SIZE]; + char indicator16[1]; + char indicatorcop32[2]; + + /* At this time we're not supporting internally parallel coprocessors, + so cop2buflength will always be 0. */ + cop2buflength = 0; + + /* Read in 32 bits. */ + buflength = 4; /* VLIW insn spans 4 bytes. */ + status = (*info->read_memory_func) (pc, buf, buflength, info); + + if (status != 0) + { + (*info->memory_error_func) (status, pc, info); + return -1; + } + + /* Put the big endian representation of the bytes to be examined + in the temporary buffers for examination. */ + + if (info->endian == BFD_ENDIAN_BIG) + { + indicator16[0] = buf[0]; + indicatorcop32[0] = buf[0]; + indicatorcop32[1] = buf[1]; + } + else + { + indicator16[0] = buf[1]; + indicatorcop32[0] = buf[1]; + indicatorcop32[1] = buf[0]; + } + + /* If the two high order bits are 00, 01 or 10, we have a 16 bit + core insn and a 48 bit copro insn. */ + + if ((indicator16[0] & 0x80) && (indicator16[0] & 0x40)) + { + if ((indicatorcop32[0] & 0xf0) == 0xf0 && (indicatorcop32[1] & 0x07) == 0x07) + { + /* We have a 32 bit copro insn. */ + corebuflength = 0; + /* All 4 4ytes are one copro insn. */ + cop1buflength = 4; + } + else + { + /* We have a 32 bit core. */ + corebuflength = 4; + cop1buflength = 0; + } + } + else + { + /* We have a 16 bit core insn and a 16 bit copro insn. */ + corebuflength = 2; + cop1buflength = 2; + } + + /* Now we have the distrubution set. Print them out. */ + status = mep_print_vliw_insns (cd, pc, info, buf, corebuflength, + cop1buflength, cop2buflength); + + return status; +} + +static int +mep_examine_vliw64_insns (CGEN_CPU_DESC cd, bfd_vma pc, disassemble_info *info) +{ + int status; + int buflength; + int corebuflength; + int cop1buflength; + int cop2buflength; + bfd_byte buf[CGEN_MAX_INSN_SIZE]; + char indicator16[1]; + char indicator64[4]; + + /* At this time we're not supporting internally parallel + coprocessors, so cop2buflength will always be 0. */ + cop2buflength = 0; + + /* Read in 64 bits. */ + buflength = 8; /* VLIW insn spans 8 bytes. */ + status = (*info->read_memory_func) (pc, buf, buflength, info); + + if (status != 0) + { + (*info->memory_error_func) (status, pc, info); + return -1; + } + + /* We have all 64 bits in the buffer now. We have to figure out + what combination of instruction sizes are present. The two + high order bits will indicate whether or not we have a 16 bit + core insn or not. If not, then we have to look at the 7,8th + bytes to tell whether we have 64 bit copro insn or a 32 bit + core insn with a 32 bit copro insn. Endianness will make a + difference here. */ + + /* Put the big endian representation of the bytes to be examined + in the temporary buffers for examination. */ + + /* indicator16[0] = buf[0]; */ + if (info->endian == BFD_ENDIAN_BIG) + { + indicator16[0] = buf[0]; + indicator64[0] = buf[0]; + indicator64[1] = buf[1]; + indicator64[2] = buf[2]; + indicator64[3] = buf[3]; + } + else + { + indicator16[0] = buf[1]; + indicator64[0] = buf[1]; + indicator64[1] = buf[0]; + indicator64[2] = buf[3]; + indicator64[3] = buf[2]; + } + + /* If the two high order bits are 00, 01 or 10, we have a 16 bit + core insn and a 48 bit copro insn. */ + + if ((indicator16[0] & 0x80) && (indicator16[0] & 0x40)) + { + if ((indicator64[0] & 0xf0) == 0xf0 && (indicator64[1] & 0x07) == 0x07 + && ((indicator64[2] & 0xfe) != 0xf0 || (indicator64[3] & 0xf4) != 0)) + { + /* We have a 64 bit copro insn. */ + corebuflength = 0; + /* All 8 bytes are one copro insn. */ + cop1buflength = 8; + } + else + { + /* We have a 32 bit core insn and a 32 bit copro insn. */ + corebuflength = 4; + cop1buflength = 4; + } + } + else + { + /* We have a 16 bit core insn and a 48 bit copro insn. */ + corebuflength = 2; + cop1buflength = 6; + } + + /* Now we have the distrubution set. Print them out. */ + status = mep_print_vliw_insns (cd, pc, info, buf, corebuflength, + cop1buflength, cop2buflength); + + return status; +} + +static int +mep_print_insn (CGEN_CPU_DESC cd, bfd_vma pc, disassemble_info *info) +{ + int status; + + /* Extract and adapt to configuration number, if available. */ + if (info->section && info->section->owner) + { + bfd *abfd = info->section->owner; + mep_config_index = abfd->tdata.elf_obj_data->elf_header->e_flags & EF_MEP_INDEX_MASK; + /* This instantly redefines MEP_CONFIG, MEP_OMASK, .... MEP_VLIW64 */ + } + + /* Picking the right ISA bitmask for the current context is tricky. */ + if (info->section) + { + if (info->section->flags & SEC_MEP_VLIW) + { + /* Are we in 32 or 64 bit vliw mode? */ + if (MEP_VLIW64) + status = mep_examine_vliw64_insns (cd, pc, info); + else + status = mep_examine_vliw32_insns (cd, pc, info); + /* Both the above branches set their own isa bitmasks. */ + } + else + { + cd->isas = & MEP_CORE_ISA; + status = default_print_insn (cd, pc, info); + } + } + else /* sid or gdb */ + { + status = default_print_insn (cd, pc, info); + } + + return status; +} + + +/* -- opc.c */ + +void mep_cgen_print_operand + (CGEN_CPU_DESC, int, PTR, CGEN_FIELDS *, void const *, bfd_vma, int); + +/* Main entry point for printing operands. + XINFO is a `void *' and not a `disassemble_info *' to not put a requirement + of dis-asm.h on cgen.h. + + This function is basically just a big switch statement. Earlier versions + used tables to look up the function to use, but + - if the table contains both assembler and disassembler functions then + the disassembler contains much of the assembler and vice-versa, + - there's a lot of inlining possibilities as things grow, + - using a switch statement avoids the function call overhead. + + This function could be moved into `print_insn_normal', but keeping it + separate makes clear the interface between `print_insn_normal' and each of + the handlers. */ + +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) +{ + disassemble_info *info = (disassemble_info *) xinfo; + + switch (opindex) + { + case MEP_OPERAND_ADDR24A4 : + print_normal (cd, info, fields->f_24u8a4n, 0|(1<f_callnum, 0|(1<f_rm, 0, pc, length); + break; + case MEP_OPERAND_CCRN : + print_keyword (cd, info, & mep_cgen_opval_h_ccr, fields->f_ccrn, 0|(1<f_8s24, 0|(1<f_8s24a2, 0|(1<f_8s24a4, 0|(1<f_8s24a8, 0|(1<f_rn, 0, pc, length); + break; + case MEP_OPERAND_CIMM5 : + print_normal (cd, info, fields->f_5u24, 0, pc, length); + break; + case MEP_OPERAND_CODE16 : + print_normal (cd, info, fields->f_16u16, 0, pc, length); + break; + case MEP_OPERAND_CODE24 : + print_normal (cd, info, fields->f_24u4n, 0|(1<f_crn, 0); + break; + case MEP_OPERAND_CRN64 : + print_keyword (cd, info, & mep_cgen_opval_h_cr64, fields->f_crn, 0); + break; + case MEP_OPERAND_CRNX : + print_keyword (cd, info, & mep_cgen_opval_h_cr, fields->f_crnx, 0|(1<f_crnx, 0|(1<f_csrn, 0|(1<f_csrn, 0|(1<f_fmax_4_4, 0); + break; + case MEP_OPERAND_FMAX_FRD : + print_fmax_cr (cd, info, & mep_cgen_opval_h_cr, fields->f_fmax_frd, 0|(1<f_fmax_frd, 0|(1<f_fmax_frm, 0|(1<f_fmax_frn, 0|(1<f_fmax_frn, 0|(1<f_fmax_rm, 0); + break; + case MEP_OPERAND_HI : + print_keyword (cd, info, & mep_cgen_opval_h_csr, 0, 0); + break; + case MEP_OPERAND_LO : + print_keyword (cd, info, & mep_cgen_opval_h_csr, 0, 0); + break; + case MEP_OPERAND_LP : + print_keyword (cd, info, & mep_cgen_opval_h_csr, 0, 0); + break; + case MEP_OPERAND_MB0 : + print_keyword (cd, info, & mep_cgen_opval_h_csr, 0, 0); + break; + case MEP_OPERAND_MB1 : + print_keyword (cd, info, & mep_cgen_opval_h_csr, 0, 0); + break; + case MEP_OPERAND_ME0 : + print_keyword (cd, info, & mep_cgen_opval_h_csr, 0, 0); + break; + case MEP_OPERAND_ME1 : + print_keyword (cd, info, & mep_cgen_opval_h_csr, 0, 0); + break; + case MEP_OPERAND_NPC : + print_keyword (cd, info, & mep_cgen_opval_h_csr, 0, 0); + break; + case MEP_OPERAND_OPT : + print_keyword (cd, info, & mep_cgen_opval_h_csr, 0, 0); + break; + case MEP_OPERAND_PCABS24A2 : + print_address (cd, info, fields->f_24u5a2n, 0|(1<f_12s4a2, 0|(1<f_17s16a2, 0|(1<f_24s5a2n, 0|(1<f_8s8a2, 0|(1<f_rl, 0); + break; + case MEP_OPERAND_RM : + print_keyword (cd, info, & mep_cgen_opval_h_gpr, fields->f_rm, 0); + break; + case MEP_OPERAND_RMA : + print_keyword (cd, info, & mep_cgen_opval_h_gpr, fields->f_rm, 0); + break; + case MEP_OPERAND_RN : + print_keyword (cd, info, & mep_cgen_opval_h_gpr, fields->f_rn, 0); + break; + case MEP_OPERAND_RN3 : + print_keyword (cd, info, & mep_cgen_opval_h_gpr, fields->f_rn3, 0); + break; + case MEP_OPERAND_RN3C : + print_keyword (cd, info, & mep_cgen_opval_h_gpr, fields->f_rn3, 0); + break; + case MEP_OPERAND_RN3L : + print_keyword (cd, info, & mep_cgen_opval_h_gpr, fields->f_rn3, 0); + break; + case MEP_OPERAND_RN3S : + print_keyword (cd, info, & mep_cgen_opval_h_gpr, fields->f_rn3, 0); + break; + case MEP_OPERAND_RN3UC : + print_keyword (cd, info, & mep_cgen_opval_h_gpr, fields->f_rn3, 0); + break; + case MEP_OPERAND_RN3UL : + print_keyword (cd, info, & mep_cgen_opval_h_gpr, fields->f_rn3, 0); + break; + case MEP_OPERAND_RN3US : + print_keyword (cd, info, & mep_cgen_opval_h_gpr, fields->f_rn3, 0); + break; + case MEP_OPERAND_RNC : + print_keyword (cd, info, & mep_cgen_opval_h_gpr, fields->f_rn, 0); + break; + case MEP_OPERAND_RNL : + print_keyword (cd, info, & mep_cgen_opval_h_gpr, fields->f_rn, 0); + break; + case MEP_OPERAND_RNS : + print_keyword (cd, info, & mep_cgen_opval_h_gpr, fields->f_rn, 0); + break; + case MEP_OPERAND_RNUC : + print_keyword (cd, info, & mep_cgen_opval_h_gpr, fields->f_rn, 0); + break; + case MEP_OPERAND_RNUL : + print_keyword (cd, info, & mep_cgen_opval_h_gpr, fields->f_rn, 0); + break; + case MEP_OPERAND_RNUS : + print_keyword (cd, info, & mep_cgen_opval_h_gpr, fields->f_rn, 0); + break; + case MEP_OPERAND_SAR : + print_keyword (cd, info, & mep_cgen_opval_h_csr, 0, 0); + break; + case MEP_OPERAND_SDISP16 : + print_normal (cd, info, fields->f_16s16, 0|(1<f_16s16, 0|(1<f_6s8, 0|(1<f_8s8, 0|(1<f_2u6, 0|(1<f_7u9, 0, pc, length); + break; + case MEP_OPERAND_UDISP7A2 : + print_normal (cd, info, fields->f_7u9a2, 0, pc, length); + break; + case MEP_OPERAND_UDISP7A4 : + print_normal (cd, info, fields->f_7u9a4, 0, pc, length); + break; + case MEP_OPERAND_UIMM16 : + print_normal (cd, info, fields->f_16u16, 0, pc, length); + break; + case MEP_OPERAND_UIMM2 : + print_normal (cd, info, fields->f_2u10, 0, pc, length); + break; + case MEP_OPERAND_UIMM24 : + print_normal (cd, info, fields->f_24u8n, 0|(1<f_3u5, 0, pc, length); + break; + case MEP_OPERAND_UIMM4 : + print_normal (cd, info, fields->f_4u8, 0, pc, length); + break; + case MEP_OPERAND_UIMM5 : + print_normal (cd, info, fields->f_5u8, 0, pc, length); + break; + case MEP_OPERAND_UIMM7A4 : + print_normal (cd, info, fields->f_7u9a4, 0, pc, length); + break; + case MEP_OPERAND_ZERO : + print_normal (cd, info, 0, 0|(1<print_handlers = & mep_cgen_print_handlers[0]; + cd->print_operand = mep_cgen_print_operand; +} + + +/* Default print handler. */ + +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) +{ + disassemble_info *info = (disassemble_info *) dis_info; + +#ifdef CGEN_PRINT_NORMAL + CGEN_PRINT_NORMAL (cd, info, value, attrs, pc, length); +#endif + + /* Print the operand as directed by the attributes. */ + if (CGEN_BOOL_ATTR (attrs, CGEN_OPERAND_SEM_ONLY)) + ; /* nothing to do */ + else if (CGEN_BOOL_ATTR (attrs, CGEN_OPERAND_SIGNED)) + (*info->fprintf_func) (info->stream, "%ld", value); + else + (*info->fprintf_func) (info->stream, "0x%lx", value); +} + +/* Default address handler. */ + +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) +{ + disassemble_info *info = (disassemble_info *) dis_info; + +#ifdef CGEN_PRINT_ADDRESS + CGEN_PRINT_ADDRESS (cd, info, value, attrs, pc, length); +#endif + + /* Print the operand as directed by the attributes. */ + if (CGEN_BOOL_ATTR (attrs, CGEN_OPERAND_SEM_ONLY)) + ; /* Nothing to do. */ + else if (CGEN_BOOL_ATTR (attrs, CGEN_OPERAND_PCREL_ADDR)) + (*info->print_address_func) (value, info); + else if (CGEN_BOOL_ATTR (attrs, CGEN_OPERAND_ABS_ADDR)) + (*info->print_address_func) (value, info); + else if (CGEN_BOOL_ATTR (attrs, CGEN_OPERAND_SIGNED)) + (*info->fprintf_func) (info->stream, "%ld", (long) value); + else + (*info->fprintf_func) (info->stream, "0x%lx", (long) value); +} + +/* Keyword print handler. */ + +static void +print_keyword (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED, + void *dis_info, + CGEN_KEYWORD *keyword_table, + long value, + unsigned int attrs ATTRIBUTE_UNUSED) +{ + disassemble_info *info = (disassemble_info *) dis_info; + const CGEN_KEYWORD_ENTRY *ke; + + ke = cgen_keyword_lookup_value (keyword_table, value); + if (ke != NULL) + (*info->fprintf_func) (info->stream, "%s", ke->name); + else + (*info->fprintf_func) (info->stream, "???"); +} + +/* Default insn printer. + + DIS_INFO is defined as `void *' so the disassembler needn't know anything + about disassemble_info. */ + +static void +print_insn_normal (CGEN_CPU_DESC cd, + void *dis_info, + const CGEN_INSN *insn, + CGEN_FIELDS *fields, + bfd_vma pc, + int length) +{ + const CGEN_SYNTAX *syntax = CGEN_INSN_SYNTAX (insn); + disassemble_info *info = (disassemble_info *) dis_info; + const CGEN_SYNTAX_CHAR_TYPE *syn; + + CGEN_INIT_PRINT (cd); + + for (syn = CGEN_SYNTAX_STRING (syntax); *syn; ++syn) + { + if (CGEN_SYNTAX_MNEMONIC_P (*syn)) + { + (*info->fprintf_func) (info->stream, "%s", CGEN_INSN_MNEMONIC (insn)); + continue; + } + if (CGEN_SYNTAX_CHAR_P (*syn)) + { + (*info->fprintf_func) (info->stream, "%c", CGEN_SYNTAX_CHAR (*syn)); + continue; + } + + /* We have an operand. */ + mep_cgen_print_operand (cd, CGEN_SYNTAX_FIELD (*syn), info, + fields, CGEN_INSN_ATTRS (insn), pc, length); + } +} + +/* Subroutine of print_insn. Reads an insn into the given buffers and updates + the extract info. + Returns 0 if all is well, non-zero otherwise. */ + +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) +{ + int status = (*info->read_memory_func) (pc, buf, buflen, info); + + if (status != 0) + { + (*info->memory_error_func) (status, pc, info); + return -1; + } + + ex_info->dis_info = info; + ex_info->valid = (1 << buflen) - 1; + ex_info->insn_bytes = buf; + + *insn_value = bfd_get_bits (buf, buflen * 8, info->endian == BFD_ENDIAN_BIG); + return 0; +} + +/* Utility to print an insn. + BUF is the base part of the insn, target byte order, BUFLEN bytes long. + The result is the size of the insn in bytes or zero for an unknown insn + or -1 if an error occurs fetching data (memory_error_func will have + been called). */ + +static int +print_insn (CGEN_CPU_DESC cd, + bfd_vma pc, + disassemble_info *info, + bfd_byte *buf, + unsigned int buflen) +{ + CGEN_INSN_INT insn_value; + const CGEN_INSN_LIST *insn_list; + CGEN_EXTRACT_INFO ex_info; + int basesize; + + /* Extract base part of instruction, just in case CGEN_DIS_* uses it. */ + basesize = cd->base_insn_bitsize < buflen * 8 ? + cd->base_insn_bitsize : buflen * 8; + insn_value = cgen_get_insn_value (cd, buf, basesize); + + + /* Fill in ex_info fields like read_insn would. Don't actually call + read_insn, since the incoming buffer is already read (and possibly + modified a la m32r). */ + ex_info.valid = (1 << buflen) - 1; + ex_info.dis_info = info; + ex_info.insn_bytes = buf; + + /* The instructions are stored in hash lists. + Pick the first one and keep trying until we find the right one. */ + + insn_list = CGEN_DIS_LOOKUP_INSN (cd, (char *) buf, insn_value); + while (insn_list != NULL) + { + const CGEN_INSN *insn = insn_list->insn; + CGEN_FIELDS fields; + int length; + unsigned long insn_value_cropped; + +#ifdef CGEN_VALIDATE_INSN_SUPPORTED + /* Not needed as insn shouldn't be in hash lists if not supported. */ + /* Supported by this cpu? */ + if (! mep_cgen_insn_supported (cd, insn)) + { + insn_list = CGEN_DIS_NEXT_INSN (insn_list); + continue; + } +#endif + + /* Basic bit mask must be correct. */ + /* ??? May wish to allow target to defer this check until the extract + handler. */ + + /* Base size may exceed this instruction's size. Extract the + relevant part from the buffer. */ + if ((unsigned) (CGEN_INSN_BITSIZE (insn) / 8) < buflen && + (unsigned) (CGEN_INSN_BITSIZE (insn) / 8) <= sizeof (unsigned long)) + insn_value_cropped = bfd_get_bits (buf, CGEN_INSN_BITSIZE (insn), + info->endian == BFD_ENDIAN_BIG); + else + insn_value_cropped = insn_value; + + if ((insn_value_cropped & CGEN_INSN_BASE_MASK (insn)) + == CGEN_INSN_BASE_VALUE (insn)) + { + /* Printing is handled in two passes. The first pass parses the + machine insn and extracts the fields. The second pass prints + them. */ + + /* Make sure the entire insn is loaded into insn_value, if it + can fit. */ + if (((unsigned) CGEN_INSN_BITSIZE (insn) > cd->base_insn_bitsize) && + (unsigned) (CGEN_INSN_BITSIZE (insn) / 8) <= sizeof (unsigned long)) + { + unsigned long full_insn_value; + int rc = read_insn (cd, pc, info, buf, + CGEN_INSN_BITSIZE (insn) / 8, + & ex_info, & full_insn_value); + if (rc != 0) + return rc; + length = CGEN_EXTRACT_FN (cd, insn) + (cd, insn, &ex_info, full_insn_value, &fields, pc); + } + else + length = CGEN_EXTRACT_FN (cd, insn) + (cd, insn, &ex_info, insn_value_cropped, &fields, pc); + + /* Length < 0 -> error. */ + if (length < 0) + return length; + if (length > 0) + { + CGEN_PRINT_FN (cd, insn) (cd, info, insn, &fields, pc, length); + /* Length is in bits, result is in bytes. */ + return length / 8; + } + } + + insn_list = CGEN_DIS_NEXT_INSN (insn_list); + } + + return 0; +} + +/* Default value for CGEN_PRINT_INSN. + The result is the size of the insn in bytes or zero for an unknown insn + or -1 if an error occured fetching bytes. */ + +#ifndef CGEN_PRINT_INSN +#define CGEN_PRINT_INSN default_print_insn +#endif + +static int +default_print_insn (CGEN_CPU_DESC cd, bfd_vma pc, disassemble_info *info) +{ + bfd_byte buf[CGEN_MAX_INSN_SIZE]; + int buflen; + int status; + + /* Attempt to read the base part of the insn. */ + buflen = cd->base_insn_bitsize / 8; + status = (*info->read_memory_func) (pc, buf, buflen, info); + + /* Try again with the minimum part, if min < base. */ + if (status != 0 && (cd->min_insn_bitsize < cd->base_insn_bitsize)) + { + buflen = cd->min_insn_bitsize / 8; + status = (*info->read_memory_func) (pc, buf, buflen, info); + } + + if (status != 0) + { + (*info->memory_error_func) (status, pc, info); + return -1; + } + + return print_insn (cd, pc, info, buf, buflen); +} + +/* Main entry point. + Print one instruction from PC on INFO->STREAM. + Return the size of the instruction (in bytes). */ + +typedef struct cpu_desc_list +{ + struct cpu_desc_list *next; + CGEN_BITSET *isa; + int mach; + int endian; + CGEN_CPU_DESC cd; +} cpu_desc_list; + +int +print_insn_mep (bfd_vma pc, disassemble_info *info) +{ + static cpu_desc_list *cd_list = 0; + cpu_desc_list *cl = 0; + static CGEN_CPU_DESC cd = 0; + static CGEN_BITSET *prev_isa; + static int prev_mach; + static int prev_endian; + int length; + CGEN_BITSET *isa; + int mach; + int endian = (info->endian == BFD_ENDIAN_BIG + ? CGEN_ENDIAN_BIG + : CGEN_ENDIAN_LITTLE); + enum bfd_architecture arch; + + /* ??? gdb will set mach but leave the architecture as "unknown" */ +#ifndef CGEN_BFD_ARCH +#define CGEN_BFD_ARCH bfd_arch_mep +#endif + arch = info->arch; + if (arch == bfd_arch_unknown) + arch = CGEN_BFD_ARCH; + + /* There's no standard way to compute the machine or isa number + so we leave it to the target. */ +#ifdef CGEN_COMPUTE_MACH + mach = CGEN_COMPUTE_MACH (info); +#else + mach = info->mach; +#endif + +#ifdef CGEN_COMPUTE_ISA + { + static CGEN_BITSET *permanent_isa; + + if (!permanent_isa) + permanent_isa = cgen_bitset_create (MAX_ISAS); + isa = permanent_isa; + cgen_bitset_clear (isa); + cgen_bitset_add (isa, CGEN_COMPUTE_ISA (info)); + } +#else + isa = info->insn_sets; +#endif + + /* If we've switched cpu's, try to find a handle we've used before */ + if (cd + && (cgen_bitset_compare (isa, prev_isa) != 0 + || mach != prev_mach + || endian != prev_endian)) + { + cd = 0; + for (cl = cd_list; cl; cl = cl->next) + { + if (cgen_bitset_compare (cl->isa, isa) == 0 && + cl->mach == mach && + cl->endian == endian) + { + cd = cl->cd; + prev_isa = cd->isas; + break; + } + } + } + + /* If we haven't initialized yet, initialize the opcode table. */ + if (! cd) + { + const bfd_arch_info_type *arch_type = bfd_lookup_arch (arch, mach); + const char *mach_name; + + if (!arch_type) + abort (); + mach_name = arch_type->printable_name; + + prev_isa = cgen_bitset_copy (isa); + prev_mach = mach; + prev_endian = endian; + cd = mep_cgen_cpu_open (CGEN_CPU_OPEN_ISAS, prev_isa, + CGEN_CPU_OPEN_BFDMACH, mach_name, + CGEN_CPU_OPEN_ENDIAN, prev_endian, + CGEN_CPU_OPEN_END); + if (!cd) + abort (); + + /* Save this away for future reference. */ + cl = xmalloc (sizeof (struct cpu_desc_list)); + cl->cd = cd; + cl->isa = prev_isa; + cl->mach = mach; + cl->endian = endian; + cl->next = cd_list; + cd_list = cl; + + mep_cgen_init_dis (cd); + } + + /* We try to have as much common code as possible. + But at this point some targets need to take over. */ + /* ??? Some targets may need a hook elsewhere. Try to avoid this, + but if not possible try to move this hook elsewhere rather than + have two hooks. */ + length = CGEN_PRINT_INSN (cd, pc, info); + if (length > 0) + return length; + if (length < 0) + return -1; + + (*info->fprintf_func) (info->stream, UNKNOWN_INSN_MSG); + return cd->default_insn_bitsize / 8; +} diff --git a/opcodes/mep-ibld.c b/opcodes/mep-ibld.c new file mode 100644 index 00000000000..7dd64967b30 --- /dev/null +++ b/opcodes/mep-ibld.c @@ -0,0 +1,2541 @@ +/* Instruction building/extraction support for mep. -*- C -*- + + THIS FILE IS MACHINE GENERATED WITH CGEN: Cpu tools GENerator. + - the resultant file is machine generated, cgen-ibld.in isn't + + Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2005, 2006 + Free Software Foundation, Inc. + + This file is part of the GNU Binutils and GDB, the GNU debugger. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ + +/* ??? Eventually more and more of this stuff can go to cpu-independent files. + Keep that in mind. */ + +#include "sysdep.h" +#include +#include "ansidecl.h" +#include "dis-asm.h" +#include "bfd.h" +#include "symcat.h" +#include "mep-desc.h" +#include "mep-opc.h" +#include "opintl.h" +#include "safe-ctype.h" + +#undef min +#define min(a,b) ((a) < (b) ? (a) : (b)) +#undef max +#define max(a,b) ((a) > (b) ? (a) : (b)) + +/* Used by the ifield rtx function. */ +#define FLD(f) (fields->f) + +static const char * insert_normal + (CGEN_CPU_DESC, long, unsigned int, unsigned int, unsigned int, + unsigned int, unsigned int, unsigned int, CGEN_INSN_BYTES_PTR); +static const char * insert_insn_normal + (CGEN_CPU_DESC, const CGEN_INSN *, + CGEN_FIELDS *, CGEN_INSN_BYTES_PTR, bfd_vma); +static int extract_normal + (CGEN_CPU_DESC, CGEN_EXTRACT_INFO *, CGEN_INSN_INT, + unsigned int, unsigned int, unsigned int, unsigned int, + unsigned int, unsigned int, bfd_vma, long *); +static int extract_insn_normal + (CGEN_CPU_DESC, const CGEN_INSN *, CGEN_EXTRACT_INFO *, + CGEN_INSN_INT, CGEN_FIELDS *, bfd_vma); +#if CGEN_INT_INSN_P +static void put_insn_int_value + (CGEN_CPU_DESC, CGEN_INSN_BYTES_PTR, int, int, CGEN_INSN_INT); +#endif +#if ! CGEN_INT_INSN_P +static CGEN_INLINE void insert_1 + (CGEN_CPU_DESC, unsigned long, int, int, int, unsigned char *); +static CGEN_INLINE int fill_cache + (CGEN_CPU_DESC, CGEN_EXTRACT_INFO *, int, int, bfd_vma); +static CGEN_INLINE long extract_1 + (CGEN_CPU_DESC, CGEN_EXTRACT_INFO *, int, int, int, unsigned char *, bfd_vma); +#endif + +/* Operand insertion. */ + +#if ! CGEN_INT_INSN_P + +/* Subroutine of insert_normal. */ + +static CGEN_INLINE void +insert_1 (CGEN_CPU_DESC cd, + unsigned long value, + int start, + int length, + int word_length, + unsigned char *bufp) +{ + unsigned long x,mask; + int shift; + + x = cgen_get_insn_value (cd, bufp, word_length); + + /* Written this way to avoid undefined behaviour. */ + mask = (((1L << (length - 1)) - 1) << 1) | 1; + if (CGEN_INSN_LSB0_P) + shift = (start + 1) - length; + else + shift = (word_length - (start + length)); + x = (x & ~(mask << shift)) | ((value & mask) << shift); + + cgen_put_insn_value (cd, bufp, word_length, (bfd_vma) x); +} + +#endif /* ! CGEN_INT_INSN_P */ + +/* Default insertion routine. + + ATTRS is a mask of the boolean attributes. + WORD_OFFSET is the offset in bits from the start of the insn of the value. + WORD_LENGTH is the length of the word in bits in which the value resides. + START is the starting bit number in the word, architecture origin. + LENGTH is the length of VALUE in bits. + TOTAL_LENGTH is the total length of the insn in bits. + + The result is an error message or NULL if success. */ + +/* ??? This duplicates functionality with bfd's howto table and + bfd_install_relocation. */ +/* ??? This doesn't handle bfd_vma's. Create another function when + necessary. */ + +static const char * +insert_normal (CGEN_CPU_DESC cd, + long value, + unsigned int attrs, + unsigned int word_offset, + unsigned int start, + unsigned int length, + unsigned int word_length, + unsigned int total_length, + CGEN_INSN_BYTES_PTR buffer) +{ + static char errbuf[100]; + /* Written this way to avoid undefined behaviour. */ + unsigned long mask = (((1L << (length - 1)) - 1) << 1) | 1; + + /* If LENGTH is zero, this operand doesn't contribute to the value. */ + if (length == 0) + return NULL; + + if (word_length > 32) + abort (); + + /* For architectures with insns smaller than the base-insn-bitsize, + word_length may be too big. */ + if (cd->min_insn_bitsize < cd->base_insn_bitsize) + { + if (word_offset == 0 + && word_length > total_length) + word_length = total_length; + } + + /* Ensure VALUE will fit. */ + if (CGEN_BOOL_ATTR (attrs, CGEN_IFLD_SIGN_OPT)) + { + long minval = - (1L << (length - 1)); + unsigned long maxval = mask; + + if ((value > 0 && (unsigned long) value > maxval) + || value < minval) + { + /* xgettext:c-format */ + sprintf (errbuf, + _("operand out of range (%ld not between %ld and %lu)"), + value, minval, maxval); + return errbuf; + } + } + else if (! CGEN_BOOL_ATTR (attrs, CGEN_IFLD_SIGNED)) + { + unsigned long maxval = mask; + unsigned long val = (unsigned long) value; + + /* For hosts with a word size > 32 check to see if value has been sign + extended beyond 32 bits. If so then ignore these higher sign bits + as the user is attempting to store a 32-bit signed value into an + unsigned 32-bit field which is allowed. */ + if (sizeof (unsigned long) > 4 && ((value >> 32) == -1)) + val &= 0xFFFFFFFF; + + if (val > maxval) + { + /* xgettext:c-format */ + sprintf (errbuf, + _("operand out of range (0x%lx not between 0 and 0x%lx)"), + val, maxval); + return errbuf; + } + } + else + { + if (! cgen_signed_overflow_ok_p (cd)) + { + long minval = - (1L << (length - 1)); + long maxval = (1L << (length - 1)) - 1; + + if (value < minval || value > maxval) + { + sprintf + /* xgettext:c-format */ + (errbuf, _("operand out of range (%ld not between %ld and %ld)"), + value, minval, maxval); + return errbuf; + } + } + } + +#if CGEN_INT_INSN_P + + { + int shift; + + if (CGEN_INSN_LSB0_P) + shift = (word_offset + start + 1) - length; + else + shift = total_length - (word_offset + start + length); + *buffer = (*buffer & ~(mask << shift)) | ((value & mask) << shift); + } + +#else /* ! CGEN_INT_INSN_P */ + + { + unsigned char *bufp = (unsigned char *) buffer + word_offset / 8; + + insert_1 (cd, value, start, length, word_length, bufp); + } + +#endif /* ! CGEN_INT_INSN_P */ + + return NULL; +} + +/* Default insn builder (insert handler). + The instruction is recorded in CGEN_INT_INSN_P byte order (meaning + that if CGEN_INSN_BYTES_PTR is an int * and thus, the value is + recorded in host byte order, otherwise BUFFER is an array of bytes + and the value is recorded in target byte order). + The result is an error message or NULL if success. */ + +static const char * +insert_insn_normal (CGEN_CPU_DESC cd, + const CGEN_INSN * insn, + CGEN_FIELDS * fields, + CGEN_INSN_BYTES_PTR buffer, + bfd_vma pc) +{ + const CGEN_SYNTAX *syntax = CGEN_INSN_SYNTAX (insn); + unsigned long value; + const CGEN_SYNTAX_CHAR_TYPE * syn; + + CGEN_INIT_INSERT (cd); + value = CGEN_INSN_BASE_VALUE (insn); + + /* If we're recording insns as numbers (rather than a string of bytes), + target byte order handling is deferred until later. */ + +#if CGEN_INT_INSN_P + + put_insn_int_value (cd, buffer, cd->base_insn_bitsize, + CGEN_FIELDS_BITSIZE (fields), value); + +#else + + cgen_put_insn_value (cd, buffer, min ((unsigned) cd->base_insn_bitsize, + (unsigned) CGEN_FIELDS_BITSIZE (fields)), + value); + +#endif /* ! CGEN_INT_INSN_P */ + + /* ??? It would be better to scan the format's fields. + Still need to be able to insert a value based on the operand though; + e.g. storing a branch displacement that got resolved later. + Needs more thought first. */ + + for (syn = CGEN_SYNTAX_STRING (syntax); * syn; ++ syn) + { + const char *errmsg; + + if (CGEN_SYNTAX_CHAR_P (* syn)) + continue; + + errmsg = (* cd->insert_operand) (cd, CGEN_SYNTAX_FIELD (*syn), + fields, buffer, pc); + if (errmsg) + return errmsg; + } + + return NULL; +} + +#if CGEN_INT_INSN_P +/* Cover function to store an insn value into an integral insn. Must go here + because it needs -desc.h for CGEN_INT_INSN_P. */ + +static void +put_insn_int_value (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED, + CGEN_INSN_BYTES_PTR buf, + int length, + int insn_length, + CGEN_INSN_INT value) +{ + /* For architectures with insns smaller than the base-insn-bitsize, + length may be too big. */ + if (length > insn_length) + *buf = value; + else + { + int shift = insn_length - length; + /* Written this way to avoid undefined behaviour. */ + CGEN_INSN_INT mask = (((1L << (length - 1)) - 1) << 1) | 1; + + *buf = (*buf & ~(mask << shift)) | ((value & mask) << shift); + } +} +#endif + +/* Operand extraction. */ + +#if ! CGEN_INT_INSN_P + +/* Subroutine of extract_normal. + Ensure sufficient bytes are cached in EX_INFO. + OFFSET is the offset in bytes from the start of the insn of the value. + BYTES is the length of the needed value. + Returns 1 for success, 0 for failure. */ + +static CGEN_INLINE int +fill_cache (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED, + CGEN_EXTRACT_INFO *ex_info, + int offset, + int bytes, + bfd_vma pc) +{ + /* It's doubtful that the middle part has already been fetched so + we don't optimize that case. kiss. */ + unsigned int mask; + disassemble_info *info = (disassemble_info *) ex_info->dis_info; + + /* First do a quick check. */ + mask = (1 << bytes) - 1; + if (((ex_info->valid >> offset) & mask) == mask) + return 1; + + /* Search for the first byte we need to read. */ + for (mask = 1 << offset; bytes > 0; --bytes, ++offset, mask <<= 1) + if (! (mask & ex_info->valid)) + break; + + if (bytes) + { + int status; + + pc += offset; + status = (*info->read_memory_func) + (pc, ex_info->insn_bytes + offset, bytes, info); + + if (status != 0) + { + (*info->memory_error_func) (status, pc, info); + return 0; + } + + ex_info->valid |= ((1 << bytes) - 1) << offset; + } + + return 1; +} + +/* Subroutine of extract_normal. */ + +static CGEN_INLINE long +extract_1 (CGEN_CPU_DESC cd, + CGEN_EXTRACT_INFO *ex_info ATTRIBUTE_UNUSED, + int start, + int length, + int word_length, + unsigned char *bufp, + bfd_vma pc ATTRIBUTE_UNUSED) +{ + unsigned long x; + int shift; + + x = cgen_get_insn_value (cd, bufp, word_length); + + if (CGEN_INSN_LSB0_P) + shift = (start + 1) - length; + else + shift = (word_length - (start + length)); + return x >> shift; +} + +#endif /* ! CGEN_INT_INSN_P */ + +/* Default extraction routine. + + INSN_VALUE is the first base_insn_bitsize bits of the insn in host order, + or sometimes less for cases like the m32r where the base insn size is 32 + but some insns are 16 bits. + ATTRS is a mask of the boolean attributes. We only need `SIGNED', + but for generality we take a bitmask of all of them. + WORD_OFFSET is the offset in bits from the start of the insn of the value. + WORD_LENGTH is the length of the word in bits in which the value resides. + START is the starting bit number in the word, architecture origin. + LENGTH is the length of VALUE in bits. + TOTAL_LENGTH is the total length of the insn in bits. + + Returns 1 for success, 0 for failure. */ + +/* ??? The return code isn't properly used. wip. */ + +/* ??? This doesn't handle bfd_vma's. Create another function when + necessary. */ + +static int +extract_normal (CGEN_CPU_DESC cd, +#if ! CGEN_INT_INSN_P + CGEN_EXTRACT_INFO *ex_info, +#else + CGEN_EXTRACT_INFO *ex_info ATTRIBUTE_UNUSED, +#endif + CGEN_INSN_INT insn_value, + unsigned int attrs, + unsigned int word_offset, + unsigned int start, + unsigned int length, + unsigned int word_length, + unsigned int total_length, +#if ! CGEN_INT_INSN_P + bfd_vma pc, +#else + bfd_vma pc ATTRIBUTE_UNUSED, +#endif + long *valuep) +{ + long value, mask; + + /* If LENGTH is zero, this operand doesn't contribute to the value + so give it a standard value of zero. */ + if (length == 0) + { + *valuep = 0; + return 1; + } + + if (word_length > 32) + abort (); + + /* For architectures with insns smaller than the insn-base-bitsize, + word_length may be too big. */ + if (cd->min_insn_bitsize < cd->base_insn_bitsize) + { + if (word_offset + word_length > total_length) + word_length = total_length - word_offset; + } + + /* Does the value reside in INSN_VALUE, and at the right alignment? */ + + if (CGEN_INT_INSN_P || (word_offset == 0 && word_length == total_length)) + { + if (CGEN_INSN_LSB0_P) + value = insn_value >> ((word_offset + start + 1) - length); + else + value = insn_value >> (total_length - ( word_offset + start + length)); + } + +#if ! CGEN_INT_INSN_P + + else + { + unsigned char *bufp = ex_info->insn_bytes + word_offset / 8; + + if (word_length > 32) + abort (); + + if (fill_cache (cd, ex_info, word_offset / 8, word_length / 8, pc) == 0) + return 0; + + value = extract_1 (cd, ex_info, start, length, word_length, bufp, pc); + } + +#endif /* ! CGEN_INT_INSN_P */ + + /* Written this way to avoid undefined behaviour. */ + mask = (((1L << (length - 1)) - 1) << 1) | 1; + + value &= mask; + /* sign extend? */ + if (CGEN_BOOL_ATTR (attrs, CGEN_IFLD_SIGNED) + && (value & (1L << (length - 1)))) + value |= ~mask; + + *valuep = value; + + return 1; +} + +/* Default insn extractor. + + INSN_VALUE is the first base_insn_bitsize bits, translated to host order. + The extracted fields are stored in FIELDS. + EX_INFO is used to handle reading variable length insns. + Return the length of the insn in bits, or 0 if no match, + or -1 if an error occurs fetching data (memory_error_func will have + been called). */ + +static int +extract_insn_normal (CGEN_CPU_DESC cd, + const CGEN_INSN *insn, + CGEN_EXTRACT_INFO *ex_info, + CGEN_INSN_INT insn_value, + CGEN_FIELDS *fields, + bfd_vma pc) +{ + const CGEN_SYNTAX *syntax = CGEN_INSN_SYNTAX (insn); + const CGEN_SYNTAX_CHAR_TYPE *syn; + + CGEN_FIELDS_BITSIZE (fields) = CGEN_INSN_BITSIZE (insn); + + CGEN_INIT_EXTRACT (cd); + + for (syn = CGEN_SYNTAX_STRING (syntax); *syn; ++syn) + { + int length; + + if (CGEN_SYNTAX_CHAR_P (*syn)) + continue; + + length = (* cd->extract_operand) (cd, CGEN_SYNTAX_FIELD (*syn), + ex_info, insn_value, fields, pc); + if (length <= 0) + return length; + } + + /* We recognized and successfully extracted this insn. */ + return CGEN_INSN_BITSIZE (insn); +} + +/* Machine generated code added here. */ + +const char * mep_cgen_insert_operand + (CGEN_CPU_DESC, int, CGEN_FIELDS *, CGEN_INSN_BYTES_PTR, bfd_vma); + +/* Main entry point for operand insertion. + + This function is basically just a big switch statement. Earlier versions + used tables to look up the function to use, but + - if the table contains both assembler and disassembler functions then + the disassembler contains much of the assembler and vice-versa, + - there's a lot of inlining possibilities as things grow, + - using a switch statement avoids the function call overhead. + + This function could be moved into `parse_insn_normal', but keeping it + separate makes clear the interface between `parse_insn_normal' and each of + the handlers. It's also needed by GAS to insert operands that couldn't be + resolved during parsing. */ + +const char * +mep_cgen_insert_operand (CGEN_CPU_DESC cd, + int opindex, + CGEN_FIELDS * fields, + CGEN_INSN_BYTES_PTR buffer, + bfd_vma pc ATTRIBUTE_UNUSED) +{ + const char * errmsg = NULL; + unsigned int total_length = CGEN_FIELDS_BITSIZE (fields); + + switch (opindex) + { + case MEP_OPERAND_ADDR24A4 : + { +{ + FLD (f_24u8a4n_hi) = ((unsigned int) (FLD (f_24u8a4n)) >> (8)); + FLD (f_24u8a4n_lo) = ((unsigned int) (((FLD (f_24u8a4n)) & (252))) >> (2)); +} + errmsg = insert_normal (cd, fields->f_24u8a4n_hi, 0, 0, 16, 16, 32, total_length, buffer); + if (errmsg) + break; + errmsg = insert_normal (cd, fields->f_24u8a4n_lo, 0, 0, 8, 6, 32, total_length, buffer); + if (errmsg) + break; + } + break; + case MEP_OPERAND_CALLNUM : + { +{ + FLD (f_5) = ((((unsigned int) (FLD (f_callnum)) >> (3))) & (1)); + FLD (f_6) = ((((unsigned int) (FLD (f_callnum)) >> (2))) & (1)); + FLD (f_7) = ((((unsigned int) (FLD (f_callnum)) >> (1))) & (1)); + FLD (f_11) = ((FLD (f_callnum)) & (1)); +} + errmsg = insert_normal (cd, fields->f_5, 0, 0, 5, 1, 32, total_length, buffer); + if (errmsg) + break; + errmsg = insert_normal (cd, fields->f_6, 0, 0, 6, 1, 32, total_length, buffer); + if (errmsg) + break; + errmsg = insert_normal (cd, fields->f_7, 0, 0, 7, 1, 32, total_length, buffer); + if (errmsg) + break; + errmsg = insert_normal (cd, fields->f_11, 0, 0, 11, 1, 32, total_length, buffer); + if (errmsg) + break; + } + break; + case MEP_OPERAND_CCCC : + errmsg = insert_normal (cd, fields->f_rm, 0, 0, 8, 4, 32, total_length, buffer); + break; + case MEP_OPERAND_CCRN : + { +{ + FLD (f_ccrn_hi) = ((((unsigned int) (FLD (f_ccrn)) >> (4))) & (3)); + FLD (f_ccrn_lo) = ((FLD (f_ccrn)) & (15)); +} + errmsg = insert_normal (cd, fields->f_ccrn_hi, 0, 0, 28, 2, 32, total_length, buffer); + if (errmsg) + break; + errmsg = insert_normal (cd, fields->f_ccrn_lo, 0, 0, 4, 4, 32, total_length, buffer); + if (errmsg) + break; + } + break; + case MEP_OPERAND_CDISP8 : + errmsg = insert_normal (cd, fields->f_8s24, 0|(1<f_8s24a2; + value = ((int) (value) >> (1)); + errmsg = insert_normal (cd, value, 0|(1<f_8s24a4; + value = ((int) (value) >> (2)); + errmsg = insert_normal (cd, value, 0|(1<f_8s24a8; + value = ((int) (value) >> (3)); + errmsg = insert_normal (cd, value, 0|(1<f_rn, 0, 0, 4, 4, 32, total_length, buffer); + break; + case MEP_OPERAND_CIMM5 : + errmsg = insert_normal (cd, fields->f_5u24, 0, 0, 24, 5, 32, total_length, buffer); + break; + case MEP_OPERAND_CODE16 : + errmsg = insert_normal (cd, fields->f_16u16, 0, 0, 16, 16, 32, total_length, buffer); + break; + case MEP_OPERAND_CODE24 : + { +{ + FLD (f_24u4n_hi) = ((unsigned int) (FLD (f_24u4n)) >> (16)); + FLD (f_24u4n_lo) = ((FLD (f_24u4n)) & (65535)); +} + errmsg = insert_normal (cd, fields->f_24u4n_hi, 0, 0, 4, 8, 32, total_length, buffer); + if (errmsg) + break; + errmsg = insert_normal (cd, fields->f_24u4n_lo, 0, 0, 16, 16, 32, total_length, buffer); + if (errmsg) + break; + } + break; + case MEP_OPERAND_CP_FLAG : + break; + case MEP_OPERAND_CRN : + errmsg = insert_normal (cd, fields->f_crn, 0, 0, 4, 4, 32, total_length, buffer); + break; + case MEP_OPERAND_CRN64 : + errmsg = insert_normal (cd, fields->f_crn, 0, 0, 4, 4, 32, total_length, buffer); + break; + case MEP_OPERAND_CRNX : + { +{ + FLD (f_crnx_lo) = ((FLD (f_crnx)) & (15)); + FLD (f_crnx_hi) = ((unsigned int) (FLD (f_crnx)) >> (4)); +} + errmsg = insert_normal (cd, fields->f_crnx_hi, 0, 0, 28, 1, 32, total_length, buffer); + if (errmsg) + break; + errmsg = insert_normal (cd, fields->f_crnx_lo, 0, 0, 4, 4, 32, total_length, buffer); + if (errmsg) + break; + } + break; + case MEP_OPERAND_CRNX64 : + { +{ + FLD (f_crnx_lo) = ((FLD (f_crnx)) & (15)); + FLD (f_crnx_hi) = ((unsigned int) (FLD (f_crnx)) >> (4)); +} + errmsg = insert_normal (cd, fields->f_crnx_hi, 0, 0, 28, 1, 32, total_length, buffer); + if (errmsg) + break; + errmsg = insert_normal (cd, fields->f_crnx_lo, 0, 0, 4, 4, 32, total_length, buffer); + if (errmsg) + break; + } + break; + case MEP_OPERAND_CSRN : + { +{ + FLD (f_csrn_lo) = ((FLD (f_csrn)) & (15)); + FLD (f_csrn_hi) = ((unsigned int) (FLD (f_csrn)) >> (4)); +} + errmsg = insert_normal (cd, fields->f_csrn_hi, 0, 0, 15, 1, 32, total_length, buffer); + if (errmsg) + break; + errmsg = insert_normal (cd, fields->f_csrn_lo, 0, 0, 8, 4, 32, total_length, buffer); + if (errmsg) + break; + } + break; + case MEP_OPERAND_CSRN_IDX : + { +{ + FLD (f_csrn_lo) = ((FLD (f_csrn)) & (15)); + FLD (f_csrn_hi) = ((unsigned int) (FLD (f_csrn)) >> (4)); +} + errmsg = insert_normal (cd, fields->f_csrn_hi, 0, 0, 15, 1, 32, total_length, buffer); + if (errmsg) + break; + errmsg = insert_normal (cd, fields->f_csrn_lo, 0, 0, 8, 4, 32, total_length, buffer); + if (errmsg) + break; + } + break; + case MEP_OPERAND_DBG : + break; + case MEP_OPERAND_DEPC : + break; + case MEP_OPERAND_EPC : + break; + case MEP_OPERAND_EXC : + break; + case MEP_OPERAND_FMAX_CCRN : + errmsg = insert_normal (cd, fields->f_fmax_4_4, 0, 0, 4, 4, 32, total_length, buffer); + break; + case MEP_OPERAND_FMAX_FRD : + { +{ + FLD (f_fmax_4_4) = ((FLD (f_fmax_frd)) & (15)); + FLD (f_fmax_28_1) = ((unsigned int) (FLD (f_fmax_frd)) >> (4)); +} + errmsg = insert_normal (cd, fields->f_fmax_28_1, 0, 0, 28, 1, 32, total_length, buffer); + if (errmsg) + break; + errmsg = insert_normal (cd, fields->f_fmax_4_4, 0, 0, 4, 4, 32, total_length, buffer); + if (errmsg) + break; + } + break; + case MEP_OPERAND_FMAX_FRD_INT : + { +{ + FLD (f_fmax_4_4) = ((FLD (f_fmax_frd)) & (15)); + FLD (f_fmax_28_1) = ((unsigned int) (FLD (f_fmax_frd)) >> (4)); +} + errmsg = insert_normal (cd, fields->f_fmax_28_1, 0, 0, 28, 1, 32, total_length, buffer); + if (errmsg) + break; + errmsg = insert_normal (cd, fields->f_fmax_4_4, 0, 0, 4, 4, 32, total_length, buffer); + if (errmsg) + break; + } + break; + case MEP_OPERAND_FMAX_FRM : + { +{ + FLD (f_fmax_24_4) = ((FLD (f_fmax_frm)) & (15)); + FLD (f_fmax_30_1) = ((unsigned int) (FLD (f_fmax_frm)) >> (4)); +} + errmsg = insert_normal (cd, fields->f_fmax_30_1, 0, 0, 30, 1, 32, total_length, buffer); + if (errmsg) + break; + errmsg = insert_normal (cd, fields->f_fmax_24_4, 0, 0, 24, 4, 32, total_length, buffer); + if (errmsg) + break; + } + break; + case MEP_OPERAND_FMAX_FRN : + { +{ + FLD (f_fmax_20_4) = ((FLD (f_fmax_frn)) & (15)); + FLD (f_fmax_29_1) = ((unsigned int) (FLD (f_fmax_frn)) >> (4)); +} + errmsg = insert_normal (cd, fields->f_fmax_29_1, 0, 0, 29, 1, 32, total_length, buffer); + if (errmsg) + break; + errmsg = insert_normal (cd, fields->f_fmax_20_4, 0, 0, 20, 4, 32, total_length, buffer); + if (errmsg) + break; + } + break; + case MEP_OPERAND_FMAX_FRN_INT : + { +{ + FLD (f_fmax_20_4) = ((FLD (f_fmax_frn)) & (15)); + FLD (f_fmax_29_1) = ((unsigned int) (FLD (f_fmax_frn)) >> (4)); +} + errmsg = insert_normal (cd, fields->f_fmax_29_1, 0, 0, 29, 1, 32, total_length, buffer); + if (errmsg) + break; + errmsg = insert_normal (cd, fields->f_fmax_20_4, 0, 0, 20, 4, 32, total_length, buffer); + if (errmsg) + break; + } + break; + case MEP_OPERAND_FMAX_RM : + errmsg = insert_normal (cd, fields->f_fmax_rm, 0, 0, 8, 4, 32, total_length, buffer); + break; + case MEP_OPERAND_HI : + break; + case MEP_OPERAND_LO : + break; + case MEP_OPERAND_LP : + break; + case MEP_OPERAND_MB0 : + break; + case MEP_OPERAND_MB1 : + break; + case MEP_OPERAND_ME0 : + break; + case MEP_OPERAND_ME1 : + break; + case MEP_OPERAND_NPC : + break; + case MEP_OPERAND_OPT : + break; + case MEP_OPERAND_PCABS24A2 : + { +{ + FLD (f_24u5a2n_lo) = ((unsigned int) (((FLD (f_24u5a2n)) & (255))) >> (1)); + FLD (f_24u5a2n_hi) = ((unsigned int) (FLD (f_24u5a2n)) >> (8)); +} + errmsg = insert_normal (cd, fields->f_24u5a2n_hi, 0, 0, 16, 16, 32, total_length, buffer); + if (errmsg) + break; + errmsg = insert_normal (cd, fields->f_24u5a2n_lo, 0, 0, 5, 7, 32, total_length, buffer); + if (errmsg) + break; + } + break; + case MEP_OPERAND_PCREL12A2 : + { + long value = fields->f_12s4a2; + value = ((int) (((value) - (pc))) >> (1)); + errmsg = insert_normal (cd, value, 0|(1<f_17s16a2; + value = ((int) (((value) - (pc))) >> (1)); + errmsg = insert_normal (cd, value, 0|(1<> (1)); + FLD (f_24s5a2n_hi) = ((int) (FLD (f_24s5a2n)) >> (8)); +} + errmsg = insert_normal (cd, fields->f_24s5a2n_hi, 0|(1<f_24s5a2n_lo, 0|(1<f_8s8a2; + value = ((int) (((value) - (pc))) >> (1)); + errmsg = insert_normal (cd, value, 0|(1<f_rl, 0, 0, 12, 4, 32, total_length, buffer); + break; + case MEP_OPERAND_RM : + errmsg = insert_normal (cd, fields->f_rm, 0, 0, 8, 4, 32, total_length, buffer); + break; + case MEP_OPERAND_RMA : + errmsg = insert_normal (cd, fields->f_rm, 0, 0, 8, 4, 32, total_length, buffer); + break; + case MEP_OPERAND_RN : + errmsg = insert_normal (cd, fields->f_rn, 0, 0, 4, 4, 32, total_length, buffer); + break; + case MEP_OPERAND_RN3 : + errmsg = insert_normal (cd, fields->f_rn3, 0, 0, 5, 3, 32, total_length, buffer); + break; + case MEP_OPERAND_RN3C : + errmsg = insert_normal (cd, fields->f_rn3, 0, 0, 5, 3, 32, total_length, buffer); + break; + case MEP_OPERAND_RN3L : + errmsg = insert_normal (cd, fields->f_rn3, 0, 0, 5, 3, 32, total_length, buffer); + break; + case MEP_OPERAND_RN3S : + errmsg = insert_normal (cd, fields->f_rn3, 0, 0, 5, 3, 32, total_length, buffer); + break; + case MEP_OPERAND_RN3UC : + errmsg = insert_normal (cd, fields->f_rn3, 0, 0, 5, 3, 32, total_length, buffer); + break; + case MEP_OPERAND_RN3UL : + errmsg = insert_normal (cd, fields->f_rn3, 0, 0, 5, 3, 32, total_length, buffer); + break; + case MEP_OPERAND_RN3US : + errmsg = insert_normal (cd, fields->f_rn3, 0, 0, 5, 3, 32, total_length, buffer); + break; + case MEP_OPERAND_RNC : + errmsg = insert_normal (cd, fields->f_rn, 0, 0, 4, 4, 32, total_length, buffer); + break; + case MEP_OPERAND_RNL : + errmsg = insert_normal (cd, fields->f_rn, 0, 0, 4, 4, 32, total_length, buffer); + break; + case MEP_OPERAND_RNS : + errmsg = insert_normal (cd, fields->f_rn, 0, 0, 4, 4, 32, total_length, buffer); + break; + case MEP_OPERAND_RNUC : + errmsg = insert_normal (cd, fields->f_rn, 0, 0, 4, 4, 32, total_length, buffer); + break; + case MEP_OPERAND_RNUL : + errmsg = insert_normal (cd, fields->f_rn, 0, 0, 4, 4, 32, total_length, buffer); + break; + case MEP_OPERAND_RNUS : + errmsg = insert_normal (cd, fields->f_rn, 0, 0, 4, 4, 32, total_length, buffer); + break; + case MEP_OPERAND_SAR : + break; + case MEP_OPERAND_SDISP16 : + errmsg = insert_normal (cd, fields->f_16s16, 0|(1<f_16s16, 0|(1<f_6s8, 0|(1<f_8s8, 0|(1<f_2u6, 0, 0, 6, 2, 32, total_length, buffer); + break; + case MEP_OPERAND_UDISP7 : + errmsg = insert_normal (cd, fields->f_7u9, 0, 0, 9, 7, 32, total_length, buffer); + break; + case MEP_OPERAND_UDISP7A2 : + { + long value = fields->f_7u9a2; + value = ((unsigned int) (value) >> (1)); + errmsg = insert_normal (cd, value, 0, 0, 9, 6, 32, total_length, buffer); + } + break; + case MEP_OPERAND_UDISP7A4 : + { + long value = fields->f_7u9a4; + value = ((unsigned int) (value) >> (2)); + errmsg = insert_normal (cd, value, 0, 0, 9, 5, 32, total_length, buffer); + } + break; + case MEP_OPERAND_UIMM16 : + errmsg = insert_normal (cd, fields->f_16u16, 0, 0, 16, 16, 32, total_length, buffer); + break; + case MEP_OPERAND_UIMM2 : + errmsg = insert_normal (cd, fields->f_2u10, 0, 0, 10, 2, 32, total_length, buffer); + break; + case MEP_OPERAND_UIMM24 : + { +{ + FLD (f_24u8n_hi) = ((unsigned int) (FLD (f_24u8n)) >> (8)); + FLD (f_24u8n_lo) = ((FLD (f_24u8n)) & (255)); +} + errmsg = insert_normal (cd, fields->f_24u8n_hi, 0, 0, 16, 16, 32, total_length, buffer); + if (errmsg) + break; + errmsg = insert_normal (cd, fields->f_24u8n_lo, 0, 0, 8, 8, 32, total_length, buffer); + if (errmsg) + break; + } + break; + case MEP_OPERAND_UIMM3 : + errmsg = insert_normal (cd, fields->f_3u5, 0, 0, 5, 3, 32, total_length, buffer); + break; + case MEP_OPERAND_UIMM4 : + errmsg = insert_normal (cd, fields->f_4u8, 0, 0, 8, 4, 32, total_length, buffer); + break; + case MEP_OPERAND_UIMM5 : + errmsg = insert_normal (cd, fields->f_5u8, 0, 0, 8, 5, 32, total_length, buffer); + break; + case MEP_OPERAND_UIMM7A4 : + { + long value = fields->f_7u9a4; + value = ((unsigned int) (value) >> (2)); + errmsg = insert_normal (cd, value, 0, 0, 9, 5, 32, total_length, buffer); + } + break; + case MEP_OPERAND_ZERO : + break; + + default : + /* xgettext:c-format */ + fprintf (stderr, _("Unrecognized field %d while building insn.\n"), + opindex); + abort (); + } + + return errmsg; +} + +int mep_cgen_extract_operand + (CGEN_CPU_DESC, int, CGEN_EXTRACT_INFO *, CGEN_INSN_INT, CGEN_FIELDS *, bfd_vma); + +/* Main entry point for operand extraction. + The result is <= 0 for error, >0 for success. + ??? Actual values aren't well defined right now. + + This function is basically just a big switch statement. Earlier versions + used tables to look up the function to use, but + - if the table contains both assembler and disassembler functions then + the disassembler contains much of the assembler and vice-versa, + - there's a lot of inlining possibilities as things grow, + - using a switch statement avoids the function call overhead. + + This function could be moved into `print_insn_normal', but keeping it + separate makes clear the interface between `print_insn_normal' and each of + the handlers. */ + +int +mep_cgen_extract_operand (CGEN_CPU_DESC cd, + int opindex, + CGEN_EXTRACT_INFO *ex_info, + CGEN_INSN_INT insn_value, + CGEN_FIELDS * fields, + bfd_vma pc) +{ + /* Assume success (for those operands that are nops). */ + int length = 1; + unsigned int total_length = CGEN_FIELDS_BITSIZE (fields); + + switch (opindex) + { + case MEP_OPERAND_ADDR24A4 : + { + length = extract_normal (cd, ex_info, insn_value, 0, 0, 16, 16, 32, total_length, pc, & fields->f_24u8a4n_hi); + if (length <= 0) break; + length = extract_normal (cd, ex_info, insn_value, 0, 0, 8, 6, 32, total_length, pc, & fields->f_24u8a4n_lo); + if (length <= 0) break; + FLD (f_24u8a4n) = ((((FLD (f_24u8a4n_hi)) << (8))) | (((FLD (f_24u8a4n_lo)) << (2)))); + } + break; + case MEP_OPERAND_CALLNUM : + { + length = extract_normal (cd, ex_info, insn_value, 0, 0, 5, 1, 32, total_length, pc, & fields->f_5); + if (length <= 0) break; + length = extract_normal (cd, ex_info, insn_value, 0, 0, 6, 1, 32, total_length, pc, & fields->f_6); + if (length <= 0) break; + length = extract_normal (cd, ex_info, insn_value, 0, 0, 7, 1, 32, total_length, pc, & fields->f_7); + if (length <= 0) break; + length = extract_normal (cd, ex_info, insn_value, 0, 0, 11, 1, 32, total_length, pc, & fields->f_11); + if (length <= 0) break; + FLD (f_callnum) = ((((FLD (f_5)) << (3))) | (((((FLD (f_6)) << (2))) | (((((FLD (f_7)) << (1))) | (FLD (f_11))))))); + } + break; + case MEP_OPERAND_CCCC : + length = extract_normal (cd, ex_info, insn_value, 0, 0, 8, 4, 32, total_length, pc, & fields->f_rm); + break; + case MEP_OPERAND_CCRN : + { + length = extract_normal (cd, ex_info, insn_value, 0, 0, 28, 2, 32, total_length, pc, & fields->f_ccrn_hi); + if (length <= 0) break; + length = extract_normal (cd, ex_info, insn_value, 0, 0, 4, 4, 32, total_length, pc, & fields->f_ccrn_lo); + if (length <= 0) break; + FLD (f_ccrn) = ((((FLD (f_ccrn_hi)) << (4))) | (FLD (f_ccrn_lo))); + } + break; + case MEP_OPERAND_CDISP8 : + length = extract_normal (cd, ex_info, insn_value, 0|(1<f_8s24); + break; + case MEP_OPERAND_CDISP8A2 : + { + long value; + length = extract_normal (cd, ex_info, insn_value, 0|(1<f_8s24a2 = value; + } + break; + case MEP_OPERAND_CDISP8A4 : + { + long value; + length = extract_normal (cd, ex_info, insn_value, 0|(1<f_8s24a4 = value; + } + break; + case MEP_OPERAND_CDISP8A8 : + { + long value; + length = extract_normal (cd, ex_info, insn_value, 0|(1<f_8s24a8 = value; + } + break; + case MEP_OPERAND_CIMM4 : + length = extract_normal (cd, ex_info, insn_value, 0, 0, 4, 4, 32, total_length, pc, & fields->f_rn); + break; + case MEP_OPERAND_CIMM5 : + length = extract_normal (cd, ex_info, insn_value, 0, 0, 24, 5, 32, total_length, pc, & fields->f_5u24); + break; + case MEP_OPERAND_CODE16 : + length = extract_normal (cd, ex_info, insn_value, 0, 0, 16, 16, 32, total_length, pc, & fields->f_16u16); + break; + case MEP_OPERAND_CODE24 : + { + length = extract_normal (cd, ex_info, insn_value, 0, 0, 4, 8, 32, total_length, pc, & fields->f_24u4n_hi); + if (length <= 0) break; + length = extract_normal (cd, ex_info, insn_value, 0, 0, 16, 16, 32, total_length, pc, & fields->f_24u4n_lo); + if (length <= 0) break; + FLD (f_24u4n) = ((((FLD (f_24u4n_hi)) << (16))) | (FLD (f_24u4n_lo))); + } + break; + case MEP_OPERAND_CP_FLAG : + break; + case MEP_OPERAND_CRN : + length = extract_normal (cd, ex_info, insn_value, 0, 0, 4, 4, 32, total_length, pc, & fields->f_crn); + break; + case MEP_OPERAND_CRN64 : + length = extract_normal (cd, ex_info, insn_value, 0, 0, 4, 4, 32, total_length, pc, & fields->f_crn); + break; + case MEP_OPERAND_CRNX : + { + length = extract_normal (cd, ex_info, insn_value, 0, 0, 28, 1, 32, total_length, pc, & fields->f_crnx_hi); + if (length <= 0) break; + length = extract_normal (cd, ex_info, insn_value, 0, 0, 4, 4, 32, total_length, pc, & fields->f_crnx_lo); + if (length <= 0) break; + FLD (f_crnx) = ((((FLD (f_crnx_hi)) << (4))) | (FLD (f_crnx_lo))); + } + break; + case MEP_OPERAND_CRNX64 : + { + length = extract_normal (cd, ex_info, insn_value, 0, 0, 28, 1, 32, total_length, pc, & fields->f_crnx_hi); + if (length <= 0) break; + length = extract_normal (cd, ex_info, insn_value, 0, 0, 4, 4, 32, total_length, pc, & fields->f_crnx_lo); + if (length <= 0) break; + FLD (f_crnx) = ((((FLD (f_crnx_hi)) << (4))) | (FLD (f_crnx_lo))); + } + break; + case MEP_OPERAND_CSRN : + { + length = extract_normal (cd, ex_info, insn_value, 0, 0, 15, 1, 32, total_length, pc, & fields->f_csrn_hi); + if (length <= 0) break; + length = extract_normal (cd, ex_info, insn_value, 0, 0, 8, 4, 32, total_length, pc, & fields->f_csrn_lo); + if (length <= 0) break; + FLD (f_csrn) = ((((FLD (f_csrn_hi)) << (4))) | (FLD (f_csrn_lo))); + } + break; + case MEP_OPERAND_CSRN_IDX : + { + length = extract_normal (cd, ex_info, insn_value, 0, 0, 15, 1, 32, total_length, pc, & fields->f_csrn_hi); + if (length <= 0) break; + length = extract_normal (cd, ex_info, insn_value, 0, 0, 8, 4, 32, total_length, pc, & fields->f_csrn_lo); + if (length <= 0) break; + FLD (f_csrn) = ((((FLD (f_csrn_hi)) << (4))) | (FLD (f_csrn_lo))); + } + break; + case MEP_OPERAND_DBG : + break; + case MEP_OPERAND_DEPC : + break; + case MEP_OPERAND_EPC : + break; + case MEP_OPERAND_EXC : + break; + case MEP_OPERAND_FMAX_CCRN : + length = extract_normal (cd, ex_info, insn_value, 0, 0, 4, 4, 32, total_length, pc, & fields->f_fmax_4_4); + break; + case MEP_OPERAND_FMAX_FRD : + { + length = extract_normal (cd, ex_info, insn_value, 0, 0, 28, 1, 32, total_length, pc, & fields->f_fmax_28_1); + if (length <= 0) break; + length = extract_normal (cd, ex_info, insn_value, 0, 0, 4, 4, 32, total_length, pc, & fields->f_fmax_4_4); + if (length <= 0) break; + FLD (f_fmax_frd) = ((((FLD (f_fmax_28_1)) << (4))) | (FLD (f_fmax_4_4))); + } + break; + case MEP_OPERAND_FMAX_FRD_INT : + { + length = extract_normal (cd, ex_info, insn_value, 0, 0, 28, 1, 32, total_length, pc, & fields->f_fmax_28_1); + if (length <= 0) break; + length = extract_normal (cd, ex_info, insn_value, 0, 0, 4, 4, 32, total_length, pc, & fields->f_fmax_4_4); + if (length <= 0) break; + FLD (f_fmax_frd) = ((((FLD (f_fmax_28_1)) << (4))) | (FLD (f_fmax_4_4))); + } + break; + case MEP_OPERAND_FMAX_FRM : + { + length = extract_normal (cd, ex_info, insn_value, 0, 0, 30, 1, 32, total_length, pc, & fields->f_fmax_30_1); + if (length <= 0) break; + length = extract_normal (cd, ex_info, insn_value, 0, 0, 24, 4, 32, total_length, pc, & fields->f_fmax_24_4); + if (length <= 0) break; + FLD (f_fmax_frm) = ((((FLD (f_fmax_30_1)) << (4))) | (FLD (f_fmax_24_4))); + } + break; + case MEP_OPERAND_FMAX_FRN : + { + length = extract_normal (cd, ex_info, insn_value, 0, 0, 29, 1, 32, total_length, pc, & fields->f_fmax_29_1); + if (length <= 0) break; + length = extract_normal (cd, ex_info, insn_value, 0, 0, 20, 4, 32, total_length, pc, & fields->f_fmax_20_4); + if (length <= 0) break; + FLD (f_fmax_frn) = ((((FLD (f_fmax_29_1)) << (4))) | (FLD (f_fmax_20_4))); + } + break; + case MEP_OPERAND_FMAX_FRN_INT : + { + length = extract_normal (cd, ex_info, insn_value, 0, 0, 29, 1, 32, total_length, pc, & fields->f_fmax_29_1); + if (length <= 0) break; + length = extract_normal (cd, ex_info, insn_value, 0, 0, 20, 4, 32, total_length, pc, & fields->f_fmax_20_4); + if (length <= 0) break; + FLD (f_fmax_frn) = ((((FLD (f_fmax_29_1)) << (4))) | (FLD (f_fmax_20_4))); + } + break; + case MEP_OPERAND_FMAX_RM : + length = extract_normal (cd, ex_info, insn_value, 0, 0, 8, 4, 32, total_length, pc, & fields->f_fmax_rm); + break; + case MEP_OPERAND_HI : + break; + case MEP_OPERAND_LO : + break; + case MEP_OPERAND_LP : + break; + case MEP_OPERAND_MB0 : + break; + case MEP_OPERAND_MB1 : + break; + case MEP_OPERAND_ME0 : + break; + case MEP_OPERAND_ME1 : + break; + case MEP_OPERAND_NPC : + break; + case MEP_OPERAND_OPT : + break; + case MEP_OPERAND_PCABS24A2 : + { + length = extract_normal (cd, ex_info, insn_value, 0, 0, 16, 16, 32, total_length, pc, & fields->f_24u5a2n_hi); + if (length <= 0) break; + length = extract_normal (cd, ex_info, insn_value, 0, 0, 5, 7, 32, total_length, pc, & fields->f_24u5a2n_lo); + if (length <= 0) break; + FLD (f_24u5a2n) = ((((FLD (f_24u5a2n_hi)) << (8))) | (((FLD (f_24u5a2n_lo)) << (1)))); + } + break; + case MEP_OPERAND_PCREL12A2 : + { + long value; + length = extract_normal (cd, ex_info, insn_value, 0|(1<f_12s4a2 = value; + } + break; + case MEP_OPERAND_PCREL17A2 : + { + long value; + length = extract_normal (cd, ex_info, insn_value, 0|(1<f_17s16a2 = value; + } + break; + case MEP_OPERAND_PCREL24A2 : + { + length = extract_normal (cd, ex_info, insn_value, 0|(1<f_24s5a2n_hi); + if (length <= 0) break; + length = extract_normal (cd, ex_info, insn_value, 0|(1<f_24s5a2n_lo); + if (length <= 0) break; + FLD (f_24s5a2n) = ((((((FLD (f_24s5a2n_hi)) << (8))) | (((FLD (f_24s5a2n_lo)) << (1))))) + (pc)); + } + break; + case MEP_OPERAND_PCREL8A2 : + { + long value; + length = extract_normal (cd, ex_info, insn_value, 0|(1<f_8s8a2 = value; + } + break; + case MEP_OPERAND_PSW : + break; + case MEP_OPERAND_R0 : + break; + case MEP_OPERAND_R1 : + break; + case MEP_OPERAND_RL : + length = extract_normal (cd, ex_info, insn_value, 0, 0, 12, 4, 32, total_length, pc, & fields->f_rl); + break; + case MEP_OPERAND_RM : + length = extract_normal (cd, ex_info, insn_value, 0, 0, 8, 4, 32, total_length, pc, & fields->f_rm); + break; + case MEP_OPERAND_RMA : + length = extract_normal (cd, ex_info, insn_value, 0, 0, 8, 4, 32, total_length, pc, & fields->f_rm); + break; + case MEP_OPERAND_RN : + length = extract_normal (cd, ex_info, insn_value, 0, 0, 4, 4, 32, total_length, pc, & fields->f_rn); + break; + case MEP_OPERAND_RN3 : + length = extract_normal (cd, ex_info, insn_value, 0, 0, 5, 3, 32, total_length, pc, & fields->f_rn3); + break; + case MEP_OPERAND_RN3C : + length = extract_normal (cd, ex_info, insn_value, 0, 0, 5, 3, 32, total_length, pc, & fields->f_rn3); + break; + case MEP_OPERAND_RN3L : + length = extract_normal (cd, ex_info, insn_value, 0, 0, 5, 3, 32, total_length, pc, & fields->f_rn3); + break; + case MEP_OPERAND_RN3S : + length = extract_normal (cd, ex_info, insn_value, 0, 0, 5, 3, 32, total_length, pc, & fields->f_rn3); + break; + case MEP_OPERAND_RN3UC : + length = extract_normal (cd, ex_info, insn_value, 0, 0, 5, 3, 32, total_length, pc, & fields->f_rn3); + break; + case MEP_OPERAND_RN3UL : + length = extract_normal (cd, ex_info, insn_value, 0, 0, 5, 3, 32, total_length, pc, & fields->f_rn3); + break; + case MEP_OPERAND_RN3US : + length = extract_normal (cd, ex_info, insn_value, 0, 0, 5, 3, 32, total_length, pc, & fields->f_rn3); + break; + case MEP_OPERAND_RNC : + length = extract_normal (cd, ex_info, insn_value, 0, 0, 4, 4, 32, total_length, pc, & fields->f_rn); + break; + case MEP_OPERAND_RNL : + length = extract_normal (cd, ex_info, insn_value, 0, 0, 4, 4, 32, total_length, pc, & fields->f_rn); + break; + case MEP_OPERAND_RNS : + length = extract_normal (cd, ex_info, insn_value, 0, 0, 4, 4, 32, total_length, pc, & fields->f_rn); + break; + case MEP_OPERAND_RNUC : + length = extract_normal (cd, ex_info, insn_value, 0, 0, 4, 4, 32, total_length, pc, & fields->f_rn); + break; + case MEP_OPERAND_RNUL : + length = extract_normal (cd, ex_info, insn_value, 0, 0, 4, 4, 32, total_length, pc, & fields->f_rn); + break; + case MEP_OPERAND_RNUS : + length = extract_normal (cd, ex_info, insn_value, 0, 0, 4, 4, 32, total_length, pc, & fields->f_rn); + break; + case MEP_OPERAND_SAR : + break; + case MEP_OPERAND_SDISP16 : + length = extract_normal (cd, ex_info, insn_value, 0|(1<f_16s16); + break; + case MEP_OPERAND_SIMM16 : + length = extract_normal (cd, ex_info, insn_value, 0|(1<f_16s16); + break; + case MEP_OPERAND_SIMM6 : + length = extract_normal (cd, ex_info, insn_value, 0|(1<f_6s8); + break; + case MEP_OPERAND_SIMM8 : + length = extract_normal (cd, ex_info, insn_value, 0|(1<f_8s8); + break; + case MEP_OPERAND_SP : + break; + case MEP_OPERAND_SPR : + break; + case MEP_OPERAND_TP : + break; + case MEP_OPERAND_TPR : + break; + case MEP_OPERAND_UDISP2 : + length = extract_normal (cd, ex_info, insn_value, 0, 0, 6, 2, 32, total_length, pc, & fields->f_2u6); + break; + case MEP_OPERAND_UDISP7 : + length = extract_normal (cd, ex_info, insn_value, 0, 0, 9, 7, 32, total_length, pc, & fields->f_7u9); + break; + case MEP_OPERAND_UDISP7A2 : + { + long value; + length = extract_normal (cd, ex_info, insn_value, 0, 0, 9, 6, 32, total_length, pc, & value); + value = ((value) << (1)); + fields->f_7u9a2 = value; + } + break; + case MEP_OPERAND_UDISP7A4 : + { + long value; + length = extract_normal (cd, ex_info, insn_value, 0, 0, 9, 5, 32, total_length, pc, & value); + value = ((value) << (2)); + fields->f_7u9a4 = value; + } + break; + case MEP_OPERAND_UIMM16 : + length = extract_normal (cd, ex_info, insn_value, 0, 0, 16, 16, 32, total_length, pc, & fields->f_16u16); + break; + case MEP_OPERAND_UIMM2 : + length = extract_normal (cd, ex_info, insn_value, 0, 0, 10, 2, 32, total_length, pc, & fields->f_2u10); + break; + case MEP_OPERAND_UIMM24 : + { + length = extract_normal (cd, ex_info, insn_value, 0, 0, 16, 16, 32, total_length, pc, & fields->f_24u8n_hi); + if (length <= 0) break; + length = extract_normal (cd, ex_info, insn_value, 0, 0, 8, 8, 32, total_length, pc, & fields->f_24u8n_lo); + if (length <= 0) break; + FLD (f_24u8n) = ((((FLD (f_24u8n_hi)) << (8))) | (FLD (f_24u8n_lo))); + } + break; + case MEP_OPERAND_UIMM3 : + length = extract_normal (cd, ex_info, insn_value, 0, 0, 5, 3, 32, total_length, pc, & fields->f_3u5); + break; + case MEP_OPERAND_UIMM4 : + length = extract_normal (cd, ex_info, insn_value, 0, 0, 8, 4, 32, total_length, pc, & fields->f_4u8); + break; + case MEP_OPERAND_UIMM5 : + length = extract_normal (cd, ex_info, insn_value, 0, 0, 8, 5, 32, total_length, pc, & fields->f_5u8); + break; + case MEP_OPERAND_UIMM7A4 : + { + long value; + length = extract_normal (cd, ex_info, insn_value, 0, 0, 9, 5, 32, total_length, pc, & value); + value = ((value) << (2)); + fields->f_7u9a4 = value; + } + break; + case MEP_OPERAND_ZERO : + break; + + default : + /* xgettext:c-format */ + fprintf (stderr, _("Unrecognized field %d while decoding insn.\n"), + opindex); + abort (); + } + + return length; +} + +cgen_insert_fn * const mep_cgen_insert_handlers[] = +{ + insert_insn_normal, +}; + +cgen_extract_fn * const mep_cgen_extract_handlers[] = +{ + extract_insn_normal, +}; + +int mep_cgen_get_int_operand (CGEN_CPU_DESC, int, const CGEN_FIELDS *); +bfd_vma mep_cgen_get_vma_operand (CGEN_CPU_DESC, int, const CGEN_FIELDS *); + +/* Getting values from cgen_fields is handled by a collection of functions. + They are distinguished by the type of the VALUE argument they return. + TODO: floating point, inlining support, remove cases where result type + not appropriate. */ + +int +mep_cgen_get_int_operand (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED, + int opindex, + const CGEN_FIELDS * fields) +{ + int value; + + switch (opindex) + { + case MEP_OPERAND_ADDR24A4 : + value = fields->f_24u8a4n; + break; + case MEP_OPERAND_CALLNUM : + value = fields->f_callnum; + break; + case MEP_OPERAND_CCCC : + value = fields->f_rm; + break; + case MEP_OPERAND_CCRN : + value = fields->f_ccrn; + break; + case MEP_OPERAND_CDISP8 : + value = fields->f_8s24; + break; + case MEP_OPERAND_CDISP8A2 : + value = fields->f_8s24a2; + break; + case MEP_OPERAND_CDISP8A4 : + value = fields->f_8s24a4; + break; + case MEP_OPERAND_CDISP8A8 : + value = fields->f_8s24a8; + break; + case MEP_OPERAND_CIMM4 : + value = fields->f_rn; + break; + case MEP_OPERAND_CIMM5 : + value = fields->f_5u24; + break; + case MEP_OPERAND_CODE16 : + value = fields->f_16u16; + break; + case MEP_OPERAND_CODE24 : + value = fields->f_24u4n; + break; + case MEP_OPERAND_CP_FLAG : + value = 0; + break; + case MEP_OPERAND_CRN : + value = fields->f_crn; + break; + case MEP_OPERAND_CRN64 : + value = fields->f_crn; + break; + case MEP_OPERAND_CRNX : + value = fields->f_crnx; + break; + case MEP_OPERAND_CRNX64 : + value = fields->f_crnx; + break; + case MEP_OPERAND_CSRN : + value = fields->f_csrn; + break; + case MEP_OPERAND_CSRN_IDX : + value = fields->f_csrn; + break; + case MEP_OPERAND_DBG : + value = 0; + break; + case MEP_OPERAND_DEPC : + value = 0; + break; + case MEP_OPERAND_EPC : + value = 0; + break; + case MEP_OPERAND_EXC : + value = 0; + break; + case MEP_OPERAND_FMAX_CCRN : + value = fields->f_fmax_4_4; + break; + case MEP_OPERAND_FMAX_FRD : + value = fields->f_fmax_frd; + break; + case MEP_OPERAND_FMAX_FRD_INT : + value = fields->f_fmax_frd; + break; + case MEP_OPERAND_FMAX_FRM : + value = fields->f_fmax_frm; + break; + case MEP_OPERAND_FMAX_FRN : + value = fields->f_fmax_frn; + break; + case MEP_OPERAND_FMAX_FRN_INT : + value = fields->f_fmax_frn; + break; + case MEP_OPERAND_FMAX_RM : + value = fields->f_fmax_rm; + break; + case MEP_OPERAND_HI : + value = 0; + break; + case MEP_OPERAND_LO : + value = 0; + break; + case MEP_OPERAND_LP : + value = 0; + break; + case MEP_OPERAND_MB0 : + value = 0; + break; + case MEP_OPERAND_MB1 : + value = 0; + break; + case MEP_OPERAND_ME0 : + value = 0; + break; + case MEP_OPERAND_ME1 : + value = 0; + break; + case MEP_OPERAND_NPC : + value = 0; + break; + case MEP_OPERAND_OPT : + value = 0; + break; + case MEP_OPERAND_PCABS24A2 : + value = fields->f_24u5a2n; + break; + case MEP_OPERAND_PCREL12A2 : + value = fields->f_12s4a2; + break; + case MEP_OPERAND_PCREL17A2 : + value = fields->f_17s16a2; + break; + case MEP_OPERAND_PCREL24A2 : + value = fields->f_24s5a2n; + break; + case MEP_OPERAND_PCREL8A2 : + value = fields->f_8s8a2; + break; + case MEP_OPERAND_PSW : + value = 0; + break; + case MEP_OPERAND_R0 : + value = 0; + break; + case MEP_OPERAND_R1 : + value = 0; + break; + case MEP_OPERAND_RL : + value = fields->f_rl; + break; + case MEP_OPERAND_RM : + value = fields->f_rm; + break; + case MEP_OPERAND_RMA : + value = fields->f_rm; + break; + case MEP_OPERAND_RN : + value = fields->f_rn; + break; + case MEP_OPERAND_RN3 : + value = fields->f_rn3; + break; + case MEP_OPERAND_RN3C : + value = fields->f_rn3; + break; + case MEP_OPERAND_RN3L : + value = fields->f_rn3; + break; + case MEP_OPERAND_RN3S : + value = fields->f_rn3; + break; + case MEP_OPERAND_RN3UC : + value = fields->f_rn3; + break; + case MEP_OPERAND_RN3UL : + value = fields->f_rn3; + break; + case MEP_OPERAND_RN3US : + value = fields->f_rn3; + break; + case MEP_OPERAND_RNC : + value = fields->f_rn; + break; + case MEP_OPERAND_RNL : + value = fields->f_rn; + break; + case MEP_OPERAND_RNS : + value = fields->f_rn; + break; + case MEP_OPERAND_RNUC : + value = fields->f_rn; + break; + case MEP_OPERAND_RNUL : + value = fields->f_rn; + break; + case MEP_OPERAND_RNUS : + value = fields->f_rn; + break; + case MEP_OPERAND_SAR : + value = 0; + break; + case MEP_OPERAND_SDISP16 : + value = fields->f_16s16; + break; + case MEP_OPERAND_SIMM16 : + value = fields->f_16s16; + break; + case MEP_OPERAND_SIMM6 : + value = fields->f_6s8; + break; + case MEP_OPERAND_SIMM8 : + value = fields->f_8s8; + break; + case MEP_OPERAND_SP : + value = 0; + break; + case MEP_OPERAND_SPR : + value = 0; + break; + case MEP_OPERAND_TP : + value = 0; + break; + case MEP_OPERAND_TPR : + value = 0; + break; + case MEP_OPERAND_UDISP2 : + value = fields->f_2u6; + break; + case MEP_OPERAND_UDISP7 : + value = fields->f_7u9; + break; + case MEP_OPERAND_UDISP7A2 : + value = fields->f_7u9a2; + break; + case MEP_OPERAND_UDISP7A4 : + value = fields->f_7u9a4; + break; + case MEP_OPERAND_UIMM16 : + value = fields->f_16u16; + break; + case MEP_OPERAND_UIMM2 : + value = fields->f_2u10; + break; + case MEP_OPERAND_UIMM24 : + value = fields->f_24u8n; + break; + case MEP_OPERAND_UIMM3 : + value = fields->f_3u5; + break; + case MEP_OPERAND_UIMM4 : + value = fields->f_4u8; + break; + case MEP_OPERAND_UIMM5 : + value = fields->f_5u8; + break; + case MEP_OPERAND_UIMM7A4 : + value = fields->f_7u9a4; + break; + case MEP_OPERAND_ZERO : + value = 0; + break; + + default : + /* xgettext:c-format */ + fprintf (stderr, _("Unrecognized field %d while getting int operand.\n"), + opindex); + abort (); + } + + return value; +} + +bfd_vma +mep_cgen_get_vma_operand (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED, + int opindex, + const CGEN_FIELDS * fields) +{ + bfd_vma value; + + switch (opindex) + { + case MEP_OPERAND_ADDR24A4 : + value = fields->f_24u8a4n; + break; + case MEP_OPERAND_CALLNUM : + value = fields->f_callnum; + break; + case MEP_OPERAND_CCCC : + value = fields->f_rm; + break; + case MEP_OPERAND_CCRN : + value = fields->f_ccrn; + break; + case MEP_OPERAND_CDISP8 : + value = fields->f_8s24; + break; + case MEP_OPERAND_CDISP8A2 : + value = fields->f_8s24a2; + break; + case MEP_OPERAND_CDISP8A4 : + value = fields->f_8s24a4; + break; + case MEP_OPERAND_CDISP8A8 : + value = fields->f_8s24a8; + break; + case MEP_OPERAND_CIMM4 : + value = fields->f_rn; + break; + case MEP_OPERAND_CIMM5 : + value = fields->f_5u24; + break; + case MEP_OPERAND_CODE16 : + value = fields->f_16u16; + break; + case MEP_OPERAND_CODE24 : + value = fields->f_24u4n; + break; + case MEP_OPERAND_CP_FLAG : + value = 0; + break; + case MEP_OPERAND_CRN : + value = fields->f_crn; + break; + case MEP_OPERAND_CRN64 : + value = fields->f_crn; + break; + case MEP_OPERAND_CRNX : + value = fields->f_crnx; + break; + case MEP_OPERAND_CRNX64 : + value = fields->f_crnx; + break; + case MEP_OPERAND_CSRN : + value = fields->f_csrn; + break; + case MEP_OPERAND_CSRN_IDX : + value = fields->f_csrn; + break; + case MEP_OPERAND_DBG : + value = 0; + break; + case MEP_OPERAND_DEPC : + value = 0; + break; + case MEP_OPERAND_EPC : + value = 0; + break; + case MEP_OPERAND_EXC : + value = 0; + break; + case MEP_OPERAND_FMAX_CCRN : + value = fields->f_fmax_4_4; + break; + case MEP_OPERAND_FMAX_FRD : + value = fields->f_fmax_frd; + break; + case MEP_OPERAND_FMAX_FRD_INT : + value = fields->f_fmax_frd; + break; + case MEP_OPERAND_FMAX_FRM : + value = fields->f_fmax_frm; + break; + case MEP_OPERAND_FMAX_FRN : + value = fields->f_fmax_frn; + break; + case MEP_OPERAND_FMAX_FRN_INT : + value = fields->f_fmax_frn; + break; + case MEP_OPERAND_FMAX_RM : + value = fields->f_fmax_rm; + break; + case MEP_OPERAND_HI : + value = 0; + break; + case MEP_OPERAND_LO : + value = 0; + break; + case MEP_OPERAND_LP : + value = 0; + break; + case MEP_OPERAND_MB0 : + value = 0; + break; + case MEP_OPERAND_MB1 : + value = 0; + break; + case MEP_OPERAND_ME0 : + value = 0; + break; + case MEP_OPERAND_ME1 : + value = 0; + break; + case MEP_OPERAND_NPC : + value = 0; + break; + case MEP_OPERAND_OPT : + value = 0; + break; + case MEP_OPERAND_PCABS24A2 : + value = fields->f_24u5a2n; + break; + case MEP_OPERAND_PCREL12A2 : + value = fields->f_12s4a2; + break; + case MEP_OPERAND_PCREL17A2 : + value = fields->f_17s16a2; + break; + case MEP_OPERAND_PCREL24A2 : + value = fields->f_24s5a2n; + break; + case MEP_OPERAND_PCREL8A2 : + value = fields->f_8s8a2; + break; + case MEP_OPERAND_PSW : + value = 0; + break; + case MEP_OPERAND_R0 : + value = 0; + break; + case MEP_OPERAND_R1 : + value = 0; + break; + case MEP_OPERAND_RL : + value = fields->f_rl; + break; + case MEP_OPERAND_RM : + value = fields->f_rm; + break; + case MEP_OPERAND_RMA : + value = fields->f_rm; + break; + case MEP_OPERAND_RN : + value = fields->f_rn; + break; + case MEP_OPERAND_RN3 : + value = fields->f_rn3; + break; + case MEP_OPERAND_RN3C : + value = fields->f_rn3; + break; + case MEP_OPERAND_RN3L : + value = fields->f_rn3; + break; + case MEP_OPERAND_RN3S : + value = fields->f_rn3; + break; + case MEP_OPERAND_RN3UC : + value = fields->f_rn3; + break; + case MEP_OPERAND_RN3UL : + value = fields->f_rn3; + break; + case MEP_OPERAND_RN3US : + value = fields->f_rn3; + break; + case MEP_OPERAND_RNC : + value = fields->f_rn; + break; + case MEP_OPERAND_RNL : + value = fields->f_rn; + break; + case MEP_OPERAND_RNS : + value = fields->f_rn; + break; + case MEP_OPERAND_RNUC : + value = fields->f_rn; + break; + case MEP_OPERAND_RNUL : + value = fields->f_rn; + break; + case MEP_OPERAND_RNUS : + value = fields->f_rn; + break; + case MEP_OPERAND_SAR : + value = 0; + break; + case MEP_OPERAND_SDISP16 : + value = fields->f_16s16; + break; + case MEP_OPERAND_SIMM16 : + value = fields->f_16s16; + break; + case MEP_OPERAND_SIMM6 : + value = fields->f_6s8; + break; + case MEP_OPERAND_SIMM8 : + value = fields->f_8s8; + break; + case MEP_OPERAND_SP : + value = 0; + break; + case MEP_OPERAND_SPR : + value = 0; + break; + case MEP_OPERAND_TP : + value = 0; + break; + case MEP_OPERAND_TPR : + value = 0; + break; + case MEP_OPERAND_UDISP2 : + value = fields->f_2u6; + break; + case MEP_OPERAND_UDISP7 : + value = fields->f_7u9; + break; + case MEP_OPERAND_UDISP7A2 : + value = fields->f_7u9a2; + break; + case MEP_OPERAND_UDISP7A4 : + value = fields->f_7u9a4; + break; + case MEP_OPERAND_UIMM16 : + value = fields->f_16u16; + break; + case MEP_OPERAND_UIMM2 : + value = fields->f_2u10; + break; + case MEP_OPERAND_UIMM24 : + value = fields->f_24u8n; + break; + case MEP_OPERAND_UIMM3 : + value = fields->f_3u5; + break; + case MEP_OPERAND_UIMM4 : + value = fields->f_4u8; + break; + case MEP_OPERAND_UIMM5 : + value = fields->f_5u8; + break; + case MEP_OPERAND_UIMM7A4 : + value = fields->f_7u9a4; + break; + case MEP_OPERAND_ZERO : + value = 0; + break; + + default : + /* xgettext:c-format */ + fprintf (stderr, _("Unrecognized field %d while getting vma operand.\n"), + opindex); + abort (); + } + + return value; +} + +void mep_cgen_set_int_operand (CGEN_CPU_DESC, int, CGEN_FIELDS *, int); +void mep_cgen_set_vma_operand (CGEN_CPU_DESC, int, CGEN_FIELDS *, bfd_vma); + +/* Stuffing values in cgen_fields is handled by a collection of functions. + They are distinguished by the type of the VALUE argument they accept. + TODO: floating point, inlining support, remove cases where argument type + not appropriate. */ + +void +mep_cgen_set_int_operand (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED, + int opindex, + CGEN_FIELDS * fields, + int value) +{ + switch (opindex) + { + case MEP_OPERAND_ADDR24A4 : + fields->f_24u8a4n = value; + break; + case MEP_OPERAND_CALLNUM : + fields->f_callnum = value; + break; + case MEP_OPERAND_CCCC : + fields->f_rm = value; + break; + case MEP_OPERAND_CCRN : + fields->f_ccrn = value; + break; + case MEP_OPERAND_CDISP8 : + fields->f_8s24 = value; + break; + case MEP_OPERAND_CDISP8A2 : + fields->f_8s24a2 = value; + break; + case MEP_OPERAND_CDISP8A4 : + fields->f_8s24a4 = value; + break; + case MEP_OPERAND_CDISP8A8 : + fields->f_8s24a8 = value; + break; + case MEP_OPERAND_CIMM4 : + fields->f_rn = value; + break; + case MEP_OPERAND_CIMM5 : + fields->f_5u24 = value; + break; + case MEP_OPERAND_CODE16 : + fields->f_16u16 = value; + break; + case MEP_OPERAND_CODE24 : + fields->f_24u4n = value; + break; + case MEP_OPERAND_CP_FLAG : + break; + case MEP_OPERAND_CRN : + fields->f_crn = value; + break; + case MEP_OPERAND_CRN64 : + fields->f_crn = value; + break; + case MEP_OPERAND_CRNX : + fields->f_crnx = value; + break; + case MEP_OPERAND_CRNX64 : + fields->f_crnx = value; + break; + case MEP_OPERAND_CSRN : + fields->f_csrn = value; + break; + case MEP_OPERAND_CSRN_IDX : + fields->f_csrn = value; + break; + case MEP_OPERAND_DBG : + break; + case MEP_OPERAND_DEPC : + break; + case MEP_OPERAND_EPC : + break; + case MEP_OPERAND_EXC : + break; + case MEP_OPERAND_FMAX_CCRN : + fields->f_fmax_4_4 = value; + break; + case MEP_OPERAND_FMAX_FRD : + fields->f_fmax_frd = value; + break; + case MEP_OPERAND_FMAX_FRD_INT : + fields->f_fmax_frd = value; + break; + case MEP_OPERAND_FMAX_FRM : + fields->f_fmax_frm = value; + break; + case MEP_OPERAND_FMAX_FRN : + fields->f_fmax_frn = value; + break; + case MEP_OPERAND_FMAX_FRN_INT : + fields->f_fmax_frn = value; + break; + case MEP_OPERAND_FMAX_RM : + fields->f_fmax_rm = value; + break; + case MEP_OPERAND_HI : + break; + case MEP_OPERAND_LO : + break; + case MEP_OPERAND_LP : + break; + case MEP_OPERAND_MB0 : + break; + case MEP_OPERAND_MB1 : + break; + case MEP_OPERAND_ME0 : + break; + case MEP_OPERAND_ME1 : + break; + case MEP_OPERAND_NPC : + break; + case MEP_OPERAND_OPT : + break; + case MEP_OPERAND_PCABS24A2 : + fields->f_24u5a2n = value; + break; + case MEP_OPERAND_PCREL12A2 : + fields->f_12s4a2 = value; + break; + case MEP_OPERAND_PCREL17A2 : + fields->f_17s16a2 = value; + break; + case MEP_OPERAND_PCREL24A2 : + fields->f_24s5a2n = value; + break; + case MEP_OPERAND_PCREL8A2 : + fields->f_8s8a2 = value; + break; + case MEP_OPERAND_PSW : + break; + case MEP_OPERAND_R0 : + break; + case MEP_OPERAND_R1 : + break; + case MEP_OPERAND_RL : + fields->f_rl = value; + break; + case MEP_OPERAND_RM : + fields->f_rm = value; + break; + case MEP_OPERAND_RMA : + fields->f_rm = value; + break; + case MEP_OPERAND_RN : + fields->f_rn = value; + break; + case MEP_OPERAND_RN3 : + fields->f_rn3 = value; + break; + case MEP_OPERAND_RN3C : + fields->f_rn3 = value; + break; + case MEP_OPERAND_RN3L : + fields->f_rn3 = value; + break; + case MEP_OPERAND_RN3S : + fields->f_rn3 = value; + break; + case MEP_OPERAND_RN3UC : + fields->f_rn3 = value; + break; + case MEP_OPERAND_RN3UL : + fields->f_rn3 = value; + break; + case MEP_OPERAND_RN3US : + fields->f_rn3 = value; + break; + case MEP_OPERAND_RNC : + fields->f_rn = value; + break; + case MEP_OPERAND_RNL : + fields->f_rn = value; + break; + case MEP_OPERAND_RNS : + fields->f_rn = value; + break; + case MEP_OPERAND_RNUC : + fields->f_rn = value; + break; + case MEP_OPERAND_RNUL : + fields->f_rn = value; + break; + case MEP_OPERAND_RNUS : + fields->f_rn = value; + break; + case MEP_OPERAND_SAR : + break; + case MEP_OPERAND_SDISP16 : + fields->f_16s16 = value; + break; + case MEP_OPERAND_SIMM16 : + fields->f_16s16 = value; + break; + case MEP_OPERAND_SIMM6 : + fields->f_6s8 = value; + break; + case MEP_OPERAND_SIMM8 : + fields->f_8s8 = value; + break; + case MEP_OPERAND_SP : + break; + case MEP_OPERAND_SPR : + break; + case MEP_OPERAND_TP : + break; + case MEP_OPERAND_TPR : + break; + case MEP_OPERAND_UDISP2 : + fields->f_2u6 = value; + break; + case MEP_OPERAND_UDISP7 : + fields->f_7u9 = value; + break; + case MEP_OPERAND_UDISP7A2 : + fields->f_7u9a2 = value; + break; + case MEP_OPERAND_UDISP7A4 : + fields->f_7u9a4 = value; + break; + case MEP_OPERAND_UIMM16 : + fields->f_16u16 = value; + break; + case MEP_OPERAND_UIMM2 : + fields->f_2u10 = value; + break; + case MEP_OPERAND_UIMM24 : + fields->f_24u8n = value; + break; + case MEP_OPERAND_UIMM3 : + fields->f_3u5 = value; + break; + case MEP_OPERAND_UIMM4 : + fields->f_4u8 = value; + break; + case MEP_OPERAND_UIMM5 : + fields->f_5u8 = value; + break; + case MEP_OPERAND_UIMM7A4 : + fields->f_7u9a4 = value; + break; + case MEP_OPERAND_ZERO : + break; + + default : + /* xgettext:c-format */ + fprintf (stderr, _("Unrecognized field %d while setting int operand.\n"), + opindex); + abort (); + } +} + +void +mep_cgen_set_vma_operand (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED, + int opindex, + CGEN_FIELDS * fields, + bfd_vma value) +{ + switch (opindex) + { + case MEP_OPERAND_ADDR24A4 : + fields->f_24u8a4n = value; + break; + case MEP_OPERAND_CALLNUM : + fields->f_callnum = value; + break; + case MEP_OPERAND_CCCC : + fields->f_rm = value; + break; + case MEP_OPERAND_CCRN : + fields->f_ccrn = value; + break; + case MEP_OPERAND_CDISP8 : + fields->f_8s24 = value; + break; + case MEP_OPERAND_CDISP8A2 : + fields->f_8s24a2 = value; + break; + case MEP_OPERAND_CDISP8A4 : + fields->f_8s24a4 = value; + break; + case MEP_OPERAND_CDISP8A8 : + fields->f_8s24a8 = value; + break; + case MEP_OPERAND_CIMM4 : + fields->f_rn = value; + break; + case MEP_OPERAND_CIMM5 : + fields->f_5u24 = value; + break; + case MEP_OPERAND_CODE16 : + fields->f_16u16 = value; + break; + case MEP_OPERAND_CODE24 : + fields->f_24u4n = value; + break; + case MEP_OPERAND_CP_FLAG : + break; + case MEP_OPERAND_CRN : + fields->f_crn = value; + break; + case MEP_OPERAND_CRN64 : + fields->f_crn = value; + break; + case MEP_OPERAND_CRNX : + fields->f_crnx = value; + break; + case MEP_OPERAND_CRNX64 : + fields->f_crnx = value; + break; + case MEP_OPERAND_CSRN : + fields->f_csrn = value; + break; + case MEP_OPERAND_CSRN_IDX : + fields->f_csrn = value; + break; + case MEP_OPERAND_DBG : + break; + case MEP_OPERAND_DEPC : + break; + case MEP_OPERAND_EPC : + break; + case MEP_OPERAND_EXC : + break; + case MEP_OPERAND_FMAX_CCRN : + fields->f_fmax_4_4 = value; + break; + case MEP_OPERAND_FMAX_FRD : + fields->f_fmax_frd = value; + break; + case MEP_OPERAND_FMAX_FRD_INT : + fields->f_fmax_frd = value; + break; + case MEP_OPERAND_FMAX_FRM : + fields->f_fmax_frm = value; + break; + case MEP_OPERAND_FMAX_FRN : + fields->f_fmax_frn = value; + break; + case MEP_OPERAND_FMAX_FRN_INT : + fields->f_fmax_frn = value; + break; + case MEP_OPERAND_FMAX_RM : + fields->f_fmax_rm = value; + break; + case MEP_OPERAND_HI : + break; + case MEP_OPERAND_LO : + break; + case MEP_OPERAND_LP : + break; + case MEP_OPERAND_MB0 : + break; + case MEP_OPERAND_MB1 : + break; + case MEP_OPERAND_ME0 : + break; + case MEP_OPERAND_ME1 : + break; + case MEP_OPERAND_NPC : + break; + case MEP_OPERAND_OPT : + break; + case MEP_OPERAND_PCABS24A2 : + fields->f_24u5a2n = value; + break; + case MEP_OPERAND_PCREL12A2 : + fields->f_12s4a2 = value; + break; + case MEP_OPERAND_PCREL17A2 : + fields->f_17s16a2 = value; + break; + case MEP_OPERAND_PCREL24A2 : + fields->f_24s5a2n = value; + break; + case MEP_OPERAND_PCREL8A2 : + fields->f_8s8a2 = value; + break; + case MEP_OPERAND_PSW : + break; + case MEP_OPERAND_R0 : + break; + case MEP_OPERAND_R1 : + break; + case MEP_OPERAND_RL : + fields->f_rl = value; + break; + case MEP_OPERAND_RM : + fields->f_rm = value; + break; + case MEP_OPERAND_RMA : + fields->f_rm = value; + break; + case MEP_OPERAND_RN : + fields->f_rn = value; + break; + case MEP_OPERAND_RN3 : + fields->f_rn3 = value; + break; + case MEP_OPERAND_RN3C : + fields->f_rn3 = value; + break; + case MEP_OPERAND_RN3L : + fields->f_rn3 = value; + break; + case MEP_OPERAND_RN3S : + fields->f_rn3 = value; + break; + case MEP_OPERAND_RN3UC : + fields->f_rn3 = value; + break; + case MEP_OPERAND_RN3UL : + fields->f_rn3 = value; + break; + case MEP_OPERAND_RN3US : + fields->f_rn3 = value; + break; + case MEP_OPERAND_RNC : + fields->f_rn = value; + break; + case MEP_OPERAND_RNL : + fields->f_rn = value; + break; + case MEP_OPERAND_RNS : + fields->f_rn = value; + break; + case MEP_OPERAND_RNUC : + fields->f_rn = value; + break; + case MEP_OPERAND_RNUL : + fields->f_rn = value; + break; + case MEP_OPERAND_RNUS : + fields->f_rn = value; + break; + case MEP_OPERAND_SAR : + break; + case MEP_OPERAND_SDISP16 : + fields->f_16s16 = value; + break; + case MEP_OPERAND_SIMM16 : + fields->f_16s16 = value; + break; + case MEP_OPERAND_SIMM6 : + fields->f_6s8 = value; + break; + case MEP_OPERAND_SIMM8 : + fields->f_8s8 = value; + break; + case MEP_OPERAND_SP : + break; + case MEP_OPERAND_SPR : + break; + case MEP_OPERAND_TP : + break; + case MEP_OPERAND_TPR : + break; + case MEP_OPERAND_UDISP2 : + fields->f_2u6 = value; + break; + case MEP_OPERAND_UDISP7 : + fields->f_7u9 = value; + break; + case MEP_OPERAND_UDISP7A2 : + fields->f_7u9a2 = value; + break; + case MEP_OPERAND_UDISP7A4 : + fields->f_7u9a4 = value; + break; + case MEP_OPERAND_UIMM16 : + fields->f_16u16 = value; + break; + case MEP_OPERAND_UIMM2 : + fields->f_2u10 = value; + break; + case MEP_OPERAND_UIMM24 : + fields->f_24u8n = value; + break; + case MEP_OPERAND_UIMM3 : + fields->f_3u5 = value; + break; + case MEP_OPERAND_UIMM4 : + fields->f_4u8 = value; + break; + case MEP_OPERAND_UIMM5 : + fields->f_5u8 = value; + break; + case MEP_OPERAND_UIMM7A4 : + fields->f_7u9a4 = value; + break; + case MEP_OPERAND_ZERO : + break; + + default : + /* xgettext:c-format */ + fprintf (stderr, _("Unrecognized field %d while setting vma operand.\n"), + opindex); + abort (); + } +} + +/* Function to call before using the instruction builder tables. */ + +void +mep_cgen_init_ibld_table (CGEN_CPU_DESC cd) +{ + cd->insert_handlers = & mep_cgen_insert_handlers[0]; + cd->extract_handlers = & mep_cgen_extract_handlers[0]; + + cd->insert_operand = mep_cgen_insert_operand; + cd->extract_operand = mep_cgen_extract_operand; + + cd->get_int_operand = mep_cgen_get_int_operand; + cd->set_int_operand = mep_cgen_set_int_operand; + cd->get_vma_operand = mep_cgen_get_vma_operand; + cd->set_vma_operand = mep_cgen_set_vma_operand; +} diff --git a/opcodes/mep-opc.c b/opcodes/mep-opc.c new file mode 100644 index 00000000000..ab5cf4aba12 --- /dev/null +++ b/opcodes/mep-opc.c @@ -0,0 +1,2274 @@ +/* Instruction opcode table for mep. + +THIS FILE IS MACHINE GENERATED WITH CGEN. + +Copyright 1996-2005 Free Software Foundation, Inc. + +This file is part of the GNU Binutils and/or GDB, the GNU debugger. + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along +with this program; if not, write to the Free Software Foundation, Inc., +51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. + +*/ + +#include "sysdep.h" +#include "ansidecl.h" +#include "bfd.h" +#include "symcat.h" +#include "mep-desc.h" +#include "mep-opc.h" +#include "libiberty.h" + +/* -- opc.c */ +#include "elf/mep.h" + +/* A mask for all ISAs executed by the core. */ +CGEN_ATTR_VALUE_BITSET_TYPE mep_all_core_isas_mask = {0, 0}; + +void +init_mep_all_core_isas_mask (void) +{ + if (mep_all_core_isas_mask.length != 0) + return; + cgen_bitset_init (& mep_all_core_isas_mask, ISA_MAX); + cgen_bitset_set (& mep_all_core_isas_mask, ISA_MEP); + /* begin-all-core-isas */ + cgen_bitset_add (& mep_all_core_isas_mask, ISA_EXT_CORE1); + cgen_bitset_add (& mep_all_core_isas_mask, ISA_EXT_CORE2); + /* end-all-core-isas */ +} + +CGEN_ATTR_VALUE_BITSET_TYPE mep_all_cop_isas_mask = {0, 0}; + +void +init_mep_all_cop_isas_mask (void) +{ + if (mep_all_cop_isas_mask.length != 0) + return; + cgen_bitset_init (& mep_all_cop_isas_mask, ISA_MAX); + /* begin-all-cop-isas */ + cgen_bitset_add (& mep_all_cop_isas_mask, ISA_EXT_COP2_16); + cgen_bitset_add (& mep_all_cop_isas_mask, ISA_EXT_COP2_32); + cgen_bitset_add (& mep_all_cop_isas_mask, ISA_EXT_COP2_48); + cgen_bitset_add (& mep_all_cop_isas_mask, ISA_EXT_COP2_64); + /* end-all-cop-isas */ +} + +int +mep_insn_supported_by_isa (const CGEN_INSN *insn, CGEN_ATTR_VALUE_BITSET_TYPE *isa_mask) +{ + CGEN_BITSET insn_isas = CGEN_INSN_BITSET_ATTR_VALUE (insn, CGEN_INSN_ISA); + return cgen_bitset_intersect_p (& insn_isas, isa_mask); +} + +#define OPTION_MASK \ + ( (1 << CGEN_INSN_OPTIONAL_BIT_INSN) \ + | (1 << CGEN_INSN_OPTIONAL_MUL_INSN) \ + | (1 << CGEN_INSN_OPTIONAL_DIV_INSN) \ + | (1 << CGEN_INSN_OPTIONAL_DEBUG_INSN) \ + | (1 << CGEN_INSN_OPTIONAL_LDZ_INSN) \ + | (1 << CGEN_INSN_OPTIONAL_ABS_INSN) \ + | (1 << CGEN_INSN_OPTIONAL_AVE_INSN) \ + | (1 << CGEN_INSN_OPTIONAL_MINMAX_INSN) \ + | (1 << CGEN_INSN_OPTIONAL_CLIP_INSN) \ + | (1 << CGEN_INSN_OPTIONAL_SAT_INSN) \ + | (1 << CGEN_INSN_OPTIONAL_UCI_INSN) \ + | (1 << CGEN_INSN_OPTIONAL_DSP_INSN) \ + | (1 << CGEN_INSN_OPTIONAL_CP_INSN) \ + | (1 << CGEN_INSN_OPTIONAL_CP64_INSN) ) + + +mep_config_map_struct mep_config_map[] = +{ + /* config-map-start */ + /* Default entry: mep core only, all options enabled. */ + { "", 0, EF_MEP_CPU_C2, 1, 0, {1,"\x0"}, {1,"\x0"}, {1,"\x0"}, {1,"\x0"}, {1,"\x0"}, {1,"\x80"}, OPTION_MASK }, + { "simple", CONFIG_SIMPLE, EF_MEP_CPU_C2, 1, 0, { 1, "\x0" }, { 1, "\x0" }, { 1, "\x0" }, { 1, "\x0" }, { 1, "\x0" }, { 1, "\xc0" }, + 0 }, + { "fmax", CONFIG_FMAX, EF_MEP_CPU_C2, 1, 0, { 1, "\x10" }, { 1, "\x8" }, { 1, "\x4" }, { 1, "\x2" }, { 1, "\x1e" }, { 1, "\xa0" }, + 0 + | (1 << CGEN_INSN_OPTIONAL_CP_INSN) + | (1 << CGEN_INSN_OPTIONAL_MUL_INSN) + | (1 << CGEN_INSN_OPTIONAL_DIV_INSN) + | (1 << CGEN_INSN_OPTIONAL_BIT_INSN) + | (1 << CGEN_INSN_OPTIONAL_LDZ_INSN) + | (1 << CGEN_INSN_OPTIONAL_ABS_INSN) + | (1 << CGEN_INSN_OPTIONAL_AVE_INSN) + | (1 << CGEN_INSN_OPTIONAL_MINMAX_INSN) + | (1 << CGEN_INSN_OPTIONAL_CLIP_INSN) + | (1 << CGEN_INSN_OPTIONAL_SAT_INSN) }, + /* config-map-end */ + { 0, 0, 0, 0, 0, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, 0 } +}; + +int mep_config_index = 0; + +static int +check_configured_mach (int machs) +{ + /* All base insns are supported. */ + int mach = 1 << MACH_BASE; + switch (MEP_CPU) + { + case EF_MEP_CPU_C2: + case EF_MEP_CPU_C3: + mach |= (1 << MACH_MEP); + break; + case EF_MEP_CPU_H1: + mach |= (1 << MACH_H1); + break; + default: + break; + } + return machs & mach; +} + +int +mep_cgen_insn_supported (CGEN_CPU_DESC cd, const CGEN_INSN *insn) +{ + int iconfig = CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_CONFIG); + int machs = CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_MACH); + CGEN_BITSET isas = CGEN_INSN_BITSET_ATTR_VALUE (insn, CGEN_INSN_ISA); + int ok1; + int ok2; + int ok3; + + /* If the insn has an option bit set that we don't want, + reject it. */ + if (CGEN_INSN_ATTRS (insn)->bool & OPTION_MASK & ~MEP_OMASK) + return 0; + + /* If attributes are absent, assume no restriction. */ + if (machs == 0) + machs = ~0; + + ok1 = ((machs & cd->machs) && cgen_bitset_intersect_p (& isas, cd->isas)); + /* If the insn is config-specific, make sure it matches. */ + ok2 = (iconfig == 0 || iconfig == MEP_CONFIG); + /* Make sure the insn is supported by the configured mach */ + ok3 = check_configured_mach (machs); + + return (ok1 && ok2 && ok3); +} +/* The hash functions are recorded here to help keep assembler code out of + the disassembler and vice versa. */ + +static int asm_hash_insn_p (const CGEN_INSN *); +static unsigned int asm_hash_insn (const char *); +static int dis_hash_insn_p (const CGEN_INSN *); +static unsigned int dis_hash_insn (const char *, CGEN_INSN_INT); + +/* Instruction formats. */ + +#if defined (__STDC__) || defined (ALMOST_STDC) || defined (HAVE_STRINGIZE) +#define F(f) & mep_cgen_ifld_table[MEP_##f] +#else +#define F(f) & mep_cgen_ifld_table[MEP_/**/f] +#endif +static const CGEN_IFMT ifmt_empty ATTRIBUTE_UNUSED = { + 0, 0, 0x0, { { 0 } } +}; + +static const CGEN_IFMT ifmt_sb ATTRIBUTE_UNUSED = { + 16, 16, 0xf00f, { { F (F_MAJOR) }, { F (F_RN) }, { F (F_RM) }, { F (F_SUB4) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_sh ATTRIBUTE_UNUSED = { + 16, 16, 0xf00f, { { F (F_MAJOR) }, { F (F_RN) }, { F (F_RM) }, { F (F_SUB4) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_sw ATTRIBUTE_UNUSED = { + 16, 16, 0xf00f, { { F (F_MAJOR) }, { F (F_RN) }, { F (F_RM) }, { F (F_SUB4) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_lbu ATTRIBUTE_UNUSED = { + 16, 16, 0xf00f, { { F (F_MAJOR) }, { F (F_RN) }, { F (F_RM) }, { F (F_SUB4) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_lhu ATTRIBUTE_UNUSED = { + 16, 16, 0xf00f, { { F (F_MAJOR) }, { F (F_RN) }, { F (F_RM) }, { F (F_SUB4) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_sw_sp ATTRIBUTE_UNUSED = { + 16, 16, 0xf083, { { F (F_MAJOR) }, { F (F_RN) }, { F (F_8) }, { F (F_7U9A4) }, { F (F_SUB2) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_sb_tp ATTRIBUTE_UNUSED = { + 16, 16, 0xf880, { { F (F_MAJOR) }, { F (F_4) }, { F (F_RN3) }, { F (F_8) }, { F (F_7U9) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_sh_tp ATTRIBUTE_UNUSED = { + 16, 16, 0xf881, { { F (F_MAJOR) }, { F (F_4) }, { F (F_RN3) }, { F (F_8) }, { F (F_7U9A2) }, { F (F_15) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_sw_tp ATTRIBUTE_UNUSED = { + 16, 16, 0xf883, { { F (F_MAJOR) }, { F (F_4) }, { F (F_RN3) }, { F (F_8) }, { F (F_7U9A4) }, { F (F_SUB2) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_lbu_tp ATTRIBUTE_UNUSED = { + 16, 16, 0xf880, { { F (F_MAJOR) }, { F (F_4) }, { F (F_RN3) }, { F (F_8) }, { F (F_7U9) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_lhu_tp ATTRIBUTE_UNUSED = { + 16, 16, 0xf881, { { F (F_MAJOR) }, { F (F_4) }, { F (F_RN3) }, { F (F_8) }, { F (F_7U9A2) }, { F (F_15) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_sb16 ATTRIBUTE_UNUSED = { + 32, 32, 0xf00f0000, { { F (F_MAJOR) }, { F (F_RN) }, { F (F_RM) }, { F (F_SUB4) }, { F (F_16S16) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_sh16 ATTRIBUTE_UNUSED = { + 32, 32, 0xf00f0000, { { F (F_MAJOR) }, { F (F_RN) }, { F (F_RM) }, { F (F_SUB4) }, { F (F_16S16) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_sw16 ATTRIBUTE_UNUSED = { + 32, 32, 0xf00f0000, { { F (F_MAJOR) }, { F (F_RN) }, { F (F_RM) }, { F (F_SUB4) }, { F (F_16S16) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_lbu16 ATTRIBUTE_UNUSED = { + 32, 32, 0xf00f0000, { { F (F_MAJOR) }, { F (F_RN) }, { F (F_RM) }, { F (F_SUB4) }, { F (F_16S16) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_lhu16 ATTRIBUTE_UNUSED = { + 32, 32, 0xf00f0000, { { F (F_MAJOR) }, { F (F_RN) }, { F (F_RM) }, { F (F_SUB4) }, { F (F_16S16) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_sw24 ATTRIBUTE_UNUSED = { + 32, 32, 0xf0030000, { { F (F_MAJOR) }, { F (F_RN) }, { F (F_24U8A4N) }, { F (F_SUB2) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_extb ATTRIBUTE_UNUSED = { + 16, 16, 0xf0ff, { { F (F_MAJOR) }, { F (F_RN) }, { F (F_RM) }, { F (F_SUB4) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_ssarb ATTRIBUTE_UNUSED = { + 16, 16, 0xfc0f, { { F (F_MAJOR) }, { F (F_4) }, { F (F_5) }, { F (F_2U6) }, { F (F_RM) }, { F (F_SUB4) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_mov ATTRIBUTE_UNUSED = { + 16, 16, 0xf00f, { { F (F_MAJOR) }, { F (F_RN) }, { F (F_RM) }, { F (F_SUB4) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_movi8 ATTRIBUTE_UNUSED = { + 16, 16, 0xf000, { { F (F_MAJOR) }, { F (F_RN) }, { F (F_8S8) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_movi16 ATTRIBUTE_UNUSED = { + 32, 32, 0xf0ff0000, { { F (F_MAJOR) }, { F (F_RN) }, { F (F_RM) }, { F (F_SUB4) }, { F (F_16S16) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_movu24 ATTRIBUTE_UNUSED = { + 32, 32, 0xf8000000, { { F (F_MAJOR) }, { F (F_4) }, { F (F_RN3) }, { F (F_24U8N) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_movu16 ATTRIBUTE_UNUSED = { + 32, 32, 0xf0ff0000, { { F (F_MAJOR) }, { F (F_RN) }, { F (F_RM) }, { F (F_SUB4) }, { F (F_16U16) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_add3 ATTRIBUTE_UNUSED = { + 16, 16, 0xf000, { { F (F_MAJOR) }, { F (F_RN) }, { F (F_RM) }, { F (F_RL) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_add ATTRIBUTE_UNUSED = { + 16, 16, 0xf003, { { F (F_MAJOR) }, { F (F_RN) }, { F (F_6S8) }, { F (F_SUB2) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_add3i ATTRIBUTE_UNUSED = { + 16, 16, 0xf083, { { F (F_MAJOR) }, { F (F_RN) }, { F (F_8) }, { F (F_7U9A4) }, { F (F_SUB2) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_slt3i ATTRIBUTE_UNUSED = { + 16, 16, 0xf007, { { F (F_MAJOR) }, { F (F_RN) }, { F (F_5U8) }, { F (F_SUB3) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_add3x ATTRIBUTE_UNUSED = { + 32, 32, 0xf00f0000, { { F (F_MAJOR) }, { F (F_RN) }, { F (F_RM) }, { F (F_SUB4) }, { F (F_16S16) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_sltu3x ATTRIBUTE_UNUSED = { + 32, 32, 0xf00f0000, { { F (F_MAJOR) }, { F (F_RN) }, { F (F_RM) }, { F (F_SUB4) }, { F (F_16U16) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_bra ATTRIBUTE_UNUSED = { + 16, 16, 0xf001, { { F (F_MAJOR) }, { F (F_12S4A2) }, { F (F_15) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_beqz ATTRIBUTE_UNUSED = { + 16, 16, 0xf001, { { F (F_MAJOR) }, { F (F_RN) }, { F (F_8S8A2) }, { F (F_15) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_beqi ATTRIBUTE_UNUSED = { + 32, 32, 0xf00f0000, { { F (F_MAJOR) }, { F (F_RN) }, { F (F_4U8) }, { F (F_SUB4) }, { F (F_17S16A2) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_beq ATTRIBUTE_UNUSED = { + 32, 32, 0xf00f0000, { { F (F_MAJOR) }, { F (F_RN) }, { F (F_RM) }, { F (F_SUB4) }, { F (F_17S16A2) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_bsr24 ATTRIBUTE_UNUSED = { + 32, 32, 0xf80f0000, { { F (F_MAJOR) }, { F (F_4) }, { F (F_24S5A2N) }, { F (F_SUB4) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_jmp ATTRIBUTE_UNUSED = { + 16, 16, 0xff0f, { { F (F_MAJOR) }, { F (F_RN) }, { F (F_RM) }, { F (F_SUB4) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_jmp24 ATTRIBUTE_UNUSED = { + 32, 32, 0xf80f0000, { { F (F_MAJOR) }, { F (F_4) }, { F (F_24U5A2N) }, { F (F_SUB4) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_ret ATTRIBUTE_UNUSED = { + 16, 16, 0xffff, { { F (F_MAJOR) }, { F (F_RN) }, { F (F_RM) }, { F (F_SUB4) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_repeat ATTRIBUTE_UNUSED = { + 32, 32, 0xf0ff0000, { { F (F_MAJOR) }, { F (F_RN) }, { F (F_RM) }, { F (F_SUB4) }, { F (F_17S16A2) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_erepeat ATTRIBUTE_UNUSED = { + 32, 32, 0xffff0000, { { F (F_MAJOR) }, { F (F_RN) }, { F (F_RM) }, { F (F_SUB4) }, { F (F_17S16A2) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_stc_lp ATTRIBUTE_UNUSED = { + 16, 16, 0xf0ff, { { F (F_MAJOR) }, { F (F_RN) }, { F (F_CSRN_LO) }, { F (F_12) }, { F (F_13) }, { F (F_14) }, { F (F_CSRN_HI) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_stc ATTRIBUTE_UNUSED = { + 16, 16, 0xf00e, { { F (F_MAJOR) }, { F (F_RN) }, { F (F_CSRN) }, { F (F_12) }, { F (F_13) }, { F (F_14) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_swi ATTRIBUTE_UNUSED = { + 16, 16, 0xffcf, { { F (F_MAJOR) }, { F (F_RN) }, { F (F_8) }, { F (F_9) }, { F (F_2U10) }, { F (F_SUB4) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_bsetm ATTRIBUTE_UNUSED = { + 16, 16, 0xf80f, { { F (F_MAJOR) }, { F (F_4) }, { F (F_3U5) }, { F (F_RM) }, { F (F_SUB4) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_tas ATTRIBUTE_UNUSED = { + 16, 16, 0xf00f, { { F (F_MAJOR) }, { F (F_RN) }, { F (F_RM) }, { F (F_SUB4) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_cache ATTRIBUTE_UNUSED = { + 16, 16, 0xf00f, { { F (F_MAJOR) }, { F (F_RN) }, { F (F_RM) }, { F (F_SUB4) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_madd ATTRIBUTE_UNUSED = { + 32, 32, 0xf00fffff, { { F (F_MAJOR) }, { F (F_RN) }, { F (F_RM) }, { F (F_SUB4) }, { F (F_16U16) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_clip ATTRIBUTE_UNUSED = { + 32, 32, 0xf0ffff07, { { F (F_MAJOR) }, { F (F_RN) }, { F (F_RM) }, { F (F_SUB4) }, { F (F_EXT) }, { F (F_5U24) }, { F (F_29) }, { F (F_30) }, { F (F_31) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_swcp ATTRIBUTE_UNUSED = { + 16, 16, 0xf00f, { { F (F_MAJOR) }, { F (F_CRN) }, { F (F_RM) }, { F (F_SUB4) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_smcp ATTRIBUTE_UNUSED = { + 16, 16, 0xf00f, { { F (F_MAJOR) }, { F (F_CRN) }, { F (F_RM) }, { F (F_SUB4) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_swcp16 ATTRIBUTE_UNUSED = { + 32, 32, 0xf00f0000, { { F (F_MAJOR) }, { F (F_CRN) }, { F (F_RM) }, { F (F_SUB4) }, { F (F_16S16) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_smcp16 ATTRIBUTE_UNUSED = { + 32, 32, 0xf00f0000, { { F (F_MAJOR) }, { F (F_CRN) }, { F (F_RM) }, { F (F_SUB4) }, { F (F_16S16) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_sbcpa ATTRIBUTE_UNUSED = { + 32, 32, 0xf00fff00, { { F (F_MAJOR) }, { F (F_CRN) }, { F (F_RM) }, { F (F_SUB4) }, { F (F_EXT) }, { F (F_8S24) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_shcpa ATTRIBUTE_UNUSED = { + 32, 32, 0xf00fff01, { { F (F_MAJOR) }, { F (F_CRN) }, { F (F_RM) }, { F (F_SUB4) }, { F (F_EXT) }, { F (F_8S24A2) }, { F (F_31) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_swcpa ATTRIBUTE_UNUSED = { + 32, 32, 0xf00fff03, { { F (F_MAJOR) }, { F (F_CRN) }, { F (F_RM) }, { F (F_SUB4) }, { F (F_EXT) }, { F (F_8S24A4) }, { F (F_30) }, { F (F_31) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_smcpa ATTRIBUTE_UNUSED = { + 32, 32, 0xf00fff07, { { F (F_MAJOR) }, { F (F_CRN) }, { F (F_RM) }, { F (F_SUB4) }, { F (F_EXT) }, { F (F_8S24A8) }, { F (F_29) }, { F (F_30) }, { F (F_31) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_bcpeq ATTRIBUTE_UNUSED = { + 32, 32, 0xff0f0000, { { F (F_MAJOR) }, { F (F_RN) }, { F (F_RM) }, { F (F_SUB4) }, { F (F_17S16A2) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_sim_syscall ATTRIBUTE_UNUSED = { + 16, 16, 0xf8ef, { { F (F_MAJOR) }, { F (F_4) }, { F (F_CALLNUM) }, { F (F_8) }, { F (F_9) }, { F (F_10) }, { F (F_SUB4) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_fadds ATTRIBUTE_UNUSED = { + 32, 32, 0xf0fff001, { { F (F_FMAX_0_4) }, { F (F_FMAX_FRD) }, { F (F_FMAX_8_4) }, { F (F_FMAX_12_4) }, { F (F_FMAX_16_4) }, { F (F_FMAX_FRN) }, { F (F_FMAX_FRM) }, { F (F_FMAX_31_1) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_fsqrts ATTRIBUTE_UNUSED = { + 32, 32, 0xf0fff0f3, { { F (F_FMAX_0_4) }, { F (F_FMAX_FRD) }, { F (F_FMAX_8_4) }, { F (F_FMAX_12_4) }, { F (F_FMAX_16_4) }, { F (F_FMAX_FRN) }, { F (F_FMAX_24_4) }, { F (F_FMAX_30_1) }, { F (F_FMAX_31_1) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_froundws ATTRIBUTE_UNUSED = { + 32, 32, 0xf0fff0f3, { { F (F_FMAX_0_4) }, { F (F_FMAX_FRD) }, { F (F_FMAX_8_4) }, { F (F_FMAX_12_4) }, { F (F_FMAX_16_4) }, { F (F_FMAX_FRN) }, { F (F_FMAX_24_4) }, { F (F_FMAX_30_1) }, { F (F_FMAX_31_1) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_fcvtsw ATTRIBUTE_UNUSED = { + 32, 32, 0xf0fff0f3, { { F (F_FMAX_0_4) }, { F (F_FMAX_FRD) }, { F (F_FMAX_8_4) }, { F (F_FMAX_12_4) }, { F (F_FMAX_16_4) }, { F (F_FMAX_FRN) }, { F (F_FMAX_24_4) }, { F (F_FMAX_30_1) }, { F (F_FMAX_31_1) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_fcmpfs ATTRIBUTE_UNUSED = { + 32, 32, 0xfffff009, { { F (F_FMAX_0_4) }, { F (F_FMAX_4_4) }, { F (F_FMAX_8_4) }, { F (F_FMAX_12_4) }, { F (F_FMAX_16_4) }, { F (F_FMAX_FRN) }, { F (F_FMAX_FRM) }, { F (F_FMAX_28_1) }, { F (F_FMAX_31_1) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_cmov_frn_rm ATTRIBUTE_UNUSED = { + 32, 32, 0xf00ffff7, { { F (F_FMAX_0_4) }, { F (F_FMAX_FRD) }, { F (F_FMAX_RM) }, { F (F_FMAX_12_4) }, { F (F_FMAX_16_4) }, { F (F_FMAX_20_4) }, { F (F_FMAX_24_4) }, { F (F_FMAX_29_1) }, { F (F_FMAX_30_1) }, { F (F_FMAX_31_1) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_cmovc_ccrn_rm ATTRIBUTE_UNUSED = { + 32, 32, 0xf00fffff, { { F (F_FMAX_0_4) }, { F (F_FMAX_4_4) }, { F (F_FMAX_RM) }, { F (F_FMAX_12_4) }, { F (F_FMAX_16_4) }, { F (F_FMAX_20_4) }, { F (F_FMAX_24_4) }, { F (F_FMAX_28_1) }, { F (F_FMAX_29_1) }, { F (F_FMAX_30_1) }, { F (F_FMAX_31_1) }, { 0 } } +}; + +#undef F + +#if defined (__STDC__) || defined (ALMOST_STDC) || defined (HAVE_STRINGIZE) +#define A(a) (1 << CGEN_INSN_##a) +#else +#define A(a) (1 << CGEN_INSN_/**/a) +#endif +#if defined (__STDC__) || defined (ALMOST_STDC) || defined (HAVE_STRINGIZE) +#define OPERAND(op) MEP_OPERAND_##op +#else +#define OPERAND(op) MEP_OPERAND_/**/op +#endif +#define MNEM CGEN_SYNTAX_MNEMONIC /* syntax value for mnemonic */ +#define OP(field) CGEN_SYNTAX_MAKE_FIELD (OPERAND (field)) + +/* The instruction table. */ + +static const CGEN_OPCODE mep_cgen_insn_opcode_table[MAX_INSNS] = +{ + /* Special null first entry. + A `num' value of zero is thus invalid. + Also, the special `invalid' insn resides here. */ + { { 0, 0, 0, 0 }, {{0}}, 0, {0}}, +/* sb $rnc,($rma) */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (RNC), ',', '(', OP (RMA), ')', 0 } }, + & ifmt_sb, { 0x8 } + }, +/* sh $rns,($rma) */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (RNS), ',', '(', OP (RMA), ')', 0 } }, + & ifmt_sh, { 0x9 } + }, +/* sw $rnl,($rma) */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (RNL), ',', '(', OP (RMA), ')', 0 } }, + & ifmt_sw, { 0xa } + }, +/* lb $rnc,($rma) */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (RNC), ',', '(', OP (RMA), ')', 0 } }, + & ifmt_sb, { 0xc } + }, +/* lh $rns,($rma) */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (RNS), ',', '(', OP (RMA), ')', 0 } }, + & ifmt_sh, { 0xd } + }, +/* lw $rnl,($rma) */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (RNL), ',', '(', OP (RMA), ')', 0 } }, + & ifmt_sw, { 0xe } + }, +/* lbu $rnuc,($rma) */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (RNUC), ',', '(', OP (RMA), ')', 0 } }, + & ifmt_lbu, { 0xb } + }, +/* lhu $rnus,($rma) */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (RNUS), ',', '(', OP (RMA), ')', 0 } }, + & ifmt_lhu, { 0xf } + }, +/* sw $rnl,$udisp7a4($spr) */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (RNL), ',', OP (UDISP7A4), '(', OP (SPR), ')', 0 } }, + & ifmt_sw_sp, { 0x4002 } + }, +/* lw $rnl,$udisp7a4($spr) */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (RNL), ',', OP (UDISP7A4), '(', OP (SPR), ')', 0 } }, + & ifmt_sw_sp, { 0x4003 } + }, +/* sb $rn3c,$udisp7($tpr) */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (RN3C), ',', OP (UDISP7), '(', OP (TPR), ')', 0 } }, + & ifmt_sb_tp, { 0x8000 } + }, +/* sh $rn3s,$udisp7a2($tpr) */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (RN3S), ',', OP (UDISP7A2), '(', OP (TPR), ')', 0 } }, + & ifmt_sh_tp, { 0x8080 } + }, +/* sw $rn3l,$udisp7a4($tpr) */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (RN3L), ',', OP (UDISP7A4), '(', OP (TPR), ')', 0 } }, + & ifmt_sw_tp, { 0x4082 } + }, +/* lb $rn3c,$udisp7($tpr) */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (RN3C), ',', OP (UDISP7), '(', OP (TPR), ')', 0 } }, + & ifmt_sb_tp, { 0x8800 } + }, +/* lh $rn3s,$udisp7a2($tpr) */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (RN3S), ',', OP (UDISP7A2), '(', OP (TPR), ')', 0 } }, + & ifmt_sh_tp, { 0x8880 } + }, +/* lw $rn3l,$udisp7a4($tpr) */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (RN3L), ',', OP (UDISP7A4), '(', OP (TPR), ')', 0 } }, + & ifmt_sw_tp, { 0x4083 } + }, +/* lbu $rn3uc,$udisp7($tpr) */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (RN3UC), ',', OP (UDISP7), '(', OP (TPR), ')', 0 } }, + & ifmt_lbu_tp, { 0x4880 } + }, +/* lhu $rn3us,$udisp7a2($tpr) */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (RN3US), ',', OP (UDISP7A2), '(', OP (TPR), ')', 0 } }, + & ifmt_lhu_tp, { 0x8881 } + }, +/* sb $rnc,$sdisp16($rma) */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (RNC), ',', OP (SDISP16), '(', OP (RMA), ')', 0 } }, + & ifmt_sb16, { 0xc0080000 } + }, +/* sh $rns,$sdisp16($rma) */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (RNS), ',', OP (SDISP16), '(', OP (RMA), ')', 0 } }, + & ifmt_sh16, { 0xc0090000 } + }, +/* sw $rnl,$sdisp16($rma) */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (RNL), ',', OP (SDISP16), '(', OP (RMA), ')', 0 } }, + & ifmt_sw16, { 0xc00a0000 } + }, +/* lb $rnc,$sdisp16($rma) */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (RNC), ',', OP (SDISP16), '(', OP (RMA), ')', 0 } }, + & ifmt_sb16, { 0xc00c0000 } + }, +/* lh $rns,$sdisp16($rma) */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (RNS), ',', OP (SDISP16), '(', OP (RMA), ')', 0 } }, + & ifmt_sh16, { 0xc00d0000 } + }, +/* lw $rnl,$sdisp16($rma) */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (RNL), ',', OP (SDISP16), '(', OP (RMA), ')', 0 } }, + & ifmt_sw16, { 0xc00e0000 } + }, +/* lbu $rnuc,$sdisp16($rma) */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (RNUC), ',', OP (SDISP16), '(', OP (RMA), ')', 0 } }, + & ifmt_lbu16, { 0xc00b0000 } + }, +/* lhu $rnus,$sdisp16($rma) */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (RNUS), ',', OP (SDISP16), '(', OP (RMA), ')', 0 } }, + & ifmt_lhu16, { 0xc00f0000 } + }, +/* sw $rnl,($addr24a4) */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (RNL), ',', '(', OP (ADDR24A4), ')', 0 } }, + & ifmt_sw24, { 0xe0020000 } + }, +/* lw $rnl,($addr24a4) */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (RNL), ',', '(', OP (ADDR24A4), ')', 0 } }, + & ifmt_sw24, { 0xe0030000 } + }, +/* extb $rn */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (RN), 0 } }, + & ifmt_extb, { 0x100d } + }, +/* exth $rn */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (RN), 0 } }, + & ifmt_extb, { 0x102d } + }, +/* extub $rn */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (RN), 0 } }, + & ifmt_extb, { 0x108d } + }, +/* extuh $rn */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (RN), 0 } }, + & ifmt_extb, { 0x10ad } + }, +/* ssarb $udisp2($rm) */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (UDISP2), '(', OP (RM), ')', 0 } }, + & ifmt_ssarb, { 0x100c } + }, +/* mov $rn,$rm */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (RN), ',', OP (RM), 0 } }, + & ifmt_mov, { 0x0 } + }, +/* mov $rn,$simm8 */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (RN), ',', OP (SIMM8), 0 } }, + & ifmt_movi8, { 0x5000 } + }, +/* mov $rn,$simm16 */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (RN), ',', OP (SIMM16), 0 } }, + & ifmt_movi16, { 0xc0010000 } + }, +/* movu $rn3,$uimm24 */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (RN3), ',', OP (UIMM24), 0 } }, + & ifmt_movu24, { 0xd0000000 } + }, +/* movu $rn,$uimm16 */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (RN), ',', OP (UIMM16), 0 } }, + & ifmt_movu16, { 0xc0110000 } + }, +/* movh $rn,$uimm16 */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (RN), ',', OP (UIMM16), 0 } }, + & ifmt_movu16, { 0xc0210000 } + }, +/* add3 $rl,$rn,$rm */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (RL), ',', OP (RN), ',', OP (RM), 0 } }, + & ifmt_add3, { 0x9000 } + }, +/* add $rn,$simm6 */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (RN), ',', OP (SIMM6), 0 } }, + & ifmt_add, { 0x6000 } + }, +/* add3 $rn,$spr,$uimm7a4 */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (RN), ',', OP (SPR), ',', OP (UIMM7A4), 0 } }, + & ifmt_add3i, { 0x4000 } + }, +/* advck3 \$0,$rn,$rm */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', '$', '0', ',', OP (RN), ',', OP (RM), 0 } }, + & ifmt_mov, { 0x7 } + }, +/* sub $rn,$rm */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (RN), ',', OP (RM), 0 } }, + & ifmt_mov, { 0x4 } + }, +/* sbvck3 \$0,$rn,$rm */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', '$', '0', ',', OP (RN), ',', OP (RM), 0 } }, + & ifmt_mov, { 0x5 } + }, +/* neg $rn,$rm */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (RN), ',', OP (RM), 0 } }, + & ifmt_mov, { 0x1 } + }, +/* slt3 \$0,$rn,$rm */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', '$', '0', ',', OP (RN), ',', OP (RM), 0 } }, + & ifmt_mov, { 0x2 } + }, +/* sltu3 \$0,$rn,$rm */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', '$', '0', ',', OP (RN), ',', OP (RM), 0 } }, + & ifmt_mov, { 0x3 } + }, +/* slt3 \$0,$rn,$uimm5 */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', '$', '0', ',', OP (RN), ',', OP (UIMM5), 0 } }, + & ifmt_slt3i, { 0x6001 } + }, +/* sltu3 \$0,$rn,$uimm5 */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', '$', '0', ',', OP (RN), ',', OP (UIMM5), 0 } }, + & ifmt_slt3i, { 0x6005 } + }, +/* sl1ad3 \$0,$rn,$rm */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', '$', '0', ',', OP (RN), ',', OP (RM), 0 } }, + & ifmt_mov, { 0x2006 } + }, +/* sl2ad3 \$0,$rn,$rm */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', '$', '0', ',', OP (RN), ',', OP (RM), 0 } }, + & ifmt_mov, { 0x2007 } + }, +/* add3 $rn,$rm,$simm16 */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (RN), ',', OP (RM), ',', OP (SIMM16), 0 } }, + & ifmt_add3x, { 0xc0000000 } + }, +/* slt3 $rn,$rm,$simm16 */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (RN), ',', OP (RM), ',', OP (SIMM16), 0 } }, + & ifmt_add3x, { 0xc0020000 } + }, +/* sltu3 $rn,$rm,$uimm16 */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (RN), ',', OP (RM), ',', OP (UIMM16), 0 } }, + & ifmt_sltu3x, { 0xc0030000 } + }, +/* or $rn,$rm */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (RN), ',', OP (RM), 0 } }, + & ifmt_mov, { 0x1000 } + }, +/* and $rn,$rm */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (RN), ',', OP (RM), 0 } }, + & ifmt_mov, { 0x1001 } + }, +/* xor $rn,$rm */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (RN), ',', OP (RM), 0 } }, + & ifmt_mov, { 0x1002 } + }, +/* nor $rn,$rm */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (RN), ',', OP (RM), 0 } }, + & ifmt_mov, { 0x1003 } + }, +/* or3 $rn,$rm,$uimm16 */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (RN), ',', OP (RM), ',', OP (UIMM16), 0 } }, + & ifmt_sltu3x, { 0xc0040000 } + }, +/* and3 $rn,$rm,$uimm16 */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (RN), ',', OP (RM), ',', OP (UIMM16), 0 } }, + & ifmt_sltu3x, { 0xc0050000 } + }, +/* xor3 $rn,$rm,$uimm16 */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (RN), ',', OP (RM), ',', OP (UIMM16), 0 } }, + & ifmt_sltu3x, { 0xc0060000 } + }, +/* sra $rn,$rm */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (RN), ',', OP (RM), 0 } }, + & ifmt_mov, { 0x200d } + }, +/* srl $rn,$rm */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (RN), ',', OP (RM), 0 } }, + & ifmt_mov, { 0x200c } + }, +/* sll $rn,$rm */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (RN), ',', OP (RM), 0 } }, + & ifmt_mov, { 0x200e } + }, +/* sra $rn,$uimm5 */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (RN), ',', OP (UIMM5), 0 } }, + & ifmt_slt3i, { 0x6003 } + }, +/* srl $rn,$uimm5 */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (RN), ',', OP (UIMM5), 0 } }, + & ifmt_slt3i, { 0x6002 } + }, +/* sll $rn,$uimm5 */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (RN), ',', OP (UIMM5), 0 } }, + & ifmt_slt3i, { 0x6006 } + }, +/* sll3 \$0,$rn,$uimm5 */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', '$', '0', ',', OP (RN), ',', OP (UIMM5), 0 } }, + & ifmt_slt3i, { 0x6007 } + }, +/* fsft $rn,$rm */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (RN), ',', OP (RM), 0 } }, + & ifmt_mov, { 0x200f } + }, +/* bra $pcrel12a2 */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (PCREL12A2), 0 } }, + & ifmt_bra, { 0xb000 } + }, +/* beqz $rn,$pcrel8a2 */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (RN), ',', OP (PCREL8A2), 0 } }, + & ifmt_beqz, { 0xa000 } + }, +/* bnez $rn,$pcrel8a2 */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (RN), ',', OP (PCREL8A2), 0 } }, + & ifmt_beqz, { 0xa001 } + }, +/* beqi $rn,$uimm4,$pcrel17a2 */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (RN), ',', OP (UIMM4), ',', OP (PCREL17A2), 0 } }, + & ifmt_beqi, { 0xe0000000 } + }, +/* bnei $rn,$uimm4,$pcrel17a2 */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (RN), ',', OP (UIMM4), ',', OP (PCREL17A2), 0 } }, + & ifmt_beqi, { 0xe0040000 } + }, +/* blti $rn,$uimm4,$pcrel17a2 */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (RN), ',', OP (UIMM4), ',', OP (PCREL17A2), 0 } }, + & ifmt_beqi, { 0xe00c0000 } + }, +/* bgei $rn,$uimm4,$pcrel17a2 */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (RN), ',', OP (UIMM4), ',', OP (PCREL17A2), 0 } }, + & ifmt_beqi, { 0xe0080000 } + }, +/* beq $rn,$rm,$pcrel17a2 */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (RN), ',', OP (RM), ',', OP (PCREL17A2), 0 } }, + & ifmt_beq, { 0xe0010000 } + }, +/* bne $rn,$rm,$pcrel17a2 */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (RN), ',', OP (RM), ',', OP (PCREL17A2), 0 } }, + & ifmt_beq, { 0xe0050000 } + }, +/* bsr $pcrel12a2 */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (PCREL12A2), 0 } }, + & ifmt_bra, { 0xb001 } + }, +/* bsr $pcrel24a2 */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (PCREL24A2), 0 } }, + & ifmt_bsr24, { 0xd8090000 } + }, +/* jmp $rm */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (RM), 0 } }, + & ifmt_jmp, { 0x100e } + }, +/* jmp $pcabs24a2 */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (PCABS24A2), 0 } }, + & ifmt_jmp24, { 0xd8080000 } + }, +/* jsr $rm */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (RM), 0 } }, + & ifmt_jmp, { 0x100f } + }, +/* ret */ + { + { 0, 0, 0, 0 }, + { { MNEM, 0 } }, + & ifmt_ret, { 0x7002 } + }, +/* repeat $rn,$pcrel17a2 */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (RN), ',', OP (PCREL17A2), 0 } }, + & ifmt_repeat, { 0xe0090000 } + }, +/* erepeat $pcrel17a2 */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (PCREL17A2), 0 } }, + & ifmt_erepeat, { 0xe0190000 } + }, +/* stc $rn,\$lp */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (RN), ',', '$', 'l', 'p', 0 } }, + & ifmt_stc_lp, { 0x7018 } + }, +/* stc $rn,\$hi */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (RN), ',', '$', 'h', 'i', 0 } }, + & ifmt_stc_lp, { 0x7078 } + }, +/* stc $rn,\$lo */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (RN), ',', '$', 'l', 'o', 0 } }, + & ifmt_stc_lp, { 0x7088 } + }, +/* stc $rn,$csrn */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (RN), ',', OP (CSRN), 0 } }, + & ifmt_stc, { 0x7008 } + }, +/* ldc $rn,\$lp */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (RN), ',', '$', 'l', 'p', 0 } }, + & ifmt_stc_lp, { 0x701a } + }, +/* ldc $rn,\$hi */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (RN), ',', '$', 'h', 'i', 0 } }, + & ifmt_stc_lp, { 0x707a } + }, +/* ldc $rn,\$lo */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (RN), ',', '$', 'l', 'o', 0 } }, + & ifmt_stc_lp, { 0x708a } + }, +/* ldc $rn,$csrn */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (RN), ',', OP (CSRN), 0 } }, + & ifmt_stc, { 0x700a } + }, +/* di */ + { + { 0, 0, 0, 0 }, + { { MNEM, 0 } }, + & ifmt_ret, { 0x7000 } + }, +/* ei */ + { + { 0, 0, 0, 0 }, + { { MNEM, 0 } }, + & ifmt_ret, { 0x7010 } + }, +/* reti */ + { + { 0, 0, 0, 0 }, + { { MNEM, 0 } }, + & ifmt_ret, { 0x7012 } + }, +/* halt */ + { + { 0, 0, 0, 0 }, + { { MNEM, 0 } }, + & ifmt_ret, { 0x7022 } + }, +/* sleep */ + { + { 0, 0, 0, 0 }, + { { MNEM, 0 } }, + & ifmt_ret, { 0x7062 } + }, +/* swi $uimm2 */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (UIMM2), 0 } }, + & ifmt_swi, { 0x7006 } + }, +/* break */ + { + { 0, 0, 0, 0 }, + { { MNEM, 0 } }, + & ifmt_ret, { 0x7032 } + }, +/* syncm */ + { + { 0, 0, 0, 0 }, + { { MNEM, 0 } }, + & ifmt_ret, { 0x7011 } + }, +/* stcb $rn,$uimm16 */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (RN), ',', OP (UIMM16), 0 } }, + & ifmt_movu16, { 0xf0040000 } + }, +/* ldcb $rn,$uimm16 */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (RN), ',', OP (UIMM16), 0 } }, + & ifmt_movu16, { 0xf0140000 } + }, +/* bsetm ($rma),$uimm3 */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', '(', OP (RMA), ')', ',', OP (UIMM3), 0 } }, + & ifmt_bsetm, { 0x2000 } + }, +/* bclrm ($rma),$uimm3 */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', '(', OP (RMA), ')', ',', OP (UIMM3), 0 } }, + & ifmt_bsetm, { 0x2001 } + }, +/* bnotm ($rma),$uimm3 */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', '(', OP (RMA), ')', ',', OP (UIMM3), 0 } }, + & ifmt_bsetm, { 0x2002 } + }, +/* btstm \$0,($rma),$uimm3 */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', '$', '0', ',', '(', OP (RMA), ')', ',', OP (UIMM3), 0 } }, + & ifmt_bsetm, { 0x2003 } + }, +/* tas $rn,($rma) */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (RN), ',', '(', OP (RMA), ')', 0 } }, + & ifmt_tas, { 0x2004 } + }, +/* cache $cimm4,($rma) */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (CIMM4), ',', '(', OP (RMA), ')', 0 } }, + & ifmt_cache, { 0x7004 } + }, +/* mul $rn,$rm */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (RN), ',', OP (RM), 0 } }, + & ifmt_mov, { 0x1004 } + }, +/* mulu $rn,$rm */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (RN), ',', OP (RM), 0 } }, + & ifmt_mov, { 0x1005 } + }, +/* mulr $rn,$rm */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (RN), ',', OP (RM), 0 } }, + & ifmt_mov, { 0x1006 } + }, +/* mulru $rn,$rm */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (RN), ',', OP (RM), 0 } }, + & ifmt_mov, { 0x1007 } + }, +/* madd $rn,$rm */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (RN), ',', OP (RM), 0 } }, + & ifmt_madd, { 0xf0013004 } + }, +/* maddu $rn,$rm */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (RN), ',', OP (RM), 0 } }, + & ifmt_madd, { 0xf0013005 } + }, +/* maddr $rn,$rm */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (RN), ',', OP (RM), 0 } }, + & ifmt_madd, { 0xf0013006 } + }, +/* maddru $rn,$rm */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (RN), ',', OP (RM), 0 } }, + & ifmt_madd, { 0xf0013007 } + }, +/* div $rn,$rm */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (RN), ',', OP (RM), 0 } }, + & ifmt_mov, { 0x1008 } + }, +/* divu $rn,$rm */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (RN), ',', OP (RM), 0 } }, + & ifmt_mov, { 0x1009 } + }, +/* dret */ + { + { 0, 0, 0, 0 }, + { { MNEM, 0 } }, + & ifmt_ret, { 0x7013 } + }, +/* dbreak */ + { + { 0, 0, 0, 0 }, + { { MNEM, 0 } }, + & ifmt_ret, { 0x7033 } + }, +/* ldz $rn,$rm */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (RN), ',', OP (RM), 0 } }, + & ifmt_madd, { 0xf0010000 } + }, +/* abs $rn,$rm */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (RN), ',', OP (RM), 0 } }, + & ifmt_madd, { 0xf0010003 } + }, +/* ave $rn,$rm */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (RN), ',', OP (RM), 0 } }, + & ifmt_madd, { 0xf0010002 } + }, +/* min $rn,$rm */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (RN), ',', OP (RM), 0 } }, + & ifmt_madd, { 0xf0010004 } + }, +/* max $rn,$rm */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (RN), ',', OP (RM), 0 } }, + & ifmt_madd, { 0xf0010005 } + }, +/* minu $rn,$rm */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (RN), ',', OP (RM), 0 } }, + & ifmt_madd, { 0xf0010006 } + }, +/* maxu $rn,$rm */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (RN), ',', OP (RM), 0 } }, + & ifmt_madd, { 0xf0010007 } + }, +/* clip $rn,$cimm5 */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (RN), ',', OP (CIMM5), 0 } }, + & ifmt_clip, { 0xf0011000 } + }, +/* clipu $rn,$cimm5 */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (RN), ',', OP (CIMM5), 0 } }, + & ifmt_clip, { 0xf0011001 } + }, +/* sadd $rn,$rm */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (RN), ',', OP (RM), 0 } }, + & ifmt_madd, { 0xf0010008 } + }, +/* ssub $rn,$rm */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (RN), ',', OP (RM), 0 } }, + & ifmt_madd, { 0xf001000a } + }, +/* saddu $rn,$rm */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (RN), ',', OP (RM), 0 } }, + & ifmt_madd, { 0xf0010009 } + }, +/* ssubu $rn,$rm */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (RN), ',', OP (RM), 0 } }, + & ifmt_madd, { 0xf001000b } + }, +/* swcp $crn,($rma) */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (CRN), ',', '(', OP (RMA), ')', 0 } }, + & ifmt_swcp, { 0x3008 } + }, +/* lwcp $crn,($rma) */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (CRN), ',', '(', OP (RMA), ')', 0 } }, + & ifmt_swcp, { 0x3009 } + }, +/* smcp $crn64,($rma) */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (CRN64), ',', '(', OP (RMA), ')', 0 } }, + & ifmt_smcp, { 0x300a } + }, +/* lmcp $crn64,($rma) */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (CRN64), ',', '(', OP (RMA), ')', 0 } }, + & ifmt_smcp, { 0x300b } + }, +/* swcpi $crn,($rma+) */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (CRN), ',', '(', OP (RMA), '+', ')', 0 } }, + & ifmt_swcp, { 0x3000 } + }, +/* lwcpi $crn,($rma+) */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (CRN), ',', '(', OP (RMA), '+', ')', 0 } }, + & ifmt_swcp, { 0x3001 } + }, +/* smcpi $crn64,($rma+) */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (CRN64), ',', '(', OP (RMA), '+', ')', 0 } }, + & ifmt_smcp, { 0x3002 } + }, +/* lmcpi $crn64,($rma+) */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (CRN64), ',', '(', OP (RMA), '+', ')', 0 } }, + & ifmt_smcp, { 0x3003 } + }, +/* swcp $crn,$sdisp16($rma) */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (CRN), ',', OP (SDISP16), '(', OP (RMA), ')', 0 } }, + & ifmt_swcp16, { 0xf00c0000 } + }, +/* lwcp $crn,$sdisp16($rma) */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (CRN), ',', OP (SDISP16), '(', OP (RMA), ')', 0 } }, + & ifmt_swcp16, { 0xf00d0000 } + }, +/* smcp $crn64,$sdisp16($rma) */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (CRN64), ',', OP (SDISP16), '(', OP (RMA), ')', 0 } }, + & ifmt_smcp16, { 0xf00e0000 } + }, +/* lmcp $crn64,$sdisp16($rma) */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (CRN64), ',', OP (SDISP16), '(', OP (RMA), ')', 0 } }, + & ifmt_smcp16, { 0xf00f0000 } + }, +/* sbcpa $crn,($rma+),$cdisp8 */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (CRN), ',', '(', OP (RMA), '+', ')', ',', OP (CDISP8), 0 } }, + & ifmt_sbcpa, { 0xf0050000 } + }, +/* lbcpa $crn,($rma+),$cdisp8 */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (CRN), ',', '(', OP (RMA), '+', ')', ',', OP (CDISP8), 0 } }, + & ifmt_sbcpa, { 0xf0054000 } + }, +/* shcpa $crn,($rma+),$cdisp8a2 */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (CRN), ',', '(', OP (RMA), '+', ')', ',', OP (CDISP8A2), 0 } }, + & ifmt_shcpa, { 0xf0051000 } + }, +/* lhcpa $crn,($rma+),$cdisp8a2 */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (CRN), ',', '(', OP (RMA), '+', ')', ',', OP (CDISP8A2), 0 } }, + & ifmt_shcpa, { 0xf0055000 } + }, +/* swcpa $crn,($rma+),$cdisp8a4 */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (CRN), ',', '(', OP (RMA), '+', ')', ',', OP (CDISP8A4), 0 } }, + & ifmt_swcpa, { 0xf0052000 } + }, +/* lwcpa $crn,($rma+),$cdisp8a4 */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (CRN), ',', '(', OP (RMA), '+', ')', ',', OP (CDISP8A4), 0 } }, + & ifmt_swcpa, { 0xf0056000 } + }, +/* smcpa $crn64,($rma+),$cdisp8a8 */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (CRN64), ',', '(', OP (RMA), '+', ')', ',', OP (CDISP8A8), 0 } }, + & ifmt_smcpa, { 0xf0053000 } + }, +/* lmcpa $crn64,($rma+),$cdisp8a8 */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (CRN64), ',', '(', OP (RMA), '+', ')', ',', OP (CDISP8A8), 0 } }, + & ifmt_smcpa, { 0xf0057000 } + }, +/* sbcpm0 $crn,($rma+),$cdisp8 */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (CRN), ',', '(', OP (RMA), '+', ')', ',', OP (CDISP8), 0 } }, + & ifmt_sbcpa, { 0xf0050800 } + }, +/* lbcpm0 $crn,($rma+),$cdisp8 */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (CRN), ',', '(', OP (RMA), '+', ')', ',', OP (CDISP8), 0 } }, + & ifmt_sbcpa, { 0xf0054800 } + }, +/* shcpm0 $crn,($rma+),$cdisp8a2 */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (CRN), ',', '(', OP (RMA), '+', ')', ',', OP (CDISP8A2), 0 } }, + & ifmt_shcpa, { 0xf0051800 } + }, +/* lhcpm0 $crn,($rma+),$cdisp8a2 */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (CRN), ',', '(', OP (RMA), '+', ')', ',', OP (CDISP8A2), 0 } }, + & ifmt_shcpa, { 0xf0055800 } + }, +/* swcpm0 $crn,($rma+),$cdisp8a4 */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (CRN), ',', '(', OP (RMA), '+', ')', ',', OP (CDISP8A4), 0 } }, + & ifmt_swcpa, { 0xf0052800 } + }, +/* lwcpm0 $crn,($rma+),$cdisp8a4 */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (CRN), ',', '(', OP (RMA), '+', ')', ',', OP (CDISP8A4), 0 } }, + & ifmt_swcpa, { 0xf0056800 } + }, +/* smcpm0 $crn64,($rma+),$cdisp8a8 */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (CRN64), ',', '(', OP (RMA), '+', ')', ',', OP (CDISP8A8), 0 } }, + & ifmt_smcpa, { 0xf0053800 } + }, +/* lmcpm0 $crn64,($rma+),$cdisp8a8 */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (CRN64), ',', '(', OP (RMA), '+', ')', ',', OP (CDISP8A8), 0 } }, + & ifmt_smcpa, { 0xf0057800 } + }, +/* sbcpm1 $crn,($rma+),$cdisp8 */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (CRN), ',', '(', OP (RMA), '+', ')', ',', OP (CDISP8), 0 } }, + & ifmt_sbcpa, { 0xf0050c00 } + }, +/* lbcpm1 $crn,($rma+),$cdisp8 */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (CRN), ',', '(', OP (RMA), '+', ')', ',', OP (CDISP8), 0 } }, + & ifmt_sbcpa, { 0xf0054c00 } + }, +/* shcpm1 $crn,($rma+),$cdisp8a2 */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (CRN), ',', '(', OP (RMA), '+', ')', ',', OP (CDISP8A2), 0 } }, + & ifmt_shcpa, { 0xf0051c00 } + }, +/* lhcpm1 $crn,($rma+),$cdisp8a2 */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (CRN), ',', '(', OP (RMA), '+', ')', ',', OP (CDISP8A2), 0 } }, + & ifmt_shcpa, { 0xf0055c00 } + }, +/* swcpm1 $crn,($rma+),$cdisp8a4 */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (CRN), ',', '(', OP (RMA), '+', ')', ',', OP (CDISP8A4), 0 } }, + & ifmt_swcpa, { 0xf0052c00 } + }, +/* lwcpm1 $crn,($rma+),$cdisp8a4 */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (CRN), ',', '(', OP (RMA), '+', ')', ',', OP (CDISP8A4), 0 } }, + & ifmt_swcpa, { 0xf0056c00 } + }, +/* smcpm1 $crn64,($rma+),$cdisp8a8 */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (CRN64), ',', '(', OP (RMA), '+', ')', ',', OP (CDISP8A8), 0 } }, + & ifmt_smcpa, { 0xf0053c00 } + }, +/* lmcpm1 $crn64,($rma+),$cdisp8a8 */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (CRN64), ',', '(', OP (RMA), '+', ')', ',', OP (CDISP8A8), 0 } }, + & ifmt_smcpa, { 0xf0057c00 } + }, +/* bcpeq $cccc,$pcrel17a2 */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (CCCC), ',', OP (PCREL17A2), 0 } }, + & ifmt_bcpeq, { 0xd8040000 } + }, +/* bcpne $cccc,$pcrel17a2 */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (CCCC), ',', OP (PCREL17A2), 0 } }, + & ifmt_bcpeq, { 0xd8050000 } + }, +/* bcpat $cccc,$pcrel17a2 */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (CCCC), ',', OP (PCREL17A2), 0 } }, + & ifmt_bcpeq, { 0xd8060000 } + }, +/* bcpaf $cccc,$pcrel17a2 */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (CCCC), ',', OP (PCREL17A2), 0 } }, + & ifmt_bcpeq, { 0xd8070000 } + }, +/* synccp */ + { + { 0, 0, 0, 0 }, + { { MNEM, 0 } }, + & ifmt_ret, { 0x7021 } + }, +/* jsrv $rm */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (RM), 0 } }, + & ifmt_jmp, { 0x180f } + }, +/* bsrv $pcrel24a2 */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (PCREL24A2), 0 } }, + & ifmt_bsr24, { 0xd80b0000 } + }, +/* --unused-- */ + { + { 0, 0, 0, 0 }, + { { MNEM, 0 } }, + & ifmt_sim_syscall, { 0x7800 } + }, +/* --reserved-- */ + { + { 0, 0, 0, 0 }, + { { MNEM, 0 } }, + & ifmt_mov, { 0x6 } + }, +/* --reserved-- */ + { + { 0, 0, 0, 0 }, + { { MNEM, 0 } }, + & ifmt_mov, { 0x100a } + }, +/* --reserved-- */ + { + { 0, 0, 0, 0 }, + { { MNEM, 0 } }, + & ifmt_mov, { 0x100b } + }, +/* --reserved-- */ + { + { 0, 0, 0, 0 }, + { { MNEM, 0 } }, + & ifmt_mov, { 0x2005 } + }, +/* --reserved-- */ + { + { 0, 0, 0, 0 }, + { { MNEM, 0 } }, + & ifmt_mov, { 0x2008 } + }, +/* --reserved-- */ + { + { 0, 0, 0, 0 }, + { { MNEM, 0 } }, + & ifmt_mov, { 0x2009 } + }, +/* --reserved-- */ + { + { 0, 0, 0, 0 }, + { { MNEM, 0 } }, + & ifmt_mov, { 0x200a } + }, +/* --reserved-- */ + { + { 0, 0, 0, 0 }, + { { MNEM, 0 } }, + & ifmt_mov, { 0x200b } + }, +/* --reserved-- */ + { + { 0, 0, 0, 0 }, + { { MNEM, 0 } }, + & ifmt_mov, { 0x3004 } + }, +/* --reserved-- */ + { + { 0, 0, 0, 0 }, + { { MNEM, 0 } }, + & ifmt_mov, { 0x3005 } + }, +/* --reserved-- */ + { + { 0, 0, 0, 0 }, + { { MNEM, 0 } }, + & ifmt_mov, { 0x3006 } + }, +/* --reserved-- */ + { + { 0, 0, 0, 0 }, + { { MNEM, 0 } }, + & ifmt_mov, { 0x3007 } + }, +/* --reserved-- */ + { + { 0, 0, 0, 0 }, + { { MNEM, 0 } }, + & ifmt_mov, { 0x300c } + }, +/* --reserved-- */ + { + { 0, 0, 0, 0 }, + { { MNEM, 0 } }, + & ifmt_mov, { 0x300d } + }, +/* --reserved-- */ + { + { 0, 0, 0, 0 }, + { { MNEM, 0 } }, + & ifmt_mov, { 0x300e } + }, +/* --reserved-- */ + { + { 0, 0, 0, 0 }, + { { MNEM, 0 } }, + & ifmt_mov, { 0x300f } + }, +/* --reserved-- */ + { + { 0, 0, 0, 0 }, + { { MNEM, 0 } }, + & ifmt_mov, { 0x7007 } + }, +/* --reserved-- */ + { + { 0, 0, 0, 0 }, + { { MNEM, 0 } }, + & ifmt_mov, { 0x700e } + }, +/* --reserved-- */ + { + { 0, 0, 0, 0 }, + { { MNEM, 0 } }, + & ifmt_mov, { 0x700f } + }, +/* --reserved-- */ + { + { 0, 0, 0, 0 }, + { { MNEM, 0 } }, + & ifmt_mov, { 0xc007 } + }, +/* --reserved-- */ + { + { 0, 0, 0, 0 }, + { { MNEM, 0 } }, + & ifmt_mov, { 0xe00d } + }, +/* --reserved-- */ + { + { 0, 0, 0, 0 }, + { { MNEM, 0 } }, + & ifmt_mov, { 0xf003 } + }, +/* --reserved-- */ + { + { 0, 0, 0, 0 }, + { { MNEM, 0 } }, + & ifmt_mov, { 0xf006 } + }, +/* --reserved-- */ + { + { 0, 0, 0, 0 }, + { { MNEM, 0 } }, + & ifmt_mov, { 0xf008 } + }, +/* --reserved-- */ + { + { 0, 0, 0, 0 }, + { { MNEM, 0 } }, + & ifmt_mov, { 0x7005 } + }, +/* --reserved-- */ + { + { 0, 0, 0, 0 }, + { { MNEM, 0 } }, + & ifmt_mov, { 0x700c } + }, +/* --reserved-- */ + { + { 0, 0, 0, 0 }, + { { MNEM, 0 } }, + & ifmt_mov, { 0x700d } + }, +/* fadds ${fmax-FRd},${fmax-FRn},${fmax-FRm} */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (FMAX_FRD), ',', OP (FMAX_FRN), ',', OP (FMAX_FRM), 0 } }, + & ifmt_fadds, { 0xf0070000 } + }, +/* fsubs ${fmax-FRd},${fmax-FRn},${fmax-FRm} */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (FMAX_FRD), ',', OP (FMAX_FRN), ',', OP (FMAX_FRM), 0 } }, + & ifmt_fadds, { 0xf0170000 } + }, +/* fmuls ${fmax-FRd},${fmax-FRn},${fmax-FRm} */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (FMAX_FRD), ',', OP (FMAX_FRN), ',', OP (FMAX_FRM), 0 } }, + & ifmt_fadds, { 0xf0270000 } + }, +/* fdivs ${fmax-FRd},${fmax-FRn},${fmax-FRm} */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (FMAX_FRD), ',', OP (FMAX_FRN), ',', OP (FMAX_FRM), 0 } }, + & ifmt_fadds, { 0xf0370000 } + }, +/* fsqrts ${fmax-FRd},${fmax-FRn} */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (FMAX_FRD), ',', OP (FMAX_FRN), 0 } }, + & ifmt_fsqrts, { 0xf0470000 } + }, +/* fabss ${fmax-FRd},${fmax-FRn} */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (FMAX_FRD), ',', OP (FMAX_FRN), 0 } }, + & ifmt_fsqrts, { 0xf0570000 } + }, +/* fnegs ${fmax-FRd},${fmax-FRn} */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (FMAX_FRD), ',', OP (FMAX_FRN), 0 } }, + & ifmt_fsqrts, { 0xf0770000 } + }, +/* fmovs ${fmax-FRd},${fmax-FRn} */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (FMAX_FRD), ',', OP (FMAX_FRN), 0 } }, + & ifmt_fsqrts, { 0xf0670000 } + }, +/* froundws ${fmax-FRd-int},${fmax-FRn} */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (FMAX_FRD_INT), ',', OP (FMAX_FRN), 0 } }, + & ifmt_froundws, { 0xf0c70000 } + }, +/* ftruncws ${fmax-FRd-int},${fmax-FRn} */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (FMAX_FRD_INT), ',', OP (FMAX_FRN), 0 } }, + & ifmt_froundws, { 0xf0d70000 } + }, +/* fceilws ${fmax-FRd-int},${fmax-FRn} */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (FMAX_FRD_INT), ',', OP (FMAX_FRN), 0 } }, + & ifmt_froundws, { 0xf0e70000 } + }, +/* ffloorws ${fmax-FRd-int},${fmax-FRn} */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (FMAX_FRD_INT), ',', OP (FMAX_FRN), 0 } }, + & ifmt_froundws, { 0xf0f70000 } + }, +/* fcvtws ${fmax-FRd-int},${fmax-FRn} */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (FMAX_FRD_INT), ',', OP (FMAX_FRN), 0 } }, + & ifmt_froundws, { 0xf0471000 } + }, +/* fcvtsw ${fmax-FRd},${fmax-FRn-int} */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (FMAX_FRD), ',', OP (FMAX_FRN_INT), 0 } }, + & ifmt_fcvtsw, { 0xf0079000 } + }, +/* fcmpfs ${fmax-FRn},${fmax-FRm} */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (FMAX_FRN), ',', OP (FMAX_FRM), 0 } }, + & ifmt_fcmpfs, { 0xf0072000 } + }, +/* fcmpus ${fmax-FRn},${fmax-FRm} */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (FMAX_FRN), ',', OP (FMAX_FRM), 0 } }, + & ifmt_fcmpfs, { 0xf0172000 } + }, +/* fcmpes ${fmax-FRn},${fmax-FRm} */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (FMAX_FRN), ',', OP (FMAX_FRM), 0 } }, + & ifmt_fcmpfs, { 0xf0272000 } + }, +/* fcmpues ${fmax-FRn},${fmax-FRm} */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (FMAX_FRN), ',', OP (FMAX_FRM), 0 } }, + & ifmt_fcmpfs, { 0xf0372000 } + }, +/* fcmpls ${fmax-FRn},${fmax-FRm} */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (FMAX_FRN), ',', OP (FMAX_FRM), 0 } }, + & ifmt_fcmpfs, { 0xf0472000 } + }, +/* fcmpuls ${fmax-FRn},${fmax-FRm} */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (FMAX_FRN), ',', OP (FMAX_FRM), 0 } }, + & ifmt_fcmpfs, { 0xf0572000 } + }, +/* fcmples ${fmax-FRn},${fmax-FRm} */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (FMAX_FRN), ',', OP (FMAX_FRM), 0 } }, + & ifmt_fcmpfs, { 0xf0672000 } + }, +/* fcmpules ${fmax-FRn},${fmax-FRm} */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (FMAX_FRN), ',', OP (FMAX_FRM), 0 } }, + & ifmt_fcmpfs, { 0xf0772000 } + }, +/* fcmpfis ${fmax-FRn},${fmax-FRm} */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (FMAX_FRN), ',', OP (FMAX_FRM), 0 } }, + & ifmt_fcmpfs, { 0xf0872000 } + }, +/* fcmpuis ${fmax-FRn},${fmax-FRm} */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (FMAX_FRN), ',', OP (FMAX_FRM), 0 } }, + & ifmt_fcmpfs, { 0xf0972000 } + }, +/* fcmpeis ${fmax-FRn},${fmax-FRm} */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (FMAX_FRN), ',', OP (FMAX_FRM), 0 } }, + & ifmt_fcmpfs, { 0xf0a72000 } + }, +/* fcmpueis ${fmax-FRn},${fmax-FRm} */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (FMAX_FRN), ',', OP (FMAX_FRM), 0 } }, + & ifmt_fcmpfs, { 0xf0b72000 } + }, +/* fcmplis ${fmax-FRn},${fmax-FRm} */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (FMAX_FRN), ',', OP (FMAX_FRM), 0 } }, + & ifmt_fcmpfs, { 0xf0c72000 } + }, +/* fcmpulis ${fmax-FRn},${fmax-FRm} */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (FMAX_FRN), ',', OP (FMAX_FRM), 0 } }, + & ifmt_fcmpfs, { 0xf0d72000 } + }, +/* fcmpleis ${fmax-FRn},${fmax-FRm} */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (FMAX_FRN), ',', OP (FMAX_FRM), 0 } }, + & ifmt_fcmpfs, { 0xf0e72000 } + }, +/* fcmpuleis ${fmax-FRn},${fmax-FRm} */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (FMAX_FRN), ',', OP (FMAX_FRM), 0 } }, + & ifmt_fcmpfs, { 0xf0f72000 } + }, +/* cmov ${fmax-FRd-int},${fmax-Rm} */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (FMAX_FRD_INT), ',', OP (FMAX_RM), 0 } }, + & ifmt_cmov_frn_rm, { 0xf007f000 } + }, +/* cmov ${fmax-Rm},${fmax-FRd-int} */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (FMAX_RM), ',', OP (FMAX_FRD_INT), 0 } }, + & ifmt_cmov_frn_rm, { 0xf007f001 } + }, +/* cmovc ${fmax-CCRn},${fmax-Rm} */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (FMAX_CCRN), ',', OP (FMAX_RM), 0 } }, + & ifmt_cmovc_ccrn_rm, { 0xf007f002 } + }, +/* cmovc ${fmax-Rm},${fmax-CCRn} */ + { + { 0, 0, 0, 0 }, + { { MNEM, ' ', OP (FMAX_RM), ',', OP (FMAX_CCRN), 0 } }, + & ifmt_cmovc_ccrn_rm, { 0xf007f003 } + }, +}; + +#undef A +#undef OPERAND +#undef MNEM +#undef OP + +/* Formats for ALIAS macro-insns. */ + +#if defined (__STDC__) || defined (ALMOST_STDC) || defined (HAVE_STRINGIZE) +#define F(f) & mep_cgen_ifld_table[MEP_##f] +#else +#define F(f) & mep_cgen_ifld_table[MEP_/**/f] +#endif +static const CGEN_IFMT ifmt_nop ATTRIBUTE_UNUSED = { + 16, 16, 0xffff, { { F (F_MAJOR) }, { F (F_RN) }, { F (F_RM) }, { F (F_SUB4) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_sb16_0 ATTRIBUTE_UNUSED = { + 16, 16, 0xf00f, { { F (F_MAJOR) }, { F (F_RN) }, { F (F_RM) }, { F (F_SUB4) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_sh16_0 ATTRIBUTE_UNUSED = { + 16, 16, 0xf00f, { { F (F_MAJOR) }, { F (F_RN) }, { F (F_RM) }, { F (F_SUB4) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_sw16_0 ATTRIBUTE_UNUSED = { + 16, 16, 0xf00f, { { F (F_MAJOR) }, { F (F_RN) }, { F (F_RM) }, { F (F_SUB4) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_lb16_0 ATTRIBUTE_UNUSED = { + 16, 16, 0xf00f, { { F (F_MAJOR) }, { F (F_RN) }, { F (F_RM) }, { F (F_SUB4) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_lh16_0 ATTRIBUTE_UNUSED = { + 16, 16, 0xf00f, { { F (F_MAJOR) }, { F (F_RN) }, { F (F_RM) }, { F (F_SUB4) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_lw16_0 ATTRIBUTE_UNUSED = { + 16, 16, 0xf00f, { { F (F_MAJOR) }, { F (F_RN) }, { F (F_RM) }, { F (F_SUB4) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_lbu16_0 ATTRIBUTE_UNUSED = { + 16, 16, 0xf00f, { { F (F_MAJOR) }, { F (F_RN) }, { F (F_RM) }, { F (F_SUB4) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_lhu16_0 ATTRIBUTE_UNUSED = { + 16, 16, 0xf00f, { { F (F_MAJOR) }, { F (F_RN) }, { F (F_RM) }, { F (F_SUB4) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_swcp16_0 ATTRIBUTE_UNUSED = { + 16, 16, 0xf00f, { { F (F_MAJOR) }, { F (F_CRN) }, { F (F_RM) }, { F (F_SUB4) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_lwcp16_0 ATTRIBUTE_UNUSED = { + 16, 16, 0xf00f, { { F (F_MAJOR) }, { F (F_CRN) }, { F (F_RM) }, { F (F_SUB4) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_smcp16_0 ATTRIBUTE_UNUSED = { + 16, 16, 0xf00f, { { F (F_MAJOR) }, { F (F_CRN) }, { F (F_RM) }, { F (F_SUB4) }, { 0 } } +}; + +static const CGEN_IFMT ifmt_lmcp16_0 ATTRIBUTE_UNUSED = { + 16, 16, 0xf00f, { { F (F_MAJOR) }, { F (F_CRN) }, { F (F_RM) }, { F (F_SUB4) }, { 0 } } +}; + +#undef F + +/* Each non-simple macro entry points to an array of expansion possibilities. */ + +#if defined (__STDC__) || defined (ALMOST_STDC) || defined (HAVE_STRINGIZE) +#define A(a) (1 << CGEN_INSN_##a) +#else +#define A(a) (1 << CGEN_INSN_/**/a) +#endif +#if defined (__STDC__) || defined (ALMOST_STDC) || defined (HAVE_STRINGIZE) +#define OPERAND(op) MEP_OPERAND_##op +#else +#define OPERAND(op) MEP_OPERAND_/**/op +#endif +#define MNEM CGEN_SYNTAX_MNEMONIC /* syntax value for mnemonic */ +#define OP(field) CGEN_SYNTAX_MAKE_FIELD (OPERAND (field)) + +/* The macro instruction table. */ + +static const CGEN_IBASE mep_cgen_macro_insn_table[] = +{ +/* nop */ + { + -1, "nop", "nop", 16, + { 0|A(ALIAS), { { { (1<macro_insn_table.init_entries = insns; + cd->macro_insn_table.entry_size = sizeof (CGEN_IBASE); + cd->macro_insn_table.num_init_entries = num_macros; + + oc = & mep_cgen_insn_opcode_table[0]; + insns = (CGEN_INSN *) cd->insn_table.init_entries; + for (i = 0; i < MAX_INSNS; ++i) + { + insns[i].opcode = &oc[i]; + mep_cgen_build_insn_regex (& insns[i]); + } + + cd->sizeof_fields = sizeof (CGEN_FIELDS); + cd->set_fields_bitsize = set_fields_bitsize; + + cd->asm_hash_p = asm_hash_insn_p; + cd->asm_hash = asm_hash_insn; + cd->asm_hash_size = CGEN_ASM_HASH_SIZE; + + cd->dis_hash_p = dis_hash_insn_p; + cd->dis_hash = dis_hash_insn; + cd->dis_hash_size = CGEN_DIS_HASH_SIZE; +} diff --git a/opcodes/mep-opc.h b/opcodes/mep-opc.h new file mode 100644 index 00000000000..d9dbd4ba7e5 --- /dev/null +++ b/opcodes/mep-opc.h @@ -0,0 +1,294 @@ +/* Instruction opcode header for mep. + +THIS FILE IS MACHINE GENERATED WITH CGEN. + +Copyright 1996-2005 Free Software Foundation, Inc. + +This file is part of the GNU Binutils and/or GDB, the GNU debugger. + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along +with this program; if not, write to the Free Software Foundation, Inc., +51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. + +*/ + +#ifndef MEP_OPC_H +#define MEP_OPC_H + +/* -- opc.h */ + +#undef CGEN_DIS_HASH_SIZE +#define CGEN_DIS_HASH_SIZE 1 + +#undef CGEN_DIS_HASH +#define CGEN_DIS_HASH(buffer, insn) 0 + +#define CGEN_VERBOSE_ASSEMBLER_ERRORS + +typedef struct +{ + char * name; + int config_enum; + unsigned cpu_flag; + int big_endian; + int vliw_bits; + CGEN_ATTR_VALUE_BITSET_TYPE cop16_isa; + CGEN_ATTR_VALUE_BITSET_TYPE cop32_isa; + CGEN_ATTR_VALUE_BITSET_TYPE cop48_isa; + CGEN_ATTR_VALUE_BITSET_TYPE cop64_isa; + CGEN_ATTR_VALUE_BITSET_TYPE cop_isa; + CGEN_ATTR_VALUE_BITSET_TYPE core_isa; + unsigned int option_mask; +} mep_config_map_struct; + +extern mep_config_map_struct mep_config_map[]; +extern int mep_config_index; + +extern void init_mep_all_core_isas_mask (void); +extern void init_mep_all_cop_isas_mask (void); +extern CGEN_ATTR_VALUE_BITSET_TYPE mep_cop_isa (void); + +#define MEP_CONFIG (mep_config_map[mep_config_index].config_enum) +#define MEP_CPU (mep_config_map[mep_config_index].cpu_flag) +#define MEP_OMASK (mep_config_map[mep_config_index].option_mask) +#define MEP_VLIW (mep_config_map[mep_config_index].vliw_bits > 0) +#define MEP_VLIW32 (mep_config_map[mep_config_index].vliw_bits == 32) +#define MEP_VLIW64 (mep_config_map[mep_config_index].vliw_bits == 64) +#define MEP_COP16_ISA (mep_config_map[mep_config_index].cop16_isa) +#define MEP_COP32_ISA (mep_config_map[mep_config_index].cop32_isa) +#define MEP_COP48_ISA (mep_config_map[mep_config_index].cop48_isa) +#define MEP_COP64_ISA (mep_config_map[mep_config_index].cop64_isa) +#define MEP_COP_ISA (mep_config_map[mep_config_index].cop_isa) +#define MEP_CORE_ISA (mep_config_map[mep_config_index].core_isa) + +extern int mep_insn_supported_by_isa (const CGEN_INSN *, CGEN_ATTR_VALUE_BITSET_TYPE *); + +/* A mask for all ISAs executed by the core. */ +#define MEP_ALL_CORE_ISAS_MASK mep_all_core_isas_mask +extern CGEN_ATTR_VALUE_BITSET_TYPE mep_all_core_isas_mask; + +#define MEP_INSN_CORE_P(insn) ( \ + init_mep_all_core_isas_mask (), \ + mep_insn_supported_by_isa (insn, & MEP_ALL_CORE_ISAS_MASK) \ +) + +/* A mask for all ISAs executed by a VLIW coprocessor. */ +#define MEP_ALL_COP_ISAS_MASK mep_all_cop_isas_mask +extern CGEN_ATTR_VALUE_BITSET_TYPE mep_all_cop_isas_mask; + +#define MEP_INSN_COP_P(insn) ( \ + init_mep_all_cop_isas_mask (), \ + mep_insn_supported_by_isa (insn, & MEP_ALL_COP_ISAS_MASK) \ +) + +extern int mep_cgen_insn_supported (CGEN_CPU_DESC, const CGEN_INSN *); + +/* -- asm.c */ +/* Enum declaration for mep instruction types. */ +typedef enum cgen_insn_type { + MEP_INSN_INVALID, MEP_INSN_SB, MEP_INSN_SH, MEP_INSN_SW + , MEP_INSN_LB, MEP_INSN_LH, MEP_INSN_LW, MEP_INSN_LBU + , MEP_INSN_LHU, MEP_INSN_SW_SP, MEP_INSN_LW_SP, MEP_INSN_SB_TP + , MEP_INSN_SH_TP, MEP_INSN_SW_TP, MEP_INSN_LB_TP, MEP_INSN_LH_TP + , MEP_INSN_LW_TP, MEP_INSN_LBU_TP, MEP_INSN_LHU_TP, MEP_INSN_SB16 + , MEP_INSN_SH16, MEP_INSN_SW16, MEP_INSN_LB16, MEP_INSN_LH16 + , MEP_INSN_LW16, MEP_INSN_LBU16, MEP_INSN_LHU16, MEP_INSN_SW24 + , MEP_INSN_LW24, MEP_INSN_EXTB, MEP_INSN_EXTH, MEP_INSN_EXTUB + , MEP_INSN_EXTUH, MEP_INSN_SSARB, MEP_INSN_MOV, MEP_INSN_MOVI8 + , MEP_INSN_MOVI16, MEP_INSN_MOVU24, MEP_INSN_MOVU16, MEP_INSN_MOVH + , MEP_INSN_ADD3, MEP_INSN_ADD, MEP_INSN_ADD3I, MEP_INSN_ADVCK3 + , MEP_INSN_SUB, MEP_INSN_SBVCK3, MEP_INSN_NEG, MEP_INSN_SLT3 + , MEP_INSN_SLTU3, MEP_INSN_SLT3I, MEP_INSN_SLTU3I, MEP_INSN_SL1AD3 + , MEP_INSN_SL2AD3, MEP_INSN_ADD3X, MEP_INSN_SLT3X, MEP_INSN_SLTU3X + , MEP_INSN_OR, MEP_INSN_AND, MEP_INSN_XOR, MEP_INSN_NOR + , MEP_INSN_OR3, MEP_INSN_AND3, MEP_INSN_XOR3, MEP_INSN_SRA + , MEP_INSN_SRL, MEP_INSN_SLL, MEP_INSN_SRAI, MEP_INSN_SRLI + , MEP_INSN_SLLI, MEP_INSN_SLL3, MEP_INSN_FSFT, MEP_INSN_BRA + , MEP_INSN_BEQZ, MEP_INSN_BNEZ, MEP_INSN_BEQI, MEP_INSN_BNEI + , MEP_INSN_BLTI, MEP_INSN_BGEI, MEP_INSN_BEQ, MEP_INSN_BNE + , MEP_INSN_BSR12, MEP_INSN_BSR24, MEP_INSN_JMP, MEP_INSN_JMP24 + , MEP_INSN_JSR, MEP_INSN_RET, MEP_INSN_REPEAT, MEP_INSN_EREPEAT + , MEP_INSN_STC_LP, MEP_INSN_STC_HI, MEP_INSN_STC_LO, MEP_INSN_STC + , MEP_INSN_LDC_LP, MEP_INSN_LDC_HI, MEP_INSN_LDC_LO, MEP_INSN_LDC + , MEP_INSN_DI, MEP_INSN_EI, MEP_INSN_RETI, MEP_INSN_HALT + , MEP_INSN_SLEEP, MEP_INSN_SWI, MEP_INSN_BREAK, MEP_INSN_SYNCM + , MEP_INSN_STCB, MEP_INSN_LDCB, MEP_INSN_BSETM, MEP_INSN_BCLRM + , MEP_INSN_BNOTM, MEP_INSN_BTSTM, MEP_INSN_TAS, MEP_INSN_CACHE + , MEP_INSN_MUL, MEP_INSN_MULU, MEP_INSN_MULR, MEP_INSN_MULRU + , MEP_INSN_MADD, MEP_INSN_MADDU, MEP_INSN_MADDR, MEP_INSN_MADDRU + , MEP_INSN_DIV, MEP_INSN_DIVU, MEP_INSN_DRET, MEP_INSN_DBREAK + , MEP_INSN_LDZ, MEP_INSN_ABS, MEP_INSN_AVE, MEP_INSN_MIN + , MEP_INSN_MAX, MEP_INSN_MINU, MEP_INSN_MAXU, MEP_INSN_CLIP + , MEP_INSN_CLIPU, MEP_INSN_SADD, MEP_INSN_SSUB, MEP_INSN_SADDU + , MEP_INSN_SSUBU, MEP_INSN_SWCP, MEP_INSN_LWCP, MEP_INSN_SMCP + , MEP_INSN_LMCP, MEP_INSN_SWCPI, MEP_INSN_LWCPI, MEP_INSN_SMCPI + , MEP_INSN_LMCPI, MEP_INSN_SWCP16, MEP_INSN_LWCP16, MEP_INSN_SMCP16 + , MEP_INSN_LMCP16, MEP_INSN_SBCPA, MEP_INSN_LBCPA, MEP_INSN_SHCPA + , MEP_INSN_LHCPA, MEP_INSN_SWCPA, MEP_INSN_LWCPA, MEP_INSN_SMCPA + , MEP_INSN_LMCPA, MEP_INSN_SBCPM0, MEP_INSN_LBCPM0, MEP_INSN_SHCPM0 + , MEP_INSN_LHCPM0, MEP_INSN_SWCPM0, MEP_INSN_LWCPM0, MEP_INSN_SMCPM0 + , MEP_INSN_LMCPM0, MEP_INSN_SBCPM1, MEP_INSN_LBCPM1, MEP_INSN_SHCPM1 + , MEP_INSN_LHCPM1, MEP_INSN_SWCPM1, MEP_INSN_LWCPM1, MEP_INSN_SMCPM1 + , MEP_INSN_LMCPM1, MEP_INSN_BCPEQ, MEP_INSN_BCPNE, MEP_INSN_BCPAT + , MEP_INSN_BCPAF, MEP_INSN_SYNCCP, MEP_INSN_JSRV, MEP_INSN_BSRV + , MEP_INSN_SIM_SYSCALL, MEP_INSN_RI_0, MEP_INSN_RI_1, MEP_INSN_RI_2 + , MEP_INSN_RI_3, MEP_INSN_RI_4, MEP_INSN_RI_5, MEP_INSN_RI_6 + , MEP_INSN_RI_7, MEP_INSN_RI_8, MEP_INSN_RI_9, MEP_INSN_RI_10 + , MEP_INSN_RI_11, MEP_INSN_RI_12, MEP_INSN_RI_13, MEP_INSN_RI_14 + , MEP_INSN_RI_15, MEP_INSN_RI_17, MEP_INSN_RI_20, MEP_INSN_RI_21 + , MEP_INSN_RI_22, MEP_INSN_RI_23, MEP_INSN_RI_24, MEP_INSN_RI_25 + , MEP_INSN_RI_26, MEP_INSN_RI_16, MEP_INSN_RI_18, MEP_INSN_RI_19 + , MEP_INSN_FADDS, MEP_INSN_FSUBS, MEP_INSN_FMULS, MEP_INSN_FDIVS + , MEP_INSN_FSQRTS, MEP_INSN_FABSS, MEP_INSN_FNEGS, MEP_INSN_FMOVS + , MEP_INSN_FROUNDWS, MEP_INSN_FTRUNCWS, MEP_INSN_FCEILWS, MEP_INSN_FFLOORWS + , MEP_INSN_FCVTWS, MEP_INSN_FCVTSW, MEP_INSN_FCMPFS, MEP_INSN_FCMPUS + , MEP_INSN_FCMPES, MEP_INSN_FCMPUES, MEP_INSN_FCMPLS, MEP_INSN_FCMPULS + , MEP_INSN_FCMPLES, MEP_INSN_FCMPULES, MEP_INSN_FCMPFIS, MEP_INSN_FCMPUIS + , MEP_INSN_FCMPEIS, MEP_INSN_FCMPUEIS, MEP_INSN_FCMPLIS, MEP_INSN_FCMPULIS + , MEP_INSN_FCMPLEIS, MEP_INSN_FCMPULEIS, MEP_INSN_CMOV_FRN_RM, MEP_INSN_CMOV_RM_FRN + , MEP_INSN_CMOVC_CCRN_RM, MEP_INSN_CMOVC_RM_CCRN +} CGEN_INSN_TYPE; + +/* Index of `invalid' insn place holder. */ +#define CGEN_INSN_INVALID MEP_INSN_INVALID + +/* Total number of insns in table. */ +#define MAX_INSNS ((int) MEP_INSN_CMOVC_RM_CCRN + 1) + +/* This struct records data prior to insertion or after extraction. */ +struct cgen_fields +{ + int length; + long f_nil; + long f_anyof; + long f_major; + long f_rn; + long f_rn3; + long f_rm; + long f_rl; + long f_sub2; + long f_sub3; + long f_sub4; + long f_ext; + long f_crn; + long f_csrn_hi; + long f_csrn_lo; + long f_csrn; + long f_crnx_hi; + long f_crnx_lo; + long f_crnx; + long f_0; + long f_1; + long f_2; + long f_3; + long f_4; + long f_5; + long f_6; + long f_7; + long f_8; + long f_9; + long f_10; + long f_11; + long f_12; + long f_13; + long f_14; + long f_15; + long f_16; + long f_17; + long f_18; + long f_19; + long f_20; + long f_21; + long f_22; + long f_23; + long f_24; + long f_25; + long f_26; + long f_27; + long f_28; + long f_29; + long f_30; + long f_31; + long f_8s8a2; + long f_12s4a2; + long f_17s16a2; + long f_24s5a2n_hi; + long f_24s5a2n_lo; + long f_24s5a2n; + long f_24u5a2n_hi; + long f_24u5a2n_lo; + long f_24u5a2n; + long f_2u6; + long f_7u9; + long f_7u9a2; + long f_7u9a4; + long f_16s16; + long f_2u10; + long f_3u5; + long f_4u8; + long f_5u8; + long f_5u24; + long f_6s8; + long f_8s8; + long f_16u16; + long f_12u16; + long f_3u29; + long f_8s24; + long f_8s24a2; + long f_8s24a4; + long f_8s24a8; + long f_24u8a4n_hi; + long f_24u8a4n_lo; + long f_24u8a4n; + long f_24u8n_hi; + long f_24u8n_lo; + long f_24u8n; + long f_24u4n_hi; + long f_24u4n_lo; + long f_24u4n; + long f_callnum; + long f_ccrn_hi; + long f_ccrn_lo; + long f_ccrn; + long f_fmax_0_4; + long f_fmax_4_4; + long f_fmax_8_4; + long f_fmax_12_4; + long f_fmax_16_4; + long f_fmax_20_4; + long f_fmax_24_4; + long f_fmax_28_1; + long f_fmax_29_1; + long f_fmax_30_1; + long f_fmax_31_1; + long f_fmax_frd; + long f_fmax_frn; + long f_fmax_frm; + long f_fmax_rm; +}; + +#define CGEN_INIT_PARSE(od) \ +{\ +} +#define CGEN_INIT_INSERT(od) \ +{\ +} +#define CGEN_INIT_EXTRACT(od) \ +{\ +} +#define CGEN_INIT_PRINT(od) \ +{\ +} + + +#endif /* MEP_OPC_H */