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