1 /* Instruction building/extraction support for openrisc. -*- 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, 2005
7 Free Software Foundation, Inc.
9 This file is part of the GNU Binutils and GDB, the GNU debugger.
11 This program is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation; either version 2, or (at your option)
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details.
21 You should have received a copy of the GNU General Public License
22 along with this program; if not, write to the Free Software Foundation, Inc.,
23 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */
25 /* ??? Eventually more and more of this stuff can go to cpu-independent files.
34 #include "openrisc-desc.h"
35 #include "openrisc-opc.h"
37 #include "safe-ctype.h"
40 #define min(a,b) ((a) < (b) ? (a) : (b))
42 #define max(a,b) ((a) > (b) ? (a) : (b))
44 /* Used by the ifield rtx function. */
45 #define FLD(f) (fields->f)
47 static const char * insert_normal
48 (CGEN_CPU_DESC
, long, unsigned int, unsigned int, unsigned int,
49 unsigned int, unsigned int, unsigned int, CGEN_INSN_BYTES_PTR
);
50 static const char * insert_insn_normal
51 (CGEN_CPU_DESC
, const CGEN_INSN
*,
52 CGEN_FIELDS
*, CGEN_INSN_BYTES_PTR
, bfd_vma
);
53 static int extract_normal
54 (CGEN_CPU_DESC
, CGEN_EXTRACT_INFO
*, CGEN_INSN_INT
,
55 unsigned int, unsigned int, unsigned int, unsigned int,
56 unsigned int, unsigned int, bfd_vma
, long *);
57 static int extract_insn_normal
58 (CGEN_CPU_DESC
, const CGEN_INSN
*, CGEN_EXTRACT_INFO
*,
59 CGEN_INSN_INT
, CGEN_FIELDS
*, bfd_vma
);
61 static void put_insn_int_value
62 (CGEN_CPU_DESC
, CGEN_INSN_BYTES_PTR
, int, int, CGEN_INSN_INT
);
65 static CGEN_INLINE
void insert_1
66 (CGEN_CPU_DESC
, unsigned long, int, int, int, unsigned char *);
67 static CGEN_INLINE
int fill_cache
68 (CGEN_CPU_DESC
, CGEN_EXTRACT_INFO
*, int, int, bfd_vma
);
69 static CGEN_INLINE
long extract_1
70 (CGEN_CPU_DESC
, CGEN_EXTRACT_INFO
*, int, int, int, unsigned char *, bfd_vma
);
73 /* Operand insertion. */
77 /* Subroutine of insert_normal. */
79 static CGEN_INLINE
void
80 insert_1 (CGEN_CPU_DESC cd
,
90 x
= cgen_get_insn_value (cd
, bufp
, word_length
);
92 /* Written this way to avoid undefined behaviour. */
93 mask
= (((1L << (length
- 1)) - 1) << 1) | 1;
95 shift
= (start
+ 1) - length
;
97 shift
= (word_length
- (start
+ length
));
98 x
= (x
& ~(mask
<< shift
)) | ((value
& mask
) << shift
);
100 cgen_put_insn_value (cd
, bufp
, word_length
, (bfd_vma
) x
);
103 #endif /* ! CGEN_INT_INSN_P */
105 /* Default insertion routine.
107 ATTRS is a mask of the boolean attributes.
108 WORD_OFFSET is the offset in bits from the start of the insn of the value.
109 WORD_LENGTH is the length of the word in bits in which the value resides.
110 START is the starting bit number in the word, architecture origin.
111 LENGTH is the length of VALUE in bits.
112 TOTAL_LENGTH is the total length of the insn in bits.
114 The result is an error message or NULL if success. */
116 /* ??? This duplicates functionality with bfd's howto table and
117 bfd_install_relocation. */
118 /* ??? This doesn't handle bfd_vma's. Create another function when
122 insert_normal (CGEN_CPU_DESC cd
,
125 unsigned int word_offset
,
128 unsigned int word_length
,
129 unsigned int total_length
,
130 CGEN_INSN_BYTES_PTR buffer
)
132 static char errbuf
[100];
133 /* Written this way to avoid undefined behaviour. */
134 unsigned long mask
= (((1L << (length
- 1)) - 1) << 1) | 1;
136 /* If LENGTH is zero, this operand doesn't contribute to the value. */
140 if (word_length
> 32)
143 /* For architectures with insns smaller than the base-insn-bitsize,
144 word_length may be too big. */
145 if (cd
->min_insn_bitsize
< cd
->base_insn_bitsize
)
148 && word_length
> total_length
)
149 word_length
= total_length
;
152 /* Ensure VALUE will fit. */
153 if (CGEN_BOOL_ATTR (attrs
, CGEN_IFLD_SIGN_OPT
))
155 long minval
= - (1L << (length
- 1));
156 unsigned long maxval
= mask
;
158 if ((value
> 0 && (unsigned long) value
> maxval
)
161 /* xgettext:c-format */
163 _("operand out of range (%ld not between %ld and %lu)"),
164 value
, minval
, maxval
);
168 else if (! CGEN_BOOL_ATTR (attrs
, CGEN_IFLD_SIGNED
))
170 unsigned long maxval
= mask
;
172 if ((unsigned long) value
> maxval
)
174 /* xgettext:c-format */
176 _("operand out of range (%lu not between 0 and %lu)"),
183 if (! cgen_signed_overflow_ok_p (cd
))
185 long minval
= - (1L << (length
- 1));
186 long maxval
= (1L << (length
- 1)) - 1;
188 if (value
< minval
|| value
> maxval
)
191 /* xgettext:c-format */
192 (errbuf
, _("operand out of range (%ld not between %ld and %ld)"),
193 value
, minval
, maxval
);
204 if (CGEN_INSN_LSB0_P
)
205 shift
= (word_offset
+ start
+ 1) - length
;
207 shift
= total_length
- (word_offset
+ start
+ length
);
208 *buffer
= (*buffer
& ~(mask
<< shift
)) | ((value
& mask
) << shift
);
211 #else /* ! CGEN_INT_INSN_P */
214 unsigned char *bufp
= (unsigned char *) buffer
+ word_offset
/ 8;
216 insert_1 (cd
, value
, start
, length
, word_length
, bufp
);
219 #endif /* ! CGEN_INT_INSN_P */
224 /* Default insn builder (insert handler).
225 The instruction is recorded in CGEN_INT_INSN_P byte order (meaning
226 that if CGEN_INSN_BYTES_PTR is an int * and thus, the value is
227 recorded in host byte order, otherwise BUFFER is an array of bytes
228 and the value is recorded in target byte order).
229 The result is an error message or NULL if success. */
232 insert_insn_normal (CGEN_CPU_DESC cd
,
233 const CGEN_INSN
* insn
,
234 CGEN_FIELDS
* fields
,
235 CGEN_INSN_BYTES_PTR buffer
,
238 const CGEN_SYNTAX
*syntax
= CGEN_INSN_SYNTAX (insn
);
240 const CGEN_SYNTAX_CHAR_TYPE
* syn
;
242 CGEN_INIT_INSERT (cd
);
243 value
= CGEN_INSN_BASE_VALUE (insn
);
245 /* If we're recording insns as numbers (rather than a string of bytes),
246 target byte order handling is deferred until later. */
250 put_insn_int_value (cd
, buffer
, cd
->base_insn_bitsize
,
251 CGEN_FIELDS_BITSIZE (fields
), value
);
255 cgen_put_insn_value (cd
, buffer
, min ((unsigned) cd
->base_insn_bitsize
,
256 (unsigned) CGEN_FIELDS_BITSIZE (fields
)),
259 #endif /* ! CGEN_INT_INSN_P */
261 /* ??? It would be better to scan the format's fields.
262 Still need to be able to insert a value based on the operand though;
263 e.g. storing a branch displacement that got resolved later.
264 Needs more thought first. */
266 for (syn
= CGEN_SYNTAX_STRING (syntax
); * syn
; ++ syn
)
270 if (CGEN_SYNTAX_CHAR_P (* syn
))
273 errmsg
= (* cd
->insert_operand
) (cd
, CGEN_SYNTAX_FIELD (*syn
),
283 /* Cover function to store an insn value into an integral insn. Must go here
284 because it needs <prefix>-desc.h for CGEN_INT_INSN_P. */
287 put_insn_int_value (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED
,
288 CGEN_INSN_BYTES_PTR buf
,
293 /* For architectures with insns smaller than the base-insn-bitsize,
294 length may be too big. */
295 if (length
> insn_length
)
299 int shift
= insn_length
- length
;
300 /* Written this way to avoid undefined behaviour. */
301 CGEN_INSN_INT mask
= (((1L << (length
- 1)) - 1) << 1) | 1;
303 *buf
= (*buf
& ~(mask
<< shift
)) | ((value
& mask
) << shift
);
308 /* Operand extraction. */
310 #if ! CGEN_INT_INSN_P
312 /* Subroutine of extract_normal.
313 Ensure sufficient bytes are cached in EX_INFO.
314 OFFSET is the offset in bytes from the start of the insn of the value.
315 BYTES is the length of the needed value.
316 Returns 1 for success, 0 for failure. */
318 static CGEN_INLINE
int
319 fill_cache (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED
,
320 CGEN_EXTRACT_INFO
*ex_info
,
325 /* It's doubtful that the middle part has already been fetched so
326 we don't optimize that case. kiss. */
328 disassemble_info
*info
= (disassemble_info
*) ex_info
->dis_info
;
330 /* First do a quick check. */
331 mask
= (1 << bytes
) - 1;
332 if (((ex_info
->valid
>> offset
) & mask
) == mask
)
335 /* Search for the first byte we need to read. */
336 for (mask
= 1 << offset
; bytes
> 0; --bytes
, ++offset
, mask
<<= 1)
337 if (! (mask
& ex_info
->valid
))
345 status
= (*info
->read_memory_func
)
346 (pc
, ex_info
->insn_bytes
+ offset
, bytes
, info
);
350 (*info
->memory_error_func
) (status
, pc
, info
);
354 ex_info
->valid
|= ((1 << bytes
) - 1) << offset
;
360 /* Subroutine of extract_normal. */
362 static CGEN_INLINE
long
363 extract_1 (CGEN_CPU_DESC cd
,
364 CGEN_EXTRACT_INFO
*ex_info ATTRIBUTE_UNUSED
,
369 bfd_vma pc ATTRIBUTE_UNUSED
)
374 x
= cgen_get_insn_value (cd
, bufp
, word_length
);
376 if (CGEN_INSN_LSB0_P
)
377 shift
= (start
+ 1) - length
;
379 shift
= (word_length
- (start
+ length
));
383 #endif /* ! CGEN_INT_INSN_P */
385 /* Default extraction routine.
387 INSN_VALUE is the first base_insn_bitsize bits of the insn in host order,
388 or sometimes less for cases like the m32r where the base insn size is 32
389 but some insns are 16 bits.
390 ATTRS is a mask of the boolean attributes. We only need `SIGNED',
391 but for generality we take a bitmask of all of them.
392 WORD_OFFSET is the offset in bits from the start of the insn of the value.
393 WORD_LENGTH is the length of the word in bits in which the value resides.
394 START is the starting bit number in the word, architecture origin.
395 LENGTH is the length of VALUE in bits.
396 TOTAL_LENGTH is the total length of the insn in bits.
398 Returns 1 for success, 0 for failure. */
400 /* ??? The return code isn't properly used. wip. */
402 /* ??? This doesn't handle bfd_vma's. Create another function when
406 extract_normal (CGEN_CPU_DESC cd
,
407 #if ! CGEN_INT_INSN_P
408 CGEN_EXTRACT_INFO
*ex_info
,
410 CGEN_EXTRACT_INFO
*ex_info ATTRIBUTE_UNUSED
,
412 CGEN_INSN_INT insn_value
,
414 unsigned int word_offset
,
417 unsigned int word_length
,
418 unsigned int total_length
,
419 #if ! CGEN_INT_INSN_P
422 bfd_vma pc ATTRIBUTE_UNUSED
,
428 /* If LENGTH is zero, this operand doesn't contribute to the value
429 so give it a standard value of zero. */
436 if (word_length
> 32)
439 /* For architectures with insns smaller than the insn-base-bitsize,
440 word_length may be too big. */
441 if (cd
->min_insn_bitsize
< cd
->base_insn_bitsize
)
444 && word_length
> total_length
)
445 word_length
= total_length
;
448 /* Does the value reside in INSN_VALUE, and at the right alignment? */
450 if (CGEN_INT_INSN_P
|| (word_offset
== 0 && word_length
== total_length
))
452 if (CGEN_INSN_LSB0_P
)
453 value
= insn_value
>> ((word_offset
+ start
+ 1) - length
);
455 value
= insn_value
>> (total_length
- ( word_offset
+ start
+ length
));
458 #if ! CGEN_INT_INSN_P
462 unsigned char *bufp
= ex_info
->insn_bytes
+ word_offset
/ 8;
464 if (word_length
> 32)
467 if (fill_cache (cd
, ex_info
, word_offset
/ 8, word_length
/ 8, pc
) == 0)
470 value
= extract_1 (cd
, ex_info
, start
, length
, word_length
, bufp
, pc
);
473 #endif /* ! CGEN_INT_INSN_P */
475 /* Written this way to avoid undefined behaviour. */
476 mask
= (((1L << (length
- 1)) - 1) << 1) | 1;
480 if (CGEN_BOOL_ATTR (attrs
, CGEN_IFLD_SIGNED
)
481 && (value
& (1L << (length
- 1))))
489 /* Default insn extractor.
491 INSN_VALUE is the first base_insn_bitsize bits, translated to host order.
492 The extracted fields are stored in FIELDS.
493 EX_INFO is used to handle reading variable length insns.
494 Return the length of the insn in bits, or 0 if no match,
495 or -1 if an error occurs fetching data (memory_error_func will have
499 extract_insn_normal (CGEN_CPU_DESC cd
,
500 const CGEN_INSN
*insn
,
501 CGEN_EXTRACT_INFO
*ex_info
,
502 CGEN_INSN_INT insn_value
,
506 const CGEN_SYNTAX
*syntax
= CGEN_INSN_SYNTAX (insn
);
507 const CGEN_SYNTAX_CHAR_TYPE
*syn
;
509 CGEN_FIELDS_BITSIZE (fields
) = CGEN_INSN_BITSIZE (insn
);
511 CGEN_INIT_EXTRACT (cd
);
513 for (syn
= CGEN_SYNTAX_STRING (syntax
); *syn
; ++syn
)
517 if (CGEN_SYNTAX_CHAR_P (*syn
))
520 length
= (* cd
->extract_operand
) (cd
, CGEN_SYNTAX_FIELD (*syn
),
521 ex_info
, insn_value
, fields
, pc
);
526 /* We recognized and successfully extracted this insn. */
527 return CGEN_INSN_BITSIZE (insn
);
530 /* Machine generated code added here. */
532 const char * openrisc_cgen_insert_operand
533 (CGEN_CPU_DESC
, int, CGEN_FIELDS
*, CGEN_INSN_BYTES_PTR
, bfd_vma
);
535 /* Main entry point for operand insertion.
537 This function is basically just a big switch statement. Earlier versions
538 used tables to look up the function to use, but
539 - if the table contains both assembler and disassembler functions then
540 the disassembler contains much of the assembler and vice-versa,
541 - there's a lot of inlining possibilities as things grow,
542 - using a switch statement avoids the function call overhead.
544 This function could be moved into `parse_insn_normal', but keeping it
545 separate makes clear the interface between `parse_insn_normal' and each of
546 the handlers. It's also needed by GAS to insert operands that couldn't be
547 resolved during parsing. */
550 openrisc_cgen_insert_operand (CGEN_CPU_DESC cd
,
552 CGEN_FIELDS
* fields
,
553 CGEN_INSN_BYTES_PTR buffer
,
554 bfd_vma pc ATTRIBUTE_UNUSED
)
556 const char * errmsg
= NULL
;
557 unsigned int total_length
= CGEN_FIELDS_BITSIZE (fields
);
561 case OPENRISC_OPERAND_ABS_26
:
563 long value
= fields
->f_abs26
;
564 value
= ((unsigned int) (pc
) >> (2));
565 errmsg
= insert_normal (cd
, value
, 0|(1<<CGEN_IFLD_SIGNED
)|(1<<CGEN_IFLD_ABS_ADDR
), 0, 25, 26, 32, total_length
, buffer
);
568 case OPENRISC_OPERAND_DISP_26
:
570 long value
= fields
->f_disp26
;
571 value
= ((int) (((value
) - (pc
))) >> (2));
572 errmsg
= insert_normal (cd
, value
, 0|(1<<CGEN_IFLD_SIGNED
)|(1<<CGEN_IFLD_PCREL_ADDR
), 0, 25, 26, 32, total_length
, buffer
);
575 case OPENRISC_OPERAND_HI16
:
576 errmsg
= insert_normal (cd
, fields
->f_simm16
, 0|(1<<CGEN_IFLD_SIGNED
), 0, 15, 16, 32, total_length
, buffer
);
578 case OPENRISC_OPERAND_LO16
:
579 errmsg
= insert_normal (cd
, fields
->f_lo16
, 0|(1<<CGEN_IFLD_SIGNED
), 0, 15, 16, 32, total_length
, buffer
);
581 case OPENRISC_OPERAND_OP_F_23
:
582 errmsg
= insert_normal (cd
, fields
->f_op4
, 0, 0, 23, 3, 32, total_length
, buffer
);
584 case OPENRISC_OPERAND_OP_F_3
:
585 errmsg
= insert_normal (cd
, fields
->f_op5
, 0, 0, 25, 5, 32, total_length
, buffer
);
587 case OPENRISC_OPERAND_RA
:
588 errmsg
= insert_normal (cd
, fields
->f_r2
, 0, 0, 20, 5, 32, total_length
, buffer
);
590 case OPENRISC_OPERAND_RB
:
591 errmsg
= insert_normal (cd
, fields
->f_r3
, 0, 0, 15, 5, 32, total_length
, buffer
);
593 case OPENRISC_OPERAND_RD
:
594 errmsg
= insert_normal (cd
, fields
->f_r1
, 0, 0, 25, 5, 32, total_length
, buffer
);
596 case OPENRISC_OPERAND_SIMM_16
:
597 errmsg
= insert_normal (cd
, fields
->f_simm16
, 0|(1<<CGEN_IFLD_SIGNED
), 0, 15, 16, 32, total_length
, buffer
);
599 case OPENRISC_OPERAND_UI16NC
:
602 FLD (f_i16_2
) = ((((unsigned int) (FLD (f_i16nc
)) >> (11))) & (31));
603 FLD (f_i16_1
) = ((FLD (f_i16nc
)) & (2047));
605 errmsg
= insert_normal (cd
, fields
->f_i16_1
, 0, 0, 10, 11, 32, total_length
, buffer
);
608 errmsg
= insert_normal (cd
, fields
->f_i16_2
, 0, 0, 25, 5, 32, total_length
, buffer
);
613 case OPENRISC_OPERAND_UIMM_16
:
614 errmsg
= insert_normal (cd
, fields
->f_uimm16
, 0, 0, 15, 16, 32, total_length
, buffer
);
616 case OPENRISC_OPERAND_UIMM_5
:
617 errmsg
= insert_normal (cd
, fields
->f_uimm5
, 0, 0, 4, 5, 32, total_length
, buffer
);
621 /* xgettext:c-format */
622 fprintf (stderr
, _("Unrecognized field %d while building insn.\n"),
630 int openrisc_cgen_extract_operand
631 (CGEN_CPU_DESC
, int, CGEN_EXTRACT_INFO
*, CGEN_INSN_INT
, CGEN_FIELDS
*, bfd_vma
);
633 /* Main entry point for operand extraction.
634 The result is <= 0 for error, >0 for success.
635 ??? Actual values aren't well defined right now.
637 This function is basically just a big switch statement. Earlier versions
638 used tables to look up the function to use, but
639 - if the table contains both assembler and disassembler functions then
640 the disassembler contains much of the assembler and vice-versa,
641 - there's a lot of inlining possibilities as things grow,
642 - using a switch statement avoids the function call overhead.
644 This function could be moved into `print_insn_normal', but keeping it
645 separate makes clear the interface between `print_insn_normal' and each of
649 openrisc_cgen_extract_operand (CGEN_CPU_DESC cd
,
651 CGEN_EXTRACT_INFO
*ex_info
,
652 CGEN_INSN_INT insn_value
,
653 CGEN_FIELDS
* fields
,
656 /* Assume success (for those operands that are nops). */
658 unsigned int total_length
= CGEN_FIELDS_BITSIZE (fields
);
662 case OPENRISC_OPERAND_ABS_26
:
665 length
= extract_normal (cd
, ex_info
, insn_value
, 0|(1<<CGEN_IFLD_SIGNED
)|(1<<CGEN_IFLD_ABS_ADDR
), 0, 25, 26, 32, total_length
, pc
, & value
);
666 value
= ((value
) << (2));
667 fields
->f_abs26
= value
;
670 case OPENRISC_OPERAND_DISP_26
:
673 length
= extract_normal (cd
, ex_info
, insn_value
, 0|(1<<CGEN_IFLD_SIGNED
)|(1<<CGEN_IFLD_PCREL_ADDR
), 0, 25, 26, 32, total_length
, pc
, & value
);
674 value
= ((((value
) << (2))) + (pc
));
675 fields
->f_disp26
= value
;
678 case OPENRISC_OPERAND_HI16
:
679 length
= extract_normal (cd
, ex_info
, insn_value
, 0|(1<<CGEN_IFLD_SIGNED
), 0, 15, 16, 32, total_length
, pc
, & fields
->f_simm16
);
681 case OPENRISC_OPERAND_LO16
:
682 length
= extract_normal (cd
, ex_info
, insn_value
, 0|(1<<CGEN_IFLD_SIGNED
), 0, 15, 16, 32, total_length
, pc
, & fields
->f_lo16
);
684 case OPENRISC_OPERAND_OP_F_23
:
685 length
= extract_normal (cd
, ex_info
, insn_value
, 0, 0, 23, 3, 32, total_length
, pc
, & fields
->f_op4
);
687 case OPENRISC_OPERAND_OP_F_3
:
688 length
= extract_normal (cd
, ex_info
, insn_value
, 0, 0, 25, 5, 32, total_length
, pc
, & fields
->f_op5
);
690 case OPENRISC_OPERAND_RA
:
691 length
= extract_normal (cd
, ex_info
, insn_value
, 0, 0, 20, 5, 32, total_length
, pc
, & fields
->f_r2
);
693 case OPENRISC_OPERAND_RB
:
694 length
= extract_normal (cd
, ex_info
, insn_value
, 0, 0, 15, 5, 32, total_length
, pc
, & fields
->f_r3
);
696 case OPENRISC_OPERAND_RD
:
697 length
= extract_normal (cd
, ex_info
, insn_value
, 0, 0, 25, 5, 32, total_length
, pc
, & fields
->f_r1
);
699 case OPENRISC_OPERAND_SIMM_16
:
700 length
= extract_normal (cd
, ex_info
, insn_value
, 0|(1<<CGEN_IFLD_SIGNED
), 0, 15, 16, 32, total_length
, pc
, & fields
->f_simm16
);
702 case OPENRISC_OPERAND_UI16NC
:
704 length
= extract_normal (cd
, ex_info
, insn_value
, 0, 0, 10, 11, 32, total_length
, pc
, & fields
->f_i16_1
);
705 if (length
<= 0) break;
706 length
= extract_normal (cd
, ex_info
, insn_value
, 0, 0, 25, 5, 32, total_length
, pc
, & fields
->f_i16_2
);
707 if (length
<= 0) break;
709 FLD (f_i16nc
) = openrisc_sign_extend_16bit (((((FLD (f_i16_2
)) << (11))) | (FLD (f_i16_1
))));
713 case OPENRISC_OPERAND_UIMM_16
:
714 length
= extract_normal (cd
, ex_info
, insn_value
, 0, 0, 15, 16, 32, total_length
, pc
, & fields
->f_uimm16
);
716 case OPENRISC_OPERAND_UIMM_5
:
717 length
= extract_normal (cd
, ex_info
, insn_value
, 0, 0, 4, 5, 32, total_length
, pc
, & fields
->f_uimm5
);
721 /* xgettext:c-format */
722 fprintf (stderr
, _("Unrecognized field %d while decoding insn.\n"),
730 cgen_insert_fn
* const openrisc_cgen_insert_handlers
[] =
735 cgen_extract_fn
* const openrisc_cgen_extract_handlers
[] =
740 int openrisc_cgen_get_int_operand (CGEN_CPU_DESC
, int, const CGEN_FIELDS
*);
741 bfd_vma
openrisc_cgen_get_vma_operand (CGEN_CPU_DESC
, int, const CGEN_FIELDS
*);
743 /* Getting values from cgen_fields is handled by a collection of functions.
744 They are distinguished by the type of the VALUE argument they return.
745 TODO: floating point, inlining support, remove cases where result type
749 openrisc_cgen_get_int_operand (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED
,
751 const CGEN_FIELDS
* fields
)
757 case OPENRISC_OPERAND_ABS_26
:
758 value
= fields
->f_abs26
;
760 case OPENRISC_OPERAND_DISP_26
:
761 value
= fields
->f_disp26
;
763 case OPENRISC_OPERAND_HI16
:
764 value
= fields
->f_simm16
;
766 case OPENRISC_OPERAND_LO16
:
767 value
= fields
->f_lo16
;
769 case OPENRISC_OPERAND_OP_F_23
:
770 value
= fields
->f_op4
;
772 case OPENRISC_OPERAND_OP_F_3
:
773 value
= fields
->f_op5
;
775 case OPENRISC_OPERAND_RA
:
776 value
= fields
->f_r2
;
778 case OPENRISC_OPERAND_RB
:
779 value
= fields
->f_r3
;
781 case OPENRISC_OPERAND_RD
:
782 value
= fields
->f_r1
;
784 case OPENRISC_OPERAND_SIMM_16
:
785 value
= fields
->f_simm16
;
787 case OPENRISC_OPERAND_UI16NC
:
788 value
= fields
->f_i16nc
;
790 case OPENRISC_OPERAND_UIMM_16
:
791 value
= fields
->f_uimm16
;
793 case OPENRISC_OPERAND_UIMM_5
:
794 value
= fields
->f_uimm5
;
798 /* xgettext:c-format */
799 fprintf (stderr
, _("Unrecognized field %d while getting int operand.\n"),
808 openrisc_cgen_get_vma_operand (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED
,
810 const CGEN_FIELDS
* fields
)
816 case OPENRISC_OPERAND_ABS_26
:
817 value
= fields
->f_abs26
;
819 case OPENRISC_OPERAND_DISP_26
:
820 value
= fields
->f_disp26
;
822 case OPENRISC_OPERAND_HI16
:
823 value
= fields
->f_simm16
;
825 case OPENRISC_OPERAND_LO16
:
826 value
= fields
->f_lo16
;
828 case OPENRISC_OPERAND_OP_F_23
:
829 value
= fields
->f_op4
;
831 case OPENRISC_OPERAND_OP_F_3
:
832 value
= fields
->f_op5
;
834 case OPENRISC_OPERAND_RA
:
835 value
= fields
->f_r2
;
837 case OPENRISC_OPERAND_RB
:
838 value
= fields
->f_r3
;
840 case OPENRISC_OPERAND_RD
:
841 value
= fields
->f_r1
;
843 case OPENRISC_OPERAND_SIMM_16
:
844 value
= fields
->f_simm16
;
846 case OPENRISC_OPERAND_UI16NC
:
847 value
= fields
->f_i16nc
;
849 case OPENRISC_OPERAND_UIMM_16
:
850 value
= fields
->f_uimm16
;
852 case OPENRISC_OPERAND_UIMM_5
:
853 value
= fields
->f_uimm5
;
857 /* xgettext:c-format */
858 fprintf (stderr
, _("Unrecognized field %d while getting vma operand.\n"),
866 void openrisc_cgen_set_int_operand (CGEN_CPU_DESC
, int, CGEN_FIELDS
*, int);
867 void openrisc_cgen_set_vma_operand (CGEN_CPU_DESC
, int, CGEN_FIELDS
*, bfd_vma
);
869 /* Stuffing values in cgen_fields is handled by a collection of functions.
870 They are distinguished by the type of the VALUE argument they accept.
871 TODO: floating point, inlining support, remove cases where argument type
875 openrisc_cgen_set_int_operand (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED
,
877 CGEN_FIELDS
* fields
,
882 case OPENRISC_OPERAND_ABS_26
:
883 fields
->f_abs26
= value
;
885 case OPENRISC_OPERAND_DISP_26
:
886 fields
->f_disp26
= value
;
888 case OPENRISC_OPERAND_HI16
:
889 fields
->f_simm16
= value
;
891 case OPENRISC_OPERAND_LO16
:
892 fields
->f_lo16
= value
;
894 case OPENRISC_OPERAND_OP_F_23
:
895 fields
->f_op4
= value
;
897 case OPENRISC_OPERAND_OP_F_3
:
898 fields
->f_op5
= value
;
900 case OPENRISC_OPERAND_RA
:
901 fields
->f_r2
= value
;
903 case OPENRISC_OPERAND_RB
:
904 fields
->f_r3
= value
;
906 case OPENRISC_OPERAND_RD
:
907 fields
->f_r1
= value
;
909 case OPENRISC_OPERAND_SIMM_16
:
910 fields
->f_simm16
= value
;
912 case OPENRISC_OPERAND_UI16NC
:
913 fields
->f_i16nc
= value
;
915 case OPENRISC_OPERAND_UIMM_16
:
916 fields
->f_uimm16
= value
;
918 case OPENRISC_OPERAND_UIMM_5
:
919 fields
->f_uimm5
= value
;
923 /* xgettext:c-format */
924 fprintf (stderr
, _("Unrecognized field %d while setting int operand.\n"),
931 openrisc_cgen_set_vma_operand (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED
,
933 CGEN_FIELDS
* fields
,
938 case OPENRISC_OPERAND_ABS_26
:
939 fields
->f_abs26
= value
;
941 case OPENRISC_OPERAND_DISP_26
:
942 fields
->f_disp26
= value
;
944 case OPENRISC_OPERAND_HI16
:
945 fields
->f_simm16
= value
;
947 case OPENRISC_OPERAND_LO16
:
948 fields
->f_lo16
= value
;
950 case OPENRISC_OPERAND_OP_F_23
:
951 fields
->f_op4
= value
;
953 case OPENRISC_OPERAND_OP_F_3
:
954 fields
->f_op5
= value
;
956 case OPENRISC_OPERAND_RA
:
957 fields
->f_r2
= value
;
959 case OPENRISC_OPERAND_RB
:
960 fields
->f_r3
= value
;
962 case OPENRISC_OPERAND_RD
:
963 fields
->f_r1
= value
;
965 case OPENRISC_OPERAND_SIMM_16
:
966 fields
->f_simm16
= value
;
968 case OPENRISC_OPERAND_UI16NC
:
969 fields
->f_i16nc
= value
;
971 case OPENRISC_OPERAND_UIMM_16
:
972 fields
->f_uimm16
= value
;
974 case OPENRISC_OPERAND_UIMM_5
:
975 fields
->f_uimm5
= value
;
979 /* xgettext:c-format */
980 fprintf (stderr
, _("Unrecognized field %d while setting vma operand.\n"),
986 /* Function to call before using the instruction builder tables. */
989 openrisc_cgen_init_ibld_table (CGEN_CPU_DESC cd
)
991 cd
->insert_handlers
= & openrisc_cgen_insert_handlers
[0];
992 cd
->extract_handlers
= & openrisc_cgen_extract_handlers
[0];
994 cd
->insert_operand
= openrisc_cgen_insert_operand
;
995 cd
->extract_operand
= openrisc_cgen_extract_operand
;
997 cd
->get_int_operand
= openrisc_cgen_get_int_operand
;
998 cd
->set_int_operand
= openrisc_cgen_set_int_operand
;
999 cd
->get_vma_operand
= openrisc_cgen_get_vma_operand
;
1000 cd
->set_vma_operand
= openrisc_cgen_set_vma_operand
;