Mon Nov 9 18:22:55 1998 Dave Brolley <brolley@cygnus.com>
[deliverable/binutils-gdb.git] / opcodes / fr30-opc.c
1 /* Generic opcode table support for targets using CGEN. -*- C -*-
2 CGEN: Cpu tools GENerator
3
4 THIS FILE IS USED TO GENERATE fr30-opc.c.
5
6 Copyright (C) 1998 Free Software Foundation, Inc.
7
8 This file is part of the GNU Binutils and GDB, the GNU debugger.
9
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2, or (at your option)
13 any later version.
14
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
19
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software Foundation, Inc.,
22 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
23
24 #include "sysdep.h"
25 #include <stdio.h>
26 #include "ansidecl.h"
27 #include "libiberty.h"
28 #include "bfd.h"
29 #include "symcat.h"
30 #include "fr30-opc.h"
31 #include "opintl.h"
32
33 /* The hash functions are recorded here to help keep assembler code out of
34 the disassembler and vice versa. */
35
36 static int asm_hash_insn_p PARAMS ((const CGEN_INSN *));
37 static unsigned int asm_hash_insn PARAMS ((const char *));
38 static int dis_hash_insn_p PARAMS ((const CGEN_INSN *));
39 static unsigned int dis_hash_insn PARAMS ((const char *, unsigned long));
40
41 /* Cover function to read and properly byteswap an insn value. */
42
43 CGEN_INSN_INT
44 cgen_get_insn_value (od, buf, length)
45 CGEN_OPCODE_DESC od;
46 unsigned char *buf;
47 int length;
48 {
49 CGEN_INSN_INT value;
50
51 switch (length)
52 {
53 case 8:
54 value = *buf;
55 break;
56 case 16:
57 if (CGEN_OPCODE_INSN_ENDIAN (od) == CGEN_ENDIAN_BIG)
58 value = bfd_getb16 (buf);
59 else
60 value = bfd_getl16 (buf);
61 break;
62 case 32:
63 if (CGEN_OPCODE_INSN_ENDIAN (od) == CGEN_ENDIAN_BIG)
64 value = bfd_getb32 (buf);
65 else
66 value = bfd_getl32 (buf);
67 break;
68 default:
69 abort ();
70 }
71
72 return value;
73 }
74
75 /* Cover function to store an insn value properly byteswapped. */
76
77 void
78 cgen_put_insn_value (od, buf, length, value)
79 CGEN_OPCODE_DESC od;
80 unsigned char *buf;
81 int length;
82 CGEN_INSN_INT value;
83 {
84 switch (length)
85 {
86 case 8:
87 buf[0] = value;
88 break;
89 case 16:
90 if (CGEN_OPCODE_INSN_ENDIAN (od) == CGEN_ENDIAN_BIG)
91 bfd_putb16 (value, buf);
92 else
93 bfd_putl16 (value, buf);
94 break;
95 case 32:
96 if (CGEN_OPCODE_INSN_ENDIAN (od) == CGEN_ENDIAN_BIG)
97 bfd_putb32 (value, buf);
98 else
99 bfd_putl32 (value, buf);
100 break;
101 default:
102 abort ();
103 }
104 }
105
106 /* Look up instruction INSN_VALUE and extract its fields.
107 INSN, if non-null, is the insn table entry.
108 Otherwise INSN_VALUE is examined to compute it.
109 LENGTH is the bit length of INSN_VALUE if known, otherwise 0.
110 0 is only valid if `insn == NULL && ! CGEN_INT_INSN_P'.
111 If INSN != NULL, LENGTH must be valid.
112 ALIAS_P is non-zero if alias insns are to be included in the search.
113
114 The result a pointer to the insn table entry, or NULL if the instruction
115 wasn't recognized. */
116
117 const CGEN_INSN *
118 fr30_cgen_lookup_insn (od, insn, insn_value, length, fields, alias_p)
119 CGEN_OPCODE_DESC od;
120 const CGEN_INSN *insn;
121 CGEN_INSN_BYTES insn_value;
122 int length;
123 CGEN_FIELDS *fields;
124 int alias_p;
125 {
126 unsigned char buf[16];
127 unsigned char *bufp;
128 unsigned int base_insn;
129 #if CGEN_INT_INSN_P
130 CGEN_EXTRACT_INFO *info = NULL;
131 #else
132 CGEN_EXTRACT_INFO ex_info;
133 CGEN_EXTRACT_INFO *info = &ex_info;
134 #endif
135
136 #if ! CGEN_INT_INSN_P
137 ex_info.dis_info = NULL;
138 ex_info.bytes = insn_value;
139 ex_info.valid = -1;
140 #endif
141
142 if (!insn)
143 {
144 const CGEN_INSN_LIST *insn_list;
145
146 #if CGEN_INT_INSN_P
147 cgen_put_insn_value (od, buf, length, insn_value);
148 bufp = buf;
149 base_insn = insn_value; /*???*/
150 #else
151 base_insn = cgen_get_insn_value (od, buf, length);
152 bufp = insn_value;
153 #endif
154
155 /* The instructions are stored in hash lists.
156 Pick the first one and keep trying until we find the right one. */
157
158 insn_list = CGEN_DIS_LOOKUP_INSN (od, bufp, base_insn);
159 while (insn_list != NULL)
160 {
161 insn = insn_list->insn;
162
163 if (alias_p
164 || ! CGEN_INSN_ATTR (insn, CGEN_INSN_ALIAS))
165 {
166 /* Basic bit mask must be correct. */
167 /* ??? May wish to allow target to defer this check until the
168 extract handler. */
169 if ((insn_value & CGEN_INSN_MASK (insn)) == CGEN_INSN_VALUE (insn))
170 {
171 /* ??? 0 is passed for `pc' */
172 int elength = (*CGEN_EXTRACT_FN (insn)) (od, insn, info,
173 insn_value, fields,
174 (bfd_vma) 0);
175 if (elength > 0)
176 {
177 /* sanity check */
178 if (length != 0 && length != elength)
179 abort ();
180 return insn;
181 }
182 }
183 }
184
185 insn_list = CGEN_DIS_NEXT_INSN (insn_list);
186 }
187 }
188 else
189 {
190 /* Sanity check: can't pass an alias insn if ! alias_p. */
191 if (! alias_p
192 && CGEN_INSN_ATTR (insn, CGEN_INSN_ALIAS))
193 abort ();
194 /* Sanity check: length must be correct. */
195 if (length != CGEN_INSN_BITSIZE (insn))
196 abort ();
197
198 /* ??? 0 is passed for `pc' */
199 length = (*CGEN_EXTRACT_FN (insn)) (od, insn, info, insn_value, fields,
200 (bfd_vma) 0);
201 /* Sanity check: must succeed.
202 Could relax this later if it ever proves useful. */
203 if (length == 0)
204 abort ();
205 return insn;
206 }
207
208 return NULL;
209 }
210
211 /* Fill in the operand instances used by INSN whose operands are FIELDS.
212 INDICES is a pointer to a buffer of MAX_OPERAND_INSTANCES ints to be filled
213 in. */
214
215 void
216 fr30_cgen_get_insn_operands (od, insn, fields, indices)
217 CGEN_OPCODE_DESC od;
218 const CGEN_INSN * insn;
219 const CGEN_FIELDS * fields;
220 int *indices;
221 {
222 const CGEN_OPERAND_INSTANCE *opinst;
223 int i;
224
225 for (i = 0, opinst = CGEN_INSN_OPERANDS (insn);
226 opinst != NULL
227 && CGEN_OPERAND_INSTANCE_TYPE (opinst) != CGEN_OPERAND_INSTANCE_END;
228 ++i, ++opinst)
229 {
230 const CGEN_OPERAND *op = CGEN_OPERAND_INSTANCE_OPERAND (opinst);
231 if (op == NULL)
232 indices[i] = CGEN_OPERAND_INSTANCE_INDEX (opinst);
233 else
234 indices[i] = fr30_cgen_get_int_operand (CGEN_OPERAND_INDEX (op),
235 fields);
236 }
237 }
238
239 /* Cover function to fr30_cgen_get_insn_operands when either INSN or FIELDS
240 isn't known.
241 The INSN, INSN_VALUE, and LENGTH arguments are passed to
242 fr30_cgen_lookup_insn unchanged.
243
244 The result is the insn table entry or NULL if the instruction wasn't
245 recognized. */
246
247 const CGEN_INSN *
248 fr30_cgen_lookup_get_insn_operands (od, insn, insn_value, length, indices)
249 CGEN_OPCODE_DESC od;
250 const CGEN_INSN *insn;
251 CGEN_INSN_BYTES insn_value;
252 int length;
253 int *indices;
254 {
255 CGEN_FIELDS fields;
256
257 /* Pass non-zero for ALIAS_P only if INSN != NULL.
258 If INSN == NULL, we want a real insn. */
259 insn = fr30_cgen_lookup_insn (od, insn, insn_value, length, &fields,
260 insn != NULL);
261 if (! insn)
262 return NULL;
263
264 fr30_cgen_get_insn_operands (od, insn, &fields, indices);
265 return insn;
266 }
267 /* Attributes. */
268
269 static const CGEN_ATTR_ENTRY MACH_attr[] =
270 {
271 { "base", MACH_BASE },
272 { "fr30", MACH_FR30 },
273 { "max", MACH_MAX },
274 { 0, 0 }
275 };
276
277 const CGEN_ATTR_TABLE fr30_cgen_hardware_attr_table[] =
278 {
279 { "CACHE-ADDR", NULL },
280 { "FUN-ACCESS", NULL },
281 { "PC", NULL },
282 { "PROFILE", NULL },
283 { 0, 0 }
284 };
285
286 const CGEN_ATTR_TABLE fr30_cgen_operand_attr_table[] =
287 {
288 { "ABS-ADDR", NULL },
289 { "FAKE", NULL },
290 { "NEGATIVE", NULL },
291 { "PCREL-ADDR", NULL },
292 { "RELAX", NULL },
293 { "SIGN-OPT", NULL },
294 { "UNSIGNED", NULL },
295 { 0, 0 }
296 };
297
298 const CGEN_ATTR_TABLE fr30_cgen_insn_attr_table[] =
299 {
300 { "ALIAS", NULL },
301 { "COND-CTI", NULL },
302 { "NO-DIS", NULL },
303 { "RELAX", NULL },
304 { "RELAXABLE", NULL },
305 { "SKIP-CTI", NULL },
306 { "UNCOND-CTI", NULL },
307 { "VIRTUAL", NULL },
308 { 0, 0 }
309 };
310
311 CGEN_KEYWORD_ENTRY fr30_cgen_opval_h_gr_entries[] =
312 {
313 { "ac", 13 },
314 { "fp", 14 },
315 { "sp", 15 },
316 { "r0", 0 },
317 { "r1", 1 },
318 { "r2", 2 },
319 { "r3", 3 },
320 { "r4", 4 },
321 { "r5", 5 },
322 { "r6", 6 },
323 { "r7", 7 },
324 { "r8", 8 },
325 { "r9", 9 },
326 { "r10", 10 },
327 { "r11", 11 },
328 { "r12", 12 },
329 { "r13", 13 },
330 { "r14", 14 },
331 { "r15", 15 }
332 };
333
334 CGEN_KEYWORD fr30_cgen_opval_h_gr =
335 {
336 & fr30_cgen_opval_h_gr_entries[0],
337 19
338 };
339
340 CGEN_KEYWORD_ENTRY fr30_cgen_opval_h_dr_entries[] =
341 {
342 { "tbr", 0 },
343 { "rp", 1 },
344 { "ssp", 2 },
345 { "usp", 3 }
346 };
347
348 CGEN_KEYWORD fr30_cgen_opval_h_dr =
349 {
350 & fr30_cgen_opval_h_dr_entries[0],
351 4
352 };
353
354 CGEN_KEYWORD_ENTRY fr30_cgen_opval_h_mdr_entries[] =
355 {
356 { "mdh", 4 },
357 { "mdl", 5 }
358 };
359
360 CGEN_KEYWORD fr30_cgen_opval_h_mdr =
361 {
362 & fr30_cgen_opval_h_mdr_entries[0],
363 2
364 };
365
366 CGEN_KEYWORD_ENTRY fr30_cgen_opval_h_cr_entries[] =
367 {
368 { "pc", 0 },
369 { "ps", 1 }
370 };
371
372 CGEN_KEYWORD fr30_cgen_opval_h_cr =
373 {
374 & fr30_cgen_opval_h_cr_entries[0],
375 2
376 };
377
378
379 /* The hardware table. */
380
381 #define HW_ENT(n) fr30_cgen_hw_entries[n]
382 static const CGEN_HW_ENTRY fr30_cgen_hw_entries[] =
383 {
384 { HW_H_PC, & HW_ENT (HW_H_PC + 1), "h-pc", CGEN_ASM_KEYWORD, (PTR) 0, { 0, 0|(1<<CGEN_HW_PROFILE)|(1<<CGEN_HW_PC), { 0 } } },
385 { HW_H_MEMORY, & HW_ENT (HW_H_MEMORY + 1), "h-memory", CGEN_ASM_KEYWORD, (PTR) 0, { 0, 0, { 0 } } },
386 { HW_H_SINT, & HW_ENT (HW_H_SINT + 1), "h-sint", CGEN_ASM_KEYWORD, (PTR) 0, { 0, 0, { 0 } } },
387 { HW_H_UINT, & HW_ENT (HW_H_UINT + 1), "h-uint", CGEN_ASM_KEYWORD, (PTR) 0, { 0, 0, { 0 } } },
388 { HW_H_ADDR, & HW_ENT (HW_H_ADDR + 1), "h-addr", CGEN_ASM_KEYWORD, (PTR) 0, { 0, 0, { 0 } } },
389 { HW_H_IADDR, & HW_ENT (HW_H_IADDR + 1), "h-iaddr", CGEN_ASM_KEYWORD, (PTR) 0, { 0, 0, { 0 } } },
390 { HW_H_GR, & HW_ENT (HW_H_GR + 1), "h-gr", CGEN_ASM_KEYWORD, (PTR) & fr30_cgen_opval_h_gr, { 0, 0|(1<<CGEN_HW_CACHE_ADDR)|(1<<CGEN_HW_PROFILE), { 0 } } },
391 { HW_H_DR, & HW_ENT (HW_H_DR + 1), "h-dr", CGEN_ASM_KEYWORD, (PTR) & fr30_cgen_opval_h_dr, { 0, 0, { 0 } } },
392 { HW_H_MDR, & HW_ENT (HW_H_MDR + 1), "h-mdr", CGEN_ASM_KEYWORD, (PTR) & fr30_cgen_opval_h_mdr, { 0, 0, { 0 } } },
393 { HW_H_CR, & HW_ENT (HW_H_CR + 1), "h-cr", CGEN_ASM_KEYWORD, (PTR) & fr30_cgen_opval_h_cr, { 0, 0, { 0 } } },
394 { HW_H_NBIT, & HW_ENT (HW_H_NBIT + 1), "h-nbit", CGEN_ASM_KEYWORD, (PTR) 0, { 0, 0|(1<<CGEN_HW_FUN_ACCESS), { 0 } } },
395 { HW_H_ZBIT, & HW_ENT (HW_H_ZBIT + 1), "h-zbit", CGEN_ASM_KEYWORD, (PTR) 0, { 0, 0|(1<<CGEN_HW_FUN_ACCESS), { 0 } } },
396 { HW_H_VBIT, & HW_ENT (HW_H_VBIT + 1), "h-vbit", CGEN_ASM_KEYWORD, (PTR) 0, { 0, 0|(1<<CGEN_HW_FUN_ACCESS), { 0 } } },
397 { HW_H_CBIT, & HW_ENT (HW_H_CBIT + 1), "h-cbit", CGEN_ASM_KEYWORD, (PTR) 0, { 0, 0|(1<<CGEN_HW_FUN_ACCESS), { 0 } } },
398 { 0 }
399 };
400
401 /* The operand table. */
402
403 #define OPERAND(op) CONCAT2 (FR30_OPERAND_,op)
404 #define OP_ENT(op) fr30_cgen_operand_table[OPERAND (op)]
405
406 const CGEN_OPERAND fr30_cgen_operand_table[MAX_OPERANDS] =
407 {
408 /* pc: program counter */
409 { "pc", & HW_ENT (HW_H_PC), 0, 0,
410 { 0, 0|(1<<CGEN_OPERAND_FAKE), { 0 } } },
411 /* Ri: destination register */
412 { "Ri", & HW_ENT (HW_H_GR), 12, 4,
413 { 0, 0|(1<<CGEN_OPERAND_UNSIGNED), { 0 } } },
414 /* Rj: source register */
415 { "Rj", & HW_ENT (HW_H_GR), 8, 4,
416 { 0, 0|(1<<CGEN_OPERAND_UNSIGNED), { 0 } } },
417 /* nbit: negative bit */
418 { "nbit", & HW_ENT (HW_H_NBIT), 0, 0,
419 { 0, 0|(1<<CGEN_OPERAND_FAKE), { 0 } } },
420 /* vbit: overflow bit */
421 { "vbit", & HW_ENT (HW_H_VBIT), 0, 0,
422 { 0, 0|(1<<CGEN_OPERAND_FAKE), { 0 } } },
423 /* zbit: zero bit */
424 { "zbit", & HW_ENT (HW_H_ZBIT), 0, 0,
425 { 0, 0|(1<<CGEN_OPERAND_FAKE), { 0 } } },
426 /* cbit: carry bit */
427 { "cbit", & HW_ENT (HW_H_CBIT), 0, 0,
428 { 0, 0|(1<<CGEN_OPERAND_FAKE), { 0 } } },
429 };
430
431 /* Operand references. */
432
433 #define INPUT CGEN_OPERAND_INSTANCE_INPUT
434 #define OUTPUT CGEN_OPERAND_INSTANCE_OUTPUT
435
436 static const CGEN_OPERAND_INSTANCE fmt_add_ops[] = {
437 { INPUT, "Rj", & HW_ENT (HW_H_GR), CGEN_MODE_SI, & OP_ENT (RJ), 0 },
438 { INPUT, "Ri", & HW_ENT (HW_H_GR), CGEN_MODE_SI, & OP_ENT (RI), 0 },
439 { OUTPUT, "Ri", & HW_ENT (HW_H_GR), CGEN_MODE_SI, & OP_ENT (RI), 0 },
440 { OUTPUT, "vbit", & HW_ENT (HW_H_VBIT), CGEN_MODE_BI, 0, 0 },
441 { OUTPUT, "cbit", & HW_ENT (HW_H_CBIT), CGEN_MODE_BI, 0, 0 },
442 { OUTPUT, "zbit", & HW_ENT (HW_H_ZBIT), CGEN_MODE_BI, 0, 0 },
443 { OUTPUT, "nbit", & HW_ENT (HW_H_NBIT), CGEN_MODE_BI, 0, 0 },
444 { 0 }
445 };
446
447 #undef INPUT
448 #undef OUTPUT
449
450 #define A(a) (1 << CONCAT2 (CGEN_INSN_,a))
451 #define MNEM CGEN_SYNTAX_MNEMONIC /* syntax value for mnemonic */
452 #define OP(field) CGEN_SYNTAX_MAKE_FIELD (OPERAND (field))
453
454 /* The instruction table.
455 This is currently non-static because the simulator accesses it
456 directly. */
457
458 const CGEN_INSN fr30_cgen_insn_table_entries[MAX_INSNS] =
459 {
460 /* Special null first entry.
461 A `num' value of zero is thus invalid.
462 Also, the special `invalid' insn resides here. */
463 { { 0 }, 0 },
464 /* add $Rj,$Ri */
465 {
466 { 1, 1, 1, 1 },
467 FR30_INSN_ADD, "add", "add",
468 { { MNEM, ' ', OP (RJ), ',', OP (RI), 0 } },
469 { 16, 16, 0xff00 }, 0xa600,
470 (PTR) & fmt_add_ops[0],
471 { 0, 0, { 0 } }
472 },
473 };
474
475 #undef A
476 #undef MNEM
477 #undef OP
478
479 static const CGEN_INSN_TABLE insn_table =
480 {
481 & fr30_cgen_insn_table_entries[0],
482 sizeof (CGEN_INSN),
483 MAX_INSNS,
484 NULL
485 };
486
487 /* Each non-simple macro entry points to an array of expansion possibilities. */
488
489 #define A(a) (1 << CONCAT2 (CGEN_INSN_,a))
490 #define MNEM CGEN_SYNTAX_MNEMONIC /* syntax value for mnemonic */
491 #define OP(field) CGEN_SYNTAX_MAKE_FIELD (OPERAND (field))
492
493 /* The macro instruction table. */
494
495 static const CGEN_INSN macro_insn_table_entries[] =
496 {
497 };
498
499 #undef A
500 #undef MNEM
501 #undef OP
502
503 static const CGEN_INSN_TABLE macro_insn_table =
504 {
505 & macro_insn_table_entries[0],
506 sizeof (CGEN_INSN),
507 (sizeof (macro_insn_table_entries) /
508 sizeof (macro_insn_table_entries[0])),
509 NULL
510 };
511
512 static void
513 init_tables ()
514 {
515 }
516
517 /* Return non-zero if INSN is to be added to the hash table.
518 Targets are free to override CGEN_{ASM,DIS}_HASH_P in the .opc file. */
519
520 static int
521 asm_hash_insn_p (insn)
522 const CGEN_INSN * insn;
523 {
524 return CGEN_ASM_HASH_P (insn);
525 }
526
527 static int
528 dis_hash_insn_p (insn)
529 const CGEN_INSN * insn;
530 {
531 /* If building the hash table and the NO-DIS attribute is present,
532 ignore. */
533 if (CGEN_INSN_ATTR (insn, CGEN_INSN_NO_DIS))
534 return 0;
535 return CGEN_DIS_HASH_P (insn);
536 }
537
538 /* The result is the hash value of the insn.
539 Targets are free to override CGEN_{ASM,DIS}_HASH in the .opc file. */
540
541 static unsigned int
542 asm_hash_insn (mnem)
543 const char * mnem;
544 {
545 return CGEN_ASM_HASH (mnem);
546 }
547
548 /* BUF is a pointer to the insn's bytes in target order.
549 VALUE is an integer of the first CGEN_BASE_INSN_BITSIZE bits,
550 host order. */
551
552 static unsigned int
553 dis_hash_insn (buf, value)
554 const char * buf;
555 unsigned long value;
556 {
557 return CGEN_DIS_HASH (buf, value);
558 }
559
560 /* Initialize an opcode table and return a descriptor.
561 It's much like opening a file, and must be the first function called. */
562
563 CGEN_OPCODE_DESC
564 fr30_cgen_opcode_open (mach, endian)
565 int mach;
566 enum cgen_endian endian;
567 {
568 CGEN_OPCODE_TABLE * table = (CGEN_OPCODE_TABLE *) xmalloc (sizeof (CGEN_OPCODE_TABLE));
569 static int init_p;
570
571 if (! init_p)
572 {
573 init_tables ();
574 init_p = 1;
575 }
576
577 memset (table, 0, sizeof (*table));
578
579 CGEN_OPCODE_MACH (table) = mach;
580 CGEN_OPCODE_ENDIAN (table) = endian;
581 /* FIXME: for the sparc case we can determine insn-endianness statically.
582 The worry here is where both data and insn endian can be independently
583 chosen, in which case this function will need another argument.
584 Actually, will want to allow for more arguments in the future anyway. */
585 CGEN_OPCODE_INSN_ENDIAN (table) = endian;
586
587 CGEN_OPCODE_HW_LIST (table) = & fr30_cgen_hw_entries[0];
588
589 CGEN_OPCODE_OPERAND_TABLE (table) = & fr30_cgen_operand_table[0];
590
591 * CGEN_OPCODE_INSN_TABLE (table) = insn_table;
592
593 * CGEN_OPCODE_MACRO_INSN_TABLE (table) = macro_insn_table;
594
595 CGEN_OPCODE_ASM_HASH_P (table) = asm_hash_insn_p;
596 CGEN_OPCODE_ASM_HASH (table) = asm_hash_insn;
597 CGEN_OPCODE_ASM_HASH_SIZE (table) = CGEN_ASM_HASH_SIZE;
598
599 CGEN_OPCODE_DIS_HASH_P (table) = dis_hash_insn_p;
600 CGEN_OPCODE_DIS_HASH (table) = dis_hash_insn;
601 CGEN_OPCODE_DIS_HASH_SIZE (table) = CGEN_DIS_HASH_SIZE;
602
603 return (CGEN_OPCODE_DESC) table;
604 }
605
606 /* Close an opcode table. */
607
608 void
609 fr30_cgen_opcode_close (desc)
610 CGEN_OPCODE_DESC desc;
611 {
612 free (desc);
613 }
614
615 /* Getting values from cgen_fields is handled by a collection of functions.
616 They are distinguished by the type of the VALUE argument they return.
617 TODO: floating point, inlining support, remove cases where result type
618 not appropriate. */
619
620 int
621 fr30_cgen_get_int_operand (opindex, fields)
622 int opindex;
623 const CGEN_FIELDS * fields;
624 {
625 int value;
626
627 switch (opindex)
628 {
629 case FR30_OPERAND_RI :
630 value = fields->f_Ri;
631 break;
632 case FR30_OPERAND_RJ :
633 value = fields->f_Rj;
634 break;
635
636 default :
637 /* xgettext:c-format */
638 fprintf (stderr, _("Unrecognized field %d while getting int operand.\n"),
639 opindex);
640 abort ();
641 }
642
643 return value;
644 }
645
646 bfd_vma
647 fr30_cgen_get_vma_operand (opindex, fields)
648 int opindex;
649 const CGEN_FIELDS * fields;
650 {
651 bfd_vma value;
652
653 switch (opindex)
654 {
655 case FR30_OPERAND_RI :
656 value = fields->f_Ri;
657 break;
658 case FR30_OPERAND_RJ :
659 value = fields->f_Rj;
660 break;
661
662 default :
663 /* xgettext:c-format */
664 fprintf (stderr, _("Unrecognized field %d while getting vma operand.\n"),
665 opindex);
666 abort ();
667 }
668
669 return value;
670 }
671
672 /* Stuffing values in cgen_fields is handled by a collection of functions.
673 They are distinguished by the type of the VALUE argument they accept.
674 TODO: floating point, inlining support, remove cases where argument type
675 not appropriate. */
676
677 void
678 fr30_cgen_set_int_operand (opindex, fields, value)
679 int opindex;
680 CGEN_FIELDS * fields;
681 int value;
682 {
683 switch (opindex)
684 {
685 case FR30_OPERAND_RI :
686 fields->f_Ri = value;
687 break;
688 case FR30_OPERAND_RJ :
689 fields->f_Rj = value;
690 break;
691
692 default :
693 /* xgettext:c-format */
694 fprintf (stderr, _("Unrecognized field %d while setting int operand.\n"),
695 opindex);
696 abort ();
697 }
698 }
699
700 void
701 fr30_cgen_set_vma_operand (opindex, fields, value)
702 int opindex;
703 CGEN_FIELDS * fields;
704 bfd_vma value;
705 {
706 switch (opindex)
707 {
708 case FR30_OPERAND_RI :
709 fields->f_Ri = value;
710 break;
711 case FR30_OPERAND_RJ :
712 fields->f_Rj = value;
713 break;
714
715 default :
716 /* xgettext:c-format */
717 fprintf (stderr, _("Unrecognized field %d while setting vma operand.\n"),
718 opindex);
719 abort ();
720 }
721 }
722
This page took 0.044702 seconds and 5 git commands to generate.