* deffilep.y: properly handle relocs with multiple def_files,
[deliverable/binutils-gdb.git] / opcodes / fr30-opc.c
CommitLineData
a86481d3
DB
1/* Generic opcode table support for targets using CGEN. -*- C -*-
2 CGEN: Cpu tools GENerator
3
4THIS FILE IS USED TO GENERATE fr30-opc.c.
5
6Copyright (C) 1998 Free Software Foundation, Inc.
7
8This file is part of the GNU Binutils and GDB, the GNU debugger.
9
10This program is free software; you can redistribute it and/or modify
11it under the terms of the GNU General Public License as published by
12the Free Software Foundation; either version 2, or (at your option)
13any later version.
14
15This program is distributed in the hope that it will be useful,
16but WITHOUT ANY WARRANTY; without even the implied warranty of
17MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18GNU General Public License for more details.
19
20You should have received a copy of the GNU General Public License
21along with this program; if not, write to the Free Software Foundation, Inc.,
2259 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
36static int asm_hash_insn_p PARAMS ((const CGEN_INSN *));
37static unsigned int asm_hash_insn PARAMS ((const char *));
38static int dis_hash_insn_p PARAMS ((const CGEN_INSN *));
39static unsigned int dis_hash_insn PARAMS ((const char *, unsigned long));
40
41/* Cover function to read and properly byteswap an insn value. */
42
43CGEN_INSN_INT
44cgen_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
77void
78cgen_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
117const CGEN_INSN *
118fr30_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
215void
216fr30_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
247const CGEN_INSN *
248fr30_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
269static const CGEN_ATTR_ENTRY MACH_attr[] =
270{
271 { "base", MACH_BASE },
272 { "fr30", MACH_FR30 },
273 { "max", MACH_MAX },
274 { 0, 0 }
275};
276
277const CGEN_ATTR_TABLE fr30_cgen_hardware_attr_table[] =
278{
279 { "CACHE-ADDR", NULL },
6146431a 280 { "FUN-ACCESS", NULL },
a86481d3
DB
281 { "PC", NULL },
282 { "PROFILE", NULL },
283 { 0, 0 }
284};
285
286const 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
298const 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
311CGEN_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
334CGEN_KEYWORD fr30_cgen_opval_h_gr =
335{
336 & fr30_cgen_opval_h_gr_entries[0],
337 19
338};
339
6146431a
DB
340CGEN_KEYWORD_ENTRY fr30_cgen_opval_h_dr_entries[] =
341{
342 { "tbr", 0 },
343 { "rp", 1 },
344 { "ssp", 2 },
345 { "usp", 3 }
346};
347
348CGEN_KEYWORD fr30_cgen_opval_h_dr =
349{
350 & fr30_cgen_opval_h_dr_entries[0],
351 4
352};
353
354CGEN_KEYWORD_ENTRY fr30_cgen_opval_h_mdr_entries[] =
355{
356 { "mdh", 4 },
357 { "mdl", 5 }
358};
359
360CGEN_KEYWORD fr30_cgen_opval_h_mdr =
361{
362 & fr30_cgen_opval_h_mdr_entries[0],
363 2
364};
365
366CGEN_KEYWORD_ENTRY fr30_cgen_opval_h_cr_entries[] =
367{
368 { "pc", 0 },
369 { "ps", 1 }
370};
371
372CGEN_KEYWORD fr30_cgen_opval_h_cr =
373{
374 & fr30_cgen_opval_h_cr_entries[0],
375 2
376};
377
a86481d3
DB
378
379/* The hardware table. */
380
381#define HW_ENT(n) fr30_cgen_hw_entries[n]
382static 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 } } },
6146431a
DB
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 } } },
a86481d3
DB
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
406const 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 } } },
6146431a
DB
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 } } },
a86481d3
DB
429};
430
431/* Operand references. */
432
433#define INPUT CGEN_OPERAND_INSTANCE_INPUT
434#define OUTPUT CGEN_OPERAND_INSTANCE_OUTPUT
435
6146431a 436static const CGEN_OPERAND_INSTANCE fmt_add_ops[] = {
a86481d3
DB
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 },
6146431a
DB
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 },
a86481d3
DB
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
458const 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 },
6146431a 464/* add $Rj,$Ri */
a86481d3
DB
465 {
466 { 1, 1, 1, 1 },
6146431a 467 FR30_INSN_ADD, "add", "add",
a86481d3
DB
468 { { MNEM, ' ', OP (RJ), ',', OP (RI), 0 } },
469 { 16, 16, 0xff00 }, 0xa600,
6146431a 470 (PTR) & fmt_add_ops[0],
a86481d3
DB
471 { 0, 0, { 0 } }
472 },
473};
474
475#undef A
476#undef MNEM
477#undef OP
478
479static 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
495static const CGEN_INSN macro_insn_table_entries[] =
496{
497};
498
499#undef A
500#undef MNEM
501#undef OP
502
503static 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
512static void
513init_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
520static int
521asm_hash_insn_p (insn)
522 const CGEN_INSN * insn;
523{
524 return CGEN_ASM_HASH_P (insn);
525}
526
527static int
528dis_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
541static unsigned int
542asm_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
552static unsigned int
553dis_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
563CGEN_OPCODE_DESC
564fr30_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
608void
609fr30_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
620int
621fr30_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
646bfd_vma
647fr30_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
677void
678fr30_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
700void
701fr30_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.051092 seconds and 4 git commands to generate.