2000-05-02 H.J. Lu <hjl@gnu.org>
[binutils.git] / opcodes / fr30-ibld.c
blob2aa44589cf2966c3c48def562ff44d1b53937e63
1 /* Instruction building/extraction support for fr30. -*- C -*-
3 THIS FILE IS MACHINE GENERATED WITH CGEN: Cpu tools GENerator.
4 - the resultant file is machine generated, cgen-ibld.in isn't
6 Copyright (C) 1996, 1997, 1998, 1999 Free Software Foundation, Inc.
8 This file is part of the GNU Binutils and GDB, the GNU debugger.
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.
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.
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. */
24 /* ??? Eventually more and more of this stuff can go to cpu-independent files.
25 Keep that in mind. */
27 #include "sysdep.h"
28 #include <ctype.h>
29 #include <stdio.h>
30 #include "ansidecl.h"
31 #include "dis-asm.h"
32 #include "bfd.h"
33 #include "symcat.h"
34 #include "fr30-desc.h"
35 #include "fr30-opc.h"
36 #include "opintl.h"
38 #undef min
39 #define min(a,b) ((a) < (b) ? (a) : (b))
40 #undef max
41 #define max(a,b) ((a) > (b) ? (a) : (b))
43 /* Used by the ifield rtx function. */
44 #define FLD(f) (fields->f)
46 static const char * insert_normal
47 PARAMS ((CGEN_CPU_DESC, long, unsigned int, unsigned int, unsigned int,
48 unsigned int, unsigned int, unsigned int, CGEN_INSN_BYTES_PTR));
49 static const char * insert_insn_normal
50 PARAMS ((CGEN_CPU_DESC, const CGEN_INSN *,
51 CGEN_FIELDS *, CGEN_INSN_BYTES_PTR, bfd_vma));
53 static int extract_normal
54 PARAMS ((CGEN_CPU_DESC, CGEN_EXTRACT_INFO *, CGEN_INSN_INT,
55 unsigned int, unsigned int, unsigned int, unsigned int,
56 unsigned int, unsigned int, bfd_vma, long *));
57 static int extract_insn_normal
58 PARAMS ((CGEN_CPU_DESC, const CGEN_INSN *, CGEN_EXTRACT_INFO *,
59 CGEN_INSN_INT, CGEN_FIELDS *, bfd_vma));
61 /* Operand insertion. */
63 #if ! CGEN_INT_INSN_P
65 /* Subroutine of insert_normal. */
67 static CGEN_INLINE void
68 insert_1 (cd, value, start, length, word_length, bufp)
69 CGEN_CPU_DESC cd;
70 unsigned long value;
71 int start,length,word_length;
72 unsigned char *bufp;
74 unsigned long x,mask;
75 int shift;
76 int big_p = CGEN_CPU_INSN_ENDIAN (cd) == CGEN_ENDIAN_BIG;
78 switch (word_length)
80 case 8:
81 x = *bufp;
82 break;
83 case 16:
84 if (big_p)
85 x = bfd_getb16 (bufp);
86 else
87 x = bfd_getl16 (bufp);
88 break;
89 case 24:
90 /* ??? This may need reworking as these cases don't necessarily
91 want the first byte and the last two bytes handled like this. */
92 if (big_p)
93 x = (bufp[0] << 16) | bfd_getb16 (bufp + 1);
94 else
95 x = bfd_getl16 (bufp) | (bufp[2] << 16);
96 break;
97 case 32:
98 if (big_p)
99 x = bfd_getb32 (bufp);
100 else
101 x = bfd_getl32 (bufp);
102 break;
103 default :
104 abort ();
107 /* Written this way to avoid undefined behaviour. */
108 mask = (((1L << (length - 1)) - 1) << 1) | 1;
109 if (CGEN_INSN_LSB0_P)
110 shift = (start + 1) - length;
111 else
112 shift = (word_length - (start + length));
113 x = (x & ~(mask << shift)) | ((value & mask) << shift);
115 switch (word_length)
117 case 8:
118 *bufp = x;
119 break;
120 case 16:
121 if (big_p)
122 bfd_putb16 (x, bufp);
123 else
124 bfd_putl16 (x, bufp);
125 break;
126 case 24:
127 /* ??? This may need reworking as these cases don't necessarily
128 want the first byte and the last two bytes handled like this. */
129 if (big_p)
131 bufp[0] = x >> 16;
132 bfd_putb16 (x, bufp + 1);
134 else
136 bfd_putl16 (x, bufp);
137 bufp[2] = x >> 16;
139 break;
140 case 32:
141 if (big_p)
142 bfd_putb32 (x, bufp);
143 else
144 bfd_putl32 (x, bufp);
145 break;
146 default :
147 abort ();
151 #endif /* ! CGEN_INT_INSN_P */
153 /* Default insertion routine.
155 ATTRS is a mask of the boolean attributes.
156 WORD_OFFSET is the offset in bits from the start of the insn of the value.
157 WORD_LENGTH is the length of the word in bits in which the value resides.
158 START is the starting bit number in the word, architecture origin.
159 LENGTH is the length of VALUE in bits.
160 TOTAL_LENGTH is the total length of the insn in bits.
162 The result is an error message or NULL if success. */
164 /* ??? This duplicates functionality with bfd's howto table and
165 bfd_install_relocation. */
166 /* ??? This doesn't handle bfd_vma's. Create another function when
167 necessary. */
169 static const char *
170 insert_normal (cd, value, attrs, word_offset, start, length, word_length,
171 total_length, buffer)
172 CGEN_CPU_DESC cd;
173 long value;
174 unsigned int attrs;
175 unsigned int word_offset, start, length, word_length, total_length;
176 CGEN_INSN_BYTES_PTR buffer;
178 static char errbuf[100];
179 /* Written this way to avoid undefined behaviour. */
180 unsigned long mask = (((1L << (length - 1)) - 1) << 1) | 1;
182 /* If LENGTH is zero, this operand doesn't contribute to the value. */
183 if (length == 0)
184 return NULL;
186 if (CGEN_INT_INSN_P
187 && word_offset != 0)
188 abort ();
190 if (word_length > 32)
191 abort ();
193 /* For architectures with insns smaller than the base-insn-bitsize,
194 word_length may be too big. */
195 if (cd->min_insn_bitsize < cd->base_insn_bitsize)
197 if (word_offset == 0
198 && word_length > total_length)
199 word_length = total_length;
202 /* Ensure VALUE will fit. */
203 if (! CGEN_BOOL_ATTR (attrs, CGEN_IFLD_SIGNED))
205 unsigned long maxval = mask;
206 if ((unsigned long) value > maxval)
208 /* xgettext:c-format */
209 sprintf (errbuf,
210 _("operand out of range (%lu not between 0 and %lu)"),
211 value, maxval);
212 return errbuf;
215 else
217 long minval = - (1L << (length - 1));
218 long maxval = (1L << (length - 1)) - 1;
219 if (value < minval || value > maxval)
221 sprintf
222 /* xgettext:c-format */
223 (errbuf, _("operand out of range (%ld not between %ld and %ld)"),
224 value, minval, maxval);
225 return errbuf;
229 #if CGEN_INT_INSN_P
232 int shift;
234 if (CGEN_INSN_LSB0_P)
235 shift = (start + 1) - length;
236 else
237 shift = word_length - (start + length);
238 *buffer = (*buffer & ~(mask << shift)) | ((value & mask) << shift);
241 #else /* ! CGEN_INT_INSN_P */
244 unsigned char *bufp = (unsigned char *) buffer + word_offset / 8;
246 insert_1 (cd, value, start, length, word_length, bufp);
249 #endif /* ! CGEN_INT_INSN_P */
251 return NULL;
254 /* Default insn builder (insert handler).
255 The instruction is recorded in CGEN_INT_INSN_P byte order
256 (meaning that if CGEN_INT_INSN_P BUFFER is an int * and thus the value is
257 recorded in host byte order, otherwise BUFFER is an array of bytes and the
258 value is recorded in target byte order).
259 The result is an error message or NULL if success. */
261 static const char *
262 insert_insn_normal (cd, insn, fields, buffer, pc)
263 CGEN_CPU_DESC cd;
264 const CGEN_INSN * insn;
265 CGEN_FIELDS * fields;
266 CGEN_INSN_BYTES_PTR buffer;
267 bfd_vma pc;
269 const CGEN_SYNTAX *syntax = CGEN_INSN_SYNTAX (insn);
270 unsigned long value;
271 const unsigned char * syn;
273 CGEN_INIT_INSERT (cd);
274 value = CGEN_INSN_BASE_VALUE (insn);
276 /* If we're recording insns as numbers (rather than a string of bytes),
277 target byte order handling is deferred until later. */
279 #if CGEN_INT_INSN_P
281 *buffer = value;
283 #else
285 cgen_put_insn_value (cd, buffer, min (cd->base_insn_bitsize,
286 CGEN_FIELDS_BITSIZE (fields)),
287 value);
289 #endif /* ! CGEN_INT_INSN_P */
291 /* ??? It would be better to scan the format's fields.
292 Still need to be able to insert a value based on the operand though;
293 e.g. storing a branch displacement that got resolved later.
294 Needs more thought first. */
296 for (syn = CGEN_SYNTAX_STRING (syntax); * syn != '\0'; ++ syn)
298 const char *errmsg;
300 if (CGEN_SYNTAX_CHAR_P (* syn))
301 continue;
303 errmsg = (* cd->insert_operand) (cd, CGEN_SYNTAX_FIELD (*syn),
304 fields, buffer, pc);
305 if (errmsg)
306 return errmsg;
309 return NULL;
312 /* Operand extraction. */
314 #if ! CGEN_INT_INSN_P
316 /* Subroutine of extract_normal.
317 Ensure sufficient bytes are cached in EX_INFO.
318 OFFSET is the offset in bytes from the start of the insn of the value.
319 BYTES is the length of the needed value.
320 Returns 1 for success, 0 for failure. */
322 static CGEN_INLINE int
323 fill_cache (cd, ex_info, offset, bytes, pc)
324 CGEN_CPU_DESC cd;
325 CGEN_EXTRACT_INFO *ex_info;
326 int offset, bytes;
327 bfd_vma pc;
329 /* It's doubtful that the middle part has already been fetched so
330 we don't optimize that case. kiss. */
331 int mask;
332 disassemble_info *info = (disassemble_info *) ex_info->dis_info;
334 /* First do a quick check. */
335 mask = (1 << bytes) - 1;
336 if (((ex_info->valid >> offset) & mask) == mask)
337 return 1;
339 /* Search for the first byte we need to read. */
340 for (mask = 1 << offset; bytes > 0; --bytes, ++offset, mask <<= 1)
341 if (! (mask & ex_info->valid))
342 break;
344 if (bytes)
346 int status;
348 pc += offset;
349 status = (*info->read_memory_func)
350 (pc, ex_info->insn_bytes + offset, bytes, info);
352 if (status != 0)
354 (*info->memory_error_func) (status, pc, info);
355 return 0;
358 ex_info->valid |= ((1 << bytes) - 1) << offset;
361 return 1;
364 /* Subroutine of extract_normal. */
366 static CGEN_INLINE long
367 extract_1 (cd, ex_info, start, length, word_length, bufp, pc)
368 CGEN_CPU_DESC cd;
369 CGEN_EXTRACT_INFO *ex_info;
370 int start,length,word_length;
371 unsigned char *bufp;
372 bfd_vma pc;
374 unsigned long x,mask;
375 int shift;
376 int big_p = CGEN_CPU_INSN_ENDIAN (cd) == CGEN_ENDIAN_BIG;
378 switch (word_length)
380 case 8:
381 x = *bufp;
382 break;
383 case 16:
384 if (big_p)
385 x = bfd_getb16 (bufp);
386 else
387 x = bfd_getl16 (bufp);
388 break;
389 case 24:
390 /* ??? This may need reworking as these cases don't necessarily
391 want the first byte and the last two bytes handled like this. */
392 if (big_p)
393 x = (bufp[0] << 16) | bfd_getb16 (bufp + 1);
394 else
395 x = bfd_getl16 (bufp) | (bufp[2] << 16);
396 break;
397 case 32:
398 if (big_p)
399 x = bfd_getb32 (bufp);
400 else
401 x = bfd_getl32 (bufp);
402 break;
403 default :
404 abort ();
407 /* Written this way to avoid undefined behaviour. */
408 mask = (((1L << (length - 1)) - 1) << 1) | 1;
409 if (CGEN_INSN_LSB0_P)
410 shift = (start + 1) - length;
411 else
412 shift = (word_length - (start + length));
413 return (x >> shift) & mask;
416 #endif /* ! CGEN_INT_INSN_P */
418 /* Default extraction routine.
420 INSN_VALUE is the first base_insn_bitsize bits of the insn in host order,
421 or sometimes less for cases like the m32r where the base insn size is 32
422 but some insns are 16 bits.
423 ATTRS is a mask of the boolean attributes. We only need `SIGNED',
424 but for generality we take a bitmask of all of them.
425 WORD_OFFSET is the offset in bits from the start of the insn of the value.
426 WORD_LENGTH is the length of the word in bits in which the value resides.
427 START is the starting bit number in the word, architecture origin.
428 LENGTH is the length of VALUE in bits.
429 TOTAL_LENGTH is the total length of the insn in bits.
431 Returns 1 for success, 0 for failure. */
433 /* ??? The return code isn't properly used. wip. */
435 /* ??? This doesn't handle bfd_vma's. Create another function when
436 necessary. */
438 static int
439 extract_normal (cd, ex_info, insn_value, attrs, word_offset, start, length,
440 word_length, total_length, pc, valuep)
441 CGEN_CPU_DESC cd;
442 CGEN_EXTRACT_INFO *ex_info;
443 CGEN_INSN_INT insn_value;
444 unsigned int attrs;
445 unsigned int word_offset, start, length, word_length, total_length;
446 bfd_vma pc;
447 long *valuep;
449 CGEN_INSN_INT value;
451 /* If LENGTH is zero, this operand doesn't contribute to the value
452 so give it a standard value of zero. */
453 if (length == 0)
455 *valuep = 0;
456 return 1;
459 if (CGEN_INT_INSN_P
460 && word_offset != 0)
461 abort ();
463 if (word_length > 32)
464 abort ();
466 /* For architectures with insns smaller than the insn-base-bitsize,
467 word_length may be too big. */
468 if (cd->min_insn_bitsize < cd->base_insn_bitsize)
470 if (word_offset == 0
471 && word_length > total_length)
472 word_length = total_length;
475 /* Does the value reside in INSN_VALUE? */
477 if (word_offset == 0)
479 /* Written this way to avoid undefined behaviour. */
480 CGEN_INSN_INT mask = (((1L << (length - 1)) - 1) << 1) | 1;
482 if (CGEN_INSN_LSB0_P)
483 value = insn_value >> ((start + 1) - length);
484 else
485 value = insn_value >> (word_length - (start + length));
486 value &= mask;
487 /* sign extend? */
488 if (CGEN_BOOL_ATTR (attrs, CGEN_IFLD_SIGNED)
489 && (value & (1L << (length - 1))))
490 value |= ~mask;
493 #if ! CGEN_INT_INSN_P
495 else
497 unsigned char *bufp = ex_info->insn_bytes + word_offset / 8;
499 if (word_length > 32)
500 abort ();
502 if (fill_cache (cd, ex_info, word_offset / 8, word_length / 8, pc) == 0)
503 return 0;
505 value = extract_1 (cd, ex_info, start, length, word_length, bufp, pc);
508 #endif /* ! CGEN_INT_INSN_P */
510 *valuep = value;
512 return 1;
515 /* Default insn extractor.
517 INSN_VALUE is the first base_insn_bitsize bits, translated to host order.
518 The extracted fields are stored in FIELDS.
519 EX_INFO is used to handle reading variable length insns.
520 Return the length of the insn in bits, or 0 if no match,
521 or -1 if an error occurs fetching data (memory_error_func will have
522 been called). */
524 static int
525 extract_insn_normal (cd, insn, ex_info, insn_value, fields, pc)
526 CGEN_CPU_DESC cd;
527 const CGEN_INSN *insn;
528 CGEN_EXTRACT_INFO *ex_info;
529 CGEN_INSN_INT insn_value;
530 CGEN_FIELDS *fields;
531 bfd_vma pc;
533 const CGEN_SYNTAX *syntax = CGEN_INSN_SYNTAX (insn);
534 const unsigned char *syn;
536 CGEN_FIELDS_BITSIZE (fields) = CGEN_INSN_BITSIZE (insn);
538 CGEN_INIT_EXTRACT (cd);
540 for (syn = CGEN_SYNTAX_STRING (syntax); *syn; ++syn)
542 int length;
544 if (CGEN_SYNTAX_CHAR_P (*syn))
545 continue;
547 length = (* cd->extract_operand) (cd, CGEN_SYNTAX_FIELD (*syn),
548 ex_info, insn_value, fields, pc);
549 if (length <= 0)
550 return length;
553 /* We recognized and successfully extracted this insn. */
554 return CGEN_INSN_BITSIZE (insn);
557 /* machine generated code added here */
559 /* Main entry point for operand insertion.
561 This function is basically just a big switch statement. Earlier versions
562 used tables to look up the function to use, but
563 - if the table contains both assembler and disassembler functions then
564 the disassembler contains much of the assembler and vice-versa,
565 - there's a lot of inlining possibilities as things grow,
566 - using a switch statement avoids the function call overhead.
568 This function could be moved into `parse_insn_normal', but keeping it
569 separate makes clear the interface between `parse_insn_normal' and each of
570 the handlers. It's also needed by GAS to insert operands that couldn't be
571 resolved during parsing.
574 const char *
575 fr30_cgen_insert_operand (cd, opindex, fields, buffer, pc)
576 CGEN_CPU_DESC cd;
577 int opindex;
578 CGEN_FIELDS * fields;
579 CGEN_INSN_BYTES_PTR buffer;
580 bfd_vma pc;
582 const char * errmsg = NULL;
583 unsigned int total_length = CGEN_FIELDS_BITSIZE (fields);
585 switch (opindex)
587 case FR30_OPERAND_CRI :
588 errmsg = insert_normal (cd, fields->f_CRi, 0, 16, 12, 4, 16, total_length, buffer);
589 break;
590 case FR30_OPERAND_CRJ :
591 errmsg = insert_normal (cd, fields->f_CRj, 0, 16, 8, 4, 16, total_length, buffer);
592 break;
593 case FR30_OPERAND_R13 :
594 break;
595 case FR30_OPERAND_R14 :
596 break;
597 case FR30_OPERAND_R15 :
598 break;
599 case FR30_OPERAND_RI :
600 errmsg = insert_normal (cd, fields->f_Ri, 0, 0, 12, 4, 16, total_length, buffer);
601 break;
602 case FR30_OPERAND_RIC :
603 errmsg = insert_normal (cd, fields->f_Ric, 0, 16, 12, 4, 16, total_length, buffer);
604 break;
605 case FR30_OPERAND_RJ :
606 errmsg = insert_normal (cd, fields->f_Rj, 0, 0, 8, 4, 16, total_length, buffer);
607 break;
608 case FR30_OPERAND_RJC :
609 errmsg = insert_normal (cd, fields->f_Rjc, 0, 16, 8, 4, 16, total_length, buffer);
610 break;
611 case FR30_OPERAND_RS1 :
612 errmsg = insert_normal (cd, fields->f_Rs1, 0, 0, 8, 4, 16, total_length, buffer);
613 break;
614 case FR30_OPERAND_RS2 :
615 errmsg = insert_normal (cd, fields->f_Rs2, 0, 0, 12, 4, 16, total_length, buffer);
616 break;
617 case FR30_OPERAND_CC :
618 errmsg = insert_normal (cd, fields->f_cc, 0, 0, 4, 4, 16, total_length, buffer);
619 break;
620 case FR30_OPERAND_CCC :
621 errmsg = insert_normal (cd, fields->f_ccc, 0, 16, 0, 8, 16, total_length, buffer);
622 break;
623 case FR30_OPERAND_DIR10 :
625 long value = fields->f_dir10;
626 value = ((unsigned int) (value) >> (2));
627 errmsg = insert_normal (cd, value, 0, 0, 8, 8, 16, total_length, buffer);
629 break;
630 case FR30_OPERAND_DIR8 :
631 errmsg = insert_normal (cd, fields->f_dir8, 0, 0, 8, 8, 16, total_length, buffer);
632 break;
633 case FR30_OPERAND_DIR9 :
635 long value = fields->f_dir9;
636 value = ((unsigned int) (value) >> (1));
637 errmsg = insert_normal (cd, value, 0, 0, 8, 8, 16, total_length, buffer);
639 break;
640 case FR30_OPERAND_DISP10 :
642 long value = fields->f_disp10;
643 value = ((int) (value) >> (2));
644 errmsg = insert_normal (cd, value, 0|(1<<CGEN_IFLD_SIGNED), 0, 4, 8, 16, total_length, buffer);
646 break;
647 case FR30_OPERAND_DISP8 :
648 errmsg = insert_normal (cd, fields->f_disp8, 0|(1<<CGEN_IFLD_SIGNED), 0, 4, 8, 16, total_length, buffer);
649 break;
650 case FR30_OPERAND_DISP9 :
652 long value = fields->f_disp9;
653 value = ((int) (value) >> (1));
654 errmsg = insert_normal (cd, value, 0|(1<<CGEN_IFLD_SIGNED), 0, 4, 8, 16, total_length, buffer);
656 break;
657 case FR30_OPERAND_I20 :
660 FLD (f_i20_4) = ((unsigned int) (FLD (f_i20)) >> (16));
661 FLD (f_i20_16) = ((FLD (f_i20)) & (65535));
663 errmsg = insert_normal (cd, fields->f_i20_4, 0, 0, 8, 4, 16, total_length, buffer);
664 if (errmsg)
665 break;
666 errmsg = insert_normal (cd, fields->f_i20_16, 0, 16, 0, 16, 16, total_length, buffer);
667 if (errmsg)
668 break;
670 break;
671 case FR30_OPERAND_I32 :
672 errmsg = insert_normal (cd, fields->f_i32, 0|(1<<CGEN_IFLD_SIGN_OPT), 16, 0, 32, 32, total_length, buffer);
673 break;
674 case FR30_OPERAND_I8 :
675 errmsg = insert_normal (cd, fields->f_i8, 0, 0, 4, 8, 16, total_length, buffer);
676 break;
677 case FR30_OPERAND_LABEL12 :
679 long value = fields->f_rel12;
680 value = ((int) (((value) - (((pc) + (2))))) >> (1));
681 errmsg = insert_normal (cd, value, 0|(1<<CGEN_IFLD_SIGNED)|(1<<CGEN_IFLD_PCREL_ADDR), 0, 5, 11, 16, total_length, buffer);
683 break;
684 case FR30_OPERAND_LABEL9 :
686 long value = fields->f_rel9;
687 value = ((int) (((value) - (((pc) + (2))))) >> (1));
688 errmsg = insert_normal (cd, value, 0|(1<<CGEN_IFLD_SIGNED)|(1<<CGEN_IFLD_PCREL_ADDR), 0, 8, 8, 16, total_length, buffer);
690 break;
691 case FR30_OPERAND_M4 :
693 long value = fields->f_m4;
694 value = ((value) & (15));
695 errmsg = insert_normal (cd, value, 0, 0, 8, 4, 16, total_length, buffer);
697 break;
698 case FR30_OPERAND_PS :
699 break;
700 case FR30_OPERAND_REGLIST_HI_LD :
701 errmsg = insert_normal (cd, fields->f_reglist_hi_ld, 0, 0, 8, 8, 16, total_length, buffer);
702 break;
703 case FR30_OPERAND_REGLIST_HI_ST :
704 errmsg = insert_normal (cd, fields->f_reglist_hi_st, 0, 0, 8, 8, 16, total_length, buffer);
705 break;
706 case FR30_OPERAND_REGLIST_LOW_LD :
707 errmsg = insert_normal (cd, fields->f_reglist_low_ld, 0, 0, 8, 8, 16, total_length, buffer);
708 break;
709 case FR30_OPERAND_REGLIST_LOW_ST :
710 errmsg = insert_normal (cd, fields->f_reglist_low_st, 0, 0, 8, 8, 16, total_length, buffer);
711 break;
712 case FR30_OPERAND_S10 :
714 long value = fields->f_s10;
715 value = ((int) (value) >> (2));
716 errmsg = insert_normal (cd, value, 0|(1<<CGEN_IFLD_SIGNED), 0, 8, 8, 16, total_length, buffer);
718 break;
719 case FR30_OPERAND_U10 :
721 long value = fields->f_u10;
722 value = ((unsigned int) (value) >> (2));
723 errmsg = insert_normal (cd, value, 0, 0, 8, 8, 16, total_length, buffer);
725 break;
726 case FR30_OPERAND_U4 :
727 errmsg = insert_normal (cd, fields->f_u4, 0, 0, 8, 4, 16, total_length, buffer);
728 break;
729 case FR30_OPERAND_U4C :
730 errmsg = insert_normal (cd, fields->f_u4c, 0, 0, 12, 4, 16, total_length, buffer);
731 break;
732 case FR30_OPERAND_U8 :
733 errmsg = insert_normal (cd, fields->f_u8, 0, 0, 8, 8, 16, total_length, buffer);
734 break;
735 case FR30_OPERAND_UDISP6 :
737 long value = fields->f_udisp6;
738 value = ((unsigned int) (value) >> (2));
739 errmsg = insert_normal (cd, value, 0, 0, 8, 4, 16, total_length, buffer);
741 break;
743 default :
744 /* xgettext:c-format */
745 fprintf (stderr, _("Unrecognized field %d while building insn.\n"),
746 opindex);
747 abort ();
750 return errmsg;
753 /* Main entry point for operand extraction.
754 The result is <= 0 for error, >0 for success.
755 ??? Actual values aren't well defined right now.
757 This function is basically just a big switch statement. Earlier versions
758 used tables to look up the function to use, but
759 - if the table contains both assembler and disassembler functions then
760 the disassembler contains much of the assembler and vice-versa,
761 - there's a lot of inlining possibilities as things grow,
762 - using a switch statement avoids the function call overhead.
764 This function could be moved into `print_insn_normal', but keeping it
765 separate makes clear the interface between `print_insn_normal' and each of
766 the handlers.
770 fr30_cgen_extract_operand (cd, opindex, ex_info, insn_value, fields, pc)
771 CGEN_CPU_DESC cd;
772 int opindex;
773 CGEN_EXTRACT_INFO *ex_info;
774 CGEN_INSN_INT insn_value;
775 CGEN_FIELDS * fields;
776 bfd_vma pc;
778 /* Assume success (for those operands that are nops). */
779 int length = 1;
780 unsigned int total_length = CGEN_FIELDS_BITSIZE (fields);
782 switch (opindex)
784 case FR30_OPERAND_CRI :
785 length = extract_normal (cd, ex_info, insn_value, 0, 16, 12, 4, 16, total_length, pc, & fields->f_CRi);
786 break;
787 case FR30_OPERAND_CRJ :
788 length = extract_normal (cd, ex_info, insn_value, 0, 16, 8, 4, 16, total_length, pc, & fields->f_CRj);
789 break;
790 case FR30_OPERAND_R13 :
791 break;
792 case FR30_OPERAND_R14 :
793 break;
794 case FR30_OPERAND_R15 :
795 break;
796 case FR30_OPERAND_RI :
797 length = extract_normal (cd, ex_info, insn_value, 0, 0, 12, 4, 16, total_length, pc, & fields->f_Ri);
798 break;
799 case FR30_OPERAND_RIC :
800 length = extract_normal (cd, ex_info, insn_value, 0, 16, 12, 4, 16, total_length, pc, & fields->f_Ric);
801 break;
802 case FR30_OPERAND_RJ :
803 length = extract_normal (cd, ex_info, insn_value, 0, 0, 8, 4, 16, total_length, pc, & fields->f_Rj);
804 break;
805 case FR30_OPERAND_RJC :
806 length = extract_normal (cd, ex_info, insn_value, 0, 16, 8, 4, 16, total_length, pc, & fields->f_Rjc);
807 break;
808 case FR30_OPERAND_RS1 :
809 length = extract_normal (cd, ex_info, insn_value, 0, 0, 8, 4, 16, total_length, pc, & fields->f_Rs1);
810 break;
811 case FR30_OPERAND_RS2 :
812 length = extract_normal (cd, ex_info, insn_value, 0, 0, 12, 4, 16, total_length, pc, & fields->f_Rs2);
813 break;
814 case FR30_OPERAND_CC :
815 length = extract_normal (cd, ex_info, insn_value, 0, 0, 4, 4, 16, total_length, pc, & fields->f_cc);
816 break;
817 case FR30_OPERAND_CCC :
818 length = extract_normal (cd, ex_info, insn_value, 0, 16, 0, 8, 16, total_length, pc, & fields->f_ccc);
819 break;
820 case FR30_OPERAND_DIR10 :
822 long value;
823 length = extract_normal (cd, ex_info, insn_value, 0, 0, 8, 8, 16, total_length, pc, & value);
824 value = ((value) << (2));
825 fields->f_dir10 = value;
827 break;
828 case FR30_OPERAND_DIR8 :
829 length = extract_normal (cd, ex_info, insn_value, 0, 0, 8, 8, 16, total_length, pc, & fields->f_dir8);
830 break;
831 case FR30_OPERAND_DIR9 :
833 long value;
834 length = extract_normal (cd, ex_info, insn_value, 0, 0, 8, 8, 16, total_length, pc, & value);
835 value = ((value) << (1));
836 fields->f_dir9 = value;
838 break;
839 case FR30_OPERAND_DISP10 :
841 long value;
842 length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_SIGNED), 0, 4, 8, 16, total_length, pc, & value);
843 value = ((value) << (2));
844 fields->f_disp10 = value;
846 break;
847 case FR30_OPERAND_DISP8 :
848 length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_SIGNED), 0, 4, 8, 16, total_length, pc, & fields->f_disp8);
849 break;
850 case FR30_OPERAND_DISP9 :
852 long value;
853 length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_SIGNED), 0, 4, 8, 16, total_length, pc, & value);
854 value = ((value) << (1));
855 fields->f_disp9 = value;
857 break;
858 case FR30_OPERAND_I20 :
860 length = extract_normal (cd, ex_info, insn_value, 0, 0, 8, 4, 16, total_length, pc, & fields->f_i20_4);
861 length = extract_normal (cd, ex_info, insn_value, 0, 16, 0, 16, 16, total_length, pc, & fields->f_i20_16);
863 FLD (f_i20) = ((((FLD (f_i20_4)) << (16))) | (FLD (f_i20_16)));
866 break;
867 case FR30_OPERAND_I32 :
868 length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_SIGN_OPT), 16, 0, 32, 32, total_length, pc, & fields->f_i32);
869 break;
870 case FR30_OPERAND_I8 :
871 length = extract_normal (cd, ex_info, insn_value, 0, 0, 4, 8, 16, total_length, pc, & fields->f_i8);
872 break;
873 case FR30_OPERAND_LABEL12 :
875 long value;
876 length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_SIGNED)|(1<<CGEN_IFLD_PCREL_ADDR), 0, 5, 11, 16, total_length, pc, & value);
877 value = ((((value) << (1))) + (((pc) + (2))));
878 fields->f_rel12 = value;
880 break;
881 case FR30_OPERAND_LABEL9 :
883 long value;
884 length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_SIGNED)|(1<<CGEN_IFLD_PCREL_ADDR), 0, 8, 8, 16, total_length, pc, & value);
885 value = ((((value) << (1))) + (((pc) + (2))));
886 fields->f_rel9 = value;
888 break;
889 case FR30_OPERAND_M4 :
891 long value;
892 length = extract_normal (cd, ex_info, insn_value, 0, 0, 8, 4, 16, total_length, pc, & value);
893 value = ((value) | (((-1) << (4))));
894 fields->f_m4 = value;
896 break;
897 case FR30_OPERAND_PS :
898 break;
899 case FR30_OPERAND_REGLIST_HI_LD :
900 length = extract_normal (cd, ex_info, insn_value, 0, 0, 8, 8, 16, total_length, pc, & fields->f_reglist_hi_ld);
901 break;
902 case FR30_OPERAND_REGLIST_HI_ST :
903 length = extract_normal (cd, ex_info, insn_value, 0, 0, 8, 8, 16, total_length, pc, & fields->f_reglist_hi_st);
904 break;
905 case FR30_OPERAND_REGLIST_LOW_LD :
906 length = extract_normal (cd, ex_info, insn_value, 0, 0, 8, 8, 16, total_length, pc, & fields->f_reglist_low_ld);
907 break;
908 case FR30_OPERAND_REGLIST_LOW_ST :
909 length = extract_normal (cd, ex_info, insn_value, 0, 0, 8, 8, 16, total_length, pc, & fields->f_reglist_low_st);
910 break;
911 case FR30_OPERAND_S10 :
913 long value;
914 length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_SIGNED), 0, 8, 8, 16, total_length, pc, & value);
915 value = ((value) << (2));
916 fields->f_s10 = value;
918 break;
919 case FR30_OPERAND_U10 :
921 long value;
922 length = extract_normal (cd, ex_info, insn_value, 0, 0, 8, 8, 16, total_length, pc, & value);
923 value = ((value) << (2));
924 fields->f_u10 = value;
926 break;
927 case FR30_OPERAND_U4 :
928 length = extract_normal (cd, ex_info, insn_value, 0, 0, 8, 4, 16, total_length, pc, & fields->f_u4);
929 break;
930 case FR30_OPERAND_U4C :
931 length = extract_normal (cd, ex_info, insn_value, 0, 0, 12, 4, 16, total_length, pc, & fields->f_u4c);
932 break;
933 case FR30_OPERAND_U8 :
934 length = extract_normal (cd, ex_info, insn_value, 0, 0, 8, 8, 16, total_length, pc, & fields->f_u8);
935 break;
936 case FR30_OPERAND_UDISP6 :
938 long value;
939 length = extract_normal (cd, ex_info, insn_value, 0, 0, 8, 4, 16, total_length, pc, & value);
940 value = ((value) << (2));
941 fields->f_udisp6 = value;
943 break;
945 default :
946 /* xgettext:c-format */
947 fprintf (stderr, _("Unrecognized field %d while decoding insn.\n"),
948 opindex);
949 abort ();
952 return length;
955 cgen_insert_fn * const fr30_cgen_insert_handlers[] =
957 insert_insn_normal,
960 cgen_extract_fn * const fr30_cgen_extract_handlers[] =
962 extract_insn_normal,
965 /* Getting values from cgen_fields is handled by a collection of functions.
966 They are distinguished by the type of the VALUE argument they return.
967 TODO: floating point, inlining support, remove cases where result type
968 not appropriate. */
971 fr30_cgen_get_int_operand (cd, opindex, fields)
972 CGEN_CPU_DESC cd;
973 int opindex;
974 const CGEN_FIELDS * fields;
976 int value;
978 switch (opindex)
980 case FR30_OPERAND_CRI :
981 value = fields->f_CRi;
982 break;
983 case FR30_OPERAND_CRJ :
984 value = fields->f_CRj;
985 break;
986 case FR30_OPERAND_R13 :
987 value = 0;
988 break;
989 case FR30_OPERAND_R14 :
990 value = 0;
991 break;
992 case FR30_OPERAND_R15 :
993 value = 0;
994 break;
995 case FR30_OPERAND_RI :
996 value = fields->f_Ri;
997 break;
998 case FR30_OPERAND_RIC :
999 value = fields->f_Ric;
1000 break;
1001 case FR30_OPERAND_RJ :
1002 value = fields->f_Rj;
1003 break;
1004 case FR30_OPERAND_RJC :
1005 value = fields->f_Rjc;
1006 break;
1007 case FR30_OPERAND_RS1 :
1008 value = fields->f_Rs1;
1009 break;
1010 case FR30_OPERAND_RS2 :
1011 value = fields->f_Rs2;
1012 break;
1013 case FR30_OPERAND_CC :
1014 value = fields->f_cc;
1015 break;
1016 case FR30_OPERAND_CCC :
1017 value = fields->f_ccc;
1018 break;
1019 case FR30_OPERAND_DIR10 :
1020 value = fields->f_dir10;
1021 break;
1022 case FR30_OPERAND_DIR8 :
1023 value = fields->f_dir8;
1024 break;
1025 case FR30_OPERAND_DIR9 :
1026 value = fields->f_dir9;
1027 break;
1028 case FR30_OPERAND_DISP10 :
1029 value = fields->f_disp10;
1030 break;
1031 case FR30_OPERAND_DISP8 :
1032 value = fields->f_disp8;
1033 break;
1034 case FR30_OPERAND_DISP9 :
1035 value = fields->f_disp9;
1036 break;
1037 case FR30_OPERAND_I20 :
1038 value = fields->f_i20;
1039 break;
1040 case FR30_OPERAND_I32 :
1041 value = fields->f_i32;
1042 break;
1043 case FR30_OPERAND_I8 :
1044 value = fields->f_i8;
1045 break;
1046 case FR30_OPERAND_LABEL12 :
1047 value = fields->f_rel12;
1048 break;
1049 case FR30_OPERAND_LABEL9 :
1050 value = fields->f_rel9;
1051 break;
1052 case FR30_OPERAND_M4 :
1053 value = fields->f_m4;
1054 break;
1055 case FR30_OPERAND_PS :
1056 value = 0;
1057 break;
1058 case FR30_OPERAND_REGLIST_HI_LD :
1059 value = fields->f_reglist_hi_ld;
1060 break;
1061 case FR30_OPERAND_REGLIST_HI_ST :
1062 value = fields->f_reglist_hi_st;
1063 break;
1064 case FR30_OPERAND_REGLIST_LOW_LD :
1065 value = fields->f_reglist_low_ld;
1066 break;
1067 case FR30_OPERAND_REGLIST_LOW_ST :
1068 value = fields->f_reglist_low_st;
1069 break;
1070 case FR30_OPERAND_S10 :
1071 value = fields->f_s10;
1072 break;
1073 case FR30_OPERAND_U10 :
1074 value = fields->f_u10;
1075 break;
1076 case FR30_OPERAND_U4 :
1077 value = fields->f_u4;
1078 break;
1079 case FR30_OPERAND_U4C :
1080 value = fields->f_u4c;
1081 break;
1082 case FR30_OPERAND_U8 :
1083 value = fields->f_u8;
1084 break;
1085 case FR30_OPERAND_UDISP6 :
1086 value = fields->f_udisp6;
1087 break;
1089 default :
1090 /* xgettext:c-format */
1091 fprintf (stderr, _("Unrecognized field %d while getting int operand.\n"),
1092 opindex);
1093 abort ();
1096 return value;
1099 bfd_vma
1100 fr30_cgen_get_vma_operand (cd, opindex, fields)
1101 CGEN_CPU_DESC cd;
1102 int opindex;
1103 const CGEN_FIELDS * fields;
1105 bfd_vma value;
1107 switch (opindex)
1109 case FR30_OPERAND_CRI :
1110 value = fields->f_CRi;
1111 break;
1112 case FR30_OPERAND_CRJ :
1113 value = fields->f_CRj;
1114 break;
1115 case FR30_OPERAND_R13 :
1116 value = 0;
1117 break;
1118 case FR30_OPERAND_R14 :
1119 value = 0;
1120 break;
1121 case FR30_OPERAND_R15 :
1122 value = 0;
1123 break;
1124 case FR30_OPERAND_RI :
1125 value = fields->f_Ri;
1126 break;
1127 case FR30_OPERAND_RIC :
1128 value = fields->f_Ric;
1129 break;
1130 case FR30_OPERAND_RJ :
1131 value = fields->f_Rj;
1132 break;
1133 case FR30_OPERAND_RJC :
1134 value = fields->f_Rjc;
1135 break;
1136 case FR30_OPERAND_RS1 :
1137 value = fields->f_Rs1;
1138 break;
1139 case FR30_OPERAND_RS2 :
1140 value = fields->f_Rs2;
1141 break;
1142 case FR30_OPERAND_CC :
1143 value = fields->f_cc;
1144 break;
1145 case FR30_OPERAND_CCC :
1146 value = fields->f_ccc;
1147 break;
1148 case FR30_OPERAND_DIR10 :
1149 value = fields->f_dir10;
1150 break;
1151 case FR30_OPERAND_DIR8 :
1152 value = fields->f_dir8;
1153 break;
1154 case FR30_OPERAND_DIR9 :
1155 value = fields->f_dir9;
1156 break;
1157 case FR30_OPERAND_DISP10 :
1158 value = fields->f_disp10;
1159 break;
1160 case FR30_OPERAND_DISP8 :
1161 value = fields->f_disp8;
1162 break;
1163 case FR30_OPERAND_DISP9 :
1164 value = fields->f_disp9;
1165 break;
1166 case FR30_OPERAND_I20 :
1167 value = fields->f_i20;
1168 break;
1169 case FR30_OPERAND_I32 :
1170 value = fields->f_i32;
1171 break;
1172 case FR30_OPERAND_I8 :
1173 value = fields->f_i8;
1174 break;
1175 case FR30_OPERAND_LABEL12 :
1176 value = fields->f_rel12;
1177 break;
1178 case FR30_OPERAND_LABEL9 :
1179 value = fields->f_rel9;
1180 break;
1181 case FR30_OPERAND_M4 :
1182 value = fields->f_m4;
1183 break;
1184 case FR30_OPERAND_PS :
1185 value = 0;
1186 break;
1187 case FR30_OPERAND_REGLIST_HI_LD :
1188 value = fields->f_reglist_hi_ld;
1189 break;
1190 case FR30_OPERAND_REGLIST_HI_ST :
1191 value = fields->f_reglist_hi_st;
1192 break;
1193 case FR30_OPERAND_REGLIST_LOW_LD :
1194 value = fields->f_reglist_low_ld;
1195 break;
1196 case FR30_OPERAND_REGLIST_LOW_ST :
1197 value = fields->f_reglist_low_st;
1198 break;
1199 case FR30_OPERAND_S10 :
1200 value = fields->f_s10;
1201 break;
1202 case FR30_OPERAND_U10 :
1203 value = fields->f_u10;
1204 break;
1205 case FR30_OPERAND_U4 :
1206 value = fields->f_u4;
1207 break;
1208 case FR30_OPERAND_U4C :
1209 value = fields->f_u4c;
1210 break;
1211 case FR30_OPERAND_U8 :
1212 value = fields->f_u8;
1213 break;
1214 case FR30_OPERAND_UDISP6 :
1215 value = fields->f_udisp6;
1216 break;
1218 default :
1219 /* xgettext:c-format */
1220 fprintf (stderr, _("Unrecognized field %d while getting vma operand.\n"),
1221 opindex);
1222 abort ();
1225 return value;
1228 /* Stuffing values in cgen_fields is handled by a collection of functions.
1229 They are distinguished by the type of the VALUE argument they accept.
1230 TODO: floating point, inlining support, remove cases where argument type
1231 not appropriate. */
1233 void
1234 fr30_cgen_set_int_operand (cd, opindex, fields, value)
1235 CGEN_CPU_DESC cd;
1236 int opindex;
1237 CGEN_FIELDS * fields;
1238 int value;
1240 switch (opindex)
1242 case FR30_OPERAND_CRI :
1243 fields->f_CRi = value;
1244 break;
1245 case FR30_OPERAND_CRJ :
1246 fields->f_CRj = value;
1247 break;
1248 case FR30_OPERAND_R13 :
1249 break;
1250 case FR30_OPERAND_R14 :
1251 break;
1252 case FR30_OPERAND_R15 :
1253 break;
1254 case FR30_OPERAND_RI :
1255 fields->f_Ri = value;
1256 break;
1257 case FR30_OPERAND_RIC :
1258 fields->f_Ric = value;
1259 break;
1260 case FR30_OPERAND_RJ :
1261 fields->f_Rj = value;
1262 break;
1263 case FR30_OPERAND_RJC :
1264 fields->f_Rjc = value;
1265 break;
1266 case FR30_OPERAND_RS1 :
1267 fields->f_Rs1 = value;
1268 break;
1269 case FR30_OPERAND_RS2 :
1270 fields->f_Rs2 = value;
1271 break;
1272 case FR30_OPERAND_CC :
1273 fields->f_cc = value;
1274 break;
1275 case FR30_OPERAND_CCC :
1276 fields->f_ccc = value;
1277 break;
1278 case FR30_OPERAND_DIR10 :
1279 fields->f_dir10 = value;
1280 break;
1281 case FR30_OPERAND_DIR8 :
1282 fields->f_dir8 = value;
1283 break;
1284 case FR30_OPERAND_DIR9 :
1285 fields->f_dir9 = value;
1286 break;
1287 case FR30_OPERAND_DISP10 :
1288 fields->f_disp10 = value;
1289 break;
1290 case FR30_OPERAND_DISP8 :
1291 fields->f_disp8 = value;
1292 break;
1293 case FR30_OPERAND_DISP9 :
1294 fields->f_disp9 = value;
1295 break;
1296 case FR30_OPERAND_I20 :
1297 fields->f_i20 = value;
1298 break;
1299 case FR30_OPERAND_I32 :
1300 fields->f_i32 = value;
1301 break;
1302 case FR30_OPERAND_I8 :
1303 fields->f_i8 = value;
1304 break;
1305 case FR30_OPERAND_LABEL12 :
1306 fields->f_rel12 = value;
1307 break;
1308 case FR30_OPERAND_LABEL9 :
1309 fields->f_rel9 = value;
1310 break;
1311 case FR30_OPERAND_M4 :
1312 fields->f_m4 = value;
1313 break;
1314 case FR30_OPERAND_PS :
1315 break;
1316 case FR30_OPERAND_REGLIST_HI_LD :
1317 fields->f_reglist_hi_ld = value;
1318 break;
1319 case FR30_OPERAND_REGLIST_HI_ST :
1320 fields->f_reglist_hi_st = value;
1321 break;
1322 case FR30_OPERAND_REGLIST_LOW_LD :
1323 fields->f_reglist_low_ld = value;
1324 break;
1325 case FR30_OPERAND_REGLIST_LOW_ST :
1326 fields->f_reglist_low_st = value;
1327 break;
1328 case FR30_OPERAND_S10 :
1329 fields->f_s10 = value;
1330 break;
1331 case FR30_OPERAND_U10 :
1332 fields->f_u10 = value;
1333 break;
1334 case FR30_OPERAND_U4 :
1335 fields->f_u4 = value;
1336 break;
1337 case FR30_OPERAND_U4C :
1338 fields->f_u4c = value;
1339 break;
1340 case FR30_OPERAND_U8 :
1341 fields->f_u8 = value;
1342 break;
1343 case FR30_OPERAND_UDISP6 :
1344 fields->f_udisp6 = value;
1345 break;
1347 default :
1348 /* xgettext:c-format */
1349 fprintf (stderr, _("Unrecognized field %d while setting int operand.\n"),
1350 opindex);
1351 abort ();
1355 void
1356 fr30_cgen_set_vma_operand (cd, opindex, fields, value)
1357 CGEN_CPU_DESC cd;
1358 int opindex;
1359 CGEN_FIELDS * fields;
1360 bfd_vma value;
1362 switch (opindex)
1364 case FR30_OPERAND_CRI :
1365 fields->f_CRi = value;
1366 break;
1367 case FR30_OPERAND_CRJ :
1368 fields->f_CRj = value;
1369 break;
1370 case FR30_OPERAND_R13 :
1371 break;
1372 case FR30_OPERAND_R14 :
1373 break;
1374 case FR30_OPERAND_R15 :
1375 break;
1376 case FR30_OPERAND_RI :
1377 fields->f_Ri = value;
1378 break;
1379 case FR30_OPERAND_RIC :
1380 fields->f_Ric = value;
1381 break;
1382 case FR30_OPERAND_RJ :
1383 fields->f_Rj = value;
1384 break;
1385 case FR30_OPERAND_RJC :
1386 fields->f_Rjc = value;
1387 break;
1388 case FR30_OPERAND_RS1 :
1389 fields->f_Rs1 = value;
1390 break;
1391 case FR30_OPERAND_RS2 :
1392 fields->f_Rs2 = value;
1393 break;
1394 case FR30_OPERAND_CC :
1395 fields->f_cc = value;
1396 break;
1397 case FR30_OPERAND_CCC :
1398 fields->f_ccc = value;
1399 break;
1400 case FR30_OPERAND_DIR10 :
1401 fields->f_dir10 = value;
1402 break;
1403 case FR30_OPERAND_DIR8 :
1404 fields->f_dir8 = value;
1405 break;
1406 case FR30_OPERAND_DIR9 :
1407 fields->f_dir9 = value;
1408 break;
1409 case FR30_OPERAND_DISP10 :
1410 fields->f_disp10 = value;
1411 break;
1412 case FR30_OPERAND_DISP8 :
1413 fields->f_disp8 = value;
1414 break;
1415 case FR30_OPERAND_DISP9 :
1416 fields->f_disp9 = value;
1417 break;
1418 case FR30_OPERAND_I20 :
1419 fields->f_i20 = value;
1420 break;
1421 case FR30_OPERAND_I32 :
1422 fields->f_i32 = value;
1423 break;
1424 case FR30_OPERAND_I8 :
1425 fields->f_i8 = value;
1426 break;
1427 case FR30_OPERAND_LABEL12 :
1428 fields->f_rel12 = value;
1429 break;
1430 case FR30_OPERAND_LABEL9 :
1431 fields->f_rel9 = value;
1432 break;
1433 case FR30_OPERAND_M4 :
1434 fields->f_m4 = value;
1435 break;
1436 case FR30_OPERAND_PS :
1437 break;
1438 case FR30_OPERAND_REGLIST_HI_LD :
1439 fields->f_reglist_hi_ld = value;
1440 break;
1441 case FR30_OPERAND_REGLIST_HI_ST :
1442 fields->f_reglist_hi_st = value;
1443 break;
1444 case FR30_OPERAND_REGLIST_LOW_LD :
1445 fields->f_reglist_low_ld = value;
1446 break;
1447 case FR30_OPERAND_REGLIST_LOW_ST :
1448 fields->f_reglist_low_st = value;
1449 break;
1450 case FR30_OPERAND_S10 :
1451 fields->f_s10 = value;
1452 break;
1453 case FR30_OPERAND_U10 :
1454 fields->f_u10 = value;
1455 break;
1456 case FR30_OPERAND_U4 :
1457 fields->f_u4 = value;
1458 break;
1459 case FR30_OPERAND_U4C :
1460 fields->f_u4c = value;
1461 break;
1462 case FR30_OPERAND_U8 :
1463 fields->f_u8 = value;
1464 break;
1465 case FR30_OPERAND_UDISP6 :
1466 fields->f_udisp6 = value;
1467 break;
1469 default :
1470 /* xgettext:c-format */
1471 fprintf (stderr, _("Unrecognized field %d while setting vma operand.\n"),
1472 opindex);
1473 abort ();
1477 /* Function to call before using the instruction builder tables. */
1479 void
1480 fr30_cgen_init_ibld_table (cd)
1481 CGEN_CPU_DESC cd;
1483 cd->insert_handlers = & fr30_cgen_insert_handlers[0];
1484 cd->extract_handlers = & fr30_cgen_extract_handlers[0];
1486 cd->insert_operand = fr30_cgen_insert_operand;
1487 cd->extract_operand = fr30_cgen_extract_operand;
1489 cd->get_int_operand = fr30_cgen_get_int_operand;
1490 cd->set_int_operand = fr30_cgen_set_int_operand;
1491 cd->get_vma_operand = fr30_cgen_get_vma_operand;
1492 cd->set_vma_operand = fr30_cgen_set_vma_operand;