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