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 1996, 1997, 1998, 1999, 2000, 2001 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.
33 #include "fr30-desc.h"
38 #define min(a,b) ((a) < (b) ? (a) : (b))
40 #define max(a,b) ((a) > (b) ? (a) : (b))
42 /* Used by the ifield rtx function. */
43 #define FLD(f) (fields->f)
45 static const char * insert_normal
46 PARAMS ((CGEN_CPU_DESC
, long, unsigned int, unsigned int, unsigned int,
47 unsigned int, unsigned int, unsigned int, CGEN_INSN_BYTES_PTR
));
48 static const char * insert_insn_normal
49 PARAMS ((CGEN_CPU_DESC
, const CGEN_INSN
*,
50 CGEN_FIELDS
*, CGEN_INSN_BYTES_PTR
, bfd_vma
));
52 static int extract_normal
53 PARAMS ((CGEN_CPU_DESC
, CGEN_EXTRACT_INFO
*, CGEN_INSN_INT
,
54 unsigned int, unsigned int, unsigned int, unsigned int,
55 unsigned int, unsigned int, bfd_vma
, long *));
56 static int extract_insn_normal
57 PARAMS ((CGEN_CPU_DESC
, const CGEN_INSN
*, CGEN_EXTRACT_INFO
*,
58 CGEN_INSN_INT
, CGEN_FIELDS
*, bfd_vma
));
59 static void put_insn_int_value
60 PARAMS ((CGEN_CPU_DESC
, CGEN_INSN_BYTES_PTR
, int, int, CGEN_INSN_INT
));
63 /* Operand insertion. */
67 /* Subroutine of insert_normal. */
69 static CGEN_INLINE
void
70 insert_1 (cd
, value
, start
, length
, word_length
, bufp
)
73 int start
,length
,word_length
;
78 int big_p
= CGEN_CPU_INSN_ENDIAN (cd
) == CGEN_ENDIAN_BIG
;
80 x
= bfd_get_bits (bufp
, word_length
, big_p
);
82 /* Written this way to avoid undefined behaviour. */
83 mask
= (((1L << (length
- 1)) - 1) << 1) | 1;
85 shift
= (start
+ 1) - length
;
87 shift
= (word_length
- (start
+ length
));
88 x
= (x
& ~(mask
<< shift
)) | ((value
& mask
) << shift
);
90 bfd_put_bits ((bfd_vma
) x
, bufp
, word_length
, big_p
);
93 #endif /* ! CGEN_INT_INSN_P */
95 /* Default insertion routine.
97 ATTRS is a mask of the boolean attributes.
98 WORD_OFFSET is the offset in bits from the start of the insn of the value.
99 WORD_LENGTH is the length of the word in bits in which the value resides.
100 START is the starting bit number in the word, architecture origin.
101 LENGTH is the length of VALUE in bits.
102 TOTAL_LENGTH is the total length of the insn in bits.
104 The result is an error message or NULL if success. */
106 /* ??? This duplicates functionality with bfd's howto table and
107 bfd_install_relocation. */
108 /* ??? This doesn't handle bfd_vma's. Create another function when
112 insert_normal (cd
, value
, attrs
, word_offset
, start
, length
, word_length
,
113 total_length
, buffer
)
117 unsigned int word_offset
, start
, length
, word_length
, total_length
;
118 CGEN_INSN_BYTES_PTR buffer
;
120 static char errbuf
[100];
121 /* Written this way to avoid undefined behaviour. */
122 unsigned long mask
= (((1L << (length
- 1)) - 1) << 1) | 1;
124 /* If LENGTH is zero, this operand doesn't contribute to the value. */
134 if (word_length
> 32)
137 /* For architectures with insns smaller than the base-insn-bitsize,
138 word_length may be too big. */
139 if (cd
->min_insn_bitsize
< cd
->base_insn_bitsize
)
142 && word_length
> total_length
)
143 word_length
= total_length
;
146 /* Ensure VALUE will fit. */
147 if (CGEN_BOOL_ATTR (attrs
, CGEN_IFLD_SIGN_OPT
))
149 long minval
= - (1L << (length
- 1));
150 unsigned long maxval
= mask
;
152 if ((value
> 0 && (unsigned long) value
> maxval
)
155 /* xgettext:c-format */
157 _("operand out of range (%ld not between %ld and %lu)"),
158 value
, minval
, maxval
);
162 else if (! CGEN_BOOL_ATTR (attrs
, CGEN_IFLD_SIGNED
))
164 unsigned long maxval
= mask
;
166 if ((unsigned long) value
> maxval
)
168 /* xgettext:c-format */
170 _("operand out of range (%lu not between 0 and %lu)"),
177 if (! cgen_signed_overflow_ok_p (cd
))
179 long minval
= - (1L << (length
- 1));
180 long maxval
= (1L << (length
- 1)) - 1;
182 if (value
< minval
|| value
> maxval
)
185 /* xgettext:c-format */
186 (errbuf
, _("operand out of range (%ld not between %ld and %ld)"),
187 value
, minval
, maxval
);
198 if (CGEN_INSN_LSB0_P
)
199 shift
= (word_offset
+ start
+ 1) - length
;
201 shift
= total_length
- (word_offset
+ start
+ length
);
202 *buffer
= (*buffer
& ~(mask
<< shift
)) | ((value
& mask
) << shift
);
205 #else /* ! CGEN_INT_INSN_P */
208 unsigned char *bufp
= (unsigned char *) buffer
+ word_offset
/ 8;
210 insert_1 (cd
, value
, start
, length
, word_length
, bufp
);
213 #endif /* ! CGEN_INT_INSN_P */
218 /* Default insn builder (insert handler).
219 The instruction is recorded in CGEN_INT_INSN_P byte order (meaning
220 that if CGEN_INSN_BYTES_PTR is an int * and thus, the value is
221 recorded in host byte order, otherwise BUFFER is an array of bytes
222 and the value is recorded in target byte order).
223 The result is an error message or NULL if success. */
226 insert_insn_normal (cd
, insn
, fields
, buffer
, pc
)
228 const CGEN_INSN
* insn
;
229 CGEN_FIELDS
* fields
;
230 CGEN_INSN_BYTES_PTR buffer
;
233 const CGEN_SYNTAX
*syntax
= CGEN_INSN_SYNTAX (insn
);
235 const CGEN_SYNTAX_CHAR_TYPE
* syn
;
237 CGEN_INIT_INSERT (cd
);
238 value
= CGEN_INSN_BASE_VALUE (insn
);
240 /* If we're recording insns as numbers (rather than a string of bytes),
241 target byte order handling is deferred until later. */
245 put_insn_int_value (cd
, buffer
, cd
->base_insn_bitsize
,
246 CGEN_FIELDS_BITSIZE (fields
), value
);
250 cgen_put_insn_value (cd
, buffer
, min (cd
->base_insn_bitsize
,
251 CGEN_FIELDS_BITSIZE (fields
)),
254 #endif /* ! CGEN_INT_INSN_P */
256 /* ??? It would be better to scan the format's fields.
257 Still need to be able to insert a value based on the operand though;
258 e.g. storing a branch displacement that got resolved later.
259 Needs more thought first. */
261 for (syn
= CGEN_SYNTAX_STRING (syntax
); * syn
; ++ syn
)
265 if (CGEN_SYNTAX_CHAR_P (* syn
))
268 errmsg
= (* cd
->insert_operand
) (cd
, CGEN_SYNTAX_FIELD (*syn
),
277 /* Cover function to store an insn value into an integral insn. Must go here
278 because it needs <prefix>-desc.h for CGEN_INT_INSN_P. */
281 put_insn_int_value (cd
, buf
, length
, insn_length
, value
)
282 CGEN_CPU_DESC cd ATTRIBUTE_UNUSED
;
283 CGEN_INSN_BYTES_PTR buf
;
288 /* For architectures with insns smaller than the base-insn-bitsize,
289 length may be too big. */
290 if (length
> insn_length
)
294 int shift
= insn_length
- length
;
295 /* Written this way to avoid undefined behaviour. */
296 CGEN_INSN_INT mask
= (((1L << (length
- 1)) - 1) << 1) | 1;
297 *buf
= (*buf
& ~(mask
<< shift
)) | ((value
& mask
) << shift
);
301 /* Operand extraction. */
303 #if ! CGEN_INT_INSN_P
305 /* Subroutine of extract_normal.
306 Ensure sufficient bytes are cached in EX_INFO.
307 OFFSET is the offset in bytes from the start of the insn of the value.
308 BYTES is the length of the needed value.
309 Returns 1 for success, 0 for failure. */
311 static CGEN_INLINE
int
312 fill_cache (cd
, ex_info
, offset
, bytes
, pc
)
314 CGEN_EXTRACT_INFO
*ex_info
;
318 /* It's doubtful that the middle part has already been fetched so
319 we don't optimize that case. kiss. */
321 disassemble_info
*info
= (disassemble_info
*) ex_info
->dis_info
;
323 /* First do a quick check. */
324 mask
= (1 << bytes
) - 1;
325 if (((ex_info
->valid
>> offset
) & mask
) == mask
)
328 /* Search for the first byte we need to read. */
329 for (mask
= 1 << offset
; bytes
> 0; --bytes
, ++offset
, mask
<<= 1)
330 if (! (mask
& ex_info
->valid
))
338 status
= (*info
->read_memory_func
)
339 (pc
, ex_info
->insn_bytes
+ offset
, bytes
, info
);
343 (*info
->memory_error_func
) (status
, pc
, info
);
347 ex_info
->valid
|= ((1 << bytes
) - 1) << offset
;
353 /* Subroutine of extract_normal. */
355 static CGEN_INLINE
long
356 extract_1 (cd
, ex_info
, start
, length
, word_length
, bufp
, pc
)
358 CGEN_EXTRACT_INFO
*ex_info
;
359 int start
,length
,word_length
;
365 int big_p
= CGEN_CPU_INSN_ENDIAN (cd
) == CGEN_ENDIAN_BIG
;
367 x
= bfd_get_bits (bufp
, word_length
, big_p
);
369 if (CGEN_INSN_LSB0_P
)
370 shift
= (start
+ 1) - length
;
372 shift
= (word_length
- (start
+ length
));
376 #endif /* ! CGEN_INT_INSN_P */
378 /* Default extraction routine.
380 INSN_VALUE is the first base_insn_bitsize bits of the insn in host order,
381 or sometimes less for cases like the m32r where the base insn size is 32
382 but some insns are 16 bits.
383 ATTRS is a mask of the boolean attributes. We only need `SIGNED',
384 but for generality we take a bitmask of all of them.
385 WORD_OFFSET is the offset in bits from the start of the insn of the value.
386 WORD_LENGTH is the length of the word in bits in which the value resides.
387 START is the starting bit number in the word, architecture origin.
388 LENGTH is the length of VALUE in bits.
389 TOTAL_LENGTH is the total length of the insn in bits.
391 Returns 1 for success, 0 for failure. */
393 /* ??? The return code isn't properly used. wip. */
395 /* ??? This doesn't handle bfd_vma's. Create another function when
399 extract_normal (cd
, ex_info
, insn_value
, attrs
, word_offset
, start
, length
,
400 word_length
, total_length
, pc
, valuep
)
402 #if ! CGEN_INT_INSN_P
403 CGEN_EXTRACT_INFO
*ex_info
;
405 CGEN_EXTRACT_INFO
*ex_info ATTRIBUTE_UNUSED
;
407 CGEN_INSN_INT insn_value
;
409 unsigned int word_offset
, start
, length
, word_length
, total_length
;
410 #if ! CGEN_INT_INSN_P
413 bfd_vma pc ATTRIBUTE_UNUSED
;
419 /* If LENGTH is zero, this operand doesn't contribute to the value
420 so give it a standard value of zero. */
433 if (word_length
> 32)
436 /* For architectures with insns smaller than the insn-base-bitsize,
437 word_length may be too big. */
438 if (cd
->min_insn_bitsize
< cd
->base_insn_bitsize
)
441 && word_length
> total_length
)
442 word_length
= total_length
;
445 /* Does the value reside in INSN_VALUE, and at the right alignment? */
447 if (CGEN_INT_INSN_P
|| (word_offset
== 0 && word_length
== total_length
))
449 if (CGEN_INSN_LSB0_P
)
450 value
= insn_value
>> ((word_offset
+ start
+ 1) - length
);
452 value
= insn_value
>> (total_length
- ( word_offset
+ start
+ length
));
455 #if ! CGEN_INT_INSN_P
459 unsigned char *bufp
= ex_info
->insn_bytes
+ word_offset
/ 8;
461 if (word_length
> 32)
464 if (fill_cache (cd
, ex_info
, word_offset
/ 8, word_length
/ 8, pc
) == 0)
467 value
= extract_1 (cd
, ex_info
, start
, length
, word_length
, bufp
, pc
);
470 #endif /* ! CGEN_INT_INSN_P */
472 /* Written this way to avoid undefined behaviour. */
473 mask
= (((1L << (length
- 1)) - 1) << 1) | 1;
477 if (CGEN_BOOL_ATTR (attrs
, CGEN_IFLD_SIGNED
)
478 && (value
& (1L << (length
- 1))))
486 /* Default insn extractor.
488 INSN_VALUE is the first base_insn_bitsize bits, translated to host order.
489 The extracted fields are stored in FIELDS.
490 EX_INFO is used to handle reading variable length insns.
491 Return the length of the insn in bits, or 0 if no match,
492 or -1 if an error occurs fetching data (memory_error_func will have
496 extract_insn_normal (cd
, insn
, ex_info
, insn_value
, fields
, pc
)
498 const CGEN_INSN
*insn
;
499 CGEN_EXTRACT_INFO
*ex_info
;
500 CGEN_INSN_INT insn_value
;
504 const CGEN_SYNTAX
*syntax
= CGEN_INSN_SYNTAX (insn
);
505 const CGEN_SYNTAX_CHAR_TYPE
*syn
;
507 CGEN_FIELDS_BITSIZE (fields
) = CGEN_INSN_BITSIZE (insn
);
509 CGEN_INIT_EXTRACT (cd
);
511 for (syn
= CGEN_SYNTAX_STRING (syntax
); *syn
; ++syn
)
515 if (CGEN_SYNTAX_CHAR_P (*syn
))
518 length
= (* cd
->extract_operand
) (cd
, CGEN_SYNTAX_FIELD (*syn
),
519 ex_info
, insn_value
, fields
, pc
);
524 /* We recognized and successfully extracted this insn. */
525 return CGEN_INSN_BITSIZE (insn
);
528 /* machine generated code added here */
530 /* Main entry point for operand insertion.
532 This function is basically just a big switch statement. Earlier versions
533 used tables to look up the function to use, but
534 - if the table contains both assembler and disassembler functions then
535 the disassembler contains much of the assembler and vice-versa,
536 - there's a lot of inlining possibilities as things grow,
537 - using a switch statement avoids the function call overhead.
539 This function could be moved into `parse_insn_normal', but keeping it
540 separate makes clear the interface between `parse_insn_normal' and each of
541 the handlers. It's also needed by GAS to insert operands that couldn't be
542 resolved during parsing.
546 fr30_cgen_insert_operand (cd
, opindex
, fields
, buffer
, pc
)
549 CGEN_FIELDS
* fields
;
550 CGEN_INSN_BYTES_PTR buffer
;
553 const char * errmsg
= NULL
;
554 unsigned int total_length
= CGEN_FIELDS_BITSIZE (fields
);
558 case FR30_OPERAND_CRI
:
559 errmsg
= insert_normal (cd
, fields
->f_CRi
, 0, 16, 12, 4, 16, total_length
, buffer
);
561 case FR30_OPERAND_CRJ
:
562 errmsg
= insert_normal (cd
, fields
->f_CRj
, 0, 16, 8, 4, 16, total_length
, buffer
);
564 case FR30_OPERAND_R13
:
566 case FR30_OPERAND_R14
:
568 case FR30_OPERAND_R15
:
570 case FR30_OPERAND_RI
:
571 errmsg
= insert_normal (cd
, fields
->f_Ri
, 0, 0, 12, 4, 16, total_length
, buffer
);
573 case FR30_OPERAND_RIC
:
574 errmsg
= insert_normal (cd
, fields
->f_Ric
, 0, 16, 12, 4, 16, total_length
, buffer
);
576 case FR30_OPERAND_RJ
:
577 errmsg
= insert_normal (cd
, fields
->f_Rj
, 0, 0, 8, 4, 16, total_length
, buffer
);
579 case FR30_OPERAND_RJC
:
580 errmsg
= insert_normal (cd
, fields
->f_Rjc
, 0, 16, 8, 4, 16, total_length
, buffer
);
582 case FR30_OPERAND_RS1
:
583 errmsg
= insert_normal (cd
, fields
->f_Rs1
, 0, 0, 8, 4, 16, total_length
, buffer
);
585 case FR30_OPERAND_RS2
:
586 errmsg
= insert_normal (cd
, fields
->f_Rs2
, 0, 0, 12, 4, 16, total_length
, buffer
);
588 case FR30_OPERAND_CC
:
589 errmsg
= insert_normal (cd
, fields
->f_cc
, 0, 0, 4, 4, 16, total_length
, buffer
);
591 case FR30_OPERAND_CCC
:
592 errmsg
= insert_normal (cd
, fields
->f_ccc
, 0, 16, 0, 8, 16, total_length
, buffer
);
594 case FR30_OPERAND_DIR10
:
596 long value
= fields
->f_dir10
;
597 value
= ((unsigned int) (value
) >> (2));
598 errmsg
= insert_normal (cd
, value
, 0, 0, 8, 8, 16, total_length
, buffer
);
601 case FR30_OPERAND_DIR8
:
602 errmsg
= insert_normal (cd
, fields
->f_dir8
, 0, 0, 8, 8, 16, total_length
, buffer
);
604 case FR30_OPERAND_DIR9
:
606 long value
= fields
->f_dir9
;
607 value
= ((unsigned int) (value
) >> (1));
608 errmsg
= insert_normal (cd
, value
, 0, 0, 8, 8, 16, total_length
, buffer
);
611 case FR30_OPERAND_DISP10
:
613 long value
= fields
->f_disp10
;
614 value
= ((int) (value
) >> (2));
615 errmsg
= insert_normal (cd
, value
, 0|(1<<CGEN_IFLD_SIGNED
), 0, 4, 8, 16, total_length
, buffer
);
618 case FR30_OPERAND_DISP8
:
619 errmsg
= insert_normal (cd
, fields
->f_disp8
, 0|(1<<CGEN_IFLD_SIGNED
), 0, 4, 8, 16, total_length
, buffer
);
621 case FR30_OPERAND_DISP9
:
623 long value
= fields
->f_disp9
;
624 value
= ((int) (value
) >> (1));
625 errmsg
= insert_normal (cd
, value
, 0|(1<<CGEN_IFLD_SIGNED
), 0, 4, 8, 16, total_length
, buffer
);
628 case FR30_OPERAND_I20
:
631 FLD (f_i20_4
) = ((unsigned int) (FLD (f_i20
)) >> (16));
632 FLD (f_i20_16
) = ((FLD (f_i20
)) & (65535));
634 errmsg
= insert_normal (cd
, fields
->f_i20_4
, 0, 0, 8, 4, 16, total_length
, buffer
);
637 errmsg
= insert_normal (cd
, fields
->f_i20_16
, 0, 16, 0, 16, 16, total_length
, buffer
);
642 case FR30_OPERAND_I32
:
643 errmsg
= insert_normal (cd
, fields
->f_i32
, 0|(1<<CGEN_IFLD_SIGN_OPT
), 16, 0, 32, 32, total_length
, buffer
);
645 case FR30_OPERAND_I8
:
646 errmsg
= insert_normal (cd
, fields
->f_i8
, 0, 0, 4, 8, 16, total_length
, buffer
);
648 case FR30_OPERAND_LABEL12
:
650 long value
= fields
->f_rel12
;
651 value
= ((int) (((value
) - (((pc
) + (2))))) >> (1));
652 errmsg
= insert_normal (cd
, value
, 0|(1<<CGEN_IFLD_SIGNED
)|(1<<CGEN_IFLD_PCREL_ADDR
), 0, 5, 11, 16, total_length
, buffer
);
655 case FR30_OPERAND_LABEL9
:
657 long value
= fields
->f_rel9
;
658 value
= ((int) (((value
) - (((pc
) + (2))))) >> (1));
659 errmsg
= insert_normal (cd
, value
, 0|(1<<CGEN_IFLD_SIGNED
)|(1<<CGEN_IFLD_PCREL_ADDR
), 0, 8, 8, 16, total_length
, buffer
);
662 case FR30_OPERAND_M4
:
664 long value
= fields
->f_m4
;
665 value
= ((value
) & (15));
666 errmsg
= insert_normal (cd
, value
, 0, 0, 8, 4, 16, total_length
, buffer
);
669 case FR30_OPERAND_PS
:
671 case FR30_OPERAND_REGLIST_HI_LD
:
672 errmsg
= insert_normal (cd
, fields
->f_reglist_hi_ld
, 0, 0, 8, 8, 16, total_length
, buffer
);
674 case FR30_OPERAND_REGLIST_HI_ST
:
675 errmsg
= insert_normal (cd
, fields
->f_reglist_hi_st
, 0, 0, 8, 8, 16, total_length
, buffer
);
677 case FR30_OPERAND_REGLIST_LOW_LD
:
678 errmsg
= insert_normal (cd
, fields
->f_reglist_low_ld
, 0, 0, 8, 8, 16, total_length
, buffer
);
680 case FR30_OPERAND_REGLIST_LOW_ST
:
681 errmsg
= insert_normal (cd
, fields
->f_reglist_low_st
, 0, 0, 8, 8, 16, total_length
, buffer
);
683 case FR30_OPERAND_S10
:
685 long value
= fields
->f_s10
;
686 value
= ((int) (value
) >> (2));
687 errmsg
= insert_normal (cd
, value
, 0|(1<<CGEN_IFLD_SIGNED
), 0, 8, 8, 16, total_length
, buffer
);
690 case FR30_OPERAND_U10
:
692 long value
= fields
->f_u10
;
693 value
= ((unsigned int) (value
) >> (2));
694 errmsg
= insert_normal (cd
, value
, 0, 0, 8, 8, 16, total_length
, buffer
);
697 case FR30_OPERAND_U4
:
698 errmsg
= insert_normal (cd
, fields
->f_u4
, 0, 0, 8, 4, 16, total_length
, buffer
);
700 case FR30_OPERAND_U4C
:
701 errmsg
= insert_normal (cd
, fields
->f_u4c
, 0, 0, 12, 4, 16, total_length
, buffer
);
703 case FR30_OPERAND_U8
:
704 errmsg
= insert_normal (cd
, fields
->f_u8
, 0, 0, 8, 8, 16, total_length
, buffer
);
706 case FR30_OPERAND_UDISP6
:
708 long value
= fields
->f_udisp6
;
709 value
= ((unsigned int) (value
) >> (2));
710 errmsg
= insert_normal (cd
, value
, 0, 0, 8, 4, 16, total_length
, buffer
);
715 /* xgettext:c-format */
716 fprintf (stderr
, _("Unrecognized field %d while building insn.\n"),
724 /* Main entry point for operand extraction.
725 The result is <= 0 for error, >0 for success.
726 ??? Actual values aren't well defined right now.
728 This function is basically just a big switch statement. Earlier versions
729 used tables to look up the function to use, but
730 - if the table contains both assembler and disassembler functions then
731 the disassembler contains much of the assembler and vice-versa,
732 - there's a lot of inlining possibilities as things grow,
733 - using a switch statement avoids the function call overhead.
735 This function could be moved into `print_insn_normal', but keeping it
736 separate makes clear the interface between `print_insn_normal' and each of
741 fr30_cgen_extract_operand (cd
, opindex
, ex_info
, insn_value
, fields
, pc
)
744 CGEN_EXTRACT_INFO
*ex_info
;
745 CGEN_INSN_INT insn_value
;
746 CGEN_FIELDS
* fields
;
749 /* Assume success (for those operands that are nops). */
751 unsigned int total_length
= CGEN_FIELDS_BITSIZE (fields
);
755 case FR30_OPERAND_CRI
:
756 length
= extract_normal (cd
, ex_info
, insn_value
, 0, 16, 12, 4, 16, total_length
, pc
, & fields
->f_CRi
);
758 case FR30_OPERAND_CRJ
:
759 length
= extract_normal (cd
, ex_info
, insn_value
, 0, 16, 8, 4, 16, total_length
, pc
, & fields
->f_CRj
);
761 case FR30_OPERAND_R13
:
763 case FR30_OPERAND_R14
:
765 case FR30_OPERAND_R15
:
767 case FR30_OPERAND_RI
:
768 length
= extract_normal (cd
, ex_info
, insn_value
, 0, 0, 12, 4, 16, total_length
, pc
, & fields
->f_Ri
);
770 case FR30_OPERAND_RIC
:
771 length
= extract_normal (cd
, ex_info
, insn_value
, 0, 16, 12, 4, 16, total_length
, pc
, & fields
->f_Ric
);
773 case FR30_OPERAND_RJ
:
774 length
= extract_normal (cd
, ex_info
, insn_value
, 0, 0, 8, 4, 16, total_length
, pc
, & fields
->f_Rj
);
776 case FR30_OPERAND_RJC
:
777 length
= extract_normal (cd
, ex_info
, insn_value
, 0, 16, 8, 4, 16, total_length
, pc
, & fields
->f_Rjc
);
779 case FR30_OPERAND_RS1
:
780 length
= extract_normal (cd
, ex_info
, insn_value
, 0, 0, 8, 4, 16, total_length
, pc
, & fields
->f_Rs1
);
782 case FR30_OPERAND_RS2
:
783 length
= extract_normal (cd
, ex_info
, insn_value
, 0, 0, 12, 4, 16, total_length
, pc
, & fields
->f_Rs2
);
785 case FR30_OPERAND_CC
:
786 length
= extract_normal (cd
, ex_info
, insn_value
, 0, 0, 4, 4, 16, total_length
, pc
, & fields
->f_cc
);
788 case FR30_OPERAND_CCC
:
789 length
= extract_normal (cd
, ex_info
, insn_value
, 0, 16, 0, 8, 16, total_length
, pc
, & fields
->f_ccc
);
791 case FR30_OPERAND_DIR10
:
794 length
= extract_normal (cd
, ex_info
, insn_value
, 0, 0, 8, 8, 16, total_length
, pc
, & value
);
795 value
= ((value
) << (2));
796 fields
->f_dir10
= value
;
799 case FR30_OPERAND_DIR8
:
800 length
= extract_normal (cd
, ex_info
, insn_value
, 0, 0, 8, 8, 16, total_length
, pc
, & fields
->f_dir8
);
802 case FR30_OPERAND_DIR9
:
805 length
= extract_normal (cd
, ex_info
, insn_value
, 0, 0, 8, 8, 16, total_length
, pc
, & value
);
806 value
= ((value
) << (1));
807 fields
->f_dir9
= value
;
810 case FR30_OPERAND_DISP10
:
813 length
= extract_normal (cd
, ex_info
, insn_value
, 0|(1<<CGEN_IFLD_SIGNED
), 0, 4, 8, 16, total_length
, pc
, & value
);
814 value
= ((value
) << (2));
815 fields
->f_disp10
= value
;
818 case FR30_OPERAND_DISP8
:
819 length
= extract_normal (cd
, ex_info
, insn_value
, 0|(1<<CGEN_IFLD_SIGNED
), 0, 4, 8, 16, total_length
, pc
, & fields
->f_disp8
);
821 case FR30_OPERAND_DISP9
:
824 length
= extract_normal (cd
, ex_info
, insn_value
, 0|(1<<CGEN_IFLD_SIGNED
), 0, 4, 8, 16, total_length
, pc
, & value
);
825 value
= ((value
) << (1));
826 fields
->f_disp9
= value
;
829 case FR30_OPERAND_I20
:
831 length
= extract_normal (cd
, ex_info
, insn_value
, 0, 0, 8, 4, 16, total_length
, pc
, & fields
->f_i20_4
);
832 if (length
<= 0) break;
833 length
= extract_normal (cd
, ex_info
, insn_value
, 0, 16, 0, 16, 16, total_length
, pc
, & fields
->f_i20_16
);
834 if (length
<= 0) break;
836 FLD (f_i20
) = ((((FLD (f_i20_4
)) << (16))) | (FLD (f_i20_16
)));
840 case FR30_OPERAND_I32
:
841 length
= extract_normal (cd
, ex_info
, insn_value
, 0|(1<<CGEN_IFLD_SIGN_OPT
), 16, 0, 32, 32, total_length
, pc
, & fields
->f_i32
);
843 case FR30_OPERAND_I8
:
844 length
= extract_normal (cd
, ex_info
, insn_value
, 0, 0, 4, 8, 16, total_length
, pc
, & fields
->f_i8
);
846 case FR30_OPERAND_LABEL12
:
849 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
);
850 value
= ((((value
) << (1))) + (((pc
) + (2))));
851 fields
->f_rel12
= value
;
854 case FR30_OPERAND_LABEL9
:
857 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
);
858 value
= ((((value
) << (1))) + (((pc
) + (2))));
859 fields
->f_rel9
= value
;
862 case FR30_OPERAND_M4
:
865 length
= extract_normal (cd
, ex_info
, insn_value
, 0, 0, 8, 4, 16, total_length
, pc
, & value
);
866 value
= ((value
) | (((-1) << (4))));
867 fields
->f_m4
= value
;
870 case FR30_OPERAND_PS
:
872 case FR30_OPERAND_REGLIST_HI_LD
:
873 length
= extract_normal (cd
, ex_info
, insn_value
, 0, 0, 8, 8, 16, total_length
, pc
, & fields
->f_reglist_hi_ld
);
875 case FR30_OPERAND_REGLIST_HI_ST
:
876 length
= extract_normal (cd
, ex_info
, insn_value
, 0, 0, 8, 8, 16, total_length
, pc
, & fields
->f_reglist_hi_st
);
878 case FR30_OPERAND_REGLIST_LOW_LD
:
879 length
= extract_normal (cd
, ex_info
, insn_value
, 0, 0, 8, 8, 16, total_length
, pc
, & fields
->f_reglist_low_ld
);
881 case FR30_OPERAND_REGLIST_LOW_ST
:
882 length
= extract_normal (cd
, ex_info
, insn_value
, 0, 0, 8, 8, 16, total_length
, pc
, & fields
->f_reglist_low_st
);
884 case FR30_OPERAND_S10
:
887 length
= extract_normal (cd
, ex_info
, insn_value
, 0|(1<<CGEN_IFLD_SIGNED
), 0, 8, 8, 16, total_length
, pc
, & value
);
888 value
= ((value
) << (2));
889 fields
->f_s10
= value
;
892 case FR30_OPERAND_U10
:
895 length
= extract_normal (cd
, ex_info
, insn_value
, 0, 0, 8, 8, 16, total_length
, pc
, & value
);
896 value
= ((value
) << (2));
897 fields
->f_u10
= value
;
900 case FR30_OPERAND_U4
:
901 length
= extract_normal (cd
, ex_info
, insn_value
, 0, 0, 8, 4, 16, total_length
, pc
, & fields
->f_u4
);
903 case FR30_OPERAND_U4C
:
904 length
= extract_normal (cd
, ex_info
, insn_value
, 0, 0, 12, 4, 16, total_length
, pc
, & fields
->f_u4c
);
906 case FR30_OPERAND_U8
:
907 length
= extract_normal (cd
, ex_info
, insn_value
, 0, 0, 8, 8, 16, total_length
, pc
, & fields
->f_u8
);
909 case FR30_OPERAND_UDISP6
:
912 length
= extract_normal (cd
, ex_info
, insn_value
, 0, 0, 8, 4, 16, total_length
, pc
, & value
);
913 value
= ((value
) << (2));
914 fields
->f_udisp6
= value
;
919 /* xgettext:c-format */
920 fprintf (stderr
, _("Unrecognized field %d while decoding insn.\n"),
928 cgen_insert_fn
* const fr30_cgen_insert_handlers
[] =
933 cgen_extract_fn
* const fr30_cgen_extract_handlers
[] =
938 /* Getting values from cgen_fields is handled by a collection of functions.
939 They are distinguished by the type of the VALUE argument they return.
940 TODO: floating point, inlining support, remove cases where result type
944 fr30_cgen_get_int_operand (cd
, opindex
, fields
)
947 const CGEN_FIELDS
* fields
;
953 case FR30_OPERAND_CRI
:
954 value
= fields
->f_CRi
;
956 case FR30_OPERAND_CRJ
:
957 value
= fields
->f_CRj
;
959 case FR30_OPERAND_R13
:
962 case FR30_OPERAND_R14
:
965 case FR30_OPERAND_R15
:
968 case FR30_OPERAND_RI
:
969 value
= fields
->f_Ri
;
971 case FR30_OPERAND_RIC
:
972 value
= fields
->f_Ric
;
974 case FR30_OPERAND_RJ
:
975 value
= fields
->f_Rj
;
977 case FR30_OPERAND_RJC
:
978 value
= fields
->f_Rjc
;
980 case FR30_OPERAND_RS1
:
981 value
= fields
->f_Rs1
;
983 case FR30_OPERAND_RS2
:
984 value
= fields
->f_Rs2
;
986 case FR30_OPERAND_CC
:
987 value
= fields
->f_cc
;
989 case FR30_OPERAND_CCC
:
990 value
= fields
->f_ccc
;
992 case FR30_OPERAND_DIR10
:
993 value
= fields
->f_dir10
;
995 case FR30_OPERAND_DIR8
:
996 value
= fields
->f_dir8
;
998 case FR30_OPERAND_DIR9
:
999 value
= fields
->f_dir9
;
1001 case FR30_OPERAND_DISP10
:
1002 value
= fields
->f_disp10
;
1004 case FR30_OPERAND_DISP8
:
1005 value
= fields
->f_disp8
;
1007 case FR30_OPERAND_DISP9
:
1008 value
= fields
->f_disp9
;
1010 case FR30_OPERAND_I20
:
1011 value
= fields
->f_i20
;
1013 case FR30_OPERAND_I32
:
1014 value
= fields
->f_i32
;
1016 case FR30_OPERAND_I8
:
1017 value
= fields
->f_i8
;
1019 case FR30_OPERAND_LABEL12
:
1020 value
= fields
->f_rel12
;
1022 case FR30_OPERAND_LABEL9
:
1023 value
= fields
->f_rel9
;
1025 case FR30_OPERAND_M4
:
1026 value
= fields
->f_m4
;
1028 case FR30_OPERAND_PS
:
1031 case FR30_OPERAND_REGLIST_HI_LD
:
1032 value
= fields
->f_reglist_hi_ld
;
1034 case FR30_OPERAND_REGLIST_HI_ST
:
1035 value
= fields
->f_reglist_hi_st
;
1037 case FR30_OPERAND_REGLIST_LOW_LD
:
1038 value
= fields
->f_reglist_low_ld
;
1040 case FR30_OPERAND_REGLIST_LOW_ST
:
1041 value
= fields
->f_reglist_low_st
;
1043 case FR30_OPERAND_S10
:
1044 value
= fields
->f_s10
;
1046 case FR30_OPERAND_U10
:
1047 value
= fields
->f_u10
;
1049 case FR30_OPERAND_U4
:
1050 value
= fields
->f_u4
;
1052 case FR30_OPERAND_U4C
:
1053 value
= fields
->f_u4c
;
1055 case FR30_OPERAND_U8
:
1056 value
= fields
->f_u8
;
1058 case FR30_OPERAND_UDISP6
:
1059 value
= fields
->f_udisp6
;
1063 /* xgettext:c-format */
1064 fprintf (stderr
, _("Unrecognized field %d while getting int operand.\n"),
1073 fr30_cgen_get_vma_operand (cd
, opindex
, fields
)
1076 const CGEN_FIELDS
* fields
;
1082 case FR30_OPERAND_CRI
:
1083 value
= fields
->f_CRi
;
1085 case FR30_OPERAND_CRJ
:
1086 value
= fields
->f_CRj
;
1088 case FR30_OPERAND_R13
:
1091 case FR30_OPERAND_R14
:
1094 case FR30_OPERAND_R15
:
1097 case FR30_OPERAND_RI
:
1098 value
= fields
->f_Ri
;
1100 case FR30_OPERAND_RIC
:
1101 value
= fields
->f_Ric
;
1103 case FR30_OPERAND_RJ
:
1104 value
= fields
->f_Rj
;
1106 case FR30_OPERAND_RJC
:
1107 value
= fields
->f_Rjc
;
1109 case FR30_OPERAND_RS1
:
1110 value
= fields
->f_Rs1
;
1112 case FR30_OPERAND_RS2
:
1113 value
= fields
->f_Rs2
;
1115 case FR30_OPERAND_CC
:
1116 value
= fields
->f_cc
;
1118 case FR30_OPERAND_CCC
:
1119 value
= fields
->f_ccc
;
1121 case FR30_OPERAND_DIR10
:
1122 value
= fields
->f_dir10
;
1124 case FR30_OPERAND_DIR8
:
1125 value
= fields
->f_dir8
;
1127 case FR30_OPERAND_DIR9
:
1128 value
= fields
->f_dir9
;
1130 case FR30_OPERAND_DISP10
:
1131 value
= fields
->f_disp10
;
1133 case FR30_OPERAND_DISP8
:
1134 value
= fields
->f_disp8
;
1136 case FR30_OPERAND_DISP9
:
1137 value
= fields
->f_disp9
;
1139 case FR30_OPERAND_I20
:
1140 value
= fields
->f_i20
;
1142 case FR30_OPERAND_I32
:
1143 value
= fields
->f_i32
;
1145 case FR30_OPERAND_I8
:
1146 value
= fields
->f_i8
;
1148 case FR30_OPERAND_LABEL12
:
1149 value
= fields
->f_rel12
;
1151 case FR30_OPERAND_LABEL9
:
1152 value
= fields
->f_rel9
;
1154 case FR30_OPERAND_M4
:
1155 value
= fields
->f_m4
;
1157 case FR30_OPERAND_PS
:
1160 case FR30_OPERAND_REGLIST_HI_LD
:
1161 value
= fields
->f_reglist_hi_ld
;
1163 case FR30_OPERAND_REGLIST_HI_ST
:
1164 value
= fields
->f_reglist_hi_st
;
1166 case FR30_OPERAND_REGLIST_LOW_LD
:
1167 value
= fields
->f_reglist_low_ld
;
1169 case FR30_OPERAND_REGLIST_LOW_ST
:
1170 value
= fields
->f_reglist_low_st
;
1172 case FR30_OPERAND_S10
:
1173 value
= fields
->f_s10
;
1175 case FR30_OPERAND_U10
:
1176 value
= fields
->f_u10
;
1178 case FR30_OPERAND_U4
:
1179 value
= fields
->f_u4
;
1181 case FR30_OPERAND_U4C
:
1182 value
= fields
->f_u4c
;
1184 case FR30_OPERAND_U8
:
1185 value
= fields
->f_u8
;
1187 case FR30_OPERAND_UDISP6
:
1188 value
= fields
->f_udisp6
;
1192 /* xgettext:c-format */
1193 fprintf (stderr
, _("Unrecognized field %d while getting vma operand.\n"),
1201 /* Stuffing values in cgen_fields is handled by a collection of functions.
1202 They are distinguished by the type of the VALUE argument they accept.
1203 TODO: floating point, inlining support, remove cases where argument type
1207 fr30_cgen_set_int_operand (cd
, opindex
, fields
, value
)
1210 CGEN_FIELDS
* fields
;
1215 case FR30_OPERAND_CRI
:
1216 fields
->f_CRi
= value
;
1218 case FR30_OPERAND_CRJ
:
1219 fields
->f_CRj
= value
;
1221 case FR30_OPERAND_R13
:
1223 case FR30_OPERAND_R14
:
1225 case FR30_OPERAND_R15
:
1227 case FR30_OPERAND_RI
:
1228 fields
->f_Ri
= value
;
1230 case FR30_OPERAND_RIC
:
1231 fields
->f_Ric
= value
;
1233 case FR30_OPERAND_RJ
:
1234 fields
->f_Rj
= value
;
1236 case FR30_OPERAND_RJC
:
1237 fields
->f_Rjc
= value
;
1239 case FR30_OPERAND_RS1
:
1240 fields
->f_Rs1
= value
;
1242 case FR30_OPERAND_RS2
:
1243 fields
->f_Rs2
= value
;
1245 case FR30_OPERAND_CC
:
1246 fields
->f_cc
= value
;
1248 case FR30_OPERAND_CCC
:
1249 fields
->f_ccc
= value
;
1251 case FR30_OPERAND_DIR10
:
1252 fields
->f_dir10
= value
;
1254 case FR30_OPERAND_DIR8
:
1255 fields
->f_dir8
= value
;
1257 case FR30_OPERAND_DIR9
:
1258 fields
->f_dir9
= value
;
1260 case FR30_OPERAND_DISP10
:
1261 fields
->f_disp10
= value
;
1263 case FR30_OPERAND_DISP8
:
1264 fields
->f_disp8
= value
;
1266 case FR30_OPERAND_DISP9
:
1267 fields
->f_disp9
= value
;
1269 case FR30_OPERAND_I20
:
1270 fields
->f_i20
= value
;
1272 case FR30_OPERAND_I32
:
1273 fields
->f_i32
= value
;
1275 case FR30_OPERAND_I8
:
1276 fields
->f_i8
= value
;
1278 case FR30_OPERAND_LABEL12
:
1279 fields
->f_rel12
= value
;
1281 case FR30_OPERAND_LABEL9
:
1282 fields
->f_rel9
= value
;
1284 case FR30_OPERAND_M4
:
1285 fields
->f_m4
= value
;
1287 case FR30_OPERAND_PS
:
1289 case FR30_OPERAND_REGLIST_HI_LD
:
1290 fields
->f_reglist_hi_ld
= value
;
1292 case FR30_OPERAND_REGLIST_HI_ST
:
1293 fields
->f_reglist_hi_st
= value
;
1295 case FR30_OPERAND_REGLIST_LOW_LD
:
1296 fields
->f_reglist_low_ld
= value
;
1298 case FR30_OPERAND_REGLIST_LOW_ST
:
1299 fields
->f_reglist_low_st
= value
;
1301 case FR30_OPERAND_S10
:
1302 fields
->f_s10
= value
;
1304 case FR30_OPERAND_U10
:
1305 fields
->f_u10
= value
;
1307 case FR30_OPERAND_U4
:
1308 fields
->f_u4
= value
;
1310 case FR30_OPERAND_U4C
:
1311 fields
->f_u4c
= value
;
1313 case FR30_OPERAND_U8
:
1314 fields
->f_u8
= value
;
1316 case FR30_OPERAND_UDISP6
:
1317 fields
->f_udisp6
= value
;
1321 /* xgettext:c-format */
1322 fprintf (stderr
, _("Unrecognized field %d while setting int operand.\n"),
1329 fr30_cgen_set_vma_operand (cd
, opindex
, fields
, value
)
1332 CGEN_FIELDS
* fields
;
1337 case FR30_OPERAND_CRI
:
1338 fields
->f_CRi
= value
;
1340 case FR30_OPERAND_CRJ
:
1341 fields
->f_CRj
= value
;
1343 case FR30_OPERAND_R13
:
1345 case FR30_OPERAND_R14
:
1347 case FR30_OPERAND_R15
:
1349 case FR30_OPERAND_RI
:
1350 fields
->f_Ri
= value
;
1352 case FR30_OPERAND_RIC
:
1353 fields
->f_Ric
= value
;
1355 case FR30_OPERAND_RJ
:
1356 fields
->f_Rj
= value
;
1358 case FR30_OPERAND_RJC
:
1359 fields
->f_Rjc
= value
;
1361 case FR30_OPERAND_RS1
:
1362 fields
->f_Rs1
= value
;
1364 case FR30_OPERAND_RS2
:
1365 fields
->f_Rs2
= value
;
1367 case FR30_OPERAND_CC
:
1368 fields
->f_cc
= value
;
1370 case FR30_OPERAND_CCC
:
1371 fields
->f_ccc
= value
;
1373 case FR30_OPERAND_DIR10
:
1374 fields
->f_dir10
= value
;
1376 case FR30_OPERAND_DIR8
:
1377 fields
->f_dir8
= value
;
1379 case FR30_OPERAND_DIR9
:
1380 fields
->f_dir9
= value
;
1382 case FR30_OPERAND_DISP10
:
1383 fields
->f_disp10
= value
;
1385 case FR30_OPERAND_DISP8
:
1386 fields
->f_disp8
= value
;
1388 case FR30_OPERAND_DISP9
:
1389 fields
->f_disp9
= value
;
1391 case FR30_OPERAND_I20
:
1392 fields
->f_i20
= value
;
1394 case FR30_OPERAND_I32
:
1395 fields
->f_i32
= value
;
1397 case FR30_OPERAND_I8
:
1398 fields
->f_i8
= value
;
1400 case FR30_OPERAND_LABEL12
:
1401 fields
->f_rel12
= value
;
1403 case FR30_OPERAND_LABEL9
:
1404 fields
->f_rel9
= value
;
1406 case FR30_OPERAND_M4
:
1407 fields
->f_m4
= value
;
1409 case FR30_OPERAND_PS
:
1411 case FR30_OPERAND_REGLIST_HI_LD
:
1412 fields
->f_reglist_hi_ld
= value
;
1414 case FR30_OPERAND_REGLIST_HI_ST
:
1415 fields
->f_reglist_hi_st
= value
;
1417 case FR30_OPERAND_REGLIST_LOW_LD
:
1418 fields
->f_reglist_low_ld
= value
;
1420 case FR30_OPERAND_REGLIST_LOW_ST
:
1421 fields
->f_reglist_low_st
= value
;
1423 case FR30_OPERAND_S10
:
1424 fields
->f_s10
= value
;
1426 case FR30_OPERAND_U10
:
1427 fields
->f_u10
= value
;
1429 case FR30_OPERAND_U4
:
1430 fields
->f_u4
= value
;
1432 case FR30_OPERAND_U4C
:
1433 fields
->f_u4c
= value
;
1435 case FR30_OPERAND_U8
:
1436 fields
->f_u8
= value
;
1438 case FR30_OPERAND_UDISP6
:
1439 fields
->f_udisp6
= value
;
1443 /* xgettext:c-format */
1444 fprintf (stderr
, _("Unrecognized field %d while setting vma operand.\n"),
1450 /* Function to call before using the instruction builder tables. */
1453 fr30_cgen_init_ibld_table (cd
)
1456 cd
->insert_handlers
= & fr30_cgen_insert_handlers
[0];
1457 cd
->extract_handlers
= & fr30_cgen_extract_handlers
[0];
1459 cd
->insert_operand
= fr30_cgen_insert_operand
;
1460 cd
->extract_operand
= fr30_cgen_extract_operand
;
1462 cd
->get_int_operand
= fr30_cgen_get_int_operand
;
1463 cd
->set_int_operand
= fr30_cgen_set_int_operand
;
1464 cd
->get_vma_operand
= fr30_cgen_get_vma_operand
;
1465 cd
->set_vma_operand
= fr30_cgen_set_vma_operand
;