Back to index

cell-binutils  2.17cvs20070401
ip2k-desc.c
Go to the documentation of this file.
00001 /* CPU data for ip2k.
00002 
00003 THIS FILE IS MACHINE GENERATED WITH CGEN.
00004 
00005 Copyright 1996-2005 Free Software Foundation, Inc.
00006 
00007 This file is part of the GNU Binutils and/or GDB, the GNU debugger.
00008 
00009 This program is free software; you can redistribute it and/or modify
00010 it under the terms of the GNU General Public License as published by
00011 the Free Software Foundation; either version 2, or (at your option)
00012 any later version.
00013 
00014 This program is distributed in the hope that it will be useful,
00015 but WITHOUT ANY WARRANTY; without even the implied warranty of
00016 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00017 GNU General Public License for more details.
00018 
00019 You should have received a copy of the GNU General Public License along
00020 with this program; if not, write to the Free Software Foundation, Inc.,
00021 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
00022 
00023 */
00024 
00025 #include "sysdep.h"
00026 #include <stdio.h>
00027 #include <stdarg.h>
00028 #include "ansidecl.h"
00029 #include "bfd.h"
00030 #include "symcat.h"
00031 #include "ip2k-desc.h"
00032 #include "ip2k-opc.h"
00033 #include "opintl.h"
00034 #include "libiberty.h"
00035 #include "xregex.h"
00036 
00037 /* Attributes.  */
00038 
00039 static const CGEN_ATTR_ENTRY bool_attr[] =
00040 {
00041   { "#f", 0 },
00042   { "#t", 1 },
00043   { 0, 0 }
00044 };
00045 
00046 static const CGEN_ATTR_ENTRY MACH_attr[] ATTRIBUTE_UNUSED =
00047 {
00048   { "base", MACH_BASE },
00049   { "ip2022", MACH_IP2022 },
00050   { "ip2022ext", MACH_IP2022EXT },
00051   { "max", MACH_MAX },
00052   { 0, 0 }
00053 };
00054 
00055 static const CGEN_ATTR_ENTRY ISA_attr[] ATTRIBUTE_UNUSED =
00056 {
00057   { "ip2k", ISA_IP2K },
00058   { "max", ISA_MAX },
00059   { 0, 0 }
00060 };
00061 
00062 const CGEN_ATTR_TABLE ip2k_cgen_ifield_attr_table[] =
00063 {
00064   { "MACH", & MACH_attr[0], & MACH_attr[0] },
00065   { "VIRTUAL", &bool_attr[0], &bool_attr[0] },
00066   { "PCREL-ADDR", &bool_attr[0], &bool_attr[0] },
00067   { "ABS-ADDR", &bool_attr[0], &bool_attr[0] },
00068   { "RESERVED", &bool_attr[0], &bool_attr[0] },
00069   { "SIGN-OPT", &bool_attr[0], &bool_attr[0] },
00070   { "SIGNED", &bool_attr[0], &bool_attr[0] },
00071   { 0, 0, 0 }
00072 };
00073 
00074 const CGEN_ATTR_TABLE ip2k_cgen_hardware_attr_table[] =
00075 {
00076   { "MACH", & MACH_attr[0], & MACH_attr[0] },
00077   { "VIRTUAL", &bool_attr[0], &bool_attr[0] },
00078   { "CACHE-ADDR", &bool_attr[0], &bool_attr[0] },
00079   { "PC", &bool_attr[0], &bool_attr[0] },
00080   { "PROFILE", &bool_attr[0], &bool_attr[0] },
00081   { 0, 0, 0 }
00082 };
00083 
00084 const CGEN_ATTR_TABLE ip2k_cgen_operand_attr_table[] =
00085 {
00086   { "MACH", & MACH_attr[0], & MACH_attr[0] },
00087   { "VIRTUAL", &bool_attr[0], &bool_attr[0] },
00088   { "PCREL-ADDR", &bool_attr[0], &bool_attr[0] },
00089   { "ABS-ADDR", &bool_attr[0], &bool_attr[0] },
00090   { "SIGN-OPT", &bool_attr[0], &bool_attr[0] },
00091   { "SIGNED", &bool_attr[0], &bool_attr[0] },
00092   { "NEGATIVE", &bool_attr[0], &bool_attr[0] },
00093   { "RELAX", &bool_attr[0], &bool_attr[0] },
00094   { "SEM-ONLY", &bool_attr[0], &bool_attr[0] },
00095   { 0, 0, 0 }
00096 };
00097 
00098 const CGEN_ATTR_TABLE ip2k_cgen_insn_attr_table[] =
00099 {
00100   { "MACH", & MACH_attr[0], & MACH_attr[0] },
00101   { "ALIAS", &bool_attr[0], &bool_attr[0] },
00102   { "VIRTUAL", &bool_attr[0], &bool_attr[0] },
00103   { "UNCOND-CTI", &bool_attr[0], &bool_attr[0] },
00104   { "COND-CTI", &bool_attr[0], &bool_attr[0] },
00105   { "SKIP-CTI", &bool_attr[0], &bool_attr[0] },
00106   { "DELAY-SLOT", &bool_attr[0], &bool_attr[0] },
00107   { "RELAXABLE", &bool_attr[0], &bool_attr[0] },
00108   { "RELAXED", &bool_attr[0], &bool_attr[0] },
00109   { "NO-DIS", &bool_attr[0], &bool_attr[0] },
00110   { "PBB", &bool_attr[0], &bool_attr[0] },
00111   { "EXT-SKIP-INSN", &bool_attr[0], &bool_attr[0] },
00112   { "SKIPA", &bool_attr[0], &bool_attr[0] },
00113   { 0, 0, 0 }
00114 };
00115 
00116 /* Instruction set variants.  */
00117 
00118 static const CGEN_ISA ip2k_cgen_isa_table[] = {
00119   { "ip2k", 16, 16, 16, 16 },
00120   { 0, 0, 0, 0, 0 }
00121 };
00122 
00123 /* Machine variants.  */
00124 
00125 static const CGEN_MACH ip2k_cgen_mach_table[] = {
00126   { "ip2022", "ip2022", MACH_IP2022, 0 },
00127   { "ip2022ext", "ip2022ext", MACH_IP2022EXT, 0 },
00128   { 0, 0, 0, 0 }
00129 };
00130 
00131 static CGEN_KEYWORD_ENTRY ip2k_cgen_opval_register_names_entries[] =
00132 {
00133   { "ADDRSEL", 2, {0, {{{0, 0}}}}, 0, 0 },
00134   { "ADDRX", 3, {0, {{{0, 0}}}}, 0, 0 },
00135   { "IPH", 4, {0, {{{0, 0}}}}, 0, 0 },
00136   { "IPL", 5, {0, {{{0, 0}}}}, 0, 0 },
00137   { "SPH", 6, {0, {{{0, 0}}}}, 0, 0 },
00138   { "SPL", 7, {0, {{{0, 0}}}}, 0, 0 },
00139   { "PCH", 8, {0, {{{0, 0}}}}, 0, 0 },
00140   { "PCL", 9, {0, {{{0, 0}}}}, 0, 0 },
00141   { "WREG", 10, {0, {{{0, 0}}}}, 0, 0 },
00142   { "STATUS", 11, {0, {{{0, 0}}}}, 0, 0 },
00143   { "DPH", 12, {0, {{{0, 0}}}}, 0, 0 },
00144   { "DPL", 13, {0, {{{0, 0}}}}, 0, 0 },
00145   { "SPDREG", 14, {0, {{{0, 0}}}}, 0, 0 },
00146   { "MULH", 15, {0, {{{0, 0}}}}, 0, 0 },
00147   { "ADDRH", 16, {0, {{{0, 0}}}}, 0, 0 },
00148   { "ADDRL", 17, {0, {{{0, 0}}}}, 0, 0 },
00149   { "DATAH", 18, {0, {{{0, 0}}}}, 0, 0 },
00150   { "DATAL", 19, {0, {{{0, 0}}}}, 0, 0 },
00151   { "INTVECH", 20, {0, {{{0, 0}}}}, 0, 0 },
00152   { "INTVECL", 21, {0, {{{0, 0}}}}, 0, 0 },
00153   { "INTSPD", 22, {0, {{{0, 0}}}}, 0, 0 },
00154   { "INTF", 23, {0, {{{0, 0}}}}, 0, 0 },
00155   { "INTE", 24, {0, {{{0, 0}}}}, 0, 0 },
00156   { "INTED", 25, {0, {{{0, 0}}}}, 0, 0 },
00157   { "FCFG", 26, {0, {{{0, 0}}}}, 0, 0 },
00158   { "TCTRL", 27, {0, {{{0, 0}}}}, 0, 0 },
00159   { "XCFG", 28, {0, {{{0, 0}}}}, 0, 0 },
00160   { "EMCFG", 29, {0, {{{0, 0}}}}, 0, 0 },
00161   { "IPCH", 30, {0, {{{0, 0}}}}, 0, 0 },
00162   { "IPCL", 31, {0, {{{0, 0}}}}, 0, 0 },
00163   { "RAIN", 32, {0, {{{0, 0}}}}, 0, 0 },
00164   { "RAOUT", 33, {0, {{{0, 0}}}}, 0, 0 },
00165   { "RADIR", 34, {0, {{{0, 0}}}}, 0, 0 },
00166   { "LFSRH", 35, {0, {{{0, 0}}}}, 0, 0 },
00167   { "RBIN", 36, {0, {{{0, 0}}}}, 0, 0 },
00168   { "RBOUT", 37, {0, {{{0, 0}}}}, 0, 0 },
00169   { "RBDIR", 38, {0, {{{0, 0}}}}, 0, 0 },
00170   { "LFSRL", 39, {0, {{{0, 0}}}}, 0, 0 },
00171   { "RCIN", 40, {0, {{{0, 0}}}}, 0, 0 },
00172   { "RCOUT", 41, {0, {{{0, 0}}}}, 0, 0 },
00173   { "RCDIR", 42, {0, {{{0, 0}}}}, 0, 0 },
00174   { "LFSRA", 43, {0, {{{0, 0}}}}, 0, 0 },
00175   { "RDIN", 44, {0, {{{0, 0}}}}, 0, 0 },
00176   { "RDOUT", 45, {0, {{{0, 0}}}}, 0, 0 },
00177   { "RDDIR", 46, {0, {{{0, 0}}}}, 0, 0 },
00178   { "REIN", 48, {0, {{{0, 0}}}}, 0, 0 },
00179   { "REOUT", 49, {0, {{{0, 0}}}}, 0, 0 },
00180   { "REDIR", 50, {0, {{{0, 0}}}}, 0, 0 },
00181   { "RFIN", 52, {0, {{{0, 0}}}}, 0, 0 },
00182   { "RFOUT", 53, {0, {{{0, 0}}}}, 0, 0 },
00183   { "RFDIR", 54, {0, {{{0, 0}}}}, 0, 0 },
00184   { "RGOUT", 57, {0, {{{0, 0}}}}, 0, 0 },
00185   { "RGDIR", 58, {0, {{{0, 0}}}}, 0, 0 },
00186   { "RTTMR", 64, {0, {{{0, 0}}}}, 0, 0 },
00187   { "RTCFG", 65, {0, {{{0, 0}}}}, 0, 0 },
00188   { "T0TMR", 66, {0, {{{0, 0}}}}, 0, 0 },
00189   { "T0CFG", 67, {0, {{{0, 0}}}}, 0, 0 },
00190   { "T1CNTH", 68, {0, {{{0, 0}}}}, 0, 0 },
00191   { "T1CNTL", 69, {0, {{{0, 0}}}}, 0, 0 },
00192   { "T1CAP1H", 70, {0, {{{0, 0}}}}, 0, 0 },
00193   { "T1CAP1L", 71, {0, {{{0, 0}}}}, 0, 0 },
00194   { "T1CAP2H", 72, {0, {{{0, 0}}}}, 0, 0 },
00195   { "T1CMP2H", 72, {0, {{{0, 0}}}}, 0, 0 },
00196   { "T1CAP2L", 73, {0, {{{0, 0}}}}, 0, 0 },
00197   { "T1CMP2L", 73, {0, {{{0, 0}}}}, 0, 0 },
00198   { "T1CMP1H", 74, {0, {{{0, 0}}}}, 0, 0 },
00199   { "T1CMP1L", 75, {0, {{{0, 0}}}}, 0, 0 },
00200   { "T1CFG1H", 76, {0, {{{0, 0}}}}, 0, 0 },
00201   { "T1CFG1L", 77, {0, {{{0, 0}}}}, 0, 0 },
00202   { "T1CFG2H", 78, {0, {{{0, 0}}}}, 0, 0 },
00203   { "T1CFG2L", 79, {0, {{{0, 0}}}}, 0, 0 },
00204   { "ADCH", 80, {0, {{{0, 0}}}}, 0, 0 },
00205   { "ADCL", 81, {0, {{{0, 0}}}}, 0, 0 },
00206   { "ADCCFG", 82, {0, {{{0, 0}}}}, 0, 0 },
00207   { "ADCTMR", 83, {0, {{{0, 0}}}}, 0, 0 },
00208   { "T2CNTH", 84, {0, {{{0, 0}}}}, 0, 0 },
00209   { "T2CNTL", 85, {0, {{{0, 0}}}}, 0, 0 },
00210   { "T2CAP1H", 86, {0, {{{0, 0}}}}, 0, 0 },
00211   { "T2CAP1L", 87, {0, {{{0, 0}}}}, 0, 0 },
00212   { "T2CAP2H", 88, {0, {{{0, 0}}}}, 0, 0 },
00213   { "T2CMP2H", 88, {0, {{{0, 0}}}}, 0, 0 },
00214   { "T2CAP2L", 89, {0, {{{0, 0}}}}, 0, 0 },
00215   { "T2CMP2L", 89, {0, {{{0, 0}}}}, 0, 0 },
00216   { "T2CMP1H", 90, {0, {{{0, 0}}}}, 0, 0 },
00217   { "T2CMP1L", 91, {0, {{{0, 0}}}}, 0, 0 },
00218   { "T2CFG1H", 92, {0, {{{0, 0}}}}, 0, 0 },
00219   { "T2CFG1L", 93, {0, {{{0, 0}}}}, 0, 0 },
00220   { "T2CFG2H", 94, {0, {{{0, 0}}}}, 0, 0 },
00221   { "T2CFG2L", 95, {0, {{{0, 0}}}}, 0, 0 },
00222   { "S1TMRH", 96, {0, {{{0, 0}}}}, 0, 0 },
00223   { "S1TMRL", 97, {0, {{{0, 0}}}}, 0, 0 },
00224   { "S1TBUFH", 98, {0, {{{0, 0}}}}, 0, 0 },
00225   { "S1TBUFL", 99, {0, {{{0, 0}}}}, 0, 0 },
00226   { "S1TCFG", 100, {0, {{{0, 0}}}}, 0, 0 },
00227   { "S1RCNT", 101, {0, {{{0, 0}}}}, 0, 0 },
00228   { "S1RBUFH", 102, {0, {{{0, 0}}}}, 0, 0 },
00229   { "S1RBUFL", 103, {0, {{{0, 0}}}}, 0, 0 },
00230   { "S1RCFG", 104, {0, {{{0, 0}}}}, 0, 0 },
00231   { "S1RSYNC", 105, {0, {{{0, 0}}}}, 0, 0 },
00232   { "S1INTF", 106, {0, {{{0, 0}}}}, 0, 0 },
00233   { "S1INTE", 107, {0, {{{0, 0}}}}, 0, 0 },
00234   { "S1MODE", 108, {0, {{{0, 0}}}}, 0, 0 },
00235   { "S1SMASK", 109, {0, {{{0, 0}}}}, 0, 0 },
00236   { "PSPCFG", 110, {0, {{{0, 0}}}}, 0, 0 },
00237   { "CMPCFG", 111, {0, {{{0, 0}}}}, 0, 0 },
00238   { "S2TMRH", 112, {0, {{{0, 0}}}}, 0, 0 },
00239   { "S2TMRL", 113, {0, {{{0, 0}}}}, 0, 0 },
00240   { "S2TBUFH", 114, {0, {{{0, 0}}}}, 0, 0 },
00241   { "S2TBUFL", 115, {0, {{{0, 0}}}}, 0, 0 },
00242   { "S2TCFG", 116, {0, {{{0, 0}}}}, 0, 0 },
00243   { "S2RCNT", 117, {0, {{{0, 0}}}}, 0, 0 },
00244   { "S2RBUFH", 118, {0, {{{0, 0}}}}, 0, 0 },
00245   { "S2RBUFL", 119, {0, {{{0, 0}}}}, 0, 0 },
00246   { "S2RCFG", 120, {0, {{{0, 0}}}}, 0, 0 },
00247   { "S2RSYNC", 121, {0, {{{0, 0}}}}, 0, 0 },
00248   { "S2INTF", 122, {0, {{{0, 0}}}}, 0, 0 },
00249   { "S2INTE", 123, {0, {{{0, 0}}}}, 0, 0 },
00250   { "S2MODE", 124, {0, {{{0, 0}}}}, 0, 0 },
00251   { "S2SMASK", 125, {0, {{{0, 0}}}}, 0, 0 },
00252   { "CALLH", 126, {0, {{{0, 0}}}}, 0, 0 },
00253   { "CALLL", 127, {0, {{{0, 0}}}}, 0, 0 }
00254 };
00255 
00256 CGEN_KEYWORD ip2k_cgen_opval_register_names =
00257 {
00258   & ip2k_cgen_opval_register_names_entries[0],
00259   121,
00260   0, 0, 0, 0, ""
00261 };
00262 
00263 
00264 /* The hardware table.  */
00265 
00266 #if defined (__STDC__) || defined (ALMOST_STDC) || defined (HAVE_STRINGIZE)
00267 #define A(a) (1 << CGEN_HW_##a)
00268 #else
00269 #define A(a) (1 << CGEN_HW_a)
00270 #endif
00271 
00272 const CGEN_HW_ENTRY ip2k_cgen_hw_table[] =
00273 {
00274   { "h-memory", HW_H_MEMORY, CGEN_ASM_NONE, 0, { 0, { { { (1<<MACH_BASE), 0 } } } } },
00275   { "h-sint", HW_H_SINT, CGEN_ASM_NONE, 0, { 0, { { { (1<<MACH_BASE), 0 } } } } },
00276   { "h-uint", HW_H_UINT, CGEN_ASM_NONE, 0, { 0, { { { (1<<MACH_BASE), 0 } } } } },
00277   { "h-addr", HW_H_ADDR, CGEN_ASM_NONE, 0, { 0, { { { (1<<MACH_BASE), 0 } } } } },
00278   { "h-iaddr", HW_H_IADDR, CGEN_ASM_NONE, 0, { 0, { { { (1<<MACH_BASE), 0 } } } } },
00279   { "h-spr", HW_H_SPR, CGEN_ASM_NONE, 0, { 0, { { { (1<<MACH_BASE), 0 } } } } },
00280   { "h-registers", HW_H_REGISTERS, CGEN_ASM_NONE, 0, { 0|A(VIRTUAL), { { { (1<<MACH_BASE), 0 } } } } },
00281   { "h-stack", HW_H_STACK, CGEN_ASM_NONE, 0, { 0, { { { (1<<MACH_BASE), 0 } } } } },
00282   { "h-pabits", HW_H_PABITS, CGEN_ASM_NONE, 0, { 0, { { { (1<<MACH_BASE), 0 } } } } },
00283   { "h-zbit", HW_H_ZBIT, CGEN_ASM_NONE, 0, { 0, { { { (1<<MACH_BASE), 0 } } } } },
00284   { "h-cbit", HW_H_CBIT, CGEN_ASM_NONE, 0, { 0, { { { (1<<MACH_BASE), 0 } } } } },
00285   { "h-dcbit", HW_H_DCBIT, CGEN_ASM_NONE, 0, { 0, { { { (1<<MACH_BASE), 0 } } } } },
00286   { "h-pc", HW_H_PC, CGEN_ASM_NONE, 0, { 0|A(PROFILE)|A(PC), { { { (1<<MACH_BASE), 0 } } } } },
00287   { 0, 0, CGEN_ASM_NONE, 0, { 0, { { { (1<<MACH_BASE), 0 } } } } }
00288 };
00289 
00290 #undef A
00291 
00292 
00293 /* The instruction field table.  */
00294 
00295 #if defined (__STDC__) || defined (ALMOST_STDC) || defined (HAVE_STRINGIZE)
00296 #define A(a) (1 << CGEN_IFLD_##a)
00297 #else
00298 #define A(a) (1 << CGEN_IFLD_a)
00299 #endif
00300 
00301 const CGEN_IFLD ip2k_cgen_ifld_table[] =
00302 {
00303   { IP2K_F_NIL, "f-nil", 0, 0, 0, 0, { 0, { { { (1<<MACH_BASE), 0 } } } }  },
00304   { IP2K_F_ANYOF, "f-anyof", 0, 0, 0, 0, { 0, { { { (1<<MACH_BASE), 0 } } } }  },
00305   { IP2K_F_IMM8, "f-imm8", 0, 16, 7, 8, { 0, { { { (1<<MACH_BASE), 0 } } } }  },
00306   { IP2K_F_REG, "f-reg", 0, 16, 8, 9, { 0|A(ABS_ADDR), { { { (1<<MACH_BASE), 0 } } } }  },
00307   { IP2K_F_ADDR16CJP, "f-addr16cjp", 0, 16, 12, 13, { 0|A(ABS_ADDR), { { { (1<<MACH_BASE), 0 } } } }  },
00308   { IP2K_F_DIR, "f-dir", 0, 16, 9, 1, { 0, { { { (1<<MACH_BASE), 0 } } } }  },
00309   { IP2K_F_BITNO, "f-bitno", 0, 16, 11, 3, { 0, { { { (1<<MACH_BASE), 0 } } } }  },
00310   { IP2K_F_OP3, "f-op3", 0, 16, 15, 3, { 0, { { { (1<<MACH_BASE), 0 } } } }  },
00311   { IP2K_F_OP4, "f-op4", 0, 16, 15, 4, { 0, { { { (1<<MACH_BASE), 0 } } } }  },
00312   { IP2K_F_OP4MID, "f-op4mid", 0, 16, 11, 4, { 0, { { { (1<<MACH_BASE), 0 } } } }  },
00313   { IP2K_F_OP6, "f-op6", 0, 16, 15, 6, { 0, { { { (1<<MACH_BASE), 0 } } } }  },
00314   { IP2K_F_OP8, "f-op8", 0, 16, 15, 8, { 0, { { { (1<<MACH_BASE), 0 } } } }  },
00315   { IP2K_F_OP6_10LOW, "f-op6-10low", 0, 16, 9, 10, { 0, { { { (1<<MACH_BASE), 0 } } } }  },
00316   { IP2K_F_OP6_7LOW, "f-op6-7low", 0, 16, 9, 7, { 0, { { { (1<<MACH_BASE), 0 } } } }  },
00317   { IP2K_F_RETI3, "f-reti3", 0, 16, 2, 3, { 0, { { { (1<<MACH_BASE), 0 } } } }  },
00318   { IP2K_F_SKIPB, "f-skipb", 0, 16, 12, 1, { 0|A(ABS_ADDR), { { { (1<<MACH_BASE), 0 } } } }  },
00319   { IP2K_F_PAGE3, "f-page3", 0, 16, 2, 3, { 0, { { { (1<<MACH_BASE), 0 } } } }  },
00320   { 0, 0, 0, 0, 0, 0, { 0, { { { (1<<MACH_BASE), 0 } } } } }
00321 };
00322 
00323 #undef A
00324 
00325 
00326 
00327 /* multi ifield declarations */
00328 
00329 
00330 
00331 /* multi ifield definitions */
00332 
00333 
00334 /* The operand table.  */
00335 
00336 #if defined (__STDC__) || defined (ALMOST_STDC) || defined (HAVE_STRINGIZE)
00337 #define A(a) (1 << CGEN_OPERAND_##a)
00338 #else
00339 #define A(a) (1 << CGEN_OPERAND_a)
00340 #endif
00341 #if defined (__STDC__) || defined (ALMOST_STDC) || defined (HAVE_STRINGIZE)
00342 #define OPERAND(op) IP2K_OPERAND_##op
00343 #else
00344 #define OPERAND(op) IP2K_OPERAND_op
00345 #endif
00346 
00347 const CGEN_OPERAND ip2k_cgen_operand_table[] =
00348 {
00349 /* pc: program counter */
00350   { "pc", IP2K_OPERAND_PC, HW_H_PC, 0, 0,
00351     { 0, { (const PTR) &ip2k_cgen_ifld_table[IP2K_F_NIL] } }, 
00352     { 0|A(SEM_ONLY), { { { (1<<MACH_BASE), 0 } } } }  },
00353 /* addr16cjp: 13-bit address */
00354   { "addr16cjp", IP2K_OPERAND_ADDR16CJP, HW_H_UINT, 12, 13,
00355     { 0, { (const PTR) &ip2k_cgen_ifld_table[IP2K_F_ADDR16CJP] } }, 
00356     { 0|A(ABS_ADDR), { { { (1<<MACH_BASE), 0 } } } }  },
00357 /* fr: register */
00358   { "fr", IP2K_OPERAND_FR, HW_H_REGISTERS, 8, 9,
00359     { 0, { (const PTR) &ip2k_cgen_ifld_table[IP2K_F_REG] } }, 
00360     { 0|A(ABS_ADDR), { { { (1<<MACH_BASE), 0 } } } }  },
00361 /* lit8: 8-bit signed literal */
00362   { "lit8", IP2K_OPERAND_LIT8, HW_H_SINT, 7, 8,
00363     { 0, { (const PTR) &ip2k_cgen_ifld_table[IP2K_F_IMM8] } }, 
00364     { 0, { { { (1<<MACH_BASE), 0 } } } }  },
00365 /* bitno: bit number */
00366   { "bitno", IP2K_OPERAND_BITNO, HW_H_UINT, 11, 3,
00367     { 0, { (const PTR) &ip2k_cgen_ifld_table[IP2K_F_BITNO] } }, 
00368     { 0, { { { (1<<MACH_BASE), 0 } } } }  },
00369 /* addr16p: page number */
00370   { "addr16p", IP2K_OPERAND_ADDR16P, HW_H_UINT, 2, 3,
00371     { 0, { (const PTR) &ip2k_cgen_ifld_table[IP2K_F_PAGE3] } }, 
00372     { 0, { { { (1<<MACH_BASE), 0 } } } }  },
00373 /* addr16h: high 8 bits of address */
00374   { "addr16h", IP2K_OPERAND_ADDR16H, HW_H_UINT, 7, 8,
00375     { 0, { (const PTR) &ip2k_cgen_ifld_table[IP2K_F_IMM8] } }, 
00376     { 0, { { { (1<<MACH_BASE), 0 } } } }  },
00377 /* addr16l: low 8 bits of address */
00378   { "addr16l", IP2K_OPERAND_ADDR16L, HW_H_UINT, 7, 8,
00379     { 0, { (const PTR) &ip2k_cgen_ifld_table[IP2K_F_IMM8] } }, 
00380     { 0, { { { (1<<MACH_BASE), 0 } } } }  },
00381 /* reti3: reti flags */
00382   { "reti3", IP2K_OPERAND_RETI3, HW_H_UINT, 2, 3,
00383     { 0, { (const PTR) &ip2k_cgen_ifld_table[IP2K_F_RETI3] } }, 
00384     { 0, { { { (1<<MACH_BASE), 0 } } } }  },
00385 /* pabits: page bits */
00386   { "pabits", IP2K_OPERAND_PABITS, HW_H_PABITS, 0, 0,
00387     { 0, { (const PTR) 0 } }, 
00388     { 0, { { { (1<<MACH_BASE), 0 } } } }  },
00389 /* zbit: zero bit */
00390   { "zbit", IP2K_OPERAND_ZBIT, HW_H_ZBIT, 0, 0,
00391     { 0, { (const PTR) 0 } }, 
00392     { 0, { { { (1<<MACH_BASE), 0 } } } }  },
00393 /* cbit: carry bit */
00394   { "cbit", IP2K_OPERAND_CBIT, HW_H_CBIT, 0, 0,
00395     { 0, { (const PTR) 0 } }, 
00396     { 0, { { { (1<<MACH_BASE), 0 } } } }  },
00397 /* dcbit: digit carry bit */
00398   { "dcbit", IP2K_OPERAND_DCBIT, HW_H_DCBIT, 0, 0,
00399     { 0, { (const PTR) 0 } }, 
00400     { 0, { { { (1<<MACH_BASE), 0 } } } }  },
00401 /* sentinel */
00402   { 0, 0, 0, 0, 0,
00403     { 0, { (const PTR) 0 } },
00404     { 0, { { { (1<<MACH_BASE), 0 } } } } }
00405 };
00406 
00407 #undef A
00408 
00409 
00410 /* The instruction table.  */
00411 
00412 #define OP(field) CGEN_SYNTAX_MAKE_FIELD (OPERAND (field))
00413 #if defined (__STDC__) || defined (ALMOST_STDC) || defined (HAVE_STRINGIZE)
00414 #define A(a) (1 << CGEN_INSN_##a)
00415 #else
00416 #define A(a) (1 << CGEN_INSN_a)
00417 #endif
00418 
00419 static const CGEN_IBASE ip2k_cgen_insn_table[MAX_INSNS] =
00420 {
00421   /* Special null first entry.
00422      A `num' value of zero is thus invalid.
00423      Also, the special `invalid' insn resides here.  */
00424   { 0, 0, 0, 0, { 0, { { { (1<<MACH_BASE), 0 } } } } },
00425 /* jmp $addr16cjp */
00426   {
00427     IP2K_INSN_JMP, "jmp", "jmp", 16,
00428     { 0|A(UNCOND_CTI), { { { (1<<MACH_BASE), 0 } } } }
00429   },
00430 /* call $addr16cjp */
00431   {
00432     IP2K_INSN_CALL, "call", "call", 16,
00433     { 0|A(UNCOND_CTI), { { { (1<<MACH_BASE), 0 } } } }
00434   },
00435 /* sb $fr,$bitno */
00436   {
00437     IP2K_INSN_SB, "sb", "sb", 16,
00438     { 0|A(SKIP_CTI), { { { (1<<MACH_BASE), 0 } } } }
00439   },
00440 /* snb $fr,$bitno */
00441   {
00442     IP2K_INSN_SNB, "snb", "snb", 16,
00443     { 0|A(SKIP_CTI), { { { (1<<MACH_BASE), 0 } } } }
00444   },
00445 /* setb $fr,$bitno */
00446   {
00447     IP2K_INSN_SETB, "setb", "setb", 16,
00448     { 0, { { { (1<<MACH_BASE), 0 } } } }
00449   },
00450 /* clrb $fr,$bitno */
00451   {
00452     IP2K_INSN_CLRB, "clrb", "clrb", 16,
00453     { 0, { { { (1<<MACH_BASE), 0 } } } }
00454   },
00455 /* xor W,#$lit8 */
00456   {
00457     IP2K_INSN_XORW_L, "xorw_l", "xor", 16,
00458     { 0, { { { (1<<MACH_BASE), 0 } } } }
00459   },
00460 /* and W,#$lit8 */
00461   {
00462     IP2K_INSN_ANDW_L, "andw_l", "and", 16,
00463     { 0, { { { (1<<MACH_BASE), 0 } } } }
00464   },
00465 /* or W,#$lit8 */
00466   {
00467     IP2K_INSN_ORW_L, "orw_l", "or", 16,
00468     { 0, { { { (1<<MACH_BASE), 0 } } } }
00469   },
00470 /* add W,#$lit8 */
00471   {
00472     IP2K_INSN_ADDW_L, "addw_l", "add", 16,
00473     { 0, { { { (1<<MACH_BASE), 0 } } } }
00474   },
00475 /* sub W,#$lit8 */
00476   {
00477     IP2K_INSN_SUBW_L, "subw_l", "sub", 16,
00478     { 0, { { { (1<<MACH_BASE), 0 } } } }
00479   },
00480 /* cmp W,#$lit8 */
00481   {
00482     IP2K_INSN_CMPW_L, "cmpw_l", "cmp", 16,
00483     { 0, { { { (1<<MACH_BASE), 0 } } } }
00484   },
00485 /* retw #$lit8 */
00486   {
00487     IP2K_INSN_RETW_L, "retw_l", "retw", 16,
00488     { 0|A(UNCOND_CTI), { { { (1<<MACH_BASE), 0 } } } }
00489   },
00490 /* cse W,#$lit8 */
00491   {
00492     IP2K_INSN_CSEW_L, "csew_l", "cse", 16,
00493     { 0|A(SKIP_CTI), { { { (1<<MACH_BASE), 0 } } } }
00494   },
00495 /* csne W,#$lit8 */
00496   {
00497     IP2K_INSN_CSNEW_L, "csnew_l", "csne", 16,
00498     { 0|A(SKIP_CTI), { { { (1<<MACH_BASE), 0 } } } }
00499   },
00500 /* push #$lit8 */
00501   {
00502     IP2K_INSN_PUSH_L, "push_l", "push", 16,
00503     { 0, { { { (1<<MACH_BASE), 0 } } } }
00504   },
00505 /* muls W,#$lit8 */
00506   {
00507     IP2K_INSN_MULSW_L, "mulsw_l", "muls", 16,
00508     { 0, { { { (1<<MACH_BASE), 0 } } } }
00509   },
00510 /* mulu W,#$lit8 */
00511   {
00512     IP2K_INSN_MULUW_L, "muluw_l", "mulu", 16,
00513     { 0, { { { (1<<MACH_BASE), 0 } } } }
00514   },
00515 /* loadl #$lit8 */
00516   {
00517     IP2K_INSN_LOADL_L, "loadl_l", "loadl", 16,
00518     { 0|A(EXT_SKIP_INSN), { { { (1<<MACH_BASE), 0 } } } }
00519   },
00520 /* loadh #$lit8 */
00521   {
00522     IP2K_INSN_LOADH_L, "loadh_l", "loadh", 16,
00523     { 0|A(EXT_SKIP_INSN), { { { (1<<MACH_BASE), 0 } } } }
00524   },
00525 /* loadl $addr16l */
00526   {
00527     IP2K_INSN_LOADL_A, "loadl_a", "loadl", 16,
00528     { 0|A(EXT_SKIP_INSN), { { { (1<<MACH_BASE), 0 } } } }
00529   },
00530 /* loadh $addr16h */
00531   {
00532     IP2K_INSN_LOADH_A, "loadh_a", "loadh", 16,
00533     { 0|A(EXT_SKIP_INSN), { { { (1<<MACH_BASE), 0 } } } }
00534   },
00535 /* addc $fr,W */
00536   {
00537     IP2K_INSN_ADDCFR_W, "addcfr_w", "addc", 16,
00538     { 0, { { { (1<<MACH_BASE), 0 } } } }
00539   },
00540 /* addc W,$fr */
00541   {
00542     IP2K_INSN_ADDCW_FR, "addcw_fr", "addc", 16,
00543     { 0, { { { (1<<MACH_BASE), 0 } } } }
00544   },
00545 /* incsnz $fr */
00546   {
00547     IP2K_INSN_INCSNZ_FR, "incsnz_fr", "incsnz", 16,
00548     { 0|A(SKIP_CTI), { { { (1<<MACH_BASE), 0 } } } }
00549   },
00550 /* incsnz W,$fr */
00551   {
00552     IP2K_INSN_INCSNZW_FR, "incsnzw_fr", "incsnz", 16,
00553     { 0|A(SKIP_CTI), { { { (1<<MACH_BASE), 0 } } } }
00554   },
00555 /* muls W,$fr */
00556   {
00557     IP2K_INSN_MULSW_FR, "mulsw_fr", "muls", 16,
00558     { 0, { { { (1<<MACH_BASE), 0 } } } }
00559   },
00560 /* mulu W,$fr */
00561   {
00562     IP2K_INSN_MULUW_FR, "muluw_fr", "mulu", 16,
00563     { 0, { { { (1<<MACH_BASE), 0 } } } }
00564   },
00565 /* decsnz $fr */
00566   {
00567     IP2K_INSN_DECSNZ_FR, "decsnz_fr", "decsnz", 16,
00568     { 0|A(SKIP_CTI), { { { (1<<MACH_BASE), 0 } } } }
00569   },
00570 /* decsnz W,$fr */
00571   {
00572     IP2K_INSN_DECSNZW_FR, "decsnzw_fr", "decsnz", 16,
00573     { 0|A(SKIP_CTI), { { { (1<<MACH_BASE), 0 } } } }
00574   },
00575 /* subc W,$fr */
00576   {
00577     IP2K_INSN_SUBCW_FR, "subcw_fr", "subc", 16,
00578     { 0, { { { (1<<MACH_BASE), 0 } } } }
00579   },
00580 /* subc $fr,W */
00581   {
00582     IP2K_INSN_SUBCFR_W, "subcfr_w", "subc", 16,
00583     { 0, { { { (1<<MACH_BASE), 0 } } } }
00584   },
00585 /* pop $fr */
00586   {
00587     IP2K_INSN_POP_FR, "pop_fr", "pop", 16,
00588     { 0, { { { (1<<MACH_BASE), 0 } } } }
00589   },
00590 /* push $fr */
00591   {
00592     IP2K_INSN_PUSH_FR, "push_fr", "push", 16,
00593     { 0, { { { (1<<MACH_BASE), 0 } } } }
00594   },
00595 /* cse W,$fr */
00596   {
00597     IP2K_INSN_CSEW_FR, "csew_fr", "cse", 16,
00598     { 0|A(SKIP_CTI), { { { (1<<MACH_BASE), 0 } } } }
00599   },
00600 /* csne W,$fr */
00601   {
00602     IP2K_INSN_CSNEW_FR, "csnew_fr", "csne", 16,
00603     { 0|A(SKIP_CTI), { { { (1<<MACH_BASE), 0 } } } }
00604   },
00605 /* incsz $fr */
00606   {
00607     IP2K_INSN_INCSZ_FR, "incsz_fr", "incsz", 16,
00608     { 0|A(SKIP_CTI), { { { (1<<MACH_BASE), 0 } } } }
00609   },
00610 /* incsz W,$fr */
00611   {
00612     IP2K_INSN_INCSZW_FR, "incszw_fr", "incsz", 16,
00613     { 0|A(SKIP_CTI), { { { (1<<MACH_BASE), 0 } } } }
00614   },
00615 /* swap $fr */
00616   {
00617     IP2K_INSN_SWAP_FR, "swap_fr", "swap", 16,
00618     { 0, { { { (1<<MACH_BASE), 0 } } } }
00619   },
00620 /* swap W,$fr */
00621   {
00622     IP2K_INSN_SWAPW_FR, "swapw_fr", "swap", 16,
00623     { 0, { { { (1<<MACH_BASE), 0 } } } }
00624   },
00625 /* rl $fr */
00626   {
00627     IP2K_INSN_RL_FR, "rl_fr", "rl", 16,
00628     { 0, { { { (1<<MACH_BASE), 0 } } } }
00629   },
00630 /* rl W,$fr */
00631   {
00632     IP2K_INSN_RLW_FR, "rlw_fr", "rl", 16,
00633     { 0, { { { (1<<MACH_BASE), 0 } } } }
00634   },
00635 /* rr $fr */
00636   {
00637     IP2K_INSN_RR_FR, "rr_fr", "rr", 16,
00638     { 0, { { { (1<<MACH_BASE), 0 } } } }
00639   },
00640 /* rr W,$fr */
00641   {
00642     IP2K_INSN_RRW_FR, "rrw_fr", "rr", 16,
00643     { 0, { { { (1<<MACH_BASE), 0 } } } }
00644   },
00645 /* decsz $fr */
00646   {
00647     IP2K_INSN_DECSZ_FR, "decsz_fr", "decsz", 16,
00648     { 0|A(SKIP_CTI), { { { (1<<MACH_BASE), 0 } } } }
00649   },
00650 /* decsz W,$fr */
00651   {
00652     IP2K_INSN_DECSZW_FR, "decszw_fr", "decsz", 16,
00653     { 0|A(SKIP_CTI), { { { (1<<MACH_BASE), 0 } } } }
00654   },
00655 /* inc $fr */
00656   {
00657     IP2K_INSN_INC_FR, "inc_fr", "inc", 16,
00658     { 0, { { { (1<<MACH_BASE), 0 } } } }
00659   },
00660 /* inc W,$fr */
00661   {
00662     IP2K_INSN_INCW_FR, "incw_fr", "inc", 16,
00663     { 0, { { { (1<<MACH_BASE), 0 } } } }
00664   },
00665 /* not $fr */
00666   {
00667     IP2K_INSN_NOT_FR, "not_fr", "not", 16,
00668     { 0, { { { (1<<MACH_BASE), 0 } } } }
00669   },
00670 /* not W,$fr */
00671   {
00672     IP2K_INSN_NOTW_FR, "notw_fr", "not", 16,
00673     { 0, { { { (1<<MACH_BASE), 0 } } } }
00674   },
00675 /* test $fr */
00676   {
00677     IP2K_INSN_TEST_FR, "test_fr", "test", 16,
00678     { 0, { { { (1<<MACH_BASE), 0 } } } }
00679   },
00680 /* mov W,#$lit8 */
00681   {
00682     IP2K_INSN_MOVW_L, "movw_l", "mov", 16,
00683     { 0, { { { (1<<MACH_BASE), 0 } } } }
00684   },
00685 /* mov $fr,W */
00686   {
00687     IP2K_INSN_MOVFR_W, "movfr_w", "mov", 16,
00688     { 0, { { { (1<<MACH_BASE), 0 } } } }
00689   },
00690 /* mov W,$fr */
00691   {
00692     IP2K_INSN_MOVW_FR, "movw_fr", "mov", 16,
00693     { 0, { { { (1<<MACH_BASE), 0 } } } }
00694   },
00695 /* add $fr,W */
00696   {
00697     IP2K_INSN_ADDFR_W, "addfr_w", "add", 16,
00698     { 0, { { { (1<<MACH_BASE), 0 } } } }
00699   },
00700 /* add W,$fr */
00701   {
00702     IP2K_INSN_ADDW_FR, "addw_fr", "add", 16,
00703     { 0, { { { (1<<MACH_BASE), 0 } } } }
00704   },
00705 /* xor $fr,W */
00706   {
00707     IP2K_INSN_XORFR_W, "xorfr_w", "xor", 16,
00708     { 0, { { { (1<<MACH_BASE), 0 } } } }
00709   },
00710 /* xor W,$fr */
00711   {
00712     IP2K_INSN_XORW_FR, "xorw_fr", "xor", 16,
00713     { 0, { { { (1<<MACH_BASE), 0 } } } }
00714   },
00715 /* and $fr,W */
00716   {
00717     IP2K_INSN_ANDFR_W, "andfr_w", "and", 16,
00718     { 0, { { { (1<<MACH_BASE), 0 } } } }
00719   },
00720 /* and W,$fr */
00721   {
00722     IP2K_INSN_ANDW_FR, "andw_fr", "and", 16,
00723     { 0, { { { (1<<MACH_BASE), 0 } } } }
00724   },
00725 /* or $fr,W */
00726   {
00727     IP2K_INSN_ORFR_W, "orfr_w", "or", 16,
00728     { 0, { { { (1<<MACH_BASE), 0 } } } }
00729   },
00730 /* or W,$fr */
00731   {
00732     IP2K_INSN_ORW_FR, "orw_fr", "or", 16,
00733     { 0, { { { (1<<MACH_BASE), 0 } } } }
00734   },
00735 /* dec $fr */
00736   {
00737     IP2K_INSN_DEC_FR, "dec_fr", "dec", 16,
00738     { 0, { { { (1<<MACH_BASE), 0 } } } }
00739   },
00740 /* dec W,$fr */
00741   {
00742     IP2K_INSN_DECW_FR, "decw_fr", "dec", 16,
00743     { 0, { { { (1<<MACH_BASE), 0 } } } }
00744   },
00745 /* sub $fr,W */
00746   {
00747     IP2K_INSN_SUBFR_W, "subfr_w", "sub", 16,
00748     { 0, { { { (1<<MACH_BASE), 0 } } } }
00749   },
00750 /* sub W,$fr */
00751   {
00752     IP2K_INSN_SUBW_FR, "subw_fr", "sub", 16,
00753     { 0, { { { (1<<MACH_BASE), 0 } } } }
00754   },
00755 /* clr $fr */
00756   {
00757     IP2K_INSN_CLR_FR, "clr_fr", "clr", 16,
00758     { 0, { { { (1<<MACH_BASE), 0 } } } }
00759   },
00760 /* cmp W,$fr */
00761   {
00762     IP2K_INSN_CMPW_FR, "cmpw_fr", "cmp", 16,
00763     { 0, { { { (1<<MACH_BASE), 0 } } } }
00764   },
00765 /* speed #$lit8 */
00766   {
00767     IP2K_INSN_SPEED, "speed", "speed", 16,
00768     { 0, { { { (1<<MACH_BASE), 0 } } } }
00769   },
00770 /* ireadi */
00771   {
00772     IP2K_INSN_IREADI, "ireadi", "ireadi", 16,
00773     { 0, { { { (1<<MACH_BASE), 0 } } } }
00774   },
00775 /* iwritei */
00776   {
00777     IP2K_INSN_IWRITEI, "iwritei", "iwritei", 16,
00778     { 0, { { { (1<<MACH_BASE), 0 } } } }
00779   },
00780 /* fread */
00781   {
00782     IP2K_INSN_FREAD, "fread", "fread", 16,
00783     { 0, { { { (1<<MACH_BASE), 0 } } } }
00784   },
00785 /* fwrite */
00786   {
00787     IP2K_INSN_FWRITE, "fwrite", "fwrite", 16,
00788     { 0, { { { (1<<MACH_BASE), 0 } } } }
00789   },
00790 /* iread */
00791   {
00792     IP2K_INSN_IREAD, "iread", "iread", 16,
00793     { 0, { { { (1<<MACH_BASE), 0 } } } }
00794   },
00795 /* iwrite */
00796   {
00797     IP2K_INSN_IWRITE, "iwrite", "iwrite", 16,
00798     { 0, { { { (1<<MACH_BASE), 0 } } } }
00799   },
00800 /* page $addr16p */
00801   {
00802     IP2K_INSN_PAGE, "page", "page", 16,
00803     { 0|A(EXT_SKIP_INSN), { { { (1<<MACH_BASE), 0 } } } }
00804   },
00805 /* system */
00806   {
00807     IP2K_INSN_SYSTEM, "system", "system", 16,
00808     { 0, { { { (1<<MACH_BASE), 0 } } } }
00809   },
00810 /* reti #$reti3 */
00811   {
00812     IP2K_INSN_RETI, "reti", "reti", 16,
00813     { 0, { { { (1<<MACH_BASE), 0 } } } }
00814   },
00815 /* ret */
00816   {
00817     IP2K_INSN_RET, "ret", "ret", 16,
00818     { 0|A(UNCOND_CTI), { { { (1<<MACH_BASE), 0 } } } }
00819   },
00820 /* int */
00821   {
00822     IP2K_INSN_INT, "int", "int", 16,
00823     { 0, { { { (1<<MACH_BASE), 0 } } } }
00824   },
00825 /* breakx */
00826   {
00827     IP2K_INSN_BREAKX, "breakx", "breakx", 16,
00828     { 0|A(EXT_SKIP_INSN), { { { (1<<MACH_BASE), 0 } } } }
00829   },
00830 /* cwdt */
00831   {
00832     IP2K_INSN_CWDT, "cwdt", "cwdt", 16,
00833     { 0, { { { (1<<MACH_BASE), 0 } } } }
00834   },
00835 /* ferase */
00836   {
00837     IP2K_INSN_FERASE, "ferase", "ferase", 16,
00838     { 0, { { { (1<<MACH_BASE), 0 } } } }
00839   },
00840 /* retnp */
00841   {
00842     IP2K_INSN_RETNP, "retnp", "retnp", 16,
00843     { 0|A(UNCOND_CTI), { { { (1<<MACH_BASE), 0 } } } }
00844   },
00845 /* break */
00846   {
00847     IP2K_INSN_BREAK, "break", "break", 16,
00848     { 0, { { { (1<<MACH_BASE), 0 } } } }
00849   },
00850 /* nop */
00851   {
00852     IP2K_INSN_NOP, "nop", "nop", 16,
00853     { 0, { { { (1<<MACH_BASE), 0 } } } }
00854   },
00855 };
00856 
00857 #undef OP
00858 #undef A
00859 
00860 /* Initialize anything needed to be done once, before any cpu_open call.  */
00861 
00862 static void
00863 init_tables (void)
00864 {
00865 }
00866 
00867 static const CGEN_MACH * lookup_mach_via_bfd_name (const CGEN_MACH *, const char *);
00868 static void build_hw_table      (CGEN_CPU_TABLE *);
00869 static void build_ifield_table  (CGEN_CPU_TABLE *);
00870 static void build_operand_table (CGEN_CPU_TABLE *);
00871 static void build_insn_table    (CGEN_CPU_TABLE *);
00872 static void ip2k_cgen_rebuild_tables (CGEN_CPU_TABLE *);
00873 
00874 /* Subroutine of ip2k_cgen_cpu_open to look up a mach via its bfd name.  */
00875 
00876 static const CGEN_MACH *
00877 lookup_mach_via_bfd_name (const CGEN_MACH *table, const char *name)
00878 {
00879   while (table->name)
00880     {
00881       if (strcmp (name, table->bfd_name) == 0)
00882        return table;
00883       ++table;
00884     }
00885   abort ();
00886 }
00887 
00888 /* Subroutine of ip2k_cgen_cpu_open to build the hardware table.  */
00889 
00890 static void
00891 build_hw_table (CGEN_CPU_TABLE *cd)
00892 {
00893   int i;
00894   int machs = cd->machs;
00895   const CGEN_HW_ENTRY *init = & ip2k_cgen_hw_table[0];
00896   /* MAX_HW is only an upper bound on the number of selected entries.
00897      However each entry is indexed by it's enum so there can be holes in
00898      the table.  */
00899   const CGEN_HW_ENTRY **selected =
00900     (const CGEN_HW_ENTRY **) xmalloc (MAX_HW * sizeof (CGEN_HW_ENTRY *));
00901 
00902   cd->hw_table.init_entries = init;
00903   cd->hw_table.entry_size = sizeof (CGEN_HW_ENTRY);
00904   memset (selected, 0, MAX_HW * sizeof (CGEN_HW_ENTRY *));
00905   /* ??? For now we just use machs to determine which ones we want.  */
00906   for (i = 0; init[i].name != NULL; ++i)
00907     if (CGEN_HW_ATTR_VALUE (&init[i], CGEN_HW_MACH)
00908        & machs)
00909       selected[init[i].type] = &init[i];
00910   cd->hw_table.entries = selected;
00911   cd->hw_table.num_entries = MAX_HW;
00912 }
00913 
00914 /* Subroutine of ip2k_cgen_cpu_open to build the hardware table.  */
00915 
00916 static void
00917 build_ifield_table (CGEN_CPU_TABLE *cd)
00918 {
00919   cd->ifld_table = & ip2k_cgen_ifld_table[0];
00920 }
00921 
00922 /* Subroutine of ip2k_cgen_cpu_open to build the hardware table.  */
00923 
00924 static void
00925 build_operand_table (CGEN_CPU_TABLE *cd)
00926 {
00927   int i;
00928   int machs = cd->machs;
00929   const CGEN_OPERAND *init = & ip2k_cgen_operand_table[0];
00930   /* MAX_OPERANDS is only an upper bound on the number of selected entries.
00931      However each entry is indexed by it's enum so there can be holes in
00932      the table.  */
00933   const CGEN_OPERAND **selected = xmalloc (MAX_OPERANDS * sizeof (* selected));
00934 
00935   cd->operand_table.init_entries = init;
00936   cd->operand_table.entry_size = sizeof (CGEN_OPERAND);
00937   memset (selected, 0, MAX_OPERANDS * sizeof (CGEN_OPERAND *));
00938   /* ??? For now we just use mach to determine which ones we want.  */
00939   for (i = 0; init[i].name != NULL; ++i)
00940     if (CGEN_OPERAND_ATTR_VALUE (&init[i], CGEN_OPERAND_MACH)
00941        & machs)
00942       selected[init[i].type] = &init[i];
00943   cd->operand_table.entries = selected;
00944   cd->operand_table.num_entries = MAX_OPERANDS;
00945 }
00946 
00947 /* Subroutine of ip2k_cgen_cpu_open to build the hardware table.
00948    ??? This could leave out insns not supported by the specified mach/isa,
00949    but that would cause errors like "foo only supported by bar" to become
00950    "unknown insn", so for now we include all insns and require the app to
00951    do the checking later.
00952    ??? On the other hand, parsing of such insns may require their hardware or
00953    operand elements to be in the table [which they mightn't be].  */
00954 
00955 static void
00956 build_insn_table (CGEN_CPU_TABLE *cd)
00957 {
00958   int i;
00959   const CGEN_IBASE *ib = & ip2k_cgen_insn_table[0];
00960   CGEN_INSN *insns = xmalloc (MAX_INSNS * sizeof (CGEN_INSN));
00961 
00962   memset (insns, 0, MAX_INSNS * sizeof (CGEN_INSN));
00963   for (i = 0; i < MAX_INSNS; ++i)
00964     insns[i].base = &ib[i];
00965   cd->insn_table.init_entries = insns;
00966   cd->insn_table.entry_size = sizeof (CGEN_IBASE);
00967   cd->insn_table.num_init_entries = MAX_INSNS;
00968 }
00969 
00970 /* Subroutine of ip2k_cgen_cpu_open to rebuild the tables.  */
00971 
00972 static void
00973 ip2k_cgen_rebuild_tables (CGEN_CPU_TABLE *cd)
00974 {
00975   int i;
00976   CGEN_BITSET *isas = cd->isas;
00977   unsigned int machs = cd->machs;
00978 
00979   cd->int_insn_p = CGEN_INT_INSN_P;
00980 
00981   /* Data derived from the isa spec.  */
00982 #define UNSET (CGEN_SIZE_UNKNOWN + 1)
00983   cd->default_insn_bitsize = UNSET;
00984   cd->base_insn_bitsize = UNSET;
00985   cd->min_insn_bitsize = 65535; /* Some ridiculously big number.  */
00986   cd->max_insn_bitsize = 0;
00987   for (i = 0; i < MAX_ISAS; ++i)
00988     if (cgen_bitset_contains (isas, i))
00989       {
00990        const CGEN_ISA *isa = & ip2k_cgen_isa_table[i];
00991 
00992        /* Default insn sizes of all selected isas must be
00993           equal or we set the result to 0, meaning "unknown".  */
00994        if (cd->default_insn_bitsize == UNSET)
00995          cd->default_insn_bitsize = isa->default_insn_bitsize;
00996        else if (isa->default_insn_bitsize == cd->default_insn_bitsize)
00997          ; /* This is ok.  */
00998        else
00999          cd->default_insn_bitsize = CGEN_SIZE_UNKNOWN;
01000 
01001        /* Base insn sizes of all selected isas must be equal
01002           or we set the result to 0, meaning "unknown".  */
01003        if (cd->base_insn_bitsize == UNSET)
01004          cd->base_insn_bitsize = isa->base_insn_bitsize;
01005        else if (isa->base_insn_bitsize == cd->base_insn_bitsize)
01006          ; /* This is ok.  */
01007        else
01008          cd->base_insn_bitsize = CGEN_SIZE_UNKNOWN;
01009 
01010        /* Set min,max insn sizes.  */
01011        if (isa->min_insn_bitsize < cd->min_insn_bitsize)
01012          cd->min_insn_bitsize = isa->min_insn_bitsize;
01013        if (isa->max_insn_bitsize > cd->max_insn_bitsize)
01014          cd->max_insn_bitsize = isa->max_insn_bitsize;
01015       }
01016 
01017   /* Data derived from the mach spec.  */
01018   for (i = 0; i < MAX_MACHS; ++i)
01019     if (((1 << i) & machs) != 0)
01020       {
01021        const CGEN_MACH *mach = & ip2k_cgen_mach_table[i];
01022 
01023        if (mach->insn_chunk_bitsize != 0)
01024        {
01025          if (cd->insn_chunk_bitsize != 0 && cd->insn_chunk_bitsize != mach->insn_chunk_bitsize)
01026            {
01027              fprintf (stderr, "ip2k_cgen_rebuild_tables: conflicting insn-chunk-bitsize values: `%d' vs. `%d'\n",
01028                      cd->insn_chunk_bitsize, mach->insn_chunk_bitsize);
01029              abort ();
01030            }
01031 
01032          cd->insn_chunk_bitsize = mach->insn_chunk_bitsize;
01033        }
01034       }
01035 
01036   /* Determine which hw elements are used by MACH.  */
01037   build_hw_table (cd);
01038 
01039   /* Build the ifield table.  */
01040   build_ifield_table (cd);
01041 
01042   /* Determine which operands are used by MACH/ISA.  */
01043   build_operand_table (cd);
01044 
01045   /* Build the instruction table.  */
01046   build_insn_table (cd);
01047 }
01048 
01049 /* Initialize a cpu table and return a descriptor.
01050    It's much like opening a file, and must be the first function called.
01051    The arguments are a set of (type/value) pairs, terminated with
01052    CGEN_CPU_OPEN_END.
01053 
01054    Currently supported values:
01055    CGEN_CPU_OPEN_ISAS:    bitmap of values in enum isa_attr
01056    CGEN_CPU_OPEN_MACHS:   bitmap of values in enum mach_attr
01057    CGEN_CPU_OPEN_BFDMACH: specify 1 mach using bfd name
01058    CGEN_CPU_OPEN_ENDIAN:  specify endian choice
01059    CGEN_CPU_OPEN_END:     terminates arguments
01060 
01061    ??? Simultaneous multiple isas might not make sense, but it's not (yet)
01062    precluded.
01063 
01064    ??? We only support ISO C stdargs here, not K&R.
01065    Laziness, plus experiment to see if anything requires K&R - eventually
01066    K&R will no longer be supported - e.g. GDB is currently trying this.  */
01067 
01068 CGEN_CPU_DESC
01069 ip2k_cgen_cpu_open (enum cgen_cpu_open_arg arg_type, ...)
01070 {
01071   CGEN_CPU_TABLE *cd = (CGEN_CPU_TABLE *) xmalloc (sizeof (CGEN_CPU_TABLE));
01072   static int init_p;
01073   CGEN_BITSET *isas = 0;  /* 0 = "unspecified" */
01074   unsigned int machs = 0; /* 0 = "unspecified" */
01075   enum cgen_endian endian = CGEN_ENDIAN_UNKNOWN;
01076   va_list ap;
01077 
01078   if (! init_p)
01079     {
01080       init_tables ();
01081       init_p = 1;
01082     }
01083 
01084   memset (cd, 0, sizeof (*cd));
01085 
01086   va_start (ap, arg_type);
01087   while (arg_type != CGEN_CPU_OPEN_END)
01088     {
01089       switch (arg_type)
01090        {
01091        case CGEN_CPU_OPEN_ISAS :
01092          isas = va_arg (ap, CGEN_BITSET *);
01093          break;
01094        case CGEN_CPU_OPEN_MACHS :
01095          machs = va_arg (ap, unsigned int);
01096          break;
01097        case CGEN_CPU_OPEN_BFDMACH :
01098          {
01099            const char *name = va_arg (ap, const char *);
01100            const CGEN_MACH *mach =
01101              lookup_mach_via_bfd_name (ip2k_cgen_mach_table, name);
01102 
01103            machs |= 1 << mach->num;
01104            break;
01105          }
01106        case CGEN_CPU_OPEN_ENDIAN :
01107          endian = va_arg (ap, enum cgen_endian);
01108          break;
01109        default :
01110          fprintf (stderr, "ip2k_cgen_cpu_open: unsupported argument `%d'\n",
01111                  arg_type);
01112          abort (); /* ??? return NULL? */
01113        }
01114       arg_type = va_arg (ap, enum cgen_cpu_open_arg);
01115     }
01116   va_end (ap);
01117 
01118   /* Mach unspecified means "all".  */
01119   if (machs == 0)
01120     machs = (1 << MAX_MACHS) - 1;
01121   /* Base mach is always selected.  */
01122   machs |= 1;
01123   if (endian == CGEN_ENDIAN_UNKNOWN)
01124     {
01125       /* ??? If target has only one, could have a default.  */
01126       fprintf (stderr, "ip2k_cgen_cpu_open: no endianness specified\n");
01127       abort ();
01128     }
01129 
01130   cd->isas = cgen_bitset_copy (isas);
01131   cd->machs = machs;
01132   cd->endian = endian;
01133   /* FIXME: for the sparc case we can determine insn-endianness statically.
01134      The worry here is where both data and insn endian can be independently
01135      chosen, in which case this function will need another argument.
01136      Actually, will want to allow for more arguments in the future anyway.  */
01137   cd->insn_endian = endian;
01138 
01139   /* Table (re)builder.  */
01140   cd->rebuild_tables = ip2k_cgen_rebuild_tables;
01141   ip2k_cgen_rebuild_tables (cd);
01142 
01143   /* Default to not allowing signed overflow.  */
01144   cd->signed_overflow_ok_p = 0;
01145   
01146   return (CGEN_CPU_DESC) cd;
01147 }
01148 
01149 /* Cover fn to ip2k_cgen_cpu_open to handle the simple case of 1 isa, 1 mach.
01150    MACH_NAME is the bfd name of the mach.  */
01151 
01152 CGEN_CPU_DESC
01153 ip2k_cgen_cpu_open_1 (const char *mach_name, enum cgen_endian endian)
01154 {
01155   return ip2k_cgen_cpu_open (CGEN_CPU_OPEN_BFDMACH, mach_name,
01156                             CGEN_CPU_OPEN_ENDIAN, endian,
01157                             CGEN_CPU_OPEN_END);
01158 }
01159 
01160 /* Close a cpu table.
01161    ??? This can live in a machine independent file, but there's currently
01162    no place to put this file (there's no libcgen).  libopcodes is the wrong
01163    place as some simulator ports use this but they don't use libopcodes.  */
01164 
01165 void
01166 ip2k_cgen_cpu_close (CGEN_CPU_DESC cd)
01167 {
01168   unsigned int i;
01169   const CGEN_INSN *insns;
01170 
01171   if (cd->macro_insn_table.init_entries)
01172     {
01173       insns = cd->macro_insn_table.init_entries;
01174       for (i = 0; i < cd->macro_insn_table.num_init_entries; ++i, ++insns)
01175        if (CGEN_INSN_RX ((insns)))
01176          regfree (CGEN_INSN_RX (insns));
01177     }
01178 
01179   if (cd->insn_table.init_entries)
01180     {
01181       insns = cd->insn_table.init_entries;
01182       for (i = 0; i < cd->insn_table.num_init_entries; ++i, ++insns)
01183        if (CGEN_INSN_RX (insns))
01184          regfree (CGEN_INSN_RX (insns));
01185     }  
01186 
01187   if (cd->macro_insn_table.init_entries)
01188     free ((CGEN_INSN *) cd->macro_insn_table.init_entries);
01189 
01190   if (cd->insn_table.init_entries)
01191     free ((CGEN_INSN *) cd->insn_table.init_entries);
01192 
01193   if (cd->hw_table.entries)
01194     free ((CGEN_HW_ENTRY *) cd->hw_table.entries);
01195 
01196   if (cd->operand_table.entries)
01197     free ((CGEN_HW_ENTRY *) cd->operand_table.entries);
01198 
01199   free (cd);
01200 }
01201