Home | History | Annotate | Line # | Download | only in opcodes
ip2k-desc.c revision 1.1
      1 /* CPU data for ip2k.
      2 
      3 THIS FILE IS MACHINE GENERATED WITH CGEN.
      4 
      5 Copyright 1996-2007 Free Software Foundation, Inc.
      6 
      7 This file is part of the GNU Binutils and/or GDB, the GNU debugger.
      8 
      9    This file is free software; you can redistribute it and/or modify
     10    it under the terms of the GNU General Public License as published by
     11    the Free Software Foundation; either version 3, or (at your option)
     12    any later version.
     13 
     14    It is distributed in the hope that it will be useful, but WITHOUT
     15    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
     16    or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
     17    License for more details.
     18 
     19    You should have received a copy of the GNU General Public License along
     20    with this program; if not, write to the Free Software Foundation, Inc.,
     21    51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
     22 
     23 */
     24 
     25 #include "sysdep.h"
     26 #include <stdio.h>
     27 #include <stdarg.h>
     28 #include "ansidecl.h"
     29 #include "bfd.h"
     30 #include "symcat.h"
     31 #include "ip2k-desc.h"
     32 #include "ip2k-opc.h"
     33 #include "opintl.h"
     34 #include "libiberty.h"
     35 #include "xregex.h"
     36 
     37 /* Attributes.  */
     38 
     39 static const CGEN_ATTR_ENTRY bool_attr[] =
     40 {
     41   { "#f", 0 },
     42   { "#t", 1 },
     43   { 0, 0 }
     44 };
     45 
     46 static const CGEN_ATTR_ENTRY MACH_attr[] ATTRIBUTE_UNUSED =
     47 {
     48   { "base", MACH_BASE },
     49   { "ip2022", MACH_IP2022 },
     50   { "ip2022ext", MACH_IP2022EXT },
     51   { "max", MACH_MAX },
     52   { 0, 0 }
     53 };
     54 
     55 static const CGEN_ATTR_ENTRY ISA_attr[] ATTRIBUTE_UNUSED =
     56 {
     57   { "ip2k", ISA_IP2K },
     58   { "max", ISA_MAX },
     59   { 0, 0 }
     60 };
     61 
     62 const CGEN_ATTR_TABLE ip2k_cgen_ifield_attr_table[] =
     63 {
     64   { "MACH", & MACH_attr[0], & MACH_attr[0] },
     65   { "VIRTUAL", &bool_attr[0], &bool_attr[0] },
     66   { "PCREL-ADDR", &bool_attr[0], &bool_attr[0] },
     67   { "ABS-ADDR", &bool_attr[0], &bool_attr[0] },
     68   { "RESERVED", &bool_attr[0], &bool_attr[0] },
     69   { "SIGN-OPT", &bool_attr[0], &bool_attr[0] },
     70   { "SIGNED", &bool_attr[0], &bool_attr[0] },
     71   { 0, 0, 0 }
     72 };
     73 
     74 const CGEN_ATTR_TABLE ip2k_cgen_hardware_attr_table[] =
     75 {
     76   { "MACH", & MACH_attr[0], & MACH_attr[0] },
     77   { "VIRTUAL", &bool_attr[0], &bool_attr[0] },
     78   { "CACHE-ADDR", &bool_attr[0], &bool_attr[0] },
     79   { "PC", &bool_attr[0], &bool_attr[0] },
     80   { "PROFILE", &bool_attr[0], &bool_attr[0] },
     81   { 0, 0, 0 }
     82 };
     83 
     84 const CGEN_ATTR_TABLE ip2k_cgen_operand_attr_table[] =
     85 {
     86   { "MACH", & MACH_attr[0], & MACH_attr[0] },
     87   { "VIRTUAL", &bool_attr[0], &bool_attr[0] },
     88   { "PCREL-ADDR", &bool_attr[0], &bool_attr[0] },
     89   { "ABS-ADDR", &bool_attr[0], &bool_attr[0] },
     90   { "SIGN-OPT", &bool_attr[0], &bool_attr[0] },
     91   { "SIGNED", &bool_attr[0], &bool_attr[0] },
     92   { "NEGATIVE", &bool_attr[0], &bool_attr[0] },
     93   { "RELAX", &bool_attr[0], &bool_attr[0] },
     94   { "SEM-ONLY", &bool_attr[0], &bool_attr[0] },
     95   { 0, 0, 0 }
     96 };
     97 
     98 const CGEN_ATTR_TABLE ip2k_cgen_insn_attr_table[] =
     99 {
    100   { "MACH", & MACH_attr[0], & MACH_attr[0] },
    101   { "ALIAS", &bool_attr[0], &bool_attr[0] },
    102   { "VIRTUAL", &bool_attr[0], &bool_attr[0] },
    103   { "UNCOND-CTI", &bool_attr[0], &bool_attr[0] },
    104   { "COND-CTI", &bool_attr[0], &bool_attr[0] },
    105   { "SKIP-CTI", &bool_attr[0], &bool_attr[0] },
    106   { "DELAY-SLOT", &bool_attr[0], &bool_attr[0] },
    107   { "RELAXABLE", &bool_attr[0], &bool_attr[0] },
    108   { "RELAXED", &bool_attr[0], &bool_attr[0] },
    109   { "NO-DIS", &bool_attr[0], &bool_attr[0] },
    110   { "PBB", &bool_attr[0], &bool_attr[0] },
    111   { "EXT-SKIP-INSN", &bool_attr[0], &bool_attr[0] },
    112   { "SKIPA", &bool_attr[0], &bool_attr[0] },
    113   { 0, 0, 0 }
    114 };
    115 
    116 /* Instruction set variants.  */
    117 
    118 static const CGEN_ISA ip2k_cgen_isa_table[] = {
    119   { "ip2k", 16, 16, 16, 16 },
    120   { 0, 0, 0, 0, 0 }
    121 };
    122 
    123 /* Machine variants.  */
    124 
    125 static const CGEN_MACH ip2k_cgen_mach_table[] = {
    126   { "ip2022", "ip2022", MACH_IP2022, 0 },
    127   { "ip2022ext", "ip2022ext", MACH_IP2022EXT, 0 },
    128   { 0, 0, 0, 0 }
    129 };
    130 
    131 static CGEN_KEYWORD_ENTRY ip2k_cgen_opval_register_names_entries[] =
    132 {
    133   { "ADDRSEL", 2, {0, {{{0, 0}}}}, 0, 0 },
    134   { "ADDRX", 3, {0, {{{0, 0}}}}, 0, 0 },
    135   { "IPH", 4, {0, {{{0, 0}}}}, 0, 0 },
    136   { "IPL", 5, {0, {{{0, 0}}}}, 0, 0 },
    137   { "SPH", 6, {0, {{{0, 0}}}}, 0, 0 },
    138   { "SPL", 7, {0, {{{0, 0}}}}, 0, 0 },
    139   { "PCH", 8, {0, {{{0, 0}}}}, 0, 0 },
    140   { "PCL", 9, {0, {{{0, 0}}}}, 0, 0 },
    141   { "WREG", 10, {0, {{{0, 0}}}}, 0, 0 },
    142   { "STATUS", 11, {0, {{{0, 0}}}}, 0, 0 },
    143   { "DPH", 12, {0, {{{0, 0}}}}, 0, 0 },
    144   { "DPL", 13, {0, {{{0, 0}}}}, 0, 0 },
    145   { "SPDREG", 14, {0, {{{0, 0}}}}, 0, 0 },
    146   { "MULH", 15, {0, {{{0, 0}}}}, 0, 0 },
    147   { "ADDRH", 16, {0, {{{0, 0}}}}, 0, 0 },
    148   { "ADDRL", 17, {0, {{{0, 0}}}}, 0, 0 },
    149   { "DATAH", 18, {0, {{{0, 0}}}}, 0, 0 },
    150   { "DATAL", 19, {0, {{{0, 0}}}}, 0, 0 },
    151   { "INTVECH", 20, {0, {{{0, 0}}}}, 0, 0 },
    152   { "INTVECL", 21, {0, {{{0, 0}}}}, 0, 0 },
    153   { "INTSPD", 22, {0, {{{0, 0}}}}, 0, 0 },
    154   { "INTF", 23, {0, {{{0, 0}}}}, 0, 0 },
    155   { "INTE", 24, {0, {{{0, 0}}}}, 0, 0 },
    156   { "INTED", 25, {0, {{{0, 0}}}}, 0, 0 },
    157   { "FCFG", 26, {0, {{{0, 0}}}}, 0, 0 },
    158   { "TCTRL", 27, {0, {{{0, 0}}}}, 0, 0 },
    159   { "XCFG", 28, {0, {{{0, 0}}}}, 0, 0 },
    160   { "EMCFG", 29, {0, {{{0, 0}}}}, 0, 0 },
    161   { "IPCH", 30, {0, {{{0, 0}}}}, 0, 0 },
    162   { "IPCL", 31, {0, {{{0, 0}}}}, 0, 0 },
    163   { "RAIN", 32, {0, {{{0, 0}}}}, 0, 0 },
    164   { "RAOUT", 33, {0, {{{0, 0}}}}, 0, 0 },
    165   { "RADIR", 34, {0, {{{0, 0}}}}, 0, 0 },
    166   { "LFSRH", 35, {0, {{{0, 0}}}}, 0, 0 },
    167   { "RBIN", 36, {0, {{{0, 0}}}}, 0, 0 },
    168   { "RBOUT", 37, {0, {{{0, 0}}}}, 0, 0 },
    169   { "RBDIR", 38, {0, {{{0, 0}}}}, 0, 0 },
    170   { "LFSRL", 39, {0, {{{0, 0}}}}, 0, 0 },
    171   { "RCIN", 40, {0, {{{0, 0}}}}, 0, 0 },
    172   { "RCOUT", 41, {0, {{{0, 0}}}}, 0, 0 },
    173   { "RCDIR", 42, {0, {{{0, 0}}}}, 0, 0 },
    174   { "LFSRA", 43, {0, {{{0, 0}}}}, 0, 0 },
    175   { "RDIN", 44, {0, {{{0, 0}}}}, 0, 0 },
    176   { "RDOUT", 45, {0, {{{0, 0}}}}, 0, 0 },
    177   { "RDDIR", 46, {0, {{{0, 0}}}}, 0, 0 },
    178   { "REIN", 48, {0, {{{0, 0}}}}, 0, 0 },
    179   { "REOUT", 49, {0, {{{0, 0}}}}, 0, 0 },
    180   { "REDIR", 50, {0, {{{0, 0}}}}, 0, 0 },
    181   { "RFIN", 52, {0, {{{0, 0}}}}, 0, 0 },
    182   { "RFOUT", 53, {0, {{{0, 0}}}}, 0, 0 },
    183   { "RFDIR", 54, {0, {{{0, 0}}}}, 0, 0 },
    184   { "RGOUT", 57, {0, {{{0, 0}}}}, 0, 0 },
    185   { "RGDIR", 58, {0, {{{0, 0}}}}, 0, 0 },
    186   { "RTTMR", 64, {0, {{{0, 0}}}}, 0, 0 },
    187   { "RTCFG", 65, {0, {{{0, 0}}}}, 0, 0 },
    188   { "T0TMR", 66, {0, {{{0, 0}}}}, 0, 0 },
    189   { "T0CFG", 67, {0, {{{0, 0}}}}, 0, 0 },
    190   { "T1CNTH", 68, {0, {{{0, 0}}}}, 0, 0 },
    191   { "T1CNTL", 69, {0, {{{0, 0}}}}, 0, 0 },
    192   { "T1CAP1H", 70, {0, {{{0, 0}}}}, 0, 0 },
    193   { "T1CAP1L", 71, {0, {{{0, 0}}}}, 0, 0 },
    194   { "T1CAP2H", 72, {0, {{{0, 0}}}}, 0, 0 },
    195   { "T1CMP2H", 72, {0, {{{0, 0}}}}, 0, 0 },
    196   { "T1CAP2L", 73, {0, {{{0, 0}}}}, 0, 0 },
    197   { "T1CMP2L", 73, {0, {{{0, 0}}}}, 0, 0 },
    198   { "T1CMP1H", 74, {0, {{{0, 0}}}}, 0, 0 },
    199   { "T1CMP1L", 75, {0, {{{0, 0}}}}, 0, 0 },
    200   { "T1CFG1H", 76, {0, {{{0, 0}}}}, 0, 0 },
    201   { "T1CFG1L", 77, {0, {{{0, 0}}}}, 0, 0 },
    202   { "T1CFG2H", 78, {0, {{{0, 0}}}}, 0, 0 },
    203   { "T1CFG2L", 79, {0, {{{0, 0}}}}, 0, 0 },
    204   { "ADCH", 80, {0, {{{0, 0}}}}, 0, 0 },
    205   { "ADCL", 81, {0, {{{0, 0}}}}, 0, 0 },
    206   { "ADCCFG", 82, {0, {{{0, 0}}}}, 0, 0 },
    207   { "ADCTMR", 83, {0, {{{0, 0}}}}, 0, 0 },
    208   { "T2CNTH", 84, {0, {{{0, 0}}}}, 0, 0 },
    209   { "T2CNTL", 85, {0, {{{0, 0}}}}, 0, 0 },
    210   { "T2CAP1H", 86, {0, {{{0, 0}}}}, 0, 0 },
    211   { "T2CAP1L", 87, {0, {{{0, 0}}}}, 0, 0 },
    212   { "T2CAP2H", 88, {0, {{{0, 0}}}}, 0, 0 },
    213   { "T2CMP2H", 88, {0, {{{0, 0}}}}, 0, 0 },
    214   { "T2CAP2L", 89, {0, {{{0, 0}}}}, 0, 0 },
    215   { "T2CMP2L", 89, {0, {{{0, 0}}}}, 0, 0 },
    216   { "T2CMP1H", 90, {0, {{{0, 0}}}}, 0, 0 },
    217   { "T2CMP1L", 91, {0, {{{0, 0}}}}, 0, 0 },
    218   { "T2CFG1H", 92, {0, {{{0, 0}}}}, 0, 0 },
    219   { "T2CFG1L", 93, {0, {{{0, 0}}}}, 0, 0 },
    220   { "T2CFG2H", 94, {0, {{{0, 0}}}}, 0, 0 },
    221   { "T2CFG2L", 95, {0, {{{0, 0}}}}, 0, 0 },
    222   { "S1TMRH", 96, {0, {{{0, 0}}}}, 0, 0 },
    223   { "S1TMRL", 97, {0, {{{0, 0}}}}, 0, 0 },
    224   { "S1TBUFH", 98, {0, {{{0, 0}}}}, 0, 0 },
    225   { "S1TBUFL", 99, {0, {{{0, 0}}}}, 0, 0 },
    226   { "S1TCFG", 100, {0, {{{0, 0}}}}, 0, 0 },
    227   { "S1RCNT", 101, {0, {{{0, 0}}}}, 0, 0 },
    228   { "S1RBUFH", 102, {0, {{{0, 0}}}}, 0, 0 },
    229   { "S1RBUFL", 103, {0, {{{0, 0}}}}, 0, 0 },
    230   { "S1RCFG", 104, {0, {{{0, 0}}}}, 0, 0 },
    231   { "S1RSYNC", 105, {0, {{{0, 0}}}}, 0, 0 },
    232   { "S1INTF", 106, {0, {{{0, 0}}}}, 0, 0 },
    233   { "S1INTE", 107, {0, {{{0, 0}}}}, 0, 0 },
    234   { "S1MODE", 108, {0, {{{0, 0}}}}, 0, 0 },
    235   { "S1SMASK", 109, {0, {{{0, 0}}}}, 0, 0 },
    236   { "PSPCFG", 110, {0, {{{0, 0}}}}, 0, 0 },
    237   { "CMPCFG", 111, {0, {{{0, 0}}}}, 0, 0 },
    238   { "S2TMRH", 112, {0, {{{0, 0}}}}, 0, 0 },
    239   { "S2TMRL", 113, {0, {{{0, 0}}}}, 0, 0 },
    240   { "S2TBUFH", 114, {0, {{{0, 0}}}}, 0, 0 },
    241   { "S2TBUFL", 115, {0, {{{0, 0}}}}, 0, 0 },
    242   { "S2TCFG", 116, {0, {{{0, 0}}}}, 0, 0 },
    243   { "S2RCNT", 117, {0, {{{0, 0}}}}, 0, 0 },
    244   { "S2RBUFH", 118, {0, {{{0, 0}}}}, 0, 0 },
    245   { "S2RBUFL", 119, {0, {{{0, 0}}}}, 0, 0 },
    246   { "S2RCFG", 120, {0, {{{0, 0}}}}, 0, 0 },
    247   { "S2RSYNC", 121, {0, {{{0, 0}}}}, 0, 0 },
    248   { "S2INTF", 122, {0, {{{0, 0}}}}, 0, 0 },
    249   { "S2INTE", 123, {0, {{{0, 0}}}}, 0, 0 },
    250   { "S2MODE", 124, {0, {{{0, 0}}}}, 0, 0 },
    251   { "S2SMASK", 125, {0, {{{0, 0}}}}, 0, 0 },
    252   { "CALLH", 126, {0, {{{0, 0}}}}, 0, 0 },
    253   { "CALLL", 127, {0, {{{0, 0}}}}, 0, 0 }
    254 };
    255 
    256 CGEN_KEYWORD ip2k_cgen_opval_register_names =
    257 {
    258   & ip2k_cgen_opval_register_names_entries[0],
    259   121,
    260   0, 0, 0, 0, ""
    261 };
    262 
    263 
    264 /* The hardware table.  */
    265 
    266 #if defined (__STDC__) || defined (ALMOST_STDC) || defined (HAVE_STRINGIZE)
    267 #define A(a) (1 << CGEN_HW_##a)
    268 #else
    269 #define A(a) (1 << CGEN_HW_/**/a)
    270 #endif
    271 
    272 const CGEN_HW_ENTRY ip2k_cgen_hw_table[] =
    273 {
    274   { "h-memory", HW_H_MEMORY, CGEN_ASM_NONE, 0, { 0, { { { (1<<MACH_BASE), 0 } } } } },
    275   { "h-sint", HW_H_SINT, CGEN_ASM_NONE, 0, { 0, { { { (1<<MACH_BASE), 0 } } } } },
    276   { "h-uint", HW_H_UINT, CGEN_ASM_NONE, 0, { 0, { { { (1<<MACH_BASE), 0 } } } } },
    277   { "h-addr", HW_H_ADDR, CGEN_ASM_NONE, 0, { 0, { { { (1<<MACH_BASE), 0 } } } } },
    278   { "h-iaddr", HW_H_IADDR, CGEN_ASM_NONE, 0, { 0, { { { (1<<MACH_BASE), 0 } } } } },
    279   { "h-spr", HW_H_SPR, CGEN_ASM_NONE, 0, { 0, { { { (1<<MACH_BASE), 0 } } } } },
    280   { "h-registers", HW_H_REGISTERS, CGEN_ASM_NONE, 0, { 0|A(VIRTUAL), { { { (1<<MACH_BASE), 0 } } } } },
    281   { "h-stack", HW_H_STACK, CGEN_ASM_NONE, 0, { 0, { { { (1<<MACH_BASE), 0 } } } } },
    282   { "h-pabits", HW_H_PABITS, CGEN_ASM_NONE, 0, { 0, { { { (1<<MACH_BASE), 0 } } } } },
    283   { "h-zbit", HW_H_ZBIT, CGEN_ASM_NONE, 0, { 0, { { { (1<<MACH_BASE), 0 } } } } },
    284   { "h-cbit", HW_H_CBIT, CGEN_ASM_NONE, 0, { 0, { { { (1<<MACH_BASE), 0 } } } } },
    285   { "h-dcbit", HW_H_DCBIT, CGEN_ASM_NONE, 0, { 0, { { { (1<<MACH_BASE), 0 } } } } },
    286   { "h-pc", HW_H_PC, CGEN_ASM_NONE, 0, { 0|A(PROFILE)|A(PC), { { { (1<<MACH_BASE), 0 } } } } },
    287   { 0, 0, CGEN_ASM_NONE, 0, { 0, { { { (1<<MACH_BASE), 0 } } } } }
    288 };
    289 
    290 #undef A
    291 
    292 
    293 /* The instruction field table.  */
    294 
    295 #if defined (__STDC__) || defined (ALMOST_STDC) || defined (HAVE_STRINGIZE)
    296 #define A(a) (1 << CGEN_IFLD_##a)
    297 #else
    298 #define A(a) (1 << CGEN_IFLD_/**/a)
    299 #endif
    300 
    301 const CGEN_IFLD ip2k_cgen_ifld_table[] =
    302 {
    303   { IP2K_F_NIL, "f-nil", 0, 0, 0, 0, { 0, { { { (1<<MACH_BASE), 0 } } } }  },
    304   { IP2K_F_ANYOF, "f-anyof", 0, 0, 0, 0, { 0, { { { (1<<MACH_BASE), 0 } } } }  },
    305   { IP2K_F_IMM8, "f-imm8", 0, 16, 7, 8, { 0, { { { (1<<MACH_BASE), 0 } } } }  },
    306   { IP2K_F_REG, "f-reg", 0, 16, 8, 9, { 0|A(ABS_ADDR), { { { (1<<MACH_BASE), 0 } } } }  },
    307   { IP2K_F_ADDR16CJP, "f-addr16cjp", 0, 16, 12, 13, { 0|A(ABS_ADDR), { { { (1<<MACH_BASE), 0 } } } }  },
    308   { IP2K_F_DIR, "f-dir", 0, 16, 9, 1, { 0, { { { (1<<MACH_BASE), 0 } } } }  },
    309   { IP2K_F_BITNO, "f-bitno", 0, 16, 11, 3, { 0, { { { (1<<MACH_BASE), 0 } } } }  },
    310   { IP2K_F_OP3, "f-op3", 0, 16, 15, 3, { 0, { { { (1<<MACH_BASE), 0 } } } }  },
    311   { IP2K_F_OP4, "f-op4", 0, 16, 15, 4, { 0, { { { (1<<MACH_BASE), 0 } } } }  },
    312   { IP2K_F_OP4MID, "f-op4mid", 0, 16, 11, 4, { 0, { { { (1<<MACH_BASE), 0 } } } }  },
    313   { IP2K_F_OP6, "f-op6", 0, 16, 15, 6, { 0, { { { (1<<MACH_BASE), 0 } } } }  },
    314   { IP2K_F_OP8, "f-op8", 0, 16, 15, 8, { 0, { { { (1<<MACH_BASE), 0 } } } }  },
    315   { IP2K_F_OP6_10LOW, "f-op6-10low", 0, 16, 9, 10, { 0, { { { (1<<MACH_BASE), 0 } } } }  },
    316   { IP2K_F_OP6_7LOW, "f-op6-7low", 0, 16, 9, 7, { 0, { { { (1<<MACH_BASE), 0 } } } }  },
    317   { IP2K_F_RETI3, "f-reti3", 0, 16, 2, 3, { 0, { { { (1<<MACH_BASE), 0 } } } }  },
    318   { IP2K_F_SKIPB, "f-skipb", 0, 16, 12, 1, { 0|A(ABS_ADDR), { { { (1<<MACH_BASE), 0 } } } }  },
    319   { IP2K_F_PAGE3, "f-page3", 0, 16, 2, 3, { 0, { { { (1<<MACH_BASE), 0 } } } }  },
    320   { 0, 0, 0, 0, 0, 0, { 0, { { { (1<<MACH_BASE), 0 } } } } }
    321 };
    322 
    323 #undef A
    324 
    325 
    326 
    327 /* multi ifield declarations */
    328 
    329 
    330 
    331 /* multi ifield definitions */
    332 
    333 
    334 /* The operand table.  */
    335 
    336 #if defined (__STDC__) || defined (ALMOST_STDC) || defined (HAVE_STRINGIZE)
    337 #define A(a) (1 << CGEN_OPERAND_##a)
    338 #else
    339 #define A(a) (1 << CGEN_OPERAND_/**/a)
    340 #endif
    341 #if defined (__STDC__) || defined (ALMOST_STDC) || defined (HAVE_STRINGIZE)
    342 #define OPERAND(op) IP2K_OPERAND_##op
    343 #else
    344 #define OPERAND(op) IP2K_OPERAND_/**/op
    345 #endif
    346 
    347 const CGEN_OPERAND ip2k_cgen_operand_table[] =
    348 {
    349 /* pc: program counter */
    350   { "pc", IP2K_OPERAND_PC, HW_H_PC, 0, 0,
    351     { 0, { (const PTR) &ip2k_cgen_ifld_table[IP2K_F_NIL] } },
    352     { 0|A(SEM_ONLY), { { { (1<<MACH_BASE), 0 } } } }  },
    353 /* addr16cjp: 13-bit address */
    354   { "addr16cjp", IP2K_OPERAND_ADDR16CJP, HW_H_UINT, 12, 13,
    355     { 0, { (const PTR) &ip2k_cgen_ifld_table[IP2K_F_ADDR16CJP] } },
    356     { 0|A(ABS_ADDR), { { { (1<<MACH_BASE), 0 } } } }  },
    357 /* fr: register */
    358   { "fr", IP2K_OPERAND_FR, HW_H_REGISTERS, 8, 9,
    359     { 0, { (const PTR) &ip2k_cgen_ifld_table[IP2K_F_REG] } },
    360     { 0|A(ABS_ADDR), { { { (1<<MACH_BASE), 0 } } } }  },
    361 /* lit8: 8-bit signed literal */
    362   { "lit8", IP2K_OPERAND_LIT8, HW_H_SINT, 7, 8,
    363     { 0, { (const PTR) &ip2k_cgen_ifld_table[IP2K_F_IMM8] } },
    364     { 0, { { { (1<<MACH_BASE), 0 } } } }  },
    365 /* bitno: bit number */
    366   { "bitno", IP2K_OPERAND_BITNO, HW_H_UINT, 11, 3,
    367     { 0, { (const PTR) &ip2k_cgen_ifld_table[IP2K_F_BITNO] } },
    368     { 0, { { { (1<<MACH_BASE), 0 } } } }  },
    369 /* addr16p: page number */
    370   { "addr16p", IP2K_OPERAND_ADDR16P, HW_H_UINT, 2, 3,
    371     { 0, { (const PTR) &ip2k_cgen_ifld_table[IP2K_F_PAGE3] } },
    372     { 0, { { { (1<<MACH_BASE), 0 } } } }  },
    373 /* addr16h: high 8 bits of address */
    374   { "addr16h", IP2K_OPERAND_ADDR16H, HW_H_UINT, 7, 8,
    375     { 0, { (const PTR) &ip2k_cgen_ifld_table[IP2K_F_IMM8] } },
    376     { 0, { { { (1<<MACH_BASE), 0 } } } }  },
    377 /* addr16l: low 8 bits of address */
    378   { "addr16l", IP2K_OPERAND_ADDR16L, HW_H_UINT, 7, 8,
    379     { 0, { (const PTR) &ip2k_cgen_ifld_table[IP2K_F_IMM8] } },
    380     { 0, { { { (1<<MACH_BASE), 0 } } } }  },
    381 /* reti3: reti flags */
    382   { "reti3", IP2K_OPERAND_RETI3, HW_H_UINT, 2, 3,
    383     { 0, { (const PTR) &ip2k_cgen_ifld_table[IP2K_F_RETI3] } },
    384     { 0, { { { (1<<MACH_BASE), 0 } } } }  },
    385 /* pabits: page bits */
    386   { "pabits", IP2K_OPERAND_PABITS, HW_H_PABITS, 0, 0,
    387     { 0, { (const PTR) 0 } },
    388     { 0, { { { (1<<MACH_BASE), 0 } } } }  },
    389 /* zbit: zero bit */
    390   { "zbit", IP2K_OPERAND_ZBIT, HW_H_ZBIT, 0, 0,
    391     { 0, { (const PTR) 0 } },
    392     { 0, { { { (1<<MACH_BASE), 0 } } } }  },
    393 /* cbit: carry bit */
    394   { "cbit", IP2K_OPERAND_CBIT, HW_H_CBIT, 0, 0,
    395     { 0, { (const PTR) 0 } },
    396     { 0, { { { (1<<MACH_BASE), 0 } } } }  },
    397 /* dcbit: digit carry bit */
    398   { "dcbit", IP2K_OPERAND_DCBIT, HW_H_DCBIT, 0, 0,
    399     { 0, { (const PTR) 0 } },
    400     { 0, { { { (1<<MACH_BASE), 0 } } } }  },
    401 /* sentinel */
    402   { 0, 0, 0, 0, 0,
    403     { 0, { (const PTR) 0 } },
    404     { 0, { { { (1<<MACH_BASE), 0 } } } } }
    405 };
    406 
    407 #undef A
    408 
    409 
    410 /* The instruction table.  */
    411 
    412 #define OP(field) CGEN_SYNTAX_MAKE_FIELD (OPERAND (field))
    413 #if defined (__STDC__) || defined (ALMOST_STDC) || defined (HAVE_STRINGIZE)
    414 #define A(a) (1 << CGEN_INSN_##a)
    415 #else
    416 #define A(a) (1 << CGEN_INSN_/**/a)
    417 #endif
    418 
    419 static const CGEN_IBASE ip2k_cgen_insn_table[MAX_INSNS] =
    420 {
    421   /* Special null first entry.
    422      A `num' value of zero is thus invalid.
    423      Also, the special `invalid' insn resides here.  */
    424   { 0, 0, 0, 0, { 0, { { { (1<<MACH_BASE), 0 } } } } },
    425 /* jmp $addr16cjp */
    426   {
    427     IP2K_INSN_JMP, "jmp", "jmp", 16,
    428     { 0|A(UNCOND_CTI), { { { (1<<MACH_BASE), 0 } } } }
    429   },
    430 /* call $addr16cjp */
    431   {
    432     IP2K_INSN_CALL, "call", "call", 16,
    433     { 0|A(UNCOND_CTI), { { { (1<<MACH_BASE), 0 } } } }
    434   },
    435 /* sb $fr,$bitno */
    436   {
    437     IP2K_INSN_SB, "sb", "sb", 16,
    438     { 0|A(SKIP_CTI), { { { (1<<MACH_BASE), 0 } } } }
    439   },
    440 /* snb $fr,$bitno */
    441   {
    442     IP2K_INSN_SNB, "snb", "snb", 16,
    443     { 0|A(SKIP_CTI), { { { (1<<MACH_BASE), 0 } } } }
    444   },
    445 /* setb $fr,$bitno */
    446   {
    447     IP2K_INSN_SETB, "setb", "setb", 16,
    448     { 0, { { { (1<<MACH_BASE), 0 } } } }
    449   },
    450 /* clrb $fr,$bitno */
    451   {
    452     IP2K_INSN_CLRB, "clrb", "clrb", 16,
    453     { 0, { { { (1<<MACH_BASE), 0 } } } }
    454   },
    455 /* xor W,#$lit8 */
    456   {
    457     IP2K_INSN_XORW_L, "xorw_l", "xor", 16,
    458     { 0, { { { (1<<MACH_BASE), 0 } } } }
    459   },
    460 /* and W,#$lit8 */
    461   {
    462     IP2K_INSN_ANDW_L, "andw_l", "and", 16,
    463     { 0, { { { (1<<MACH_BASE), 0 } } } }
    464   },
    465 /* or W,#$lit8 */
    466   {
    467     IP2K_INSN_ORW_L, "orw_l", "or", 16,
    468     { 0, { { { (1<<MACH_BASE), 0 } } } }
    469   },
    470 /* add W,#$lit8 */
    471   {
    472     IP2K_INSN_ADDW_L, "addw_l", "add", 16,
    473     { 0, { { { (1<<MACH_BASE), 0 } } } }
    474   },
    475 /* sub W,#$lit8 */
    476   {
    477     IP2K_INSN_SUBW_L, "subw_l", "sub", 16,
    478     { 0, { { { (1<<MACH_BASE), 0 } } } }
    479   },
    480 /* cmp W,#$lit8 */
    481   {
    482     IP2K_INSN_CMPW_L, "cmpw_l", "cmp", 16,
    483     { 0, { { { (1<<MACH_BASE), 0 } } } }
    484   },
    485 /* retw #$lit8 */
    486   {
    487     IP2K_INSN_RETW_L, "retw_l", "retw", 16,
    488     { 0|A(UNCOND_CTI), { { { (1<<MACH_BASE), 0 } } } }
    489   },
    490 /* cse W,#$lit8 */
    491   {
    492     IP2K_INSN_CSEW_L, "csew_l", "cse", 16,
    493     { 0|A(SKIP_CTI), { { { (1<<MACH_BASE), 0 } } } }
    494   },
    495 /* csne W,#$lit8 */
    496   {
    497     IP2K_INSN_CSNEW_L, "csnew_l", "csne", 16,
    498     { 0|A(SKIP_CTI), { { { (1<<MACH_BASE), 0 } } } }
    499   },
    500 /* push #$lit8 */
    501   {
    502     IP2K_INSN_PUSH_L, "push_l", "push", 16,
    503     { 0, { { { (1<<MACH_BASE), 0 } } } }
    504   },
    505 /* muls W,#$lit8 */
    506   {
    507     IP2K_INSN_MULSW_L, "mulsw_l", "muls", 16,
    508     { 0, { { { (1<<MACH_BASE), 0 } } } }
    509   },
    510 /* mulu W,#$lit8 */
    511   {
    512     IP2K_INSN_MULUW_L, "muluw_l", "mulu", 16,
    513     { 0, { { { (1<<MACH_BASE), 0 } } } }
    514   },
    515 /* loadl #$lit8 */
    516   {
    517     IP2K_INSN_LOADL_L, "loadl_l", "loadl", 16,
    518     { 0|A(EXT_SKIP_INSN), { { { (1<<MACH_BASE), 0 } } } }
    519   },
    520 /* loadh #$lit8 */
    521   {
    522     IP2K_INSN_LOADH_L, "loadh_l", "loadh", 16,
    523     { 0|A(EXT_SKIP_INSN), { { { (1<<MACH_BASE), 0 } } } }
    524   },
    525 /* loadl $addr16l */
    526   {
    527     IP2K_INSN_LOADL_A, "loadl_a", "loadl", 16,
    528     { 0|A(EXT_SKIP_INSN), { { { (1<<MACH_BASE), 0 } } } }
    529   },
    530 /* loadh $addr16h */
    531   {
    532     IP2K_INSN_LOADH_A, "loadh_a", "loadh", 16,
    533     { 0|A(EXT_SKIP_INSN), { { { (1<<MACH_BASE), 0 } } } }
    534   },
    535 /* addc $fr,W */
    536   {
    537     IP2K_INSN_ADDCFR_W, "addcfr_w", "addc", 16,
    538     { 0, { { { (1<<MACH_BASE), 0 } } } }
    539   },
    540 /* addc W,$fr */
    541   {
    542     IP2K_INSN_ADDCW_FR, "addcw_fr", "addc", 16,
    543     { 0, { { { (1<<MACH_BASE), 0 } } } }
    544   },
    545 /* incsnz $fr */
    546   {
    547     IP2K_INSN_INCSNZ_FR, "incsnz_fr", "incsnz", 16,
    548     { 0|A(SKIP_CTI), { { { (1<<MACH_BASE), 0 } } } }
    549   },
    550 /* incsnz W,$fr */
    551   {
    552     IP2K_INSN_INCSNZW_FR, "incsnzw_fr", "incsnz", 16,
    553     { 0|A(SKIP_CTI), { { { (1<<MACH_BASE), 0 } } } }
    554   },
    555 /* muls W,$fr */
    556   {
    557     IP2K_INSN_MULSW_FR, "mulsw_fr", "muls", 16,
    558     { 0, { { { (1<<MACH_BASE), 0 } } } }
    559   },
    560 /* mulu W,$fr */
    561   {
    562     IP2K_INSN_MULUW_FR, "muluw_fr", "mulu", 16,
    563     { 0, { { { (1<<MACH_BASE), 0 } } } }
    564   },
    565 /* decsnz $fr */
    566   {
    567     IP2K_INSN_DECSNZ_FR, "decsnz_fr", "decsnz", 16,
    568     { 0|A(SKIP_CTI), { { { (1<<MACH_BASE), 0 } } } }
    569   },
    570 /* decsnz W,$fr */
    571   {
    572     IP2K_INSN_DECSNZW_FR, "decsnzw_fr", "decsnz", 16,
    573     { 0|A(SKIP_CTI), { { { (1<<MACH_BASE), 0 } } } }
    574   },
    575 /* subc W,$fr */
    576   {
    577     IP2K_INSN_SUBCW_FR, "subcw_fr", "subc", 16,
    578     { 0, { { { (1<<MACH_BASE), 0 } } } }
    579   },
    580 /* subc $fr,W */
    581   {
    582     IP2K_INSN_SUBCFR_W, "subcfr_w", "subc", 16,
    583     { 0, { { { (1<<MACH_BASE), 0 } } } }
    584   },
    585 /* pop $fr */
    586   {
    587     IP2K_INSN_POP_FR, "pop_fr", "pop", 16,
    588     { 0, { { { (1<<MACH_BASE), 0 } } } }
    589   },
    590 /* push $fr */
    591   {
    592     IP2K_INSN_PUSH_FR, "push_fr", "push", 16,
    593     { 0, { { { (1<<MACH_BASE), 0 } } } }
    594   },
    595 /* cse W,$fr */
    596   {
    597     IP2K_INSN_CSEW_FR, "csew_fr", "cse", 16,
    598     { 0|A(SKIP_CTI), { { { (1<<MACH_BASE), 0 } } } }
    599   },
    600 /* csne W,$fr */
    601   {
    602     IP2K_INSN_CSNEW_FR, "csnew_fr", "csne", 16,
    603     { 0|A(SKIP_CTI), { { { (1<<MACH_BASE), 0 } } } }
    604   },
    605 /* incsz $fr */
    606   {
    607     IP2K_INSN_INCSZ_FR, "incsz_fr", "incsz", 16,
    608     { 0|A(SKIP_CTI), { { { (1<<MACH_BASE), 0 } } } }
    609   },
    610 /* incsz W,$fr */
    611   {
    612     IP2K_INSN_INCSZW_FR, "incszw_fr", "incsz", 16,
    613     { 0|A(SKIP_CTI), { { { (1<<MACH_BASE), 0 } } } }
    614   },
    615 /* swap $fr */
    616   {
    617     IP2K_INSN_SWAP_FR, "swap_fr", "swap", 16,
    618     { 0, { { { (1<<MACH_BASE), 0 } } } }
    619   },
    620 /* swap W,$fr */
    621   {
    622     IP2K_INSN_SWAPW_FR, "swapw_fr", "swap", 16,
    623     { 0, { { { (1<<MACH_BASE), 0 } } } }
    624   },
    625 /* rl $fr */
    626   {
    627     IP2K_INSN_RL_FR, "rl_fr", "rl", 16,
    628     { 0, { { { (1<<MACH_BASE), 0 } } } }
    629   },
    630 /* rl W,$fr */
    631   {
    632     IP2K_INSN_RLW_FR, "rlw_fr", "rl", 16,
    633     { 0, { { { (1<<MACH_BASE), 0 } } } }
    634   },
    635 /* rr $fr */
    636   {
    637     IP2K_INSN_RR_FR, "rr_fr", "rr", 16,
    638     { 0, { { { (1<<MACH_BASE), 0 } } } }
    639   },
    640 /* rr W,$fr */
    641   {
    642     IP2K_INSN_RRW_FR, "rrw_fr", "rr", 16,
    643     { 0, { { { (1<<MACH_BASE), 0 } } } }
    644   },
    645 /* decsz $fr */
    646   {
    647     IP2K_INSN_DECSZ_FR, "decsz_fr", "decsz", 16,
    648     { 0|A(SKIP_CTI), { { { (1<<MACH_BASE), 0 } } } }
    649   },
    650 /* decsz W,$fr */
    651   {
    652     IP2K_INSN_DECSZW_FR, "decszw_fr", "decsz", 16,
    653     { 0|A(SKIP_CTI), { { { (1<<MACH_BASE), 0 } } } }
    654   },
    655 /* inc $fr */
    656   {
    657     IP2K_INSN_INC_FR, "inc_fr", "inc", 16,
    658     { 0, { { { (1<<MACH_BASE), 0 } } } }
    659   },
    660 /* inc W,$fr */
    661   {
    662     IP2K_INSN_INCW_FR, "incw_fr", "inc", 16,
    663     { 0, { { { (1<<MACH_BASE), 0 } } } }
    664   },
    665 /* not $fr */
    666   {
    667     IP2K_INSN_NOT_FR, "not_fr", "not", 16,
    668     { 0, { { { (1<<MACH_BASE), 0 } } } }
    669   },
    670 /* not W,$fr */
    671   {
    672     IP2K_INSN_NOTW_FR, "notw_fr", "not", 16,
    673     { 0, { { { (1<<MACH_BASE), 0 } } } }
    674   },
    675 /* test $fr */
    676   {
    677     IP2K_INSN_TEST_FR, "test_fr", "test", 16,
    678     { 0, { { { (1<<MACH_BASE), 0 } } } }
    679   },
    680 /* mov W,#$lit8 */
    681   {
    682     IP2K_INSN_MOVW_L, "movw_l", "mov", 16,
    683     { 0, { { { (1<<MACH_BASE), 0 } } } }
    684   },
    685 /* mov $fr,W */
    686   {
    687     IP2K_INSN_MOVFR_W, "movfr_w", "mov", 16,
    688     { 0, { { { (1<<MACH_BASE), 0 } } } }
    689   },
    690 /* mov W,$fr */
    691   {
    692     IP2K_INSN_MOVW_FR, "movw_fr", "mov", 16,
    693     { 0, { { { (1<<MACH_BASE), 0 } } } }
    694   },
    695 /* add $fr,W */
    696   {
    697     IP2K_INSN_ADDFR_W, "addfr_w", "add", 16,
    698     { 0, { { { (1<<MACH_BASE), 0 } } } }
    699   },
    700 /* add W,$fr */
    701   {
    702     IP2K_INSN_ADDW_FR, "addw_fr", "add", 16,
    703     { 0, { { { (1<<MACH_BASE), 0 } } } }
    704   },
    705 /* xor $fr,W */
    706   {
    707     IP2K_INSN_XORFR_W, "xorfr_w", "xor", 16,
    708     { 0, { { { (1<<MACH_BASE), 0 } } } }
    709   },
    710 /* xor W,$fr */
    711   {
    712     IP2K_INSN_XORW_FR, "xorw_fr", "xor", 16,
    713     { 0, { { { (1<<MACH_BASE), 0 } } } }
    714   },
    715 /* and $fr,W */
    716   {
    717     IP2K_INSN_ANDFR_W, "andfr_w", "and", 16,
    718     { 0, { { { (1<<MACH_BASE), 0 } } } }
    719   },
    720 /* and W,$fr */
    721   {
    722     IP2K_INSN_ANDW_FR, "andw_fr", "and", 16,
    723     { 0, { { { (1<<MACH_BASE), 0 } } } }
    724   },
    725 /* or $fr,W */
    726   {
    727     IP2K_INSN_ORFR_W, "orfr_w", "or", 16,
    728     { 0, { { { (1<<MACH_BASE), 0 } } } }
    729   },
    730 /* or W,$fr */
    731   {
    732     IP2K_INSN_ORW_FR, "orw_fr", "or", 16,
    733     { 0, { { { (1<<MACH_BASE), 0 } } } }
    734   },
    735 /* dec $fr */
    736   {
    737     IP2K_INSN_DEC_FR, "dec_fr", "dec", 16,
    738     { 0, { { { (1<<MACH_BASE), 0 } } } }
    739   },
    740 /* dec W,$fr */
    741   {
    742     IP2K_INSN_DECW_FR, "decw_fr", "dec", 16,
    743     { 0, { { { (1<<MACH_BASE), 0 } } } }
    744   },
    745 /* sub $fr,W */
    746   {
    747     IP2K_INSN_SUBFR_W, "subfr_w", "sub", 16,
    748     { 0, { { { (1<<MACH_BASE), 0 } } } }
    749   },
    750 /* sub W,$fr */
    751   {
    752     IP2K_INSN_SUBW_FR, "subw_fr", "sub", 16,
    753     { 0, { { { (1<<MACH_BASE), 0 } } } }
    754   },
    755 /* clr $fr */
    756   {
    757     IP2K_INSN_CLR_FR, "clr_fr", "clr", 16,
    758     { 0, { { { (1<<MACH_BASE), 0 } } } }
    759   },
    760 /* cmp W,$fr */
    761   {
    762     IP2K_INSN_CMPW_FR, "cmpw_fr", "cmp", 16,
    763     { 0, { { { (1<<MACH_BASE), 0 } } } }
    764   },
    765 /* speed #$lit8 */
    766   {
    767     IP2K_INSN_SPEED, "speed", "speed", 16,
    768     { 0, { { { (1<<MACH_BASE), 0 } } } }
    769   },
    770 /* ireadi */
    771   {
    772     IP2K_INSN_IREADI, "ireadi", "ireadi", 16,
    773     { 0, { { { (1<<MACH_BASE), 0 } } } }
    774   },
    775 /* iwritei */
    776   {
    777     IP2K_INSN_IWRITEI, "iwritei", "iwritei", 16,
    778     { 0, { { { (1<<MACH_BASE), 0 } } } }
    779   },
    780 /* fread */
    781   {
    782     IP2K_INSN_FREAD, "fread", "fread", 16,
    783     { 0, { { { (1<<MACH_BASE), 0 } } } }
    784   },
    785 /* fwrite */
    786   {
    787     IP2K_INSN_FWRITE, "fwrite", "fwrite", 16,
    788     { 0, { { { (1<<MACH_BASE), 0 } } } }
    789   },
    790 /* iread */
    791   {
    792     IP2K_INSN_IREAD, "iread", "iread", 16,
    793     { 0, { { { (1<<MACH_BASE), 0 } } } }
    794   },
    795 /* iwrite */
    796   {
    797     IP2K_INSN_IWRITE, "iwrite", "iwrite", 16,
    798     { 0, { { { (1<<MACH_BASE), 0 } } } }
    799   },
    800 /* page $addr16p */
    801   {
    802     IP2K_INSN_PAGE, "page", "page", 16,
    803     { 0|A(EXT_SKIP_INSN), { { { (1<<MACH_BASE), 0 } } } }
    804   },
    805 /* system */
    806   {
    807     IP2K_INSN_SYSTEM, "system", "system", 16,
    808     { 0, { { { (1<<MACH_BASE), 0 } } } }
    809   },
    810 /* reti #$reti3 */
    811   {
    812     IP2K_INSN_RETI, "reti", "reti", 16,
    813     { 0, { { { (1<<MACH_BASE), 0 } } } }
    814   },
    815 /* ret */
    816   {
    817     IP2K_INSN_RET, "ret", "ret", 16,
    818     { 0|A(UNCOND_CTI), { { { (1<<MACH_BASE), 0 } } } }
    819   },
    820 /* int */
    821   {
    822     IP2K_INSN_INT, "int", "int", 16,
    823     { 0, { { { (1<<MACH_BASE), 0 } } } }
    824   },
    825 /* breakx */
    826   {
    827     IP2K_INSN_BREAKX, "breakx", "breakx", 16,
    828     { 0|A(EXT_SKIP_INSN), { { { (1<<MACH_BASE), 0 } } } }
    829   },
    830 /* cwdt */
    831   {
    832     IP2K_INSN_CWDT, "cwdt", "cwdt", 16,
    833     { 0, { { { (1<<MACH_BASE), 0 } } } }
    834   },
    835 /* ferase */
    836   {
    837     IP2K_INSN_FERASE, "ferase", "ferase", 16,
    838     { 0, { { { (1<<MACH_BASE), 0 } } } }
    839   },
    840 /* retnp */
    841   {
    842     IP2K_INSN_RETNP, "retnp", "retnp", 16,
    843     { 0|A(UNCOND_CTI), { { { (1<<MACH_BASE), 0 } } } }
    844   },
    845 /* break */
    846   {
    847     IP2K_INSN_BREAK, "break", "break", 16,
    848     { 0, { { { (1<<MACH_BASE), 0 } } } }
    849   },
    850 /* nop */
    851   {
    852     IP2K_INSN_NOP, "nop", "nop", 16,
    853     { 0, { { { (1<<MACH_BASE), 0 } } } }
    854   },
    855 };
    856 
    857 #undef OP
    858 #undef A
    859 
    860 /* Initialize anything needed to be done once, before any cpu_open call.  */
    861 
    862 static void
    863 init_tables (void)
    864 {
    865 }
    866 
    867 static const CGEN_MACH * lookup_mach_via_bfd_name (const CGEN_MACH *, const char *);
    868 static void build_hw_table      (CGEN_CPU_TABLE *);
    869 static void build_ifield_table  (CGEN_CPU_TABLE *);
    870 static void build_operand_table (CGEN_CPU_TABLE *);
    871 static void build_insn_table    (CGEN_CPU_TABLE *);
    872 static void ip2k_cgen_rebuild_tables (CGEN_CPU_TABLE *);
    873 
    874 /* Subroutine of ip2k_cgen_cpu_open to look up a mach via its bfd name.  */
    875 
    876 static const CGEN_MACH *
    877 lookup_mach_via_bfd_name (const CGEN_MACH *table, const char *name)
    878 {
    879   while (table->name)
    880     {
    881       if (strcmp (name, table->bfd_name) == 0)
    882 	return table;
    883       ++table;
    884     }
    885   abort ();
    886 }
    887 
    888 /* Subroutine of ip2k_cgen_cpu_open to build the hardware table.  */
    889 
    890 static void
    891 build_hw_table (CGEN_CPU_TABLE *cd)
    892 {
    893   int i;
    894   int machs = cd->machs;
    895   const CGEN_HW_ENTRY *init = & ip2k_cgen_hw_table[0];
    896   /* MAX_HW is only an upper bound on the number of selected entries.
    897      However each entry is indexed by it's enum so there can be holes in
    898      the table.  */
    899   const CGEN_HW_ENTRY **selected =
    900     (const CGEN_HW_ENTRY **) xmalloc (MAX_HW * sizeof (CGEN_HW_ENTRY *));
    901 
    902   cd->hw_table.init_entries = init;
    903   cd->hw_table.entry_size = sizeof (CGEN_HW_ENTRY);
    904   memset (selected, 0, MAX_HW * sizeof (CGEN_HW_ENTRY *));
    905   /* ??? For now we just use machs to determine which ones we want.  */
    906   for (i = 0; init[i].name != NULL; ++i)
    907     if (CGEN_HW_ATTR_VALUE (&init[i], CGEN_HW_MACH)
    908 	& machs)
    909       selected[init[i].type] = &init[i];
    910   cd->hw_table.entries = selected;
    911   cd->hw_table.num_entries = MAX_HW;
    912 }
    913 
    914 /* Subroutine of ip2k_cgen_cpu_open to build the hardware table.  */
    915 
    916 static void
    917 build_ifield_table (CGEN_CPU_TABLE *cd)
    918 {
    919   cd->ifld_table = & ip2k_cgen_ifld_table[0];
    920 }
    921 
    922 /* Subroutine of ip2k_cgen_cpu_open to build the hardware table.  */
    923 
    924 static void
    925 build_operand_table (CGEN_CPU_TABLE *cd)
    926 {
    927   int i;
    928   int machs = cd->machs;
    929   const CGEN_OPERAND *init = & ip2k_cgen_operand_table[0];
    930   /* MAX_OPERANDS is only an upper bound on the number of selected entries.
    931      However each entry is indexed by it's enum so there can be holes in
    932      the table.  */
    933   const CGEN_OPERAND **selected = xmalloc (MAX_OPERANDS * sizeof (* selected));
    934 
    935   cd->operand_table.init_entries = init;
    936   cd->operand_table.entry_size = sizeof (CGEN_OPERAND);
    937   memset (selected, 0, MAX_OPERANDS * sizeof (CGEN_OPERAND *));
    938   /* ??? For now we just use mach to determine which ones we want.  */
    939   for (i = 0; init[i].name != NULL; ++i)
    940     if (CGEN_OPERAND_ATTR_VALUE (&init[i], CGEN_OPERAND_MACH)
    941 	& machs)
    942       selected[init[i].type] = &init[i];
    943   cd->operand_table.entries = selected;
    944   cd->operand_table.num_entries = MAX_OPERANDS;
    945 }
    946 
    947 /* Subroutine of ip2k_cgen_cpu_open to build the hardware table.
    948    ??? This could leave out insns not supported by the specified mach/isa,
    949    but that would cause errors like "foo only supported by bar" to become
    950    "unknown insn", so for now we include all insns and require the app to
    951    do the checking later.
    952    ??? On the other hand, parsing of such insns may require their hardware or
    953    operand elements to be in the table [which they mightn't be].  */
    954 
    955 static void
    956 build_insn_table (CGEN_CPU_TABLE *cd)
    957 {
    958   int i;
    959   const CGEN_IBASE *ib = & ip2k_cgen_insn_table[0];
    960   CGEN_INSN *insns = xmalloc (MAX_INSNS * sizeof (CGEN_INSN));
    961 
    962   memset (insns, 0, MAX_INSNS * sizeof (CGEN_INSN));
    963   for (i = 0; i < MAX_INSNS; ++i)
    964     insns[i].base = &ib[i];
    965   cd->insn_table.init_entries = insns;
    966   cd->insn_table.entry_size = sizeof (CGEN_IBASE);
    967   cd->insn_table.num_init_entries = MAX_INSNS;
    968 }
    969 
    970 /* Subroutine of ip2k_cgen_cpu_open to rebuild the tables.  */
    971 
    972 static void
    973 ip2k_cgen_rebuild_tables (CGEN_CPU_TABLE *cd)
    974 {
    975   int i;
    976   CGEN_BITSET *isas = cd->isas;
    977   unsigned int machs = cd->machs;
    978 
    979   cd->int_insn_p = CGEN_INT_INSN_P;
    980 
    981   /* Data derived from the isa spec.  */
    982 #define UNSET (CGEN_SIZE_UNKNOWN + 1)
    983   cd->default_insn_bitsize = UNSET;
    984   cd->base_insn_bitsize = UNSET;
    985   cd->min_insn_bitsize = 65535; /* Some ridiculously big number.  */
    986   cd->max_insn_bitsize = 0;
    987   for (i = 0; i < MAX_ISAS; ++i)
    988     if (cgen_bitset_contains (isas, i))
    989       {
    990 	const CGEN_ISA *isa = & ip2k_cgen_isa_table[i];
    991 
    992 	/* Default insn sizes of all selected isas must be
    993 	   equal or we set the result to 0, meaning "unknown".  */
    994 	if (cd->default_insn_bitsize == UNSET)
    995 	  cd->default_insn_bitsize = isa->default_insn_bitsize;
    996 	else if (isa->default_insn_bitsize == cd->default_insn_bitsize)
    997 	  ; /* This is ok.  */
    998 	else
    999 	  cd->default_insn_bitsize = CGEN_SIZE_UNKNOWN;
   1000 
   1001 	/* Base insn sizes of all selected isas must be equal
   1002 	   or we set the result to 0, meaning "unknown".  */
   1003 	if (cd->base_insn_bitsize == UNSET)
   1004 	  cd->base_insn_bitsize = isa->base_insn_bitsize;
   1005 	else if (isa->base_insn_bitsize == cd->base_insn_bitsize)
   1006 	  ; /* This is ok.  */
   1007 	else
   1008 	  cd->base_insn_bitsize = CGEN_SIZE_UNKNOWN;
   1009 
   1010 	/* Set min,max insn sizes.  */
   1011 	if (isa->min_insn_bitsize < cd->min_insn_bitsize)
   1012 	  cd->min_insn_bitsize = isa->min_insn_bitsize;
   1013 	if (isa->max_insn_bitsize > cd->max_insn_bitsize)
   1014 	  cd->max_insn_bitsize = isa->max_insn_bitsize;
   1015       }
   1016 
   1017   /* Data derived from the mach spec.  */
   1018   for (i = 0; i < MAX_MACHS; ++i)
   1019     if (((1 << i) & machs) != 0)
   1020       {
   1021 	const CGEN_MACH *mach = & ip2k_cgen_mach_table[i];
   1022 
   1023 	if (mach->insn_chunk_bitsize != 0)
   1024 	{
   1025 	  if (cd->insn_chunk_bitsize != 0 && cd->insn_chunk_bitsize != mach->insn_chunk_bitsize)
   1026 	    {
   1027 	      fprintf (stderr, "ip2k_cgen_rebuild_tables: conflicting insn-chunk-bitsize values: `%d' vs. `%d'\n",
   1028 		       cd->insn_chunk_bitsize, mach->insn_chunk_bitsize);
   1029 	      abort ();
   1030 	    }
   1031 
   1032  	  cd->insn_chunk_bitsize = mach->insn_chunk_bitsize;
   1033 	}
   1034       }
   1035 
   1036   /* Determine which hw elements are used by MACH.  */
   1037   build_hw_table (cd);
   1038 
   1039   /* Build the ifield table.  */
   1040   build_ifield_table (cd);
   1041 
   1042   /* Determine which operands are used by MACH/ISA.  */
   1043   build_operand_table (cd);
   1044 
   1045   /* Build the instruction table.  */
   1046   build_insn_table (cd);
   1047 }
   1048 
   1049 /* Initialize a cpu table and return a descriptor.
   1050    It's much like opening a file, and must be the first function called.
   1051    The arguments are a set of (type/value) pairs, terminated with
   1052    CGEN_CPU_OPEN_END.
   1053 
   1054    Currently supported values:
   1055    CGEN_CPU_OPEN_ISAS:    bitmap of values in enum isa_attr
   1056    CGEN_CPU_OPEN_MACHS:   bitmap of values in enum mach_attr
   1057    CGEN_CPU_OPEN_BFDMACH: specify 1 mach using bfd name
   1058    CGEN_CPU_OPEN_ENDIAN:  specify endian choice
   1059    CGEN_CPU_OPEN_END:     terminates arguments
   1060 
   1061    ??? Simultaneous multiple isas might not make sense, but it's not (yet)
   1062    precluded.
   1063 
   1064    ??? We only support ISO C stdargs here, not K&R.
   1065    Laziness, plus experiment to see if anything requires K&R - eventually
   1066    K&R will no longer be supported - e.g. GDB is currently trying this.  */
   1067 
   1068 CGEN_CPU_DESC
   1069 ip2k_cgen_cpu_open (enum cgen_cpu_open_arg arg_type, ...)
   1070 {
   1071   CGEN_CPU_TABLE *cd = (CGEN_CPU_TABLE *) xmalloc (sizeof (CGEN_CPU_TABLE));
   1072   static int init_p;
   1073   CGEN_BITSET *isas = 0;  /* 0 = "unspecified" */
   1074   unsigned int machs = 0; /* 0 = "unspecified" */
   1075   enum cgen_endian endian = CGEN_ENDIAN_UNKNOWN;
   1076   va_list ap;
   1077 
   1078   if (! init_p)
   1079     {
   1080       init_tables ();
   1081       init_p = 1;
   1082     }
   1083 
   1084   memset (cd, 0, sizeof (*cd));
   1085 
   1086   va_start (ap, arg_type);
   1087   while (arg_type != CGEN_CPU_OPEN_END)
   1088     {
   1089       switch (arg_type)
   1090 	{
   1091 	case CGEN_CPU_OPEN_ISAS :
   1092 	  isas = va_arg (ap, CGEN_BITSET *);
   1093 	  break;
   1094 	case CGEN_CPU_OPEN_MACHS :
   1095 	  machs = va_arg (ap, unsigned int);
   1096 	  break;
   1097 	case CGEN_CPU_OPEN_BFDMACH :
   1098 	  {
   1099 	    const char *name = va_arg (ap, const char *);
   1100 	    const CGEN_MACH *mach =
   1101 	      lookup_mach_via_bfd_name (ip2k_cgen_mach_table, name);
   1102 
   1103 	    machs |= 1 << mach->num;
   1104 	    break;
   1105 	  }
   1106 	case CGEN_CPU_OPEN_ENDIAN :
   1107 	  endian = va_arg (ap, enum cgen_endian);
   1108 	  break;
   1109 	default :
   1110 	  fprintf (stderr, "ip2k_cgen_cpu_open: unsupported argument `%d'\n",
   1111 		   arg_type);
   1112 	  abort (); /* ??? return NULL? */
   1113 	}
   1114       arg_type = va_arg (ap, enum cgen_cpu_open_arg);
   1115     }
   1116   va_end (ap);
   1117 
   1118   /* Mach unspecified means "all".  */
   1119   if (machs == 0)
   1120     machs = (1 << MAX_MACHS) - 1;
   1121   /* Base mach is always selected.  */
   1122   machs |= 1;
   1123   if (endian == CGEN_ENDIAN_UNKNOWN)
   1124     {
   1125       /* ??? If target has only one, could have a default.  */
   1126       fprintf (stderr, "ip2k_cgen_cpu_open: no endianness specified\n");
   1127       abort ();
   1128     }
   1129 
   1130   cd->isas = cgen_bitset_copy (isas);
   1131   cd->machs = machs;
   1132   cd->endian = endian;
   1133   /* FIXME: for the sparc case we can determine insn-endianness statically.
   1134      The worry here is where both data and insn endian can be independently
   1135      chosen, in which case this function will need another argument.
   1136      Actually, will want to allow for more arguments in the future anyway.  */
   1137   cd->insn_endian = endian;
   1138 
   1139   /* Table (re)builder.  */
   1140   cd->rebuild_tables = ip2k_cgen_rebuild_tables;
   1141   ip2k_cgen_rebuild_tables (cd);
   1142 
   1143   /* Default to not allowing signed overflow.  */
   1144   cd->signed_overflow_ok_p = 0;
   1145 
   1146   return (CGEN_CPU_DESC) cd;
   1147 }
   1148 
   1149 /* Cover fn to ip2k_cgen_cpu_open to handle the simple case of 1 isa, 1 mach.
   1150    MACH_NAME is the bfd name of the mach.  */
   1151 
   1152 CGEN_CPU_DESC
   1153 ip2k_cgen_cpu_open_1 (const char *mach_name, enum cgen_endian endian)
   1154 {
   1155   return ip2k_cgen_cpu_open (CGEN_CPU_OPEN_BFDMACH, mach_name,
   1156 			       CGEN_CPU_OPEN_ENDIAN, endian,
   1157 			       CGEN_CPU_OPEN_END);
   1158 }
   1159 
   1160 /* Close a cpu table.
   1161    ??? This can live in a machine independent file, but there's currently
   1162    no place to put this file (there's no libcgen).  libopcodes is the wrong
   1163    place as some simulator ports use this but they don't use libopcodes.  */
   1164 
   1165 void
   1166 ip2k_cgen_cpu_close (CGEN_CPU_DESC cd)
   1167 {
   1168   unsigned int i;
   1169   const CGEN_INSN *insns;
   1170 
   1171   if (cd->macro_insn_table.init_entries)
   1172     {
   1173       insns = cd->macro_insn_table.init_entries;
   1174       for (i = 0; i < cd->macro_insn_table.num_init_entries; ++i, ++insns)
   1175 	if (CGEN_INSN_RX ((insns)))
   1176 	  regfree (CGEN_INSN_RX (insns));
   1177     }
   1178 
   1179   if (cd->insn_table.init_entries)
   1180     {
   1181       insns = cd->insn_table.init_entries;
   1182       for (i = 0; i < cd->insn_table.num_init_entries; ++i, ++insns)
   1183 	if (CGEN_INSN_RX (insns))
   1184 	  regfree (CGEN_INSN_RX (insns));
   1185     }
   1186 
   1187   if (cd->macro_insn_table.init_entries)
   1188     free ((CGEN_INSN *) cd->macro_insn_table.init_entries);
   1189 
   1190   if (cd->insn_table.init_entries)
   1191     free ((CGEN_INSN *) cd->insn_table.init_entries);
   1192 
   1193   if (cd->hw_table.entries)
   1194     free ((CGEN_HW_ENTRY *) cd->hw_table.entries);
   1195 
   1196   if (cd->operand_table.entries)
   1197     free ((CGEN_HW_ENTRY *) cd->operand_table.entries);
   1198 
   1199   free (cd);
   1200 }
   1201 
   1202