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 1996, 1997, 1998, 1999, 2000, 2001, 2005, 2006, 2007
7   Free Software Foundation, Inc.
8
9   This file is part of libopcodes.
10
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.
15
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.
20
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.  */
24
25/* ??? Eventually more and more of this stuff can go to cpu-independent files.
26   Keep that in mind.  */
27
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 "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
47static 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);
50static const char * insert_insn_normal
51  (CGEN_CPU_DESC, const CGEN_INSN *,
52   CGEN_FIELDS *, CGEN_INSN_BYTES_PTR, bfd_vma);
53static 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 *);
57static 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
61static 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
65static CGEN_INLINE void insert_1
66  (CGEN_CPU_DESC, unsigned long, int, int, int, unsigned char *);
67static CGEN_INLINE int fill_cache
68  (CGEN_CPU_DESC, CGEN_EXTRACT_INFO *,  int, int, bfd_vma);
69static CGEN_INLINE long extract_1
70  (CGEN_CPU_DESC, CGEN_EXTRACT_INFO *, int, int, int, unsigned char *, bfd_vma);
71#endif
72
73/* Operand insertion.  */
74
75#if ! CGEN_INT_INSN_P
76
77/* Subroutine of insert_normal.  */
78
79static CGEN_INLINE void
80insert_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
121static const char *
122insert_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 > 32)
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
239static const char *
240insert_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
294static void
295put_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
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
326static CGEN_INLINE int
327fill_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
370static CGEN_INLINE long
371extract_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
413static int
414extract_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 > 32)
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 > 32)
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
505static int
506extract_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
537/* Machine generated code added here.  */
538
539const 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
556const char *
557xc16x_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
756int 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
774int
775xc16x_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
976cgen_insert_fn * const xc16x_cgen_insert_handlers[] =
977{
978  insert_insn_normal,
979};
980
981cgen_extract_fn * const xc16x_cgen_extract_handlers[] =
982{
983  extract_insn_normal,
984};
985
986int xc16x_cgen_get_int_operand     (CGEN_CPU_DESC, int, const CGEN_FIELDS *);
987bfd_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
994int
995xc16x_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
1197bfd_vma
1198xc16x_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
1400void xc16x_cgen_set_int_operand  (CGEN_CPU_DESC, int, CGEN_FIELDS *, int);
1401void 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
1408void
1409xc16x_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
1602void
1603xc16x_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
1798void
1799xc16x_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}
1812