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