OSDN Git Service

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