Home | History | Annotate | Download | only in opcodes
      1 /* CPU data for ip2k.
      2 
      3 THIS FILE IS MACHINE GENERATED WITH CGEN.
      4 
      5 Copyright (C) 1996-2016 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 #define A(a) (1 << CGEN_HW_##a)
    267 
    268 const CGEN_HW_ENTRY ip2k_cgen_hw_table[] =
    269 {
    270   { "h-memory", HW_H_MEMORY, CGEN_ASM_NONE, 0, { 0, { { { (1<<MACH_BASE), 0 } } } } },
    271   { "h-sint", HW_H_SINT, CGEN_ASM_NONE, 0, { 0, { { { (1<<MACH_BASE), 0 } } } } },
    272   { "h-uint", HW_H_UINT, CGEN_ASM_NONE, 0, { 0, { { { (1<<MACH_BASE), 0 } } } } },
    273   { "h-addr", HW_H_ADDR, CGEN_ASM_NONE, 0, { 0, { { { (1<<MACH_BASE), 0 } } } } },
    274   { "h-iaddr", HW_H_IADDR, CGEN_ASM_NONE, 0, { 0, { { { (1<<MACH_BASE), 0 } } } } },
    275   { "h-spr", HW_H_SPR, CGEN_ASM_NONE, 0, { 0, { { { (1<<MACH_BASE), 0 } } } } },
    276   { "h-registers", HW_H_REGISTERS, CGEN_ASM_NONE, 0, { 0|A(VIRTUAL), { { { (1<<MACH_BASE), 0 } } } } },
    277   { "h-stack", HW_H_STACK, CGEN_ASM_NONE, 0, { 0, { { { (1<<MACH_BASE), 0 } } } } },
    278   { "h-pabits", HW_H_PABITS, CGEN_ASM_NONE, 0, { 0, { { { (1<<MACH_BASE), 0 } } } } },
    279   { "h-zbit", HW_H_ZBIT, CGEN_ASM_NONE, 0, { 0, { { { (1<<MACH_BASE), 0 } } } } },
    280   { "h-cbit", HW_H_CBIT, CGEN_ASM_NONE, 0, { 0, { { { (1<<MACH_BASE), 0 } } } } },
    281   { "h-dcbit", HW_H_DCBIT, CGEN_ASM_NONE, 0, { 0, { { { (1<<MACH_BASE), 0 } } } } },
    282   { "h-pc", HW_H_PC, CGEN_ASM_NONE, 0, { 0|A(PROFILE)|A(PC), { { { (1<<MACH_BASE), 0 } } } } },
    283   { 0, 0, CGEN_ASM_NONE, 0, { 0, { { { (1<<MACH_BASE), 0 } } } } }
    284 };
    285 
    286 #undef A
    287 
    288 
    289 /* The instruction field table.  */
    290 
    291 #define A(a) (1 << CGEN_IFLD_##a)
    292 
    293 const CGEN_IFLD ip2k_cgen_ifld_table[] =
    294 {
    295   { IP2K_F_NIL, "f-nil", 0, 0, 0, 0, { 0, { { { (1<<MACH_BASE), 0 } } } }  },
    296   { IP2K_F_ANYOF, "f-anyof", 0, 0, 0, 0, { 0, { { { (1<<MACH_BASE), 0 } } } }  },
    297   { IP2K_F_IMM8, "f-imm8", 0, 16, 7, 8, { 0, { { { (1<<MACH_BASE), 0 } } } }  },
    298   { IP2K_F_REG, "f-reg", 0, 16, 8, 9, { 0|A(ABS_ADDR), { { { (1<<MACH_BASE), 0 } } } }  },
    299   { IP2K_F_ADDR16CJP, "f-addr16cjp", 0, 16, 12, 13, { 0|A(ABS_ADDR), { { { (1<<MACH_BASE), 0 } } } }  },
    300   { IP2K_F_DIR, "f-dir", 0, 16, 9, 1, { 0, { { { (1<<MACH_BASE), 0 } } } }  },
    301   { IP2K_F_BITNO, "f-bitno", 0, 16, 11, 3, { 0, { { { (1<<MACH_BASE), 0 } } } }  },
    302   { IP2K_F_OP3, "f-op3", 0, 16, 15, 3, { 0, { { { (1<<MACH_BASE), 0 } } } }  },
    303   { IP2K_F_OP4, "f-op4", 0, 16, 15, 4, { 0, { { { (1<<MACH_BASE), 0 } } } }  },
    304   { IP2K_F_OP4MID, "f-op4mid", 0, 16, 11, 4, { 0, { { { (1<<MACH_BASE), 0 } } } }  },
    305   { IP2K_F_OP6, "f-op6", 0, 16, 15, 6, { 0, { { { (1<<MACH_BASE), 0 } } } }  },
    306   { IP2K_F_OP8, "f-op8", 0, 16, 15, 8, { 0, { { { (1<<MACH_BASE), 0 } } } }  },
    307   { IP2K_F_OP6_10LOW, "f-op6-10low", 0, 16, 9, 10, { 0, { { { (1<<MACH_BASE), 0 } } } }  },
    308   { IP2K_F_OP6_7LOW, "f-op6-7low", 0, 16, 9, 7, { 0, { { { (1<<MACH_BASE), 0 } } } }  },
    309   { IP2K_F_RETI3, "f-reti3", 0, 16, 2, 3, { 0, { { { (1<<MACH_BASE), 0 } } } }  },
    310   { IP2K_F_SKIPB, "f-skipb", 0, 16, 12, 1, { 0|A(ABS_ADDR), { { { (1<<MACH_BASE), 0 } } } }  },
    311   { IP2K_F_PAGE3, "f-page3", 0, 16, 2, 3, { 0, { { { (1<<MACH_BASE), 0 } } } }  },
    312   { 0, 0, 0, 0, 0, 0, { 0, { { { (1<<MACH_BASE), 0 } } } } }
    313 };
    314 
    315 #undef A
    316 
    317 
    318 
    319 /* multi ifield declarations */
    320 
    321 
    322 
    323 /* multi ifield definitions */
    324 
    325 
    326 /* The operand table.  */
    327 
    328 #define A(a) (1 << CGEN_OPERAND_##a)
    329 #define OPERAND(op) IP2K_OPERAND_##op
    330 
    331 const CGEN_OPERAND ip2k_cgen_operand_table[] =
    332 {
    333 /* pc: program counter */
    334   { "pc", IP2K_OPERAND_PC, HW_H_PC, 0, 0,
    335     { 0, { (const PTR) &ip2k_cgen_ifld_table[IP2K_F_NIL] } },
    336     { 0|A(SEM_ONLY), { { { (1<<MACH_BASE), 0 } } } }  },
    337 /* addr16cjp: 13-bit address */
    338   { "addr16cjp", IP2K_OPERAND_ADDR16CJP, HW_H_UINT, 12, 13,
    339     { 0, { (const PTR) &ip2k_cgen_ifld_table[IP2K_F_ADDR16CJP] } },
    340     { 0|A(ABS_ADDR), { { { (1<<MACH_BASE), 0 } } } }  },
    341 /* fr: register */
    342   { "fr", IP2K_OPERAND_FR, HW_H_REGISTERS, 8, 9,
    343     { 0, { (const PTR) &ip2k_cgen_ifld_table[IP2K_F_REG] } },
    344     { 0|A(ABS_ADDR), { { { (1<<MACH_BASE), 0 } } } }  },
    345 /* lit8: 8-bit signed literal */
    346   { "lit8", IP2K_OPERAND_LIT8, HW_H_SINT, 7, 8,
    347     { 0, { (const PTR) &ip2k_cgen_ifld_table[IP2K_F_IMM8] } },
    348     { 0, { { { (1<<MACH_BASE), 0 } } } }  },
    349 /* bitno: bit number */
    350   { "bitno", IP2K_OPERAND_BITNO, HW_H_UINT, 11, 3,
    351     { 0, { (const PTR) &ip2k_cgen_ifld_table[IP2K_F_BITNO] } },
    352     { 0, { { { (1<<MACH_BASE), 0 } } } }  },
    353 /* addr16p: page number */
    354   { "addr16p", IP2K_OPERAND_ADDR16P, HW_H_UINT, 2, 3,
    355     { 0, { (const PTR) &ip2k_cgen_ifld_table[IP2K_F_PAGE3] } },
    356     { 0, { { { (1<<MACH_BASE), 0 } } } }  },
    357 /* addr16h: high 8 bits of address */
    358   { "addr16h", IP2K_OPERAND_ADDR16H, HW_H_UINT, 7, 8,
    359     { 0, { (const PTR) &ip2k_cgen_ifld_table[IP2K_F_IMM8] } },
    360     { 0, { { { (1<<MACH_BASE), 0 } } } }  },
    361 /* addr16l: low 8 bits of address */
    362   { "addr16l", IP2K_OPERAND_ADDR16L, HW_H_UINT, 7, 8,
    363     { 0, { (const PTR) &ip2k_cgen_ifld_table[IP2K_F_IMM8] } },
    364     { 0, { { { (1<<MACH_BASE), 0 } } } }  },
    365 /* reti3: reti flags */
    366   { "reti3", IP2K_OPERAND_RETI3, HW_H_UINT, 2, 3,
    367     { 0, { (const PTR) &ip2k_cgen_ifld_table[IP2K_F_RETI3] } },
    368     { 0, { { { (1<<MACH_BASE), 0 } } } }  },
    369 /* pabits: page bits */
    370   { "pabits", IP2K_OPERAND_PABITS, HW_H_PABITS, 0, 0,
    371     { 0, { (const PTR) 0 } },
    372     { 0, { { { (1<<MACH_BASE), 0 } } } }  },
    373 /* zbit: zero bit */
    374   { "zbit", IP2K_OPERAND_ZBIT, HW_H_ZBIT, 0, 0,
    375     { 0, { (const PTR) 0 } },
    376     { 0, { { { (1<<MACH_BASE), 0 } } } }  },
    377 /* cbit: carry bit */
    378   { "cbit", IP2K_OPERAND_CBIT, HW_H_CBIT, 0, 0,
    379     { 0, { (const PTR) 0 } },
    380     { 0, { { { (1<<MACH_BASE), 0 } } } }  },
    381 /* dcbit: digit carry bit */
    382   { "dcbit", IP2K_OPERAND_DCBIT, HW_H_DCBIT, 0, 0,
    383     { 0, { (const PTR) 0 } },
    384     { 0, { { { (1<<MACH_BASE), 0 } } } }  },
    385 /* sentinel */
    386   { 0, 0, 0, 0, 0,
    387     { 0, { (const PTR) 0 } },
    388     { 0, { { { (1<<MACH_BASE), 0 } } } } }
    389 };
    390 
    391 #undef A
    392 
    393 
    394 /* The instruction table.  */
    395 
    396 #define OP(field) CGEN_SYNTAX_MAKE_FIELD (OPERAND (field))
    397 #define A(a) (1 << CGEN_INSN_##a)
    398 
    399 static const CGEN_IBASE ip2k_cgen_insn_table[MAX_INSNS] =
    400 {
    401   /* Special null first entry.
    402      A `num' value of zero is thus invalid.
    403      Also, the special `invalid' insn resides here.  */
    404   { 0, 0, 0, 0, { 0, { { { (1<<MACH_BASE), 0 } } } } },
    405 /* jmp $addr16cjp */
    406   {
    407     IP2K_INSN_JMP, "jmp", "jmp", 16,
    408     { 0|A(UNCOND_CTI), { { { (1<<MACH_BASE), 0 } } } }
    409   },
    410 /* call $addr16cjp */
    411   {
    412     IP2K_INSN_CALL, "call", "call", 16,
    413     { 0|A(UNCOND_CTI), { { { (1<<MACH_BASE), 0 } } } }
    414   },
    415 /* sb $fr,$bitno */
    416   {
    417     IP2K_INSN_SB, "sb", "sb", 16,
    418     { 0|A(SKIP_CTI), { { { (1<<MACH_BASE), 0 } } } }
    419   },
    420 /* snb $fr,$bitno */
    421   {
    422     IP2K_INSN_SNB, "snb", "snb", 16,
    423     { 0|A(SKIP_CTI), { { { (1<<MACH_BASE), 0 } } } }
    424   },
    425 /* setb $fr,$bitno */
    426   {
    427     IP2K_INSN_SETB, "setb", "setb", 16,
    428     { 0, { { { (1<<MACH_BASE), 0 } } } }
    429   },
    430 /* clrb $fr,$bitno */
    431   {
    432     IP2K_INSN_CLRB, "clrb", "clrb", 16,
    433     { 0, { { { (1<<MACH_BASE), 0 } } } }
    434   },
    435 /* xor W,#$lit8 */
    436   {
    437     IP2K_INSN_XORW_L, "xorw_l", "xor", 16,
    438     { 0, { { { (1<<MACH_BASE), 0 } } } }
    439   },
    440 /* and W,#$lit8 */
    441   {
    442     IP2K_INSN_ANDW_L, "andw_l", "and", 16,
    443     { 0, { { { (1<<MACH_BASE), 0 } } } }
    444   },
    445 /* or W,#$lit8 */
    446   {
    447     IP2K_INSN_ORW_L, "orw_l", "or", 16,
    448     { 0, { { { (1<<MACH_BASE), 0 } } } }
    449   },
    450 /* add W,#$lit8 */
    451   {
    452     IP2K_INSN_ADDW_L, "addw_l", "add", 16,
    453     { 0, { { { (1<<MACH_BASE), 0 } } } }
    454   },
    455 /* sub W,#$lit8 */
    456   {
    457     IP2K_INSN_SUBW_L, "subw_l", "sub", 16,
    458     { 0, { { { (1<<MACH_BASE), 0 } } } }
    459   },
    460 /* cmp W,#$lit8 */
    461   {
    462     IP2K_INSN_CMPW_L, "cmpw_l", "cmp", 16,
    463     { 0, { { { (1<<MACH_BASE), 0 } } } }
    464   },
    465 /* retw #$lit8 */
    466   {
    467     IP2K_INSN_RETW_L, "retw_l", "retw", 16,
    468     { 0|A(UNCOND_CTI), { { { (1<<MACH_BASE), 0 } } } }
    469   },
    470 /* cse W,#$lit8 */
    471   {
    472     IP2K_INSN_CSEW_L, "csew_l", "cse", 16,
    473     { 0|A(SKIP_CTI), { { { (1<<MACH_BASE), 0 } } } }
    474   },
    475 /* csne W,#$lit8 */
    476   {
    477     IP2K_INSN_CSNEW_L, "csnew_l", "csne", 16,
    478     { 0|A(SKIP_CTI), { { { (1<<MACH_BASE), 0 } } } }
    479   },
    480 /* push #$lit8 */
    481   {
    482     IP2K_INSN_PUSH_L, "push_l", "push", 16,
    483     { 0, { { { (1<<MACH_BASE), 0 } } } }
    484   },
    485 /* muls W,#$lit8 */
    486   {
    487     IP2K_INSN_MULSW_L, "mulsw_l", "muls", 16,
    488     { 0, { { { (1<<MACH_BASE), 0 } } } }
    489   },
    490 /* mulu W,#$lit8 */
    491   {
    492     IP2K_INSN_MULUW_L, "muluw_l", "mulu", 16,
    493     { 0, { { { (1<<MACH_BASE), 0 } } } }
    494   },
    495 /* loadl #$lit8 */
    496   {
    497     IP2K_INSN_LOADL_L, "loadl_l", "loadl", 16,
    498     { 0|A(EXT_SKIP_INSN), { { { (1<<MACH_BASE), 0 } } } }
    499   },
    500 /* loadh #$lit8 */
    501   {
    502     IP2K_INSN_LOADH_L, "loadh_l", "loadh", 16,
    503     { 0|A(EXT_SKIP_INSN), { { { (1<<MACH_BASE), 0 } } } }
    504   },
    505 /* loadl $addr16l */
    506   {
    507     IP2K_INSN_LOADL_A, "loadl_a", "loadl", 16,
    508     { 0|A(EXT_SKIP_INSN), { { { (1<<MACH_BASE), 0 } } } }
    509   },
    510 /* loadh $addr16h */
    511   {
    512     IP2K_INSN_LOADH_A, "loadh_a", "loadh", 16,
    513     { 0|A(EXT_SKIP_INSN), { { { (1<<MACH_BASE), 0 } } } }
    514   },
    515 /* addc $fr,W */
    516   {
    517     IP2K_INSN_ADDCFR_W, "addcfr_w", "addc", 16,
    518     { 0, { { { (1<<MACH_BASE), 0 } } } }
    519   },
    520 /* addc W,$fr */
    521   {
    522     IP2K_INSN_ADDCW_FR, "addcw_fr", "addc", 16,
    523     { 0, { { { (1<<MACH_BASE), 0 } } } }
    524   },
    525 /* incsnz $fr */
    526   {
    527     IP2K_INSN_INCSNZ_FR, "incsnz_fr", "incsnz", 16,
    528     { 0|A(SKIP_CTI), { { { (1<<MACH_BASE), 0 } } } }
    529   },
    530 /* incsnz W,$fr */
    531   {
    532     IP2K_INSN_INCSNZW_FR, "incsnzw_fr", "incsnz", 16,
    533     { 0|A(SKIP_CTI), { { { (1<<MACH_BASE), 0 } } } }
    534   },
    535 /* muls W,$fr */
    536   {
    537     IP2K_INSN_MULSW_FR, "mulsw_fr", "muls", 16,
    538     { 0, { { { (1<<MACH_BASE), 0 } } } }
    539   },
    540 /* mulu W,$fr */
    541   {
    542     IP2K_INSN_MULUW_FR, "muluw_fr", "mulu", 16,
    543     { 0, { { { (1<<MACH_BASE), 0 } } } }
    544   },
    545 /* decsnz $fr */
    546   {
    547     IP2K_INSN_DECSNZ_FR, "decsnz_fr", "decsnz", 16,
    548     { 0|A(SKIP_CTI), { { { (1<<MACH_BASE), 0 } } } }
    549   },
    550 /* decsnz W,$fr */
    551   {
    552     IP2K_INSN_DECSNZW_FR, "decsnzw_fr", "decsnz", 16,
    553     { 0|A(SKIP_CTI), { { { (1<<MACH_BASE), 0 } } } }
    554   },
    555 /* subc W,$fr */
    556   {
    557     IP2K_INSN_SUBCW_FR, "subcw_fr", "subc", 16,
    558     { 0, { { { (1<<MACH_BASE), 0 } } } }
    559   },
    560 /* subc $fr,W */
    561   {
    562     IP2K_INSN_SUBCFR_W, "subcfr_w", "subc", 16,
    563     { 0, { { { (1<<MACH_BASE), 0 } } } }
    564   },
    565 /* pop $fr */
    566   {
    567     IP2K_INSN_POP_FR, "pop_fr", "pop", 16,
    568     { 0, { { { (1<<MACH_BASE), 0 } } } }
    569   },
    570 /* push $fr */
    571   {
    572     IP2K_INSN_PUSH_FR, "push_fr", "push", 16,
    573     { 0, { { { (1<<MACH_BASE), 0 } } } }
    574   },
    575 /* cse W,$fr */
    576   {
    577     IP2K_INSN_CSEW_FR, "csew_fr", "cse", 16,
    578     { 0|A(SKIP_CTI), { { { (1<<MACH_BASE), 0 } } } }
    579   },
    580 /* csne W,$fr */
    581   {
    582     IP2K_INSN_CSNEW_FR, "csnew_fr", "csne", 16,
    583     { 0|A(SKIP_CTI), { { { (1<<MACH_BASE), 0 } } } }
    584   },
    585 /* incsz $fr */
    586   {
    587     IP2K_INSN_INCSZ_FR, "incsz_fr", "incsz", 16,
    588     { 0|A(SKIP_CTI), { { { (1<<MACH_BASE), 0 } } } }
    589   },
    590 /* incsz W,$fr */
    591   {
    592     IP2K_INSN_INCSZW_FR, "incszw_fr", "incsz", 16,
    593     { 0|A(SKIP_CTI), { { { (1<<MACH_BASE), 0 } } } }
    594   },
    595 /* swap $fr */
    596   {
    597     IP2K_INSN_SWAP_FR, "swap_fr", "swap", 16,
    598     { 0, { { { (1<<MACH_BASE), 0 } } } }
    599   },
    600 /* swap W,$fr */
    601   {
    602     IP2K_INSN_SWAPW_FR, "swapw_fr", "swap", 16,
    603     { 0, { { { (1<<MACH_BASE), 0 } } } }
    604   },
    605 /* rl $fr */
    606   {
    607     IP2K_INSN_RL_FR, "rl_fr", "rl", 16,
    608     { 0, { { { (1<<MACH_BASE), 0 } } } }
    609   },
    610 /* rl W,$fr */
    611   {
    612     IP2K_INSN_RLW_FR, "rlw_fr", "rl", 16,
    613     { 0, { { { (1<<MACH_BASE), 0 } } } }
    614   },
    615 /* rr $fr */
    616   {
    617     IP2K_INSN_RR_FR, "rr_fr", "rr", 16,
    618     { 0, { { { (1<<MACH_BASE), 0 } } } }
    619   },
    620 /* rr W,$fr */
    621   {
    622     IP2K_INSN_RRW_FR, "rrw_fr", "rr", 16,
    623     { 0, { { { (1<<MACH_BASE), 0 } } } }
    624   },
    625 /* decsz $fr */
    626   {
    627     IP2K_INSN_DECSZ_FR, "decsz_fr", "decsz", 16,
    628     { 0|A(SKIP_CTI), { { { (1<<MACH_BASE), 0 } } } }
    629   },
    630 /* decsz W,$fr */
    631   {
    632     IP2K_INSN_DECSZW_FR, "decszw_fr", "decsz", 16,
    633     { 0|A(SKIP_CTI), { { { (1<<MACH_BASE), 0 } } } }
    634   },
    635 /* inc $fr */
    636   {
    637     IP2K_INSN_INC_FR, "inc_fr", "inc", 16,
    638     { 0, { { { (1<<MACH_BASE), 0 } } } }
    639   },
    640 /* inc W,$fr */
    641   {
    642     IP2K_INSN_INCW_FR, "incw_fr", "inc", 16,
    643     { 0, { { { (1<<MACH_BASE), 0 } } } }
    644   },
    645 /* not $fr */
    646   {
    647     IP2K_INSN_NOT_FR, "not_fr", "not", 16,
    648     { 0, { { { (1<<MACH_BASE), 0 } } } }
    649   },
    650 /* not W,$fr */
    651   {
    652     IP2K_INSN_NOTW_FR, "notw_fr", "not", 16,
    653     { 0, { { { (1<<MACH_BASE), 0 } } } }
    654   },
    655 /* test $fr */
    656   {
    657     IP2K_INSN_TEST_FR, "test_fr", "test", 16,
    658     { 0, { { { (1<<MACH_BASE), 0 } } } }
    659   },
    660 /* mov W,#$lit8 */
    661   {
    662     IP2K_INSN_MOVW_L, "movw_l", "mov", 16,
    663     { 0, { { { (1<<MACH_BASE), 0 } } } }
    664   },
    665 /* mov $fr,W */
    666   {
    667     IP2K_INSN_MOVFR_W, "movfr_w", "mov", 16,
    668     { 0, { { { (1<<MACH_BASE), 0 } } } }
    669   },
    670 /* mov W,$fr */
    671   {
    672     IP2K_INSN_MOVW_FR, "movw_fr", "mov", 16,
    673     { 0, { { { (1<<MACH_BASE), 0 } } } }
    674   },
    675 /* add $fr,W */
    676   {
    677     IP2K_INSN_ADDFR_W, "addfr_w", "add", 16,
    678     { 0, { { { (1<<MACH_BASE), 0 } } } }
    679   },
    680 /* add W,$fr */
    681   {
    682     IP2K_INSN_ADDW_FR, "addw_fr", "add", 16,
    683     { 0, { { { (1<<MACH_BASE), 0 } } } }
    684   },
    685 /* xor $fr,W */
    686   {
    687     IP2K_INSN_XORFR_W, "xorfr_w", "xor", 16,
    688     { 0, { { { (1<<MACH_BASE), 0 } } } }
    689   },
    690 /* xor W,$fr */
    691   {
    692     IP2K_INSN_XORW_FR, "xorw_fr", "xor", 16,
    693     { 0, { { { (1<<MACH_BASE), 0 } } } }
    694   },
    695 /* and $fr,W */
    696   {
    697     IP2K_INSN_ANDFR_W, "andfr_w", "and", 16,
    698     { 0, { { { (1<<MACH_BASE), 0 } } } }
    699   },
    700 /* and W,$fr */
    701   {
    702     IP2K_INSN_ANDW_FR, "andw_fr", "and", 16,
    703     { 0, { { { (1<<MACH_BASE), 0 } } } }
    704   },
    705 /* or $fr,W */
    706   {
    707     IP2K_INSN_ORFR_W, "orfr_w", "or", 16,
    708     { 0, { { { (1<<MACH_BASE), 0 } } } }
    709   },
    710 /* or W,$fr */
    711   {
    712     IP2K_INSN_ORW_FR, "orw_fr", "or", 16,
    713     { 0, { { { (1<<MACH_BASE), 0 } } } }
    714   },
    715 /* dec $fr */
    716   {
    717     IP2K_INSN_DEC_FR, "dec_fr", "dec", 16,
    718     { 0, { { { (1<<MACH_BASE), 0 } } } }
    719   },
    720 /* dec W,$fr */
    721   {
    722     IP2K_INSN_DECW_FR, "decw_fr", "dec", 16,
    723     { 0, { { { (1<<MACH_BASE), 0 } } } }
    724   },
    725 /* sub $fr,W */
    726   {
    727     IP2K_INSN_SUBFR_W, "subfr_w", "sub", 16,
    728     { 0, { { { (1<<MACH_BASE), 0 } } } }
    729   },
    730 /* sub W,$fr */
    731   {
    732     IP2K_INSN_SUBW_FR, "subw_fr", "sub", 16,
    733     { 0, { { { (1<<MACH_BASE), 0 } } } }
    734   },
    735 /* clr $fr */
    736   {
    737     IP2K_INSN_CLR_FR, "clr_fr", "clr", 16,
    738     { 0, { { { (1<<MACH_BASE), 0 } } } }
    739   },
    740 /* cmp W,$fr */
    741   {
    742     IP2K_INSN_CMPW_FR, "cmpw_fr", "cmp", 16,
    743     { 0, { { { (1<<MACH_BASE), 0 } } } }
    744   },
    745 /* speed #$lit8 */
    746   {
    747     IP2K_INSN_SPEED, "speed", "speed", 16,
    748     { 0, { { { (1<<MACH_BASE), 0 } } } }
    749   },
    750 /* ireadi */
    751   {
    752     IP2K_INSN_IREADI, "ireadi", "ireadi", 16,
    753     { 0, { { { (1<<MACH_BASE), 0 } } } }
    754   },
    755 /* iwritei */
    756   {
    757     IP2K_INSN_IWRITEI, "iwritei", "iwritei", 16,
    758     { 0, { { { (1<<MACH_BASE), 0 } } } }
    759   },
    760 /* fread */
    761   {
    762     IP2K_INSN_FREAD, "fread", "fread", 16,
    763     { 0, { { { (1<<MACH_BASE), 0 } } } }
    764   },
    765 /* fwrite */
    766   {
    767     IP2K_INSN_FWRITE, "fwrite", "fwrite", 16,
    768     { 0, { { { (1<<MACH_BASE), 0 } } } }
    769   },
    770 /* iread */
    771   {
    772     IP2K_INSN_IREAD, "iread", "iread", 16,
    773     { 0, { { { (1<<MACH_BASE), 0 } } } }
    774   },
    775 /* iwrite */
    776   {
    777     IP2K_INSN_IWRITE, "iwrite", "iwrite", 16,
    778     { 0, { { { (1<<MACH_BASE), 0 } } } }
    779   },
    780 /* page $addr16p */
    781   {
    782     IP2K_INSN_PAGE, "page", "page", 16,
    783     { 0|A(EXT_SKIP_INSN), { { { (1<<MACH_BASE), 0 } } } }
    784   },
    785 /* system */
    786   {
    787     IP2K_INSN_SYSTEM, "system", "system", 16,
    788     { 0, { { { (1<<MACH_BASE), 0 } } } }
    789   },
    790 /* reti #$reti3 */
    791   {
    792     IP2K_INSN_RETI, "reti", "reti", 16,
    793     { 0, { { { (1<<MACH_BASE), 0 } } } }
    794   },
    795 /* ret */
    796   {
    797     IP2K_INSN_RET, "ret", "ret", 16,
    798     { 0|A(UNCOND_CTI), { { { (1<<MACH_BASE), 0 } } } }
    799   },
    800 /* int */
    801   {
    802     IP2K_INSN_INT, "int", "int", 16,
    803     { 0, { { { (1<<MACH_BASE), 0 } } } }
    804   },
    805 /* breakx */
    806   {
    807     IP2K_INSN_BREAKX, "breakx", "breakx", 16,
    808     { 0|A(EXT_SKIP_INSN), { { { (1<<MACH_BASE), 0 } } } }
    809   },
    810 /* cwdt */
    811   {
    812     IP2K_INSN_CWDT, "cwdt", "cwdt", 16,
    813     { 0, { { { (1<<MACH_BASE), 0 } } } }
    814   },
    815 /* ferase */
    816   {
    817     IP2K_INSN_FERASE, "ferase", "ferase", 16,
    818     { 0, { { { (1<<MACH_BASE), 0 } } } }
    819   },
    820 /* retnp */
    821   {
    822     IP2K_INSN_RETNP, "retnp", "retnp", 16,
    823     { 0|A(UNCOND_CTI), { { { (1<<MACH_BASE), 0 } } } }
    824   },
    825 /* break */
    826   {
    827     IP2K_INSN_BREAK, "break", "break", 16,
    828     { 0, { { { (1<<MACH_BASE), 0 } } } }
    829   },
    830 /* nop */
    831   {
    832     IP2K_INSN_NOP, "nop", "nop", 16,
    833     { 0, { { { (1<<MACH_BASE), 0 } } } }
    834   },
    835 };
    836 
    837 #undef OP
    838 #undef A
    839 
    840 /* Initialize anything needed to be done once, before any cpu_open call.  */
    841 
    842 static void
    843 init_tables (void)
    844 {
    845 }
    846 
    847 static const CGEN_MACH * lookup_mach_via_bfd_name (const CGEN_MACH *, const char *);
    848 static void build_hw_table      (CGEN_CPU_TABLE *);
    849 static void build_ifield_table  (CGEN_CPU_TABLE *);
    850 static void build_operand_table (CGEN_CPU_TABLE *);
    851 static void build_insn_table    (CGEN_CPU_TABLE *);
    852 static void ip2k_cgen_rebuild_tables (CGEN_CPU_TABLE *);
    853 
    854 /* Subroutine of ip2k_cgen_cpu_open to look up a mach via its bfd name.  */
    855 
    856 static const CGEN_MACH *
    857 lookup_mach_via_bfd_name (const CGEN_MACH *table, const char *name)
    858 {
    859   while (table->name)
    860     {
    861       if (strcmp (name, table->bfd_name) == 0)
    862 	return table;
    863       ++table;
    864     }
    865   abort ();
    866 }
    867 
    868 /* Subroutine of ip2k_cgen_cpu_open to build the hardware table.  */
    869 
    870 static void
    871 build_hw_table (CGEN_CPU_TABLE *cd)
    872 {
    873   int i;
    874   int machs = cd->machs;
    875   const CGEN_HW_ENTRY *init = & ip2k_cgen_hw_table[0];
    876   /* MAX_HW is only an upper bound on the number of selected entries.
    877      However each entry is indexed by it's enum so there can be holes in
    878      the table.  */
    879   const CGEN_HW_ENTRY **selected =
    880     (const CGEN_HW_ENTRY **) xmalloc (MAX_HW * sizeof (CGEN_HW_ENTRY *));
    881 
    882   cd->hw_table.init_entries = init;
    883   cd->hw_table.entry_size = sizeof (CGEN_HW_ENTRY);
    884   memset (selected, 0, MAX_HW * sizeof (CGEN_HW_ENTRY *));
    885   /* ??? For now we just use machs to determine which ones we want.  */
    886   for (i = 0; init[i].name != NULL; ++i)
    887     if (CGEN_HW_ATTR_VALUE (&init[i], CGEN_HW_MACH)
    888 	& machs)
    889       selected[init[i].type] = &init[i];
    890   cd->hw_table.entries = selected;
    891   cd->hw_table.num_entries = MAX_HW;
    892 }
    893 
    894 /* Subroutine of ip2k_cgen_cpu_open to build the hardware table.  */
    895 
    896 static void
    897 build_ifield_table (CGEN_CPU_TABLE *cd)
    898 {
    899   cd->ifld_table = & ip2k_cgen_ifld_table[0];
    900 }
    901 
    902 /* Subroutine of ip2k_cgen_cpu_open to build the hardware table.  */
    903 
    904 static void
    905 build_operand_table (CGEN_CPU_TABLE *cd)
    906 {
    907   int i;
    908   int machs = cd->machs;
    909   const CGEN_OPERAND *init = & ip2k_cgen_operand_table[0];
    910   /* MAX_OPERANDS is only an upper bound on the number of selected entries.
    911      However each entry is indexed by it's enum so there can be holes in
    912      the table.  */
    913   const CGEN_OPERAND **selected = xmalloc (MAX_OPERANDS * sizeof (* selected));
    914 
    915   cd->operand_table.init_entries = init;
    916   cd->operand_table.entry_size = sizeof (CGEN_OPERAND);
    917   memset (selected, 0, MAX_OPERANDS * sizeof (CGEN_OPERAND *));
    918   /* ??? For now we just use mach to determine which ones we want.  */
    919   for (i = 0; init[i].name != NULL; ++i)
    920     if (CGEN_OPERAND_ATTR_VALUE (&init[i], CGEN_OPERAND_MACH)
    921 	& machs)
    922       selected[init[i].type] = &init[i];
    923   cd->operand_table.entries = selected;
    924   cd->operand_table.num_entries = MAX_OPERANDS;
    925 }
    926 
    927 /* Subroutine of ip2k_cgen_cpu_open to build the hardware table.
    928    ??? This could leave out insns not supported by the specified mach/isa,
    929    but that would cause errors like "foo only supported by bar" to become
    930    "unknown insn", so for now we include all insns and require the app to
    931    do the checking later.
    932    ??? On the other hand, parsing of such insns may require their hardware or
    933    operand elements to be in the table [which they mightn't be].  */
    934 
    935 static void
    936 build_insn_table (CGEN_CPU_TABLE *cd)
    937 {
    938   int i;
    939   const CGEN_IBASE *ib = & ip2k_cgen_insn_table[0];
    940   CGEN_INSN *insns = xmalloc (MAX_INSNS * sizeof (CGEN_INSN));
    941 
    942   memset (insns, 0, MAX_INSNS * sizeof (CGEN_INSN));
    943   for (i = 0; i < MAX_INSNS; ++i)
    944     insns[i].base = &ib[i];
    945   cd->insn_table.init_entries = insns;
    946   cd->insn_table.entry_size = sizeof (CGEN_IBASE);
    947   cd->insn_table.num_init_entries = MAX_INSNS;
    948 }
    949 
    950 /* Subroutine of ip2k_cgen_cpu_open to rebuild the tables.  */
    951 
    952 static void
    953 ip2k_cgen_rebuild_tables (CGEN_CPU_TABLE *cd)
    954 {
    955   int i;
    956   CGEN_BITSET *isas = cd->isas;
    957   unsigned int machs = cd->machs;
    958 
    959   cd->int_insn_p = CGEN_INT_INSN_P;
    960 
    961   /* Data derived from the isa spec.  */
    962 #define UNSET (CGEN_SIZE_UNKNOWN + 1)
    963   cd->default_insn_bitsize = UNSET;
    964   cd->base_insn_bitsize = UNSET;
    965   cd->min_insn_bitsize = 65535; /* Some ridiculously big number.  */
    966   cd->max_insn_bitsize = 0;
    967   for (i = 0; i < MAX_ISAS; ++i)
    968     if (cgen_bitset_contains (isas, i))
    969       {
    970 	const CGEN_ISA *isa = & ip2k_cgen_isa_table[i];
    971 
    972 	/* Default insn sizes of all selected isas must be
    973 	   equal or we set the result to 0, meaning "unknown".  */
    974 	if (cd->default_insn_bitsize == UNSET)
    975 	  cd->default_insn_bitsize = isa->default_insn_bitsize;
    976 	else if (isa->default_insn_bitsize == cd->default_insn_bitsize)
    977 	  ; /* This is ok.  */
    978 	else
    979 	  cd->default_insn_bitsize = CGEN_SIZE_UNKNOWN;
    980 
    981 	/* Base insn sizes of all selected isas must be equal
    982 	   or we set the result to 0, meaning "unknown".  */
    983 	if (cd->base_insn_bitsize == UNSET)
    984 	  cd->base_insn_bitsize = isa->base_insn_bitsize;
    985 	else if (isa->base_insn_bitsize == cd->base_insn_bitsize)
    986 	  ; /* This is ok.  */
    987 	else
    988 	  cd->base_insn_bitsize = CGEN_SIZE_UNKNOWN;
    989 
    990 	/* Set min,max insn sizes.  */
    991 	if (isa->min_insn_bitsize < cd->min_insn_bitsize)
    992 	  cd->min_insn_bitsize = isa->min_insn_bitsize;
    993 	if (isa->max_insn_bitsize > cd->max_insn_bitsize)
    994 	  cd->max_insn_bitsize = isa->max_insn_bitsize;
    995       }
    996 
    997   /* Data derived from the mach spec.  */
    998   for (i = 0; i < MAX_MACHS; ++i)
    999     if (((1 << i) & machs) != 0)
   1000       {
   1001 	const CGEN_MACH *mach = & ip2k_cgen_mach_table[i];
   1002 
   1003 	if (mach->insn_chunk_bitsize != 0)
   1004 	{
   1005 	  if (cd->insn_chunk_bitsize != 0 && cd->insn_chunk_bitsize != mach->insn_chunk_bitsize)
   1006 	    {
   1007 	      fprintf (stderr, "ip2k_cgen_rebuild_tables: conflicting insn-chunk-bitsize values: `%d' vs. `%d'\n",
   1008 		       cd->insn_chunk_bitsize, mach->insn_chunk_bitsize);
   1009 	      abort ();
   1010 	    }
   1011 
   1012  	  cd->insn_chunk_bitsize = mach->insn_chunk_bitsize;
   1013 	}
   1014       }
   1015 
   1016   /* Determine which hw elements are used by MACH.  */
   1017   build_hw_table (cd);
   1018 
   1019   /* Build the ifield table.  */
   1020   build_ifield_table (cd);
   1021 
   1022   /* Determine which operands are used by MACH/ISA.  */
   1023   build_operand_table (cd);
   1024 
   1025   /* Build the instruction table.  */
   1026   build_insn_table (cd);
   1027 }
   1028 
   1029 /* Initialize a cpu table and return a descriptor.
   1030    It's much like opening a file, and must be the first function called.
   1031    The arguments are a set of (type/value) pairs, terminated with
   1032    CGEN_CPU_OPEN_END.
   1033 
   1034    Currently supported values:
   1035    CGEN_CPU_OPEN_ISAS:    bitmap of values in enum isa_attr
   1036    CGEN_CPU_OPEN_MACHS:   bitmap of values in enum mach_attr
   1037    CGEN_CPU_OPEN_BFDMACH: specify 1 mach using bfd name
   1038    CGEN_CPU_OPEN_ENDIAN:  specify endian choice
   1039    CGEN_CPU_OPEN_END:     terminates arguments
   1040 
   1041    ??? Simultaneous multiple isas might not make sense, but it's not (yet)
   1042    precluded.  */
   1043 
   1044 CGEN_CPU_DESC
   1045 ip2k_cgen_cpu_open (enum cgen_cpu_open_arg arg_type, ...)
   1046 {
   1047   CGEN_CPU_TABLE *cd = (CGEN_CPU_TABLE *) xmalloc (sizeof (CGEN_CPU_TABLE));
   1048   static int init_p;
   1049   CGEN_BITSET *isas = 0;  /* 0 = "unspecified" */
   1050   unsigned int machs = 0; /* 0 = "unspecified" */
   1051   enum cgen_endian endian = CGEN_ENDIAN_UNKNOWN;
   1052   va_list ap;
   1053 
   1054   if (! init_p)
   1055     {
   1056       init_tables ();
   1057       init_p = 1;
   1058     }
   1059 
   1060   memset (cd, 0, sizeof (*cd));
   1061 
   1062   va_start (ap, arg_type);
   1063   while (arg_type != CGEN_CPU_OPEN_END)
   1064     {
   1065       switch (arg_type)
   1066 	{
   1067 	case CGEN_CPU_OPEN_ISAS :
   1068 	  isas = va_arg (ap, CGEN_BITSET *);
   1069 	  break;
   1070 	case CGEN_CPU_OPEN_MACHS :
   1071 	  machs = va_arg (ap, unsigned int);
   1072 	  break;
   1073 	case CGEN_CPU_OPEN_BFDMACH :
   1074 	  {
   1075 	    const char *name = va_arg (ap, const char *);
   1076 	    const CGEN_MACH *mach =
   1077 	      lookup_mach_via_bfd_name (ip2k_cgen_mach_table, name);
   1078 
   1079 	    machs |= 1 << mach->num;
   1080 	    break;
   1081 	  }
   1082 	case CGEN_CPU_OPEN_ENDIAN :
   1083 	  endian = va_arg (ap, enum cgen_endian);
   1084 	  break;
   1085 	default :
   1086 	  fprintf (stderr, "ip2k_cgen_cpu_open: unsupported argument `%d'\n",
   1087 		   arg_type);
   1088 	  abort (); /* ??? return NULL? */
   1089 	}
   1090       arg_type = va_arg (ap, enum cgen_cpu_open_arg);
   1091     }
   1092   va_end (ap);
   1093 
   1094   /* Mach unspecified means "all".  */
   1095   if (machs == 0)
   1096     machs = (1 << MAX_MACHS) - 1;
   1097   /* Base mach is always selected.  */
   1098   machs |= 1;
   1099   if (endian == CGEN_ENDIAN_UNKNOWN)
   1100     {
   1101       /* ??? If target has only one, could have a default.  */
   1102       fprintf (stderr, "ip2k_cgen_cpu_open: no endianness specified\n");
   1103       abort ();
   1104     }
   1105 
   1106   cd->isas = cgen_bitset_copy (isas);
   1107   cd->machs = machs;
   1108   cd->endian = endian;
   1109   /* FIXME: for the sparc case we can determine insn-endianness statically.
   1110      The worry here is where both data and insn endian can be independently
   1111      chosen, in which case this function will need another argument.
   1112      Actually, will want to allow for more arguments in the future anyway.  */
   1113   cd->insn_endian = endian;
   1114 
   1115   /* Table (re)builder.  */
   1116   cd->rebuild_tables = ip2k_cgen_rebuild_tables;
   1117   ip2k_cgen_rebuild_tables (cd);
   1118 
   1119   /* Default to not allowing signed overflow.  */
   1120   cd->signed_overflow_ok_p = 0;
   1121 
   1122   return (CGEN_CPU_DESC) cd;
   1123 }
   1124 
   1125 /* Cover fn to ip2k_cgen_cpu_open to handle the simple case of 1 isa, 1 mach.
   1126    MACH_NAME is the bfd name of the mach.  */
   1127 
   1128 CGEN_CPU_DESC
   1129 ip2k_cgen_cpu_open_1 (const char *mach_name, enum cgen_endian endian)
   1130 {
   1131   return ip2k_cgen_cpu_open (CGEN_CPU_OPEN_BFDMACH, mach_name,
   1132 			       CGEN_CPU_OPEN_ENDIAN, endian,
   1133 			       CGEN_CPU_OPEN_END);
   1134 }
   1135 
   1136 /* Close a cpu table.
   1137    ??? This can live in a machine independent file, but there's currently
   1138    no place to put this file (there's no libcgen).  libopcodes is the wrong
   1139    place as some simulator ports use this but they don't use libopcodes.  */
   1140 
   1141 void
   1142 ip2k_cgen_cpu_close (CGEN_CPU_DESC cd)
   1143 {
   1144   unsigned int i;
   1145   const CGEN_INSN *insns;
   1146 
   1147   if (cd->macro_insn_table.init_entries)
   1148     {
   1149       insns = cd->macro_insn_table.init_entries;
   1150       for (i = 0; i < cd->macro_insn_table.num_init_entries; ++i, ++insns)
   1151 	if (CGEN_INSN_RX ((insns)))
   1152 	  regfree (CGEN_INSN_RX (insns));
   1153     }
   1154 
   1155   if (cd->insn_table.init_entries)
   1156     {
   1157       insns = cd->insn_table.init_entries;
   1158       for (i = 0; i < cd->insn_table.num_init_entries; ++i, ++insns)
   1159 	if (CGEN_INSN_RX (insns))
   1160 	  regfree (CGEN_INSN_RX (insns));
   1161     }
   1162 
   1163   if (cd->macro_insn_table.init_entries)
   1164     free ((CGEN_INSN *) cd->macro_insn_table.init_entries);
   1165 
   1166   if (cd->insn_table.init_entries)
   1167     free ((CGEN_INSN *) cd->insn_table.init_entries);
   1168 
   1169   if (cd->hw_table.entries)
   1170     free ((CGEN_HW_ENTRY *) cd->hw_table.entries);
   1171 
   1172   if (cd->operand_table.entries)
   1173     free ((CGEN_HW_ENTRY *) cd->operand_table.entries);
   1174 
   1175   free (cd);
   1176 }
   1177 
   1178