1 /* Instruction building/extraction support for xstormy16. -*- 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, 2006, 2007,
7 2008, 2010 Free Software Foundation, Inc.
9 This file is part of libopcodes.
11 This library 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 3, or (at your option)
16 It is distributed in the hope that it will be useful, but WITHOUT
17 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
18 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
19 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 "xstormy16-desc.h"
35 #include "xstormy16-opc.h"
36 #include "cgen/basic-modes.h"
38 #include "safe-ctype.h"
41 #define min(a,b) ((a) < (b) ? (a) : (b))
43 #define max(a,b) ((a) > (b) ? (a) : (b))
45 /* Used by the ifield rtx function. */
46 #define FLD(f) (fields->f)
48 static const char * insert_normal
49 (CGEN_CPU_DESC
, long, unsigned int, unsigned int, unsigned int,
50 unsigned int, unsigned int, unsigned int, CGEN_INSN_BYTES_PTR
);
51 static const char * insert_insn_normal
52 (CGEN_CPU_DESC
, const CGEN_INSN
*,
53 CGEN_FIELDS
*, CGEN_INSN_BYTES_PTR
, bfd_vma
);
54 static int extract_normal
55 (CGEN_CPU_DESC
, CGEN_EXTRACT_INFO
*, CGEN_INSN_INT
,
56 unsigned int, unsigned int, unsigned int, unsigned int,
57 unsigned int, unsigned int, bfd_vma
, long *);
58 static int extract_insn_normal
59 (CGEN_CPU_DESC
, const CGEN_INSN
*, CGEN_EXTRACT_INFO
*,
60 CGEN_INSN_INT
, CGEN_FIELDS
*, bfd_vma
);
62 static void put_insn_int_value
63 (CGEN_CPU_DESC
, CGEN_INSN_BYTES_PTR
, int, int, CGEN_INSN_INT
);
66 static CGEN_INLINE
void insert_1
67 (CGEN_CPU_DESC
, unsigned long, int, int, int, unsigned char *);
68 static CGEN_INLINE
int fill_cache
69 (CGEN_CPU_DESC
, CGEN_EXTRACT_INFO
*, int, int, bfd_vma
);
70 static CGEN_INLINE
long extract_1
71 (CGEN_CPU_DESC
, CGEN_EXTRACT_INFO
*, int, int, int, unsigned char *, bfd_vma
);
74 /* Operand insertion. */
78 /* Subroutine of insert_normal. */
80 static CGEN_INLINE
void
81 insert_1 (CGEN_CPU_DESC cd
,
91 x
= cgen_get_insn_value (cd
, bufp
, word_length
);
93 /* Written this way to avoid undefined behaviour. */
94 mask
= (((1L << (length
- 1)) - 1) << 1) | 1;
96 shift
= (start
+ 1) - length
;
98 shift
= (word_length
- (start
+ length
));
99 x
= (x
& ~(mask
<< shift
)) | ((value
& mask
) << shift
);
101 cgen_put_insn_value (cd
, bufp
, word_length
, (bfd_vma
) x
);
104 #endif /* ! CGEN_INT_INSN_P */
106 /* Default insertion routine.
108 ATTRS is a mask of the boolean attributes.
109 WORD_OFFSET is the offset in bits from the start of the insn of the value.
110 WORD_LENGTH is the length of the word in bits in which the value resides.
111 START is the starting bit number in the word, architecture origin.
112 LENGTH is the length of VALUE in bits.
113 TOTAL_LENGTH is the total length of the insn in bits.
115 The result is an error message or NULL if success. */
117 /* ??? This duplicates functionality with bfd's howto table and
118 bfd_install_relocation. */
119 /* ??? This doesn't handle bfd_vma's. Create another function when
123 insert_normal (CGEN_CPU_DESC cd
,
126 unsigned int word_offset
,
129 unsigned int word_length
,
130 unsigned int total_length
,
131 CGEN_INSN_BYTES_PTR buffer
)
133 static char errbuf
[100];
134 /* Written this way to avoid undefined behaviour. */
135 unsigned long mask
= (((1L << (length
- 1)) - 1) << 1) | 1;
137 /* If LENGTH is zero, this operand doesn't contribute to the value. */
141 if (word_length
> 8 * sizeof (CGEN_INSN_INT
))
144 /* For architectures with insns smaller than the base-insn-bitsize,
145 word_length may be too big. */
146 if (cd
->min_insn_bitsize
< cd
->base_insn_bitsize
)
149 && word_length
> total_length
)
150 word_length
= total_length
;
153 /* Ensure VALUE will fit. */
154 if (CGEN_BOOL_ATTR (attrs
, CGEN_IFLD_SIGN_OPT
))
156 long minval
= - (1L << (length
- 1));
157 unsigned long maxval
= mask
;
159 if ((value
> 0 && (unsigned long) value
> maxval
)
162 /* xgettext:c-format */
164 _("operand out of range (%ld not between %ld and %lu)"),
165 value
, minval
, maxval
);
169 else if (! CGEN_BOOL_ATTR (attrs
, CGEN_IFLD_SIGNED
))
171 unsigned long maxval
= mask
;
172 unsigned long val
= (unsigned long) value
;
174 /* For hosts with a word size > 32 check to see if value has been sign
175 extended beyond 32 bits. If so then ignore these higher sign bits
176 as the user is attempting to store a 32-bit signed value into an
177 unsigned 32-bit field which is allowed. */
178 if (sizeof (unsigned long) > 4 && ((value
>> 32) == -1))
183 /* xgettext:c-format */
185 _("operand out of range (0x%lx not between 0 and 0x%lx)"),
192 if (! cgen_signed_overflow_ok_p (cd
))
194 long minval
= - (1L << (length
- 1));
195 long maxval
= (1L << (length
- 1)) - 1;
197 if (value
< minval
|| value
> maxval
)
200 /* xgettext:c-format */
201 (errbuf
, _("operand out of range (%ld not between %ld and %ld)"),
202 value
, minval
, maxval
);
213 if (CGEN_INSN_LSB0_P
)
214 shift
= (word_offset
+ start
+ 1) - length
;
216 shift
= total_length
- (word_offset
+ start
+ length
);
217 *buffer
= (*buffer
& ~(mask
<< shift
)) | ((value
& mask
) << shift
);
220 #else /* ! CGEN_INT_INSN_P */
223 unsigned char *bufp
= (unsigned char *) buffer
+ word_offset
/ 8;
225 insert_1 (cd
, value
, start
, length
, word_length
, bufp
);
228 #endif /* ! CGEN_INT_INSN_P */
233 /* Default insn builder (insert handler).
234 The instruction is recorded in CGEN_INT_INSN_P byte order (meaning
235 that if CGEN_INSN_BYTES_PTR is an int * and thus, the value is
236 recorded in host byte order, otherwise BUFFER is an array of bytes
237 and the value is recorded in target byte order).
238 The result is an error message or NULL if success. */
241 insert_insn_normal (CGEN_CPU_DESC cd
,
242 const CGEN_INSN
* insn
,
243 CGEN_FIELDS
* fields
,
244 CGEN_INSN_BYTES_PTR buffer
,
247 const CGEN_SYNTAX
*syntax
= CGEN_INSN_SYNTAX (insn
);
249 const CGEN_SYNTAX_CHAR_TYPE
* syn
;
251 CGEN_INIT_INSERT (cd
);
252 value
= CGEN_INSN_BASE_VALUE (insn
);
254 /* If we're recording insns as numbers (rather than a string of bytes),
255 target byte order handling is deferred until later. */
259 put_insn_int_value (cd
, buffer
, cd
->base_insn_bitsize
,
260 CGEN_FIELDS_BITSIZE (fields
), value
);
264 cgen_put_insn_value (cd
, buffer
, min ((unsigned) cd
->base_insn_bitsize
,
265 (unsigned) CGEN_FIELDS_BITSIZE (fields
)),
268 #endif /* ! CGEN_INT_INSN_P */
270 /* ??? It would be better to scan the format's fields.
271 Still need to be able to insert a value based on the operand though;
272 e.g. storing a branch displacement that got resolved later.
273 Needs more thought first. */
275 for (syn
= CGEN_SYNTAX_STRING (syntax
); * syn
; ++ syn
)
279 if (CGEN_SYNTAX_CHAR_P (* syn
))
282 errmsg
= (* cd
->insert_operand
) (cd
, CGEN_SYNTAX_FIELD (*syn
),
292 /* Cover function to store an insn value into an integral insn. Must go here
293 because it needs <prefix>-desc.h for CGEN_INT_INSN_P. */
296 put_insn_int_value (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED
,
297 CGEN_INSN_BYTES_PTR buf
,
302 /* For architectures with insns smaller than the base-insn-bitsize,
303 length may be too big. */
304 if (length
> insn_length
)
308 int shift
= insn_length
- length
;
309 /* Written this way to avoid undefined behaviour. */
310 CGEN_INSN_INT mask
= (((1L << (length
- 1)) - 1) << 1) | 1;
312 *buf
= (*buf
& ~(mask
<< shift
)) | ((value
& mask
) << shift
);
317 /* Operand extraction. */
319 #if ! CGEN_INT_INSN_P
321 /* Subroutine of extract_normal.
322 Ensure sufficient bytes are cached in EX_INFO.
323 OFFSET is the offset in bytes from the start of the insn of the value.
324 BYTES is the length of the needed value.
325 Returns 1 for success, 0 for failure. */
327 static CGEN_INLINE
int
328 fill_cache (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED
,
329 CGEN_EXTRACT_INFO
*ex_info
,
334 /* It's doubtful that the middle part has already been fetched so
335 we don't optimize that case. kiss. */
337 disassemble_info
*info
= (disassemble_info
*) ex_info
->dis_info
;
339 /* First do a quick check. */
340 mask
= (1 << bytes
) - 1;
341 if (((ex_info
->valid
>> offset
) & mask
) == mask
)
344 /* Search for the first byte we need to read. */
345 for (mask
= 1 << offset
; bytes
> 0; --bytes
, ++offset
, mask
<<= 1)
346 if (! (mask
& ex_info
->valid
))
354 status
= (*info
->read_memory_func
)
355 (pc
, ex_info
->insn_bytes
+ offset
, bytes
, info
);
359 (*info
->memory_error_func
) (status
, pc
, info
);
363 ex_info
->valid
|= ((1 << bytes
) - 1) << offset
;
369 /* Subroutine of extract_normal. */
371 static CGEN_INLINE
long
372 extract_1 (CGEN_CPU_DESC cd
,
373 CGEN_EXTRACT_INFO
*ex_info ATTRIBUTE_UNUSED
,
378 bfd_vma pc ATTRIBUTE_UNUSED
)
383 x
= cgen_get_insn_value (cd
, bufp
, word_length
);
385 if (CGEN_INSN_LSB0_P
)
386 shift
= (start
+ 1) - length
;
388 shift
= (word_length
- (start
+ length
));
392 #endif /* ! CGEN_INT_INSN_P */
394 /* Default extraction routine.
396 INSN_VALUE is the first base_insn_bitsize bits of the insn in host order,
397 or sometimes less for cases like the m32r where the base insn size is 32
398 but some insns are 16 bits.
399 ATTRS is a mask of the boolean attributes. We only need `SIGNED',
400 but for generality we take a bitmask of all of them.
401 WORD_OFFSET is the offset in bits from the start of the insn of the value.
402 WORD_LENGTH is the length of the word in bits in which the value resides.
403 START is the starting bit number in the word, architecture origin.
404 LENGTH is the length of VALUE in bits.
405 TOTAL_LENGTH is the total length of the insn in bits.
407 Returns 1 for success, 0 for failure. */
409 /* ??? The return code isn't properly used. wip. */
411 /* ??? This doesn't handle bfd_vma's. Create another function when
415 extract_normal (CGEN_CPU_DESC cd
,
416 #if ! CGEN_INT_INSN_P
417 CGEN_EXTRACT_INFO
*ex_info
,
419 CGEN_EXTRACT_INFO
*ex_info ATTRIBUTE_UNUSED
,
421 CGEN_INSN_INT insn_value
,
423 unsigned int word_offset
,
426 unsigned int word_length
,
427 unsigned int total_length
,
428 #if ! CGEN_INT_INSN_P
431 bfd_vma pc ATTRIBUTE_UNUSED
,
437 /* If LENGTH is zero, this operand doesn't contribute to the value
438 so give it a standard value of zero. */
445 if (word_length
> 8 * sizeof (CGEN_INSN_INT
))
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
)
452 if (word_offset
+ word_length
> total_length
)
453 word_length
= total_length
- word_offset
;
456 /* Does the value reside in INSN_VALUE, and at the right alignment? */
458 if (CGEN_INT_INSN_P
|| (word_offset
== 0 && word_length
== total_length
))
460 if (CGEN_INSN_LSB0_P
)
461 value
= insn_value
>> ((word_offset
+ start
+ 1) - length
);
463 value
= insn_value
>> (total_length
- ( word_offset
+ start
+ length
));
466 #if ! CGEN_INT_INSN_P
470 unsigned char *bufp
= ex_info
->insn_bytes
+ word_offset
/ 8;
472 if (word_length
> 8 * sizeof (CGEN_INSN_INT
))
475 if (fill_cache (cd
, ex_info
, word_offset
/ 8, word_length
/ 8, pc
) == 0)
478 value
= extract_1 (cd
, ex_info
, start
, length
, word_length
, bufp
, pc
);
481 #endif /* ! CGEN_INT_INSN_P */
483 /* Written this way to avoid undefined behaviour. */
484 mask
= (((1L << (length
- 1)) - 1) << 1) | 1;
488 if (CGEN_BOOL_ATTR (attrs
, CGEN_IFLD_SIGNED
)
489 && (value
& (1L << (length
- 1))))
497 /* Default insn extractor.
499 INSN_VALUE is the first base_insn_bitsize bits, translated to host order.
500 The extracted fields are stored in FIELDS.
501 EX_INFO is used to handle reading variable length insns.
502 Return the length of the insn in bits, or 0 if no match,
503 or -1 if an error occurs fetching data (memory_error_func will have
507 extract_insn_normal (CGEN_CPU_DESC cd
,
508 const CGEN_INSN
*insn
,
509 CGEN_EXTRACT_INFO
*ex_info
,
510 CGEN_INSN_INT insn_value
,
514 const CGEN_SYNTAX
*syntax
= CGEN_INSN_SYNTAX (insn
);
515 const CGEN_SYNTAX_CHAR_TYPE
*syn
;
517 CGEN_FIELDS_BITSIZE (fields
) = CGEN_INSN_BITSIZE (insn
);
519 CGEN_INIT_EXTRACT (cd
);
521 for (syn
= CGEN_SYNTAX_STRING (syntax
); *syn
; ++syn
)
525 if (CGEN_SYNTAX_CHAR_P (*syn
))
528 length
= (* cd
->extract_operand
) (cd
, CGEN_SYNTAX_FIELD (*syn
),
529 ex_info
, insn_value
, fields
, pc
);
534 /* We recognized and successfully extracted this insn. */
535 return CGEN_INSN_BITSIZE (insn
);
538 /* Machine generated code added here. */
540 const char * xstormy16_cgen_insert_operand
541 (CGEN_CPU_DESC
, int, CGEN_FIELDS
*, CGEN_INSN_BYTES_PTR
, bfd_vma
);
543 /* Main entry point for operand insertion.
545 This function is basically just a big switch statement. Earlier versions
546 used tables to look up the function to use, but
547 - if the table contains both assembler and disassembler functions then
548 the disassembler contains much of the assembler and vice-versa,
549 - there's a lot of inlining possibilities as things grow,
550 - using a switch statement avoids the function call overhead.
552 This function could be moved into `parse_insn_normal', but keeping it
553 separate makes clear the interface between `parse_insn_normal' and each of
554 the handlers. It's also needed by GAS to insert operands that couldn't be
555 resolved during parsing. */
558 xstormy16_cgen_insert_operand (CGEN_CPU_DESC cd
,
560 CGEN_FIELDS
* fields
,
561 CGEN_INSN_BYTES_PTR buffer
,
562 bfd_vma pc ATTRIBUTE_UNUSED
)
564 const char * errmsg
= NULL
;
565 unsigned int total_length
= CGEN_FIELDS_BITSIZE (fields
);
569 case XSTORMY16_OPERAND_RB
:
570 errmsg
= insert_normal (cd
, fields
->f_Rb
, 0, 0, 17, 3, 32, total_length
, buffer
);
572 case XSTORMY16_OPERAND_RBJ
:
573 errmsg
= insert_normal (cd
, fields
->f_Rbj
, 0, 0, 11, 1, 32, total_length
, buffer
);
575 case XSTORMY16_OPERAND_RD
:
576 errmsg
= insert_normal (cd
, fields
->f_Rd
, 0, 0, 12, 4, 32, total_length
, buffer
);
578 case XSTORMY16_OPERAND_RDM
:
579 errmsg
= insert_normal (cd
, fields
->f_Rdm
, 0, 0, 13, 3, 32, total_length
, buffer
);
581 case XSTORMY16_OPERAND_RM
:
582 errmsg
= insert_normal (cd
, fields
->f_Rm
, 0, 0, 4, 3, 32, total_length
, buffer
);
584 case XSTORMY16_OPERAND_RS
:
585 errmsg
= insert_normal (cd
, fields
->f_Rs
, 0, 0, 8, 4, 32, total_length
, buffer
);
587 case XSTORMY16_OPERAND_ABS24
:
590 FLD (f_abs24_1
) = ((FLD (f_abs24
)) & (255));
591 FLD (f_abs24_2
) = ((UINT
) (FLD (f_abs24
)) >> (8));
593 errmsg
= insert_normal (cd
, fields
->f_abs24_1
, 0, 0, 8, 8, 32, total_length
, buffer
);
596 errmsg
= insert_normal (cd
, fields
->f_abs24_2
, 0, 0, 16, 16, 32, total_length
, buffer
);
601 case XSTORMY16_OPERAND_BCOND2
:
602 errmsg
= insert_normal (cd
, fields
->f_op2
, 0, 0, 4, 4, 32, total_length
, buffer
);
604 case XSTORMY16_OPERAND_BCOND5
:
605 errmsg
= insert_normal (cd
, fields
->f_op5
, 0, 0, 16, 4, 32, total_length
, buffer
);
607 case XSTORMY16_OPERAND_HMEM8
:
609 long value
= fields
->f_hmem8
;
610 value
= ((value
) - (32512));
611 errmsg
= insert_normal (cd
, value
, 0|(1<<CGEN_IFLD_ABS_ADDR
), 0, 8, 8, 32, total_length
, buffer
);
614 case XSTORMY16_OPERAND_IMM12
:
615 errmsg
= insert_normal (cd
, fields
->f_imm12
, 0|(1<<CGEN_IFLD_SIGNED
), 0, 20, 12, 32, total_length
, buffer
);
617 case XSTORMY16_OPERAND_IMM16
:
618 errmsg
= insert_normal (cd
, fields
->f_imm16
, 0|(1<<CGEN_IFLD_SIGN_OPT
), 0, 16, 16, 32, total_length
, buffer
);
620 case XSTORMY16_OPERAND_IMM2
:
621 errmsg
= insert_normal (cd
, fields
->f_imm2
, 0, 0, 10, 2, 32, total_length
, buffer
);
623 case XSTORMY16_OPERAND_IMM3
:
624 errmsg
= insert_normal (cd
, fields
->f_imm3
, 0, 0, 4, 3, 32, total_length
, buffer
);
626 case XSTORMY16_OPERAND_IMM3B
:
627 errmsg
= insert_normal (cd
, fields
->f_imm3b
, 0, 0, 17, 3, 32, total_length
, buffer
);
629 case XSTORMY16_OPERAND_IMM4
:
630 errmsg
= insert_normal (cd
, fields
->f_imm4
, 0, 0, 8, 4, 32, total_length
, buffer
);
632 case XSTORMY16_OPERAND_IMM8
:
633 errmsg
= insert_normal (cd
, fields
->f_imm8
, 0, 0, 8, 8, 32, total_length
, buffer
);
635 case XSTORMY16_OPERAND_IMM8SMALL
:
636 errmsg
= insert_normal (cd
, fields
->f_imm8
, 0, 0, 8, 8, 32, total_length
, buffer
);
638 case XSTORMY16_OPERAND_LMEM8
:
639 errmsg
= insert_normal (cd
, fields
->f_lmem8
, 0|(1<<CGEN_IFLD_ABS_ADDR
), 0, 8, 8, 32, total_length
, buffer
);
641 case XSTORMY16_OPERAND_REL12
:
643 long value
= fields
->f_rel12
;
644 value
= ((value
) - (((pc
) + (4))));
645 errmsg
= insert_normal (cd
, value
, 0|(1<<CGEN_IFLD_SIGNED
)|(1<<CGEN_IFLD_PCREL_ADDR
), 0, 20, 12, 32, total_length
, buffer
);
648 case XSTORMY16_OPERAND_REL12A
:
650 long value
= fields
->f_rel12a
;
651 value
= ((SI
) (((value
) - (((pc
) + (2))))) >> (1));
652 errmsg
= insert_normal (cd
, value
, 0|(1<<CGEN_IFLD_SIGNED
)|(1<<CGEN_IFLD_PCREL_ADDR
), 0, 4, 11, 32, total_length
, buffer
);
655 case XSTORMY16_OPERAND_REL8_2
:
657 long value
= fields
->f_rel8_2
;
658 value
= ((value
) - (((pc
) + (2))));
659 errmsg
= insert_normal (cd
, value
, 0|(1<<CGEN_IFLD_SIGNED
)|(1<<CGEN_IFLD_PCREL_ADDR
), 0, 8, 8, 32, total_length
, buffer
);
662 case XSTORMY16_OPERAND_REL8_4
:
664 long value
= fields
->f_rel8_4
;
665 value
= ((value
) - (((pc
) + (4))));
666 errmsg
= insert_normal (cd
, value
, 0|(1<<CGEN_IFLD_SIGNED
)|(1<<CGEN_IFLD_PCREL_ADDR
), 0, 8, 8, 32, total_length
, buffer
);
669 case XSTORMY16_OPERAND_WS2
:
670 errmsg
= insert_normal (cd
, fields
->f_op2m
, 0, 0, 7, 1, 32, total_length
, buffer
);
674 /* xgettext:c-format */
675 fprintf (stderr
, _("Unrecognized field %d while building insn.\n"),
683 int xstormy16_cgen_extract_operand
684 (CGEN_CPU_DESC
, int, CGEN_EXTRACT_INFO
*, CGEN_INSN_INT
, CGEN_FIELDS
*, bfd_vma
);
686 /* Main entry point for operand extraction.
687 The result is <= 0 for error, >0 for success.
688 ??? Actual values aren't well defined right now.
690 This function is basically just a big switch statement. Earlier versions
691 used tables to look up the function to use, but
692 - if the table contains both assembler and disassembler functions then
693 the disassembler contains much of the assembler and vice-versa,
694 - there's a lot of inlining possibilities as things grow,
695 - using a switch statement avoids the function call overhead.
697 This function could be moved into `print_insn_normal', but keeping it
698 separate makes clear the interface between `print_insn_normal' and each of
702 xstormy16_cgen_extract_operand (CGEN_CPU_DESC cd
,
704 CGEN_EXTRACT_INFO
*ex_info
,
705 CGEN_INSN_INT insn_value
,
706 CGEN_FIELDS
* fields
,
709 /* Assume success (for those operands that are nops). */
711 unsigned int total_length
= CGEN_FIELDS_BITSIZE (fields
);
715 case XSTORMY16_OPERAND_RB
:
716 length
= extract_normal (cd
, ex_info
, insn_value
, 0, 0, 17, 3, 32, total_length
, pc
, & fields
->f_Rb
);
718 case XSTORMY16_OPERAND_RBJ
:
719 length
= extract_normal (cd
, ex_info
, insn_value
, 0, 0, 11, 1, 32, total_length
, pc
, & fields
->f_Rbj
);
721 case XSTORMY16_OPERAND_RD
:
722 length
= extract_normal (cd
, ex_info
, insn_value
, 0, 0, 12, 4, 32, total_length
, pc
, & fields
->f_Rd
);
724 case XSTORMY16_OPERAND_RDM
:
725 length
= extract_normal (cd
, ex_info
, insn_value
, 0, 0, 13, 3, 32, total_length
, pc
, & fields
->f_Rdm
);
727 case XSTORMY16_OPERAND_RM
:
728 length
= extract_normal (cd
, ex_info
, insn_value
, 0, 0, 4, 3, 32, total_length
, pc
, & fields
->f_Rm
);
730 case XSTORMY16_OPERAND_RS
:
731 length
= extract_normal (cd
, ex_info
, insn_value
, 0, 0, 8, 4, 32, total_length
, pc
, & fields
->f_Rs
);
733 case XSTORMY16_OPERAND_ABS24
:
735 length
= extract_normal (cd
, ex_info
, insn_value
, 0, 0, 8, 8, 32, total_length
, pc
, & fields
->f_abs24_1
);
736 if (length
<= 0) break;
737 length
= extract_normal (cd
, ex_info
, insn_value
, 0, 0, 16, 16, 32, total_length
, pc
, & fields
->f_abs24_2
);
738 if (length
<= 0) break;
739 FLD (f_abs24
) = ((((FLD (f_abs24_2
)) << (8))) | (FLD (f_abs24_1
)));
742 case XSTORMY16_OPERAND_BCOND2
:
743 length
= extract_normal (cd
, ex_info
, insn_value
, 0, 0, 4, 4, 32, total_length
, pc
, & fields
->f_op2
);
745 case XSTORMY16_OPERAND_BCOND5
:
746 length
= extract_normal (cd
, ex_info
, insn_value
, 0, 0, 16, 4, 32, total_length
, pc
, & fields
->f_op5
);
748 case XSTORMY16_OPERAND_HMEM8
:
751 length
= extract_normal (cd
, ex_info
, insn_value
, 0|(1<<CGEN_IFLD_ABS_ADDR
), 0, 8, 8, 32, total_length
, pc
, & value
);
752 value
= ((value
) + (32512));
753 fields
->f_hmem8
= value
;
756 case XSTORMY16_OPERAND_IMM12
:
757 length
= extract_normal (cd
, ex_info
, insn_value
, 0|(1<<CGEN_IFLD_SIGNED
), 0, 20, 12, 32, total_length
, pc
, & fields
->f_imm12
);
759 case XSTORMY16_OPERAND_IMM16
:
760 length
= extract_normal (cd
, ex_info
, insn_value
, 0|(1<<CGEN_IFLD_SIGN_OPT
), 0, 16, 16, 32, total_length
, pc
, & fields
->f_imm16
);
762 case XSTORMY16_OPERAND_IMM2
:
763 length
= extract_normal (cd
, ex_info
, insn_value
, 0, 0, 10, 2, 32, total_length
, pc
, & fields
->f_imm2
);
765 case XSTORMY16_OPERAND_IMM3
:
766 length
= extract_normal (cd
, ex_info
, insn_value
, 0, 0, 4, 3, 32, total_length
, pc
, & fields
->f_imm3
);
768 case XSTORMY16_OPERAND_IMM3B
:
769 length
= extract_normal (cd
, ex_info
, insn_value
, 0, 0, 17, 3, 32, total_length
, pc
, & fields
->f_imm3b
);
771 case XSTORMY16_OPERAND_IMM4
:
772 length
= extract_normal (cd
, ex_info
, insn_value
, 0, 0, 8, 4, 32, total_length
, pc
, & fields
->f_imm4
);
774 case XSTORMY16_OPERAND_IMM8
:
775 length
= extract_normal (cd
, ex_info
, insn_value
, 0, 0, 8, 8, 32, total_length
, pc
, & fields
->f_imm8
);
777 case XSTORMY16_OPERAND_IMM8SMALL
:
778 length
= extract_normal (cd
, ex_info
, insn_value
, 0, 0, 8, 8, 32, total_length
, pc
, & fields
->f_imm8
);
780 case XSTORMY16_OPERAND_LMEM8
:
781 length
= extract_normal (cd
, ex_info
, insn_value
, 0|(1<<CGEN_IFLD_ABS_ADDR
), 0, 8, 8, 32, total_length
, pc
, & fields
->f_lmem8
);
783 case XSTORMY16_OPERAND_REL12
:
786 length
= extract_normal (cd
, ex_info
, insn_value
, 0|(1<<CGEN_IFLD_SIGNED
)|(1<<CGEN_IFLD_PCREL_ADDR
), 0, 20, 12, 32, total_length
, pc
, & value
);
787 value
= ((value
) + (((pc
) + (4))));
788 fields
->f_rel12
= value
;
791 case XSTORMY16_OPERAND_REL12A
:
794 length
= extract_normal (cd
, ex_info
, insn_value
, 0|(1<<CGEN_IFLD_SIGNED
)|(1<<CGEN_IFLD_PCREL_ADDR
), 0, 4, 11, 32, total_length
, pc
, & value
);
795 value
= ((((value
) << (1))) + (((pc
) + (2))));
796 fields
->f_rel12a
= value
;
799 case XSTORMY16_OPERAND_REL8_2
:
802 length
= extract_normal (cd
, ex_info
, insn_value
, 0|(1<<CGEN_IFLD_SIGNED
)|(1<<CGEN_IFLD_PCREL_ADDR
), 0, 8, 8, 32, total_length
, pc
, & value
);
803 value
= ((value
) + (((pc
) + (2))));
804 fields
->f_rel8_2
= value
;
807 case XSTORMY16_OPERAND_REL8_4
:
810 length
= extract_normal (cd
, ex_info
, insn_value
, 0|(1<<CGEN_IFLD_SIGNED
)|(1<<CGEN_IFLD_PCREL_ADDR
), 0, 8, 8, 32, total_length
, pc
, & value
);
811 value
= ((value
) + (((pc
) + (4))));
812 fields
->f_rel8_4
= value
;
815 case XSTORMY16_OPERAND_WS2
:
816 length
= extract_normal (cd
, ex_info
, insn_value
, 0, 0, 7, 1, 32, total_length
, pc
, & fields
->f_op2m
);
820 /* xgettext:c-format */
821 fprintf (stderr
, _("Unrecognized field %d while decoding insn.\n"),
829 cgen_insert_fn
* const xstormy16_cgen_insert_handlers
[] =
834 cgen_extract_fn
* const xstormy16_cgen_extract_handlers
[] =
839 int xstormy16_cgen_get_int_operand (CGEN_CPU_DESC
, int, const CGEN_FIELDS
*);
840 bfd_vma
xstormy16_cgen_get_vma_operand (CGEN_CPU_DESC
, int, const CGEN_FIELDS
*);
842 /* Getting values from cgen_fields is handled by a collection of functions.
843 They are distinguished by the type of the VALUE argument they return.
844 TODO: floating point, inlining support, remove cases where result type
848 xstormy16_cgen_get_int_operand (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED
,
850 const CGEN_FIELDS
* fields
)
856 case XSTORMY16_OPERAND_RB
:
857 value
= fields
->f_Rb
;
859 case XSTORMY16_OPERAND_RBJ
:
860 value
= fields
->f_Rbj
;
862 case XSTORMY16_OPERAND_RD
:
863 value
= fields
->f_Rd
;
865 case XSTORMY16_OPERAND_RDM
:
866 value
= fields
->f_Rdm
;
868 case XSTORMY16_OPERAND_RM
:
869 value
= fields
->f_Rm
;
871 case XSTORMY16_OPERAND_RS
:
872 value
= fields
->f_Rs
;
874 case XSTORMY16_OPERAND_ABS24
:
875 value
= fields
->f_abs24
;
877 case XSTORMY16_OPERAND_BCOND2
:
878 value
= fields
->f_op2
;
880 case XSTORMY16_OPERAND_BCOND5
:
881 value
= fields
->f_op5
;
883 case XSTORMY16_OPERAND_HMEM8
:
884 value
= fields
->f_hmem8
;
886 case XSTORMY16_OPERAND_IMM12
:
887 value
= fields
->f_imm12
;
889 case XSTORMY16_OPERAND_IMM16
:
890 value
= fields
->f_imm16
;
892 case XSTORMY16_OPERAND_IMM2
:
893 value
= fields
->f_imm2
;
895 case XSTORMY16_OPERAND_IMM3
:
896 value
= fields
->f_imm3
;
898 case XSTORMY16_OPERAND_IMM3B
:
899 value
= fields
->f_imm3b
;
901 case XSTORMY16_OPERAND_IMM4
:
902 value
= fields
->f_imm4
;
904 case XSTORMY16_OPERAND_IMM8
:
905 value
= fields
->f_imm8
;
907 case XSTORMY16_OPERAND_IMM8SMALL
:
908 value
= fields
->f_imm8
;
910 case XSTORMY16_OPERAND_LMEM8
:
911 value
= fields
->f_lmem8
;
913 case XSTORMY16_OPERAND_REL12
:
914 value
= fields
->f_rel12
;
916 case XSTORMY16_OPERAND_REL12A
:
917 value
= fields
->f_rel12a
;
919 case XSTORMY16_OPERAND_REL8_2
:
920 value
= fields
->f_rel8_2
;
922 case XSTORMY16_OPERAND_REL8_4
:
923 value
= fields
->f_rel8_4
;
925 case XSTORMY16_OPERAND_WS2
:
926 value
= fields
->f_op2m
;
930 /* xgettext:c-format */
931 fprintf (stderr
, _("Unrecognized field %d while getting int operand.\n"),
940 xstormy16_cgen_get_vma_operand (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED
,
942 const CGEN_FIELDS
* fields
)
948 case XSTORMY16_OPERAND_RB
:
949 value
= fields
->f_Rb
;
951 case XSTORMY16_OPERAND_RBJ
:
952 value
= fields
->f_Rbj
;
954 case XSTORMY16_OPERAND_RD
:
955 value
= fields
->f_Rd
;
957 case XSTORMY16_OPERAND_RDM
:
958 value
= fields
->f_Rdm
;
960 case XSTORMY16_OPERAND_RM
:
961 value
= fields
->f_Rm
;
963 case XSTORMY16_OPERAND_RS
:
964 value
= fields
->f_Rs
;
966 case XSTORMY16_OPERAND_ABS24
:
967 value
= fields
->f_abs24
;
969 case XSTORMY16_OPERAND_BCOND2
:
970 value
= fields
->f_op2
;
972 case XSTORMY16_OPERAND_BCOND5
:
973 value
= fields
->f_op5
;
975 case XSTORMY16_OPERAND_HMEM8
:
976 value
= fields
->f_hmem8
;
978 case XSTORMY16_OPERAND_IMM12
:
979 value
= fields
->f_imm12
;
981 case XSTORMY16_OPERAND_IMM16
:
982 value
= fields
->f_imm16
;
984 case XSTORMY16_OPERAND_IMM2
:
985 value
= fields
->f_imm2
;
987 case XSTORMY16_OPERAND_IMM3
:
988 value
= fields
->f_imm3
;
990 case XSTORMY16_OPERAND_IMM3B
:
991 value
= fields
->f_imm3b
;
993 case XSTORMY16_OPERAND_IMM4
:
994 value
= fields
->f_imm4
;
996 case XSTORMY16_OPERAND_IMM8
:
997 value
= fields
->f_imm8
;
999 case XSTORMY16_OPERAND_IMM8SMALL
:
1000 value
= fields
->f_imm8
;
1002 case XSTORMY16_OPERAND_LMEM8
:
1003 value
= fields
->f_lmem8
;
1005 case XSTORMY16_OPERAND_REL12
:
1006 value
= fields
->f_rel12
;
1008 case XSTORMY16_OPERAND_REL12A
:
1009 value
= fields
->f_rel12a
;
1011 case XSTORMY16_OPERAND_REL8_2
:
1012 value
= fields
->f_rel8_2
;
1014 case XSTORMY16_OPERAND_REL8_4
:
1015 value
= fields
->f_rel8_4
;
1017 case XSTORMY16_OPERAND_WS2
:
1018 value
= fields
->f_op2m
;
1022 /* xgettext:c-format */
1023 fprintf (stderr
, _("Unrecognized field %d while getting vma operand.\n"),
1031 void xstormy16_cgen_set_int_operand (CGEN_CPU_DESC
, int, CGEN_FIELDS
*, int);
1032 void xstormy16_cgen_set_vma_operand (CGEN_CPU_DESC
, int, CGEN_FIELDS
*, bfd_vma
);
1034 /* Stuffing values in cgen_fields is handled by a collection of functions.
1035 They are distinguished by the type of the VALUE argument they accept.
1036 TODO: floating point, inlining support, remove cases where argument type
1040 xstormy16_cgen_set_int_operand (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED
,
1042 CGEN_FIELDS
* fields
,
1047 case XSTORMY16_OPERAND_RB
:
1048 fields
->f_Rb
= value
;
1050 case XSTORMY16_OPERAND_RBJ
:
1051 fields
->f_Rbj
= value
;
1053 case XSTORMY16_OPERAND_RD
:
1054 fields
->f_Rd
= value
;
1056 case XSTORMY16_OPERAND_RDM
:
1057 fields
->f_Rdm
= value
;
1059 case XSTORMY16_OPERAND_RM
:
1060 fields
->f_Rm
= value
;
1062 case XSTORMY16_OPERAND_RS
:
1063 fields
->f_Rs
= value
;
1065 case XSTORMY16_OPERAND_ABS24
:
1066 fields
->f_abs24
= value
;
1068 case XSTORMY16_OPERAND_BCOND2
:
1069 fields
->f_op2
= value
;
1071 case XSTORMY16_OPERAND_BCOND5
:
1072 fields
->f_op5
= value
;
1074 case XSTORMY16_OPERAND_HMEM8
:
1075 fields
->f_hmem8
= value
;
1077 case XSTORMY16_OPERAND_IMM12
:
1078 fields
->f_imm12
= value
;
1080 case XSTORMY16_OPERAND_IMM16
:
1081 fields
->f_imm16
= value
;
1083 case XSTORMY16_OPERAND_IMM2
:
1084 fields
->f_imm2
= value
;
1086 case XSTORMY16_OPERAND_IMM3
:
1087 fields
->f_imm3
= value
;
1089 case XSTORMY16_OPERAND_IMM3B
:
1090 fields
->f_imm3b
= value
;
1092 case XSTORMY16_OPERAND_IMM4
:
1093 fields
->f_imm4
= value
;
1095 case XSTORMY16_OPERAND_IMM8
:
1096 fields
->f_imm8
= value
;
1098 case XSTORMY16_OPERAND_IMM8SMALL
:
1099 fields
->f_imm8
= value
;
1101 case XSTORMY16_OPERAND_LMEM8
:
1102 fields
->f_lmem8
= value
;
1104 case XSTORMY16_OPERAND_REL12
:
1105 fields
->f_rel12
= value
;
1107 case XSTORMY16_OPERAND_REL12A
:
1108 fields
->f_rel12a
= value
;
1110 case XSTORMY16_OPERAND_REL8_2
:
1111 fields
->f_rel8_2
= value
;
1113 case XSTORMY16_OPERAND_REL8_4
:
1114 fields
->f_rel8_4
= value
;
1116 case XSTORMY16_OPERAND_WS2
:
1117 fields
->f_op2m
= value
;
1121 /* xgettext:c-format */
1122 fprintf (stderr
, _("Unrecognized field %d while setting int operand.\n"),
1129 xstormy16_cgen_set_vma_operand (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED
,
1131 CGEN_FIELDS
* fields
,
1136 case XSTORMY16_OPERAND_RB
:
1137 fields
->f_Rb
= value
;
1139 case XSTORMY16_OPERAND_RBJ
:
1140 fields
->f_Rbj
= value
;
1142 case XSTORMY16_OPERAND_RD
:
1143 fields
->f_Rd
= value
;
1145 case XSTORMY16_OPERAND_RDM
:
1146 fields
->f_Rdm
= value
;
1148 case XSTORMY16_OPERAND_RM
:
1149 fields
->f_Rm
= value
;
1151 case XSTORMY16_OPERAND_RS
:
1152 fields
->f_Rs
= value
;
1154 case XSTORMY16_OPERAND_ABS24
:
1155 fields
->f_abs24
= value
;
1157 case XSTORMY16_OPERAND_BCOND2
:
1158 fields
->f_op2
= value
;
1160 case XSTORMY16_OPERAND_BCOND5
:
1161 fields
->f_op5
= value
;
1163 case XSTORMY16_OPERAND_HMEM8
:
1164 fields
->f_hmem8
= value
;
1166 case XSTORMY16_OPERAND_IMM12
:
1167 fields
->f_imm12
= value
;
1169 case XSTORMY16_OPERAND_IMM16
:
1170 fields
->f_imm16
= value
;
1172 case XSTORMY16_OPERAND_IMM2
:
1173 fields
->f_imm2
= value
;
1175 case XSTORMY16_OPERAND_IMM3
:
1176 fields
->f_imm3
= value
;
1178 case XSTORMY16_OPERAND_IMM3B
:
1179 fields
->f_imm3b
= value
;
1181 case XSTORMY16_OPERAND_IMM4
:
1182 fields
->f_imm4
= value
;
1184 case XSTORMY16_OPERAND_IMM8
:
1185 fields
->f_imm8
= value
;
1187 case XSTORMY16_OPERAND_IMM8SMALL
:
1188 fields
->f_imm8
= value
;
1190 case XSTORMY16_OPERAND_LMEM8
:
1191 fields
->f_lmem8
= value
;
1193 case XSTORMY16_OPERAND_REL12
:
1194 fields
->f_rel12
= value
;
1196 case XSTORMY16_OPERAND_REL12A
:
1197 fields
->f_rel12a
= value
;
1199 case XSTORMY16_OPERAND_REL8_2
:
1200 fields
->f_rel8_2
= value
;
1202 case XSTORMY16_OPERAND_REL8_4
:
1203 fields
->f_rel8_4
= value
;
1205 case XSTORMY16_OPERAND_WS2
:
1206 fields
->f_op2m
= value
;
1210 /* xgettext:c-format */
1211 fprintf (stderr
, _("Unrecognized field %d while setting vma operand.\n"),
1217 /* Function to call before using the instruction builder tables. */
1220 xstormy16_cgen_init_ibld_table (CGEN_CPU_DESC cd
)
1222 cd
->insert_handlers
= & xstormy16_cgen_insert_handlers
[0];
1223 cd
->extract_handlers
= & xstormy16_cgen_extract_handlers
[0];
1225 cd
->insert_operand
= xstormy16_cgen_insert_operand
;
1226 cd
->extract_operand
= xstormy16_cgen_extract_operand
;
1228 cd
->get_int_operand
= xstormy16_cgen_get_int_operand
;
1229 cd
->set_int_operand
= xstormy16_cgen_set_int_operand
;
1230 cd
->get_vma_operand
= xstormy16_cgen_get_vma_operand
;
1231 cd
->set_vma_operand
= xstormy16_cgen_set_vma_operand
;