Home | History | Annotate | Line # | Download | only in opcodes
lm32-desc.c revision 1.10
      1 /* DO NOT EDIT!  -*- buffer-read-only: t -*- vi:set ro:  */
      2 /* CPU data for lm32.
      3 
      4 THIS FILE IS MACHINE GENERATED WITH CGEN.
      5 
      6 Copyright (C) 1996-2022 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 <stdlib.h>
     30 #include "ansidecl.h"
     31 #include "bfd.h"
     32 #include "symcat.h"
     33 #include "lm32-desc.h"
     34 #include "lm32-opc.h"
     35 #include "opintl.h"
     36 #include "libiberty.h"
     37 #include "xregex.h"
     38 
     39 /* Attributes.  */
     40 
     41 static const CGEN_ATTR_ENTRY bool_attr[] =
     42 {
     43   { "#f", 0 },
     44   { "#t", 1 },
     45   { 0, 0 }
     46 };
     47 
     48 static const CGEN_ATTR_ENTRY MACH_attr[] ATTRIBUTE_UNUSED =
     49 {
     50   { "base", MACH_BASE },
     51   { "lm32", MACH_LM32 },
     52   { "max", MACH_MAX },
     53   { 0, 0 }
     54 };
     55 
     56 static const CGEN_ATTR_ENTRY ISA_attr[] ATTRIBUTE_UNUSED =
     57 {
     58   { "lm32", ISA_LM32 },
     59   { "max", ISA_MAX },
     60   { 0, 0 }
     61 };
     62 
     63 const CGEN_ATTR_TABLE lm32_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 lm32_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 lm32_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 lm32_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   { 0, 0, 0 }
    113 };
    114 
    115 /* Instruction set variants.  */
    116 
    117 static const CGEN_ISA lm32_cgen_isa_table[] = {
    118   { "lm32", 32, 32, 32, 32 },
    119   { 0, 0, 0, 0, 0 }
    120 };
    121 
    122 /* Machine variants.  */
    123 
    124 static const CGEN_MACH lm32_cgen_mach_table[] = {
    125   { "lm32", "lm32", MACH_LM32, 0 },
    126   { 0, 0, 0, 0 }
    127 };
    128 
    129 static CGEN_KEYWORD_ENTRY lm32_cgen_opval_h_gr_entries[] =
    130 {
    131   { "gp", 26, {0, {{{0, 0}}}}, 0, 0 },
    132   { "fp", 27, {0, {{{0, 0}}}}, 0, 0 },
    133   { "sp", 28, {0, {{{0, 0}}}}, 0, 0 },
    134   { "ra", 29, {0, {{{0, 0}}}}, 0, 0 },
    135   { "ea", 30, {0, {{{0, 0}}}}, 0, 0 },
    136   { "ba", 31, {0, {{{0, 0}}}}, 0, 0 },
    137   { "r0", 0, {0, {{{0, 0}}}}, 0, 0 },
    138   { "r1", 1, {0, {{{0, 0}}}}, 0, 0 },
    139   { "r2", 2, {0, {{{0, 0}}}}, 0, 0 },
    140   { "r3", 3, {0, {{{0, 0}}}}, 0, 0 },
    141   { "r4", 4, {0, {{{0, 0}}}}, 0, 0 },
    142   { "r5", 5, {0, {{{0, 0}}}}, 0, 0 },
    143   { "r6", 6, {0, {{{0, 0}}}}, 0, 0 },
    144   { "r7", 7, {0, {{{0, 0}}}}, 0, 0 },
    145   { "r8", 8, {0, {{{0, 0}}}}, 0, 0 },
    146   { "r9", 9, {0, {{{0, 0}}}}, 0, 0 },
    147   { "r10", 10, {0, {{{0, 0}}}}, 0, 0 },
    148   { "r11", 11, {0, {{{0, 0}}}}, 0, 0 },
    149   { "r12", 12, {0, {{{0, 0}}}}, 0, 0 },
    150   { "r13", 13, {0, {{{0, 0}}}}, 0, 0 },
    151   { "r14", 14, {0, {{{0, 0}}}}, 0, 0 },
    152   { "r15", 15, {0, {{{0, 0}}}}, 0, 0 },
    153   { "r16", 16, {0, {{{0, 0}}}}, 0, 0 },
    154   { "r17", 17, {0, {{{0, 0}}}}, 0, 0 },
    155   { "r18", 18, {0, {{{0, 0}}}}, 0, 0 },
    156   { "r19", 19, {0, {{{0, 0}}}}, 0, 0 },
    157   { "r20", 20, {0, {{{0, 0}}}}, 0, 0 },
    158   { "r21", 21, {0, {{{0, 0}}}}, 0, 0 },
    159   { "r22", 22, {0, {{{0, 0}}}}, 0, 0 },
    160   { "r23", 23, {0, {{{0, 0}}}}, 0, 0 },
    161   { "r24", 24, {0, {{{0, 0}}}}, 0, 0 },
    162   { "r25", 25, {0, {{{0, 0}}}}, 0, 0 },
    163   { "r26", 26, {0, {{{0, 0}}}}, 0, 0 },
    164   { "r27", 27, {0, {{{0, 0}}}}, 0, 0 },
    165   { "r28", 28, {0, {{{0, 0}}}}, 0, 0 },
    166   { "r29", 29, {0, {{{0, 0}}}}, 0, 0 },
    167   { "r30", 30, {0, {{{0, 0}}}}, 0, 0 },
    168   { "r31", 31, {0, {{{0, 0}}}}, 0, 0 }
    169 };
    170 
    171 CGEN_KEYWORD lm32_cgen_opval_h_gr =
    172 {
    173   & lm32_cgen_opval_h_gr_entries[0],
    174   38,
    175   0, 0, 0, 0, ""
    176 };
    177 
    178 static CGEN_KEYWORD_ENTRY lm32_cgen_opval_h_csr_entries[] =
    179 {
    180   { "IE", 0, {0, {{{0, 0}}}}, 0, 0 },
    181   { "IM", 1, {0, {{{0, 0}}}}, 0, 0 },
    182   { "IP", 2, {0, {{{0, 0}}}}, 0, 0 },
    183   { "ICC", 3, {0, {{{0, 0}}}}, 0, 0 },
    184   { "DCC", 4, {0, {{{0, 0}}}}, 0, 0 },
    185   { "CC", 5, {0, {{{0, 0}}}}, 0, 0 },
    186   { "CFG", 6, {0, {{{0, 0}}}}, 0, 0 },
    187   { "EBA", 7, {0, {{{0, 0}}}}, 0, 0 },
    188   { "DC", 8, {0, {{{0, 0}}}}, 0, 0 },
    189   { "DEBA", 9, {0, {{{0, 0}}}}, 0, 0 },
    190   { "CFG2", 10, {0, {{{0, 0}}}}, 0, 0 },
    191   { "JTX", 14, {0, {{{0, 0}}}}, 0, 0 },
    192   { "JRX", 15, {0, {{{0, 0}}}}, 0, 0 },
    193   { "BP0", 16, {0, {{{0, 0}}}}, 0, 0 },
    194   { "BP1", 17, {0, {{{0, 0}}}}, 0, 0 },
    195   { "BP2", 18, {0, {{{0, 0}}}}, 0, 0 },
    196   { "BP3", 19, {0, {{{0, 0}}}}, 0, 0 },
    197   { "WP0", 24, {0, {{{0, 0}}}}, 0, 0 },
    198   { "WP1", 25, {0, {{{0, 0}}}}, 0, 0 },
    199   { "WP2", 26, {0, {{{0, 0}}}}, 0, 0 },
    200   { "WP3", 27, {0, {{{0, 0}}}}, 0, 0 },
    201   { "PSW", 29, {0, {{{0, 0}}}}, 0, 0 },
    202   { "TLBVADDR", 30, {0, {{{0, 0}}}}, 0, 0 },
    203   { "TLBPADDR", 31, {0, {{{0, 0}}}}, 0, 0 },
    204   { "TLBBADVADDR", 31, {0, {{{0, 0}}}}, 0, 0 }
    205 };
    206 
    207 CGEN_KEYWORD lm32_cgen_opval_h_csr =
    208 {
    209   & lm32_cgen_opval_h_csr_entries[0],
    210   25,
    211   0, 0, 0, 0, ""
    212 };
    213 
    214 
    215 /* The hardware table.  */
    216 
    217 #define A(a) (1 << CGEN_HW_##a)
    218 
    219 const CGEN_HW_ENTRY lm32_cgen_hw_table[] =
    220 {
    221   { "h-memory", HW_H_MEMORY, CGEN_ASM_NONE, 0, { 0, { { { (1<<MACH_BASE), 0 } } } } },
    222   { "h-sint", HW_H_SINT, CGEN_ASM_NONE, 0, { 0, { { { (1<<MACH_BASE), 0 } } } } },
    223   { "h-uint", HW_H_UINT, CGEN_ASM_NONE, 0, { 0, { { { (1<<MACH_BASE), 0 } } } } },
    224   { "h-addr", HW_H_ADDR, CGEN_ASM_NONE, 0, { 0, { { { (1<<MACH_BASE), 0 } } } } },
    225   { "h-iaddr", HW_H_IADDR, CGEN_ASM_NONE, 0, { 0, { { { (1<<MACH_BASE), 0 } } } } },
    226   { "h-pc", HW_H_PC, CGEN_ASM_NONE, 0, { 0|A(PC), { { { (1<<MACH_BASE), 0 } } } } },
    227   { "h-gr", HW_H_GR, CGEN_ASM_KEYWORD, & lm32_cgen_opval_h_gr, { 0, { { { (1<<MACH_BASE), 0 } } } } },
    228   { "h-csr", HW_H_CSR, CGEN_ASM_KEYWORD, & lm32_cgen_opval_h_csr, { 0, { { { (1<<MACH_BASE), 0 } } } } },
    229   { 0, 0, CGEN_ASM_NONE, 0, { 0, { { { (1<<MACH_BASE), 0 } } } } }
    230 };
    231 
    232 #undef A
    233 
    234 
    235 /* The instruction field table.  */
    236 
    237 #define A(a) (1 << CGEN_IFLD_##a)
    238 
    239 const CGEN_IFLD lm32_cgen_ifld_table[] =
    240 {
    241   { LM32_F_NIL, "f-nil", 0, 0, 0, 0, { 0, { { { (1<<MACH_BASE), 0 } } } }  },
    242   { LM32_F_ANYOF, "f-anyof", 0, 0, 0, 0, { 0, { { { (1<<MACH_BASE), 0 } } } }  },
    243   { LM32_F_OPCODE, "f-opcode", 0, 32, 31, 6, { 0, { { { (1<<MACH_BASE), 0 } } } }  },
    244   { LM32_F_R0, "f-r0", 0, 32, 25, 5, { 0, { { { (1<<MACH_BASE), 0 } } } }  },
    245   { LM32_F_R1, "f-r1", 0, 32, 20, 5, { 0, { { { (1<<MACH_BASE), 0 } } } }  },
    246   { LM32_F_R2, "f-r2", 0, 32, 15, 5, { 0, { { { (1<<MACH_BASE), 0 } } } }  },
    247   { LM32_F_RESV0, "f-resv0", 0, 32, 10, 11, { 0|A(RESERVED), { { { (1<<MACH_BASE), 0 } } } }  },
    248   { LM32_F_SHIFT, "f-shift", 0, 32, 4, 5, { 0, { { { (1<<MACH_BASE), 0 } } } }  },
    249   { LM32_F_IMM, "f-imm", 0, 32, 15, 16, { 0, { { { (1<<MACH_BASE), 0 } } } }  },
    250   { LM32_F_UIMM, "f-uimm", 0, 32, 15, 16, { 0, { { { (1<<MACH_BASE), 0 } } } }  },
    251   { LM32_F_CSR, "f-csr", 0, 32, 25, 5, { 0, { { { (1<<MACH_BASE), 0 } } } }  },
    252   { LM32_F_USER, "f-user", 0, 32, 10, 11, { 0, { { { (1<<MACH_BASE), 0 } } } }  },
    253   { LM32_F_EXCEPTION, "f-exception", 0, 32, 25, 26, { 0, { { { (1<<MACH_BASE), 0 } } } }  },
    254   { LM32_F_BRANCH, "f-branch", 0, 32, 15, 16, { 0|A(PCREL_ADDR), { { { (1<<MACH_BASE), 0 } } } }  },
    255   { LM32_F_CALL, "f-call", 0, 32, 25, 26, { 0|A(PCREL_ADDR), { { { (1<<MACH_BASE), 0 } } } }  },
    256   { 0, 0, 0, 0, 0, 0, { 0, { { { (1<<MACH_BASE), 0 } } } } }
    257 };
    258 
    259 #undef A
    260 
    261 
    262 
    263 /* multi ifield declarations */
    264 
    265 
    266 
    267 /* multi ifield definitions */
    268 
    269 
    270 /* The operand table.  */
    271 
    272 #define A(a) (1 << CGEN_OPERAND_##a)
    273 #define OPERAND(op) LM32_OPERAND_##op
    274 
    275 const CGEN_OPERAND lm32_cgen_operand_table[] =
    276 {
    277 /* pc: program counter */
    278   { "pc", LM32_OPERAND_PC, HW_H_PC, 0, 0,
    279     { 0, { &lm32_cgen_ifld_table[LM32_F_NIL] } },
    280     { 0|A(SEM_ONLY), { { { (1<<MACH_BASE), 0 } } } }  },
    281 /* r0: register 0 */
    282   { "r0", LM32_OPERAND_R0, HW_H_GR, 25, 5,
    283     { 0, { &lm32_cgen_ifld_table[LM32_F_R0] } },
    284     { 0, { { { (1<<MACH_BASE), 0 } } } }  },
    285 /* r1: register 1 */
    286   { "r1", LM32_OPERAND_R1, HW_H_GR, 20, 5,
    287     { 0, { &lm32_cgen_ifld_table[LM32_F_R1] } },
    288     { 0, { { { (1<<MACH_BASE), 0 } } } }  },
    289 /* r2: register 2 */
    290   { "r2", LM32_OPERAND_R2, HW_H_GR, 15, 5,
    291     { 0, { &lm32_cgen_ifld_table[LM32_F_R2] } },
    292     { 0, { { { (1<<MACH_BASE), 0 } } } }  },
    293 /* shift: shift amout */
    294   { "shift", LM32_OPERAND_SHIFT, HW_H_UINT, 4, 5,
    295     { 0, { &lm32_cgen_ifld_table[LM32_F_SHIFT] } },
    296     { 0, { { { (1<<MACH_BASE), 0 } } } }  },
    297 /* imm: signed immediate */
    298   { "imm", LM32_OPERAND_IMM, HW_H_SINT, 15, 16,
    299     { 0, { &lm32_cgen_ifld_table[LM32_F_IMM] } },
    300     { 0, { { { (1<<MACH_BASE), 0 } } } }  },
    301 /* uimm: unsigned immediate */
    302   { "uimm", LM32_OPERAND_UIMM, HW_H_UINT, 15, 16,
    303     { 0, { &lm32_cgen_ifld_table[LM32_F_UIMM] } },
    304     { 0, { { { (1<<MACH_BASE), 0 } } } }  },
    305 /* branch: branch offset */
    306   { "branch", LM32_OPERAND_BRANCH, HW_H_IADDR, 15, 16,
    307     { 0, { &lm32_cgen_ifld_table[LM32_F_BRANCH] } },
    308     { 0|A(PCREL_ADDR), { { { (1<<MACH_BASE), 0 } } } }  },
    309 /* call: call offset */
    310   { "call", LM32_OPERAND_CALL, HW_H_IADDR, 25, 26,
    311     { 0, { &lm32_cgen_ifld_table[LM32_F_CALL] } },
    312     { 0|A(PCREL_ADDR), { { { (1<<MACH_BASE), 0 } } } }  },
    313 /* csr: csr */
    314   { "csr", LM32_OPERAND_CSR, HW_H_CSR, 25, 5,
    315     { 0, { &lm32_cgen_ifld_table[LM32_F_CSR] } },
    316     { 0, { { { (1<<MACH_BASE), 0 } } } }  },
    317 /* user: user */
    318   { "user", LM32_OPERAND_USER, HW_H_UINT, 10, 11,
    319     { 0, { &lm32_cgen_ifld_table[LM32_F_USER] } },
    320     { 0, { { { (1<<MACH_BASE), 0 } } } }  },
    321 /* exception: exception */
    322   { "exception", LM32_OPERAND_EXCEPTION, HW_H_UINT, 25, 26,
    323     { 0, { &lm32_cgen_ifld_table[LM32_F_EXCEPTION] } },
    324     { 0, { { { (1<<MACH_BASE), 0 } } } }  },
    325 /* hi16: high 16-bit immediate */
    326   { "hi16", LM32_OPERAND_HI16, HW_H_UINT, 15, 16,
    327     { 0, { &lm32_cgen_ifld_table[LM32_F_UIMM] } },
    328     { 0, { { { (1<<MACH_BASE), 0 } } } }  },
    329 /* lo16: low 16-bit immediate */
    330   { "lo16", LM32_OPERAND_LO16, HW_H_UINT, 15, 16,
    331     { 0, { &lm32_cgen_ifld_table[LM32_F_UIMM] } },
    332     { 0, { { { (1<<MACH_BASE), 0 } } } }  },
    333 /* gp16: gp relative 16-bit immediate */
    334   { "gp16", LM32_OPERAND_GP16, HW_H_SINT, 15, 16,
    335     { 0, { &lm32_cgen_ifld_table[LM32_F_IMM] } },
    336     { 0, { { { (1<<MACH_BASE), 0 } } } }  },
    337 /* got16: got 16-bit immediate */
    338   { "got16", LM32_OPERAND_GOT16, HW_H_SINT, 15, 16,
    339     { 0, { &lm32_cgen_ifld_table[LM32_F_IMM] } },
    340     { 0, { { { (1<<MACH_BASE), 0 } } } }  },
    341 /* gotoffhi16: got offset high 16-bit immediate */
    342   { "gotoffhi16", LM32_OPERAND_GOTOFFHI16, HW_H_SINT, 15, 16,
    343     { 0, { &lm32_cgen_ifld_table[LM32_F_IMM] } },
    344     { 0, { { { (1<<MACH_BASE), 0 } } } }  },
    345 /* gotofflo16: got offset low 16-bit immediate */
    346   { "gotofflo16", LM32_OPERAND_GOTOFFLO16, HW_H_SINT, 15, 16,
    347     { 0, { &lm32_cgen_ifld_table[LM32_F_IMM] } },
    348     { 0, { { { (1<<MACH_BASE), 0 } } } }  },
    349 /* sentinel */
    350   { 0, 0, 0, 0, 0,
    351     { 0, { 0 } },
    352     { 0, { { { (1<<MACH_BASE), 0 } } } } }
    353 };
    354 
    355 #undef A
    356 
    357 
    358 /* The instruction table.  */
    359 
    360 #define OP(field) CGEN_SYNTAX_MAKE_FIELD (OPERAND (field))
    361 #define A(a) (1 << CGEN_INSN_##a)
    362 
    363 static const CGEN_IBASE lm32_cgen_insn_table[MAX_INSNS] =
    364 {
    365   /* Special null first entry.
    366      A `num' value of zero is thus invalid.
    367      Also, the special `invalid' insn resides here.  */
    368   { 0, 0, 0, 0, { 0, { { { (1<<MACH_BASE), 0 } } } } },
    369 /* add $r2,$r0,$r1 */
    370   {
    371     LM32_INSN_ADD, "add", "add", 32,
    372     { 0, { { { (1<<MACH_BASE), 0 } } } }
    373   },
    374 /* addi $r1,$r0,$imm */
    375   {
    376     LM32_INSN_ADDI, "addi", "addi", 32,
    377     { 0, { { { (1<<MACH_BASE), 0 } } } }
    378   },
    379 /* and $r2,$r0,$r1 */
    380   {
    381     LM32_INSN_AND, "and", "and", 32,
    382     { 0, { { { (1<<MACH_BASE), 0 } } } }
    383   },
    384 /* andi $r1,$r0,$uimm */
    385   {
    386     LM32_INSN_ANDI, "andi", "andi", 32,
    387     { 0, { { { (1<<MACH_BASE), 0 } } } }
    388   },
    389 /* andhi $r1,$r0,$hi16 */
    390   {
    391     LM32_INSN_ANDHII, "andhii", "andhi", 32,
    392     { 0, { { { (1<<MACH_BASE), 0 } } } }
    393   },
    394 /* b $r0 */
    395   {
    396     LM32_INSN_B, "b", "b", 32,
    397     { 0|A(UNCOND_CTI), { { { (1<<MACH_BASE), 0 } } } }
    398   },
    399 /* bi $call */
    400   {
    401     LM32_INSN_BI, "bi", "bi", 32,
    402     { 0|A(UNCOND_CTI), { { { (1<<MACH_BASE), 0 } } } }
    403   },
    404 /* be $r0,$r1,$branch */
    405   {
    406     LM32_INSN_BE, "be", "be", 32,
    407     { 0|A(COND_CTI), { { { (1<<MACH_BASE), 0 } } } }
    408   },
    409 /* bg $r0,$r1,$branch */
    410   {
    411     LM32_INSN_BG, "bg", "bg", 32,
    412     { 0|A(COND_CTI), { { { (1<<MACH_BASE), 0 } } } }
    413   },
    414 /* bge $r0,$r1,$branch */
    415   {
    416     LM32_INSN_BGE, "bge", "bge", 32,
    417     { 0|A(COND_CTI), { { { (1<<MACH_BASE), 0 } } } }
    418   },
    419 /* bgeu $r0,$r1,$branch */
    420   {
    421     LM32_INSN_BGEU, "bgeu", "bgeu", 32,
    422     { 0|A(COND_CTI), { { { (1<<MACH_BASE), 0 } } } }
    423   },
    424 /* bgu $r0,$r1,$branch */
    425   {
    426     LM32_INSN_BGU, "bgu", "bgu", 32,
    427     { 0|A(COND_CTI), { { { (1<<MACH_BASE), 0 } } } }
    428   },
    429 /* bne $r0,$r1,$branch */
    430   {
    431     LM32_INSN_BNE, "bne", "bne", 32,
    432     { 0|A(COND_CTI), { { { (1<<MACH_BASE), 0 } } } }
    433   },
    434 /* call $r0 */
    435   {
    436     LM32_INSN_CALL, "call", "call", 32,
    437     { 0|A(UNCOND_CTI), { { { (1<<MACH_BASE), 0 } } } }
    438   },
    439 /* calli $call */
    440   {
    441     LM32_INSN_CALLI, "calli", "calli", 32,
    442     { 0|A(UNCOND_CTI), { { { (1<<MACH_BASE), 0 } } } }
    443   },
    444 /* cmpe $r2,$r0,$r1 */
    445   {
    446     LM32_INSN_CMPE, "cmpe", "cmpe", 32,
    447     { 0, { { { (1<<MACH_BASE), 0 } } } }
    448   },
    449 /* cmpei $r1,$r0,$imm */
    450   {
    451     LM32_INSN_CMPEI, "cmpei", "cmpei", 32,
    452     { 0, { { { (1<<MACH_BASE), 0 } } } }
    453   },
    454 /* cmpg $r2,$r0,$r1 */
    455   {
    456     LM32_INSN_CMPG, "cmpg", "cmpg", 32,
    457     { 0, { { { (1<<MACH_BASE), 0 } } } }
    458   },
    459 /* cmpgi $r1,$r0,$imm */
    460   {
    461     LM32_INSN_CMPGI, "cmpgi", "cmpgi", 32,
    462     { 0, { { { (1<<MACH_BASE), 0 } } } }
    463   },
    464 /* cmpge $r2,$r0,$r1 */
    465   {
    466     LM32_INSN_CMPGE, "cmpge", "cmpge", 32,
    467     { 0, { { { (1<<MACH_BASE), 0 } } } }
    468   },
    469 /* cmpgei $r1,$r0,$imm */
    470   {
    471     LM32_INSN_CMPGEI, "cmpgei", "cmpgei", 32,
    472     { 0, { { { (1<<MACH_BASE), 0 } } } }
    473   },
    474 /* cmpgeu $r2,$r0,$r1 */
    475   {
    476     LM32_INSN_CMPGEU, "cmpgeu", "cmpgeu", 32,
    477     { 0, { { { (1<<MACH_BASE), 0 } } } }
    478   },
    479 /* cmpgeui $r1,$r0,$uimm */
    480   {
    481     LM32_INSN_CMPGEUI, "cmpgeui", "cmpgeui", 32,
    482     { 0, { { { (1<<MACH_BASE), 0 } } } }
    483   },
    484 /* cmpgu $r2,$r0,$r1 */
    485   {
    486     LM32_INSN_CMPGU, "cmpgu", "cmpgu", 32,
    487     { 0, { { { (1<<MACH_BASE), 0 } } } }
    488   },
    489 /* cmpgui $r1,$r0,$uimm */
    490   {
    491     LM32_INSN_CMPGUI, "cmpgui", "cmpgui", 32,
    492     { 0, { { { (1<<MACH_BASE), 0 } } } }
    493   },
    494 /* cmpne $r2,$r0,$r1 */
    495   {
    496     LM32_INSN_CMPNE, "cmpne", "cmpne", 32,
    497     { 0, { { { (1<<MACH_BASE), 0 } } } }
    498   },
    499 /* cmpnei $r1,$r0,$imm */
    500   {
    501     LM32_INSN_CMPNEI, "cmpnei", "cmpnei", 32,
    502     { 0, { { { (1<<MACH_BASE), 0 } } } }
    503   },
    504 /* divu $r2,$r0,$r1 */
    505   {
    506     LM32_INSN_DIVU, "divu", "divu", 32,
    507     { 0|A(UNCOND_CTI), { { { (1<<MACH_BASE), 0 } } } }
    508   },
    509 /* lb $r1,($r0+$imm) */
    510   {
    511     LM32_INSN_LB, "lb", "lb", 32,
    512     { 0, { { { (1<<MACH_BASE), 0 } } } }
    513   },
    514 /* lbu $r1,($r0+$imm) */
    515   {
    516     LM32_INSN_LBU, "lbu", "lbu", 32,
    517     { 0, { { { (1<<MACH_BASE), 0 } } } }
    518   },
    519 /* lh $r1,($r0+$imm) */
    520   {
    521     LM32_INSN_LH, "lh", "lh", 32,
    522     { 0, { { { (1<<MACH_BASE), 0 } } } }
    523   },
    524 /* lhu $r1,($r0+$imm) */
    525   {
    526     LM32_INSN_LHU, "lhu", "lhu", 32,
    527     { 0, { { { (1<<MACH_BASE), 0 } } } }
    528   },
    529 /* lw $r1,($r0+$imm) */
    530   {
    531     LM32_INSN_LW, "lw", "lw", 32,
    532     { 0, { { { (1<<MACH_BASE), 0 } } } }
    533   },
    534 /* modu $r2,$r0,$r1 */
    535   {
    536     LM32_INSN_MODU, "modu", "modu", 32,
    537     { 0|A(UNCOND_CTI), { { { (1<<MACH_BASE), 0 } } } }
    538   },
    539 /* mul $r2,$r0,$r1 */
    540   {
    541     LM32_INSN_MUL, "mul", "mul", 32,
    542     { 0, { { { (1<<MACH_BASE), 0 } } } }
    543   },
    544 /* muli $r1,$r0,$imm */
    545   {
    546     LM32_INSN_MULI, "muli", "muli", 32,
    547     { 0, { { { (1<<MACH_BASE), 0 } } } }
    548   },
    549 /* nor $r2,$r0,$r1 */
    550   {
    551     LM32_INSN_NOR, "nor", "nor", 32,
    552     { 0, { { { (1<<MACH_BASE), 0 } } } }
    553   },
    554 /* nori $r1,$r0,$uimm */
    555   {
    556     LM32_INSN_NORI, "nori", "nori", 32,
    557     { 0, { { { (1<<MACH_BASE), 0 } } } }
    558   },
    559 /* or $r2,$r0,$r1 */
    560   {
    561     LM32_INSN_OR, "or", "or", 32,
    562     { 0, { { { (1<<MACH_BASE), 0 } } } }
    563   },
    564 /* ori $r1,$r0,$lo16 */
    565   {
    566     LM32_INSN_ORI, "ori", "ori", 32,
    567     { 0, { { { (1<<MACH_BASE), 0 } } } }
    568   },
    569 /* orhi $r1,$r0,$hi16 */
    570   {
    571     LM32_INSN_ORHII, "orhii", "orhi", 32,
    572     { 0, { { { (1<<MACH_BASE), 0 } } } }
    573   },
    574 /* rcsr $r2,$csr */
    575   {
    576     LM32_INSN_RCSR, "rcsr", "rcsr", 32,
    577     { 0, { { { (1<<MACH_BASE), 0 } } } }
    578   },
    579 /* sb ($r0+$imm),$r1 */
    580   {
    581     LM32_INSN_SB, "sb", "sb", 32,
    582     { 0, { { { (1<<MACH_BASE), 0 } } } }
    583   },
    584 /* sextb $r2,$r0 */
    585   {
    586     LM32_INSN_SEXTB, "sextb", "sextb", 32,
    587     { 0, { { { (1<<MACH_BASE), 0 } } } }
    588   },
    589 /* sexth $r2,$r0 */
    590   {
    591     LM32_INSN_SEXTH, "sexth", "sexth", 32,
    592     { 0, { { { (1<<MACH_BASE), 0 } } } }
    593   },
    594 /* sh ($r0+$imm),$r1 */
    595   {
    596     LM32_INSN_SH, "sh", "sh", 32,
    597     { 0, { { { (1<<MACH_BASE), 0 } } } }
    598   },
    599 /* sl $r2,$r0,$r1 */
    600   {
    601     LM32_INSN_SL, "sl", "sl", 32,
    602     { 0, { { { (1<<MACH_BASE), 0 } } } }
    603   },
    604 /* sli $r1,$r0,$imm */
    605   {
    606     LM32_INSN_SLI, "sli", "sli", 32,
    607     { 0, { { { (1<<MACH_BASE), 0 } } } }
    608   },
    609 /* sr $r2,$r0,$r1 */
    610   {
    611     LM32_INSN_SR, "sr", "sr", 32,
    612     { 0, { { { (1<<MACH_BASE), 0 } } } }
    613   },
    614 /* sri $r1,$r0,$imm */
    615   {
    616     LM32_INSN_SRI, "sri", "sri", 32,
    617     { 0, { { { (1<<MACH_BASE), 0 } } } }
    618   },
    619 /* sru $r2,$r0,$r1 */
    620   {
    621     LM32_INSN_SRU, "sru", "sru", 32,
    622     { 0, { { { (1<<MACH_BASE), 0 } } } }
    623   },
    624 /* srui $r1,$r0,$imm */
    625   {
    626     LM32_INSN_SRUI, "srui", "srui", 32,
    627     { 0, { { { (1<<MACH_BASE), 0 } } } }
    628   },
    629 /* sub $r2,$r0,$r1 */
    630   {
    631     LM32_INSN_SUB, "sub", "sub", 32,
    632     { 0, { { { (1<<MACH_BASE), 0 } } } }
    633   },
    634 /* sw ($r0+$imm),$r1 */
    635   {
    636     LM32_INSN_SW, "sw", "sw", 32,
    637     { 0, { { { (1<<MACH_BASE), 0 } } } }
    638   },
    639 /* user $r2,$r0,$r1,$user */
    640   {
    641     LM32_INSN_USER, "user", "user", 32,
    642     { 0, { { { (1<<MACH_BASE), 0 } } } }
    643   },
    644 /* wcsr $csr,$r1 */
    645   {
    646     LM32_INSN_WCSR, "wcsr", "wcsr", 32,
    647     { 0, { { { (1<<MACH_BASE), 0 } } } }
    648   },
    649 /* xor $r2,$r0,$r1 */
    650   {
    651     LM32_INSN_XOR, "xor", "xor", 32,
    652     { 0, { { { (1<<MACH_BASE), 0 } } } }
    653   },
    654 /* xori $r1,$r0,$uimm */
    655   {
    656     LM32_INSN_XORI, "xori", "xori", 32,
    657     { 0, { { { (1<<MACH_BASE), 0 } } } }
    658   },
    659 /* xnor $r2,$r0,$r1 */
    660   {
    661     LM32_INSN_XNOR, "xnor", "xnor", 32,
    662     { 0, { { { (1<<MACH_BASE), 0 } } } }
    663   },
    664 /* xnori $r1,$r0,$uimm */
    665   {
    666     LM32_INSN_XNORI, "xnori", "xnori", 32,
    667     { 0, { { { (1<<MACH_BASE), 0 } } } }
    668   },
    669 /* break */
    670   {
    671     LM32_INSN_BREAK, "break", "break", 32,
    672     { 0|A(UNCOND_CTI), { { { (1<<MACH_BASE), 0 } } } }
    673   },
    674 /* scall */
    675   {
    676     LM32_INSN_SCALL, "scall", "scall", 32,
    677     { 0|A(UNCOND_CTI), { { { (1<<MACH_BASE), 0 } } } }
    678   },
    679 /* bret */
    680   {
    681     -1, "bret", "bret", 32,
    682     { 0|A(ALIAS)|A(UNCOND_CTI), { { { (1<<MACH_BASE), 0 } } } }
    683   },
    684 /* eret */
    685   {
    686     -1, "eret", "eret", 32,
    687     { 0|A(ALIAS)|A(UNCOND_CTI), { { { (1<<MACH_BASE), 0 } } } }
    688   },
    689 /* ret */
    690   {
    691     -1, "ret", "ret", 32,
    692     { 0|A(ALIAS)|A(UNCOND_CTI), { { { (1<<MACH_BASE), 0 } } } }
    693   },
    694 /* mv $r2,$r0 */
    695   {
    696     -1, "mv", "mv", 32,
    697     { 0|A(ALIAS), { { { (1<<MACH_BASE), 0 } } } }
    698   },
    699 /* mvi $r1,$imm */
    700   {
    701     -1, "mvi", "mvi", 32,
    702     { 0|A(ALIAS), { { { (1<<MACH_BASE), 0 } } } }
    703   },
    704 /* mvu $r1,$lo16 */
    705   {
    706     -1, "mvui", "mvu", 32,
    707     { 0|A(ALIAS), { { { (1<<MACH_BASE), 0 } } } }
    708   },
    709 /* mvhi $r1,$hi16 */
    710   {
    711     -1, "mvhi", "mvhi", 32,
    712     { 0|A(ALIAS), { { { (1<<MACH_BASE), 0 } } } }
    713   },
    714 /* mva $r1,$gp16 */
    715   {
    716     -1, "mva", "mva", 32,
    717     { 0|A(ALIAS), { { { (1<<MACH_BASE), 0 } } } }
    718   },
    719 /* not $r2,$r0 */
    720   {
    721     -1, "not", "not", 32,
    722     { 0|A(ALIAS), { { { (1<<MACH_BASE), 0 } } } }
    723   },
    724 /* nop */
    725   {
    726     -1, "nop", "nop", 32,
    727     { 0|A(ALIAS), { { { (1<<MACH_BASE), 0 } } } }
    728   },
    729 /* lb $r1,$gp16 */
    730   {
    731     -1, "lbgprel", "lb", 32,
    732     { 0|A(ALIAS), { { { (1<<MACH_BASE), 0 } } } }
    733   },
    734 /* lbu $r1,$gp16 */
    735   {
    736     -1, "lbugprel", "lbu", 32,
    737     { 0|A(ALIAS), { { { (1<<MACH_BASE), 0 } } } }
    738   },
    739 /* lh $r1,$gp16 */
    740   {
    741     -1, "lhgprel", "lh", 32,
    742     { 0|A(ALIAS), { { { (1<<MACH_BASE), 0 } } } }
    743   },
    744 /* lhu $r1,$gp16 */
    745   {
    746     -1, "lhugprel", "lhu", 32,
    747     { 0|A(ALIAS), { { { (1<<MACH_BASE), 0 } } } }
    748   },
    749 /* lw $r1,$gp16 */
    750   {
    751     -1, "lwgprel", "lw", 32,
    752     { 0|A(ALIAS), { { { (1<<MACH_BASE), 0 } } } }
    753   },
    754 /* sb $gp16,$r1 */
    755   {
    756     -1, "sbgprel", "sb", 32,
    757     { 0|A(ALIAS), { { { (1<<MACH_BASE), 0 } } } }
    758   },
    759 /* sh $gp16,$r1 */
    760   {
    761     -1, "shgprel", "sh", 32,
    762     { 0|A(ALIAS), { { { (1<<MACH_BASE), 0 } } } }
    763   },
    764 /* sw $gp16,$r1 */
    765   {
    766     -1, "swgprel", "sw", 32,
    767     { 0|A(ALIAS), { { { (1<<MACH_BASE), 0 } } } }
    768   },
    769 /* lw $r1,(gp+$got16) */
    770   {
    771     -1, "lwgotrel", "lw", 32,
    772     { 0|A(ALIAS), { { { (1<<MACH_BASE), 0 } } } }
    773   },
    774 /* orhi $r1,$r0,$gotoffhi16 */
    775   {
    776     -1, "orhigotoffi", "orhi", 32,
    777     { 0|A(ALIAS), { { { (1<<MACH_BASE), 0 } } } }
    778   },
    779 /* addi $r1,$r0,$gotofflo16 */
    780   {
    781     -1, "addgotoff", "addi", 32,
    782     { 0|A(ALIAS), { { { (1<<MACH_BASE), 0 } } } }
    783   },
    784 /* sw ($r0+$gotofflo16),$r1 */
    785   {
    786     -1, "swgotoff", "sw", 32,
    787     { 0|A(ALIAS), { { { (1<<MACH_BASE), 0 } } } }
    788   },
    789 /* lw $r1,($r0+$gotofflo16) */
    790   {
    791     -1, "lwgotoff", "lw", 32,
    792     { 0|A(ALIAS), { { { (1<<MACH_BASE), 0 } } } }
    793   },
    794 /* sh ($r0+$gotofflo16),$r1 */
    795   {
    796     -1, "shgotoff", "sh", 32,
    797     { 0|A(ALIAS), { { { (1<<MACH_BASE), 0 } } } }
    798   },
    799 /* lh $r1,($r0+$gotofflo16) */
    800   {
    801     -1, "lhgotoff", "lh", 32,
    802     { 0|A(ALIAS), { { { (1<<MACH_BASE), 0 } } } }
    803   },
    804 /* lhu $r1,($r0+$gotofflo16) */
    805   {
    806     -1, "lhugotoff", "lhu", 32,
    807     { 0|A(ALIAS), { { { (1<<MACH_BASE), 0 } } } }
    808   },
    809 /* sb ($r0+$gotofflo16),$r1 */
    810   {
    811     -1, "sbgotoff", "sb", 32,
    812     { 0|A(ALIAS), { { { (1<<MACH_BASE), 0 } } } }
    813   },
    814 /* lb $r1,($r0+$gotofflo16) */
    815   {
    816     -1, "lbgotoff", "lb", 32,
    817     { 0|A(ALIAS), { { { (1<<MACH_BASE), 0 } } } }
    818   },
    819 /* lbu $r1,($r0+$gotofflo16) */
    820   {
    821     -1, "lbugotoff", "lbu", 32,
    822     { 0|A(ALIAS), { { { (1<<MACH_BASE), 0 } } } }
    823   },
    824 };
    825 
    826 #undef OP
    827 #undef A
    828 
    829 /* Initialize anything needed to be done once, before any cpu_open call.  */
    830 
    831 static void
    832 init_tables (void)
    833 {
    834 }
    835 
    836 #ifndef opcodes_error_handler
    837 #define opcodes_error_handler(...) \
    838   fprintf (stderr, __VA_ARGS__); fputc ('\n', stderr)
    839 #endif
    840 
    841 static const CGEN_MACH * lookup_mach_via_bfd_name (const CGEN_MACH *, const char *);
    842 static void build_hw_table      (CGEN_CPU_TABLE *);
    843 static void build_ifield_table  (CGEN_CPU_TABLE *);
    844 static void build_operand_table (CGEN_CPU_TABLE *);
    845 static void build_insn_table    (CGEN_CPU_TABLE *);
    846 static void lm32_cgen_rebuild_tables (CGEN_CPU_TABLE *);
    847 
    848 /* Subroutine of lm32_cgen_cpu_open to look up a mach via its bfd name.  */
    849 
    850 static const CGEN_MACH *
    851 lookup_mach_via_bfd_name (const CGEN_MACH *table, const char *name)
    852 {
    853   while (table->name)
    854     {
    855       if (strcmp (name, table->bfd_name) == 0)
    856 	return table;
    857       ++table;
    858     }
    859   return NULL;
    860 }
    861 
    862 /* Subroutine of lm32_cgen_cpu_open to build the hardware table.  */
    863 
    864 static void
    865 build_hw_table (CGEN_CPU_TABLE *cd)
    866 {
    867   int i;
    868   int machs = cd->machs;
    869   const CGEN_HW_ENTRY *init = & lm32_cgen_hw_table[0];
    870   /* MAX_HW is only an upper bound on the number of selected entries.
    871      However each entry is indexed by it's enum so there can be holes in
    872      the table.  */
    873   const CGEN_HW_ENTRY **selected =
    874     (const CGEN_HW_ENTRY **) xmalloc (MAX_HW * sizeof (CGEN_HW_ENTRY *));
    875 
    876   cd->hw_table.init_entries = init;
    877   cd->hw_table.entry_size = sizeof (CGEN_HW_ENTRY);
    878   memset (selected, 0, MAX_HW * sizeof (CGEN_HW_ENTRY *));
    879   /* ??? For now we just use machs to determine which ones we want.  */
    880   for (i = 0; init[i].name != NULL; ++i)
    881     if (CGEN_HW_ATTR_VALUE (&init[i], CGEN_HW_MACH)
    882 	& machs)
    883       selected[init[i].type] = &init[i];
    884   cd->hw_table.entries = selected;
    885   cd->hw_table.num_entries = MAX_HW;
    886 }
    887 
    888 /* Subroutine of lm32_cgen_cpu_open to build the hardware table.  */
    889 
    890 static void
    891 build_ifield_table (CGEN_CPU_TABLE *cd)
    892 {
    893   cd->ifld_table = & lm32_cgen_ifld_table[0];
    894 }
    895 
    896 /* Subroutine of lm32_cgen_cpu_open to build the hardware table.  */
    897 
    898 static void
    899 build_operand_table (CGEN_CPU_TABLE *cd)
    900 {
    901   int i;
    902   int machs = cd->machs;
    903   const CGEN_OPERAND *init = & lm32_cgen_operand_table[0];
    904   /* MAX_OPERANDS is only an upper bound on the number of selected entries.
    905      However each entry is indexed by it's enum so there can be holes in
    906      the table.  */
    907   const CGEN_OPERAND **selected = xmalloc (MAX_OPERANDS * sizeof (* selected));
    908 
    909   cd->operand_table.init_entries = init;
    910   cd->operand_table.entry_size = sizeof (CGEN_OPERAND);
    911   memset (selected, 0, MAX_OPERANDS * sizeof (CGEN_OPERAND *));
    912   /* ??? For now we just use mach to determine which ones we want.  */
    913   for (i = 0; init[i].name != NULL; ++i)
    914     if (CGEN_OPERAND_ATTR_VALUE (&init[i], CGEN_OPERAND_MACH)
    915 	& machs)
    916       selected[init[i].type] = &init[i];
    917   cd->operand_table.entries = selected;
    918   cd->operand_table.num_entries = MAX_OPERANDS;
    919 }
    920 
    921 /* Subroutine of lm32_cgen_cpu_open to build the hardware table.
    922    ??? This could leave out insns not supported by the specified mach/isa,
    923    but that would cause errors like "foo only supported by bar" to become
    924    "unknown insn", so for now we include all insns and require the app to
    925    do the checking later.
    926    ??? On the other hand, parsing of such insns may require their hardware or
    927    operand elements to be in the table [which they mightn't be].  */
    928 
    929 static void
    930 build_insn_table (CGEN_CPU_TABLE *cd)
    931 {
    932   int i;
    933   const CGEN_IBASE *ib = & lm32_cgen_insn_table[0];
    934   CGEN_INSN *insns = xmalloc (MAX_INSNS * sizeof (CGEN_INSN));
    935 
    936   memset (insns, 0, MAX_INSNS * sizeof (CGEN_INSN));
    937   for (i = 0; i < MAX_INSNS; ++i)
    938     insns[i].base = &ib[i];
    939   cd->insn_table.init_entries = insns;
    940   cd->insn_table.entry_size = sizeof (CGEN_IBASE);
    941   cd->insn_table.num_init_entries = MAX_INSNS;
    942 }
    943 
    944 /* Subroutine of lm32_cgen_cpu_open to rebuild the tables.  */
    945 
    946 static void
    947 lm32_cgen_rebuild_tables (CGEN_CPU_TABLE *cd)
    948 {
    949   int i;
    950   CGEN_BITSET *isas = cd->isas;
    951   unsigned int machs = cd->machs;
    952 
    953   cd->int_insn_p = CGEN_INT_INSN_P;
    954 
    955   /* Data derived from the isa spec.  */
    956 #define UNSET (CGEN_SIZE_UNKNOWN + 1)
    957   cd->default_insn_bitsize = UNSET;
    958   cd->base_insn_bitsize = UNSET;
    959   cd->min_insn_bitsize = 65535; /* Some ridiculously big number.  */
    960   cd->max_insn_bitsize = 0;
    961   for (i = 0; i < MAX_ISAS; ++i)
    962     if (cgen_bitset_contains (isas, i))
    963       {
    964 	const CGEN_ISA *isa = & lm32_cgen_isa_table[i];
    965 
    966 	/* Default insn sizes of all selected isas must be
    967 	   equal or we set the result to 0, meaning "unknown".  */
    968 	if (cd->default_insn_bitsize == UNSET)
    969 	  cd->default_insn_bitsize = isa->default_insn_bitsize;
    970 	else if (isa->default_insn_bitsize == cd->default_insn_bitsize)
    971 	  ; /* This is ok.  */
    972 	else
    973 	  cd->default_insn_bitsize = CGEN_SIZE_UNKNOWN;
    974 
    975 	/* Base insn sizes of all selected isas must be equal
    976 	   or we set the result to 0, meaning "unknown".  */
    977 	if (cd->base_insn_bitsize == UNSET)
    978 	  cd->base_insn_bitsize = isa->base_insn_bitsize;
    979 	else if (isa->base_insn_bitsize == cd->base_insn_bitsize)
    980 	  ; /* This is ok.  */
    981 	else
    982 	  cd->base_insn_bitsize = CGEN_SIZE_UNKNOWN;
    983 
    984 	/* Set min,max insn sizes.  */
    985 	if (isa->min_insn_bitsize < cd->min_insn_bitsize)
    986 	  cd->min_insn_bitsize = isa->min_insn_bitsize;
    987 	if (isa->max_insn_bitsize > cd->max_insn_bitsize)
    988 	  cd->max_insn_bitsize = isa->max_insn_bitsize;
    989       }
    990 
    991   /* Data derived from the mach spec.  */
    992   for (i = 0; i < MAX_MACHS; ++i)
    993     if (((1 << i) & machs) != 0)
    994       {
    995 	const CGEN_MACH *mach = & lm32_cgen_mach_table[i];
    996 
    997 	if (mach->insn_chunk_bitsize != 0)
    998 	{
    999 	  if (cd->insn_chunk_bitsize != 0 && cd->insn_chunk_bitsize != mach->insn_chunk_bitsize)
   1000 	    {
   1001 	      opcodes_error_handler
   1002 		(/* xgettext:c-format */
   1003 		 _("internal error: lm32_cgen_rebuild_tables: "
   1004 		   "conflicting insn-chunk-bitsize values: `%d' vs. `%d'"),
   1005 		 cd->insn_chunk_bitsize, mach->insn_chunk_bitsize);
   1006 	      abort ();
   1007 	    }
   1008 
   1009  	  cd->insn_chunk_bitsize = mach->insn_chunk_bitsize;
   1010 	}
   1011       }
   1012 
   1013   /* Determine which hw elements are used by MACH.  */
   1014   build_hw_table (cd);
   1015 
   1016   /* Build the ifield table.  */
   1017   build_ifield_table (cd);
   1018 
   1019   /* Determine which operands are used by MACH/ISA.  */
   1020   build_operand_table (cd);
   1021 
   1022   /* Build the instruction table.  */
   1023   build_insn_table (cd);
   1024 }
   1025 
   1026 /* Initialize a cpu table and return a descriptor.
   1027    It's much like opening a file, and must be the first function called.
   1028    The arguments are a set of (type/value) pairs, terminated with
   1029    CGEN_CPU_OPEN_END.
   1030 
   1031    Currently supported values:
   1032    CGEN_CPU_OPEN_ISAS:    bitmap of values in enum isa_attr
   1033    CGEN_CPU_OPEN_MACHS:   bitmap of values in enum mach_attr
   1034    CGEN_CPU_OPEN_BFDMACH: specify 1 mach using bfd name
   1035    CGEN_CPU_OPEN_ENDIAN:  specify endian choice
   1036    CGEN_CPU_OPEN_INSN_ENDIAN: specify instruction endian choice
   1037    CGEN_CPU_OPEN_END:     terminates arguments
   1038 
   1039    ??? Simultaneous multiple isas might not make sense, but it's not (yet)
   1040    precluded.  */
   1041 
   1042 CGEN_CPU_DESC
   1043 lm32_cgen_cpu_open (enum cgen_cpu_open_arg arg_type, ...)
   1044 {
   1045   CGEN_CPU_TABLE *cd = (CGEN_CPU_TABLE *) xmalloc (sizeof (CGEN_CPU_TABLE));
   1046   static int init_p;
   1047   CGEN_BITSET *isas = 0;  /* 0 = "unspecified" */
   1048   unsigned int machs = 0; /* 0 = "unspecified" */
   1049   enum cgen_endian endian = CGEN_ENDIAN_UNKNOWN;
   1050   enum cgen_endian insn_endian = CGEN_ENDIAN_UNKNOWN;
   1051   va_list ap;
   1052 
   1053   if (! init_p)
   1054     {
   1055       init_tables ();
   1056       init_p = 1;
   1057     }
   1058 
   1059   memset (cd, 0, sizeof (*cd));
   1060 
   1061   va_start (ap, arg_type);
   1062   while (arg_type != CGEN_CPU_OPEN_END)
   1063     {
   1064       switch (arg_type)
   1065 	{
   1066 	case CGEN_CPU_OPEN_ISAS :
   1067 	  isas = va_arg (ap, CGEN_BITSET *);
   1068 	  break;
   1069 	case CGEN_CPU_OPEN_MACHS :
   1070 	  machs = va_arg (ap, unsigned int);
   1071 	  break;
   1072 	case CGEN_CPU_OPEN_BFDMACH :
   1073 	  {
   1074 	    const char *name = va_arg (ap, const char *);
   1075 	    const CGEN_MACH *mach =
   1076 	      lookup_mach_via_bfd_name (lm32_cgen_mach_table, name);
   1077 
   1078 	    if (mach != NULL)
   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 	case CGEN_CPU_OPEN_INSN_ENDIAN :
   1086 	  insn_endian = va_arg (ap, enum cgen_endian);
   1087 	  break;
   1088 	default :
   1089 	  opcodes_error_handler
   1090 	    (/* xgettext:c-format */
   1091 	     _("internal error: lm32_cgen_cpu_open: "
   1092 	       "unsupported argument `%d'"),
   1093 	     arg_type);
   1094 	  abort (); /* ??? return NULL? */
   1095 	}
   1096       arg_type = va_arg (ap, enum cgen_cpu_open_arg);
   1097     }
   1098   va_end (ap);
   1099 
   1100   /* Mach unspecified means "all".  */
   1101   if (machs == 0)
   1102     machs = (1 << MAX_MACHS) - 1;
   1103   /* Base mach is always selected.  */
   1104   machs |= 1;
   1105   if (endian == CGEN_ENDIAN_UNKNOWN)
   1106     {
   1107       /* ??? If target has only one, could have a default.  */
   1108       opcodes_error_handler
   1109 	(/* xgettext:c-format */
   1110 	 _("internal error: lm32_cgen_cpu_open: no endianness specified"));
   1111       abort ();
   1112     }
   1113 
   1114   cd->isas = cgen_bitset_copy (isas);
   1115   cd->machs = machs;
   1116   cd->endian = endian;
   1117   cd->insn_endian
   1118     = (insn_endian == CGEN_ENDIAN_UNKNOWN ? endian : insn_endian);
   1119 
   1120   /* Table (re)builder.  */
   1121   cd->rebuild_tables = lm32_cgen_rebuild_tables;
   1122   lm32_cgen_rebuild_tables (cd);
   1123 
   1124   /* Default to not allowing signed overflow.  */
   1125   cd->signed_overflow_ok_p = 0;
   1126 
   1127   return (CGEN_CPU_DESC) cd;
   1128 }
   1129 
   1130 /* Cover fn to lm32_cgen_cpu_open to handle the simple case of 1 isa, 1 mach.
   1131    MACH_NAME is the bfd name of the mach.  */
   1132 
   1133 CGEN_CPU_DESC
   1134 lm32_cgen_cpu_open_1 (const char *mach_name, enum cgen_endian endian)
   1135 {
   1136   return lm32_cgen_cpu_open (CGEN_CPU_OPEN_BFDMACH, mach_name,
   1137 			       CGEN_CPU_OPEN_ENDIAN, endian,
   1138 			       CGEN_CPU_OPEN_END);
   1139 }
   1140 
   1141 /* Close a cpu table.
   1142    ??? This can live in a machine independent file, but there's currently
   1143    no place to put this file (there's no libcgen).  libopcodes is the wrong
   1144    place as some simulator ports use this but they don't use libopcodes.  */
   1145 
   1146 void
   1147 lm32_cgen_cpu_close (CGEN_CPU_DESC cd)
   1148 {
   1149   unsigned int i;
   1150   const CGEN_INSN *insns;
   1151 
   1152   if (cd->macro_insn_table.init_entries)
   1153     {
   1154       insns = cd->macro_insn_table.init_entries;
   1155       for (i = 0; i < cd->macro_insn_table.num_init_entries; ++i, ++insns)
   1156 	if (CGEN_INSN_RX ((insns)))
   1157 	  regfree (CGEN_INSN_RX (insns));
   1158     }
   1159 
   1160   if (cd->insn_table.init_entries)
   1161     {
   1162       insns = cd->insn_table.init_entries;
   1163       for (i = 0; i < cd->insn_table.num_init_entries; ++i, ++insns)
   1164 	if (CGEN_INSN_RX (insns))
   1165 	  regfree (CGEN_INSN_RX (insns));
   1166     }
   1167 
   1168   free ((CGEN_INSN *) cd->macro_insn_table.init_entries);
   1169   free ((CGEN_INSN *) cd->insn_table.init_entries);
   1170   free ((CGEN_HW_ENTRY *) cd->hw_table.entries);
   1171   free ((CGEN_HW_ENTRY *) cd->operand_table.entries);
   1172   free (cd);
   1173 }
   1174 
   1175