1 /* Instruction building/extraction support for iq2000. -*- 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 "iq2000-desc.h"
34 #include "iq2000-opc.h"
36 #include "safe-ctype.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
));
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
));
60 static void put_insn_int_value
61 PARAMS ((CGEN_CPU_DESC
, CGEN_INSN_BYTES_PTR
, int, int, CGEN_INSN_INT
));
64 static CGEN_INLINE
void insert_1
65 PARAMS ((CGEN_CPU_DESC
, unsigned long, int, int, int, unsigned char *));
66 static CGEN_INLINE
int fill_cache
67 PARAMS ((CGEN_CPU_DESC
, CGEN_EXTRACT_INFO
*, int, int, bfd_vma
));
68 static CGEN_INLINE
long extract_1
69 PARAMS ((CGEN_CPU_DESC
, CGEN_EXTRACT_INFO
*, int, int, int,
70 unsigned char *, bfd_vma
));
73 /* Operand insertion. */
77 /* Subroutine of insert_normal. */
79 static CGEN_INLINE
void
80 insert_1 (cd
, value
, start
, length
, word_length
, bufp
)
83 int start
,length
,word_length
;
89 x
= cgen_get_insn_value (cd
, bufp
, word_length
);
91 /* Written this way to avoid undefined behaviour. */
92 mask
= (((1L << (length
- 1)) - 1) << 1) | 1;
94 shift
= (start
+ 1) - length
;
96 shift
= (word_length
- (start
+ length
));
97 x
= (x
& ~(mask
<< shift
)) | ((value
& mask
) << shift
);
99 cgen_put_insn_value (cd
, bufp
, word_length
, (bfd_vma
) x
);
102 #endif /* ! CGEN_INT_INSN_P */
104 /* Default insertion routine.
106 ATTRS is a mask of the boolean attributes.
107 WORD_OFFSET is the offset in bits from the start of the insn of the value.
108 WORD_LENGTH is the length of the word in bits in which the value resides.
109 START is the starting bit number in the word, architecture origin.
110 LENGTH is the length of VALUE in bits.
111 TOTAL_LENGTH is the total length of the insn in bits.
113 The result is an error message or NULL if success. */
115 /* ??? This duplicates functionality with bfd's howto table and
116 bfd_install_relocation. */
117 /* ??? This doesn't handle bfd_vma's. Create another function when
121 insert_normal (cd
, value
, attrs
, word_offset
, start
, length
, word_length
,
122 total_length
, buffer
)
126 unsigned int word_offset
, start
, length
, word_length
, total_length
;
127 CGEN_INSN_BYTES_PTR buffer
;
129 static char errbuf
[100];
130 /* Written this way to avoid undefined behaviour. */
131 unsigned long mask
= (((1L << (length
- 1)) - 1) << 1) | 1;
133 /* If LENGTH is zero, this operand doesn't contribute to the value. */
143 if (word_length
> 32)
146 /* For architectures with insns smaller than the base-insn-bitsize,
147 word_length may be too big. */
148 if (cd
->min_insn_bitsize
< cd
->base_insn_bitsize
)
151 && word_length
> total_length
)
152 word_length
= total_length
;
155 /* Ensure VALUE will fit. */
156 if (CGEN_BOOL_ATTR (attrs
, CGEN_IFLD_SIGN_OPT
))
158 long minval
= - (1L << (length
- 1));
159 unsigned long maxval
= mask
;
161 if ((value
> 0 && (unsigned long) value
> maxval
)
164 /* xgettext:c-format */
166 _("operand out of range (%ld not between %ld and %lu)"),
167 value
, minval
, maxval
);
171 else if (! CGEN_BOOL_ATTR (attrs
, CGEN_IFLD_SIGNED
))
173 unsigned long maxval
= mask
;
175 if ((unsigned long) value
> maxval
)
177 /* xgettext:c-format */
179 _("operand out of range (%lu not between 0 and %lu)"),
186 if (! cgen_signed_overflow_ok_p (cd
))
188 long minval
= - (1L << (length
- 1));
189 long maxval
= (1L << (length
- 1)) - 1;
191 if (value
< minval
|| value
> maxval
)
194 /* xgettext:c-format */
195 (errbuf
, _("operand out of range (%ld not between %ld and %ld)"),
196 value
, minval
, maxval
);
207 if (CGEN_INSN_LSB0_P
)
208 shift
= (word_offset
+ start
+ 1) - length
;
210 shift
= total_length
- (word_offset
+ start
+ length
);
211 *buffer
= (*buffer
& ~(mask
<< shift
)) | ((value
& mask
) << shift
);
214 #else /* ! CGEN_INT_INSN_P */
217 unsigned char *bufp
= (unsigned char *) buffer
+ word_offset
/ 8;
219 insert_1 (cd
, value
, start
, length
, word_length
, bufp
);
222 #endif /* ! CGEN_INT_INSN_P */
227 /* Default insn builder (insert handler).
228 The instruction is recorded in CGEN_INT_INSN_P byte order (meaning
229 that if CGEN_INSN_BYTES_PTR is an int * and thus, the value is
230 recorded in host byte order, otherwise BUFFER is an array of bytes
231 and the value is recorded in target byte order).
232 The result is an error message or NULL if success. */
235 insert_insn_normal (cd
, insn
, fields
, buffer
, pc
)
237 const CGEN_INSN
* insn
;
238 CGEN_FIELDS
* fields
;
239 CGEN_INSN_BYTES_PTR buffer
;
242 const CGEN_SYNTAX
*syntax
= CGEN_INSN_SYNTAX (insn
);
244 const CGEN_SYNTAX_CHAR_TYPE
* syn
;
246 CGEN_INIT_INSERT (cd
);
247 value
= CGEN_INSN_BASE_VALUE (insn
);
249 /* If we're recording insns as numbers (rather than a string of bytes),
250 target byte order handling is deferred until later. */
254 put_insn_int_value (cd
, buffer
, cd
->base_insn_bitsize
,
255 CGEN_FIELDS_BITSIZE (fields
), value
);
259 cgen_put_insn_value (cd
, buffer
, min ((unsigned) cd
->base_insn_bitsize
,
260 (unsigned) CGEN_FIELDS_BITSIZE (fields
)),
263 #endif /* ! CGEN_INT_INSN_P */
265 /* ??? It would be better to scan the format's fields.
266 Still need to be able to insert a value based on the operand though;
267 e.g. storing a branch displacement that got resolved later.
268 Needs more thought first. */
270 for (syn
= CGEN_SYNTAX_STRING (syntax
); * syn
; ++ syn
)
274 if (CGEN_SYNTAX_CHAR_P (* syn
))
277 errmsg
= (* cd
->insert_operand
) (cd
, CGEN_SYNTAX_FIELD (*syn
),
287 /* Cover function to store an insn value into an integral insn. Must go here
288 because it needs <prefix>-desc.h for CGEN_INT_INSN_P. */
291 put_insn_int_value (cd
, buf
, length
, insn_length
, value
)
292 CGEN_CPU_DESC cd ATTRIBUTE_UNUSED
;
293 CGEN_INSN_BYTES_PTR buf
;
298 /* For architectures with insns smaller than the base-insn-bitsize,
299 length may be too big. */
300 if (length
> insn_length
)
304 int shift
= insn_length
- length
;
305 /* Written this way to avoid undefined behaviour. */
306 CGEN_INSN_INT mask
= (((1L << (length
- 1)) - 1) << 1) | 1;
307 *buf
= (*buf
& ~(mask
<< shift
)) | ((value
& mask
) << shift
);
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
)
324 CGEN_CPU_DESC cd ATTRIBUTE_UNUSED
;
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 ATTRIBUTE_UNUSED
;
370 int start
,length
,word_length
;
372 bfd_vma pc ATTRIBUTE_UNUSED
;
377 int big_p
= CGEN_CPU_INSN_ENDIAN (cd
) == CGEN_ENDIAN_BIG
;
379 x
= cgen_get_insn_value (cd
, bufp
, word_length
);
381 if (CGEN_INSN_LSB0_P
)
382 shift
= (start
+ 1) - length
;
384 shift
= (word_length
- (start
+ length
));
388 #endif /* ! CGEN_INT_INSN_P */
390 /* Default extraction routine.
392 INSN_VALUE is the first base_insn_bitsize bits of the insn in host order,
393 or sometimes less for cases like the m32r where the base insn size is 32
394 but some insns are 16 bits.
395 ATTRS is a mask of the boolean attributes. We only need `SIGNED',
396 but for generality we take a bitmask of all of them.
397 WORD_OFFSET is the offset in bits from the start of the insn of the value.
398 WORD_LENGTH is the length of the word in bits in which the value resides.
399 START is the starting bit number in the word, architecture origin.
400 LENGTH is the length of VALUE in bits.
401 TOTAL_LENGTH is the total length of the insn in bits.
403 Returns 1 for success, 0 for failure. */
405 /* ??? The return code isn't properly used. wip. */
407 /* ??? This doesn't handle bfd_vma's. Create another function when
411 extract_normal (cd
, ex_info
, insn_value
, attrs
, word_offset
, start
, length
,
412 word_length
, total_length
, pc
, valuep
)
414 #if ! CGEN_INT_INSN_P
415 CGEN_EXTRACT_INFO
*ex_info
;
417 CGEN_EXTRACT_INFO
*ex_info ATTRIBUTE_UNUSED
;
419 CGEN_INSN_INT insn_value
;
421 unsigned int word_offset
, start
, length
, word_length
, total_length
;
422 #if ! CGEN_INT_INSN_P
425 bfd_vma pc ATTRIBUTE_UNUSED
;
431 /* If LENGTH is zero, this operand doesn't contribute to the value
432 so give it a standard value of zero. */
445 if (word_length
> 32)
448 /* For architectures with insns smaller than the insn-base-bitsize,
449 word_length may be too big. */
450 if (cd
->min_insn_bitsize
< cd
->base_insn_bitsize
)
453 && word_length
> total_length
)
454 word_length
= total_length
;
457 /* Does the value reside in INSN_VALUE, and at the right alignment? */
459 if (CGEN_INT_INSN_P
|| (word_offset
== 0 && word_length
== total_length
))
461 if (CGEN_INSN_LSB0_P
)
462 value
= insn_value
>> ((word_offset
+ start
+ 1) - length
);
464 value
= insn_value
>> (total_length
- ( word_offset
+ start
+ length
));
467 #if ! CGEN_INT_INSN_P
471 unsigned char *bufp
= ex_info
->insn_bytes
+ word_offset
/ 8;
473 if (word_length
> 32)
476 if (fill_cache (cd
, ex_info
, word_offset
/ 8, word_length
/ 8, pc
) == 0)
479 value
= extract_1 (cd
, ex_info
, start
, length
, word_length
, bufp
, pc
);
482 #endif /* ! CGEN_INT_INSN_P */
484 /* Written this way to avoid undefined behaviour. */
485 mask
= (((1L << (length
- 1)) - 1) << 1) | 1;
489 if (CGEN_BOOL_ATTR (attrs
, CGEN_IFLD_SIGNED
)
490 && (value
& (1L << (length
- 1))))
498 /* Default insn extractor.
500 INSN_VALUE is the first base_insn_bitsize bits, translated to host order.
501 The extracted fields are stored in FIELDS.
502 EX_INFO is used to handle reading variable length insns.
503 Return the length of the insn in bits, or 0 if no match,
504 or -1 if an error occurs fetching data (memory_error_func will have
508 extract_insn_normal (cd
, insn
, ex_info
, insn_value
, fields
, pc
)
510 const CGEN_INSN
*insn
;
511 CGEN_EXTRACT_INFO
*ex_info
;
512 CGEN_INSN_INT insn_value
;
516 const CGEN_SYNTAX
*syntax
= CGEN_INSN_SYNTAX (insn
);
517 const CGEN_SYNTAX_CHAR_TYPE
*syn
;
519 CGEN_FIELDS_BITSIZE (fields
) = CGEN_INSN_BITSIZE (insn
);
521 CGEN_INIT_EXTRACT (cd
);
523 for (syn
= CGEN_SYNTAX_STRING (syntax
); *syn
; ++syn
)
527 if (CGEN_SYNTAX_CHAR_P (*syn
))
530 length
= (* cd
->extract_operand
) (cd
, CGEN_SYNTAX_FIELD (*syn
),
531 ex_info
, insn_value
, fields
, pc
);
536 /* We recognized and successfully extracted this insn. */
537 return CGEN_INSN_BITSIZE (insn
);
540 /* machine generated code added here */
542 const char * iq2000_cgen_insert_operand
543 PARAMS ((CGEN_CPU_DESC
, int, CGEN_FIELDS
*, CGEN_INSN_BYTES_PTR
, bfd_vma
));
545 /* Main entry point for operand insertion.
547 This function is basically just a big switch statement. Earlier versions
548 used tables to look up the function to use, but
549 - if the table contains both assembler and disassembler functions then
550 the disassembler contains much of the assembler and vice-versa,
551 - there's a lot of inlining possibilities as things grow,
552 - using a switch statement avoids the function call overhead.
554 This function could be moved into `parse_insn_normal', but keeping it
555 separate makes clear the interface between `parse_insn_normal' and each of
556 the handlers. It's also needed by GAS to insert operands that couldn't be
557 resolved during parsing. */
560 iq2000_cgen_insert_operand (cd
, opindex
, fields
, buffer
, pc
)
563 CGEN_FIELDS
* fields
;
564 CGEN_INSN_BYTES_PTR buffer
;
565 bfd_vma pc ATTRIBUTE_UNUSED
;
567 const char * errmsg
= NULL
;
568 unsigned int total_length
= CGEN_FIELDS_BITSIZE (fields
);
572 case IQ2000_OPERAND_BASE
:
573 errmsg
= insert_normal (cd
, fields
->f_rs
, 0, 0, 25, 5, 32, total_length
, buffer
);
575 case IQ2000_OPERAND_BASEOFF
:
576 errmsg
= insert_normal (cd
, fields
->f_imm
, 0, 0, 15, 16, 32, total_length
, buffer
);
578 case IQ2000_OPERAND_BITNUM
:
579 errmsg
= insert_normal (cd
, fields
->f_rt
, 0, 0, 20, 5, 32, total_length
, buffer
);
581 case IQ2000_OPERAND_BYTECOUNT
:
582 errmsg
= insert_normal (cd
, fields
->f_bytecount
, 0, 0, 7, 8, 32, total_length
, buffer
);
584 case IQ2000_OPERAND_CAM_Y
:
585 errmsg
= insert_normal (cd
, fields
->f_cam_y
, 0, 0, 2, 3, 32, total_length
, buffer
);
587 case IQ2000_OPERAND_CAM_Z
:
588 errmsg
= insert_normal (cd
, fields
->f_cam_z
, 0, 0, 5, 3, 32, total_length
, buffer
);
590 case IQ2000_OPERAND_CM_3FUNC
:
591 errmsg
= insert_normal (cd
, fields
->f_cm_3func
, 0, 0, 5, 3, 32, total_length
, buffer
);
593 case IQ2000_OPERAND_CM_3Z
:
594 errmsg
= insert_normal (cd
, fields
->f_cm_3z
, 0, 0, 1, 2, 32, total_length
, buffer
);
596 case IQ2000_OPERAND_CM_4FUNC
:
597 errmsg
= insert_normal (cd
, fields
->f_cm_4func
, 0, 0, 5, 4, 32, total_length
, buffer
);
599 case IQ2000_OPERAND_CM_4Z
:
600 errmsg
= insert_normal (cd
, fields
->f_cm_4z
, 0, 0, 2, 3, 32, total_length
, buffer
);
602 case IQ2000_OPERAND_COUNT
:
603 errmsg
= insert_normal (cd
, fields
->f_count
, 0, 0, 15, 7, 32, total_length
, buffer
);
605 case IQ2000_OPERAND_EXECODE
:
606 errmsg
= insert_normal (cd
, fields
->f_excode
, 0, 0, 25, 20, 32, total_length
, buffer
);
608 case IQ2000_OPERAND_F_INDEX
:
609 errmsg
= insert_normal (cd
, fields
->f_index
, 0, 0, 8, 9, 32, total_length
, buffer
);
611 case IQ2000_OPERAND_HI16
:
612 errmsg
= insert_normal (cd
, fields
->f_imm
, 0, 0, 15, 16, 32, total_length
, buffer
);
614 case IQ2000_OPERAND_IMM
:
615 errmsg
= insert_normal (cd
, fields
->f_imm
, 0, 0, 15, 16, 32, total_length
, buffer
);
617 case IQ2000_OPERAND_JMPTARG
:
619 long value
= fields
->f_jtarg
;
620 value
= ((unsigned int) (((value
) & (262143))) >> (2));
621 errmsg
= insert_normal (cd
, value
, 0|(1<<CGEN_IFLD_ABS_ADDR
), 0, 15, 16, 32, total_length
, buffer
);
624 case IQ2000_OPERAND_JMPTARGQ10
:
626 long value
= fields
->f_jtargq10
;
627 value
= ((unsigned int) (((value
) & (8388607))) >> (2));
628 errmsg
= insert_normal (cd
, value
, 0|(1<<CGEN_IFLD_ABS_ADDR
), 0, 20, 21, 32, total_length
, buffer
);
631 case IQ2000_OPERAND_LO16
:
632 errmsg
= insert_normal (cd
, fields
->f_imm
, 0, 0, 15, 16, 32, total_length
, buffer
);
634 case IQ2000_OPERAND_MASK
:
635 errmsg
= insert_normal (cd
, fields
->f_mask
, 0, 0, 9, 4, 32, total_length
, buffer
);
637 case IQ2000_OPERAND_MASKL
:
638 errmsg
= insert_normal (cd
, fields
->f_maskl
, 0, 0, 4, 5, 32, total_length
, buffer
);
640 case IQ2000_OPERAND_MASKQ10
:
641 errmsg
= insert_normal (cd
, fields
->f_maskq10
, 0, 0, 10, 5, 32, total_length
, buffer
);
643 case IQ2000_OPERAND_MASKR
:
644 errmsg
= insert_normal (cd
, fields
->f_rs
, 0, 0, 25, 5, 32, total_length
, buffer
);
646 case IQ2000_OPERAND_MLO16
:
647 errmsg
= insert_normal (cd
, fields
->f_imm
, 0, 0, 15, 16, 32, total_length
, buffer
);
649 case IQ2000_OPERAND_OFFSET
:
651 long value
= fields
->f_offset
;
652 value
= ((int) (((value
) - (pc
))) >> (2));
653 errmsg
= insert_normal (cd
, value
, 0|(1<<CGEN_IFLD_SIGNED
)|(1<<CGEN_IFLD_PCREL_ADDR
), 0, 15, 16, 32, total_length
, buffer
);
656 case IQ2000_OPERAND_RD
:
657 errmsg
= insert_normal (cd
, fields
->f_rd
, 0, 0, 15, 5, 32, total_length
, buffer
);
659 case IQ2000_OPERAND_RD_RS
:
662 FLD (f_rd
) = FLD (f_rd_rs
);
663 FLD (f_rs
) = FLD (f_rd_rs
);
665 errmsg
= insert_normal (cd
, fields
->f_rd
, 0, 0, 15, 5, 32, total_length
, buffer
);
668 errmsg
= insert_normal (cd
, fields
->f_rs
, 0, 0, 25, 5, 32, total_length
, buffer
);
673 case IQ2000_OPERAND_RD_RT
:
676 FLD (f_rd
) = FLD (f_rd_rt
);
677 FLD (f_rt
) = FLD (f_rd_rt
);
679 errmsg
= insert_normal (cd
, fields
->f_rd
, 0, 0, 15, 5, 32, total_length
, buffer
);
682 errmsg
= insert_normal (cd
, fields
->f_rt
, 0, 0, 20, 5, 32, total_length
, buffer
);
687 case IQ2000_OPERAND_RS
:
688 errmsg
= insert_normal (cd
, fields
->f_rs
, 0, 0, 25, 5, 32, total_length
, buffer
);
690 case IQ2000_OPERAND_RT
:
691 errmsg
= insert_normal (cd
, fields
->f_rt
, 0, 0, 20, 5, 32, total_length
, buffer
);
693 case IQ2000_OPERAND_RT_RS
:
696 FLD (f_rt
) = FLD (f_rt_rs
);
697 FLD (f_rs
) = FLD (f_rt_rs
);
699 errmsg
= insert_normal (cd
, fields
->f_rt
, 0, 0, 20, 5, 32, total_length
, buffer
);
702 errmsg
= insert_normal (cd
, fields
->f_rs
, 0, 0, 25, 5, 32, total_length
, buffer
);
707 case IQ2000_OPERAND_SHAMT
:
708 errmsg
= insert_normal (cd
, fields
->f_shamt
, 0, 0, 10, 5, 32, total_length
, buffer
);
712 /* xgettext:c-format */
713 fprintf (stderr
, _("Unrecognized field %d while building insn.\n"),
721 int iq2000_cgen_extract_operand
722 PARAMS ((CGEN_CPU_DESC
, int, CGEN_EXTRACT_INFO
*, CGEN_INSN_INT
,
723 CGEN_FIELDS
*, bfd_vma
));
725 /* Main entry point for operand extraction.
726 The result is <= 0 for error, >0 for success.
727 ??? Actual values aren't well defined right now.
729 This function is basically just a big switch statement. Earlier versions
730 used tables to look up the function to use, but
731 - if the table contains both assembler and disassembler functions then
732 the disassembler contains much of the assembler and vice-versa,
733 - there's a lot of inlining possibilities as things grow,
734 - using a switch statement avoids the function call overhead.
736 This function could be moved into `print_insn_normal', but keeping it
737 separate makes clear the interface between `print_insn_normal' and each of
741 iq2000_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 IQ2000_OPERAND_BASE
:
756 length
= extract_normal (cd
, ex_info
, insn_value
, 0, 0, 25, 5, 32, total_length
, pc
, & fields
->f_rs
);
758 case IQ2000_OPERAND_BASEOFF
:
759 length
= extract_normal (cd
, ex_info
, insn_value
, 0, 0, 15, 16, 32, total_length
, pc
, & fields
->f_imm
);
761 case IQ2000_OPERAND_BITNUM
:
762 length
= extract_normal (cd
, ex_info
, insn_value
, 0, 0, 20, 5, 32, total_length
, pc
, & fields
->f_rt
);
764 case IQ2000_OPERAND_BYTECOUNT
:
765 length
= extract_normal (cd
, ex_info
, insn_value
, 0, 0, 7, 8, 32, total_length
, pc
, & fields
->f_bytecount
);
767 case IQ2000_OPERAND_CAM_Y
:
768 length
= extract_normal (cd
, ex_info
, insn_value
, 0, 0, 2, 3, 32, total_length
, pc
, & fields
->f_cam_y
);
770 case IQ2000_OPERAND_CAM_Z
:
771 length
= extract_normal (cd
, ex_info
, insn_value
, 0, 0, 5, 3, 32, total_length
, pc
, & fields
->f_cam_z
);
773 case IQ2000_OPERAND_CM_3FUNC
:
774 length
= extract_normal (cd
, ex_info
, insn_value
, 0, 0, 5, 3, 32, total_length
, pc
, & fields
->f_cm_3func
);
776 case IQ2000_OPERAND_CM_3Z
:
777 length
= extract_normal (cd
, ex_info
, insn_value
, 0, 0, 1, 2, 32, total_length
, pc
, & fields
->f_cm_3z
);
779 case IQ2000_OPERAND_CM_4FUNC
:
780 length
= extract_normal (cd
, ex_info
, insn_value
, 0, 0, 5, 4, 32, total_length
, pc
, & fields
->f_cm_4func
);
782 case IQ2000_OPERAND_CM_4Z
:
783 length
= extract_normal (cd
, ex_info
, insn_value
, 0, 0, 2, 3, 32, total_length
, pc
, & fields
->f_cm_4z
);
785 case IQ2000_OPERAND_COUNT
:
786 length
= extract_normal (cd
, ex_info
, insn_value
, 0, 0, 15, 7, 32, total_length
, pc
, & fields
->f_count
);
788 case IQ2000_OPERAND_EXECODE
:
789 length
= extract_normal (cd
, ex_info
, insn_value
, 0, 0, 25, 20, 32, total_length
, pc
, & fields
->f_excode
);
791 case IQ2000_OPERAND_F_INDEX
:
792 length
= extract_normal (cd
, ex_info
, insn_value
, 0, 0, 8, 9, 32, total_length
, pc
, & fields
->f_index
);
794 case IQ2000_OPERAND_HI16
:
795 length
= extract_normal (cd
, ex_info
, insn_value
, 0, 0, 15, 16, 32, total_length
, pc
, & fields
->f_imm
);
797 case IQ2000_OPERAND_IMM
:
798 length
= extract_normal (cd
, ex_info
, insn_value
, 0, 0, 15, 16, 32, total_length
, pc
, & fields
->f_imm
);
800 case IQ2000_OPERAND_JMPTARG
:
803 length
= extract_normal (cd
, ex_info
, insn_value
, 0|(1<<CGEN_IFLD_ABS_ADDR
), 0, 15, 16, 32, total_length
, pc
, & value
);
804 value
= ((((pc
) & (0xf0000000))) | (((value
) << (2))));
805 fields
->f_jtarg
= value
;
808 case IQ2000_OPERAND_JMPTARGQ10
:
811 length
= extract_normal (cd
, ex_info
, insn_value
, 0|(1<<CGEN_IFLD_ABS_ADDR
), 0, 20, 21, 32, total_length
, pc
, & value
);
812 value
= ((((pc
) & (0xf0000000))) | (((value
) << (2))));
813 fields
->f_jtargq10
= value
;
816 case IQ2000_OPERAND_LO16
:
817 length
= extract_normal (cd
, ex_info
, insn_value
, 0, 0, 15, 16, 32, total_length
, pc
, & fields
->f_imm
);
819 case IQ2000_OPERAND_MASK
:
820 length
= extract_normal (cd
, ex_info
, insn_value
, 0, 0, 9, 4, 32, total_length
, pc
, & fields
->f_mask
);
822 case IQ2000_OPERAND_MASKL
:
823 length
= extract_normal (cd
, ex_info
, insn_value
, 0, 0, 4, 5, 32, total_length
, pc
, & fields
->f_maskl
);
825 case IQ2000_OPERAND_MASKQ10
:
826 length
= extract_normal (cd
, ex_info
, insn_value
, 0, 0, 10, 5, 32, total_length
, pc
, & fields
->f_maskq10
);
828 case IQ2000_OPERAND_MASKR
:
829 length
= extract_normal (cd
, ex_info
, insn_value
, 0, 0, 25, 5, 32, total_length
, pc
, & fields
->f_rs
);
831 case IQ2000_OPERAND_MLO16
:
832 length
= extract_normal (cd
, ex_info
, insn_value
, 0, 0, 15, 16, 32, total_length
, pc
, & fields
->f_imm
);
834 case IQ2000_OPERAND_OFFSET
:
837 length
= extract_normal (cd
, ex_info
, insn_value
, 0|(1<<CGEN_IFLD_SIGNED
)|(1<<CGEN_IFLD_PCREL_ADDR
), 0, 15, 16, 32, total_length
, pc
, & value
);
838 value
= ((((value
) << (2))) + (((pc
) + (4))));
839 fields
->f_offset
= value
;
842 case IQ2000_OPERAND_RD
:
843 length
= extract_normal (cd
, ex_info
, insn_value
, 0, 0, 15, 5, 32, total_length
, pc
, & fields
->f_rd
);
845 case IQ2000_OPERAND_RD_RS
:
847 length
= extract_normal (cd
, ex_info
, insn_value
, 0, 0, 15, 5, 32, total_length
, pc
, & fields
->f_rd
);
848 if (length
<= 0) break;
849 length
= extract_normal (cd
, ex_info
, insn_value
, 0, 0, 25, 5, 32, total_length
, pc
, & fields
->f_rs
);
850 if (length
<= 0) break;
852 FLD (f_rd_rs
) = FLD (f_rs
);
856 case IQ2000_OPERAND_RD_RT
:
858 length
= extract_normal (cd
, ex_info
, insn_value
, 0, 0, 15, 5, 32, total_length
, pc
, & fields
->f_rd
);
859 if (length
<= 0) break;
860 length
= extract_normal (cd
, ex_info
, insn_value
, 0, 0, 20, 5, 32, total_length
, pc
, & fields
->f_rt
);
861 if (length
<= 0) break;
863 FLD (f_rd_rt
) = FLD (f_rt
);
867 case IQ2000_OPERAND_RS
:
868 length
= extract_normal (cd
, ex_info
, insn_value
, 0, 0, 25, 5, 32, total_length
, pc
, & fields
->f_rs
);
870 case IQ2000_OPERAND_RT
:
871 length
= extract_normal (cd
, ex_info
, insn_value
, 0, 0, 20, 5, 32, total_length
, pc
, & fields
->f_rt
);
873 case IQ2000_OPERAND_RT_RS
:
875 length
= extract_normal (cd
, ex_info
, insn_value
, 0, 0, 20, 5, 32, total_length
, pc
, & fields
->f_rt
);
876 if (length
<= 0) break;
877 length
= extract_normal (cd
, ex_info
, insn_value
, 0, 0, 25, 5, 32, total_length
, pc
, & fields
->f_rs
);
878 if (length
<= 0) break;
880 FLD (f_rd_rs
) = FLD (f_rs
);
884 case IQ2000_OPERAND_SHAMT
:
885 length
= extract_normal (cd
, ex_info
, insn_value
, 0, 0, 10, 5, 32, total_length
, pc
, & fields
->f_shamt
);
889 /* xgettext:c-format */
890 fprintf (stderr
, _("Unrecognized field %d while decoding insn.\n"),
898 cgen_insert_fn
* const iq2000_cgen_insert_handlers
[] =
903 cgen_extract_fn
* const iq2000_cgen_extract_handlers
[] =
908 int iq2000_cgen_get_int_operand
909 PARAMS ((CGEN_CPU_DESC
, int, const CGEN_FIELDS
*));
910 bfd_vma iq2000_cgen_get_vma_operand
911 PARAMS ((CGEN_CPU_DESC
, int, const CGEN_FIELDS
*));
913 /* Getting values from cgen_fields is handled by a collection of functions.
914 They are distinguished by the type of the VALUE argument they return.
915 TODO: floating point, inlining support, remove cases where result type
919 iq2000_cgen_get_int_operand (cd
, opindex
, fields
)
920 CGEN_CPU_DESC cd ATTRIBUTE_UNUSED
;
922 const CGEN_FIELDS
* fields
;
928 case IQ2000_OPERAND_BASE
:
929 value
= fields
->f_rs
;
931 case IQ2000_OPERAND_BASEOFF
:
932 value
= fields
->f_imm
;
934 case IQ2000_OPERAND_BITNUM
:
935 value
= fields
->f_rt
;
937 case IQ2000_OPERAND_BYTECOUNT
:
938 value
= fields
->f_bytecount
;
940 case IQ2000_OPERAND_CAM_Y
:
941 value
= fields
->f_cam_y
;
943 case IQ2000_OPERAND_CAM_Z
:
944 value
= fields
->f_cam_z
;
946 case IQ2000_OPERAND_CM_3FUNC
:
947 value
= fields
->f_cm_3func
;
949 case IQ2000_OPERAND_CM_3Z
:
950 value
= fields
->f_cm_3z
;
952 case IQ2000_OPERAND_CM_4FUNC
:
953 value
= fields
->f_cm_4func
;
955 case IQ2000_OPERAND_CM_4Z
:
956 value
= fields
->f_cm_4z
;
958 case IQ2000_OPERAND_COUNT
:
959 value
= fields
->f_count
;
961 case IQ2000_OPERAND_EXECODE
:
962 value
= fields
->f_excode
;
964 case IQ2000_OPERAND_F_INDEX
:
965 value
= fields
->f_index
;
967 case IQ2000_OPERAND_HI16
:
968 value
= fields
->f_imm
;
970 case IQ2000_OPERAND_IMM
:
971 value
= fields
->f_imm
;
973 case IQ2000_OPERAND_JMPTARG
:
974 value
= fields
->f_jtarg
;
976 case IQ2000_OPERAND_JMPTARGQ10
:
977 value
= fields
->f_jtargq10
;
979 case IQ2000_OPERAND_LO16
:
980 value
= fields
->f_imm
;
982 case IQ2000_OPERAND_MASK
:
983 value
= fields
->f_mask
;
985 case IQ2000_OPERAND_MASKL
:
986 value
= fields
->f_maskl
;
988 case IQ2000_OPERAND_MASKQ10
:
989 value
= fields
->f_maskq10
;
991 case IQ2000_OPERAND_MASKR
:
992 value
= fields
->f_rs
;
994 case IQ2000_OPERAND_MLO16
:
995 value
= fields
->f_imm
;
997 case IQ2000_OPERAND_OFFSET
:
998 value
= fields
->f_offset
;
1000 case IQ2000_OPERAND_RD
:
1001 value
= fields
->f_rd
;
1003 case IQ2000_OPERAND_RD_RS
:
1004 value
= fields
->f_rd_rs
;
1006 case IQ2000_OPERAND_RD_RT
:
1007 value
= fields
->f_rd_rt
;
1009 case IQ2000_OPERAND_RS
:
1010 value
= fields
->f_rs
;
1012 case IQ2000_OPERAND_RT
:
1013 value
= fields
->f_rt
;
1015 case IQ2000_OPERAND_RT_RS
:
1016 value
= fields
->f_rt_rs
;
1018 case IQ2000_OPERAND_SHAMT
:
1019 value
= fields
->f_shamt
;
1023 /* xgettext:c-format */
1024 fprintf (stderr
, _("Unrecognized field %d while getting int operand.\n"),
1033 iq2000_cgen_get_vma_operand (cd
, opindex
, fields
)
1034 CGEN_CPU_DESC cd ATTRIBUTE_UNUSED
;
1036 const CGEN_FIELDS
* fields
;
1042 case IQ2000_OPERAND_BASE
:
1043 value
= fields
->f_rs
;
1045 case IQ2000_OPERAND_BASEOFF
:
1046 value
= fields
->f_imm
;
1048 case IQ2000_OPERAND_BITNUM
:
1049 value
= fields
->f_rt
;
1051 case IQ2000_OPERAND_BYTECOUNT
:
1052 value
= fields
->f_bytecount
;
1054 case IQ2000_OPERAND_CAM_Y
:
1055 value
= fields
->f_cam_y
;
1057 case IQ2000_OPERAND_CAM_Z
:
1058 value
= fields
->f_cam_z
;
1060 case IQ2000_OPERAND_CM_3FUNC
:
1061 value
= fields
->f_cm_3func
;
1063 case IQ2000_OPERAND_CM_3Z
:
1064 value
= fields
->f_cm_3z
;
1066 case IQ2000_OPERAND_CM_4FUNC
:
1067 value
= fields
->f_cm_4func
;
1069 case IQ2000_OPERAND_CM_4Z
:
1070 value
= fields
->f_cm_4z
;
1072 case IQ2000_OPERAND_COUNT
:
1073 value
= fields
->f_count
;
1075 case IQ2000_OPERAND_EXECODE
:
1076 value
= fields
->f_excode
;
1078 case IQ2000_OPERAND_F_INDEX
:
1079 value
= fields
->f_index
;
1081 case IQ2000_OPERAND_HI16
:
1082 value
= fields
->f_imm
;
1084 case IQ2000_OPERAND_IMM
:
1085 value
= fields
->f_imm
;
1087 case IQ2000_OPERAND_JMPTARG
:
1088 value
= fields
->f_jtarg
;
1090 case IQ2000_OPERAND_JMPTARGQ10
:
1091 value
= fields
->f_jtargq10
;
1093 case IQ2000_OPERAND_LO16
:
1094 value
= fields
->f_imm
;
1096 case IQ2000_OPERAND_MASK
:
1097 value
= fields
->f_mask
;
1099 case IQ2000_OPERAND_MASKL
:
1100 value
= fields
->f_maskl
;
1102 case IQ2000_OPERAND_MASKQ10
:
1103 value
= fields
->f_maskq10
;
1105 case IQ2000_OPERAND_MASKR
:
1106 value
= fields
->f_rs
;
1108 case IQ2000_OPERAND_MLO16
:
1109 value
= fields
->f_imm
;
1111 case IQ2000_OPERAND_OFFSET
:
1112 value
= fields
->f_offset
;
1114 case IQ2000_OPERAND_RD
:
1115 value
= fields
->f_rd
;
1117 case IQ2000_OPERAND_RD_RS
:
1118 value
= fields
->f_rd_rs
;
1120 case IQ2000_OPERAND_RD_RT
:
1121 value
= fields
->f_rd_rt
;
1123 case IQ2000_OPERAND_RS
:
1124 value
= fields
->f_rs
;
1126 case IQ2000_OPERAND_RT
:
1127 value
= fields
->f_rt
;
1129 case IQ2000_OPERAND_RT_RS
:
1130 value
= fields
->f_rt_rs
;
1132 case IQ2000_OPERAND_SHAMT
:
1133 value
= fields
->f_shamt
;
1137 /* xgettext:c-format */
1138 fprintf (stderr
, _("Unrecognized field %d while getting vma operand.\n"),
1146 void iq2000_cgen_set_int_operand
1147 PARAMS ((CGEN_CPU_DESC
, int, CGEN_FIELDS
*, int));
1148 void iq2000_cgen_set_vma_operand
1149 PARAMS ((CGEN_CPU_DESC
, int, CGEN_FIELDS
*, bfd_vma
));
1151 /* Stuffing values in cgen_fields is handled by a collection of functions.
1152 They are distinguished by the type of the VALUE argument they accept.
1153 TODO: floating point, inlining support, remove cases where argument type
1157 iq2000_cgen_set_int_operand (cd
, opindex
, fields
, value
)
1158 CGEN_CPU_DESC cd ATTRIBUTE_UNUSED
;
1160 CGEN_FIELDS
* fields
;
1165 case IQ2000_OPERAND_BASE
:
1166 fields
->f_rs
= value
;
1168 case IQ2000_OPERAND_BASEOFF
:
1169 fields
->f_imm
= value
;
1171 case IQ2000_OPERAND_BITNUM
:
1172 fields
->f_rt
= value
;
1174 case IQ2000_OPERAND_BYTECOUNT
:
1175 fields
->f_bytecount
= value
;
1177 case IQ2000_OPERAND_CAM_Y
:
1178 fields
->f_cam_y
= value
;
1180 case IQ2000_OPERAND_CAM_Z
:
1181 fields
->f_cam_z
= value
;
1183 case IQ2000_OPERAND_CM_3FUNC
:
1184 fields
->f_cm_3func
= value
;
1186 case IQ2000_OPERAND_CM_3Z
:
1187 fields
->f_cm_3z
= value
;
1189 case IQ2000_OPERAND_CM_4FUNC
:
1190 fields
->f_cm_4func
= value
;
1192 case IQ2000_OPERAND_CM_4Z
:
1193 fields
->f_cm_4z
= value
;
1195 case IQ2000_OPERAND_COUNT
:
1196 fields
->f_count
= value
;
1198 case IQ2000_OPERAND_EXECODE
:
1199 fields
->f_excode
= value
;
1201 case IQ2000_OPERAND_F_INDEX
:
1202 fields
->f_index
= value
;
1204 case IQ2000_OPERAND_HI16
:
1205 fields
->f_imm
= value
;
1207 case IQ2000_OPERAND_IMM
:
1208 fields
->f_imm
= value
;
1210 case IQ2000_OPERAND_JMPTARG
:
1211 fields
->f_jtarg
= value
;
1213 case IQ2000_OPERAND_JMPTARGQ10
:
1214 fields
->f_jtargq10
= value
;
1216 case IQ2000_OPERAND_LO16
:
1217 fields
->f_imm
= value
;
1219 case IQ2000_OPERAND_MASK
:
1220 fields
->f_mask
= value
;
1222 case IQ2000_OPERAND_MASKL
:
1223 fields
->f_maskl
= value
;
1225 case IQ2000_OPERAND_MASKQ10
:
1226 fields
->f_maskq10
= value
;
1228 case IQ2000_OPERAND_MASKR
:
1229 fields
->f_rs
= value
;
1231 case IQ2000_OPERAND_MLO16
:
1232 fields
->f_imm
= value
;
1234 case IQ2000_OPERAND_OFFSET
:
1235 fields
->f_offset
= value
;
1237 case IQ2000_OPERAND_RD
:
1238 fields
->f_rd
= value
;
1240 case IQ2000_OPERAND_RD_RS
:
1241 fields
->f_rd_rs
= value
;
1243 case IQ2000_OPERAND_RD_RT
:
1244 fields
->f_rd_rt
= value
;
1246 case IQ2000_OPERAND_RS
:
1247 fields
->f_rs
= value
;
1249 case IQ2000_OPERAND_RT
:
1250 fields
->f_rt
= value
;
1252 case IQ2000_OPERAND_RT_RS
:
1253 fields
->f_rt_rs
= value
;
1255 case IQ2000_OPERAND_SHAMT
:
1256 fields
->f_shamt
= value
;
1260 /* xgettext:c-format */
1261 fprintf (stderr
, _("Unrecognized field %d while setting int operand.\n"),
1268 iq2000_cgen_set_vma_operand (cd
, opindex
, fields
, value
)
1269 CGEN_CPU_DESC cd ATTRIBUTE_UNUSED
;
1271 CGEN_FIELDS
* fields
;
1276 case IQ2000_OPERAND_BASE
:
1277 fields
->f_rs
= value
;
1279 case IQ2000_OPERAND_BASEOFF
:
1280 fields
->f_imm
= value
;
1282 case IQ2000_OPERAND_BITNUM
:
1283 fields
->f_rt
= value
;
1285 case IQ2000_OPERAND_BYTECOUNT
:
1286 fields
->f_bytecount
= value
;
1288 case IQ2000_OPERAND_CAM_Y
:
1289 fields
->f_cam_y
= value
;
1291 case IQ2000_OPERAND_CAM_Z
:
1292 fields
->f_cam_z
= value
;
1294 case IQ2000_OPERAND_CM_3FUNC
:
1295 fields
->f_cm_3func
= value
;
1297 case IQ2000_OPERAND_CM_3Z
:
1298 fields
->f_cm_3z
= value
;
1300 case IQ2000_OPERAND_CM_4FUNC
:
1301 fields
->f_cm_4func
= value
;
1303 case IQ2000_OPERAND_CM_4Z
:
1304 fields
->f_cm_4z
= value
;
1306 case IQ2000_OPERAND_COUNT
:
1307 fields
->f_count
= value
;
1309 case IQ2000_OPERAND_EXECODE
:
1310 fields
->f_excode
= value
;
1312 case IQ2000_OPERAND_F_INDEX
:
1313 fields
->f_index
= value
;
1315 case IQ2000_OPERAND_HI16
:
1316 fields
->f_imm
= value
;
1318 case IQ2000_OPERAND_IMM
:
1319 fields
->f_imm
= value
;
1321 case IQ2000_OPERAND_JMPTARG
:
1322 fields
->f_jtarg
= value
;
1324 case IQ2000_OPERAND_JMPTARGQ10
:
1325 fields
->f_jtargq10
= value
;
1327 case IQ2000_OPERAND_LO16
:
1328 fields
->f_imm
= value
;
1330 case IQ2000_OPERAND_MASK
:
1331 fields
->f_mask
= value
;
1333 case IQ2000_OPERAND_MASKL
:
1334 fields
->f_maskl
= value
;
1336 case IQ2000_OPERAND_MASKQ10
:
1337 fields
->f_maskq10
= value
;
1339 case IQ2000_OPERAND_MASKR
:
1340 fields
->f_rs
= value
;
1342 case IQ2000_OPERAND_MLO16
:
1343 fields
->f_imm
= value
;
1345 case IQ2000_OPERAND_OFFSET
:
1346 fields
->f_offset
= value
;
1348 case IQ2000_OPERAND_RD
:
1349 fields
->f_rd
= value
;
1351 case IQ2000_OPERAND_RD_RS
:
1352 fields
->f_rd_rs
= value
;
1354 case IQ2000_OPERAND_RD_RT
:
1355 fields
->f_rd_rt
= value
;
1357 case IQ2000_OPERAND_RS
:
1358 fields
->f_rs
= value
;
1360 case IQ2000_OPERAND_RT
:
1361 fields
->f_rt
= value
;
1363 case IQ2000_OPERAND_RT_RS
:
1364 fields
->f_rt_rs
= value
;
1366 case IQ2000_OPERAND_SHAMT
:
1367 fields
->f_shamt
= value
;
1371 /* xgettext:c-format */
1372 fprintf (stderr
, _("Unrecognized field %d while setting vma operand.\n"),
1378 /* Function to call before using the instruction builder tables. */
1381 iq2000_cgen_init_ibld_table (cd
)
1384 cd
->insert_handlers
= & iq2000_cgen_insert_handlers
[0];
1385 cd
->extract_handlers
= & iq2000_cgen_extract_handlers
[0];
1387 cd
->insert_operand
= iq2000_cgen_insert_operand
;
1388 cd
->extract_operand
= iq2000_cgen_extract_operand
;
1390 cd
->get_int_operand
= iq2000_cgen_get_int_operand
;
1391 cd
->set_int_operand
= iq2000_cgen_set_int_operand
;
1392 cd
->get_vma_operand
= iq2000_cgen_get_vma_operand
;
1393 cd
->set_vma_operand
= iq2000_cgen_set_vma_operand
;