Automatic date update in version.in
[binutils-gdb.git] / opcodes / xc16x-ibld.c
blob21d13acdb979be559450bb57c1624470c1864b1b
1 /* DO NOT EDIT! -*- buffer-read-only: t -*- vi:set ro: */
2 /* Instruction building/extraction support for xc16x. -*- C -*-
4 THIS FILE IS MACHINE GENERATED WITH CGEN: Cpu tools GENerator.
5 - the resultant file is machine generated, cgen-ibld.in isn't
7 Copyright (C) 1996-2021 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)
14 any later version.
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.
26 Keep that in mind. */
28 #include "sysdep.h"
29 #include <stdio.h>
30 #include "ansidecl.h"
31 #include "dis-asm.h"
32 #include "bfd.h"
33 #include "symcat.h"
34 #include "xc16x-desc.h"
35 #include "xc16x-opc.h"
36 #include "cgen/basic-modes.h"
37 #include "opintl.h"
38 #include "safe-ctype.h"
40 #undef min
41 #define min(a,b) ((a) < (b) ? (a) : (b))
42 #undef max
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);
61 #if CGEN_INT_INSN_P
62 static void put_insn_int_value
63 (CGEN_CPU_DESC, CGEN_INSN_BYTES_PTR, int, int, CGEN_INSN_INT);
64 #endif
65 #if ! CGEN_INT_INSN_P
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);
72 #endif
74 /* Operand insertion. */
76 #if ! CGEN_INT_INSN_P
78 /* Subroutine of insert_normal. */
80 static CGEN_INLINE void
81 insert_1 (CGEN_CPU_DESC cd,
82 unsigned long value,
83 int start,
84 int length,
85 int word_length,
86 unsigned char *bufp)
88 unsigned long x, mask;
89 int shift;
91 x = cgen_get_insn_value (cd, bufp, word_length, cd->endian);
93 /* Written this way to avoid undefined behaviour. */
94 mask = (1UL << (length - 1) << 1) - 1;
95 if (CGEN_INSN_LSB0_P)
96 shift = (start + 1) - length;
97 else
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, cd->endian);
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
120 necessary. */
122 static const char *
123 insert_normal (CGEN_CPU_DESC cd,
124 long value,
125 unsigned int attrs,
126 unsigned int word_offset,
127 unsigned int start,
128 unsigned int length,
129 unsigned int word_length,
130 unsigned int total_length,
131 CGEN_INSN_BYTES_PTR buffer)
133 static char errbuf[100];
134 unsigned long mask;
136 /* If LENGTH is zero, this operand doesn't contribute to the value. */
137 if (length == 0)
138 return NULL;
140 /* Written this way to avoid undefined behaviour. */
141 mask = (1UL << (length - 1) << 1) - 1;
143 if (word_length > 8 * sizeof (CGEN_INSN_INT))
144 abort ();
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)
150 if (word_offset == 0
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 = - (1UL << (length - 1));
159 unsigned long maxval = mask;
161 if ((value > 0 && (unsigned long) value > maxval)
162 || value < minval)
164 /* xgettext:c-format */
165 sprintf (errbuf,
166 _("operand out of range (%ld not between %ld and %lu)"),
167 value, minval, maxval);
168 return errbuf;
171 else if (! CGEN_BOOL_ATTR (attrs, CGEN_IFLD_SIGNED))
173 unsigned long maxval = mask;
174 unsigned long val = (unsigned long) value;
176 /* For hosts with a word size > 32 check to see if value has been sign
177 extended beyond 32 bits. If so then ignore these higher sign bits
178 as the user is attempting to store a 32-bit signed value into an
179 unsigned 32-bit field which is allowed. */
180 if (sizeof (unsigned long) > 4 && ((value >> 32) == -1))
181 val &= 0xFFFFFFFF;
183 if (val > maxval)
185 /* xgettext:c-format */
186 sprintf (errbuf,
187 _("operand out of range (0x%lx not between 0 and 0x%lx)"),
188 val, maxval);
189 return errbuf;
192 else
194 if (! cgen_signed_overflow_ok_p (cd))
196 long minval = - (1UL << (length - 1));
197 long maxval = (1UL << (length - 1)) - 1;
199 if (value < minval || value > maxval)
201 sprintf
202 /* xgettext:c-format */
203 (errbuf, _("operand out of range (%ld not between %ld and %ld)"),
204 value, minval, maxval);
205 return errbuf;
210 #if CGEN_INT_INSN_P
213 int shift_within_word, shift_to_word, shift;
215 /* How to shift the value to BIT0 of the word. */
216 shift_to_word = total_length - (word_offset + word_length);
218 /* How to shift the value to the field within the word. */
219 if (CGEN_INSN_LSB0_P)
220 shift_within_word = start + 1 - length;
221 else
222 shift_within_word = word_length - start - length;
224 /* The total SHIFT, then mask in the value. */
225 shift = shift_to_word + shift_within_word;
226 *buffer = (*buffer & ~(mask << shift)) | ((value & mask) << shift);
229 #else /* ! CGEN_INT_INSN_P */
232 unsigned char *bufp = (unsigned char *) buffer + word_offset / 8;
234 insert_1 (cd, value, start, length, word_length, bufp);
237 #endif /* ! CGEN_INT_INSN_P */
239 return NULL;
242 /* Default insn builder (insert handler).
243 The instruction is recorded in CGEN_INT_INSN_P byte order (meaning
244 that if CGEN_INSN_BYTES_PTR is an int * and thus, the value is
245 recorded in host byte order, otherwise BUFFER is an array of bytes
246 and the value is recorded in target byte order).
247 The result is an error message or NULL if success. */
249 static const char *
250 insert_insn_normal (CGEN_CPU_DESC cd,
251 const CGEN_INSN * insn,
252 CGEN_FIELDS * fields,
253 CGEN_INSN_BYTES_PTR buffer,
254 bfd_vma pc)
256 const CGEN_SYNTAX *syntax = CGEN_INSN_SYNTAX (insn);
257 unsigned long value;
258 const CGEN_SYNTAX_CHAR_TYPE * syn;
260 CGEN_INIT_INSERT (cd);
261 value = CGEN_INSN_BASE_VALUE (insn);
263 /* If we're recording insns as numbers (rather than a string of bytes),
264 target byte order handling is deferred until later. */
266 #if CGEN_INT_INSN_P
268 put_insn_int_value (cd, buffer, cd->base_insn_bitsize,
269 CGEN_FIELDS_BITSIZE (fields), value);
271 #else
273 cgen_put_insn_value (cd, buffer, min ((unsigned) cd->base_insn_bitsize,
274 (unsigned) CGEN_FIELDS_BITSIZE (fields)),
275 value, cd->insn_endian);
277 #endif /* ! CGEN_INT_INSN_P */
279 /* ??? It would be better to scan the format's fields.
280 Still need to be able to insert a value based on the operand though;
281 e.g. storing a branch displacement that got resolved later.
282 Needs more thought first. */
284 for (syn = CGEN_SYNTAX_STRING (syntax); * syn; ++ syn)
286 const char *errmsg;
288 if (CGEN_SYNTAX_CHAR_P (* syn))
289 continue;
291 errmsg = (* cd->insert_operand) (cd, CGEN_SYNTAX_FIELD (*syn),
292 fields, buffer, pc);
293 if (errmsg)
294 return errmsg;
297 return NULL;
300 #if CGEN_INT_INSN_P
301 /* Cover function to store an insn value into an integral insn. Must go here
302 because it needs <prefix>-desc.h for CGEN_INT_INSN_P. */
304 static void
305 put_insn_int_value (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
306 CGEN_INSN_BYTES_PTR buf,
307 int length,
308 int insn_length,
309 CGEN_INSN_INT value)
311 /* For architectures with insns smaller than the base-insn-bitsize,
312 length may be too big. */
313 if (length > insn_length)
314 *buf = value;
315 else
317 int shift = insn_length - length;
318 /* Written this way to avoid undefined behaviour. */
319 CGEN_INSN_INT mask = length == 0 ? 0 : (1UL << (length - 1) << 1) - 1;
321 *buf = (*buf & ~(mask << shift)) | ((value & mask) << shift);
324 #endif
326 /* Operand extraction. */
328 #if ! CGEN_INT_INSN_P
330 /* Subroutine of extract_normal.
331 Ensure sufficient bytes are cached in EX_INFO.
332 OFFSET is the offset in bytes from the start of the insn of the value.
333 BYTES is the length of the needed value.
334 Returns 1 for success, 0 for failure. */
336 static CGEN_INLINE int
337 fill_cache (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
338 CGEN_EXTRACT_INFO *ex_info,
339 int offset,
340 int bytes,
341 bfd_vma pc)
343 /* It's doubtful that the middle part has already been fetched so
344 we don't optimize that case. kiss. */
345 unsigned int mask;
346 disassemble_info *info = (disassemble_info *) ex_info->dis_info;
348 /* First do a quick check. */
349 mask = (1 << bytes) - 1;
350 if (((ex_info->valid >> offset) & mask) == mask)
351 return 1;
353 /* Search for the first byte we need to read. */
354 for (mask = 1 << offset; bytes > 0; --bytes, ++offset, mask <<= 1)
355 if (! (mask & ex_info->valid))
356 break;
358 if (bytes)
360 int status;
362 pc += offset;
363 status = (*info->read_memory_func)
364 (pc, ex_info->insn_bytes + offset, bytes, info);
366 if (status != 0)
368 (*info->memory_error_func) (status, pc, info);
369 return 0;
372 ex_info->valid |= ((1 << bytes) - 1) << offset;
375 return 1;
378 /* Subroutine of extract_normal. */
380 static CGEN_INLINE long
381 extract_1 (CGEN_CPU_DESC cd,
382 CGEN_EXTRACT_INFO *ex_info ATTRIBUTE_UNUSED,
383 int start,
384 int length,
385 int word_length,
386 unsigned char *bufp,
387 bfd_vma pc ATTRIBUTE_UNUSED)
389 unsigned long x;
390 int shift;
392 x = cgen_get_insn_value (cd, bufp, word_length, cd->endian);
394 if (CGEN_INSN_LSB0_P)
395 shift = (start + 1) - length;
396 else
397 shift = (word_length - (start + length));
398 return x >> shift;
401 #endif /* ! CGEN_INT_INSN_P */
403 /* Default extraction routine.
405 INSN_VALUE is the first base_insn_bitsize bits of the insn in host order,
406 or sometimes less for cases like the m32r where the base insn size is 32
407 but some insns are 16 bits.
408 ATTRS is a mask of the boolean attributes. We only need `SIGNED',
409 but for generality we take a bitmask of all of them.
410 WORD_OFFSET is the offset in bits from the start of the insn of the value.
411 WORD_LENGTH is the length of the word in bits in which the value resides.
412 START is the starting bit number in the word, architecture origin.
413 LENGTH is the length of VALUE in bits.
414 TOTAL_LENGTH is the total length of the insn in bits.
416 Returns 1 for success, 0 for failure. */
418 /* ??? The return code isn't properly used. wip. */
420 /* ??? This doesn't handle bfd_vma's. Create another function when
421 necessary. */
423 static int
424 extract_normal (CGEN_CPU_DESC cd,
425 #if ! CGEN_INT_INSN_P
426 CGEN_EXTRACT_INFO *ex_info,
427 #else
428 CGEN_EXTRACT_INFO *ex_info ATTRIBUTE_UNUSED,
429 #endif
430 CGEN_INSN_INT insn_value,
431 unsigned int attrs,
432 unsigned int word_offset,
433 unsigned int start,
434 unsigned int length,
435 unsigned int word_length,
436 unsigned int total_length,
437 #if ! CGEN_INT_INSN_P
438 bfd_vma pc,
439 #else
440 bfd_vma pc ATTRIBUTE_UNUSED,
441 #endif
442 long *valuep)
444 long value, mask;
446 /* If LENGTH is zero, this operand doesn't contribute to the value
447 so give it a standard value of zero. */
448 if (length == 0)
450 *valuep = 0;
451 return 1;
454 if (word_length > 8 * sizeof (CGEN_INSN_INT))
455 abort ();
457 /* For architectures with insns smaller than the insn-base-bitsize,
458 word_length may be too big. */
459 if (cd->min_insn_bitsize < cd->base_insn_bitsize)
461 if (word_offset + word_length > total_length)
462 word_length = total_length - word_offset;
465 /* Does the value reside in INSN_VALUE, and at the right alignment? */
467 if (CGEN_INT_INSN_P || (word_offset == 0 && word_length == total_length))
469 if (CGEN_INSN_LSB0_P)
470 value = insn_value >> ((word_offset + start + 1) - length);
471 else
472 value = insn_value >> (total_length - ( word_offset + start + length));
475 #if ! CGEN_INT_INSN_P
477 else
479 unsigned char *bufp = ex_info->insn_bytes + word_offset / 8;
481 if (word_length > 8 * sizeof (CGEN_INSN_INT))
482 abort ();
484 if (fill_cache (cd, ex_info, word_offset / 8, word_length / 8, pc) == 0)
486 *valuep = 0;
487 return 0;
490 value = extract_1 (cd, ex_info, start, length, word_length, bufp, pc);
493 #endif /* ! CGEN_INT_INSN_P */
495 /* Written this way to avoid undefined behaviour. */
496 mask = (1UL << (length - 1) << 1) - 1;
498 value &= mask;
499 /* sign extend? */
500 if (CGEN_BOOL_ATTR (attrs, CGEN_IFLD_SIGNED)
501 && (value & (1UL << (length - 1))))
502 value |= ~mask;
504 *valuep = value;
506 return 1;
509 /* Default insn extractor.
511 INSN_VALUE is the first base_insn_bitsize bits, translated to host order.
512 The extracted fields are stored in FIELDS.
513 EX_INFO is used to handle reading variable length insns.
514 Return the length of the insn in bits, or 0 if no match,
515 or -1 if an error occurs fetching data (memory_error_func will have
516 been called). */
518 static int
519 extract_insn_normal (CGEN_CPU_DESC cd,
520 const CGEN_INSN *insn,
521 CGEN_EXTRACT_INFO *ex_info,
522 CGEN_INSN_INT insn_value,
523 CGEN_FIELDS *fields,
524 bfd_vma pc)
526 const CGEN_SYNTAX *syntax = CGEN_INSN_SYNTAX (insn);
527 const CGEN_SYNTAX_CHAR_TYPE *syn;
529 CGEN_FIELDS_BITSIZE (fields) = CGEN_INSN_BITSIZE (insn);
531 CGEN_INIT_EXTRACT (cd);
533 for (syn = CGEN_SYNTAX_STRING (syntax); *syn; ++syn)
535 int length;
537 if (CGEN_SYNTAX_CHAR_P (*syn))
538 continue;
540 length = (* cd->extract_operand) (cd, CGEN_SYNTAX_FIELD (*syn),
541 ex_info, insn_value, fields, pc);
542 if (length <= 0)
543 return length;
546 /* We recognized and successfully extracted this insn. */
547 return CGEN_INSN_BITSIZE (insn);
550 /* Machine generated code added here. */
552 const char * xc16x_cgen_insert_operand
553 (CGEN_CPU_DESC, int, CGEN_FIELDS *, CGEN_INSN_BYTES_PTR, bfd_vma);
555 /* Main entry point for operand insertion.
557 This function is basically just a big switch statement. Earlier versions
558 used tables to look up the function to use, but
559 - if the table contains both assembler and disassembler functions then
560 the disassembler contains much of the assembler and vice-versa,
561 - there's a lot of inlining possibilities as things grow,
562 - using a switch statement avoids the function call overhead.
564 This function could be moved into `parse_insn_normal', but keeping it
565 separate makes clear the interface between `parse_insn_normal' and each of
566 the handlers. It's also needed by GAS to insert operands that couldn't be
567 resolved during parsing. */
569 const char *
570 xc16x_cgen_insert_operand (CGEN_CPU_DESC cd,
571 int opindex,
572 CGEN_FIELDS * fields,
573 CGEN_INSN_BYTES_PTR buffer,
574 bfd_vma pc ATTRIBUTE_UNUSED)
576 const char * errmsg = NULL;
577 unsigned int total_length = CGEN_FIELDS_BITSIZE (fields);
579 switch (opindex)
581 case XC16X_OPERAND_REGNAM :
582 errmsg = insert_normal (cd, fields->f_reg8, 0, 0, 15, 8, 32, total_length, buffer);
583 break;
584 case XC16X_OPERAND_BIT01 :
585 errmsg = insert_normal (cd, fields->f_op_1bit, 0, 0, 8, 1, 32, total_length, buffer);
586 break;
587 case XC16X_OPERAND_BIT1 :
588 errmsg = insert_normal (cd, fields->f_op_bit1, 0, 0, 11, 1, 32, total_length, buffer);
589 break;
590 case XC16X_OPERAND_BIT2 :
591 errmsg = insert_normal (cd, fields->f_op_bit2, 0, 0, 11, 2, 32, total_length, buffer);
592 break;
593 case XC16X_OPERAND_BIT4 :
594 errmsg = insert_normal (cd, fields->f_op_bit4, 0, 0, 11, 4, 32, total_length, buffer);
595 break;
596 case XC16X_OPERAND_BIT8 :
597 errmsg = insert_normal (cd, fields->f_op_bit8, 0, 0, 31, 8, 32, total_length, buffer);
598 break;
599 case XC16X_OPERAND_BITONE :
600 errmsg = insert_normal (cd, fields->f_op_onebit, 0, 0, 9, 1, 32, total_length, buffer);
601 break;
602 case XC16X_OPERAND_CADDR :
603 errmsg = insert_normal (cd, fields->f_offset16, 0|(1<<CGEN_IFLD_RELOC)|(1<<CGEN_IFLD_ABS_ADDR), 0, 31, 16, 32, total_length, buffer);
604 break;
605 case XC16X_OPERAND_COND :
606 errmsg = insert_normal (cd, fields->f_condcode, 0, 0, 7, 4, 32, total_length, buffer);
607 break;
608 case XC16X_OPERAND_DATA8 :
609 errmsg = insert_normal (cd, fields->f_data8, 0, 0, 23, 8, 32, total_length, buffer);
610 break;
611 case XC16X_OPERAND_DATAHI8 :
612 errmsg = insert_normal (cd, fields->f_datahi8, 0, 0, 31, 8, 32, total_length, buffer);
613 break;
614 case XC16X_OPERAND_DOT :
615 break;
616 case XC16X_OPERAND_DR :
617 errmsg = insert_normal (cd, fields->f_r1, 0, 0, 15, 4, 32, total_length, buffer);
618 break;
619 case XC16X_OPERAND_DRB :
620 errmsg = insert_normal (cd, fields->f_r1, 0, 0, 15, 4, 32, total_length, buffer);
621 break;
622 case XC16X_OPERAND_DRI :
623 errmsg = insert_normal (cd, fields->f_r4, 0, 0, 11, 4, 32, total_length, buffer);
624 break;
625 case XC16X_OPERAND_EXTCOND :
626 errmsg = insert_normal (cd, fields->f_extccode, 0, 0, 15, 5, 32, total_length, buffer);
627 break;
628 case XC16X_OPERAND_GENREG :
629 errmsg = insert_normal (cd, fields->f_regb8, 0, 0, 15, 8, 32, total_length, buffer);
630 break;
631 case XC16X_OPERAND_HASH :
632 break;
633 case XC16X_OPERAND_ICOND :
634 errmsg = insert_normal (cd, fields->f_icondcode, 0, 0, 15, 4, 32, total_length, buffer);
635 break;
636 case XC16X_OPERAND_LBIT2 :
637 errmsg = insert_normal (cd, fields->f_op_lbit2, 0, 0, 15, 2, 32, total_length, buffer);
638 break;
639 case XC16X_OPERAND_LBIT4 :
640 errmsg = insert_normal (cd, fields->f_op_lbit4, 0, 0, 15, 4, 32, total_length, buffer);
641 break;
642 case XC16X_OPERAND_MASK8 :
643 errmsg = insert_normal (cd, fields->f_mask8, 0, 0, 23, 8, 32, total_length, buffer);
644 break;
645 case XC16X_OPERAND_MASKLO8 :
646 errmsg = insert_normal (cd, fields->f_datahi8, 0, 0, 31, 8, 32, total_length, buffer);
647 break;
648 case XC16X_OPERAND_MEMGR8 :
649 errmsg = insert_normal (cd, fields->f_memgr8, 0, 0, 31, 16, 32, total_length, buffer);
650 break;
651 case XC16X_OPERAND_MEMORY :
652 errmsg = insert_normal (cd, fields->f_memory, 0, 0, 31, 16, 32, total_length, buffer);
653 break;
654 case XC16X_OPERAND_PAG :
655 break;
656 case XC16X_OPERAND_PAGENUM :
657 errmsg = insert_normal (cd, fields->f_pagenum, 0, 0, 25, 10, 32, total_length, buffer);
658 break;
659 case XC16X_OPERAND_POF :
660 break;
661 case XC16X_OPERAND_QBIT :
662 errmsg = insert_normal (cd, fields->f_qbit, 0, 0, 7, 4, 32, total_length, buffer);
663 break;
664 case XC16X_OPERAND_QHIBIT :
665 errmsg = insert_normal (cd, fields->f_qhibit, 0, 0, 27, 4, 32, total_length, buffer);
666 break;
667 case XC16X_OPERAND_QLOBIT :
668 errmsg = insert_normal (cd, fields->f_qlobit, 0, 0, 31, 4, 32, total_length, buffer);
669 break;
670 case XC16X_OPERAND_REG8 :
671 errmsg = insert_normal (cd, fields->f_reg8, 0, 0, 15, 8, 32, total_length, buffer);
672 break;
673 case XC16X_OPERAND_REGB8 :
674 errmsg = insert_normal (cd, fields->f_regb8, 0, 0, 15, 8, 32, total_length, buffer);
675 break;
676 case XC16X_OPERAND_REGBMEM8 :
677 errmsg = insert_normal (cd, fields->f_regmem8, 0, 0, 15, 8, 32, total_length, buffer);
678 break;
679 case XC16X_OPERAND_REGHI8 :
680 errmsg = insert_normal (cd, fields->f_reghi8, 0, 0, 23, 8, 32, total_length, buffer);
681 break;
682 case XC16X_OPERAND_REGMEM8 :
683 errmsg = insert_normal (cd, fields->f_regmem8, 0, 0, 15, 8, 32, total_length, buffer);
684 break;
685 case XC16X_OPERAND_REGOFF8 :
686 errmsg = insert_normal (cd, fields->f_regoff8, 0, 0, 15, 8, 32, total_length, buffer);
687 break;
688 case XC16X_OPERAND_REL :
689 errmsg = insert_normal (cd, fields->f_rel8, 0|(1<<CGEN_IFLD_RELOC)|(1<<CGEN_IFLD_PCREL_ADDR), 0, 15, 8, 32, total_length, buffer);
690 break;
691 case XC16X_OPERAND_RELHI :
692 errmsg = insert_normal (cd, fields->f_relhi8, 0|(1<<CGEN_IFLD_RELOC)|(1<<CGEN_IFLD_PCREL_ADDR), 0, 23, 8, 32, total_length, buffer);
693 break;
694 case XC16X_OPERAND_SEG :
695 errmsg = insert_normal (cd, fields->f_seg8, 0, 0, 15, 8, 32, total_length, buffer);
696 break;
697 case XC16X_OPERAND_SEGHI8 :
698 errmsg = insert_normal (cd, fields->f_segnum8, 0, 0, 23, 8, 32, total_length, buffer);
699 break;
700 case XC16X_OPERAND_SEGM :
701 break;
702 case XC16X_OPERAND_SOF :
703 break;
704 case XC16X_OPERAND_SR :
705 errmsg = insert_normal (cd, fields->f_r2, 0, 0, 11, 4, 32, total_length, buffer);
706 break;
707 case XC16X_OPERAND_SR2 :
708 errmsg = insert_normal (cd, fields->f_r0, 0, 0, 9, 2, 32, total_length, buffer);
709 break;
710 case XC16X_OPERAND_SRB :
711 errmsg = insert_normal (cd, fields->f_r2, 0, 0, 11, 4, 32, total_length, buffer);
712 break;
713 case XC16X_OPERAND_SRC1 :
714 errmsg = insert_normal (cd, fields->f_r1, 0, 0, 15, 4, 32, total_length, buffer);
715 break;
716 case XC16X_OPERAND_SRC2 :
717 errmsg = insert_normal (cd, fields->f_r2, 0, 0, 11, 4, 32, total_length, buffer);
718 break;
719 case XC16X_OPERAND_SRDIV :
720 errmsg = insert_normal (cd, fields->f_reg8, 0, 0, 15, 8, 32, total_length, buffer);
721 break;
722 case XC16X_OPERAND_U4 :
723 errmsg = insert_normal (cd, fields->f_uimm4, 0, 0, 15, 4, 32, total_length, buffer);
724 break;
725 case XC16X_OPERAND_UIMM16 :
726 errmsg = insert_normal (cd, fields->f_uimm16, 0, 0, 31, 16, 32, total_length, buffer);
727 break;
728 case XC16X_OPERAND_UIMM2 :
729 errmsg = insert_normal (cd, fields->f_uimm2, 0, 0, 13, 2, 32, total_length, buffer);
730 break;
731 case XC16X_OPERAND_UIMM3 :
732 errmsg = insert_normal (cd, fields->f_uimm3, 0, 0, 10, 3, 32, total_length, buffer);
733 break;
734 case XC16X_OPERAND_UIMM4 :
735 errmsg = insert_normal (cd, fields->f_uimm4, 0, 0, 15, 4, 32, total_length, buffer);
736 break;
737 case XC16X_OPERAND_UIMM7 :
738 errmsg = insert_normal (cd, fields->f_uimm7, 0|(1<<CGEN_IFLD_RELOC)|(1<<CGEN_IFLD_PCREL_ADDR), 0, 15, 7, 32, total_length, buffer);
739 break;
740 case XC16X_OPERAND_UIMM8 :
741 errmsg = insert_normal (cd, fields->f_uimm8, 0, 0, 23, 8, 32, total_length, buffer);
742 break;
743 case XC16X_OPERAND_UPAG16 :
744 errmsg = insert_normal (cd, fields->f_uimm16, 0, 0, 31, 16, 32, total_length, buffer);
745 break;
746 case XC16X_OPERAND_UPOF16 :
747 errmsg = insert_normal (cd, fields->f_memory, 0, 0, 31, 16, 32, total_length, buffer);
748 break;
749 case XC16X_OPERAND_USEG16 :
750 errmsg = insert_normal (cd, fields->f_offset16, 0|(1<<CGEN_IFLD_RELOC)|(1<<CGEN_IFLD_ABS_ADDR), 0, 31, 16, 32, total_length, buffer);
751 break;
752 case XC16X_OPERAND_USEG8 :
753 errmsg = insert_normal (cd, fields->f_seg8, 0, 0, 15, 8, 32, total_length, buffer);
754 break;
755 case XC16X_OPERAND_USOF16 :
756 errmsg = insert_normal (cd, fields->f_offset16, 0|(1<<CGEN_IFLD_RELOC)|(1<<CGEN_IFLD_ABS_ADDR), 0, 31, 16, 32, total_length, buffer);
757 break;
759 default :
760 /* xgettext:c-format */
761 opcodes_error_handler
762 (_("internal error: unrecognized field %d while building insn"),
763 opindex);
764 abort ();
767 return errmsg;
770 int xc16x_cgen_extract_operand
771 (CGEN_CPU_DESC, int, CGEN_EXTRACT_INFO *, CGEN_INSN_INT, CGEN_FIELDS *, bfd_vma);
773 /* Main entry point for operand extraction.
774 The result is <= 0 for error, >0 for success.
775 ??? Actual values aren't well defined right now.
777 This function is basically just a big switch statement. Earlier versions
778 used tables to look up the function to use, but
779 - if the table contains both assembler and disassembler functions then
780 the disassembler contains much of the assembler and vice-versa,
781 - there's a lot of inlining possibilities as things grow,
782 - using a switch statement avoids the function call overhead.
784 This function could be moved into `print_insn_normal', but keeping it
785 separate makes clear the interface between `print_insn_normal' and each of
786 the handlers. */
789 xc16x_cgen_extract_operand (CGEN_CPU_DESC cd,
790 int opindex,
791 CGEN_EXTRACT_INFO *ex_info,
792 CGEN_INSN_INT insn_value,
793 CGEN_FIELDS * fields,
794 bfd_vma pc)
796 /* Assume success (for those operands that are nops). */
797 int length = 1;
798 unsigned int total_length = CGEN_FIELDS_BITSIZE (fields);
800 switch (opindex)
802 case XC16X_OPERAND_REGNAM :
803 length = extract_normal (cd, ex_info, insn_value, 0, 0, 15, 8, 32, total_length, pc, & fields->f_reg8);
804 break;
805 case XC16X_OPERAND_BIT01 :
806 length = extract_normal (cd, ex_info, insn_value, 0, 0, 8, 1, 32, total_length, pc, & fields->f_op_1bit);
807 break;
808 case XC16X_OPERAND_BIT1 :
809 length = extract_normal (cd, ex_info, insn_value, 0, 0, 11, 1, 32, total_length, pc, & fields->f_op_bit1);
810 break;
811 case XC16X_OPERAND_BIT2 :
812 length = extract_normal (cd, ex_info, insn_value, 0, 0, 11, 2, 32, total_length, pc, & fields->f_op_bit2);
813 break;
814 case XC16X_OPERAND_BIT4 :
815 length = extract_normal (cd, ex_info, insn_value, 0, 0, 11, 4, 32, total_length, pc, & fields->f_op_bit4);
816 break;
817 case XC16X_OPERAND_BIT8 :
818 length = extract_normal (cd, ex_info, insn_value, 0, 0, 31, 8, 32, total_length, pc, & fields->f_op_bit8);
819 break;
820 case XC16X_OPERAND_BITONE :
821 length = extract_normal (cd, ex_info, insn_value, 0, 0, 9, 1, 32, total_length, pc, & fields->f_op_onebit);
822 break;
823 case XC16X_OPERAND_CADDR :
824 length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_RELOC)|(1<<CGEN_IFLD_ABS_ADDR), 0, 31, 16, 32, total_length, pc, & fields->f_offset16);
825 break;
826 case XC16X_OPERAND_COND :
827 length = extract_normal (cd, ex_info, insn_value, 0, 0, 7, 4, 32, total_length, pc, & fields->f_condcode);
828 break;
829 case XC16X_OPERAND_DATA8 :
830 length = extract_normal (cd, ex_info, insn_value, 0, 0, 23, 8, 32, total_length, pc, & fields->f_data8);
831 break;
832 case XC16X_OPERAND_DATAHI8 :
833 length = extract_normal (cd, ex_info, insn_value, 0, 0, 31, 8, 32, total_length, pc, & fields->f_datahi8);
834 break;
835 case XC16X_OPERAND_DOT :
836 break;
837 case XC16X_OPERAND_DR :
838 length = extract_normal (cd, ex_info, insn_value, 0, 0, 15, 4, 32, total_length, pc, & fields->f_r1);
839 break;
840 case XC16X_OPERAND_DRB :
841 length = extract_normal (cd, ex_info, insn_value, 0, 0, 15, 4, 32, total_length, pc, & fields->f_r1);
842 break;
843 case XC16X_OPERAND_DRI :
844 length = extract_normal (cd, ex_info, insn_value, 0, 0, 11, 4, 32, total_length, pc, & fields->f_r4);
845 break;
846 case XC16X_OPERAND_EXTCOND :
847 length = extract_normal (cd, ex_info, insn_value, 0, 0, 15, 5, 32, total_length, pc, & fields->f_extccode);
848 break;
849 case XC16X_OPERAND_GENREG :
850 length = extract_normal (cd, ex_info, insn_value, 0, 0, 15, 8, 32, total_length, pc, & fields->f_regb8);
851 break;
852 case XC16X_OPERAND_HASH :
853 break;
854 case XC16X_OPERAND_ICOND :
855 length = extract_normal (cd, ex_info, insn_value, 0, 0, 15, 4, 32, total_length, pc, & fields->f_icondcode);
856 break;
857 case XC16X_OPERAND_LBIT2 :
858 length = extract_normal (cd, ex_info, insn_value, 0, 0, 15, 2, 32, total_length, pc, & fields->f_op_lbit2);
859 break;
860 case XC16X_OPERAND_LBIT4 :
861 length = extract_normal (cd, ex_info, insn_value, 0, 0, 15, 4, 32, total_length, pc, & fields->f_op_lbit4);
862 break;
863 case XC16X_OPERAND_MASK8 :
864 length = extract_normal (cd, ex_info, insn_value, 0, 0, 23, 8, 32, total_length, pc, & fields->f_mask8);
865 break;
866 case XC16X_OPERAND_MASKLO8 :
867 length = extract_normal (cd, ex_info, insn_value, 0, 0, 31, 8, 32, total_length, pc, & fields->f_datahi8);
868 break;
869 case XC16X_OPERAND_MEMGR8 :
870 length = extract_normal (cd, ex_info, insn_value, 0, 0, 31, 16, 32, total_length, pc, & fields->f_memgr8);
871 break;
872 case XC16X_OPERAND_MEMORY :
873 length = extract_normal (cd, ex_info, insn_value, 0, 0, 31, 16, 32, total_length, pc, & fields->f_memory);
874 break;
875 case XC16X_OPERAND_PAG :
876 break;
877 case XC16X_OPERAND_PAGENUM :
878 length = extract_normal (cd, ex_info, insn_value, 0, 0, 25, 10, 32, total_length, pc, & fields->f_pagenum);
879 break;
880 case XC16X_OPERAND_POF :
881 break;
882 case XC16X_OPERAND_QBIT :
883 length = extract_normal (cd, ex_info, insn_value, 0, 0, 7, 4, 32, total_length, pc, & fields->f_qbit);
884 break;
885 case XC16X_OPERAND_QHIBIT :
886 length = extract_normal (cd, ex_info, insn_value, 0, 0, 27, 4, 32, total_length, pc, & fields->f_qhibit);
887 break;
888 case XC16X_OPERAND_QLOBIT :
889 length = extract_normal (cd, ex_info, insn_value, 0, 0, 31, 4, 32, total_length, pc, & fields->f_qlobit);
890 break;
891 case XC16X_OPERAND_REG8 :
892 length = extract_normal (cd, ex_info, insn_value, 0, 0, 15, 8, 32, total_length, pc, & fields->f_reg8);
893 break;
894 case XC16X_OPERAND_REGB8 :
895 length = extract_normal (cd, ex_info, insn_value, 0, 0, 15, 8, 32, total_length, pc, & fields->f_regb8);
896 break;
897 case XC16X_OPERAND_REGBMEM8 :
898 length = extract_normal (cd, ex_info, insn_value, 0, 0, 15, 8, 32, total_length, pc, & fields->f_regmem8);
899 break;
900 case XC16X_OPERAND_REGHI8 :
901 length = extract_normal (cd, ex_info, insn_value, 0, 0, 23, 8, 32, total_length, pc, & fields->f_reghi8);
902 break;
903 case XC16X_OPERAND_REGMEM8 :
904 length = extract_normal (cd, ex_info, insn_value, 0, 0, 15, 8, 32, total_length, pc, & fields->f_regmem8);
905 break;
906 case XC16X_OPERAND_REGOFF8 :
907 length = extract_normal (cd, ex_info, insn_value, 0, 0, 15, 8, 32, total_length, pc, & fields->f_regoff8);
908 break;
909 case XC16X_OPERAND_REL :
910 length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_RELOC)|(1<<CGEN_IFLD_PCREL_ADDR), 0, 15, 8, 32, total_length, pc, & fields->f_rel8);
911 break;
912 case XC16X_OPERAND_RELHI :
913 length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_RELOC)|(1<<CGEN_IFLD_PCREL_ADDR), 0, 23, 8, 32, total_length, pc, & fields->f_relhi8);
914 break;
915 case XC16X_OPERAND_SEG :
916 length = extract_normal (cd, ex_info, insn_value, 0, 0, 15, 8, 32, total_length, pc, & fields->f_seg8);
917 break;
918 case XC16X_OPERAND_SEGHI8 :
919 length = extract_normal (cd, ex_info, insn_value, 0, 0, 23, 8, 32, total_length, pc, & fields->f_segnum8);
920 break;
921 case XC16X_OPERAND_SEGM :
922 break;
923 case XC16X_OPERAND_SOF :
924 break;
925 case XC16X_OPERAND_SR :
926 length = extract_normal (cd, ex_info, insn_value, 0, 0, 11, 4, 32, total_length, pc, & fields->f_r2);
927 break;
928 case XC16X_OPERAND_SR2 :
929 length = extract_normal (cd, ex_info, insn_value, 0, 0, 9, 2, 32, total_length, pc, & fields->f_r0);
930 break;
931 case XC16X_OPERAND_SRB :
932 length = extract_normal (cd, ex_info, insn_value, 0, 0, 11, 4, 32, total_length, pc, & fields->f_r2);
933 break;
934 case XC16X_OPERAND_SRC1 :
935 length = extract_normal (cd, ex_info, insn_value, 0, 0, 15, 4, 32, total_length, pc, & fields->f_r1);
936 break;
937 case XC16X_OPERAND_SRC2 :
938 length = extract_normal (cd, ex_info, insn_value, 0, 0, 11, 4, 32, total_length, pc, & fields->f_r2);
939 break;
940 case XC16X_OPERAND_SRDIV :
941 length = extract_normal (cd, ex_info, insn_value, 0, 0, 15, 8, 32, total_length, pc, & fields->f_reg8);
942 break;
943 case XC16X_OPERAND_U4 :
944 length = extract_normal (cd, ex_info, insn_value, 0, 0, 15, 4, 32, total_length, pc, & fields->f_uimm4);
945 break;
946 case XC16X_OPERAND_UIMM16 :
947 length = extract_normal (cd, ex_info, insn_value, 0, 0, 31, 16, 32, total_length, pc, & fields->f_uimm16);
948 break;
949 case XC16X_OPERAND_UIMM2 :
950 length = extract_normal (cd, ex_info, insn_value, 0, 0, 13, 2, 32, total_length, pc, & fields->f_uimm2);
951 break;
952 case XC16X_OPERAND_UIMM3 :
953 length = extract_normal (cd, ex_info, insn_value, 0, 0, 10, 3, 32, total_length, pc, & fields->f_uimm3);
954 break;
955 case XC16X_OPERAND_UIMM4 :
956 length = extract_normal (cd, ex_info, insn_value, 0, 0, 15, 4, 32, total_length, pc, & fields->f_uimm4);
957 break;
958 case XC16X_OPERAND_UIMM7 :
959 length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_RELOC)|(1<<CGEN_IFLD_PCREL_ADDR), 0, 15, 7, 32, total_length, pc, & fields->f_uimm7);
960 break;
961 case XC16X_OPERAND_UIMM8 :
962 length = extract_normal (cd, ex_info, insn_value, 0, 0, 23, 8, 32, total_length, pc, & fields->f_uimm8);
963 break;
964 case XC16X_OPERAND_UPAG16 :
965 length = extract_normal (cd, ex_info, insn_value, 0, 0, 31, 16, 32, total_length, pc, & fields->f_uimm16);
966 break;
967 case XC16X_OPERAND_UPOF16 :
968 length = extract_normal (cd, ex_info, insn_value, 0, 0, 31, 16, 32, total_length, pc, & fields->f_memory);
969 break;
970 case XC16X_OPERAND_USEG16 :
971 length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_RELOC)|(1<<CGEN_IFLD_ABS_ADDR), 0, 31, 16, 32, total_length, pc, & fields->f_offset16);
972 break;
973 case XC16X_OPERAND_USEG8 :
974 length = extract_normal (cd, ex_info, insn_value, 0, 0, 15, 8, 32, total_length, pc, & fields->f_seg8);
975 break;
976 case XC16X_OPERAND_USOF16 :
977 length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_RELOC)|(1<<CGEN_IFLD_ABS_ADDR), 0, 31, 16, 32, total_length, pc, & fields->f_offset16);
978 break;
980 default :
981 /* xgettext:c-format */
982 opcodes_error_handler
983 (_("internal error: unrecognized field %d while decoding insn"),
984 opindex);
985 abort ();
988 return length;
991 cgen_insert_fn * const xc16x_cgen_insert_handlers[] =
993 insert_insn_normal,
996 cgen_extract_fn * const xc16x_cgen_extract_handlers[] =
998 extract_insn_normal,
1001 int xc16x_cgen_get_int_operand (CGEN_CPU_DESC, int, const CGEN_FIELDS *);
1002 bfd_vma xc16x_cgen_get_vma_operand (CGEN_CPU_DESC, int, const CGEN_FIELDS *);
1004 /* Getting values from cgen_fields is handled by a collection of functions.
1005 They are distinguished by the type of the VALUE argument they return.
1006 TODO: floating point, inlining support, remove cases where result type
1007 not appropriate. */
1010 xc16x_cgen_get_int_operand (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
1011 int opindex,
1012 const CGEN_FIELDS * fields)
1014 int value;
1016 switch (opindex)
1018 case XC16X_OPERAND_REGNAM :
1019 value = fields->f_reg8;
1020 break;
1021 case XC16X_OPERAND_BIT01 :
1022 value = fields->f_op_1bit;
1023 break;
1024 case XC16X_OPERAND_BIT1 :
1025 value = fields->f_op_bit1;
1026 break;
1027 case XC16X_OPERAND_BIT2 :
1028 value = fields->f_op_bit2;
1029 break;
1030 case XC16X_OPERAND_BIT4 :
1031 value = fields->f_op_bit4;
1032 break;
1033 case XC16X_OPERAND_BIT8 :
1034 value = fields->f_op_bit8;
1035 break;
1036 case XC16X_OPERAND_BITONE :
1037 value = fields->f_op_onebit;
1038 break;
1039 case XC16X_OPERAND_CADDR :
1040 value = fields->f_offset16;
1041 break;
1042 case XC16X_OPERAND_COND :
1043 value = fields->f_condcode;
1044 break;
1045 case XC16X_OPERAND_DATA8 :
1046 value = fields->f_data8;
1047 break;
1048 case XC16X_OPERAND_DATAHI8 :
1049 value = fields->f_datahi8;
1050 break;
1051 case XC16X_OPERAND_DOT :
1052 value = 0;
1053 break;
1054 case XC16X_OPERAND_DR :
1055 value = fields->f_r1;
1056 break;
1057 case XC16X_OPERAND_DRB :
1058 value = fields->f_r1;
1059 break;
1060 case XC16X_OPERAND_DRI :
1061 value = fields->f_r4;
1062 break;
1063 case XC16X_OPERAND_EXTCOND :
1064 value = fields->f_extccode;
1065 break;
1066 case XC16X_OPERAND_GENREG :
1067 value = fields->f_regb8;
1068 break;
1069 case XC16X_OPERAND_HASH :
1070 value = 0;
1071 break;
1072 case XC16X_OPERAND_ICOND :
1073 value = fields->f_icondcode;
1074 break;
1075 case XC16X_OPERAND_LBIT2 :
1076 value = fields->f_op_lbit2;
1077 break;
1078 case XC16X_OPERAND_LBIT4 :
1079 value = fields->f_op_lbit4;
1080 break;
1081 case XC16X_OPERAND_MASK8 :
1082 value = fields->f_mask8;
1083 break;
1084 case XC16X_OPERAND_MASKLO8 :
1085 value = fields->f_datahi8;
1086 break;
1087 case XC16X_OPERAND_MEMGR8 :
1088 value = fields->f_memgr8;
1089 break;
1090 case XC16X_OPERAND_MEMORY :
1091 value = fields->f_memory;
1092 break;
1093 case XC16X_OPERAND_PAG :
1094 value = 0;
1095 break;
1096 case XC16X_OPERAND_PAGENUM :
1097 value = fields->f_pagenum;
1098 break;
1099 case XC16X_OPERAND_POF :
1100 value = 0;
1101 break;
1102 case XC16X_OPERAND_QBIT :
1103 value = fields->f_qbit;
1104 break;
1105 case XC16X_OPERAND_QHIBIT :
1106 value = fields->f_qhibit;
1107 break;
1108 case XC16X_OPERAND_QLOBIT :
1109 value = fields->f_qlobit;
1110 break;
1111 case XC16X_OPERAND_REG8 :
1112 value = fields->f_reg8;
1113 break;
1114 case XC16X_OPERAND_REGB8 :
1115 value = fields->f_regb8;
1116 break;
1117 case XC16X_OPERAND_REGBMEM8 :
1118 value = fields->f_regmem8;
1119 break;
1120 case XC16X_OPERAND_REGHI8 :
1121 value = fields->f_reghi8;
1122 break;
1123 case XC16X_OPERAND_REGMEM8 :
1124 value = fields->f_regmem8;
1125 break;
1126 case XC16X_OPERAND_REGOFF8 :
1127 value = fields->f_regoff8;
1128 break;
1129 case XC16X_OPERAND_REL :
1130 value = fields->f_rel8;
1131 break;
1132 case XC16X_OPERAND_RELHI :
1133 value = fields->f_relhi8;
1134 break;
1135 case XC16X_OPERAND_SEG :
1136 value = fields->f_seg8;
1137 break;
1138 case XC16X_OPERAND_SEGHI8 :
1139 value = fields->f_segnum8;
1140 break;
1141 case XC16X_OPERAND_SEGM :
1142 value = 0;
1143 break;
1144 case XC16X_OPERAND_SOF :
1145 value = 0;
1146 break;
1147 case XC16X_OPERAND_SR :
1148 value = fields->f_r2;
1149 break;
1150 case XC16X_OPERAND_SR2 :
1151 value = fields->f_r0;
1152 break;
1153 case XC16X_OPERAND_SRB :
1154 value = fields->f_r2;
1155 break;
1156 case XC16X_OPERAND_SRC1 :
1157 value = fields->f_r1;
1158 break;
1159 case XC16X_OPERAND_SRC2 :
1160 value = fields->f_r2;
1161 break;
1162 case XC16X_OPERAND_SRDIV :
1163 value = fields->f_reg8;
1164 break;
1165 case XC16X_OPERAND_U4 :
1166 value = fields->f_uimm4;
1167 break;
1168 case XC16X_OPERAND_UIMM16 :
1169 value = fields->f_uimm16;
1170 break;
1171 case XC16X_OPERAND_UIMM2 :
1172 value = fields->f_uimm2;
1173 break;
1174 case XC16X_OPERAND_UIMM3 :
1175 value = fields->f_uimm3;
1176 break;
1177 case XC16X_OPERAND_UIMM4 :
1178 value = fields->f_uimm4;
1179 break;
1180 case XC16X_OPERAND_UIMM7 :
1181 value = fields->f_uimm7;
1182 break;
1183 case XC16X_OPERAND_UIMM8 :
1184 value = fields->f_uimm8;
1185 break;
1186 case XC16X_OPERAND_UPAG16 :
1187 value = fields->f_uimm16;
1188 break;
1189 case XC16X_OPERAND_UPOF16 :
1190 value = fields->f_memory;
1191 break;
1192 case XC16X_OPERAND_USEG16 :
1193 value = fields->f_offset16;
1194 break;
1195 case XC16X_OPERAND_USEG8 :
1196 value = fields->f_seg8;
1197 break;
1198 case XC16X_OPERAND_USOF16 :
1199 value = fields->f_offset16;
1200 break;
1202 default :
1203 /* xgettext:c-format */
1204 opcodes_error_handler
1205 (_("internal error: unrecognized field %d while getting int operand"),
1206 opindex);
1207 abort ();
1210 return value;
1213 bfd_vma
1214 xc16x_cgen_get_vma_operand (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
1215 int opindex,
1216 const CGEN_FIELDS * fields)
1218 bfd_vma value;
1220 switch (opindex)
1222 case XC16X_OPERAND_REGNAM :
1223 value = fields->f_reg8;
1224 break;
1225 case XC16X_OPERAND_BIT01 :
1226 value = fields->f_op_1bit;
1227 break;
1228 case XC16X_OPERAND_BIT1 :
1229 value = fields->f_op_bit1;
1230 break;
1231 case XC16X_OPERAND_BIT2 :
1232 value = fields->f_op_bit2;
1233 break;
1234 case XC16X_OPERAND_BIT4 :
1235 value = fields->f_op_bit4;
1236 break;
1237 case XC16X_OPERAND_BIT8 :
1238 value = fields->f_op_bit8;
1239 break;
1240 case XC16X_OPERAND_BITONE :
1241 value = fields->f_op_onebit;
1242 break;
1243 case XC16X_OPERAND_CADDR :
1244 value = fields->f_offset16;
1245 break;
1246 case XC16X_OPERAND_COND :
1247 value = fields->f_condcode;
1248 break;
1249 case XC16X_OPERAND_DATA8 :
1250 value = fields->f_data8;
1251 break;
1252 case XC16X_OPERAND_DATAHI8 :
1253 value = fields->f_datahi8;
1254 break;
1255 case XC16X_OPERAND_DOT :
1256 value = 0;
1257 break;
1258 case XC16X_OPERAND_DR :
1259 value = fields->f_r1;
1260 break;
1261 case XC16X_OPERAND_DRB :
1262 value = fields->f_r1;
1263 break;
1264 case XC16X_OPERAND_DRI :
1265 value = fields->f_r4;
1266 break;
1267 case XC16X_OPERAND_EXTCOND :
1268 value = fields->f_extccode;
1269 break;
1270 case XC16X_OPERAND_GENREG :
1271 value = fields->f_regb8;
1272 break;
1273 case XC16X_OPERAND_HASH :
1274 value = 0;
1275 break;
1276 case XC16X_OPERAND_ICOND :
1277 value = fields->f_icondcode;
1278 break;
1279 case XC16X_OPERAND_LBIT2 :
1280 value = fields->f_op_lbit2;
1281 break;
1282 case XC16X_OPERAND_LBIT4 :
1283 value = fields->f_op_lbit4;
1284 break;
1285 case XC16X_OPERAND_MASK8 :
1286 value = fields->f_mask8;
1287 break;
1288 case XC16X_OPERAND_MASKLO8 :
1289 value = fields->f_datahi8;
1290 break;
1291 case XC16X_OPERAND_MEMGR8 :
1292 value = fields->f_memgr8;
1293 break;
1294 case XC16X_OPERAND_MEMORY :
1295 value = fields->f_memory;
1296 break;
1297 case XC16X_OPERAND_PAG :
1298 value = 0;
1299 break;
1300 case XC16X_OPERAND_PAGENUM :
1301 value = fields->f_pagenum;
1302 break;
1303 case XC16X_OPERAND_POF :
1304 value = 0;
1305 break;
1306 case XC16X_OPERAND_QBIT :
1307 value = fields->f_qbit;
1308 break;
1309 case XC16X_OPERAND_QHIBIT :
1310 value = fields->f_qhibit;
1311 break;
1312 case XC16X_OPERAND_QLOBIT :
1313 value = fields->f_qlobit;
1314 break;
1315 case XC16X_OPERAND_REG8 :
1316 value = fields->f_reg8;
1317 break;
1318 case XC16X_OPERAND_REGB8 :
1319 value = fields->f_regb8;
1320 break;
1321 case XC16X_OPERAND_REGBMEM8 :
1322 value = fields->f_regmem8;
1323 break;
1324 case XC16X_OPERAND_REGHI8 :
1325 value = fields->f_reghi8;
1326 break;
1327 case XC16X_OPERAND_REGMEM8 :
1328 value = fields->f_regmem8;
1329 break;
1330 case XC16X_OPERAND_REGOFF8 :
1331 value = fields->f_regoff8;
1332 break;
1333 case XC16X_OPERAND_REL :
1334 value = fields->f_rel8;
1335 break;
1336 case XC16X_OPERAND_RELHI :
1337 value = fields->f_relhi8;
1338 break;
1339 case XC16X_OPERAND_SEG :
1340 value = fields->f_seg8;
1341 break;
1342 case XC16X_OPERAND_SEGHI8 :
1343 value = fields->f_segnum8;
1344 break;
1345 case XC16X_OPERAND_SEGM :
1346 value = 0;
1347 break;
1348 case XC16X_OPERAND_SOF :
1349 value = 0;
1350 break;
1351 case XC16X_OPERAND_SR :
1352 value = fields->f_r2;
1353 break;
1354 case XC16X_OPERAND_SR2 :
1355 value = fields->f_r0;
1356 break;
1357 case XC16X_OPERAND_SRB :
1358 value = fields->f_r2;
1359 break;
1360 case XC16X_OPERAND_SRC1 :
1361 value = fields->f_r1;
1362 break;
1363 case XC16X_OPERAND_SRC2 :
1364 value = fields->f_r2;
1365 break;
1366 case XC16X_OPERAND_SRDIV :
1367 value = fields->f_reg8;
1368 break;
1369 case XC16X_OPERAND_U4 :
1370 value = fields->f_uimm4;
1371 break;
1372 case XC16X_OPERAND_UIMM16 :
1373 value = fields->f_uimm16;
1374 break;
1375 case XC16X_OPERAND_UIMM2 :
1376 value = fields->f_uimm2;
1377 break;
1378 case XC16X_OPERAND_UIMM3 :
1379 value = fields->f_uimm3;
1380 break;
1381 case XC16X_OPERAND_UIMM4 :
1382 value = fields->f_uimm4;
1383 break;
1384 case XC16X_OPERAND_UIMM7 :
1385 value = fields->f_uimm7;
1386 break;
1387 case XC16X_OPERAND_UIMM8 :
1388 value = fields->f_uimm8;
1389 break;
1390 case XC16X_OPERAND_UPAG16 :
1391 value = fields->f_uimm16;
1392 break;
1393 case XC16X_OPERAND_UPOF16 :
1394 value = fields->f_memory;
1395 break;
1396 case XC16X_OPERAND_USEG16 :
1397 value = fields->f_offset16;
1398 break;
1399 case XC16X_OPERAND_USEG8 :
1400 value = fields->f_seg8;
1401 break;
1402 case XC16X_OPERAND_USOF16 :
1403 value = fields->f_offset16;
1404 break;
1406 default :
1407 /* xgettext:c-format */
1408 opcodes_error_handler
1409 (_("internal error: unrecognized field %d while getting vma operand"),
1410 opindex);
1411 abort ();
1414 return value;
1417 void xc16x_cgen_set_int_operand (CGEN_CPU_DESC, int, CGEN_FIELDS *, int);
1418 void xc16x_cgen_set_vma_operand (CGEN_CPU_DESC, int, CGEN_FIELDS *, bfd_vma);
1420 /* Stuffing values in cgen_fields is handled by a collection of functions.
1421 They are distinguished by the type of the VALUE argument they accept.
1422 TODO: floating point, inlining support, remove cases where argument type
1423 not appropriate. */
1425 void
1426 xc16x_cgen_set_int_operand (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
1427 int opindex,
1428 CGEN_FIELDS * fields,
1429 int value)
1431 switch (opindex)
1433 case XC16X_OPERAND_REGNAM :
1434 fields->f_reg8 = value;
1435 break;
1436 case XC16X_OPERAND_BIT01 :
1437 fields->f_op_1bit = value;
1438 break;
1439 case XC16X_OPERAND_BIT1 :
1440 fields->f_op_bit1 = value;
1441 break;
1442 case XC16X_OPERAND_BIT2 :
1443 fields->f_op_bit2 = value;
1444 break;
1445 case XC16X_OPERAND_BIT4 :
1446 fields->f_op_bit4 = value;
1447 break;
1448 case XC16X_OPERAND_BIT8 :
1449 fields->f_op_bit8 = value;
1450 break;
1451 case XC16X_OPERAND_BITONE :
1452 fields->f_op_onebit = value;
1453 break;
1454 case XC16X_OPERAND_CADDR :
1455 fields->f_offset16 = value;
1456 break;
1457 case XC16X_OPERAND_COND :
1458 fields->f_condcode = value;
1459 break;
1460 case XC16X_OPERAND_DATA8 :
1461 fields->f_data8 = value;
1462 break;
1463 case XC16X_OPERAND_DATAHI8 :
1464 fields->f_datahi8 = value;
1465 break;
1466 case XC16X_OPERAND_DOT :
1467 break;
1468 case XC16X_OPERAND_DR :
1469 fields->f_r1 = value;
1470 break;
1471 case XC16X_OPERAND_DRB :
1472 fields->f_r1 = value;
1473 break;
1474 case XC16X_OPERAND_DRI :
1475 fields->f_r4 = value;
1476 break;
1477 case XC16X_OPERAND_EXTCOND :
1478 fields->f_extccode = value;
1479 break;
1480 case XC16X_OPERAND_GENREG :
1481 fields->f_regb8 = value;
1482 break;
1483 case XC16X_OPERAND_HASH :
1484 break;
1485 case XC16X_OPERAND_ICOND :
1486 fields->f_icondcode = value;
1487 break;
1488 case XC16X_OPERAND_LBIT2 :
1489 fields->f_op_lbit2 = value;
1490 break;
1491 case XC16X_OPERAND_LBIT4 :
1492 fields->f_op_lbit4 = value;
1493 break;
1494 case XC16X_OPERAND_MASK8 :
1495 fields->f_mask8 = value;
1496 break;
1497 case XC16X_OPERAND_MASKLO8 :
1498 fields->f_datahi8 = value;
1499 break;
1500 case XC16X_OPERAND_MEMGR8 :
1501 fields->f_memgr8 = value;
1502 break;
1503 case XC16X_OPERAND_MEMORY :
1504 fields->f_memory = value;
1505 break;
1506 case XC16X_OPERAND_PAG :
1507 break;
1508 case XC16X_OPERAND_PAGENUM :
1509 fields->f_pagenum = value;
1510 break;
1511 case XC16X_OPERAND_POF :
1512 break;
1513 case XC16X_OPERAND_QBIT :
1514 fields->f_qbit = value;
1515 break;
1516 case XC16X_OPERAND_QHIBIT :
1517 fields->f_qhibit = value;
1518 break;
1519 case XC16X_OPERAND_QLOBIT :
1520 fields->f_qlobit = value;
1521 break;
1522 case XC16X_OPERAND_REG8 :
1523 fields->f_reg8 = value;
1524 break;
1525 case XC16X_OPERAND_REGB8 :
1526 fields->f_regb8 = value;
1527 break;
1528 case XC16X_OPERAND_REGBMEM8 :
1529 fields->f_regmem8 = value;
1530 break;
1531 case XC16X_OPERAND_REGHI8 :
1532 fields->f_reghi8 = value;
1533 break;
1534 case XC16X_OPERAND_REGMEM8 :
1535 fields->f_regmem8 = value;
1536 break;
1537 case XC16X_OPERAND_REGOFF8 :
1538 fields->f_regoff8 = value;
1539 break;
1540 case XC16X_OPERAND_REL :
1541 fields->f_rel8 = value;
1542 break;
1543 case XC16X_OPERAND_RELHI :
1544 fields->f_relhi8 = value;
1545 break;
1546 case XC16X_OPERAND_SEG :
1547 fields->f_seg8 = value;
1548 break;
1549 case XC16X_OPERAND_SEGHI8 :
1550 fields->f_segnum8 = value;
1551 break;
1552 case XC16X_OPERAND_SEGM :
1553 break;
1554 case XC16X_OPERAND_SOF :
1555 break;
1556 case XC16X_OPERAND_SR :
1557 fields->f_r2 = value;
1558 break;
1559 case XC16X_OPERAND_SR2 :
1560 fields->f_r0 = value;
1561 break;
1562 case XC16X_OPERAND_SRB :
1563 fields->f_r2 = value;
1564 break;
1565 case XC16X_OPERAND_SRC1 :
1566 fields->f_r1 = value;
1567 break;
1568 case XC16X_OPERAND_SRC2 :
1569 fields->f_r2 = value;
1570 break;
1571 case XC16X_OPERAND_SRDIV :
1572 fields->f_reg8 = value;
1573 break;
1574 case XC16X_OPERAND_U4 :
1575 fields->f_uimm4 = value;
1576 break;
1577 case XC16X_OPERAND_UIMM16 :
1578 fields->f_uimm16 = value;
1579 break;
1580 case XC16X_OPERAND_UIMM2 :
1581 fields->f_uimm2 = value;
1582 break;
1583 case XC16X_OPERAND_UIMM3 :
1584 fields->f_uimm3 = value;
1585 break;
1586 case XC16X_OPERAND_UIMM4 :
1587 fields->f_uimm4 = value;
1588 break;
1589 case XC16X_OPERAND_UIMM7 :
1590 fields->f_uimm7 = value;
1591 break;
1592 case XC16X_OPERAND_UIMM8 :
1593 fields->f_uimm8 = value;
1594 break;
1595 case XC16X_OPERAND_UPAG16 :
1596 fields->f_uimm16 = value;
1597 break;
1598 case XC16X_OPERAND_UPOF16 :
1599 fields->f_memory = value;
1600 break;
1601 case XC16X_OPERAND_USEG16 :
1602 fields->f_offset16 = value;
1603 break;
1604 case XC16X_OPERAND_USEG8 :
1605 fields->f_seg8 = value;
1606 break;
1607 case XC16X_OPERAND_USOF16 :
1608 fields->f_offset16 = value;
1609 break;
1611 default :
1612 /* xgettext:c-format */
1613 opcodes_error_handler
1614 (_("internal error: unrecognized field %d while setting int operand"),
1615 opindex);
1616 abort ();
1620 void
1621 xc16x_cgen_set_vma_operand (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
1622 int opindex,
1623 CGEN_FIELDS * fields,
1624 bfd_vma value)
1626 switch (opindex)
1628 case XC16X_OPERAND_REGNAM :
1629 fields->f_reg8 = value;
1630 break;
1631 case XC16X_OPERAND_BIT01 :
1632 fields->f_op_1bit = value;
1633 break;
1634 case XC16X_OPERAND_BIT1 :
1635 fields->f_op_bit1 = value;
1636 break;
1637 case XC16X_OPERAND_BIT2 :
1638 fields->f_op_bit2 = value;
1639 break;
1640 case XC16X_OPERAND_BIT4 :
1641 fields->f_op_bit4 = value;
1642 break;
1643 case XC16X_OPERAND_BIT8 :
1644 fields->f_op_bit8 = value;
1645 break;
1646 case XC16X_OPERAND_BITONE :
1647 fields->f_op_onebit = value;
1648 break;
1649 case XC16X_OPERAND_CADDR :
1650 fields->f_offset16 = value;
1651 break;
1652 case XC16X_OPERAND_COND :
1653 fields->f_condcode = value;
1654 break;
1655 case XC16X_OPERAND_DATA8 :
1656 fields->f_data8 = value;
1657 break;
1658 case XC16X_OPERAND_DATAHI8 :
1659 fields->f_datahi8 = value;
1660 break;
1661 case XC16X_OPERAND_DOT :
1662 break;
1663 case XC16X_OPERAND_DR :
1664 fields->f_r1 = value;
1665 break;
1666 case XC16X_OPERAND_DRB :
1667 fields->f_r1 = value;
1668 break;
1669 case XC16X_OPERAND_DRI :
1670 fields->f_r4 = value;
1671 break;
1672 case XC16X_OPERAND_EXTCOND :
1673 fields->f_extccode = value;
1674 break;
1675 case XC16X_OPERAND_GENREG :
1676 fields->f_regb8 = value;
1677 break;
1678 case XC16X_OPERAND_HASH :
1679 break;
1680 case XC16X_OPERAND_ICOND :
1681 fields->f_icondcode = value;
1682 break;
1683 case XC16X_OPERAND_LBIT2 :
1684 fields->f_op_lbit2 = value;
1685 break;
1686 case XC16X_OPERAND_LBIT4 :
1687 fields->f_op_lbit4 = value;
1688 break;
1689 case XC16X_OPERAND_MASK8 :
1690 fields->f_mask8 = value;
1691 break;
1692 case XC16X_OPERAND_MASKLO8 :
1693 fields->f_datahi8 = value;
1694 break;
1695 case XC16X_OPERAND_MEMGR8 :
1696 fields->f_memgr8 = value;
1697 break;
1698 case XC16X_OPERAND_MEMORY :
1699 fields->f_memory = value;
1700 break;
1701 case XC16X_OPERAND_PAG :
1702 break;
1703 case XC16X_OPERAND_PAGENUM :
1704 fields->f_pagenum = value;
1705 break;
1706 case XC16X_OPERAND_POF :
1707 break;
1708 case XC16X_OPERAND_QBIT :
1709 fields->f_qbit = value;
1710 break;
1711 case XC16X_OPERAND_QHIBIT :
1712 fields->f_qhibit = value;
1713 break;
1714 case XC16X_OPERAND_QLOBIT :
1715 fields->f_qlobit = value;
1716 break;
1717 case XC16X_OPERAND_REG8 :
1718 fields->f_reg8 = value;
1719 break;
1720 case XC16X_OPERAND_REGB8 :
1721 fields->f_regb8 = value;
1722 break;
1723 case XC16X_OPERAND_REGBMEM8 :
1724 fields->f_regmem8 = value;
1725 break;
1726 case XC16X_OPERAND_REGHI8 :
1727 fields->f_reghi8 = value;
1728 break;
1729 case XC16X_OPERAND_REGMEM8 :
1730 fields->f_regmem8 = value;
1731 break;
1732 case XC16X_OPERAND_REGOFF8 :
1733 fields->f_regoff8 = value;
1734 break;
1735 case XC16X_OPERAND_REL :
1736 fields->f_rel8 = value;
1737 break;
1738 case XC16X_OPERAND_RELHI :
1739 fields->f_relhi8 = value;
1740 break;
1741 case XC16X_OPERAND_SEG :
1742 fields->f_seg8 = value;
1743 break;
1744 case XC16X_OPERAND_SEGHI8 :
1745 fields->f_segnum8 = value;
1746 break;
1747 case XC16X_OPERAND_SEGM :
1748 break;
1749 case XC16X_OPERAND_SOF :
1750 break;
1751 case XC16X_OPERAND_SR :
1752 fields->f_r2 = value;
1753 break;
1754 case XC16X_OPERAND_SR2 :
1755 fields->f_r0 = value;
1756 break;
1757 case XC16X_OPERAND_SRB :
1758 fields->f_r2 = value;
1759 break;
1760 case XC16X_OPERAND_SRC1 :
1761 fields->f_r1 = value;
1762 break;
1763 case XC16X_OPERAND_SRC2 :
1764 fields->f_r2 = value;
1765 break;
1766 case XC16X_OPERAND_SRDIV :
1767 fields->f_reg8 = value;
1768 break;
1769 case XC16X_OPERAND_U4 :
1770 fields->f_uimm4 = value;
1771 break;
1772 case XC16X_OPERAND_UIMM16 :
1773 fields->f_uimm16 = value;
1774 break;
1775 case XC16X_OPERAND_UIMM2 :
1776 fields->f_uimm2 = value;
1777 break;
1778 case XC16X_OPERAND_UIMM3 :
1779 fields->f_uimm3 = value;
1780 break;
1781 case XC16X_OPERAND_UIMM4 :
1782 fields->f_uimm4 = value;
1783 break;
1784 case XC16X_OPERAND_UIMM7 :
1785 fields->f_uimm7 = value;
1786 break;
1787 case XC16X_OPERAND_UIMM8 :
1788 fields->f_uimm8 = value;
1789 break;
1790 case XC16X_OPERAND_UPAG16 :
1791 fields->f_uimm16 = value;
1792 break;
1793 case XC16X_OPERAND_UPOF16 :
1794 fields->f_memory = value;
1795 break;
1796 case XC16X_OPERAND_USEG16 :
1797 fields->f_offset16 = value;
1798 break;
1799 case XC16X_OPERAND_USEG8 :
1800 fields->f_seg8 = value;
1801 break;
1802 case XC16X_OPERAND_USOF16 :
1803 fields->f_offset16 = value;
1804 break;
1806 default :
1807 /* xgettext:c-format */
1808 opcodes_error_handler
1809 (_("internal error: unrecognized field %d while setting vma operand"),
1810 opindex);
1811 abort ();
1815 /* Function to call before using the instruction builder tables. */
1817 void
1818 xc16x_cgen_init_ibld_table (CGEN_CPU_DESC cd)
1820 cd->insert_handlers = & xc16x_cgen_insert_handlers[0];
1821 cd->extract_handlers = & xc16x_cgen_extract_handlers[0];
1823 cd->insert_operand = xc16x_cgen_insert_operand;
1824 cd->extract_operand = xc16x_cgen_extract_operand;
1826 cd->get_int_operand = xc16x_cgen_get_int_operand;
1827 cd->set_int_operand = xc16x_cgen_set_int_operand;
1828 cd->get_vma_operand = xc16x_cgen_get_vma_operand;
1829 cd->set_vma_operand = xc16x_cgen_set_vma_operand;