Home | History | Annotate | Download | only in opcodes
      1 /* Instruction building/extraction support for xstormy16. -*- 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-2016 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 "xstormy16-desc.h"
     34 #include "xstormy16-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 
     73 /* Operand insertion.  */
     75 
     76 #if ! CGEN_INT_INSN_P
     77 
     78 /* Subroutine of insert_normal.  */
     79 
     80 static CGEN_INLINE void
     81 insert_1 (CGEN_CPU_DESC cd,
     82 	  unsigned long value,
     83 	  int start,
     84 	  int length,
     85 	  int word_length,
     86 	  unsigned char *bufp)
     87 {
     88   unsigned long x,mask;
     89   int shift;
     90 
     91   x = cgen_get_insn_value (cd, bufp, word_length);
     92 
     93   /* Written this way to avoid undefined behaviour.  */
     94   mask = (((1L << (length - 1)) - 1) << 1) | 1;
     95   if (CGEN_INSN_LSB0_P)
     96     shift = (start + 1) - length;
     97   else
     98     shift = (word_length - (start + length));
     99   x = (x & ~(mask << shift)) | ((value & mask) << shift);
    100 
    101   cgen_put_insn_value (cd, bufp, word_length, (bfd_vma) x);
    102 }
    103 
    104 #endif /* ! CGEN_INT_INSN_P */
    105 
    106 /* Default insertion routine.
    107 
    108    ATTRS is a mask of the boolean attributes.
    109    WORD_OFFSET is the offset in bits from the start of the insn of the value.
    110    WORD_LENGTH is the length of the word in bits in which the value resides.
    111    START is the starting bit number in the word, architecture origin.
    112    LENGTH is the length of VALUE in bits.
    113    TOTAL_LENGTH is the total length of the insn in bits.
    114 
    115    The result is an error message or NULL if success.  */
    116 
    117 /* ??? This duplicates functionality with bfd's howto table and
    118    bfd_install_relocation.  */
    119 /* ??? This doesn't handle bfd_vma's.  Create another function when
    120    necessary.  */
    121 
    122 static const char *
    123 insert_normal (CGEN_CPU_DESC cd,
    124 	       long value,
    125 	       unsigned int attrs,
    126 	       unsigned int word_offset,
    127 	       unsigned int start,
    128 	       unsigned int length,
    129 	       unsigned int word_length,
    130 	       unsigned int total_length,
    131 	       CGEN_INSN_BYTES_PTR buffer)
    132 {
    133   static char errbuf[100];
    134   /* Written this way to avoid undefined behaviour.  */
    135   unsigned long mask = (((1L << (length - 1)) - 1) << 1) | 1;
    136 
    137   /* If LENGTH is zero, this operand doesn't contribute to the value.  */
    138   if (length == 0)
    139     return NULL;
    140 
    141   if (word_length > 8 * sizeof (CGEN_INSN_INT))
    142     abort ();
    143 
    144   /* For architectures with insns smaller than the base-insn-bitsize,
    145      word_length may be too big.  */
    146   if (cd->min_insn_bitsize < cd->base_insn_bitsize)
    147     {
    148       if (word_offset == 0
    149 	  && word_length > total_length)
    150 	word_length = total_length;
    151     }
    152 
    153   /* Ensure VALUE will fit.  */
    154   if (CGEN_BOOL_ATTR (attrs, CGEN_IFLD_SIGN_OPT))
    155     {
    156       long minval = - (1L << (length - 1));
    157       unsigned long maxval = mask;
    158 
    159       if ((value > 0 && (unsigned long) value > maxval)
    160 	  || value < minval)
    161 	{
    162 	  /* xgettext:c-format */
    163 	  sprintf (errbuf,
    164 		   _("operand out of range (%ld not between %ld and %lu)"),
    165 		   value, minval, maxval);
    166 	  return errbuf;
    167 	}
    168     }
    169   else if (! CGEN_BOOL_ATTR (attrs, CGEN_IFLD_SIGNED))
    170     {
    171       unsigned long maxval = mask;
    172       unsigned long val = (unsigned long) value;
    173 
    174       /* For hosts with a word size > 32 check to see if value has been sign
    175 	 extended beyond 32 bits.  If so then ignore these higher sign bits
    176 	 as the user is attempting to store a 32-bit signed value into an
    177 	 unsigned 32-bit field which is allowed.  */
    178       if (sizeof (unsigned long) > 4 && ((value >> 32) == -1))
    179 	val &= 0xFFFFFFFF;
    180 
    181       if (val > maxval)
    182 	{
    183 	  /* xgettext:c-format */
    184 	  sprintf (errbuf,
    185 		   _("operand out of range (0x%lx not between 0 and 0x%lx)"),
    186 		   val, maxval);
    187 	  return errbuf;
    188 	}
    189     }
    190   else
    191     {
    192       if (! cgen_signed_overflow_ok_p (cd))
    193 	{
    194 	  long minval = - (1L << (length - 1));
    195 	  long maxval =   (1L << (length - 1)) - 1;
    196 
    197 	  if (value < minval || value > maxval)
    198 	    {
    199 	      sprintf
    200 		/* xgettext:c-format */
    201 		(errbuf, _("operand out of range (%ld not between %ld and %ld)"),
    202 		 value, minval, maxval);
    203 	      return errbuf;
    204 	    }
    205 	}
    206     }
    207 
    208 #if CGEN_INT_INSN_P
    209 
    210   {
    211     int shift_within_word, shift_to_word, shift;
    212 
    213     /* How to shift the value to BIT0 of the word.  */
    214     shift_to_word = total_length - (word_offset + word_length);
    215 
    216     /* How to shift the value to the field within the word.  */
    217     if (CGEN_INSN_LSB0_P)
    218       shift_within_word = start + 1 - length;
    219     else
    220       shift_within_word = word_length - start - length;
    221 
    222     /* The total SHIFT, then mask in the value.  */
    223     shift = shift_to_word + shift_within_word;
    224     *buffer = (*buffer & ~(mask << shift)) | ((value & mask) << shift);
    225   }
    226 
    227 #else /* ! CGEN_INT_INSN_P */
    228 
    229   {
    230     unsigned char *bufp = (unsigned char *) buffer + word_offset / 8;
    231 
    232     insert_1 (cd, value, start, length, word_length, bufp);
    233   }
    234 
    235 #endif /* ! CGEN_INT_INSN_P */
    236 
    237   return NULL;
    238 }
    239 
    240 /* Default insn builder (insert handler).
    241    The instruction is recorded in CGEN_INT_INSN_P byte order (meaning
    242    that if CGEN_INSN_BYTES_PTR is an int * and thus, the value is
    243    recorded in host byte order, otherwise BUFFER is an array of bytes
    244    and the value is recorded in target byte order).
    245    The result is an error message or NULL if success.  */
    246 
    247 static const char *
    248 insert_insn_normal (CGEN_CPU_DESC cd,
    249 		    const CGEN_INSN * insn,
    250 		    CGEN_FIELDS * fields,
    251 		    CGEN_INSN_BYTES_PTR buffer,
    252 		    bfd_vma pc)
    253 {
    254   const CGEN_SYNTAX *syntax = CGEN_INSN_SYNTAX (insn);
    255   unsigned long value;
    256   const CGEN_SYNTAX_CHAR_TYPE * syn;
    257 
    258   CGEN_INIT_INSERT (cd);
    259   value = CGEN_INSN_BASE_VALUE (insn);
    260 
    261   /* If we're recording insns as numbers (rather than a string of bytes),
    262      target byte order handling is deferred until later.  */
    263 
    264 #if CGEN_INT_INSN_P
    265 
    266   put_insn_int_value (cd, buffer, cd->base_insn_bitsize,
    267 		      CGEN_FIELDS_BITSIZE (fields), value);
    268 
    269 #else
    270 
    271   cgen_put_insn_value (cd, buffer, min ((unsigned) cd->base_insn_bitsize,
    272 					(unsigned) CGEN_FIELDS_BITSIZE (fields)),
    273 		       value);
    274 
    275 #endif /* ! CGEN_INT_INSN_P */
    276 
    277   /* ??? It would be better to scan the format's fields.
    278      Still need to be able to insert a value based on the operand though;
    279      e.g. storing a branch displacement that got resolved later.
    280      Needs more thought first.  */
    281 
    282   for (syn = CGEN_SYNTAX_STRING (syntax); * syn; ++ syn)
    283     {
    284       const char *errmsg;
    285 
    286       if (CGEN_SYNTAX_CHAR_P (* syn))
    287 	continue;
    288 
    289       errmsg = (* cd->insert_operand) (cd, CGEN_SYNTAX_FIELD (*syn),
    290 				       fields, buffer, pc);
    291       if (errmsg)
    292 	return errmsg;
    293     }
    294 
    295   return NULL;
    296 }
    297 
    298 #if CGEN_INT_INSN_P
    299 /* Cover function to store an insn value into an integral insn.  Must go here
    300    because it needs <prefix>-desc.h for CGEN_INT_INSN_P.  */
    301 
    302 static void
    303 put_insn_int_value (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
    304 		    CGEN_INSN_BYTES_PTR buf,
    305 		    int length,
    306 		    int insn_length,
    307 		    CGEN_INSN_INT value)
    308 {
    309   /* For architectures with insns smaller than the base-insn-bitsize,
    310      length may be too big.  */
    311   if (length > insn_length)
    312     *buf = value;
    313   else
    314     {
    315       int shift = insn_length - length;
    316       /* Written this way to avoid undefined behaviour.  */
    317       CGEN_INSN_INT mask = (((1L << (length - 1)) - 1) << 1) | 1;
    318 
    319       *buf = (*buf & ~(mask << shift)) | ((value & mask) << shift);
    320     }
    321 }
    322 #endif
    323 
    324 /* Operand extraction.  */
    326 
    327 #if ! CGEN_INT_INSN_P
    328 
    329 /* Subroutine of extract_normal.
    330    Ensure sufficient bytes are cached in EX_INFO.
    331    OFFSET is the offset in bytes from the start of the insn of the value.
    332    BYTES is the length of the needed value.
    333    Returns 1 for success, 0 for failure.  */
    334 
    335 static CGEN_INLINE int
    336 fill_cache (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
    337 	    CGEN_EXTRACT_INFO *ex_info,
    338 	    int offset,
    339 	    int bytes,
    340 	    bfd_vma pc)
    341 {
    342   /* It's doubtful that the middle part has already been fetched so
    343      we don't optimize that case.  kiss.  */
    344   unsigned int mask;
    345   disassemble_info *info = (disassemble_info *) ex_info->dis_info;
    346 
    347   /* First do a quick check.  */
    348   mask = (1 << bytes) - 1;
    349   if (((ex_info->valid >> offset) & mask) == mask)
    350     return 1;
    351 
    352   /* Search for the first byte we need to read.  */
    353   for (mask = 1 << offset; bytes > 0; --bytes, ++offset, mask <<= 1)
    354     if (! (mask & ex_info->valid))
    355       break;
    356 
    357   if (bytes)
    358     {
    359       int status;
    360 
    361       pc += offset;
    362       status = (*info->read_memory_func)
    363 	(pc, ex_info->insn_bytes + offset, bytes, info);
    364 
    365       if (status != 0)
    366 	{
    367 	  (*info->memory_error_func) (status, pc, info);
    368 	  return 0;
    369 	}
    370 
    371       ex_info->valid |= ((1 << bytes) - 1) << offset;
    372     }
    373 
    374   return 1;
    375 }
    376 
    377 /* Subroutine of extract_normal.  */
    378 
    379 static CGEN_INLINE long
    380 extract_1 (CGEN_CPU_DESC cd,
    381 	   CGEN_EXTRACT_INFO *ex_info ATTRIBUTE_UNUSED,
    382 	   int start,
    383 	   int length,
    384 	   int word_length,
    385 	   unsigned char *bufp,
    386 	   bfd_vma pc ATTRIBUTE_UNUSED)
    387 {
    388   unsigned long x;
    389   int shift;
    390 
    391   x = cgen_get_insn_value (cd, bufp, word_length);
    392 
    393   if (CGEN_INSN_LSB0_P)
    394     shift = (start + 1) - length;
    395   else
    396     shift = (word_length - (start + length));
    397   return x >> shift;
    398 }
    399 
    400 #endif /* ! CGEN_INT_INSN_P */
    401 
    402 /* Default extraction routine.
    403 
    404    INSN_VALUE is the first base_insn_bitsize bits of the insn in host order,
    405    or sometimes less for cases like the m32r where the base insn size is 32
    406    but some insns are 16 bits.
    407    ATTRS is a mask of the boolean attributes.  We only need `SIGNED',
    408    but for generality we take a bitmask of all of them.
    409    WORD_OFFSET is the offset in bits from the start of the insn of the value.
    410    WORD_LENGTH is the length of the word in bits in which the value resides.
    411    START is the starting bit number in the word, architecture origin.
    412    LENGTH is the length of VALUE in bits.
    413    TOTAL_LENGTH is the total length of the insn in bits.
    414 
    415    Returns 1 for success, 0 for failure.  */
    416 
    417 /* ??? The return code isn't properly used.  wip.  */
    418 
    419 /* ??? This doesn't handle bfd_vma's.  Create another function when
    420    necessary.  */
    421 
    422 static int
    423 extract_normal (CGEN_CPU_DESC cd,
    424 #if ! CGEN_INT_INSN_P
    425 		CGEN_EXTRACT_INFO *ex_info,
    426 #else
    427 		CGEN_EXTRACT_INFO *ex_info ATTRIBUTE_UNUSED,
    428 #endif
    429 		CGEN_INSN_INT insn_value,
    430 		unsigned int attrs,
    431 		unsigned int word_offset,
    432 		unsigned int start,
    433 		unsigned int length,
    434 		unsigned int word_length,
    435 		unsigned int total_length,
    436 #if ! CGEN_INT_INSN_P
    437 		bfd_vma pc,
    438 #else
    439 		bfd_vma pc ATTRIBUTE_UNUSED,
    440 #endif
    441 		long *valuep)
    442 {
    443   long value, mask;
    444 
    445   /* If LENGTH is zero, this operand doesn't contribute to the value
    446      so give it a standard value of zero.  */
    447   if (length == 0)
    448     {
    449       *valuep = 0;
    450       return 1;
    451     }
    452 
    453   if (word_length > 8 * sizeof (CGEN_INSN_INT))
    454     abort ();
    455 
    456   /* For architectures with insns smaller than the insn-base-bitsize,
    457      word_length may be too big.  */
    458   if (cd->min_insn_bitsize < cd->base_insn_bitsize)
    459     {
    460       if (word_offset + word_length > total_length)
    461 	word_length = total_length - word_offset;
    462     }
    463 
    464   /* Does the value reside in INSN_VALUE, and at the right alignment?  */
    465 
    466   if (CGEN_INT_INSN_P || (word_offset == 0 && word_length == total_length))
    467     {
    468       if (CGEN_INSN_LSB0_P)
    469 	value = insn_value >> ((word_offset + start + 1) - length);
    470       else
    471 	value = insn_value >> (total_length - ( word_offset + start + length));
    472     }
    473 
    474 #if ! CGEN_INT_INSN_P
    475 
    476   else
    477     {
    478       unsigned char *bufp = ex_info->insn_bytes + word_offset / 8;
    479 
    480       if (word_length > 8 * sizeof (CGEN_INSN_INT))
    481 	abort ();
    482 
    483       if (fill_cache (cd, ex_info, word_offset / 8, word_length / 8, pc) == 0)
    484 	return 0;
    485 
    486       value = extract_1 (cd, ex_info, start, length, word_length, bufp, pc);
    487     }
    488 
    489 #endif /* ! CGEN_INT_INSN_P */
    490 
    491   /* Written this way to avoid undefined behaviour.  */
    492   mask = (((1L << (length - 1)) - 1) << 1) | 1;
    493 
    494   value &= mask;
    495   /* sign extend? */
    496   if (CGEN_BOOL_ATTR (attrs, CGEN_IFLD_SIGNED)
    497       && (value & (1L << (length - 1))))
    498     value |= ~mask;
    499 
    500   *valuep = value;
    501 
    502   return 1;
    503 }
    504 
    505 /* Default insn extractor.
    506 
    507    INSN_VALUE is the first base_insn_bitsize bits, translated to host order.
    508    The extracted fields are stored in FIELDS.
    509    EX_INFO is used to handle reading variable length insns.
    510    Return the length of the insn in bits, or 0 if no match,
    511    or -1 if an error occurs fetching data (memory_error_func will have
    512    been called).  */
    513 
    514 static int
    515 extract_insn_normal (CGEN_CPU_DESC cd,
    516 		     const CGEN_INSN *insn,
    517 		     CGEN_EXTRACT_INFO *ex_info,
    518 		     CGEN_INSN_INT insn_value,
    519 		     CGEN_FIELDS *fields,
    520 		     bfd_vma pc)
    521 {
    522   const CGEN_SYNTAX *syntax = CGEN_INSN_SYNTAX (insn);
    523   const CGEN_SYNTAX_CHAR_TYPE *syn;
    524 
    525   CGEN_FIELDS_BITSIZE (fields) = CGEN_INSN_BITSIZE (insn);
    526 
    527   CGEN_INIT_EXTRACT (cd);
    528 
    529   for (syn = CGEN_SYNTAX_STRING (syntax); *syn; ++syn)
    530     {
    531       int length;
    532 
    533       if (CGEN_SYNTAX_CHAR_P (*syn))
    534 	continue;
    535 
    536       length = (* cd->extract_operand) (cd, CGEN_SYNTAX_FIELD (*syn),
    537 					ex_info, insn_value, fields, pc);
    538       if (length <= 0)
    539 	return length;
    540     }
    541 
    542   /* We recognized and successfully extracted this insn.  */
    543   return CGEN_INSN_BITSIZE (insn);
    544 }
    545 
    546 /* Machine generated code added here.  */
    548 
    549 const char * xstormy16_cgen_insert_operand
    550   (CGEN_CPU_DESC, int, CGEN_FIELDS *, CGEN_INSN_BYTES_PTR, bfd_vma);
    551 
    552 /* Main entry point for operand insertion.
    553 
    554    This function is basically just a big switch statement.  Earlier versions
    555    used tables to look up the function to use, but
    556    - if the table contains both assembler and disassembler functions then
    557      the disassembler contains much of the assembler and vice-versa,
    558    - there's a lot of inlining possibilities as things grow,
    559    - using a switch statement avoids the function call overhead.
    560 
    561    This function could be moved into `parse_insn_normal', but keeping it
    562    separate makes clear the interface between `parse_insn_normal' and each of
    563    the handlers.  It's also needed by GAS to insert operands that couldn't be
    564    resolved during parsing.  */
    565 
    566 const char *
    567 xstormy16_cgen_insert_operand (CGEN_CPU_DESC cd,
    568 			     int opindex,
    569 			     CGEN_FIELDS * fields,
    570 			     CGEN_INSN_BYTES_PTR buffer,
    571 			     bfd_vma pc ATTRIBUTE_UNUSED)
    572 {
    573   const char * errmsg = NULL;
    574   unsigned int total_length = CGEN_FIELDS_BITSIZE (fields);
    575 
    576   switch (opindex)
    577     {
    578     case XSTORMY16_OPERAND_RB :
    579       errmsg = insert_normal (cd, fields->f_Rb, 0, 0, 17, 3, 32, total_length, buffer);
    580       break;
    581     case XSTORMY16_OPERAND_RBJ :
    582       errmsg = insert_normal (cd, fields->f_Rbj, 0, 0, 11, 1, 32, total_length, buffer);
    583       break;
    584     case XSTORMY16_OPERAND_RD :
    585       errmsg = insert_normal (cd, fields->f_Rd, 0, 0, 12, 4, 32, total_length, buffer);
    586       break;
    587     case XSTORMY16_OPERAND_RDM :
    588       errmsg = insert_normal (cd, fields->f_Rdm, 0, 0, 13, 3, 32, total_length, buffer);
    589       break;
    590     case XSTORMY16_OPERAND_RM :
    591       errmsg = insert_normal (cd, fields->f_Rm, 0, 0, 4, 3, 32, total_length, buffer);
    592       break;
    593     case XSTORMY16_OPERAND_RS :
    594       errmsg = insert_normal (cd, fields->f_Rs, 0, 0, 8, 4, 32, total_length, buffer);
    595       break;
    596     case XSTORMY16_OPERAND_ABS24 :
    597       {
    598 {
    599   FLD (f_abs24_1) = ((FLD (f_abs24)) & (255));
    600   FLD (f_abs24_2) = ((UINT) (FLD (f_abs24)) >> (8));
    601 }
    602         errmsg = insert_normal (cd, fields->f_abs24_1, 0, 0, 8, 8, 32, total_length, buffer);
    603         if (errmsg)
    604           break;
    605         errmsg = insert_normal (cd, fields->f_abs24_2, 0, 0, 16, 16, 32, total_length, buffer);
    606         if (errmsg)
    607           break;
    608       }
    609       break;
    610     case XSTORMY16_OPERAND_BCOND2 :
    611       errmsg = insert_normal (cd, fields->f_op2, 0, 0, 4, 4, 32, total_length, buffer);
    612       break;
    613     case XSTORMY16_OPERAND_BCOND5 :
    614       errmsg = insert_normal (cd, fields->f_op5, 0, 0, 16, 4, 32, total_length, buffer);
    615       break;
    616     case XSTORMY16_OPERAND_HMEM8 :
    617       {
    618         long value = fields->f_hmem8;
    619         value = ((value) - (32512));
    620         errmsg = insert_normal (cd, value, 0|(1<<CGEN_IFLD_ABS_ADDR), 0, 8, 8, 32, total_length, buffer);
    621       }
    622       break;
    623     case XSTORMY16_OPERAND_IMM12 :
    624       errmsg = insert_normal (cd, fields->f_imm12, 0|(1<<CGEN_IFLD_SIGNED), 0, 20, 12, 32, total_length, buffer);
    625       break;
    626     case XSTORMY16_OPERAND_IMM16 :
    627       errmsg = insert_normal (cd, fields->f_imm16, 0|(1<<CGEN_IFLD_SIGN_OPT), 0, 16, 16, 32, total_length, buffer);
    628       break;
    629     case XSTORMY16_OPERAND_IMM2 :
    630       errmsg = insert_normal (cd, fields->f_imm2, 0, 0, 10, 2, 32, total_length, buffer);
    631       break;
    632     case XSTORMY16_OPERAND_IMM3 :
    633       errmsg = insert_normal (cd, fields->f_imm3, 0, 0, 4, 3, 32, total_length, buffer);
    634       break;
    635     case XSTORMY16_OPERAND_IMM3B :
    636       errmsg = insert_normal (cd, fields->f_imm3b, 0, 0, 17, 3, 32, total_length, buffer);
    637       break;
    638     case XSTORMY16_OPERAND_IMM4 :
    639       errmsg = insert_normal (cd, fields->f_imm4, 0, 0, 8, 4, 32, total_length, buffer);
    640       break;
    641     case XSTORMY16_OPERAND_IMM8 :
    642       errmsg = insert_normal (cd, fields->f_imm8, 0, 0, 8, 8, 32, total_length, buffer);
    643       break;
    644     case XSTORMY16_OPERAND_IMM8SMALL :
    645       errmsg = insert_normal (cd, fields->f_imm8, 0, 0, 8, 8, 32, total_length, buffer);
    646       break;
    647     case XSTORMY16_OPERAND_LMEM8 :
    648       errmsg = insert_normal (cd, fields->f_lmem8, 0|(1<<CGEN_IFLD_ABS_ADDR), 0, 8, 8, 32, total_length, buffer);
    649       break;
    650     case XSTORMY16_OPERAND_REL12 :
    651       {
    652         long value = fields->f_rel12;
    653         value = ((value) - (((pc) + (4))));
    654         errmsg = insert_normal (cd, value, 0|(1<<CGEN_IFLD_SIGNED)|(1<<CGEN_IFLD_PCREL_ADDR), 0, 20, 12, 32, total_length, buffer);
    655       }
    656       break;
    657     case XSTORMY16_OPERAND_REL12A :
    658       {
    659         long value = fields->f_rel12a;
    660         value = ((SI) (((value) - (((pc) + (2))))) >> (1));
    661         errmsg = insert_normal (cd, value, 0|(1<<CGEN_IFLD_SIGNED)|(1<<CGEN_IFLD_PCREL_ADDR), 0, 4, 11, 32, total_length, buffer);
    662       }
    663       break;
    664     case XSTORMY16_OPERAND_REL8_2 :
    665       {
    666         long value = fields->f_rel8_2;
    667         value = ((value) - (((pc) + (2))));
    668         errmsg = insert_normal (cd, value, 0|(1<<CGEN_IFLD_SIGNED)|(1<<CGEN_IFLD_PCREL_ADDR), 0, 8, 8, 32, total_length, buffer);
    669       }
    670       break;
    671     case XSTORMY16_OPERAND_REL8_4 :
    672       {
    673         long value = fields->f_rel8_4;
    674         value = ((value) - (((pc) + (4))));
    675         errmsg = insert_normal (cd, value, 0|(1<<CGEN_IFLD_SIGNED)|(1<<CGEN_IFLD_PCREL_ADDR), 0, 8, 8, 32, total_length, buffer);
    676       }
    677       break;
    678     case XSTORMY16_OPERAND_WS2 :
    679       errmsg = insert_normal (cd, fields->f_op2m, 0, 0, 7, 1, 32, total_length, buffer);
    680       break;
    681 
    682     default :
    683       /* xgettext:c-format */
    684       fprintf (stderr, _("Unrecognized field %d while building insn.\n"),
    685 	       opindex);
    686       abort ();
    687   }
    688 
    689   return errmsg;
    690 }
    691 
    692 int xstormy16_cgen_extract_operand
    693   (CGEN_CPU_DESC, int, CGEN_EXTRACT_INFO *, CGEN_INSN_INT, CGEN_FIELDS *, bfd_vma);
    694 
    695 /* Main entry point for operand extraction.
    696    The result is <= 0 for error, >0 for success.
    697    ??? Actual values aren't well defined right now.
    698 
    699    This function is basically just a big switch statement.  Earlier versions
    700    used tables to look up the function to use, but
    701    - if the table contains both assembler and disassembler functions then
    702      the disassembler contains much of the assembler and vice-versa,
    703    - there's a lot of inlining possibilities as things grow,
    704    - using a switch statement avoids the function call overhead.
    705 
    706    This function could be moved into `print_insn_normal', but keeping it
    707    separate makes clear the interface between `print_insn_normal' and each of
    708    the handlers.  */
    709 
    710 int
    711 xstormy16_cgen_extract_operand (CGEN_CPU_DESC cd,
    712 			     int opindex,
    713 			     CGEN_EXTRACT_INFO *ex_info,
    714 			     CGEN_INSN_INT insn_value,
    715 			     CGEN_FIELDS * fields,
    716 			     bfd_vma pc)
    717 {
    718   /* Assume success (for those operands that are nops).  */
    719   int length = 1;
    720   unsigned int total_length = CGEN_FIELDS_BITSIZE (fields);
    721 
    722   switch (opindex)
    723     {
    724     case XSTORMY16_OPERAND_RB :
    725       length = extract_normal (cd, ex_info, insn_value, 0, 0, 17, 3, 32, total_length, pc, & fields->f_Rb);
    726       break;
    727     case XSTORMY16_OPERAND_RBJ :
    728       length = extract_normal (cd, ex_info, insn_value, 0, 0, 11, 1, 32, total_length, pc, & fields->f_Rbj);
    729       break;
    730     case XSTORMY16_OPERAND_RD :
    731       length = extract_normal (cd, ex_info, insn_value, 0, 0, 12, 4, 32, total_length, pc, & fields->f_Rd);
    732       break;
    733     case XSTORMY16_OPERAND_RDM :
    734       length = extract_normal (cd, ex_info, insn_value, 0, 0, 13, 3, 32, total_length, pc, & fields->f_Rdm);
    735       break;
    736     case XSTORMY16_OPERAND_RM :
    737       length = extract_normal (cd, ex_info, insn_value, 0, 0, 4, 3, 32, total_length, pc, & fields->f_Rm);
    738       break;
    739     case XSTORMY16_OPERAND_RS :
    740       length = extract_normal (cd, ex_info, insn_value, 0, 0, 8, 4, 32, total_length, pc, & fields->f_Rs);
    741       break;
    742     case XSTORMY16_OPERAND_ABS24 :
    743       {
    744         length = extract_normal (cd, ex_info, insn_value, 0, 0, 8, 8, 32, total_length, pc, & fields->f_abs24_1);
    745         if (length <= 0) break;
    746         length = extract_normal (cd, ex_info, insn_value, 0, 0, 16, 16, 32, total_length, pc, & fields->f_abs24_2);
    747         if (length <= 0) break;
    748   FLD (f_abs24) = ((((FLD (f_abs24_2)) << (8))) | (FLD (f_abs24_1)));
    749       }
    750       break;
    751     case XSTORMY16_OPERAND_BCOND2 :
    752       length = extract_normal (cd, ex_info, insn_value, 0, 0, 4, 4, 32, total_length, pc, & fields->f_op2);
    753       break;
    754     case XSTORMY16_OPERAND_BCOND5 :
    755       length = extract_normal (cd, ex_info, insn_value, 0, 0, 16, 4, 32, total_length, pc, & fields->f_op5);
    756       break;
    757     case XSTORMY16_OPERAND_HMEM8 :
    758       {
    759         long value;
    760         length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_ABS_ADDR), 0, 8, 8, 32, total_length, pc, & value);
    761         value = ((value) + (32512));
    762         fields->f_hmem8 = value;
    763       }
    764       break;
    765     case XSTORMY16_OPERAND_IMM12 :
    766       length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_SIGNED), 0, 20, 12, 32, total_length, pc, & fields->f_imm12);
    767       break;
    768     case XSTORMY16_OPERAND_IMM16 :
    769       length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_SIGN_OPT), 0, 16, 16, 32, total_length, pc, & fields->f_imm16);
    770       break;
    771     case XSTORMY16_OPERAND_IMM2 :
    772       length = extract_normal (cd, ex_info, insn_value, 0, 0, 10, 2, 32, total_length, pc, & fields->f_imm2);
    773       break;
    774     case XSTORMY16_OPERAND_IMM3 :
    775       length = extract_normal (cd, ex_info, insn_value, 0, 0, 4, 3, 32, total_length, pc, & fields->f_imm3);
    776       break;
    777     case XSTORMY16_OPERAND_IMM3B :
    778       length = extract_normal (cd, ex_info, insn_value, 0, 0, 17, 3, 32, total_length, pc, & fields->f_imm3b);
    779       break;
    780     case XSTORMY16_OPERAND_IMM4 :
    781       length = extract_normal (cd, ex_info, insn_value, 0, 0, 8, 4, 32, total_length, pc, & fields->f_imm4);
    782       break;
    783     case XSTORMY16_OPERAND_IMM8 :
    784       length = extract_normal (cd, ex_info, insn_value, 0, 0, 8, 8, 32, total_length, pc, & fields->f_imm8);
    785       break;
    786     case XSTORMY16_OPERAND_IMM8SMALL :
    787       length = extract_normal (cd, ex_info, insn_value, 0, 0, 8, 8, 32, total_length, pc, & fields->f_imm8);
    788       break;
    789     case XSTORMY16_OPERAND_LMEM8 :
    790       length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_ABS_ADDR), 0, 8, 8, 32, total_length, pc, & fields->f_lmem8);
    791       break;
    792     case XSTORMY16_OPERAND_REL12 :
    793       {
    794         long value;
    795         length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_SIGNED)|(1<<CGEN_IFLD_PCREL_ADDR), 0, 20, 12, 32, total_length, pc, & value);
    796         value = ((value) + (((pc) + (4))));
    797         fields->f_rel12 = value;
    798       }
    799       break;
    800     case XSTORMY16_OPERAND_REL12A :
    801       {
    802         long value;
    803         length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_SIGNED)|(1<<CGEN_IFLD_PCREL_ADDR), 0, 4, 11, 32, total_length, pc, & value);
    804         value = ((((value) << (1))) + (((pc) + (2))));
    805         fields->f_rel12a = value;
    806       }
    807       break;
    808     case XSTORMY16_OPERAND_REL8_2 :
    809       {
    810         long value;
    811         length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_SIGNED)|(1<<CGEN_IFLD_PCREL_ADDR), 0, 8, 8, 32, total_length, pc, & value);
    812         value = ((value) + (((pc) + (2))));
    813         fields->f_rel8_2 = value;
    814       }
    815       break;
    816     case XSTORMY16_OPERAND_REL8_4 :
    817       {
    818         long value;
    819         length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_SIGNED)|(1<<CGEN_IFLD_PCREL_ADDR), 0, 8, 8, 32, total_length, pc, & value);
    820         value = ((value) + (((pc) + (4))));
    821         fields->f_rel8_4 = value;
    822       }
    823       break;
    824     case XSTORMY16_OPERAND_WS2 :
    825       length = extract_normal (cd, ex_info, insn_value, 0, 0, 7, 1, 32, total_length, pc, & fields->f_op2m);
    826       break;
    827 
    828     default :
    829       /* xgettext:c-format */
    830       fprintf (stderr, _("Unrecognized field %d while decoding insn.\n"),
    831 	       opindex);
    832       abort ();
    833     }
    834 
    835   return length;
    836 }
    837 
    838 cgen_insert_fn * const xstormy16_cgen_insert_handlers[] =
    839 {
    840   insert_insn_normal,
    841 };
    842 
    843 cgen_extract_fn * const xstormy16_cgen_extract_handlers[] =
    844 {
    845   extract_insn_normal,
    846 };
    847 
    848 int xstormy16_cgen_get_int_operand     (CGEN_CPU_DESC, int, const CGEN_FIELDS *);
    849 bfd_vma xstormy16_cgen_get_vma_operand (CGEN_CPU_DESC, int, const CGEN_FIELDS *);
    850 
    851 /* Getting values from cgen_fields is handled by a collection of functions.
    852    They are distinguished by the type of the VALUE argument they return.
    853    TODO: floating point, inlining support, remove cases where result type
    854    not appropriate.  */
    855 
    856 int
    857 xstormy16_cgen_get_int_operand (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
    858 			     int opindex,
    859 			     const CGEN_FIELDS * fields)
    860 {
    861   int value;
    862 
    863   switch (opindex)
    864     {
    865     case XSTORMY16_OPERAND_RB :
    866       value = fields->f_Rb;
    867       break;
    868     case XSTORMY16_OPERAND_RBJ :
    869       value = fields->f_Rbj;
    870       break;
    871     case XSTORMY16_OPERAND_RD :
    872       value = fields->f_Rd;
    873       break;
    874     case XSTORMY16_OPERAND_RDM :
    875       value = fields->f_Rdm;
    876       break;
    877     case XSTORMY16_OPERAND_RM :
    878       value = fields->f_Rm;
    879       break;
    880     case XSTORMY16_OPERAND_RS :
    881       value = fields->f_Rs;
    882       break;
    883     case XSTORMY16_OPERAND_ABS24 :
    884       value = fields->f_abs24;
    885       break;
    886     case XSTORMY16_OPERAND_BCOND2 :
    887       value = fields->f_op2;
    888       break;
    889     case XSTORMY16_OPERAND_BCOND5 :
    890       value = fields->f_op5;
    891       break;
    892     case XSTORMY16_OPERAND_HMEM8 :
    893       value = fields->f_hmem8;
    894       break;
    895     case XSTORMY16_OPERAND_IMM12 :
    896       value = fields->f_imm12;
    897       break;
    898     case XSTORMY16_OPERAND_IMM16 :
    899       value = fields->f_imm16;
    900       break;
    901     case XSTORMY16_OPERAND_IMM2 :
    902       value = fields->f_imm2;
    903       break;
    904     case XSTORMY16_OPERAND_IMM3 :
    905       value = fields->f_imm3;
    906       break;
    907     case XSTORMY16_OPERAND_IMM3B :
    908       value = fields->f_imm3b;
    909       break;
    910     case XSTORMY16_OPERAND_IMM4 :
    911       value = fields->f_imm4;
    912       break;
    913     case XSTORMY16_OPERAND_IMM8 :
    914       value = fields->f_imm8;
    915       break;
    916     case XSTORMY16_OPERAND_IMM8SMALL :
    917       value = fields->f_imm8;
    918       break;
    919     case XSTORMY16_OPERAND_LMEM8 :
    920       value = fields->f_lmem8;
    921       break;
    922     case XSTORMY16_OPERAND_REL12 :
    923       value = fields->f_rel12;
    924       break;
    925     case XSTORMY16_OPERAND_REL12A :
    926       value = fields->f_rel12a;
    927       break;
    928     case XSTORMY16_OPERAND_REL8_2 :
    929       value = fields->f_rel8_2;
    930       break;
    931     case XSTORMY16_OPERAND_REL8_4 :
    932       value = fields->f_rel8_4;
    933       break;
    934     case XSTORMY16_OPERAND_WS2 :
    935       value = fields->f_op2m;
    936       break;
    937 
    938     default :
    939       /* xgettext:c-format */
    940       fprintf (stderr, _("Unrecognized field %d while getting int operand.\n"),
    941 		       opindex);
    942       abort ();
    943   }
    944 
    945   return value;
    946 }
    947 
    948 bfd_vma
    949 xstormy16_cgen_get_vma_operand (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
    950 			     int opindex,
    951 			     const CGEN_FIELDS * fields)
    952 {
    953   bfd_vma value;
    954 
    955   switch (opindex)
    956     {
    957     case XSTORMY16_OPERAND_RB :
    958       value = fields->f_Rb;
    959       break;
    960     case XSTORMY16_OPERAND_RBJ :
    961       value = fields->f_Rbj;
    962       break;
    963     case XSTORMY16_OPERAND_RD :
    964       value = fields->f_Rd;
    965       break;
    966     case XSTORMY16_OPERAND_RDM :
    967       value = fields->f_Rdm;
    968       break;
    969     case XSTORMY16_OPERAND_RM :
    970       value = fields->f_Rm;
    971       break;
    972     case XSTORMY16_OPERAND_RS :
    973       value = fields->f_Rs;
    974       break;
    975     case XSTORMY16_OPERAND_ABS24 :
    976       value = fields->f_abs24;
    977       break;
    978     case XSTORMY16_OPERAND_BCOND2 :
    979       value = fields->f_op2;
    980       break;
    981     case XSTORMY16_OPERAND_BCOND5 :
    982       value = fields->f_op5;
    983       break;
    984     case XSTORMY16_OPERAND_HMEM8 :
    985       value = fields->f_hmem8;
    986       break;
    987     case XSTORMY16_OPERAND_IMM12 :
    988       value = fields->f_imm12;
    989       break;
    990     case XSTORMY16_OPERAND_IMM16 :
    991       value = fields->f_imm16;
    992       break;
    993     case XSTORMY16_OPERAND_IMM2 :
    994       value = fields->f_imm2;
    995       break;
    996     case XSTORMY16_OPERAND_IMM3 :
    997       value = fields->f_imm3;
    998       break;
    999     case XSTORMY16_OPERAND_IMM3B :
   1000       value = fields->f_imm3b;
   1001       break;
   1002     case XSTORMY16_OPERAND_IMM4 :
   1003       value = fields->f_imm4;
   1004       break;
   1005     case XSTORMY16_OPERAND_IMM8 :
   1006       value = fields->f_imm8;
   1007       break;
   1008     case XSTORMY16_OPERAND_IMM8SMALL :
   1009       value = fields->f_imm8;
   1010       break;
   1011     case XSTORMY16_OPERAND_LMEM8 :
   1012       value = fields->f_lmem8;
   1013       break;
   1014     case XSTORMY16_OPERAND_REL12 :
   1015       value = fields->f_rel12;
   1016       break;
   1017     case XSTORMY16_OPERAND_REL12A :
   1018       value = fields->f_rel12a;
   1019       break;
   1020     case XSTORMY16_OPERAND_REL8_2 :
   1021       value = fields->f_rel8_2;
   1022       break;
   1023     case XSTORMY16_OPERAND_REL8_4 :
   1024       value = fields->f_rel8_4;
   1025       break;
   1026     case XSTORMY16_OPERAND_WS2 :
   1027       value = fields->f_op2m;
   1028       break;
   1029 
   1030     default :
   1031       /* xgettext:c-format */
   1032       fprintf (stderr, _("Unrecognized field %d while getting vma operand.\n"),
   1033 		       opindex);
   1034       abort ();
   1035   }
   1036 
   1037   return value;
   1038 }
   1039 
   1040 void xstormy16_cgen_set_int_operand  (CGEN_CPU_DESC, int, CGEN_FIELDS *, int);
   1041 void xstormy16_cgen_set_vma_operand  (CGEN_CPU_DESC, int, CGEN_FIELDS *, bfd_vma);
   1042 
   1043 /* Stuffing values in cgen_fields is handled by a collection of functions.
   1044    They are distinguished by the type of the VALUE argument they accept.
   1045    TODO: floating point, inlining support, remove cases where argument type
   1046    not appropriate.  */
   1047 
   1048 void
   1049 xstormy16_cgen_set_int_operand (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
   1050 			     int opindex,
   1051 			     CGEN_FIELDS * fields,
   1052 			     int value)
   1053 {
   1054   switch (opindex)
   1055     {
   1056     case XSTORMY16_OPERAND_RB :
   1057       fields->f_Rb = value;
   1058       break;
   1059     case XSTORMY16_OPERAND_RBJ :
   1060       fields->f_Rbj = value;
   1061       break;
   1062     case XSTORMY16_OPERAND_RD :
   1063       fields->f_Rd = value;
   1064       break;
   1065     case XSTORMY16_OPERAND_RDM :
   1066       fields->f_Rdm = value;
   1067       break;
   1068     case XSTORMY16_OPERAND_RM :
   1069       fields->f_Rm = value;
   1070       break;
   1071     case XSTORMY16_OPERAND_RS :
   1072       fields->f_Rs = value;
   1073       break;
   1074     case XSTORMY16_OPERAND_ABS24 :
   1075       fields->f_abs24 = value;
   1076       break;
   1077     case XSTORMY16_OPERAND_BCOND2 :
   1078       fields->f_op2 = value;
   1079       break;
   1080     case XSTORMY16_OPERAND_BCOND5 :
   1081       fields->f_op5 = value;
   1082       break;
   1083     case XSTORMY16_OPERAND_HMEM8 :
   1084       fields->f_hmem8 = value;
   1085       break;
   1086     case XSTORMY16_OPERAND_IMM12 :
   1087       fields->f_imm12 = value;
   1088       break;
   1089     case XSTORMY16_OPERAND_IMM16 :
   1090       fields->f_imm16 = value;
   1091       break;
   1092     case XSTORMY16_OPERAND_IMM2 :
   1093       fields->f_imm2 = value;
   1094       break;
   1095     case XSTORMY16_OPERAND_IMM3 :
   1096       fields->f_imm3 = value;
   1097       break;
   1098     case XSTORMY16_OPERAND_IMM3B :
   1099       fields->f_imm3b = value;
   1100       break;
   1101     case XSTORMY16_OPERAND_IMM4 :
   1102       fields->f_imm4 = value;
   1103       break;
   1104     case XSTORMY16_OPERAND_IMM8 :
   1105       fields->f_imm8 = value;
   1106       break;
   1107     case XSTORMY16_OPERAND_IMM8SMALL :
   1108       fields->f_imm8 = value;
   1109       break;
   1110     case XSTORMY16_OPERAND_LMEM8 :
   1111       fields->f_lmem8 = value;
   1112       break;
   1113     case XSTORMY16_OPERAND_REL12 :
   1114       fields->f_rel12 = value;
   1115       break;
   1116     case XSTORMY16_OPERAND_REL12A :
   1117       fields->f_rel12a = value;
   1118       break;
   1119     case XSTORMY16_OPERAND_REL8_2 :
   1120       fields->f_rel8_2 = value;
   1121       break;
   1122     case XSTORMY16_OPERAND_REL8_4 :
   1123       fields->f_rel8_4 = value;
   1124       break;
   1125     case XSTORMY16_OPERAND_WS2 :
   1126       fields->f_op2m = value;
   1127       break;
   1128 
   1129     default :
   1130       /* xgettext:c-format */
   1131       fprintf (stderr, _("Unrecognized field %d while setting int operand.\n"),
   1132 		       opindex);
   1133       abort ();
   1134   }
   1135 }
   1136 
   1137 void
   1138 xstormy16_cgen_set_vma_operand (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
   1139 			     int opindex,
   1140 			     CGEN_FIELDS * fields,
   1141 			     bfd_vma value)
   1142 {
   1143   switch (opindex)
   1144     {
   1145     case XSTORMY16_OPERAND_RB :
   1146       fields->f_Rb = value;
   1147       break;
   1148     case XSTORMY16_OPERAND_RBJ :
   1149       fields->f_Rbj = value;
   1150       break;
   1151     case XSTORMY16_OPERAND_RD :
   1152       fields->f_Rd = value;
   1153       break;
   1154     case XSTORMY16_OPERAND_RDM :
   1155       fields->f_Rdm = value;
   1156       break;
   1157     case XSTORMY16_OPERAND_RM :
   1158       fields->f_Rm = value;
   1159       break;
   1160     case XSTORMY16_OPERAND_RS :
   1161       fields->f_Rs = value;
   1162       break;
   1163     case XSTORMY16_OPERAND_ABS24 :
   1164       fields->f_abs24 = value;
   1165       break;
   1166     case XSTORMY16_OPERAND_BCOND2 :
   1167       fields->f_op2 = value;
   1168       break;
   1169     case XSTORMY16_OPERAND_BCOND5 :
   1170       fields->f_op5 = value;
   1171       break;
   1172     case XSTORMY16_OPERAND_HMEM8 :
   1173       fields->f_hmem8 = value;
   1174       break;
   1175     case XSTORMY16_OPERAND_IMM12 :
   1176       fields->f_imm12 = value;
   1177       break;
   1178     case XSTORMY16_OPERAND_IMM16 :
   1179       fields->f_imm16 = value;
   1180       break;
   1181     case XSTORMY16_OPERAND_IMM2 :
   1182       fields->f_imm2 = value;
   1183       break;
   1184     case XSTORMY16_OPERAND_IMM3 :
   1185       fields->f_imm3 = value;
   1186       break;
   1187     case XSTORMY16_OPERAND_IMM3B :
   1188       fields->f_imm3b = value;
   1189       break;
   1190     case XSTORMY16_OPERAND_IMM4 :
   1191       fields->f_imm4 = value;
   1192       break;
   1193     case XSTORMY16_OPERAND_IMM8 :
   1194       fields->f_imm8 = value;
   1195       break;
   1196     case XSTORMY16_OPERAND_IMM8SMALL :
   1197       fields->f_imm8 = value;
   1198       break;
   1199     case XSTORMY16_OPERAND_LMEM8 :
   1200       fields->f_lmem8 = value;
   1201       break;
   1202     case XSTORMY16_OPERAND_REL12 :
   1203       fields->f_rel12 = value;
   1204       break;
   1205     case XSTORMY16_OPERAND_REL12A :
   1206       fields->f_rel12a = value;
   1207       break;
   1208     case XSTORMY16_OPERAND_REL8_2 :
   1209       fields->f_rel8_2 = value;
   1210       break;
   1211     case XSTORMY16_OPERAND_REL8_4 :
   1212       fields->f_rel8_4 = value;
   1213       break;
   1214     case XSTORMY16_OPERAND_WS2 :
   1215       fields->f_op2m = value;
   1216       break;
   1217 
   1218     default :
   1219       /* xgettext:c-format */
   1220       fprintf (stderr, _("Unrecognized field %d while setting vma operand.\n"),
   1221 		       opindex);
   1222       abort ();
   1223   }
   1224 }
   1225 
   1226 /* Function to call before using the instruction builder tables.  */
   1227 
   1228 void
   1229 xstormy16_cgen_init_ibld_table (CGEN_CPU_DESC cd)
   1230 {
   1231   cd->insert_handlers = & xstormy16_cgen_insert_handlers[0];
   1232   cd->extract_handlers = & xstormy16_cgen_extract_handlers[0];
   1233 
   1234   cd->insert_operand = xstormy16_cgen_insert_operand;
   1235   cd->extract_operand = xstormy16_cgen_extract_operand;
   1236 
   1237   cd->get_int_operand = xstormy16_cgen_get_int_operand;
   1238   cd->set_int_operand = xstormy16_cgen_set_int_operand;
   1239   cd->get_vma_operand = xstormy16_cgen_get_vma_operand;
   1240   cd->set_vma_operand = xstormy16_cgen_set_vma_operand;
   1241 }
   1242