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-2017 Free Software Foundation, Inc.
8 This file is part of libopcodes.
10 This library 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 3, or (at your option)
15 It is distributed in the hope that it will be useful, but WITHOUT
16 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
17 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
18 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 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */
24 /* ??? Eventually more and more of this stuff can go to cpu-independent files.
33 #include "fr30-desc.h"
35 #include "cgen/basic-modes.h"
37 #include "safe-ctype.h"
40 #define min(a,b) ((a) < (b) ? (a) : (b))
42 #define max(a,b) ((a) > (b) ? (a) : (b))
44 /* Used by the ifield rtx function. */
45 #define FLD(f) (fields->f)
47 static const char * insert_normal
48 (CGEN_CPU_DESC, long, unsigned int, unsigned int, unsigned int,
49 unsigned int, unsigned int, unsigned int, CGEN_INSN_BYTES_PTR);
50 static const char * insert_insn_normal
51 (CGEN_CPU_DESC, const CGEN_INSN *,
52 CGEN_FIELDS *, CGEN_INSN_BYTES_PTR, bfd_vma);
53 static int extract_normal
54 (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 (CGEN_CPU_DESC, const CGEN_INSN *, CGEN_EXTRACT_INFO *,
59 CGEN_INSN_INT, CGEN_FIELDS *, bfd_vma);
61 static void put_insn_int_value
62 (CGEN_CPU_DESC, CGEN_INSN_BYTES_PTR, int, int, CGEN_INSN_INT);
65 static CGEN_INLINE void insert_1
66 (CGEN_CPU_DESC, unsigned long, int, int, int, unsigned char *);
67 static CGEN_INLINE int fill_cache
68 (CGEN_CPU_DESC, CGEN_EXTRACT_INFO *, int, int, bfd_vma);
69 static CGEN_INLINE long extract_1
70 (CGEN_CPU_DESC, CGEN_EXTRACT_INFO *, int, int, int, unsigned char *, bfd_vma);
73 /* Operand insertion. */
77 /* Subroutine of insert_normal. */
79 static CGEN_INLINE void
80 insert_1 (CGEN_CPU_DESC cd,
90 x = cgen_get_insn_value (cd, bufp, word_length);
92 /* Written this way to avoid undefined behaviour. */
93 mask = (((1L << (length - 1)) - 1) << 1) | 1;
95 shift = (start + 1) - length;
97 shift = (word_length - (start + length));
98 x = (x & ~(mask << shift)) | ((value & mask) << shift);
100 cgen_put_insn_value (cd, bufp, word_length, (bfd_vma) x);
103 #endif /* ! CGEN_INT_INSN_P */
105 /* Default insertion routine.
107 ATTRS is a mask of the boolean attributes.
108 WORD_OFFSET is the offset in bits from the start of the insn of the value.
109 WORD_LENGTH is the length of the word in bits in which the value resides.
110 START is the starting bit number in the word, architecture origin.
111 LENGTH is the length of VALUE in bits.
112 TOTAL_LENGTH is the total length of the insn in bits.
114 The result is an error message or NULL if success. */
116 /* ??? This duplicates functionality with bfd's howto table and
117 bfd_install_relocation. */
118 /* ??? This doesn't handle bfd_vma's. Create another function when
122 insert_normal (CGEN_CPU_DESC cd,
125 unsigned int word_offset,
128 unsigned int word_length,
129 unsigned int total_length,
130 CGEN_INSN_BYTES_PTR buffer)
132 static char errbuf[100];
133 /* Written this way to avoid undefined behaviour. */
134 unsigned long mask = (((1L << (length - 1)) - 1) << 1) | 1;
136 /* If LENGTH is zero, this operand doesn't contribute to the value. */
140 if (word_length > 8 * sizeof (CGEN_INSN_INT))
143 /* For architectures with insns smaller than the base-insn-bitsize,
144 word_length may be too big. */
145 if (cd->min_insn_bitsize < cd->base_insn_bitsize)
148 && word_length > total_length)
149 word_length = total_length;
152 /* Ensure VALUE will fit. */
153 if (CGEN_BOOL_ATTR (attrs, CGEN_IFLD_SIGN_OPT))
155 long minval = - (1L << (length - 1));
156 unsigned long maxval = mask;
158 if ((value > 0 && (unsigned long) value > maxval)
161 /* xgettext:c-format */
163 _("operand out of range (%ld not between %ld and %lu)"),
164 value, minval, maxval);
168 else if (! CGEN_BOOL_ATTR (attrs, CGEN_IFLD_SIGNED))
170 unsigned long maxval = mask;
171 unsigned long val = (unsigned long) value;
173 /* For hosts with a word size > 32 check to see if value has been sign
174 extended beyond 32 bits. If so then ignore these higher sign bits
175 as the user is attempting to store a 32-bit signed value into an
176 unsigned 32-bit field which is allowed. */
177 if (sizeof (unsigned long) > 4 && ((value >> 32) == -1))
182 /* xgettext:c-format */
184 _("operand out of range (0x%lx not between 0 and 0x%lx)"),
191 if (! cgen_signed_overflow_ok_p (cd))
193 long minval = - (1L << (length - 1));
194 long maxval = (1L << (length - 1)) - 1;
196 if (value < minval || value > maxval)
199 /* xgettext:c-format */
200 (errbuf, _("operand out of range (%ld not between %ld and %ld)"),
201 value, minval, maxval);
210 int shift_within_word, shift_to_word, shift;
212 /* How to shift the value to BIT0 of the word. */
213 shift_to_word = total_length - (word_offset + word_length);
215 /* How to shift the value to the field within the word. */
216 if (CGEN_INSN_LSB0_P)
217 shift_within_word = start + 1 - length;
219 shift_within_word = word_length - start - length;
221 /* The total SHIFT, then mask in the value. */
222 shift = shift_to_word + shift_within_word;
223 *buffer = (*buffer & ~(mask << shift)) | ((value & mask) << shift);
226 #else /* ! CGEN_INT_INSN_P */
229 unsigned char *bufp = (unsigned char *) buffer + word_offset / 8;
231 insert_1 (cd, value, start, length, word_length, bufp);
234 #endif /* ! CGEN_INT_INSN_P */
239 /* Default insn builder (insert handler).
240 The instruction is recorded in CGEN_INT_INSN_P byte order (meaning
241 that if CGEN_INSN_BYTES_PTR is an int * and thus, the value is
242 recorded in host byte order, otherwise BUFFER is an array of bytes
243 and the value is recorded in target byte order).
244 The result is an error message or NULL if success. */
247 insert_insn_normal (CGEN_CPU_DESC cd,
248 const CGEN_INSN * insn,
249 CGEN_FIELDS * fields,
250 CGEN_INSN_BYTES_PTR buffer,
253 const CGEN_SYNTAX *syntax = CGEN_INSN_SYNTAX (insn);
255 const CGEN_SYNTAX_CHAR_TYPE * syn;
257 CGEN_INIT_INSERT (cd);
258 value = CGEN_INSN_BASE_VALUE (insn);
260 /* If we're recording insns as numbers (rather than a string of bytes),
261 target byte order handling is deferred until later. */
265 put_insn_int_value (cd, buffer, cd->base_insn_bitsize,
266 CGEN_FIELDS_BITSIZE (fields), value);
270 cgen_put_insn_value (cd, buffer, min ((unsigned) cd->base_insn_bitsize,
271 (unsigned) CGEN_FIELDS_BITSIZE (fields)),
274 #endif /* ! CGEN_INT_INSN_P */
276 /* ??? It would be better to scan the format's fields.
277 Still need to be able to insert a value based on the operand though;
278 e.g. storing a branch displacement that got resolved later.
279 Needs more thought first. */
281 for (syn = CGEN_SYNTAX_STRING (syntax); * syn; ++ syn)
285 if (CGEN_SYNTAX_CHAR_P (* syn))
288 errmsg = (* cd->insert_operand) (cd, CGEN_SYNTAX_FIELD (*syn),
298 /* Cover function to store an insn value into an integral insn. Must go here
299 because it needs <prefix>-desc.h for CGEN_INT_INSN_P. */
302 put_insn_int_value (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
303 CGEN_INSN_BYTES_PTR buf,
308 /* For architectures with insns smaller than the base-insn-bitsize,
309 length may be too big. */
310 if (length > insn_length)
314 int shift = insn_length - length;
315 /* Written this way to avoid undefined behaviour. */
316 CGEN_INSN_INT mask = (((1L << (length - 1)) - 1) << 1) | 1;
318 *buf = (*buf & ~(mask << shift)) | ((value & mask) << shift);
323 /* Operand extraction. */
325 #if ! CGEN_INT_INSN_P
327 /* Subroutine of extract_normal.
328 Ensure sufficient bytes are cached in EX_INFO.
329 OFFSET is the offset in bytes from the start of the insn of the value.
330 BYTES is the length of the needed value.
331 Returns 1 for success, 0 for failure. */
333 static CGEN_INLINE int
334 fill_cache (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
335 CGEN_EXTRACT_INFO *ex_info,
340 /* It's doubtful that the middle part has already been fetched so
341 we don't optimize that case. kiss. */
343 disassemble_info *info = (disassemble_info *) ex_info->dis_info;
345 /* First do a quick check. */
346 mask = (1 << bytes) - 1;
347 if (((ex_info->valid >> offset) & mask) == mask)
350 /* Search for the first byte we need to read. */
351 for (mask = 1 << offset; bytes > 0; --bytes, ++offset, mask <<= 1)
352 if (! (mask & ex_info->valid))
360 status = (*info->read_memory_func)
361 (pc, ex_info->insn_bytes + offset, bytes, info);
365 (*info->memory_error_func) (status, pc, info);
369 ex_info->valid |= ((1 << bytes) - 1) << offset;
375 /* Subroutine of extract_normal. */
377 static CGEN_INLINE long
378 extract_1 (CGEN_CPU_DESC cd,
379 CGEN_EXTRACT_INFO *ex_info ATTRIBUTE_UNUSED,
384 bfd_vma pc ATTRIBUTE_UNUSED)
389 x = cgen_get_insn_value (cd, bufp, word_length);
391 if (CGEN_INSN_LSB0_P)
392 shift = (start + 1) - length;
394 shift = (word_length - (start + length));
398 #endif /* ! CGEN_INT_INSN_P */
400 /* Default extraction routine.
402 INSN_VALUE is the first base_insn_bitsize bits of the insn in host order,
403 or sometimes less for cases like the m32r where the base insn size is 32
404 but some insns are 16 bits.
405 ATTRS is a mask of the boolean attributes. We only need `SIGNED',
406 but for generality we take a bitmask of all of them.
407 WORD_OFFSET is the offset in bits from the start of the insn of the value.
408 WORD_LENGTH is the length of the word in bits in which the value resides.
409 START is the starting bit number in the word, architecture origin.
410 LENGTH is the length of VALUE in bits.
411 TOTAL_LENGTH is the total length of the insn in bits.
413 Returns 1 for success, 0 for failure. */
415 /* ??? The return code isn't properly used. wip. */
417 /* ??? This doesn't handle bfd_vma's. Create another function when
421 extract_normal (CGEN_CPU_DESC cd,
422 #if ! CGEN_INT_INSN_P
423 CGEN_EXTRACT_INFO *ex_info,
425 CGEN_EXTRACT_INFO *ex_info ATTRIBUTE_UNUSED,
427 CGEN_INSN_INT insn_value,
429 unsigned int word_offset,
432 unsigned int word_length,
433 unsigned int total_length,
434 #if ! CGEN_INT_INSN_P
437 bfd_vma pc ATTRIBUTE_UNUSED,
443 /* If LENGTH is zero, this operand doesn't contribute to the value
444 so give it a standard value of zero. */
451 if (word_length > 8 * sizeof (CGEN_INSN_INT))
454 /* For architectures with insns smaller than the insn-base-bitsize,
455 word_length may be too big. */
456 if (cd->min_insn_bitsize < cd->base_insn_bitsize)
458 if (word_offset + word_length > total_length)
459 word_length = total_length - word_offset;
462 /* Does the value reside in INSN_VALUE, and at the right alignment? */
464 if (CGEN_INT_INSN_P || (word_offset == 0 && word_length == total_length))
466 if (CGEN_INSN_LSB0_P)
467 value = insn_value >> ((word_offset + start + 1) - length);
469 value = insn_value >> (total_length - ( word_offset + start + length));
472 #if ! CGEN_INT_INSN_P
476 unsigned char *bufp = ex_info->insn_bytes + word_offset / 8;
478 if (word_length > 8 * sizeof (CGEN_INSN_INT))
481 if (fill_cache (cd, ex_info, word_offset / 8, word_length / 8, pc) == 0)
484 value = extract_1 (cd, ex_info, start, length, word_length, bufp, pc);
487 #endif /* ! CGEN_INT_INSN_P */
489 /* Written this way to avoid undefined behaviour. */
490 mask = (((1L << (length - 1)) - 1) << 1) | 1;
494 if (CGEN_BOOL_ATTR (attrs, CGEN_IFLD_SIGNED)
495 && (value & (1L << (length - 1))))
503 /* Default insn extractor.
505 INSN_VALUE is the first base_insn_bitsize bits, translated to host order.
506 The extracted fields are stored in FIELDS.
507 EX_INFO is used to handle reading variable length insns.
508 Return the length of the insn in bits, or 0 if no match,
509 or -1 if an error occurs fetching data (memory_error_func will have
513 extract_insn_normal (CGEN_CPU_DESC cd,
514 const CGEN_INSN *insn,
515 CGEN_EXTRACT_INFO *ex_info,
516 CGEN_INSN_INT insn_value,
520 const CGEN_SYNTAX *syntax = CGEN_INSN_SYNTAX (insn);
521 const CGEN_SYNTAX_CHAR_TYPE *syn;
523 CGEN_FIELDS_BITSIZE (fields) = CGEN_INSN_BITSIZE (insn);
525 CGEN_INIT_EXTRACT (cd);
527 for (syn = CGEN_SYNTAX_STRING (syntax); *syn; ++syn)
531 if (CGEN_SYNTAX_CHAR_P (*syn))
534 length = (* cd->extract_operand) (cd, CGEN_SYNTAX_FIELD (*syn),
535 ex_info, insn_value, fields, pc);
540 /* We recognized and successfully extracted this insn. */
541 return CGEN_INSN_BITSIZE (insn);
544 /* Machine generated code added here. */
546 const char * fr30_cgen_insert_operand
547 (CGEN_CPU_DESC, int, CGEN_FIELDS *, CGEN_INSN_BYTES_PTR, bfd_vma);
549 /* Main entry point for operand insertion.
551 This function is basically just a big switch statement. Earlier versions
552 used tables to look up the function to use, but
553 - if the table contains both assembler and disassembler functions then
554 the disassembler contains much of the assembler and vice-versa,
555 - there's a lot of inlining possibilities as things grow,
556 - using a switch statement avoids the function call overhead.
558 This function could be moved into `parse_insn_normal', but keeping it
559 separate makes clear the interface between `parse_insn_normal' and each of
560 the handlers. It's also needed by GAS to insert operands that couldn't be
561 resolved during parsing. */
564 fr30_cgen_insert_operand (CGEN_CPU_DESC cd,
566 CGEN_FIELDS * fields,
567 CGEN_INSN_BYTES_PTR buffer,
568 bfd_vma pc ATTRIBUTE_UNUSED)
570 const char * errmsg = NULL;
571 unsigned int total_length = CGEN_FIELDS_BITSIZE (fields);
575 case FR30_OPERAND_CRI :
576 errmsg = insert_normal (cd, fields->f_CRi, 0, 16, 12, 4, 16, total_length, buffer);
578 case FR30_OPERAND_CRJ :
579 errmsg = insert_normal (cd, fields->f_CRj, 0, 16, 8, 4, 16, total_length, buffer);
581 case FR30_OPERAND_R13 :
583 case FR30_OPERAND_R14 :
585 case FR30_OPERAND_R15 :
587 case FR30_OPERAND_RI :
588 errmsg = insert_normal (cd, fields->f_Ri, 0, 0, 12, 4, 16, total_length, buffer);
590 case FR30_OPERAND_RIC :
591 errmsg = insert_normal (cd, fields->f_Ric, 0, 16, 12, 4, 16, total_length, buffer);
593 case FR30_OPERAND_RJ :
594 errmsg = insert_normal (cd, fields->f_Rj, 0, 0, 8, 4, 16, total_length, buffer);
596 case FR30_OPERAND_RJC :
597 errmsg = insert_normal (cd, fields->f_Rjc, 0, 16, 8, 4, 16, total_length, buffer);
599 case FR30_OPERAND_RS1 :
600 errmsg = insert_normal (cd, fields->f_Rs1, 0, 0, 8, 4, 16, total_length, buffer);
602 case FR30_OPERAND_RS2 :
603 errmsg = insert_normal (cd, fields->f_Rs2, 0, 0, 12, 4, 16, total_length, buffer);
605 case FR30_OPERAND_CC :
606 errmsg = insert_normal (cd, fields->f_cc, 0, 0, 4, 4, 16, total_length, buffer);
608 case FR30_OPERAND_CCC :
609 errmsg = insert_normal (cd, fields->f_ccc, 0, 16, 0, 8, 16, total_length, buffer);
611 case FR30_OPERAND_DIR10 :
613 long value = fields->f_dir10;
614 value = ((USI) (value) >> (2));
615 errmsg = insert_normal (cd, value, 0, 0, 8, 8, 16, total_length, buffer);
618 case FR30_OPERAND_DIR8 :
619 errmsg = insert_normal (cd, fields->f_dir8, 0, 0, 8, 8, 16, total_length, buffer);
621 case FR30_OPERAND_DIR9 :
623 long value = fields->f_dir9;
624 value = ((USI) (value) >> (1));
625 errmsg = insert_normal (cd, value, 0, 0, 8, 8, 16, total_length, buffer);
628 case FR30_OPERAND_DISP10 :
630 long value = fields->f_disp10;
631 value = ((SI) (value) >> (2));
632 errmsg = insert_normal (cd, value, 0|(1<<CGEN_IFLD_SIGNED), 0, 4, 8, 16, total_length, buffer);
635 case FR30_OPERAND_DISP8 :
636 errmsg = insert_normal (cd, fields->f_disp8, 0|(1<<CGEN_IFLD_SIGNED), 0, 4, 8, 16, total_length, buffer);
638 case FR30_OPERAND_DISP9 :
640 long value = fields->f_disp9;
641 value = ((SI) (value) >> (1));
642 errmsg = insert_normal (cd, value, 0|(1<<CGEN_IFLD_SIGNED), 0, 4, 8, 16, total_length, buffer);
645 case FR30_OPERAND_I20 :
648 FLD (f_i20_4) = ((UINT) (FLD (f_i20)) >> (16));
649 FLD (f_i20_16) = ((FLD (f_i20)) & (65535));
651 errmsg = insert_normal (cd, fields->f_i20_4, 0, 0, 8, 4, 16, total_length, buffer);
654 errmsg = insert_normal (cd, fields->f_i20_16, 0, 16, 0, 16, 16, total_length, buffer);
659 case FR30_OPERAND_I32 :
660 errmsg = insert_normal (cd, fields->f_i32, 0|(1<<CGEN_IFLD_SIGN_OPT), 16, 0, 32, 32, total_length, buffer);
662 case FR30_OPERAND_I8 :
663 errmsg = insert_normal (cd, fields->f_i8, 0, 0, 4, 8, 16, total_length, buffer);
665 case FR30_OPERAND_LABEL12 :
667 long value = fields->f_rel12;
668 value = ((SI) (((value) - (((pc) + (2))))) >> (1));
669 errmsg = insert_normal (cd, value, 0|(1<<CGEN_IFLD_SIGNED)|(1<<CGEN_IFLD_PCREL_ADDR), 0, 5, 11, 16, total_length, buffer);
672 case FR30_OPERAND_LABEL9 :
674 long value = fields->f_rel9;
675 value = ((SI) (((value) - (((pc) + (2))))) >> (1));
676 errmsg = insert_normal (cd, value, 0|(1<<CGEN_IFLD_SIGNED)|(1<<CGEN_IFLD_PCREL_ADDR), 0, 8, 8, 16, total_length, buffer);
679 case FR30_OPERAND_M4 :
681 long value = fields->f_m4;
682 value = ((value) & (15));
683 errmsg = insert_normal (cd, value, 0, 0, 8, 4, 16, total_length, buffer);
686 case FR30_OPERAND_PS :
688 case FR30_OPERAND_REGLIST_HI_LD :
689 errmsg = insert_normal (cd, fields->f_reglist_hi_ld, 0, 0, 8, 8, 16, total_length, buffer);
691 case FR30_OPERAND_REGLIST_HI_ST :
692 errmsg = insert_normal (cd, fields->f_reglist_hi_st, 0, 0, 8, 8, 16, total_length, buffer);
694 case FR30_OPERAND_REGLIST_LOW_LD :
695 errmsg = insert_normal (cd, fields->f_reglist_low_ld, 0, 0, 8, 8, 16, total_length, buffer);
697 case FR30_OPERAND_REGLIST_LOW_ST :
698 errmsg = insert_normal (cd, fields->f_reglist_low_st, 0, 0, 8, 8, 16, total_length, buffer);
700 case FR30_OPERAND_S10 :
702 long value = fields->f_s10;
703 value = ((SI) (value) >> (2));
704 errmsg = insert_normal (cd, value, 0|(1<<CGEN_IFLD_SIGNED), 0, 8, 8, 16, total_length, buffer);
707 case FR30_OPERAND_U10 :
709 long value = fields->f_u10;
710 value = ((USI) (value) >> (2));
711 errmsg = insert_normal (cd, value, 0, 0, 8, 8, 16, total_length, buffer);
714 case FR30_OPERAND_U4 :
715 errmsg = insert_normal (cd, fields->f_u4, 0, 0, 8, 4, 16, total_length, buffer);
717 case FR30_OPERAND_U4C :
718 errmsg = insert_normal (cd, fields->f_u4c, 0, 0, 12, 4, 16, total_length, buffer);
720 case FR30_OPERAND_U8 :
721 errmsg = insert_normal (cd, fields->f_u8, 0, 0, 8, 8, 16, total_length, buffer);
723 case FR30_OPERAND_UDISP6 :
725 long value = fields->f_udisp6;
726 value = ((USI) (value) >> (2));
727 errmsg = insert_normal (cd, value, 0, 0, 8, 4, 16, total_length, buffer);
732 /* xgettext:c-format */
733 fprintf (stderr, _("Unrecognized field %d while building insn.\n"),
741 int fr30_cgen_extract_operand
742 (CGEN_CPU_DESC, int, CGEN_EXTRACT_INFO *, CGEN_INSN_INT, CGEN_FIELDS *, bfd_vma);
744 /* Main entry point for operand extraction.
745 The result is <= 0 for error, >0 for success.
746 ??? Actual values aren't well defined right now.
748 This function is basically just a big switch statement. Earlier versions
749 used tables to look up the function to use, but
750 - if the table contains both assembler and disassembler functions then
751 the disassembler contains much of the assembler and vice-versa,
752 - there's a lot of inlining possibilities as things grow,
753 - using a switch statement avoids the function call overhead.
755 This function could be moved into `print_insn_normal', but keeping it
756 separate makes clear the interface between `print_insn_normal' and each of
760 fr30_cgen_extract_operand (CGEN_CPU_DESC cd,
762 CGEN_EXTRACT_INFO *ex_info,
763 CGEN_INSN_INT insn_value,
764 CGEN_FIELDS * fields,
767 /* Assume success (for those operands that are nops). */
769 unsigned int total_length = CGEN_FIELDS_BITSIZE (fields);
773 case FR30_OPERAND_CRI :
774 length = extract_normal (cd, ex_info, insn_value, 0, 16, 12, 4, 16, total_length, pc, & fields->f_CRi);
776 case FR30_OPERAND_CRJ :
777 length = extract_normal (cd, ex_info, insn_value, 0, 16, 8, 4, 16, total_length, pc, & fields->f_CRj);
779 case FR30_OPERAND_R13 :
781 case FR30_OPERAND_R14 :
783 case FR30_OPERAND_R15 :
785 case FR30_OPERAND_RI :
786 length = extract_normal (cd, ex_info, insn_value, 0, 0, 12, 4, 16, total_length, pc, & fields->f_Ri);
788 case FR30_OPERAND_RIC :
789 length = extract_normal (cd, ex_info, insn_value, 0, 16, 12, 4, 16, total_length, pc, & fields->f_Ric);
791 case FR30_OPERAND_RJ :
792 length = extract_normal (cd, ex_info, insn_value, 0, 0, 8, 4, 16, total_length, pc, & fields->f_Rj);
794 case FR30_OPERAND_RJC :
795 length = extract_normal (cd, ex_info, insn_value, 0, 16, 8, 4, 16, total_length, pc, & fields->f_Rjc);
797 case FR30_OPERAND_RS1 :
798 length = extract_normal (cd, ex_info, insn_value, 0, 0, 8, 4, 16, total_length, pc, & fields->f_Rs1);
800 case FR30_OPERAND_RS2 :
801 length = extract_normal (cd, ex_info, insn_value, 0, 0, 12, 4, 16, total_length, pc, & fields->f_Rs2);
803 case FR30_OPERAND_CC :
804 length = extract_normal (cd, ex_info, insn_value, 0, 0, 4, 4, 16, total_length, pc, & fields->f_cc);
806 case FR30_OPERAND_CCC :
807 length = extract_normal (cd, ex_info, insn_value, 0, 16, 0, 8, 16, total_length, pc, & fields->f_ccc);
809 case FR30_OPERAND_DIR10 :
812 length = extract_normal (cd, ex_info, insn_value, 0, 0, 8, 8, 16, total_length, pc, & value);
813 value = ((value) << (2));
814 fields->f_dir10 = value;
817 case FR30_OPERAND_DIR8 :
818 length = extract_normal (cd, ex_info, insn_value, 0, 0, 8, 8, 16, total_length, pc, & fields->f_dir8);
820 case FR30_OPERAND_DIR9 :
823 length = extract_normal (cd, ex_info, insn_value, 0, 0, 8, 8, 16, total_length, pc, & value);
824 value = ((value) << (1));
825 fields->f_dir9 = value;
828 case FR30_OPERAND_DISP10 :
831 length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_SIGNED), 0, 4, 8, 16, total_length, pc, & value);
832 value = ((value) << (2));
833 fields->f_disp10 = value;
836 case FR30_OPERAND_DISP8 :
837 length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_SIGNED), 0, 4, 8, 16, total_length, pc, & fields->f_disp8);
839 case FR30_OPERAND_DISP9 :
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) << (1));
844 fields->f_disp9 = value;
847 case FR30_OPERAND_I20 :
849 length = extract_normal (cd, ex_info, insn_value, 0, 0, 8, 4, 16, total_length, pc, & fields->f_i20_4);
850 if (length <= 0) break;
851 length = extract_normal (cd, ex_info, insn_value, 0, 16, 0, 16, 16, total_length, pc, & fields->f_i20_16);
852 if (length <= 0) break;
854 FLD (f_i20) = ((((FLD (f_i20_4)) << (16))) | (FLD (f_i20_16)));
858 case FR30_OPERAND_I32 :
859 length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_SIGN_OPT), 16, 0, 32, 32, total_length, pc, & fields->f_i32);
861 case FR30_OPERAND_I8 :
862 length = extract_normal (cd, ex_info, insn_value, 0, 0, 4, 8, 16, total_length, pc, & fields->f_i8);
864 case FR30_OPERAND_LABEL12 :
867 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);
868 value = ((((value) << (1))) + (((pc) + (2))));
869 fields->f_rel12 = value;
872 case FR30_OPERAND_LABEL9 :
875 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);
876 value = ((((value) << (1))) + (((pc) + (2))));
877 fields->f_rel9 = value;
880 case FR30_OPERAND_M4 :
883 length = extract_normal (cd, ex_info, insn_value, 0, 0, 8, 4, 16, total_length, pc, & value);
884 value = ((value) | (-16));
885 fields->f_m4 = value;
888 case FR30_OPERAND_PS :
890 case FR30_OPERAND_REGLIST_HI_LD :
891 length = extract_normal (cd, ex_info, insn_value, 0, 0, 8, 8, 16, total_length, pc, & fields->f_reglist_hi_ld);
893 case FR30_OPERAND_REGLIST_HI_ST :
894 length = extract_normal (cd, ex_info, insn_value, 0, 0, 8, 8, 16, total_length, pc, & fields->f_reglist_hi_st);
896 case FR30_OPERAND_REGLIST_LOW_LD :
897 length = extract_normal (cd, ex_info, insn_value, 0, 0, 8, 8, 16, total_length, pc, & fields->f_reglist_low_ld);
899 case FR30_OPERAND_REGLIST_LOW_ST :
900 length = extract_normal (cd, ex_info, insn_value, 0, 0, 8, 8, 16, total_length, pc, & fields->f_reglist_low_st);
902 case FR30_OPERAND_S10 :
905 length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_SIGNED), 0, 8, 8, 16, total_length, pc, & value);
906 value = ((value) << (2));
907 fields->f_s10 = value;
910 case FR30_OPERAND_U10 :
913 length = extract_normal (cd, ex_info, insn_value, 0, 0, 8, 8, 16, total_length, pc, & value);
914 value = ((value) << (2));
915 fields->f_u10 = value;
918 case FR30_OPERAND_U4 :
919 length = extract_normal (cd, ex_info, insn_value, 0, 0, 8, 4, 16, total_length, pc, & fields->f_u4);
921 case FR30_OPERAND_U4C :
922 length = extract_normal (cd, ex_info, insn_value, 0, 0, 12, 4, 16, total_length, pc, & fields->f_u4c);
924 case FR30_OPERAND_U8 :
925 length = extract_normal (cd, ex_info, insn_value, 0, 0, 8, 8, 16, total_length, pc, & fields->f_u8);
927 case FR30_OPERAND_UDISP6 :
930 length = extract_normal (cd, ex_info, insn_value, 0, 0, 8, 4, 16, total_length, pc, & value);
931 value = ((value) << (2));
932 fields->f_udisp6 = value;
937 /* xgettext:c-format */
938 fprintf (stderr, _("Unrecognized field %d while decoding insn.\n"),
946 cgen_insert_fn * const fr30_cgen_insert_handlers[] =
951 cgen_extract_fn * const fr30_cgen_extract_handlers[] =
956 int fr30_cgen_get_int_operand (CGEN_CPU_DESC, int, const CGEN_FIELDS *);
957 bfd_vma fr30_cgen_get_vma_operand (CGEN_CPU_DESC, int, const CGEN_FIELDS *);
959 /* Getting values from cgen_fields is handled by a collection of functions.
960 They are distinguished by the type of the VALUE argument they return.
961 TODO: floating point, inlining support, remove cases where result type
965 fr30_cgen_get_int_operand (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
967 const CGEN_FIELDS * fields)
973 case FR30_OPERAND_CRI :
974 value = fields->f_CRi;
976 case FR30_OPERAND_CRJ :
977 value = fields->f_CRj;
979 case FR30_OPERAND_R13 :
982 case FR30_OPERAND_R14 :
985 case FR30_OPERAND_R15 :
988 case FR30_OPERAND_RI :
989 value = fields->f_Ri;
991 case FR30_OPERAND_RIC :
992 value = fields->f_Ric;
994 case FR30_OPERAND_RJ :
995 value = fields->f_Rj;
997 case FR30_OPERAND_RJC :
998 value = fields->f_Rjc;
1000 case FR30_OPERAND_RS1 :
1001 value = fields->f_Rs1;
1003 case FR30_OPERAND_RS2 :
1004 value = fields->f_Rs2;
1006 case FR30_OPERAND_CC :
1007 value = fields->f_cc;
1009 case FR30_OPERAND_CCC :
1010 value = fields->f_ccc;
1012 case FR30_OPERAND_DIR10 :
1013 value = fields->f_dir10;
1015 case FR30_OPERAND_DIR8 :
1016 value = fields->f_dir8;
1018 case FR30_OPERAND_DIR9 :
1019 value = fields->f_dir9;
1021 case FR30_OPERAND_DISP10 :
1022 value = fields->f_disp10;
1024 case FR30_OPERAND_DISP8 :
1025 value = fields->f_disp8;
1027 case FR30_OPERAND_DISP9 :
1028 value = fields->f_disp9;
1030 case FR30_OPERAND_I20 :
1031 value = fields->f_i20;
1033 case FR30_OPERAND_I32 :
1034 value = fields->f_i32;
1036 case FR30_OPERAND_I8 :
1037 value = fields->f_i8;
1039 case FR30_OPERAND_LABEL12 :
1040 value = fields->f_rel12;
1042 case FR30_OPERAND_LABEL9 :
1043 value = fields->f_rel9;
1045 case FR30_OPERAND_M4 :
1046 value = fields->f_m4;
1048 case FR30_OPERAND_PS :
1051 case FR30_OPERAND_REGLIST_HI_LD :
1052 value = fields->f_reglist_hi_ld;
1054 case FR30_OPERAND_REGLIST_HI_ST :
1055 value = fields->f_reglist_hi_st;
1057 case FR30_OPERAND_REGLIST_LOW_LD :
1058 value = fields->f_reglist_low_ld;
1060 case FR30_OPERAND_REGLIST_LOW_ST :
1061 value = fields->f_reglist_low_st;
1063 case FR30_OPERAND_S10 :
1064 value = fields->f_s10;
1066 case FR30_OPERAND_U10 :
1067 value = fields->f_u10;
1069 case FR30_OPERAND_U4 :
1070 value = fields->f_u4;
1072 case FR30_OPERAND_U4C :
1073 value = fields->f_u4c;
1075 case FR30_OPERAND_U8 :
1076 value = fields->f_u8;
1078 case FR30_OPERAND_UDISP6 :
1079 value = fields->f_udisp6;
1083 /* xgettext:c-format */
1084 fprintf (stderr, _("Unrecognized field %d while getting int operand.\n"),
1093 fr30_cgen_get_vma_operand (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
1095 const CGEN_FIELDS * fields)
1101 case FR30_OPERAND_CRI :
1102 value = fields->f_CRi;
1104 case FR30_OPERAND_CRJ :
1105 value = fields->f_CRj;
1107 case FR30_OPERAND_R13 :
1110 case FR30_OPERAND_R14 :
1113 case FR30_OPERAND_R15 :
1116 case FR30_OPERAND_RI :
1117 value = fields->f_Ri;
1119 case FR30_OPERAND_RIC :
1120 value = fields->f_Ric;
1122 case FR30_OPERAND_RJ :
1123 value = fields->f_Rj;
1125 case FR30_OPERAND_RJC :
1126 value = fields->f_Rjc;
1128 case FR30_OPERAND_RS1 :
1129 value = fields->f_Rs1;
1131 case FR30_OPERAND_RS2 :
1132 value = fields->f_Rs2;
1134 case FR30_OPERAND_CC :
1135 value = fields->f_cc;
1137 case FR30_OPERAND_CCC :
1138 value = fields->f_ccc;
1140 case FR30_OPERAND_DIR10 :
1141 value = fields->f_dir10;
1143 case FR30_OPERAND_DIR8 :
1144 value = fields->f_dir8;
1146 case FR30_OPERAND_DIR9 :
1147 value = fields->f_dir9;
1149 case FR30_OPERAND_DISP10 :
1150 value = fields->f_disp10;
1152 case FR30_OPERAND_DISP8 :
1153 value = fields->f_disp8;
1155 case FR30_OPERAND_DISP9 :
1156 value = fields->f_disp9;
1158 case FR30_OPERAND_I20 :
1159 value = fields->f_i20;
1161 case FR30_OPERAND_I32 :
1162 value = fields->f_i32;
1164 case FR30_OPERAND_I8 :
1165 value = fields->f_i8;
1167 case FR30_OPERAND_LABEL12 :
1168 value = fields->f_rel12;
1170 case FR30_OPERAND_LABEL9 :
1171 value = fields->f_rel9;
1173 case FR30_OPERAND_M4 :
1174 value = fields->f_m4;
1176 case FR30_OPERAND_PS :
1179 case FR30_OPERAND_REGLIST_HI_LD :
1180 value = fields->f_reglist_hi_ld;
1182 case FR30_OPERAND_REGLIST_HI_ST :
1183 value = fields->f_reglist_hi_st;
1185 case FR30_OPERAND_REGLIST_LOW_LD :
1186 value = fields->f_reglist_low_ld;
1188 case FR30_OPERAND_REGLIST_LOW_ST :
1189 value = fields->f_reglist_low_st;
1191 case FR30_OPERAND_S10 :
1192 value = fields->f_s10;
1194 case FR30_OPERAND_U10 :
1195 value = fields->f_u10;
1197 case FR30_OPERAND_U4 :
1198 value = fields->f_u4;
1200 case FR30_OPERAND_U4C :
1201 value = fields->f_u4c;
1203 case FR30_OPERAND_U8 :
1204 value = fields->f_u8;
1206 case FR30_OPERAND_UDISP6 :
1207 value = fields->f_udisp6;
1211 /* xgettext:c-format */
1212 fprintf (stderr, _("Unrecognized field %d while getting vma operand.\n"),
1220 void fr30_cgen_set_int_operand (CGEN_CPU_DESC, int, CGEN_FIELDS *, int);
1221 void fr30_cgen_set_vma_operand (CGEN_CPU_DESC, int, CGEN_FIELDS *, bfd_vma);
1223 /* Stuffing values in cgen_fields is handled by a collection of functions.
1224 They are distinguished by the type of the VALUE argument they accept.
1225 TODO: floating point, inlining support, remove cases where argument type
1229 fr30_cgen_set_int_operand (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
1231 CGEN_FIELDS * fields,
1236 case FR30_OPERAND_CRI :
1237 fields->f_CRi = value;
1239 case FR30_OPERAND_CRJ :
1240 fields->f_CRj = value;
1242 case FR30_OPERAND_R13 :
1244 case FR30_OPERAND_R14 :
1246 case FR30_OPERAND_R15 :
1248 case FR30_OPERAND_RI :
1249 fields->f_Ri = value;
1251 case FR30_OPERAND_RIC :
1252 fields->f_Ric = value;
1254 case FR30_OPERAND_RJ :
1255 fields->f_Rj = value;
1257 case FR30_OPERAND_RJC :
1258 fields->f_Rjc = value;
1260 case FR30_OPERAND_RS1 :
1261 fields->f_Rs1 = value;
1263 case FR30_OPERAND_RS2 :
1264 fields->f_Rs2 = value;
1266 case FR30_OPERAND_CC :
1267 fields->f_cc = value;
1269 case FR30_OPERAND_CCC :
1270 fields->f_ccc = value;
1272 case FR30_OPERAND_DIR10 :
1273 fields->f_dir10 = value;
1275 case FR30_OPERAND_DIR8 :
1276 fields->f_dir8 = value;
1278 case FR30_OPERAND_DIR9 :
1279 fields->f_dir9 = value;
1281 case FR30_OPERAND_DISP10 :
1282 fields->f_disp10 = value;
1284 case FR30_OPERAND_DISP8 :
1285 fields->f_disp8 = value;
1287 case FR30_OPERAND_DISP9 :
1288 fields->f_disp9 = value;
1290 case FR30_OPERAND_I20 :
1291 fields->f_i20 = value;
1293 case FR30_OPERAND_I32 :
1294 fields->f_i32 = value;
1296 case FR30_OPERAND_I8 :
1297 fields->f_i8 = value;
1299 case FR30_OPERAND_LABEL12 :
1300 fields->f_rel12 = value;
1302 case FR30_OPERAND_LABEL9 :
1303 fields->f_rel9 = value;
1305 case FR30_OPERAND_M4 :
1306 fields->f_m4 = value;
1308 case FR30_OPERAND_PS :
1310 case FR30_OPERAND_REGLIST_HI_LD :
1311 fields->f_reglist_hi_ld = value;
1313 case FR30_OPERAND_REGLIST_HI_ST :
1314 fields->f_reglist_hi_st = value;
1316 case FR30_OPERAND_REGLIST_LOW_LD :
1317 fields->f_reglist_low_ld = value;
1319 case FR30_OPERAND_REGLIST_LOW_ST :
1320 fields->f_reglist_low_st = value;
1322 case FR30_OPERAND_S10 :
1323 fields->f_s10 = value;
1325 case FR30_OPERAND_U10 :
1326 fields->f_u10 = value;
1328 case FR30_OPERAND_U4 :
1329 fields->f_u4 = value;
1331 case FR30_OPERAND_U4C :
1332 fields->f_u4c = value;
1334 case FR30_OPERAND_U8 :
1335 fields->f_u8 = value;
1337 case FR30_OPERAND_UDISP6 :
1338 fields->f_udisp6 = value;
1342 /* xgettext:c-format */
1343 fprintf (stderr, _("Unrecognized field %d while setting int operand.\n"),
1350 fr30_cgen_set_vma_operand (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
1352 CGEN_FIELDS * fields,
1357 case FR30_OPERAND_CRI :
1358 fields->f_CRi = value;
1360 case FR30_OPERAND_CRJ :
1361 fields->f_CRj = value;
1363 case FR30_OPERAND_R13 :
1365 case FR30_OPERAND_R14 :
1367 case FR30_OPERAND_R15 :
1369 case FR30_OPERAND_RI :
1370 fields->f_Ri = value;
1372 case FR30_OPERAND_RIC :
1373 fields->f_Ric = value;
1375 case FR30_OPERAND_RJ :
1376 fields->f_Rj = value;
1378 case FR30_OPERAND_RJC :
1379 fields->f_Rjc = value;
1381 case FR30_OPERAND_RS1 :
1382 fields->f_Rs1 = value;
1384 case FR30_OPERAND_RS2 :
1385 fields->f_Rs2 = value;
1387 case FR30_OPERAND_CC :
1388 fields->f_cc = value;
1390 case FR30_OPERAND_CCC :
1391 fields->f_ccc = value;
1393 case FR30_OPERAND_DIR10 :
1394 fields->f_dir10 = value;
1396 case FR30_OPERAND_DIR8 :
1397 fields->f_dir8 = value;
1399 case FR30_OPERAND_DIR9 :
1400 fields->f_dir9 = value;
1402 case FR30_OPERAND_DISP10 :
1403 fields->f_disp10 = value;
1405 case FR30_OPERAND_DISP8 :
1406 fields->f_disp8 = value;
1408 case FR30_OPERAND_DISP9 :
1409 fields->f_disp9 = value;
1411 case FR30_OPERAND_I20 :
1412 fields->f_i20 = value;
1414 case FR30_OPERAND_I32 :
1415 fields->f_i32 = value;
1417 case FR30_OPERAND_I8 :
1418 fields->f_i8 = value;
1420 case FR30_OPERAND_LABEL12 :
1421 fields->f_rel12 = value;
1423 case FR30_OPERAND_LABEL9 :
1424 fields->f_rel9 = value;
1426 case FR30_OPERAND_M4 :
1427 fields->f_m4 = value;
1429 case FR30_OPERAND_PS :
1431 case FR30_OPERAND_REGLIST_HI_LD :
1432 fields->f_reglist_hi_ld = value;
1434 case FR30_OPERAND_REGLIST_HI_ST :
1435 fields->f_reglist_hi_st = value;
1437 case FR30_OPERAND_REGLIST_LOW_LD :
1438 fields->f_reglist_low_ld = value;
1440 case FR30_OPERAND_REGLIST_LOW_ST :
1441 fields->f_reglist_low_st = value;
1443 case FR30_OPERAND_S10 :
1444 fields->f_s10 = value;
1446 case FR30_OPERAND_U10 :
1447 fields->f_u10 = value;
1449 case FR30_OPERAND_U4 :
1450 fields->f_u4 = value;
1452 case FR30_OPERAND_U4C :
1453 fields->f_u4c = value;
1455 case FR30_OPERAND_U8 :
1456 fields->f_u8 = value;
1458 case FR30_OPERAND_UDISP6 :
1459 fields->f_udisp6 = value;
1463 /* xgettext:c-format */
1464 fprintf (stderr, _("Unrecognized field %d while setting vma operand.\n"),
1470 /* Function to call before using the instruction builder tables. */
1473 fr30_cgen_init_ibld_table (CGEN_CPU_DESC cd)
1475 cd->insert_handlers = & fr30_cgen_insert_handlers[0];
1476 cd->extract_handlers = & fr30_cgen_extract_handlers[0];
1478 cd->insert_operand = fr30_cgen_insert_operand;
1479 cd->extract_operand = fr30_cgen_extract_operand;
1481 cd->get_int_operand = fr30_cgen_get_int_operand;
1482 cd->set_int_operand = fr30_cgen_set_int_operand;
1483 cd->get_vma_operand = fr30_cgen_get_vma_operand;
1484 cd->set_vma_operand = fr30_cgen_set_vma_operand;