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