1 /* Instruction building/extraction support for m32r. -*- C -*-
3 THIS FILE IS MACHINE GENERATED WITH CGEN: Cpu tools GENerator.
4 - the resultant file is machine generated, cgen-ibld.in isn't
6 Copyright (C) 1996, 1997, 1998, 1999 Free Software Foundation, Inc.
8 This file is part of the GNU Binutils and GDB, the GNU debugger.
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2, or (at your option)
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 "m32r-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
));
61 /* Operand insertion. */
65 /* Subroutine of insert_normal. */
67 static CGEN_INLINE
void
68 insert_1 (cd
, value
, start
, length
, word_length
, bufp
)
71 int start
,length
,word_length
;
76 int big_p
= CGEN_CPU_INSN_ENDIAN (cd
) == CGEN_ENDIAN_BIG
;
85 x
= bfd_getb16 (bufp
);
87 x
= bfd_getl16 (bufp
);
90 /* ??? This may need reworking as these cases don't necessarily
91 want the first byte and the last two bytes handled like this. */
93 x
= (bufp
[0] << 16) | bfd_getb16 (bufp
+ 1);
95 x
= bfd_getl16 (bufp
) | (bufp
[2] << 16);
99 x
= bfd_getb32 (bufp
);
101 x
= bfd_getl32 (bufp
);
107 /* Written this way to avoid undefined behaviour. */
108 mask
= (((1L << (length
- 1)) - 1) << 1) | 1;
109 if (CGEN_INSN_LSB0_P
)
110 shift
= (start
+ 1) - length
;
112 shift
= (word_length
- (start
+ length
));
113 x
= (x
& ~(mask
<< shift
)) | ((value
& mask
) << shift
);
122 bfd_putb16 (x
, bufp
);
124 bfd_putl16 (x
, bufp
);
127 /* ??? This may need reworking as these cases don't necessarily
128 want the first byte and the last two bytes handled like this. */
132 bfd_putb16 (x
, bufp
+ 1);
136 bfd_putl16 (x
, bufp
);
142 bfd_putb32 (x
, bufp
);
144 bfd_putl32 (x
, bufp
);
151 #endif /* ! CGEN_INT_INSN_P */
153 /* Default insertion routine.
155 ATTRS is a mask of the boolean attributes.
156 WORD_OFFSET is the offset in bits from the start of the insn of the value.
157 WORD_LENGTH is the length of the word in bits in which the value resides.
158 START is the starting bit number in the word, architecture origin.
159 LENGTH is the length of VALUE in bits.
160 TOTAL_LENGTH is the total length of the insn in bits.
162 The result is an error message or NULL if success. */
164 /* ??? This duplicates functionality with bfd's howto table and
165 bfd_install_relocation. */
166 /* ??? This doesn't handle bfd_vma's. Create another function when
170 insert_normal (cd
, value
, attrs
, word_offset
, start
, length
, word_length
,
171 total_length
, buffer
)
175 unsigned int word_offset
, start
, length
, word_length
, total_length
;
176 CGEN_INSN_BYTES_PTR buffer
;
178 static char errbuf
[100];
179 /* Written this way to avoid undefined behaviour. */
180 unsigned long mask
= (((1L << (length
- 1)) - 1) << 1) | 1;
182 /* If LENGTH is zero, this operand doesn't contribute to the value. */
190 if (word_length
> 32)
193 /* For architectures with insns smaller than the base-insn-bitsize,
194 word_length may be too big. */
195 if (cd
->min_insn_bitsize
< cd
->base_insn_bitsize
)
198 && word_length
> total_length
)
199 word_length
= total_length
;
202 /* Ensure VALUE will fit. */
203 if (! CGEN_BOOL_ATTR (attrs
, CGEN_IFLD_SIGNED
))
205 unsigned long maxval
= mask
;
206 if ((unsigned long) value
> maxval
)
208 /* xgettext:c-format */
210 _("operand out of range (%lu not between 0 and %lu)"),
217 long minval
= - (1L << (length
- 1));
218 long maxval
= (1L << (length
- 1)) - 1;
219 if (value
< minval
|| value
> maxval
)
222 /* xgettext:c-format */
223 (errbuf
, _("operand out of range (%ld not between %ld and %ld)"),
224 value
, minval
, maxval
);
234 if (CGEN_INSN_LSB0_P
)
235 shift
= (start
+ 1) - length
;
237 shift
= word_length
- (start
+ length
);
238 *buffer
= (*buffer
& ~(mask
<< shift
)) | ((value
& mask
) << shift
);
241 #else /* ! CGEN_INT_INSN_P */
244 unsigned char *bufp
= (unsigned char *) buffer
+ word_offset
/ 8;
246 insert_1 (cd
, value
, start
, length
, word_length
, bufp
);
249 #endif /* ! CGEN_INT_INSN_P */
254 /* Default insn builder (insert handler).
255 The instruction is recorded in CGEN_INT_INSN_P byte order
256 (meaning that if CGEN_INT_INSN_P BUFFER is an int * and thus the value is
257 recorded in host byte order, otherwise BUFFER is an array of bytes and the
258 value is recorded in target byte order).
259 The result is an error message or NULL if success. */
262 insert_insn_normal (cd
, insn
, fields
, buffer
, pc
)
264 const CGEN_INSN
* insn
;
265 CGEN_FIELDS
* fields
;
266 CGEN_INSN_BYTES_PTR buffer
;
269 const CGEN_SYNTAX
*syntax
= CGEN_INSN_SYNTAX (insn
);
271 const unsigned char * syn
;
273 CGEN_INIT_INSERT (cd
);
274 value
= CGEN_INSN_BASE_VALUE (insn
);
276 /* If we're recording insns as numbers (rather than a string of bytes),
277 target byte order handling is deferred until later. */
285 cgen_put_insn_value (cd
, buffer
, min (cd
->base_insn_bitsize
,
286 CGEN_FIELDS_BITSIZE (fields
)),
289 #endif /* ! CGEN_INT_INSN_P */
291 /* ??? It would be better to scan the format's fields.
292 Still need to be able to insert a value based on the operand though;
293 e.g. storing a branch displacement that got resolved later.
294 Needs more thought first. */
296 for (syn
= CGEN_SYNTAX_STRING (syntax
); * syn
!= '\0'; ++ syn
)
300 if (CGEN_SYNTAX_CHAR_P (* syn
))
303 errmsg
= (* cd
->insert_operand
) (cd
, CGEN_SYNTAX_FIELD (*syn
),
312 /* Operand extraction. */
314 #if ! CGEN_INT_INSN_P
316 /* Subroutine of extract_normal.
317 Ensure sufficient bytes are cached in EX_INFO.
318 OFFSET is the offset in bytes from the start of the insn of the value.
319 BYTES is the length of the needed value.
320 Returns 1 for success, 0 for failure. */
322 static CGEN_INLINE
int
323 fill_cache (cd
, ex_info
, offset
, bytes
, pc
)
325 CGEN_EXTRACT_INFO
*ex_info
;
329 /* It's doubtful that the middle part has already been fetched so
330 we don't optimize that case. kiss. */
332 disassemble_info
*info
= (disassemble_info
*) ex_info
->dis_info
;
334 /* First do a quick check. */
335 mask
= (1 << bytes
) - 1;
336 if (((ex_info
->valid
>> offset
) & mask
) == mask
)
339 /* Search for the first byte we need to read. */
340 for (mask
= 1 << offset
; bytes
> 0; --bytes
, ++offset
, mask
<<= 1)
341 if (! (mask
& ex_info
->valid
))
349 status
= (*info
->read_memory_func
)
350 (pc
, ex_info
->insn_bytes
+ offset
, bytes
, info
);
354 (*info
->memory_error_func
) (status
, pc
, info
);
358 ex_info
->valid
|= ((1 << bytes
) - 1) << offset
;
364 /* Subroutine of extract_normal. */
366 static CGEN_INLINE
long
367 extract_1 (cd
, ex_info
, start
, length
, word_length
, bufp
, pc
)
369 CGEN_EXTRACT_INFO
*ex_info
;
370 int start
,length
,word_length
;
374 unsigned long x
,mask
;
376 int big_p
= CGEN_CPU_INSN_ENDIAN (cd
) == CGEN_ENDIAN_BIG
;
385 x
= bfd_getb16 (bufp
);
387 x
= bfd_getl16 (bufp
);
390 /* ??? This may need reworking as these cases don't necessarily
391 want the first byte and the last two bytes handled like this. */
393 x
= (bufp
[0] << 16) | bfd_getb16 (bufp
+ 1);
395 x
= bfd_getl16 (bufp
) | (bufp
[2] << 16);
399 x
= bfd_getb32 (bufp
);
401 x
= bfd_getl32 (bufp
);
407 /* Written this way to avoid undefined behaviour. */
408 mask
= (((1L << (length
- 1)) - 1) << 1) | 1;
409 if (CGEN_INSN_LSB0_P
)
410 shift
= (start
+ 1) - length
;
412 shift
= (word_length
- (start
+ length
));
413 return (x
>> shift
) & mask
;
416 #endif /* ! CGEN_INT_INSN_P */
418 /* Default extraction routine.
420 INSN_VALUE is the first base_insn_bitsize bits of the insn in host order,
421 or sometimes less for cases like the m32r where the base insn size is 32
422 but some insns are 16 bits.
423 ATTRS is a mask of the boolean attributes. We only need `SIGNED',
424 but for generality we take a bitmask of all of them.
425 WORD_OFFSET is the offset in bits from the start of the insn of the value.
426 WORD_LENGTH is the length of the word in bits in which the value resides.
427 START is the starting bit number in the word, architecture origin.
428 LENGTH is the length of VALUE in bits.
429 TOTAL_LENGTH is the total length of the insn in bits.
431 Returns 1 for success, 0 for failure. */
433 /* ??? The return code isn't properly used. wip. */
435 /* ??? This doesn't handle bfd_vma's. Create another function when
439 extract_normal (cd
, ex_info
, insn_value
, attrs
, word_offset
, start
, length
,
440 word_length
, total_length
, pc
, valuep
)
442 CGEN_EXTRACT_INFO
*ex_info
;
443 CGEN_INSN_INT insn_value
;
445 unsigned int word_offset
, start
, length
, word_length
, total_length
;
451 /* If LENGTH is zero, this operand doesn't contribute to the value
452 so give it a standard value of zero. */
463 if (word_length
> 32)
466 /* For architectures with insns smaller than the insn-base-bitsize,
467 word_length may be too big. */
468 if (cd
->min_insn_bitsize
< cd
->base_insn_bitsize
)
471 && word_length
> total_length
)
472 word_length
= total_length
;
475 /* Does the value reside in INSN_VALUE? */
477 if (word_offset
== 0)
479 /* Written this way to avoid undefined behaviour. */
480 CGEN_INSN_INT mask
= (((1L << (length
- 1)) - 1) << 1) | 1;
482 if (CGEN_INSN_LSB0_P
)
483 value
= insn_value
>> ((start
+ 1) - length
);
485 value
= insn_value
>> (word_length
- (start
+ length
));
488 if (CGEN_BOOL_ATTR (attrs
, CGEN_IFLD_SIGNED
)
489 && (value
& (1L << (length
- 1))))
493 #if ! CGEN_INT_INSN_P
497 unsigned char *bufp
= ex_info
->insn_bytes
+ word_offset
/ 8;
499 if (word_length
> 32)
502 if (fill_cache (cd
, ex_info
, word_offset
/ 8, word_length
/ 8, pc
) == 0)
505 value
= extract_1 (cd
, ex_info
, start
, length
, word_length
, bufp
, pc
);
508 #endif /* ! CGEN_INT_INSN_P */
515 /* Default insn extractor.
517 INSN_VALUE is the first base_insn_bitsize bits, translated to host order.
518 The extracted fields are stored in FIELDS.
519 EX_INFO is used to handle reading variable length insns.
520 Return the length of the insn in bits, or 0 if no match,
521 or -1 if an error occurs fetching data (memory_error_func will have
525 extract_insn_normal (cd
, insn
, ex_info
, insn_value
, fields
, pc
)
527 const CGEN_INSN
*insn
;
528 CGEN_EXTRACT_INFO
*ex_info
;
529 CGEN_INSN_INT insn_value
;
533 const CGEN_SYNTAX
*syntax
= CGEN_INSN_SYNTAX (insn
);
534 const unsigned char *syn
;
536 CGEN_FIELDS_BITSIZE (fields
) = CGEN_INSN_BITSIZE (insn
);
538 CGEN_INIT_EXTRACT (cd
);
540 for (syn
= CGEN_SYNTAX_STRING (syntax
); *syn
; ++syn
)
544 if (CGEN_SYNTAX_CHAR_P (*syn
))
547 length
= (* cd
->extract_operand
) (cd
, CGEN_SYNTAX_FIELD (*syn
),
548 ex_info
, insn_value
, fields
, pc
);
553 /* We recognized and successfully extracted this insn. */
554 return CGEN_INSN_BITSIZE (insn
);
557 /* machine generated code added here */
559 /* Main entry point for operand insertion.
561 This function is basically just a big switch statement. Earlier versions
562 used tables to look up the function to use, but
563 - if the table contains both assembler and disassembler functions then
564 the disassembler contains much of the assembler and vice-versa,
565 - there's a lot of inlining possibilities as things grow,
566 - using a switch statement avoids the function call overhead.
568 This function could be moved into `parse_insn_normal', but keeping it
569 separate makes clear the interface between `parse_insn_normal' and each of
570 the handlers. It's also needed by GAS to insert operands that couldn't be
571 resolved during parsing.
575 m32r_cgen_insert_operand (cd
, opindex
, fields
, buffer
, pc
)
578 CGEN_FIELDS
* fields
;
579 CGEN_INSN_BYTES_PTR buffer
;
582 const char * errmsg
= NULL
;
583 unsigned int total_length
= CGEN_FIELDS_BITSIZE (fields
);
587 case M32R_OPERAND_DCR
:
588 errmsg
= insert_normal (cd
, fields
->f_r1
, 0, 0, 4, 4, 32, total_length
, buffer
);
590 case M32R_OPERAND_DISP16
:
592 long value
= fields
->f_disp16
;
593 value
= ((int) (((value
) - (pc
))) >> (2));
594 errmsg
= insert_normal (cd
, value
, 0|(1<<CGEN_IFLD_SIGNED
)|(1<<CGEN_IFLD_RELOC
)|(1<<CGEN_IFLD_PCREL_ADDR
), 0, 16, 16, 32, total_length
, buffer
);
597 case M32R_OPERAND_DISP24
:
599 long value
= fields
->f_disp24
;
600 value
= ((int) (((value
) - (pc
))) >> (2));
601 errmsg
= insert_normal (cd
, value
, 0|(1<<CGEN_IFLD_SIGNED
)|(1<<CGEN_IFLD_RELOC
)|(1<<CGEN_IFLD_PCREL_ADDR
), 0, 8, 24, 32, total_length
, buffer
);
604 case M32R_OPERAND_DISP8
:
606 long value
= fields
->f_disp8
;
607 value
= ((int) (((value
) - (((pc
) & (-4))))) >> (2));
608 errmsg
= insert_normal (cd
, value
, 0|(1<<CGEN_IFLD_SIGNED
)|(1<<CGEN_IFLD_RELOC
)|(1<<CGEN_IFLD_PCREL_ADDR
), 0, 8, 8, 32, total_length
, buffer
);
611 case M32R_OPERAND_DR
:
612 errmsg
= insert_normal (cd
, fields
->f_r1
, 0, 0, 4, 4, 32, total_length
, buffer
);
614 case M32R_OPERAND_HASH
:
616 case M32R_OPERAND_HI16
:
617 errmsg
= insert_normal (cd
, fields
->f_hi16
, 0|(1<<CGEN_IFLD_SIGN_OPT
), 0, 16, 16, 32, total_length
, buffer
);
619 case M32R_OPERAND_SCR
:
620 errmsg
= insert_normal (cd
, fields
->f_r2
, 0, 0, 12, 4, 32, total_length
, buffer
);
622 case M32R_OPERAND_SIMM16
:
623 errmsg
= insert_normal (cd
, fields
->f_simm16
, 0|(1<<CGEN_IFLD_SIGNED
), 0, 16, 16, 32, total_length
, buffer
);
625 case M32R_OPERAND_SIMM8
:
626 errmsg
= insert_normal (cd
, fields
->f_simm8
, 0|(1<<CGEN_IFLD_SIGNED
), 0, 8, 8, 32, total_length
, buffer
);
628 case M32R_OPERAND_SLO16
:
629 errmsg
= insert_normal (cd
, fields
->f_simm16
, 0|(1<<CGEN_IFLD_SIGNED
), 0, 16, 16, 32, total_length
, buffer
);
631 case M32R_OPERAND_SR
:
632 errmsg
= insert_normal (cd
, fields
->f_r2
, 0, 0, 12, 4, 32, total_length
, buffer
);
634 case M32R_OPERAND_SRC1
:
635 errmsg
= insert_normal (cd
, fields
->f_r1
, 0, 0, 4, 4, 32, total_length
, buffer
);
637 case M32R_OPERAND_SRC2
:
638 errmsg
= insert_normal (cd
, fields
->f_r2
, 0, 0, 12, 4, 32, total_length
, buffer
);
640 case M32R_OPERAND_UIMM16
:
641 errmsg
= insert_normal (cd
, fields
->f_uimm16
, 0, 0, 16, 16, 32, total_length
, buffer
);
643 case M32R_OPERAND_UIMM24
:
644 errmsg
= insert_normal (cd
, fields
->f_uimm24
, 0|(1<<CGEN_IFLD_RELOC
)|(1<<CGEN_IFLD_ABS_ADDR
), 0, 8, 24, 32, total_length
, buffer
);
646 case M32R_OPERAND_UIMM4
:
647 errmsg
= insert_normal (cd
, fields
->f_uimm4
, 0, 0, 12, 4, 32, total_length
, buffer
);
649 case M32R_OPERAND_UIMM5
:
650 errmsg
= insert_normal (cd
, fields
->f_uimm5
, 0, 0, 11, 5, 32, total_length
, buffer
);
652 case M32R_OPERAND_ULO16
:
653 errmsg
= insert_normal (cd
, fields
->f_uimm16
, 0, 0, 16, 16, 32, total_length
, buffer
);
657 /* xgettext:c-format */
658 fprintf (stderr
, _("Unrecognized field %d while building insn.\n"),
666 /* Main entry point for operand extraction.
667 The result is <= 0 for error, >0 for success.
668 ??? Actual values aren't well defined right now.
670 This function is basically just a big switch statement. Earlier versions
671 used tables to look up the function to use, but
672 - if the table contains both assembler and disassembler functions then
673 the disassembler contains much of the assembler and vice-versa,
674 - there's a lot of inlining possibilities as things grow,
675 - using a switch statement avoids the function call overhead.
677 This function could be moved into `print_insn_normal', but keeping it
678 separate makes clear the interface between `print_insn_normal' and each of
683 m32r_cgen_extract_operand (cd
, opindex
, ex_info
, insn_value
, fields
, pc
)
686 CGEN_EXTRACT_INFO
*ex_info
;
687 CGEN_INSN_INT insn_value
;
688 CGEN_FIELDS
* fields
;
691 /* Assume success (for those operands that are nops). */
693 unsigned int total_length
= CGEN_FIELDS_BITSIZE (fields
);
697 case M32R_OPERAND_DCR
:
698 length
= extract_normal (cd
, ex_info
, insn_value
, 0, 0, 4, 4, 32, total_length
, pc
, & fields
->f_r1
);
700 case M32R_OPERAND_DISP16
:
703 length
= extract_normal (cd
, ex_info
, insn_value
, 0|(1<<CGEN_IFLD_SIGNED
)|(1<<CGEN_IFLD_RELOC
)|(1<<CGEN_IFLD_PCREL_ADDR
), 0, 16, 16, 32, total_length
, pc
, & value
);
704 value
= ((((value
) << (2))) + (pc
));
705 fields
->f_disp16
= value
;
708 case M32R_OPERAND_DISP24
:
711 length
= extract_normal (cd
, ex_info
, insn_value
, 0|(1<<CGEN_IFLD_SIGNED
)|(1<<CGEN_IFLD_RELOC
)|(1<<CGEN_IFLD_PCREL_ADDR
), 0, 8, 24, 32, total_length
, pc
, & value
);
712 value
= ((((value
) << (2))) + (pc
));
713 fields
->f_disp24
= value
;
716 case M32R_OPERAND_DISP8
:
719 length
= extract_normal (cd
, ex_info
, insn_value
, 0|(1<<CGEN_IFLD_SIGNED
)|(1<<CGEN_IFLD_RELOC
)|(1<<CGEN_IFLD_PCREL_ADDR
), 0, 8, 8, 32, total_length
, pc
, & value
);
720 value
= ((((value
) << (2))) + (((pc
) & (-4))));
721 fields
->f_disp8
= value
;
724 case M32R_OPERAND_DR
:
725 length
= extract_normal (cd
, ex_info
, insn_value
, 0, 0, 4, 4, 32, total_length
, pc
, & fields
->f_r1
);
727 case M32R_OPERAND_HASH
:
729 case M32R_OPERAND_HI16
:
730 length
= extract_normal (cd
, ex_info
, insn_value
, 0|(1<<CGEN_IFLD_SIGN_OPT
), 0, 16, 16, 32, total_length
, pc
, & fields
->f_hi16
);
732 case M32R_OPERAND_SCR
:
733 length
= extract_normal (cd
, ex_info
, insn_value
, 0, 0, 12, 4, 32, total_length
, pc
, & fields
->f_r2
);
735 case M32R_OPERAND_SIMM16
:
736 length
= extract_normal (cd
, ex_info
, insn_value
, 0|(1<<CGEN_IFLD_SIGNED
), 0, 16, 16, 32, total_length
, pc
, & fields
->f_simm16
);
738 case M32R_OPERAND_SIMM8
:
739 length
= extract_normal (cd
, ex_info
, insn_value
, 0|(1<<CGEN_IFLD_SIGNED
), 0, 8, 8, 32, total_length
, pc
, & fields
->f_simm8
);
741 case M32R_OPERAND_SLO16
:
742 length
= extract_normal (cd
, ex_info
, insn_value
, 0|(1<<CGEN_IFLD_SIGNED
), 0, 16, 16, 32, total_length
, pc
, & fields
->f_simm16
);
744 case M32R_OPERAND_SR
:
745 length
= extract_normal (cd
, ex_info
, insn_value
, 0, 0, 12, 4, 32, total_length
, pc
, & fields
->f_r2
);
747 case M32R_OPERAND_SRC1
:
748 length
= extract_normal (cd
, ex_info
, insn_value
, 0, 0, 4, 4, 32, total_length
, pc
, & fields
->f_r1
);
750 case M32R_OPERAND_SRC2
:
751 length
= extract_normal (cd
, ex_info
, insn_value
, 0, 0, 12, 4, 32, total_length
, pc
, & fields
->f_r2
);
753 case M32R_OPERAND_UIMM16
:
754 length
= extract_normal (cd
, ex_info
, insn_value
, 0, 0, 16, 16, 32, total_length
, pc
, & fields
->f_uimm16
);
756 case M32R_OPERAND_UIMM24
:
757 length
= extract_normal (cd
, ex_info
, insn_value
, 0|(1<<CGEN_IFLD_RELOC
)|(1<<CGEN_IFLD_ABS_ADDR
), 0, 8, 24, 32, total_length
, pc
, & fields
->f_uimm24
);
759 case M32R_OPERAND_UIMM4
:
760 length
= extract_normal (cd
, ex_info
, insn_value
, 0, 0, 12, 4, 32, total_length
, pc
, & fields
->f_uimm4
);
762 case M32R_OPERAND_UIMM5
:
763 length
= extract_normal (cd
, ex_info
, insn_value
, 0, 0, 11, 5, 32, total_length
, pc
, & fields
->f_uimm5
);
765 case M32R_OPERAND_ULO16
:
766 length
= extract_normal (cd
, ex_info
, insn_value
, 0, 0, 16, 16, 32, total_length
, pc
, & fields
->f_uimm16
);
770 /* xgettext:c-format */
771 fprintf (stderr
, _("Unrecognized field %d while decoding insn.\n"),
779 cgen_insert_fn
* const m32r_cgen_insert_handlers
[] =
784 cgen_extract_fn
* const m32r_cgen_extract_handlers
[] =
789 /* Getting values from cgen_fields is handled by a collection of functions.
790 They are distinguished by the type of the VALUE argument they return.
791 TODO: floating point, inlining support, remove cases where result type
795 m32r_cgen_get_int_operand (cd
, opindex
, fields
)
798 const CGEN_FIELDS
* fields
;
804 case M32R_OPERAND_DCR
:
805 value
= fields
->f_r1
;
807 case M32R_OPERAND_DISP16
:
808 value
= fields
->f_disp16
;
810 case M32R_OPERAND_DISP24
:
811 value
= fields
->f_disp24
;
813 case M32R_OPERAND_DISP8
:
814 value
= fields
->f_disp8
;
816 case M32R_OPERAND_DR
:
817 value
= fields
->f_r1
;
819 case M32R_OPERAND_HASH
:
822 case M32R_OPERAND_HI16
:
823 value
= fields
->f_hi16
;
825 case M32R_OPERAND_SCR
:
826 value
= fields
->f_r2
;
828 case M32R_OPERAND_SIMM16
:
829 value
= fields
->f_simm16
;
831 case M32R_OPERAND_SIMM8
:
832 value
= fields
->f_simm8
;
834 case M32R_OPERAND_SLO16
:
835 value
= fields
->f_simm16
;
837 case M32R_OPERAND_SR
:
838 value
= fields
->f_r2
;
840 case M32R_OPERAND_SRC1
:
841 value
= fields
->f_r1
;
843 case M32R_OPERAND_SRC2
:
844 value
= fields
->f_r2
;
846 case M32R_OPERAND_UIMM16
:
847 value
= fields
->f_uimm16
;
849 case M32R_OPERAND_UIMM24
:
850 value
= fields
->f_uimm24
;
852 case M32R_OPERAND_UIMM4
:
853 value
= fields
->f_uimm4
;
855 case M32R_OPERAND_UIMM5
:
856 value
= fields
->f_uimm5
;
858 case M32R_OPERAND_ULO16
:
859 value
= fields
->f_uimm16
;
863 /* xgettext:c-format */
864 fprintf (stderr
, _("Unrecognized field %d while getting int operand.\n"),
873 m32r_cgen_get_vma_operand (cd
, opindex
, fields
)
876 const CGEN_FIELDS
* fields
;
882 case M32R_OPERAND_DCR
:
883 value
= fields
->f_r1
;
885 case M32R_OPERAND_DISP16
:
886 value
= fields
->f_disp16
;
888 case M32R_OPERAND_DISP24
:
889 value
= fields
->f_disp24
;
891 case M32R_OPERAND_DISP8
:
892 value
= fields
->f_disp8
;
894 case M32R_OPERAND_DR
:
895 value
= fields
->f_r1
;
897 case M32R_OPERAND_HASH
:
900 case M32R_OPERAND_HI16
:
901 value
= fields
->f_hi16
;
903 case M32R_OPERAND_SCR
:
904 value
= fields
->f_r2
;
906 case M32R_OPERAND_SIMM16
:
907 value
= fields
->f_simm16
;
909 case M32R_OPERAND_SIMM8
:
910 value
= fields
->f_simm8
;
912 case M32R_OPERAND_SLO16
:
913 value
= fields
->f_simm16
;
915 case M32R_OPERAND_SR
:
916 value
= fields
->f_r2
;
918 case M32R_OPERAND_SRC1
:
919 value
= fields
->f_r1
;
921 case M32R_OPERAND_SRC2
:
922 value
= fields
->f_r2
;
924 case M32R_OPERAND_UIMM16
:
925 value
= fields
->f_uimm16
;
927 case M32R_OPERAND_UIMM24
:
928 value
= fields
->f_uimm24
;
930 case M32R_OPERAND_UIMM4
:
931 value
= fields
->f_uimm4
;
933 case M32R_OPERAND_UIMM5
:
934 value
= fields
->f_uimm5
;
936 case M32R_OPERAND_ULO16
:
937 value
= fields
->f_uimm16
;
941 /* xgettext:c-format */
942 fprintf (stderr
, _("Unrecognized field %d while getting vma operand.\n"),
950 /* Stuffing values in cgen_fields is handled by a collection of functions.
951 They are distinguished by the type of the VALUE argument they accept.
952 TODO: floating point, inlining support, remove cases where argument type
956 m32r_cgen_set_int_operand (cd
, opindex
, fields
, value
)
959 CGEN_FIELDS
* fields
;
964 case M32R_OPERAND_DCR
:
965 fields
->f_r1
= value
;
967 case M32R_OPERAND_DISP16
:
968 fields
->f_disp16
= value
;
970 case M32R_OPERAND_DISP24
:
971 fields
->f_disp24
= value
;
973 case M32R_OPERAND_DISP8
:
974 fields
->f_disp8
= value
;
976 case M32R_OPERAND_DR
:
977 fields
->f_r1
= value
;
979 case M32R_OPERAND_HASH
:
981 case M32R_OPERAND_HI16
:
982 fields
->f_hi16
= value
;
984 case M32R_OPERAND_SCR
:
985 fields
->f_r2
= value
;
987 case M32R_OPERAND_SIMM16
:
988 fields
->f_simm16
= value
;
990 case M32R_OPERAND_SIMM8
:
991 fields
->f_simm8
= value
;
993 case M32R_OPERAND_SLO16
:
994 fields
->f_simm16
= value
;
996 case M32R_OPERAND_SR
:
997 fields
->f_r2
= value
;
999 case M32R_OPERAND_SRC1
:
1000 fields
->f_r1
= value
;
1002 case M32R_OPERAND_SRC2
:
1003 fields
->f_r2
= value
;
1005 case M32R_OPERAND_UIMM16
:
1006 fields
->f_uimm16
= value
;
1008 case M32R_OPERAND_UIMM24
:
1009 fields
->f_uimm24
= value
;
1011 case M32R_OPERAND_UIMM4
:
1012 fields
->f_uimm4
= value
;
1014 case M32R_OPERAND_UIMM5
:
1015 fields
->f_uimm5
= value
;
1017 case M32R_OPERAND_ULO16
:
1018 fields
->f_uimm16
= value
;
1022 /* xgettext:c-format */
1023 fprintf (stderr
, _("Unrecognized field %d while setting int operand.\n"),
1030 m32r_cgen_set_vma_operand (cd
, opindex
, fields
, value
)
1033 CGEN_FIELDS
* fields
;
1038 case M32R_OPERAND_DCR
:
1039 fields
->f_r1
= value
;
1041 case M32R_OPERAND_DISP16
:
1042 fields
->f_disp16
= value
;
1044 case M32R_OPERAND_DISP24
:
1045 fields
->f_disp24
= value
;
1047 case M32R_OPERAND_DISP8
:
1048 fields
->f_disp8
= value
;
1050 case M32R_OPERAND_DR
:
1051 fields
->f_r1
= value
;
1053 case M32R_OPERAND_HASH
:
1055 case M32R_OPERAND_HI16
:
1056 fields
->f_hi16
= value
;
1058 case M32R_OPERAND_SCR
:
1059 fields
->f_r2
= value
;
1061 case M32R_OPERAND_SIMM16
:
1062 fields
->f_simm16
= value
;
1064 case M32R_OPERAND_SIMM8
:
1065 fields
->f_simm8
= value
;
1067 case M32R_OPERAND_SLO16
:
1068 fields
->f_simm16
= value
;
1070 case M32R_OPERAND_SR
:
1071 fields
->f_r2
= value
;
1073 case M32R_OPERAND_SRC1
:
1074 fields
->f_r1
= value
;
1076 case M32R_OPERAND_SRC2
:
1077 fields
->f_r2
= value
;
1079 case M32R_OPERAND_UIMM16
:
1080 fields
->f_uimm16
= value
;
1082 case M32R_OPERAND_UIMM24
:
1083 fields
->f_uimm24
= value
;
1085 case M32R_OPERAND_UIMM4
:
1086 fields
->f_uimm4
= value
;
1088 case M32R_OPERAND_UIMM5
:
1089 fields
->f_uimm5
= value
;
1091 case M32R_OPERAND_ULO16
:
1092 fields
->f_uimm16
= value
;
1096 /* xgettext:c-format */
1097 fprintf (stderr
, _("Unrecognized field %d while setting vma operand.\n"),
1103 /* Function to call before using the instruction builder tables. */
1106 m32r_cgen_init_ibld_table (cd
)
1109 cd
->insert_handlers
= & m32r_cgen_insert_handlers
[0];
1110 cd
->extract_handlers
= & m32r_cgen_extract_handlers
[0];
1112 cd
->insert_operand
= m32r_cgen_insert_operand
;
1113 cd
->extract_operand
= m32r_cgen_extract_operand
;
1115 cd
->get_int_operand
= m32r_cgen_get_int_operand
;
1116 cd
->set_int_operand
= m32r_cgen_set_int_operand
;
1117 cd
->get_vma_operand
= m32r_cgen_get_vma_operand
;
1118 cd
->set_vma_operand
= m32r_cgen_set_vma_operand
;