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, 2000 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)
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.
34 #include "fr30-desc.h"
39 #define min(a,b) ((a) < (b) ? (a) : (b))
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
));
60 static void put_insn_int_value
61 PARAMS ((CGEN_CPU_DESC
, CGEN_INSN_BYTES_PTR
, int, int, CGEN_INSN_INT
));
64 /* Operand insertion. */
68 /* Subroutine of insert_normal. */
70 static CGEN_INLINE
void
71 insert_1 (cd
, value
, start
, length
, word_length
, bufp
)
74 int start
,length
,word_length
;
79 int big_p
= CGEN_CPU_INSN_ENDIAN (cd
) == CGEN_ENDIAN_BIG
;
88 x
= bfd_getb16 (bufp
);
90 x
= bfd_getl16 (bufp
);
93 /* ??? This may need reworking as these cases don't necessarily
94 want the first byte and the last two bytes handled like this. */
96 x
= (bufp
[0] << 16) | bfd_getb16 (bufp
+ 1);
98 x
= bfd_getl16 (bufp
) | (bufp
[2] << 16);
102 x
= bfd_getb32 (bufp
);
104 x
= bfd_getl32 (bufp
);
110 /* Written this way to avoid undefined behaviour. */
111 mask
= (((1L << (length
- 1)) - 1) << 1) | 1;
112 if (CGEN_INSN_LSB0_P
)
113 shift
= (start
+ 1) - length
;
115 shift
= (word_length
- (start
+ length
));
116 x
= (x
& ~(mask
<< shift
)) | ((value
& mask
) << shift
);
125 bfd_putb16 (x
, bufp
);
127 bfd_putl16 (x
, bufp
);
130 /* ??? This may need reworking as these cases don't necessarily
131 want the first byte and the last two bytes handled like this. */
135 bfd_putb16 (x
, bufp
+ 1);
139 bfd_putl16 (x
, bufp
);
145 bfd_putb32 (x
, bufp
);
147 bfd_putl32 (x
, bufp
);
154 #endif /* ! CGEN_INT_INSN_P */
156 /* Default insertion routine.
158 ATTRS is a mask of the boolean attributes.
159 WORD_OFFSET is the offset in bits from the start of the insn of the value.
160 WORD_LENGTH is the length of the word in bits in which the value resides.
161 START is the starting bit number in the word, architecture origin.
162 LENGTH is the length of VALUE in bits.
163 TOTAL_LENGTH is the total length of the insn in bits.
165 The result is an error message or NULL if success. */
167 /* ??? This duplicates functionality with bfd's howto table and
168 bfd_install_relocation. */
169 /* ??? This doesn't handle bfd_vma's. Create another function when
173 insert_normal (cd
, value
, attrs
, word_offset
, start
, length
, word_length
,
174 total_length
, buffer
)
178 unsigned int word_offset
, start
, length
, word_length
, total_length
;
179 CGEN_INSN_BYTES_PTR buffer
;
181 static char errbuf
[100];
182 /* Written this way to avoid undefined behaviour. */
183 unsigned long mask
= (((1L << (length
- 1)) - 1) << 1) | 1;
185 /* If LENGTH is zero, this operand doesn't contribute to the value. */
195 if (word_length
> 32)
198 /* For architectures with insns smaller than the base-insn-bitsize,
199 word_length may be too big. */
200 if (cd
->min_insn_bitsize
< cd
->base_insn_bitsize
)
203 && word_length
> total_length
)
204 word_length
= total_length
;
207 /* Ensure VALUE will fit. */
208 if (! CGEN_BOOL_ATTR (attrs
, CGEN_IFLD_SIGNED
))
210 unsigned long maxval
= mask
;
212 if ((unsigned long) value
> maxval
)
214 /* xgettext:c-format */
216 _("operand out of range (%lu not between 0 and %lu)"),
223 if (! cgen_signed_overflow_ok_p (cd
))
225 long minval
= - (1L << (length
- 1));
226 long maxval
= (1L << (length
- 1)) - 1;
228 if (value
< minval
|| value
> maxval
)
231 /* xgettext:c-format */
232 (errbuf
, _("operand out of range (%ld not between %ld and %ld)"),
233 value
, minval
, maxval
);
244 if (CGEN_INSN_LSB0_P
)
245 shift
= (word_offset
+ start
+ 1) - length
;
247 shift
= total_length
- (word_offset
+ start
+ length
);
248 *buffer
= (*buffer
& ~(mask
<< shift
)) | ((value
& mask
) << shift
);
251 #else /* ! CGEN_INT_INSN_P */
254 unsigned char *bufp
= (unsigned char *) buffer
+ word_offset
/ 8;
256 insert_1 (cd
, value
, start
, length
, word_length
, bufp
);
259 #endif /* ! CGEN_INT_INSN_P */
264 /* Default insn builder (insert handler).
265 The instruction is recorded in CGEN_INT_INSN_P byte order
266 (meaning that if CGEN_INT_INSN_P BUFFER is an int * and thus the value is
267 recorded in host byte order, otherwise BUFFER is an array of bytes and the
268 value is recorded in target byte order).
269 The result is an error message or NULL if success. */
272 insert_insn_normal (cd
, insn
, fields
, buffer
, pc
)
274 const CGEN_INSN
* insn
;
275 CGEN_FIELDS
* fields
;
276 CGEN_INSN_BYTES_PTR buffer
;
279 const CGEN_SYNTAX
*syntax
= CGEN_INSN_SYNTAX (insn
);
281 const unsigned char * syn
;
283 CGEN_INIT_INSERT (cd
);
284 value
= CGEN_INSN_BASE_VALUE (insn
);
286 /* If we're recording insns as numbers (rather than a string of bytes),
287 target byte order handling is deferred until later. */
291 put_insn_int_value (cd
, buffer
, cd
->base_insn_bitsize
,
292 CGEN_FIELDS_BITSIZE (fields
), value
);
296 cgen_put_insn_value (cd
, buffer
, min (cd
->base_insn_bitsize
,
297 CGEN_FIELDS_BITSIZE (fields
)),
300 #endif /* ! CGEN_INT_INSN_P */
302 /* ??? It would be better to scan the format's fields.
303 Still need to be able to insert a value based on the operand though;
304 e.g. storing a branch displacement that got resolved later.
305 Needs more thought first. */
307 for (syn
= CGEN_SYNTAX_STRING (syntax
); * syn
!= '\0'; ++ syn
)
311 if (CGEN_SYNTAX_CHAR_P (* syn
))
314 errmsg
= (* cd
->insert_operand
) (cd
, CGEN_SYNTAX_FIELD (*syn
),
323 /* Cover function to store an insn value into an integral insn. Must go here
324 because it needs <prefix>-desc.h for CGEN_INT_INSN_P. */
327 put_insn_int_value (cd
, buf
, length
, insn_length
, value
)
329 CGEN_INSN_BYTES_PTR buf
;
334 /* For architectures with insns smaller than the base-insn-bitsize,
335 length may be too big. */
336 if (length
> insn_length
)
340 int shift
= insn_length
- length
;
341 /* Written this way to avoid undefined behaviour. */
342 CGEN_INSN_INT mask
= (((1L << (length
- 1)) - 1) << 1) | 1;
343 *buf
= (*buf
& ~(mask
<< shift
)) | ((value
& mask
) << shift
);
347 /* Operand extraction. */
349 #if ! CGEN_INT_INSN_P
351 /* Subroutine of extract_normal.
352 Ensure sufficient bytes are cached in EX_INFO.
353 OFFSET is the offset in bytes from the start of the insn of the value.
354 BYTES is the length of the needed value.
355 Returns 1 for success, 0 for failure. */
357 static CGEN_INLINE
int
358 fill_cache (cd
, ex_info
, offset
, bytes
, pc
)
360 CGEN_EXTRACT_INFO
*ex_info
;
364 /* It's doubtful that the middle part has already been fetched so
365 we don't optimize that case. kiss. */
367 disassemble_info
*info
= (disassemble_info
*) ex_info
->dis_info
;
369 /* First do a quick check. */
370 mask
= (1 << bytes
) - 1;
371 if (((ex_info
->valid
>> offset
) & mask
) == mask
)
374 /* Search for the first byte we need to read. */
375 for (mask
= 1 << offset
; bytes
> 0; --bytes
, ++offset
, mask
<<= 1)
376 if (! (mask
& ex_info
->valid
))
384 status
= (*info
->read_memory_func
)
385 (pc
, ex_info
->insn_bytes
+ offset
, bytes
, info
);
389 (*info
->memory_error_func
) (status
, pc
, info
);
393 ex_info
->valid
|= ((1 << bytes
) - 1) << offset
;
399 /* Subroutine of extract_normal. */
401 static CGEN_INLINE
long
402 extract_1 (cd
, ex_info
, start
, length
, word_length
, bufp
, pc
)
404 CGEN_EXTRACT_INFO
*ex_info
;
405 int start
,length
,word_length
;
409 unsigned long x
,mask
;
411 int big_p
= CGEN_CPU_INSN_ENDIAN (cd
) == CGEN_ENDIAN_BIG
;
420 x
= bfd_getb16 (bufp
);
422 x
= bfd_getl16 (bufp
);
425 /* ??? This may need reworking as these cases don't necessarily
426 want the first byte and the last two bytes handled like this. */
428 x
= (bufp
[0] << 16) | bfd_getb16 (bufp
+ 1);
430 x
= bfd_getl16 (bufp
) | (bufp
[2] << 16);
434 x
= bfd_getb32 (bufp
);
436 x
= bfd_getl32 (bufp
);
442 /* Written this way to avoid undefined behaviour. */
443 mask
= (((1L << (length
- 1)) - 1) << 1) | 1;
444 if (CGEN_INSN_LSB0_P
)
445 shift
= (start
+ 1) - length
;
447 shift
= (word_length
- (start
+ length
));
448 return (x
>> shift
) & mask
;
451 #endif /* ! CGEN_INT_INSN_P */
453 /* Default extraction routine.
455 INSN_VALUE is the first base_insn_bitsize bits of the insn in host order,
456 or sometimes less for cases like the m32r where the base insn size is 32
457 but some insns are 16 bits.
458 ATTRS is a mask of the boolean attributes. We only need `SIGNED',
459 but for generality we take a bitmask of all of them.
460 WORD_OFFSET is the offset in bits from the start of the insn of the value.
461 WORD_LENGTH is the length of the word in bits in which the value resides.
462 START is the starting bit number in the word, architecture origin.
463 LENGTH is the length of VALUE in bits.
464 TOTAL_LENGTH is the total length of the insn in bits.
466 Returns 1 for success, 0 for failure. */
468 /* ??? The return code isn't properly used. wip. */
470 /* ??? This doesn't handle bfd_vma's. Create another function when
474 extract_normal (cd
, ex_info
, insn_value
, attrs
, word_offset
, start
, length
,
475 word_length
, total_length
, pc
, valuep
)
477 #if ! CGEN_INT_INSN_P
478 CGEN_EXTRACT_INFO
*ex_info
;
480 CGEN_EXTRACT_INFO
*ex_info ATTRIBUTE_UNUSED
;
482 CGEN_INSN_INT insn_value
;
484 unsigned int word_offset
, start
, length
, word_length
, total_length
;
485 #if ! CGEN_INT_INSN_P
488 bfd_vma pc ATTRIBUTE_UNUSED
;
494 /* If LENGTH is zero, this operand doesn't contribute to the value
495 so give it a standard value of zero. */
508 if (word_length
> 32)
511 /* For architectures with insns smaller than the insn-base-bitsize,
512 word_length may be too big. */
513 if (cd
->min_insn_bitsize
< cd
->base_insn_bitsize
)
516 && word_length
> total_length
)
517 word_length
= total_length
;
520 /* Does the value reside in INSN_VALUE? */
522 if (CGEN_INT_INSN_P
|| word_offset
== 0)
524 /* Written this way to avoid undefined behaviour. */
525 CGEN_INSN_INT mask
= (((1L << (length
- 1)) - 1) << 1) | 1;
527 if (CGEN_INSN_LSB0_P
)
528 value
= insn_value
>> ((word_offset
+ start
+ 1) - length
);
530 value
= insn_value
>> (total_length
- ( word_offset
+ start
+ length
));
533 if (CGEN_BOOL_ATTR (attrs
, CGEN_IFLD_SIGNED
)
534 && (value
& (1L << (length
- 1))))
538 #if ! CGEN_INT_INSN_P
542 unsigned char *bufp
= ex_info
->insn_bytes
+ word_offset
/ 8;
544 if (word_length
> 32)
547 if (fill_cache (cd
, ex_info
, word_offset
/ 8, word_length
/ 8, pc
) == 0)
550 value
= extract_1 (cd
, ex_info
, start
, length
, word_length
, bufp
, pc
);
553 #endif /* ! CGEN_INT_INSN_P */
560 /* Default insn extractor.
562 INSN_VALUE is the first base_insn_bitsize bits, translated to host order.
563 The extracted fields are stored in FIELDS.
564 EX_INFO is used to handle reading variable length insns.
565 Return the length of the insn in bits, or 0 if no match,
566 or -1 if an error occurs fetching data (memory_error_func will have
570 extract_insn_normal (cd
, insn
, ex_info
, insn_value
, fields
, pc
)
572 const CGEN_INSN
*insn
;
573 CGEN_EXTRACT_INFO
*ex_info
;
574 CGEN_INSN_INT insn_value
;
578 const CGEN_SYNTAX
*syntax
= CGEN_INSN_SYNTAX (insn
);
579 const unsigned char *syn
;
581 CGEN_FIELDS_BITSIZE (fields
) = CGEN_INSN_BITSIZE (insn
);
583 CGEN_INIT_EXTRACT (cd
);
585 for (syn
= CGEN_SYNTAX_STRING (syntax
); *syn
; ++syn
)
589 if (CGEN_SYNTAX_CHAR_P (*syn
))
592 length
= (* cd
->extract_operand
) (cd
, CGEN_SYNTAX_FIELD (*syn
),
593 ex_info
, insn_value
, fields
, pc
);
598 /* We recognized and successfully extracted this insn. */
599 return CGEN_INSN_BITSIZE (insn
);
602 /* machine generated code added here */
604 /* Main entry point for operand insertion.
606 This function is basically just a big switch statement. Earlier versions
607 used tables to look up the function to use, but
608 - if the table contains both assembler and disassembler functions then
609 the disassembler contains much of the assembler and vice-versa,
610 - there's a lot of inlining possibilities as things grow,
611 - using a switch statement avoids the function call overhead.
613 This function could be moved into `parse_insn_normal', but keeping it
614 separate makes clear the interface between `parse_insn_normal' and each of
615 the handlers. It's also needed by GAS to insert operands that couldn't be
616 resolved during parsing.
620 fr30_cgen_insert_operand (cd
, opindex
, fields
, buffer
, pc
)
623 CGEN_FIELDS
* fields
;
624 CGEN_INSN_BYTES_PTR buffer
;
627 const char * errmsg
= NULL
;
628 unsigned int total_length
= CGEN_FIELDS_BITSIZE (fields
);
632 case FR30_OPERAND_CRI
:
633 errmsg
= insert_normal (cd
, fields
->f_CRi
, 0, 16, 12, 4, 16, total_length
, buffer
);
635 case FR30_OPERAND_CRJ
:
636 errmsg
= insert_normal (cd
, fields
->f_CRj
, 0, 16, 8, 4, 16, total_length
, buffer
);
638 case FR30_OPERAND_R13
:
640 case FR30_OPERAND_R14
:
642 case FR30_OPERAND_R15
:
644 case FR30_OPERAND_RI
:
645 errmsg
= insert_normal (cd
, fields
->f_Ri
, 0, 0, 12, 4, 16, total_length
, buffer
);
647 case FR30_OPERAND_RIC
:
648 errmsg
= insert_normal (cd
, fields
->f_Ric
, 0, 16, 12, 4, 16, total_length
, buffer
);
650 case FR30_OPERAND_RJ
:
651 errmsg
= insert_normal (cd
, fields
->f_Rj
, 0, 0, 8, 4, 16, total_length
, buffer
);
653 case FR30_OPERAND_RJC
:
654 errmsg
= insert_normal (cd
, fields
->f_Rjc
, 0, 16, 8, 4, 16, total_length
, buffer
);
656 case FR30_OPERAND_RS1
:
657 errmsg
= insert_normal (cd
, fields
->f_Rs1
, 0, 0, 8, 4, 16, total_length
, buffer
);
659 case FR30_OPERAND_RS2
:
660 errmsg
= insert_normal (cd
, fields
->f_Rs2
, 0, 0, 12, 4, 16, total_length
, buffer
);
662 case FR30_OPERAND_CC
:
663 errmsg
= insert_normal (cd
, fields
->f_cc
, 0, 0, 4, 4, 16, total_length
, buffer
);
665 case FR30_OPERAND_CCC
:
666 errmsg
= insert_normal (cd
, fields
->f_ccc
, 0, 16, 0, 8, 16, total_length
, buffer
);
668 case FR30_OPERAND_DIR10
:
670 long value
= fields
->f_dir10
;
671 value
= ((unsigned int) (value
) >> (2));
672 errmsg
= insert_normal (cd
, value
, 0, 0, 8, 8, 16, total_length
, buffer
);
675 case FR30_OPERAND_DIR8
:
676 errmsg
= insert_normal (cd
, fields
->f_dir8
, 0, 0, 8, 8, 16, total_length
, buffer
);
678 case FR30_OPERAND_DIR9
:
680 long value
= fields
->f_dir9
;
681 value
= ((unsigned int) (value
) >> (1));
682 errmsg
= insert_normal (cd
, value
, 0, 0, 8, 8, 16, total_length
, buffer
);
685 case FR30_OPERAND_DISP10
:
687 long value
= fields
->f_disp10
;
688 value
= ((int) (value
) >> (2));
689 errmsg
= insert_normal (cd
, value
, 0|(1<<CGEN_IFLD_SIGNED
), 0, 4, 8, 16, total_length
, buffer
);
692 case FR30_OPERAND_DISP8
:
693 errmsg
= insert_normal (cd
, fields
->f_disp8
, 0|(1<<CGEN_IFLD_SIGNED
), 0, 4, 8, 16, total_length
, buffer
);
695 case FR30_OPERAND_DISP9
:
697 long value
= fields
->f_disp9
;
698 value
= ((int) (value
) >> (1));
699 errmsg
= insert_normal (cd
, value
, 0|(1<<CGEN_IFLD_SIGNED
), 0, 4, 8, 16, total_length
, buffer
);
702 case FR30_OPERAND_I20
:
705 FLD (f_i20_4
) = ((unsigned int) (FLD (f_i20
)) >> (16));
706 FLD (f_i20_16
) = ((FLD (f_i20
)) & (65535));
708 errmsg
= insert_normal (cd
, fields
->f_i20_4
, 0, 0, 8, 4, 16, total_length
, buffer
);
711 errmsg
= insert_normal (cd
, fields
->f_i20_16
, 0, 16, 0, 16, 16, total_length
, buffer
);
716 case FR30_OPERAND_I32
:
717 errmsg
= insert_normal (cd
, fields
->f_i32
, 0|(1<<CGEN_IFLD_SIGN_OPT
), 16, 0, 32, 32, total_length
, buffer
);
719 case FR30_OPERAND_I8
:
720 errmsg
= insert_normal (cd
, fields
->f_i8
, 0, 0, 4, 8, 16, total_length
, buffer
);
722 case FR30_OPERAND_LABEL12
:
724 long value
= fields
->f_rel12
;
725 value
= ((int) (((value
) - (((pc
) + (2))))) >> (1));
726 errmsg
= insert_normal (cd
, value
, 0|(1<<CGEN_IFLD_SIGNED
)|(1<<CGEN_IFLD_PCREL_ADDR
), 0, 5, 11, 16, total_length
, buffer
);
729 case FR30_OPERAND_LABEL9
:
731 long value
= fields
->f_rel9
;
732 value
= ((int) (((value
) - (((pc
) + (2))))) >> (1));
733 errmsg
= insert_normal (cd
, value
, 0|(1<<CGEN_IFLD_SIGNED
)|(1<<CGEN_IFLD_PCREL_ADDR
), 0, 8, 8, 16, total_length
, buffer
);
736 case FR30_OPERAND_M4
:
738 long value
= fields
->f_m4
;
739 value
= ((value
) & (15));
740 errmsg
= insert_normal (cd
, value
, 0, 0, 8, 4, 16, total_length
, buffer
);
743 case FR30_OPERAND_PS
:
745 case FR30_OPERAND_REGLIST_HI_LD
:
746 errmsg
= insert_normal (cd
, fields
->f_reglist_hi_ld
, 0, 0, 8, 8, 16, total_length
, buffer
);
748 case FR30_OPERAND_REGLIST_HI_ST
:
749 errmsg
= insert_normal (cd
, fields
->f_reglist_hi_st
, 0, 0, 8, 8, 16, total_length
, buffer
);
751 case FR30_OPERAND_REGLIST_LOW_LD
:
752 errmsg
= insert_normal (cd
, fields
->f_reglist_low_ld
, 0, 0, 8, 8, 16, total_length
, buffer
);
754 case FR30_OPERAND_REGLIST_LOW_ST
:
755 errmsg
= insert_normal (cd
, fields
->f_reglist_low_st
, 0, 0, 8, 8, 16, total_length
, buffer
);
757 case FR30_OPERAND_S10
:
759 long value
= fields
->f_s10
;
760 value
= ((int) (value
) >> (2));
761 errmsg
= insert_normal (cd
, value
, 0|(1<<CGEN_IFLD_SIGNED
), 0, 8, 8, 16, total_length
, buffer
);
764 case FR30_OPERAND_U10
:
766 long value
= fields
->f_u10
;
767 value
= ((unsigned int) (value
) >> (2));
768 errmsg
= insert_normal (cd
, value
, 0, 0, 8, 8, 16, total_length
, buffer
);
771 case FR30_OPERAND_U4
:
772 errmsg
= insert_normal (cd
, fields
->f_u4
, 0, 0, 8, 4, 16, total_length
, buffer
);
774 case FR30_OPERAND_U4C
:
775 errmsg
= insert_normal (cd
, fields
->f_u4c
, 0, 0, 12, 4, 16, total_length
, buffer
);
777 case FR30_OPERAND_U8
:
778 errmsg
= insert_normal (cd
, fields
->f_u8
, 0, 0, 8, 8, 16, total_length
, buffer
);
780 case FR30_OPERAND_UDISP6
:
782 long value
= fields
->f_udisp6
;
783 value
= ((unsigned int) (value
) >> (2));
784 errmsg
= insert_normal (cd
, value
, 0, 0, 8, 4, 16, total_length
, buffer
);
789 /* xgettext:c-format */
790 fprintf (stderr
, _("Unrecognized field %d while building insn.\n"),
798 /* Main entry point for operand extraction.
799 The result is <= 0 for error, >0 for success.
800 ??? Actual values aren't well defined right now.
802 This function is basically just a big switch statement. Earlier versions
803 used tables to look up the function to use, but
804 - if the table contains both assembler and disassembler functions then
805 the disassembler contains much of the assembler and vice-versa,
806 - there's a lot of inlining possibilities as things grow,
807 - using a switch statement avoids the function call overhead.
809 This function could be moved into `print_insn_normal', but keeping it
810 separate makes clear the interface between `print_insn_normal' and each of
815 fr30_cgen_extract_operand (cd
, opindex
, ex_info
, insn_value
, fields
, pc
)
818 CGEN_EXTRACT_INFO
*ex_info
;
819 CGEN_INSN_INT insn_value
;
820 CGEN_FIELDS
* fields
;
823 /* Assume success (for those operands that are nops). */
825 unsigned int total_length
= CGEN_FIELDS_BITSIZE (fields
);
829 case FR30_OPERAND_CRI
:
830 length
= extract_normal (cd
, ex_info
, insn_value
, 0, 16, 12, 4, 16, total_length
, pc
, & fields
->f_CRi
);
832 case FR30_OPERAND_CRJ
:
833 length
= extract_normal (cd
, ex_info
, insn_value
, 0, 16, 8, 4, 16, total_length
, pc
, & fields
->f_CRj
);
835 case FR30_OPERAND_R13
:
837 case FR30_OPERAND_R14
:
839 case FR30_OPERAND_R15
:
841 case FR30_OPERAND_RI
:
842 length
= extract_normal (cd
, ex_info
, insn_value
, 0, 0, 12, 4, 16, total_length
, pc
, & fields
->f_Ri
);
844 case FR30_OPERAND_RIC
:
845 length
= extract_normal (cd
, ex_info
, insn_value
, 0, 16, 12, 4, 16, total_length
, pc
, & fields
->f_Ric
);
847 case FR30_OPERAND_RJ
:
848 length
= extract_normal (cd
, ex_info
, insn_value
, 0, 0, 8, 4, 16, total_length
, pc
, & fields
->f_Rj
);
850 case FR30_OPERAND_RJC
:
851 length
= extract_normal (cd
, ex_info
, insn_value
, 0, 16, 8, 4, 16, total_length
, pc
, & fields
->f_Rjc
);
853 case FR30_OPERAND_RS1
:
854 length
= extract_normal (cd
, ex_info
, insn_value
, 0, 0, 8, 4, 16, total_length
, pc
, & fields
->f_Rs1
);
856 case FR30_OPERAND_RS2
:
857 length
= extract_normal (cd
, ex_info
, insn_value
, 0, 0, 12, 4, 16, total_length
, pc
, & fields
->f_Rs2
);
859 case FR30_OPERAND_CC
:
860 length
= extract_normal (cd
, ex_info
, insn_value
, 0, 0, 4, 4, 16, total_length
, pc
, & fields
->f_cc
);
862 case FR30_OPERAND_CCC
:
863 length
= extract_normal (cd
, ex_info
, insn_value
, 0, 16, 0, 8, 16, total_length
, pc
, & fields
->f_ccc
);
865 case FR30_OPERAND_DIR10
:
868 length
= extract_normal (cd
, ex_info
, insn_value
, 0, 0, 8, 8, 16, total_length
, pc
, & value
);
869 value
= ((value
) << (2));
870 fields
->f_dir10
= value
;
873 case FR30_OPERAND_DIR8
:
874 length
= extract_normal (cd
, ex_info
, insn_value
, 0, 0, 8, 8, 16, total_length
, pc
, & fields
->f_dir8
);
876 case FR30_OPERAND_DIR9
:
879 length
= extract_normal (cd
, ex_info
, insn_value
, 0, 0, 8, 8, 16, total_length
, pc
, & value
);
880 value
= ((value
) << (1));
881 fields
->f_dir9
= value
;
884 case FR30_OPERAND_DISP10
:
887 length
= extract_normal (cd
, ex_info
, insn_value
, 0|(1<<CGEN_IFLD_SIGNED
), 0, 4, 8, 16, total_length
, pc
, & value
);
888 value
= ((value
) << (2));
889 fields
->f_disp10
= value
;
892 case FR30_OPERAND_DISP8
:
893 length
= extract_normal (cd
, ex_info
, insn_value
, 0|(1<<CGEN_IFLD_SIGNED
), 0, 4, 8, 16, total_length
, pc
, & fields
->f_disp8
);
895 case FR30_OPERAND_DISP9
:
898 length
= extract_normal (cd
, ex_info
, insn_value
, 0|(1<<CGEN_IFLD_SIGNED
), 0, 4, 8, 16, total_length
, pc
, & value
);
899 value
= ((value
) << (1));
900 fields
->f_disp9
= value
;
903 case FR30_OPERAND_I20
:
905 length
= extract_normal (cd
, ex_info
, insn_value
, 0, 0, 8, 4, 16, total_length
, pc
, & fields
->f_i20_4
);
906 if (length
<= 0) break;
907 length
= extract_normal (cd
, ex_info
, insn_value
, 0, 16, 0, 16, 16, total_length
, pc
, & fields
->f_i20_16
);
908 if (length
<= 0) break;
910 FLD (f_i20
) = ((((FLD (f_i20_4
)) << (16))) | (FLD (f_i20_16
)));
914 case FR30_OPERAND_I32
:
915 length
= extract_normal (cd
, ex_info
, insn_value
, 0|(1<<CGEN_IFLD_SIGN_OPT
), 16, 0, 32, 32, total_length
, pc
, & fields
->f_i32
);
917 case FR30_OPERAND_I8
:
918 length
= extract_normal (cd
, ex_info
, insn_value
, 0, 0, 4, 8, 16, total_length
, pc
, & fields
->f_i8
);
920 case FR30_OPERAND_LABEL12
:
923 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
);
924 value
= ((((value
) << (1))) + (((pc
) + (2))));
925 fields
->f_rel12
= value
;
928 case FR30_OPERAND_LABEL9
:
931 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
);
932 value
= ((((value
) << (1))) + (((pc
) + (2))));
933 fields
->f_rel9
= value
;
936 case FR30_OPERAND_M4
:
939 length
= extract_normal (cd
, ex_info
, insn_value
, 0, 0, 8, 4, 16, total_length
, pc
, & value
);
940 value
= ((value
) | (((-1) << (4))));
941 fields
->f_m4
= value
;
944 case FR30_OPERAND_PS
:
946 case FR30_OPERAND_REGLIST_HI_LD
:
947 length
= extract_normal (cd
, ex_info
, insn_value
, 0, 0, 8, 8, 16, total_length
, pc
, & fields
->f_reglist_hi_ld
);
949 case FR30_OPERAND_REGLIST_HI_ST
:
950 length
= extract_normal (cd
, ex_info
, insn_value
, 0, 0, 8, 8, 16, total_length
, pc
, & fields
->f_reglist_hi_st
);
952 case FR30_OPERAND_REGLIST_LOW_LD
:
953 length
= extract_normal (cd
, ex_info
, insn_value
, 0, 0, 8, 8, 16, total_length
, pc
, & fields
->f_reglist_low_ld
);
955 case FR30_OPERAND_REGLIST_LOW_ST
:
956 length
= extract_normal (cd
, ex_info
, insn_value
, 0, 0, 8, 8, 16, total_length
, pc
, & fields
->f_reglist_low_st
);
958 case FR30_OPERAND_S10
:
961 length
= extract_normal (cd
, ex_info
, insn_value
, 0|(1<<CGEN_IFLD_SIGNED
), 0, 8, 8, 16, total_length
, pc
, & value
);
962 value
= ((value
) << (2));
963 fields
->f_s10
= value
;
966 case FR30_OPERAND_U10
:
969 length
= extract_normal (cd
, ex_info
, insn_value
, 0, 0, 8, 8, 16, total_length
, pc
, & value
);
970 value
= ((value
) << (2));
971 fields
->f_u10
= value
;
974 case FR30_OPERAND_U4
:
975 length
= extract_normal (cd
, ex_info
, insn_value
, 0, 0, 8, 4, 16, total_length
, pc
, & fields
->f_u4
);
977 case FR30_OPERAND_U4C
:
978 length
= extract_normal (cd
, ex_info
, insn_value
, 0, 0, 12, 4, 16, total_length
, pc
, & fields
->f_u4c
);
980 case FR30_OPERAND_U8
:
981 length
= extract_normal (cd
, ex_info
, insn_value
, 0, 0, 8, 8, 16, total_length
, pc
, & fields
->f_u8
);
983 case FR30_OPERAND_UDISP6
:
986 length
= extract_normal (cd
, ex_info
, insn_value
, 0, 0, 8, 4, 16, total_length
, pc
, & value
);
987 value
= ((value
) << (2));
988 fields
->f_udisp6
= value
;
993 /* xgettext:c-format */
994 fprintf (stderr
, _("Unrecognized field %d while decoding insn.\n"),
1002 cgen_insert_fn
* const fr30_cgen_insert_handlers
[] =
1007 cgen_extract_fn
* const fr30_cgen_extract_handlers
[] =
1009 extract_insn_normal
,
1012 /* Getting values from cgen_fields is handled by a collection of functions.
1013 They are distinguished by the type of the VALUE argument they return.
1014 TODO: floating point, inlining support, remove cases where result type
1018 fr30_cgen_get_int_operand (cd
, opindex
, fields
)
1021 const CGEN_FIELDS
* fields
;
1027 case FR30_OPERAND_CRI
:
1028 value
= fields
->f_CRi
;
1030 case FR30_OPERAND_CRJ
:
1031 value
= fields
->f_CRj
;
1033 case FR30_OPERAND_R13
:
1036 case FR30_OPERAND_R14
:
1039 case FR30_OPERAND_R15
:
1042 case FR30_OPERAND_RI
:
1043 value
= fields
->f_Ri
;
1045 case FR30_OPERAND_RIC
:
1046 value
= fields
->f_Ric
;
1048 case FR30_OPERAND_RJ
:
1049 value
= fields
->f_Rj
;
1051 case FR30_OPERAND_RJC
:
1052 value
= fields
->f_Rjc
;
1054 case FR30_OPERAND_RS1
:
1055 value
= fields
->f_Rs1
;
1057 case FR30_OPERAND_RS2
:
1058 value
= fields
->f_Rs2
;
1060 case FR30_OPERAND_CC
:
1061 value
= fields
->f_cc
;
1063 case FR30_OPERAND_CCC
:
1064 value
= fields
->f_ccc
;
1066 case FR30_OPERAND_DIR10
:
1067 value
= fields
->f_dir10
;
1069 case FR30_OPERAND_DIR8
:
1070 value
= fields
->f_dir8
;
1072 case FR30_OPERAND_DIR9
:
1073 value
= fields
->f_dir9
;
1075 case FR30_OPERAND_DISP10
:
1076 value
= fields
->f_disp10
;
1078 case FR30_OPERAND_DISP8
:
1079 value
= fields
->f_disp8
;
1081 case FR30_OPERAND_DISP9
:
1082 value
= fields
->f_disp9
;
1084 case FR30_OPERAND_I20
:
1085 value
= fields
->f_i20
;
1087 case FR30_OPERAND_I32
:
1088 value
= fields
->f_i32
;
1090 case FR30_OPERAND_I8
:
1091 value
= fields
->f_i8
;
1093 case FR30_OPERAND_LABEL12
:
1094 value
= fields
->f_rel12
;
1096 case FR30_OPERAND_LABEL9
:
1097 value
= fields
->f_rel9
;
1099 case FR30_OPERAND_M4
:
1100 value
= fields
->f_m4
;
1102 case FR30_OPERAND_PS
:
1105 case FR30_OPERAND_REGLIST_HI_LD
:
1106 value
= fields
->f_reglist_hi_ld
;
1108 case FR30_OPERAND_REGLIST_HI_ST
:
1109 value
= fields
->f_reglist_hi_st
;
1111 case FR30_OPERAND_REGLIST_LOW_LD
:
1112 value
= fields
->f_reglist_low_ld
;
1114 case FR30_OPERAND_REGLIST_LOW_ST
:
1115 value
= fields
->f_reglist_low_st
;
1117 case FR30_OPERAND_S10
:
1118 value
= fields
->f_s10
;
1120 case FR30_OPERAND_U10
:
1121 value
= fields
->f_u10
;
1123 case FR30_OPERAND_U4
:
1124 value
= fields
->f_u4
;
1126 case FR30_OPERAND_U4C
:
1127 value
= fields
->f_u4c
;
1129 case FR30_OPERAND_U8
:
1130 value
= fields
->f_u8
;
1132 case FR30_OPERAND_UDISP6
:
1133 value
= fields
->f_udisp6
;
1137 /* xgettext:c-format */
1138 fprintf (stderr
, _("Unrecognized field %d while getting int operand.\n"),
1147 fr30_cgen_get_vma_operand (cd
, opindex
, fields
)
1150 const CGEN_FIELDS
* fields
;
1156 case FR30_OPERAND_CRI
:
1157 value
= fields
->f_CRi
;
1159 case FR30_OPERAND_CRJ
:
1160 value
= fields
->f_CRj
;
1162 case FR30_OPERAND_R13
:
1165 case FR30_OPERAND_R14
:
1168 case FR30_OPERAND_R15
:
1171 case FR30_OPERAND_RI
:
1172 value
= fields
->f_Ri
;
1174 case FR30_OPERAND_RIC
:
1175 value
= fields
->f_Ric
;
1177 case FR30_OPERAND_RJ
:
1178 value
= fields
->f_Rj
;
1180 case FR30_OPERAND_RJC
:
1181 value
= fields
->f_Rjc
;
1183 case FR30_OPERAND_RS1
:
1184 value
= fields
->f_Rs1
;
1186 case FR30_OPERAND_RS2
:
1187 value
= fields
->f_Rs2
;
1189 case FR30_OPERAND_CC
:
1190 value
= fields
->f_cc
;
1192 case FR30_OPERAND_CCC
:
1193 value
= fields
->f_ccc
;
1195 case FR30_OPERAND_DIR10
:
1196 value
= fields
->f_dir10
;
1198 case FR30_OPERAND_DIR8
:
1199 value
= fields
->f_dir8
;
1201 case FR30_OPERAND_DIR9
:
1202 value
= fields
->f_dir9
;
1204 case FR30_OPERAND_DISP10
:
1205 value
= fields
->f_disp10
;
1207 case FR30_OPERAND_DISP8
:
1208 value
= fields
->f_disp8
;
1210 case FR30_OPERAND_DISP9
:
1211 value
= fields
->f_disp9
;
1213 case FR30_OPERAND_I20
:
1214 value
= fields
->f_i20
;
1216 case FR30_OPERAND_I32
:
1217 value
= fields
->f_i32
;
1219 case FR30_OPERAND_I8
:
1220 value
= fields
->f_i8
;
1222 case FR30_OPERAND_LABEL12
:
1223 value
= fields
->f_rel12
;
1225 case FR30_OPERAND_LABEL9
:
1226 value
= fields
->f_rel9
;
1228 case FR30_OPERAND_M4
:
1229 value
= fields
->f_m4
;
1231 case FR30_OPERAND_PS
:
1234 case FR30_OPERAND_REGLIST_HI_LD
:
1235 value
= fields
->f_reglist_hi_ld
;
1237 case FR30_OPERAND_REGLIST_HI_ST
:
1238 value
= fields
->f_reglist_hi_st
;
1240 case FR30_OPERAND_REGLIST_LOW_LD
:
1241 value
= fields
->f_reglist_low_ld
;
1243 case FR30_OPERAND_REGLIST_LOW_ST
:
1244 value
= fields
->f_reglist_low_st
;
1246 case FR30_OPERAND_S10
:
1247 value
= fields
->f_s10
;
1249 case FR30_OPERAND_U10
:
1250 value
= fields
->f_u10
;
1252 case FR30_OPERAND_U4
:
1253 value
= fields
->f_u4
;
1255 case FR30_OPERAND_U4C
:
1256 value
= fields
->f_u4c
;
1258 case FR30_OPERAND_U8
:
1259 value
= fields
->f_u8
;
1261 case FR30_OPERAND_UDISP6
:
1262 value
= fields
->f_udisp6
;
1266 /* xgettext:c-format */
1267 fprintf (stderr
, _("Unrecognized field %d while getting vma operand.\n"),
1275 /* Stuffing values in cgen_fields is handled by a collection of functions.
1276 They are distinguished by the type of the VALUE argument they accept.
1277 TODO: floating point, inlining support, remove cases where argument type
1281 fr30_cgen_set_int_operand (cd
, opindex
, fields
, value
)
1284 CGEN_FIELDS
* fields
;
1289 case FR30_OPERAND_CRI
:
1290 fields
->f_CRi
= value
;
1292 case FR30_OPERAND_CRJ
:
1293 fields
->f_CRj
= value
;
1295 case FR30_OPERAND_R13
:
1297 case FR30_OPERAND_R14
:
1299 case FR30_OPERAND_R15
:
1301 case FR30_OPERAND_RI
:
1302 fields
->f_Ri
= value
;
1304 case FR30_OPERAND_RIC
:
1305 fields
->f_Ric
= value
;
1307 case FR30_OPERAND_RJ
:
1308 fields
->f_Rj
= value
;
1310 case FR30_OPERAND_RJC
:
1311 fields
->f_Rjc
= value
;
1313 case FR30_OPERAND_RS1
:
1314 fields
->f_Rs1
= value
;
1316 case FR30_OPERAND_RS2
:
1317 fields
->f_Rs2
= value
;
1319 case FR30_OPERAND_CC
:
1320 fields
->f_cc
= value
;
1322 case FR30_OPERAND_CCC
:
1323 fields
->f_ccc
= value
;
1325 case FR30_OPERAND_DIR10
:
1326 fields
->f_dir10
= value
;
1328 case FR30_OPERAND_DIR8
:
1329 fields
->f_dir8
= value
;
1331 case FR30_OPERAND_DIR9
:
1332 fields
->f_dir9
= value
;
1334 case FR30_OPERAND_DISP10
:
1335 fields
->f_disp10
= value
;
1337 case FR30_OPERAND_DISP8
:
1338 fields
->f_disp8
= value
;
1340 case FR30_OPERAND_DISP9
:
1341 fields
->f_disp9
= value
;
1343 case FR30_OPERAND_I20
:
1344 fields
->f_i20
= value
;
1346 case FR30_OPERAND_I32
:
1347 fields
->f_i32
= value
;
1349 case FR30_OPERAND_I8
:
1350 fields
->f_i8
= value
;
1352 case FR30_OPERAND_LABEL12
:
1353 fields
->f_rel12
= value
;
1355 case FR30_OPERAND_LABEL9
:
1356 fields
->f_rel9
= value
;
1358 case FR30_OPERAND_M4
:
1359 fields
->f_m4
= value
;
1361 case FR30_OPERAND_PS
:
1363 case FR30_OPERAND_REGLIST_HI_LD
:
1364 fields
->f_reglist_hi_ld
= value
;
1366 case FR30_OPERAND_REGLIST_HI_ST
:
1367 fields
->f_reglist_hi_st
= value
;
1369 case FR30_OPERAND_REGLIST_LOW_LD
:
1370 fields
->f_reglist_low_ld
= value
;
1372 case FR30_OPERAND_REGLIST_LOW_ST
:
1373 fields
->f_reglist_low_st
= value
;
1375 case FR30_OPERAND_S10
:
1376 fields
->f_s10
= value
;
1378 case FR30_OPERAND_U10
:
1379 fields
->f_u10
= value
;
1381 case FR30_OPERAND_U4
:
1382 fields
->f_u4
= value
;
1384 case FR30_OPERAND_U4C
:
1385 fields
->f_u4c
= value
;
1387 case FR30_OPERAND_U8
:
1388 fields
->f_u8
= value
;
1390 case FR30_OPERAND_UDISP6
:
1391 fields
->f_udisp6
= value
;
1395 /* xgettext:c-format */
1396 fprintf (stderr
, _("Unrecognized field %d while setting int operand.\n"),
1403 fr30_cgen_set_vma_operand (cd
, opindex
, fields
, value
)
1406 CGEN_FIELDS
* fields
;
1411 case FR30_OPERAND_CRI
:
1412 fields
->f_CRi
= value
;
1414 case FR30_OPERAND_CRJ
:
1415 fields
->f_CRj
= value
;
1417 case FR30_OPERAND_R13
:
1419 case FR30_OPERAND_R14
:
1421 case FR30_OPERAND_R15
:
1423 case FR30_OPERAND_RI
:
1424 fields
->f_Ri
= value
;
1426 case FR30_OPERAND_RIC
:
1427 fields
->f_Ric
= value
;
1429 case FR30_OPERAND_RJ
:
1430 fields
->f_Rj
= value
;
1432 case FR30_OPERAND_RJC
:
1433 fields
->f_Rjc
= value
;
1435 case FR30_OPERAND_RS1
:
1436 fields
->f_Rs1
= value
;
1438 case FR30_OPERAND_RS2
:
1439 fields
->f_Rs2
= value
;
1441 case FR30_OPERAND_CC
:
1442 fields
->f_cc
= value
;
1444 case FR30_OPERAND_CCC
:
1445 fields
->f_ccc
= value
;
1447 case FR30_OPERAND_DIR10
:
1448 fields
->f_dir10
= value
;
1450 case FR30_OPERAND_DIR8
:
1451 fields
->f_dir8
= value
;
1453 case FR30_OPERAND_DIR9
:
1454 fields
->f_dir9
= value
;
1456 case FR30_OPERAND_DISP10
:
1457 fields
->f_disp10
= value
;
1459 case FR30_OPERAND_DISP8
:
1460 fields
->f_disp8
= value
;
1462 case FR30_OPERAND_DISP9
:
1463 fields
->f_disp9
= value
;
1465 case FR30_OPERAND_I20
:
1466 fields
->f_i20
= value
;
1468 case FR30_OPERAND_I32
:
1469 fields
->f_i32
= value
;
1471 case FR30_OPERAND_I8
:
1472 fields
->f_i8
= value
;
1474 case FR30_OPERAND_LABEL12
:
1475 fields
->f_rel12
= value
;
1477 case FR30_OPERAND_LABEL9
:
1478 fields
->f_rel9
= value
;
1480 case FR30_OPERAND_M4
:
1481 fields
->f_m4
= value
;
1483 case FR30_OPERAND_PS
:
1485 case FR30_OPERAND_REGLIST_HI_LD
:
1486 fields
->f_reglist_hi_ld
= value
;
1488 case FR30_OPERAND_REGLIST_HI_ST
:
1489 fields
->f_reglist_hi_st
= value
;
1491 case FR30_OPERAND_REGLIST_LOW_LD
:
1492 fields
->f_reglist_low_ld
= value
;
1494 case FR30_OPERAND_REGLIST_LOW_ST
:
1495 fields
->f_reglist_low_st
= value
;
1497 case FR30_OPERAND_S10
:
1498 fields
->f_s10
= value
;
1500 case FR30_OPERAND_U10
:
1501 fields
->f_u10
= value
;
1503 case FR30_OPERAND_U4
:
1504 fields
->f_u4
= value
;
1506 case FR30_OPERAND_U4C
:
1507 fields
->f_u4c
= value
;
1509 case FR30_OPERAND_U8
:
1510 fields
->f_u8
= value
;
1512 case FR30_OPERAND_UDISP6
:
1513 fields
->f_udisp6
= value
;
1517 /* xgettext:c-format */
1518 fprintf (stderr
, _("Unrecognized field %d while setting vma operand.\n"),
1524 /* Function to call before using the instruction builder tables. */
1527 fr30_cgen_init_ibld_table (cd
)
1530 cd
->insert_handlers
= & fr30_cgen_insert_handlers
[0];
1531 cd
->extract_handlers
= & fr30_cgen_extract_handlers
[0];
1533 cd
->insert_operand
= fr30_cgen_insert_operand
;
1534 cd
->extract_operand
= fr30_cgen_extract_operand
;
1536 cd
->get_int_operand
= fr30_cgen_get_int_operand
;
1537 cd
->set_int_operand
= fr30_cgen_set_int_operand
;
1538 cd
->get_vma_operand
= fr30_cgen_get_vma_operand
;
1539 cd
->set_vma_operand
= fr30_cgen_set_vma_operand
;