Fix compile time warnings
[binutils-gdb.git] / opcodes / openrisc-desc.c
1 /* CPU data for openrisc.
2
3 THIS FILE IS MACHINE GENERATED WITH CGEN.
4
5 Copyright 1996, 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
6
7 This file is part of the GNU Binutils and/or GDB, the GNU debugger.
8
9 This program 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 2, or (at your option)
12 any later version.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public 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 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22
23 */
24
25 #include "sysdep.h"
26 #include <ctype.h>
27 #include <stdio.h>
28 #include <stdarg.h>
29 #include "ansidecl.h"
30 #include "bfd.h"
31 #include "symcat.h"
32 #include "openrisc-desc.h"
33 #include "openrisc-opc.h"
34 #include "opintl.h"
35 #include "libiberty.h"
36
37 static void init_tables PARAMS ((void));
38 static const CGEN_MACH * lookup_mach_via_bfd_name PARAMS ((const CGEN_MACH *, const char *));
39 static void build_hw_table PARAMS ((CGEN_CPU_TABLE *));
40 static void build_ifield_table PARAMS ((CGEN_CPU_TABLE *));
41 static void build_operand_table PARAMS ((CGEN_CPU_TABLE *));
42 static void build_insn_table PARAMS ((CGEN_CPU_TABLE *));
43 static void openrisc_cgen_rebuild_tables PARAMS ((CGEN_CPU_TABLE *));
44 /* Attributes. */
45
46 static const CGEN_ATTR_ENTRY bool_attr[] =
47 {
48 { "#f", 0 },
49 { "#t", 1 },
50 { 0, 0 }
51 };
52
53 static const CGEN_ATTR_ENTRY MACH_attr[] =
54 {
55 { "base", MACH_BASE },
56 { "openrisc", MACH_OPENRISC },
57 { "or1300", MACH_OR1300 },
58 { "max", MACH_MAX },
59 { 0, 0 }
60 };
61
62 static const CGEN_ATTR_ENTRY ISA_attr[] =
63 {
64 { "or32", ISA_OR32 },
65 { "max", ISA_MAX },
66 { 0, 0 }
67 };
68
69 static const CGEN_ATTR_ENTRY HAS_CACHE_attr[] =
70 {
71 { "DATA_CACHE", HAS_CACHE_DATA_CACHE },
72 { "INSN_CACHE", HAS_CACHE_INSN_CACHE },
73 { 0, 0 }
74 };
75
76 const CGEN_ATTR_TABLE openrisc_cgen_ifield_attr_table[] =
77 {
78 { "MACH", & MACH_attr[0], & MACH_attr[0] },
79 { "VIRTUAL", &bool_attr[0], &bool_attr[0] },
80 { "PCREL-ADDR", &bool_attr[0], &bool_attr[0] },
81 { "ABS-ADDR", &bool_attr[0], &bool_attr[0] },
82 { "RESERVED", &bool_attr[0], &bool_attr[0] },
83 { "SIGN-OPT", &bool_attr[0], &bool_attr[0] },
84 { "SIGNED", &bool_attr[0], &bool_attr[0] },
85 { 0, 0, 0 }
86 };
87
88 const CGEN_ATTR_TABLE openrisc_cgen_hardware_attr_table[] =
89 {
90 { "MACH", & MACH_attr[0], & MACH_attr[0] },
91 { "VIRTUAL", &bool_attr[0], &bool_attr[0] },
92 { "CACHE-ADDR", &bool_attr[0], &bool_attr[0] },
93 { "PC", &bool_attr[0], &bool_attr[0] },
94 { "PROFILE", &bool_attr[0], &bool_attr[0] },
95 { 0, 0, 0 }
96 };
97
98 const CGEN_ATTR_TABLE openrisc_cgen_operand_attr_table[] =
99 {
100 { "MACH", & MACH_attr[0], & MACH_attr[0] },
101 { "VIRTUAL", &bool_attr[0], &bool_attr[0] },
102 { "PCREL-ADDR", &bool_attr[0], &bool_attr[0] },
103 { "ABS-ADDR", &bool_attr[0], &bool_attr[0] },
104 { "SIGN-OPT", &bool_attr[0], &bool_attr[0] },
105 { "SIGNED", &bool_attr[0], &bool_attr[0] },
106 { "NEGATIVE", &bool_attr[0], &bool_attr[0] },
107 { "RELAX", &bool_attr[0], &bool_attr[0] },
108 { "SEM-ONLY", &bool_attr[0], &bool_attr[0] },
109 { 0, 0, 0 }
110 };
111
112 const CGEN_ATTR_TABLE openrisc_cgen_insn_attr_table[] =
113 {
114 { "MACH", & MACH_attr[0], & MACH_attr[0] },
115 { "ALIAS", &bool_attr[0], &bool_attr[0] },
116 { "VIRTUAL", &bool_attr[0], &bool_attr[0] },
117 { "UNCOND-CTI", &bool_attr[0], &bool_attr[0] },
118 { "COND-CTI", &bool_attr[0], &bool_attr[0] },
119 { "SKIP-CTI", &bool_attr[0], &bool_attr[0] },
120 { "DELAY-SLOT", &bool_attr[0], &bool_attr[0] },
121 { "RELAXABLE", &bool_attr[0], &bool_attr[0] },
122 { "RELAX", &bool_attr[0], &bool_attr[0] },
123 { "NO-DIS", &bool_attr[0], &bool_attr[0] },
124 { "PBB", &bool_attr[0], &bool_attr[0] },
125 { "NOT-IN-DELAY-SLOT", &bool_attr[0], &bool_attr[0] },
126 { 0, 0, 0 }
127 };
128
129 /* Instruction set variants. */
130
131 static const CGEN_ISA openrisc_cgen_isa_table[] = {
132 { "or32", 32, 32, 32, 32 },
133 { 0, 0, 0, 0, 0 }
134 };
135
136 /* Machine variants. */
137
138 static const CGEN_MACH openrisc_cgen_mach_table[] = {
139 { "openrisc", "openrisc", MACH_OPENRISC, 0 },
140 { "or1300", "openrisc:1300", MACH_OR1300, 0 },
141 { 0, 0, 0, 0 }
142 };
143
144 static CGEN_KEYWORD_ENTRY openrisc_cgen_opval_h_gr_entries[] =
145 {
146 { "r0", 0, {0, {0}}, 0, 0 },
147 { "r1", 1, {0, {0}}, 0, 0 },
148 { "r2", 2, {0, {0}}, 0, 0 },
149 { "r3", 3, {0, {0}}, 0, 0 },
150 { "r4", 4, {0, {0}}, 0, 0 },
151 { "r5", 5, {0, {0}}, 0, 0 },
152 { "r6", 6, {0, {0}}, 0, 0 },
153 { "r7", 7, {0, {0}}, 0, 0 },
154 { "r8", 8, {0, {0}}, 0, 0 },
155 { "r9", 9, {0, {0}}, 0, 0 },
156 { "r10", 10, {0, {0}}, 0, 0 },
157 { "r11", 11, {0, {0}}, 0, 0 },
158 { "r12", 12, {0, {0}}, 0, 0 },
159 { "r13", 13, {0, {0}}, 0, 0 },
160 { "r14", 14, {0, {0}}, 0, 0 },
161 { "r15", 15, {0, {0}}, 0, 0 },
162 { "r16", 16, {0, {0}}, 0, 0 },
163 { "r17", 17, {0, {0}}, 0, 0 },
164 { "r18", 18, {0, {0}}, 0, 0 },
165 { "r19", 19, {0, {0}}, 0, 0 },
166 { "r20", 20, {0, {0}}, 0, 0 },
167 { "r21", 21, {0, {0}}, 0, 0 },
168 { "r22", 22, {0, {0}}, 0, 0 },
169 { "r23", 23, {0, {0}}, 0, 0 },
170 { "r24", 24, {0, {0}}, 0, 0 },
171 { "r25", 25, {0, {0}}, 0, 0 },
172 { "r26", 26, {0, {0}}, 0, 0 },
173 { "r27", 27, {0, {0}}, 0, 0 },
174 { "r28", 28, {0, {0}}, 0, 0 },
175 { "r29", 29, {0, {0}}, 0, 0 },
176 { "r30", 30, {0, {0}}, 0, 0 },
177 { "r31", 31, {0, {0}}, 0, 0 },
178 { "lr", 11, {0, {0}}, 0, 0 },
179 { "sp", 1, {0, {0}}, 0, 0 },
180 { "fp", 2, {0, {0}}, 0, 0 }
181 };
182
183 CGEN_KEYWORD openrisc_cgen_opval_h_gr =
184 {
185 & openrisc_cgen_opval_h_gr_entries[0],
186 35,
187 0, 0, 0, 0, ""
188 };
189
190
191 /* The hardware table. */
192
193 #if defined (__STDC__) || defined (ALMOST_STDC) || defined (HAVE_STRINGIZE)
194 #define A(a) (1 << CGEN_HW_##a)
195 #else
196 #define A(a) (1 << CGEN_HW_/**/a)
197 #endif
198
199 const CGEN_HW_ENTRY openrisc_cgen_hw_table[] =
200 {
201 { "h-memory", HW_H_MEMORY, CGEN_ASM_NONE, 0, { 0, { (1<<MACH_BASE) } } },
202 { "h-sint", HW_H_SINT, CGEN_ASM_NONE, 0, { 0, { (1<<MACH_BASE) } } },
203 { "h-uint", HW_H_UINT, CGEN_ASM_NONE, 0, { 0, { (1<<MACH_BASE) } } },
204 { "h-addr", HW_H_ADDR, CGEN_ASM_NONE, 0, { 0, { (1<<MACH_BASE) } } },
205 { "h-iaddr", HW_H_IADDR, CGEN_ASM_NONE, 0, { 0, { (1<<MACH_BASE) } } },
206 { "h-pc", HW_H_PC, CGEN_ASM_NONE, 0, { 0|A(PROFILE)|A(PC), { (1<<MACH_BASE) } } },
207 { "h-gr", HW_H_GR, CGEN_ASM_KEYWORD, (PTR) & openrisc_cgen_opval_h_gr, { 0|A(PROFILE), { (1<<MACH_BASE) } } },
208 { "h-sr", HW_H_SR, CGEN_ASM_NONE, 0, { 0, { (1<<MACH_BASE) } } },
209 { "h-hi16", HW_H_HI16, CGEN_ASM_NONE, 0, { 0, { (1<<MACH_BASE) } } },
210 { "h-lo16", HW_H_LO16, CGEN_ASM_NONE, 0, { 0, { (1<<MACH_BASE) } } },
211 { "h-cbit", HW_H_CBIT, CGEN_ASM_NONE, 0, { 0, { (1<<MACH_BASE) } } },
212 { "h-delay-insn", HW_H_DELAY_INSN, CGEN_ASM_NONE, 0, { 0, { (1<<MACH_BASE) } } },
213 { 0, 0, CGEN_ASM_NONE, 0, {0, {0}} }
214 };
215
216 #undef A
217
218
219 /* The instruction field table. */
220
221 #if defined (__STDC__) || defined (ALMOST_STDC) || defined (HAVE_STRINGIZE)
222 #define A(a) (1 << CGEN_IFLD_##a)
223 #else
224 #define A(a) (1 << CGEN_IFLD_/**/a)
225 #endif
226
227 const CGEN_IFLD openrisc_cgen_ifld_table[] =
228 {
229 { OPENRISC_F_NIL, "f-nil", 0, 0, 0, 0, { 0, { (1<<MACH_BASE) } } },
230 { OPENRISC_F_ANYOF, "f-anyof", 0, 0, 0, 0, { 0, { (1<<MACH_BASE) } } },
231 { OPENRISC_F_CLASS, "f-class", 0, 32, 31, 2, { 0, { (1<<MACH_BASE) } } },
232 { OPENRISC_F_SUB, "f-sub", 0, 32, 29, 4, { 0, { (1<<MACH_BASE) } } },
233 { OPENRISC_F_R1, "f-r1", 0, 32, 25, 5, { 0, { (1<<MACH_BASE) } } },
234 { OPENRISC_F_R2, "f-r2", 0, 32, 20, 5, { 0, { (1<<MACH_BASE) } } },
235 { OPENRISC_F_R3, "f-r3", 0, 32, 15, 5, { 0, { (1<<MACH_BASE) } } },
236 { OPENRISC_F_SIMM16, "f-simm16", 0, 32, 15, 16, { 0, { (1<<MACH_BASE) } } },
237 { OPENRISC_F_UIMM16, "f-uimm16", 0, 32, 15, 16, { 0, { (1<<MACH_BASE) } } },
238 { OPENRISC_F_UIMM5, "f-uimm5", 0, 32, 4, 5, { 0, { (1<<MACH_BASE) } } },
239 { OPENRISC_F_HI16, "f-hi16", 0, 32, 15, 16, { 0, { (1<<MACH_BASE) } } },
240 { OPENRISC_F_LO16, "f-lo16", 0, 32, 15, 16, { 0, { (1<<MACH_BASE) } } },
241 { OPENRISC_F_OP1, "f-op1", 0, 32, 31, 2, { 0, { (1<<MACH_BASE) } } },
242 { OPENRISC_F_OP2, "f-op2", 0, 32, 29, 4, { 0, { (1<<MACH_BASE) } } },
243 { OPENRISC_F_OP3, "f-op3", 0, 32, 25, 2, { 0, { (1<<MACH_BASE) } } },
244 { OPENRISC_F_OP4, "f-op4", 0, 32, 23, 3, { 0, { (1<<MACH_BASE) } } },
245 { OPENRISC_F_OP5, "f-op5", 0, 32, 25, 5, { 0, { (1<<MACH_BASE) } } },
246 { OPENRISC_F_OP6, "f-op6", 0, 32, 7, 3, { 0, { (1<<MACH_BASE) } } },
247 { OPENRISC_F_OP7, "f-op7", 0, 32, 3, 4, { 0, { (1<<MACH_BASE) } } },
248 { OPENRISC_F_I16_1, "f-i16-1", 0, 32, 10, 11, { 0, { (1<<MACH_BASE) } } },
249 { OPENRISC_F_I16_2, "f-i16-2", 0, 32, 25, 5, { 0, { (1<<MACH_BASE) } } },
250 { OPENRISC_F_DISP26, "f-disp26", 0, 32, 25, 26, { 0|A(PCREL_ADDR), { (1<<MACH_BASE) } } },
251 { OPENRISC_F_ABS26, "f-abs26", 0, 32, 25, 26, { 0|A(ABS_ADDR), { (1<<MACH_BASE) } } },
252 { OPENRISC_F_F_15_8, "f-f-15-8", 0, 32, 15, 8, { 0|A(RESERVED), { (1<<MACH_BASE) } } },
253 { OPENRISC_F_F_10_3, "f-f-10-3", 0, 32, 10, 3, { 0|A(RESERVED), { (1<<MACH_BASE) } } },
254 { OPENRISC_F_F_4_1, "f-f-4-1", 0, 32, 4, 1, { 0|A(RESERVED), { (1<<MACH_BASE) } } },
255 { OPENRISC_F_F_7_3, "f-f-7-3", 0, 32, 7, 3, { 0|A(RESERVED), { (1<<MACH_BASE) } } },
256 { OPENRISC_F_F_10_7, "f-f-10-7", 0, 32, 10, 7, { 0|A(RESERVED), { (1<<MACH_BASE) } } },
257 { OPENRISC_F_F_10_11, "f-f-10-11", 0, 32, 10, 11, { 0|A(RESERVED), { (1<<MACH_BASE) } } },
258 { 0, 0, 0, 0, 0, 0, {0, {0}} }
259 };
260
261 #undef A
262
263
264 /* The operand table. */
265
266 #if defined (__STDC__) || defined (ALMOST_STDC) || defined (HAVE_STRINGIZE)
267 #define A(a) (1 << CGEN_OPERAND_##a)
268 #else
269 #define A(a) (1 << CGEN_OPERAND_/**/a)
270 #endif
271 #if defined (__STDC__) || defined (ALMOST_STDC) || defined (HAVE_STRINGIZE)
272 #define OPERAND(op) OPENRISC_OPERAND_##op
273 #else
274 #define OPERAND(op) OPENRISC_OPERAND_/**/op
275 #endif
276
277 const CGEN_OPERAND openrisc_cgen_operand_table[] =
278 {
279 /* pc: program counter */
280 { "pc", OPENRISC_OPERAND_PC, HW_H_PC, 0, 0,
281 { 0|A(SEM_ONLY), { (1<<MACH_BASE) } } },
282 /* sr: special register */
283 { "sr", OPENRISC_OPERAND_SR, HW_H_SR, 0, 0,
284 { 0|A(SEM_ONLY), { (1<<MACH_BASE) } } },
285 /* cbit: condition bit */
286 { "cbit", OPENRISC_OPERAND_CBIT, HW_H_CBIT, 0, 0,
287 { 0|A(SEM_ONLY), { (1<<MACH_BASE) } } },
288 /* simm-16: 16 bit signed immediate */
289 { "simm-16", OPENRISC_OPERAND_SIMM_16, HW_H_SINT, 15, 16,
290 { 0, { (1<<MACH_BASE) } } },
291 /* uimm-16: 16 bit unsigned immediate */
292 { "uimm-16", OPENRISC_OPERAND_UIMM_16, HW_H_UINT, 15, 16,
293 { 0, { (1<<MACH_BASE) } } },
294 /* disp-26: pc-rel 26 bit */
295 { "disp-26", OPENRISC_OPERAND_DISP_26, HW_H_IADDR, 25, 26,
296 { 0|A(PCREL_ADDR), { (1<<MACH_BASE) } } },
297 /* abs-26: abs 26 bit */
298 { "abs-26", OPENRISC_OPERAND_ABS_26, HW_H_IADDR, 25, 26,
299 { 0|A(ABS_ADDR), { (1<<MACH_BASE) } } },
300 /* uimm-5: imm5 */
301 { "uimm-5", OPENRISC_OPERAND_UIMM_5, HW_H_UINT, 4, 5,
302 { 0, { (1<<MACH_BASE) } } },
303 /* rD: destination register */
304 { "rD", OPENRISC_OPERAND_RD, HW_H_GR, 25, 5,
305 { 0, { (1<<MACH_BASE) } } },
306 /* rA: source register A */
307 { "rA", OPENRISC_OPERAND_RA, HW_H_GR, 20, 5,
308 { 0, { (1<<MACH_BASE) } } },
309 /* rB: source register B */
310 { "rB", OPENRISC_OPERAND_RB, HW_H_GR, 15, 5,
311 { 0, { (1<<MACH_BASE) } } },
312 /* op-f-23: f-op23 */
313 { "op-f-23", OPENRISC_OPERAND_OP_F_23, HW_H_UINT, 23, 3,
314 { 0, { (1<<MACH_BASE) } } },
315 /* op-f-3: f-op3 */
316 { "op-f-3", OPENRISC_OPERAND_OP_F_3, HW_H_UINT, 25, 5,
317 { 0, { (1<<MACH_BASE) } } },
318 /* hi16: high 16 bit immediate, sign optional */
319 { "hi16", OPENRISC_OPERAND_HI16, HW_H_HI16, 15, 16,
320 { 0|A(SIGN_OPT), { (1<<MACH_BASE) } } },
321 /* lo16: low 16 bit immediate, sign optional */
322 { "lo16", OPENRISC_OPERAND_LO16, HW_H_LO16, 15, 16,
323 { 0|A(SIGN_OPT), { (1<<MACH_BASE) } } },
324 /* ui16nc: 16 bit immediate, sign optional */
325 { "ui16nc", OPENRISC_OPERAND_UI16NC, HW_H_LO16, 10, 16,
326 { 0|A(SIGN_OPT)|A(VIRTUAL), { (1<<MACH_BASE) } } },
327 { 0, 0, 0, 0, 0, {0, {0}} }
328 };
329
330 #undef A
331
332
333 /* The instruction table. */
334
335 #define OP(field) CGEN_SYNTAX_MAKE_FIELD (OPERAND (field))
336 #if defined (__STDC__) || defined (ALMOST_STDC) || defined (HAVE_STRINGIZE)
337 #define A(a) (1 << CGEN_INSN_##a)
338 #else
339 #define A(a) (1 << CGEN_INSN_/**/a)
340 #endif
341
342 static const CGEN_IBASE openrisc_cgen_insn_table[MAX_INSNS] =
343 {
344 /* Special null first entry.
345 A `num' value of zero is thus invalid.
346 Also, the special `invalid' insn resides here. */
347 { 0, 0, 0, 0, {0, {0}} },
348 /* l.j ${abs-26} */
349 {
350 OPENRISC_INSN_L_J, "l-j", "l.j", 32,
351 { 0|A(NOT_IN_DELAY_SLOT)|A(UNCOND_CTI)|A(DELAY_SLOT), { (1<<MACH_BASE) } }
352 },
353 /* l.jal ${abs-26} */
354 {
355 OPENRISC_INSN_L_JAL, "l-jal", "l.jal", 32,
356 { 0|A(NOT_IN_DELAY_SLOT)|A(UNCOND_CTI)|A(DELAY_SLOT), { (1<<MACH_BASE) } }
357 },
358 /* l.jr $rA */
359 {
360 OPENRISC_INSN_L_JR, "l-jr", "l.jr", 32,
361 { 0|A(NOT_IN_DELAY_SLOT)|A(UNCOND_CTI)|A(DELAY_SLOT), { (1<<MACH_BASE) } }
362 },
363 /* l.jalr $rA */
364 {
365 OPENRISC_INSN_L_JALR, "l-jalr", "l.jalr", 32,
366 { 0|A(NOT_IN_DELAY_SLOT)|A(UNCOND_CTI)|A(DELAY_SLOT), { (1<<MACH_BASE) } }
367 },
368 /* l.bal ${disp-26} */
369 {
370 OPENRISC_INSN_L_BAL, "l-bal", "l.bal", 32,
371 { 0|A(NOT_IN_DELAY_SLOT)|A(UNCOND_CTI)|A(DELAY_SLOT), { (1<<MACH_BASE) } }
372 },
373 /* l.bnf ${disp-26} */
374 {
375 OPENRISC_INSN_L_BNF, "l-bnf", "l.bnf", 32,
376 { 0|A(NOT_IN_DELAY_SLOT)|A(COND_CTI)|A(DELAY_SLOT), { (1<<MACH_BASE) } }
377 },
378 /* l.bf ${disp-26} */
379 {
380 OPENRISC_INSN_L_BF, "l-bf", "l.bf", 32,
381 { 0|A(NOT_IN_DELAY_SLOT)|A(COND_CTI)|A(DELAY_SLOT), { (1<<MACH_BASE) } }
382 },
383 /* l.brk ${uimm-16} */
384 {
385 OPENRISC_INSN_L_BRK, "l-brk", "l.brk", 32,
386 { 0|A(NOT_IN_DELAY_SLOT), { (1<<MACH_BASE) } }
387 },
388 /* l.rfe $rA */
389 {
390 OPENRISC_INSN_L_RFE, "l-rfe", "l.rfe", 32,
391 { 0|A(NOT_IN_DELAY_SLOT)|A(UNCOND_CTI)|A(DELAY_SLOT), { (1<<MACH_BASE) } }
392 },
393 /* l.sys ${uimm-16} */
394 {
395 OPENRISC_INSN_L_SYS, "l-sys", "l.sys", 32,
396 { 0|A(NOT_IN_DELAY_SLOT)|A(UNCOND_CTI)|A(DELAY_SLOT), { (1<<MACH_BASE) } }
397 },
398 /* l.nop */
399 {
400 OPENRISC_INSN_L_NOP, "l-nop", "l.nop", 32,
401 { 0, { (1<<MACH_BASE) } }
402 },
403 /* l.movhi $rD,$hi16 */
404 {
405 OPENRISC_INSN_L_MOVHI, "l-movhi", "l.movhi", 32,
406 { 0|A(DELAY_SLOT), { (1<<MACH_BASE) } }
407 },
408 /* l.mfsr $rD,$rA */
409 {
410 OPENRISC_INSN_L_MFSR, "l-mfsr", "l.mfsr", 32,
411 { 0|A(DELAY_SLOT), { (1<<MACH_BASE) } }
412 },
413 /* l.mtsr $rA,$rB */
414 {
415 OPENRISC_INSN_L_MTSR, "l-mtsr", "l.mtsr", 32,
416 { 0|A(DELAY_SLOT), { (1<<MACH_BASE) } }
417 },
418 /* l.lw $rD,${simm-16}($rA) */
419 {
420 OPENRISC_INSN_L_LW, "l-lw", "l.lw", 32,
421 { 0|A(DELAY_SLOT), { (1<<MACH_BASE) } }
422 },
423 /* l.lbz $rD,${simm-16}($rA) */
424 {
425 OPENRISC_INSN_L_LBZ, "l-lbz", "l.lbz", 32,
426 { 0|A(DELAY_SLOT), { (1<<MACH_BASE) } }
427 },
428 /* l.lbs $rD,${simm-16}($rA) */
429 {
430 OPENRISC_INSN_L_LBS, "l-lbs", "l.lbs", 32,
431 { 0|A(DELAY_SLOT), { (1<<MACH_BASE) } }
432 },
433 /* l.lhz $rD,${simm-16}($rA) */
434 {
435 OPENRISC_INSN_L_LHZ, "l-lhz", "l.lhz", 32,
436 { 0|A(DELAY_SLOT), { (1<<MACH_BASE) } }
437 },
438 /* l.lhs $rD,${simm-16}($rA) */
439 {
440 OPENRISC_INSN_L_LHS, "l-lhs", "l.lhs", 32,
441 { 0|A(DELAY_SLOT), { (1<<MACH_BASE) } }
442 },
443 /* l.sw ${ui16nc}($rA),$rB */
444 {
445 OPENRISC_INSN_L_SW, "l-sw", "l.sw", 32,
446 { 0|A(DELAY_SLOT), { (1<<MACH_BASE) } }
447 },
448 /* l.sb ${ui16nc}($rA),$rB */
449 {
450 OPENRISC_INSN_L_SB, "l-sb", "l.sb", 32,
451 { 0|A(DELAY_SLOT), { (1<<MACH_BASE) } }
452 },
453 /* l.sh ${ui16nc}($rA),$rB */
454 {
455 OPENRISC_INSN_L_SH, "l-sh", "l.sh", 32,
456 { 0|A(DELAY_SLOT), { (1<<MACH_BASE) } }
457 },
458 /* l.sll $rD,$rA,$rB */
459 {
460 OPENRISC_INSN_L_SLL, "l-sll", "l.sll", 32,
461 { 0, { (1<<MACH_BASE) } }
462 },
463 /* l.slli $rD,$rA,${uimm-5} */
464 {
465 OPENRISC_INSN_L_SLLI, "l-slli", "l.slli", 32,
466 { 0, { (1<<MACH_BASE) } }
467 },
468 /* l.srl $rD,$rA,$rB */
469 {
470 OPENRISC_INSN_L_SRL, "l-srl", "l.srl", 32,
471 { 0, { (1<<MACH_BASE) } }
472 },
473 /* l.srli $rD,$rA,${uimm-5} */
474 {
475 OPENRISC_INSN_L_SRLI, "l-srli", "l.srli", 32,
476 { 0, { (1<<MACH_BASE) } }
477 },
478 /* l.sra $rD,$rA,$rB */
479 {
480 OPENRISC_INSN_L_SRA, "l-sra", "l.sra", 32,
481 { 0, { (1<<MACH_BASE) } }
482 },
483 /* l.srai $rD,$rA,${uimm-5} */
484 {
485 OPENRISC_INSN_L_SRAI, "l-srai", "l.srai", 32,
486 { 0, { (1<<MACH_BASE) } }
487 },
488 /* l.ror $rD,$rA,$rB */
489 {
490 OPENRISC_INSN_L_ROR, "l-ror", "l.ror", 32,
491 { 0, { (1<<MACH_BASE) } }
492 },
493 /* l.rori $rD,$rA,${uimm-5} */
494 {
495 OPENRISC_INSN_L_RORI, "l-rori", "l.rori", 32,
496 { 0, { (1<<MACH_BASE) } }
497 },
498 /* l.add $rD,$rA,$rB */
499 {
500 OPENRISC_INSN_L_ADD, "l-add", "l.add", 32,
501 { 0, { (1<<MACH_BASE) } }
502 },
503 /* l.addi $rD,$rA,$lo16 */
504 {
505 OPENRISC_INSN_L_ADDI, "l-addi", "l.addi", 32,
506 { 0, { (1<<MACH_BASE) } }
507 },
508 /* l.sub $rD,$rA,$rB */
509 {
510 OPENRISC_INSN_L_SUB, "l-sub", "l.sub", 32,
511 { 0, { (1<<MACH_BASE) } }
512 },
513 /* l.subi $rD,$rA,$lo16 */
514 {
515 OPENRISC_INSN_L_SUBI, "l-subi", "l.subi", 32,
516 { 0, { (1<<MACH_BASE) } }
517 },
518 /* l.and $rD,$rA,$rB */
519 {
520 OPENRISC_INSN_L_AND, "l-and", "l.and", 32,
521 { 0, { (1<<MACH_BASE) } }
522 },
523 /* l.andi $rD,$rA,$lo16 */
524 {
525 OPENRISC_INSN_L_ANDI, "l-andi", "l.andi", 32,
526 { 0, { (1<<MACH_BASE) } }
527 },
528 /* l.or $rD,$rA,$rB */
529 {
530 OPENRISC_INSN_L_OR, "l-or", "l.or", 32,
531 { 0, { (1<<MACH_BASE) } }
532 },
533 /* l.ori $rD,$rA,$lo16 */
534 {
535 OPENRISC_INSN_L_ORI, "l-ori", "l.ori", 32,
536 { 0, { (1<<MACH_BASE) } }
537 },
538 /* l.xor $rD,$rA,$rB */
539 {
540 OPENRISC_INSN_L_XOR, "l-xor", "l.xor", 32,
541 { 0, { (1<<MACH_BASE) } }
542 },
543 /* l.xori $rD,$rA,$lo16 */
544 {
545 OPENRISC_INSN_L_XORI, "l-xori", "l.xori", 32,
546 { 0, { (1<<MACH_BASE) } }
547 },
548 /* l.mul $rD,$rA,$rB */
549 {
550 OPENRISC_INSN_L_MUL, "l-mul", "l.mul", 32,
551 { 0, { (1<<MACH_BASE) } }
552 },
553 /* l.muli $rD,$rA,$lo16 */
554 {
555 OPENRISC_INSN_L_MULI, "l-muli", "l.muli", 32,
556 { 0, { (1<<MACH_BASE) } }
557 },
558 /* l.div $rD,$rA,$rB */
559 {
560 OPENRISC_INSN_L_DIV, "l-div", "l.div", 32,
561 { 0|A(DELAY_SLOT), { (1<<MACH_BASE) } }
562 },
563 /* l.divu $rD,$rA,$rB */
564 {
565 OPENRISC_INSN_L_DIVU, "l-divu", "l.divu", 32,
566 { 0|A(DELAY_SLOT), { (1<<MACH_BASE) } }
567 },
568 /* l.sfgts $rA,$rB */
569 {
570 OPENRISC_INSN_L_SFGTS, "l-sfgts", "l.sfgts", 32,
571 { 0|A(DELAY_SLOT), { (1<<MACH_BASE) } }
572 },
573 /* l.sfgtu $rA,$rB */
574 {
575 OPENRISC_INSN_L_SFGTU, "l-sfgtu", "l.sfgtu", 32,
576 { 0|A(DELAY_SLOT), { (1<<MACH_BASE) } }
577 },
578 /* l.sfges $rA,$rB */
579 {
580 OPENRISC_INSN_L_SFGES, "l-sfges", "l.sfges", 32,
581 { 0|A(DELAY_SLOT), { (1<<MACH_BASE) } }
582 },
583 /* l.sfgeu $rA,$rB */
584 {
585 OPENRISC_INSN_L_SFGEU, "l-sfgeu", "l.sfgeu", 32,
586 { 0|A(DELAY_SLOT), { (1<<MACH_BASE) } }
587 },
588 /* l.sflts $rA,$rB */
589 {
590 OPENRISC_INSN_L_SFLTS, "l-sflts", "l.sflts", 32,
591 { 0|A(DELAY_SLOT), { (1<<MACH_BASE) } }
592 },
593 /* l.sfltu $rA,$rB */
594 {
595 OPENRISC_INSN_L_SFLTU, "l-sfltu", "l.sfltu", 32,
596 { 0|A(DELAY_SLOT), { (1<<MACH_BASE) } }
597 },
598 /* l.sfles $rA,$rB */
599 {
600 OPENRISC_INSN_L_SFLES, "l-sfles", "l.sfles", 32,
601 { 0|A(DELAY_SLOT), { (1<<MACH_BASE) } }
602 },
603 /* l.sfleu $rA,$rB */
604 {
605 OPENRISC_INSN_L_SFLEU, "l-sfleu", "l.sfleu", 32,
606 { 0|A(DELAY_SLOT), { (1<<MACH_BASE) } }
607 },
608 /* l.sfgtsi $rA,${simm-16} */
609 {
610 OPENRISC_INSN_L_SFGTSI, "l-sfgtsi", "l.sfgtsi", 32,
611 { 0|A(DELAY_SLOT), { (1<<MACH_BASE) } }
612 },
613 /* l.sfgtui $rA,${uimm-16} */
614 {
615 OPENRISC_INSN_L_SFGTUI, "l-sfgtui", "l.sfgtui", 32,
616 { 0|A(DELAY_SLOT), { (1<<MACH_BASE) } }
617 },
618 /* l.sfgesi $rA,${simm-16} */
619 {
620 OPENRISC_INSN_L_SFGESI, "l-sfgesi", "l.sfgesi", 32,
621 { 0|A(DELAY_SLOT), { (1<<MACH_BASE) } }
622 },
623 /* l.sfgeui $rA,${uimm-16} */
624 {
625 OPENRISC_INSN_L_SFGEUI, "l-sfgeui", "l.sfgeui", 32,
626 { 0|A(DELAY_SLOT), { (1<<MACH_BASE) } }
627 },
628 /* l.sfltsi $rA,${simm-16} */
629 {
630 OPENRISC_INSN_L_SFLTSI, "l-sfltsi", "l.sfltsi", 32,
631 { 0|A(DELAY_SLOT), { (1<<MACH_BASE) } }
632 },
633 /* l.sfltui $rA,${uimm-16} */
634 {
635 OPENRISC_INSN_L_SFLTUI, "l-sfltui", "l.sfltui", 32,
636 { 0|A(DELAY_SLOT), { (1<<MACH_BASE) } }
637 },
638 /* l.sflesi $rA,${simm-16} */
639 {
640 OPENRISC_INSN_L_SFLESI, "l-sflesi", "l.sflesi", 32,
641 { 0|A(DELAY_SLOT), { (1<<MACH_BASE) } }
642 },
643 /* l.sfleui $rA,${uimm-16} */
644 {
645 OPENRISC_INSN_L_SFLEUI, "l-sfleui", "l.sfleui", 32,
646 { 0|A(DELAY_SLOT), { (1<<MACH_BASE) } }
647 },
648 /* l.sfeq $rA,$rB */
649 {
650 OPENRISC_INSN_L_SFEQ, "l-sfeq", "l.sfeq", 32,
651 { 0|A(DELAY_SLOT), { (1<<MACH_BASE) } }
652 },
653 /* l.sfeqi $rA,${simm-16} */
654 {
655 OPENRISC_INSN_L_SFEQI, "l-sfeqi", "l.sfeqi", 32,
656 { 0|A(DELAY_SLOT), { (1<<MACH_BASE) } }
657 },
658 /* l.sfne $rA,$rB */
659 {
660 OPENRISC_INSN_L_SFNE, "l-sfne", "l.sfne", 32,
661 { 0|A(DELAY_SLOT), { (1<<MACH_BASE) } }
662 },
663 /* l.sfnei $rA,${simm-16} */
664 {
665 OPENRISC_INSN_L_SFNEI, "l-sfnei", "l.sfnei", 32,
666 { 0|A(DELAY_SLOT), { (1<<MACH_BASE) } }
667 },
668 };
669
670 #undef OP
671 #undef A
672
673 /* Initialize anything needed to be done once, before any cpu_open call. */
674
675 static void
676 init_tables ()
677 {
678 }
679
680 /* Subroutine of openrisc_cgen_cpu_open to look up a mach via its bfd name. */
681
682 static const CGEN_MACH *
683 lookup_mach_via_bfd_name (table, name)
684 const CGEN_MACH *table;
685 const char *name;
686 {
687 while (table->name)
688 {
689 if (strcmp (name, table->bfd_name) == 0)
690 return table;
691 ++table;
692 }
693 abort ();
694 }
695
696 /* Subroutine of openrisc_cgen_cpu_open to build the hardware table. */
697
698 static void
699 build_hw_table (cd)
700 CGEN_CPU_TABLE *cd;
701 {
702 int i;
703 int machs = cd->machs;
704 const CGEN_HW_ENTRY *init = & openrisc_cgen_hw_table[0];
705 /* MAX_HW is only an upper bound on the number of selected entries.
706 However each entry is indexed by it's enum so there can be holes in
707 the table. */
708 const CGEN_HW_ENTRY **selected =
709 (const CGEN_HW_ENTRY **) xmalloc (MAX_HW * sizeof (CGEN_HW_ENTRY *));
710
711 cd->hw_table.init_entries = init;
712 cd->hw_table.entry_size = sizeof (CGEN_HW_ENTRY);
713 memset (selected, 0, MAX_HW * sizeof (CGEN_HW_ENTRY *));
714 /* ??? For now we just use machs to determine which ones we want. */
715 for (i = 0; init[i].name != NULL; ++i)
716 if (CGEN_HW_ATTR_VALUE (&init[i], CGEN_HW_MACH)
717 & machs)
718 selected[init[i].type] = &init[i];
719 cd->hw_table.entries = selected;
720 cd->hw_table.num_entries = MAX_HW;
721 }
722
723 /* Subroutine of openrisc_cgen_cpu_open to build the hardware table. */
724
725 static void
726 build_ifield_table (cd)
727 CGEN_CPU_TABLE *cd;
728 {
729 cd->ifld_table = & openrisc_cgen_ifld_table[0];
730 }
731
732 /* Subroutine of openrisc_cgen_cpu_open to build the hardware table. */
733
734 static void
735 build_operand_table (cd)
736 CGEN_CPU_TABLE *cd;
737 {
738 int i;
739 int machs = cd->machs;
740 const CGEN_OPERAND *init = & openrisc_cgen_operand_table[0];
741 /* MAX_OPERANDS is only an upper bound on the number of selected entries.
742 However each entry is indexed by it's enum so there can be holes in
743 the table. */
744 const CGEN_OPERAND **selected =
745 (const CGEN_OPERAND **) xmalloc (MAX_OPERANDS * sizeof (CGEN_OPERAND *));
746
747 cd->operand_table.init_entries = init;
748 cd->operand_table.entry_size = sizeof (CGEN_OPERAND);
749 memset (selected, 0, MAX_OPERANDS * sizeof (CGEN_OPERAND *));
750 /* ??? For now we just use mach to determine which ones we want. */
751 for (i = 0; init[i].name != NULL; ++i)
752 if (CGEN_OPERAND_ATTR_VALUE (&init[i], CGEN_OPERAND_MACH)
753 & machs)
754 selected[init[i].type] = &init[i];
755 cd->operand_table.entries = selected;
756 cd->operand_table.num_entries = MAX_OPERANDS;
757 }
758
759 /* Subroutine of openrisc_cgen_cpu_open to build the hardware table.
760 ??? This could leave out insns not supported by the specified mach/isa,
761 but that would cause errors like "foo only supported by bar" to become
762 "unknown insn", so for now we include all insns and require the app to
763 do the checking later.
764 ??? On the other hand, parsing of such insns may require their hardware or
765 operand elements to be in the table [which they mightn't be]. */
766
767 static void
768 build_insn_table (cd)
769 CGEN_CPU_TABLE *cd;
770 {
771 int i;
772 const CGEN_IBASE *ib = & openrisc_cgen_insn_table[0];
773 CGEN_INSN *insns = (CGEN_INSN *) xmalloc (MAX_INSNS * sizeof (CGEN_INSN));
774
775 memset (insns, 0, MAX_INSNS * sizeof (CGEN_INSN));
776 for (i = 0; i < MAX_INSNS; ++i)
777 insns[i].base = &ib[i];
778 cd->insn_table.init_entries = insns;
779 cd->insn_table.entry_size = sizeof (CGEN_IBASE);
780 cd->insn_table.num_init_entries = MAX_INSNS;
781 }
782
783 /* Subroutine of openrisc_cgen_cpu_open to rebuild the tables. */
784
785 static void
786 openrisc_cgen_rebuild_tables (cd)
787 CGEN_CPU_TABLE *cd;
788 {
789 int i;
790 unsigned int isas = cd->isas;
791 unsigned int machs = cd->machs;
792
793 cd->int_insn_p = CGEN_INT_INSN_P;
794
795 /* Data derived from the isa spec. */
796 #define UNSET (CGEN_SIZE_UNKNOWN + 1)
797 cd->default_insn_bitsize = UNSET;
798 cd->base_insn_bitsize = UNSET;
799 cd->min_insn_bitsize = 65535; /* some ridiculously big number */
800 cd->max_insn_bitsize = 0;
801 for (i = 0; i < MAX_ISAS; ++i)
802 if (((1 << i) & isas) != 0)
803 {
804 const CGEN_ISA *isa = & openrisc_cgen_isa_table[i];
805
806 /* Default insn sizes of all selected isas must be equal or we set
807 the result to 0, meaning "unknown". */
808 if (cd->default_insn_bitsize == UNSET)
809 cd->default_insn_bitsize = isa->default_insn_bitsize;
810 else if (isa->default_insn_bitsize == cd->default_insn_bitsize)
811 ; /* this is ok */
812 else
813 cd->default_insn_bitsize = CGEN_SIZE_UNKNOWN;
814
815 /* Base insn sizes of all selected isas must be equal or we set
816 the result to 0, meaning "unknown". */
817 if (cd->base_insn_bitsize == UNSET)
818 cd->base_insn_bitsize = isa->base_insn_bitsize;
819 else if (isa->base_insn_bitsize == cd->base_insn_bitsize)
820 ; /* this is ok */
821 else
822 cd->base_insn_bitsize = CGEN_SIZE_UNKNOWN;
823
824 /* Set min,max insn sizes. */
825 if (isa->min_insn_bitsize < cd->min_insn_bitsize)
826 cd->min_insn_bitsize = isa->min_insn_bitsize;
827 if (isa->max_insn_bitsize > cd->max_insn_bitsize)
828 cd->max_insn_bitsize = isa->max_insn_bitsize;
829 }
830
831 /* Data derived from the mach spec. */
832 for (i = 0; i < MAX_MACHS; ++i)
833 if (((1 << i) & machs) != 0)
834 {
835 const CGEN_MACH *mach = & openrisc_cgen_mach_table[i];
836
837 if (mach->insn_chunk_bitsize != 0)
838 {
839 if (cd->insn_chunk_bitsize != 0 && cd->insn_chunk_bitsize != mach->insn_chunk_bitsize)
840 {
841 fprintf (stderr, "openrisc_cgen_rebuild_tables: conflicting insn-chunk-bitsize values: `%d' vs. `%d'\n",
842 cd->insn_chunk_bitsize, mach->insn_chunk_bitsize);
843 abort ();
844 }
845
846 cd->insn_chunk_bitsize = mach->insn_chunk_bitsize;
847 }
848 }
849
850 /* Determine which hw elements are used by MACH. */
851 build_hw_table (cd);
852
853 /* Build the ifield table. */
854 build_ifield_table (cd);
855
856 /* Determine which operands are used by MACH/ISA. */
857 build_operand_table (cd);
858
859 /* Build the instruction table. */
860 build_insn_table (cd);
861 }
862
863 /* Initialize a cpu table and return a descriptor.
864 It's much like opening a file, and must be the first function called.
865 The arguments are a set of (type/value) pairs, terminated with
866 CGEN_CPU_OPEN_END.
867
868 Currently supported values:
869 CGEN_CPU_OPEN_ISAS: bitmap of values in enum isa_attr
870 CGEN_CPU_OPEN_MACHS: bitmap of values in enum mach_attr
871 CGEN_CPU_OPEN_BFDMACH: specify 1 mach using bfd name
872 CGEN_CPU_OPEN_ENDIAN: specify endian choice
873 CGEN_CPU_OPEN_END: terminates arguments
874
875 ??? Simultaneous multiple isas might not make sense, but it's not (yet)
876 precluded.
877
878 ??? We only support ISO C stdargs here, not K&R.
879 Laziness, plus experiment to see if anything requires K&R - eventually
880 K&R will no longer be supported - e.g. GDB is currently trying this. */
881
882 CGEN_CPU_DESC
883 openrisc_cgen_cpu_open (enum cgen_cpu_open_arg arg_type, ...)
884 {
885 CGEN_CPU_TABLE *cd = (CGEN_CPU_TABLE *) xmalloc (sizeof (CGEN_CPU_TABLE));
886 static int init_p;
887 unsigned int isas = 0; /* 0 = "unspecified" */
888 unsigned int machs = 0; /* 0 = "unspecified" */
889 enum cgen_endian endian = CGEN_ENDIAN_UNKNOWN;
890 va_list ap;
891
892 if (! init_p)
893 {
894 init_tables ();
895 init_p = 1;
896 }
897
898 memset (cd, 0, sizeof (*cd));
899
900 va_start (ap, arg_type);
901 while (arg_type != CGEN_CPU_OPEN_END)
902 {
903 switch (arg_type)
904 {
905 case CGEN_CPU_OPEN_ISAS :
906 isas = va_arg (ap, unsigned int);
907 break;
908 case CGEN_CPU_OPEN_MACHS :
909 machs = va_arg (ap, unsigned int);
910 break;
911 case CGEN_CPU_OPEN_BFDMACH :
912 {
913 const char *name = va_arg (ap, const char *);
914 const CGEN_MACH *mach =
915 lookup_mach_via_bfd_name (openrisc_cgen_mach_table, name);
916
917 machs |= 1 << mach->num;
918 break;
919 }
920 case CGEN_CPU_OPEN_ENDIAN :
921 endian = va_arg (ap, enum cgen_endian);
922 break;
923 default :
924 fprintf (stderr, "openrisc_cgen_cpu_open: unsupported argument `%d'\n",
925 arg_type);
926 abort (); /* ??? return NULL? */
927 }
928 arg_type = va_arg (ap, enum cgen_cpu_open_arg);
929 }
930 va_end (ap);
931
932 /* mach unspecified means "all" */
933 if (machs == 0)
934 machs = (1 << MAX_MACHS) - 1;
935 /* base mach is always selected */
936 machs |= 1;
937 /* isa unspecified means "all" */
938 if (isas == 0)
939 isas = (1 << MAX_ISAS) - 1;
940 if (endian == CGEN_ENDIAN_UNKNOWN)
941 {
942 /* ??? If target has only one, could have a default. */
943 fprintf (stderr, "openrisc_cgen_cpu_open: no endianness specified\n");
944 abort ();
945 }
946
947 cd->isas = isas;
948 cd->machs = machs;
949 cd->endian = endian;
950 /* FIXME: for the sparc case we can determine insn-endianness statically.
951 The worry here is where both data and insn endian can be independently
952 chosen, in which case this function will need another argument.
953 Actually, will want to allow for more arguments in the future anyway. */
954 cd->insn_endian = endian;
955
956 /* Table (re)builder. */
957 cd->rebuild_tables = openrisc_cgen_rebuild_tables;
958 openrisc_cgen_rebuild_tables (cd);
959
960 /* Default to not allowing signed overflow. */
961 cd->signed_overflow_ok_p = 0;
962
963 return (CGEN_CPU_DESC) cd;
964 }
965
966 /* Cover fn to openrisc_cgen_cpu_open to handle the simple case of 1 isa, 1 mach.
967 MACH_NAME is the bfd name of the mach. */
968
969 CGEN_CPU_DESC
970 openrisc_cgen_cpu_open_1 (mach_name, endian)
971 const char *mach_name;
972 enum cgen_endian endian;
973 {
974 return openrisc_cgen_cpu_open (CGEN_CPU_OPEN_BFDMACH, mach_name,
975 CGEN_CPU_OPEN_ENDIAN, endian,
976 CGEN_CPU_OPEN_END);
977 }
978
979 /* Close a cpu table.
980 ??? This can live in a machine independent file, but there's currently
981 no place to put this file (there's no libcgen). libopcodes is the wrong
982 place as some simulator ports use this but they don't use libopcodes. */
983
984 void
985 openrisc_cgen_cpu_close (cd)
986 CGEN_CPU_DESC cd;
987 {
988 if (cd->insn_table.init_entries)
989 free ((CGEN_INSN *) cd->insn_table.init_entries);
990 if (cd->hw_table.entries)
991 free ((CGEN_HW_ENTRY *) cd->hw_table.entries);
992 free (cd);
993 }
994