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