Back to index

cell-binutils  2.17cvs20070401
xstormy16-ibld.c
Go to the documentation of this file.
00001 /* Instruction building/extraction support for xstormy16. -*- C -*-
00002 
00003    THIS FILE IS MACHINE GENERATED WITH CGEN: Cpu tools GENerator.
00004    - the resultant file is machine generated, cgen-ibld.in isn't
00005 
00006    Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2005, 2006
00007    Free Software Foundation, Inc.
00008 
00009    This file is part of the GNU Binutils and GDB, the GNU debugger.
00010 
00011    This program is free software; you can redistribute it and/or modify
00012    it under the terms of the GNU General Public License as published by
00013    the Free Software Foundation; either version 2, or (at your option)
00014    any later version.
00015 
00016    This program is distributed in the hope that it will be useful,
00017    but WITHOUT ANY WARRANTY; without even the implied warranty of
00018    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00019    GNU General Public License for more details.
00020 
00021    You should have received a copy of the GNU General Public License
00022    along with this program; if not, write to the Free Software Foundation, Inc.,
00023    51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.  */
00024 
00025 /* ??? Eventually more and more of this stuff can go to cpu-independent files.
00026    Keep that in mind.  */
00027 
00028 #include "sysdep.h"
00029 #include <stdio.h>
00030 #include "ansidecl.h"
00031 #include "dis-asm.h"
00032 #include "bfd.h"
00033 #include "symcat.h"
00034 #include "xstormy16-desc.h"
00035 #include "xstormy16-opc.h"
00036 #include "opintl.h"
00037 #include "safe-ctype.h"
00038 
00039 #undef  min
00040 #define min(a,b) ((a) < (b) ? (a) : (b))
00041 #undef  max
00042 #define max(a,b) ((a) > (b) ? (a) : (b))
00043 
00044 /* Used by the ifield rtx function.  */
00045 #define FLD(f) (fields->f)
00046 
00047 static const char * insert_normal
00048   (CGEN_CPU_DESC, long, unsigned int, unsigned int, unsigned int,
00049    unsigned int, unsigned int, unsigned int, CGEN_INSN_BYTES_PTR);
00050 static const char * insert_insn_normal
00051   (CGEN_CPU_DESC, const CGEN_INSN *,
00052    CGEN_FIELDS *, CGEN_INSN_BYTES_PTR, bfd_vma);
00053 static int extract_normal
00054   (CGEN_CPU_DESC, CGEN_EXTRACT_INFO *, CGEN_INSN_INT,
00055    unsigned int, unsigned int, unsigned int, unsigned int,
00056    unsigned int, unsigned int, bfd_vma, long *);
00057 static int extract_insn_normal
00058   (CGEN_CPU_DESC, const CGEN_INSN *, CGEN_EXTRACT_INFO *,
00059    CGEN_INSN_INT, CGEN_FIELDS *, bfd_vma);
00060 #if CGEN_INT_INSN_P
00061 static void put_insn_int_value
00062   (CGEN_CPU_DESC, CGEN_INSN_BYTES_PTR, int, int, CGEN_INSN_INT);
00063 #endif
00064 #if ! CGEN_INT_INSN_P
00065 static CGEN_INLINE void insert_1
00066   (CGEN_CPU_DESC, unsigned long, int, int, int, unsigned char *);
00067 static CGEN_INLINE int fill_cache
00068   (CGEN_CPU_DESC, CGEN_EXTRACT_INFO *,  int, int, bfd_vma);
00069 static CGEN_INLINE long extract_1
00070   (CGEN_CPU_DESC, CGEN_EXTRACT_INFO *, int, int, int, unsigned char *, bfd_vma);
00071 #endif
00072 
00073 /* Operand insertion.  */
00074 
00075 #if ! CGEN_INT_INSN_P
00076 
00077 /* Subroutine of insert_normal.  */
00078 
00079 static CGEN_INLINE void
00080 insert_1 (CGEN_CPU_DESC cd,
00081          unsigned long value,
00082          int start,
00083          int length,
00084          int word_length,
00085          unsigned char *bufp)
00086 {
00087   unsigned long x,mask;
00088   int shift;
00089 
00090   x = cgen_get_insn_value (cd, bufp, word_length);
00091 
00092   /* Written this way to avoid undefined behaviour.  */
00093   mask = (((1L << (length - 1)) - 1) << 1) | 1;
00094   if (CGEN_INSN_LSB0_P)
00095     shift = (start + 1) - length;
00096   else
00097     shift = (word_length - (start + length));
00098   x = (x & ~(mask << shift)) | ((value & mask) << shift);
00099 
00100   cgen_put_insn_value (cd, bufp, word_length, (bfd_vma) x);
00101 }
00102 
00103 #endif /* ! CGEN_INT_INSN_P */
00104 
00105 /* Default insertion routine.
00106 
00107    ATTRS is a mask of the boolean attributes.
00108    WORD_OFFSET is the offset in bits from the start of the insn of the value.
00109    WORD_LENGTH is the length of the word in bits in which the value resides.
00110    START is the starting bit number in the word, architecture origin.
00111    LENGTH is the length of VALUE in bits.
00112    TOTAL_LENGTH is the total length of the insn in bits.
00113 
00114    The result is an error message or NULL if success.  */
00115 
00116 /* ??? This duplicates functionality with bfd's howto table and
00117    bfd_install_relocation.  */
00118 /* ??? This doesn't handle bfd_vma's.  Create another function when
00119    necessary.  */
00120 
00121 static const char *
00122 insert_normal (CGEN_CPU_DESC cd,
00123               long value,
00124               unsigned int attrs,
00125               unsigned int word_offset,
00126               unsigned int start,
00127               unsigned int length,
00128               unsigned int word_length,
00129               unsigned int total_length,
00130               CGEN_INSN_BYTES_PTR buffer)
00131 {
00132   static char errbuf[100];
00133   /* Written this way to avoid undefined behaviour.  */
00134   unsigned long mask = (((1L << (length - 1)) - 1) << 1) | 1;
00135 
00136   /* If LENGTH is zero, this operand doesn't contribute to the value.  */
00137   if (length == 0)
00138     return NULL;
00139 
00140   if (word_length > 32)
00141     abort ();
00142 
00143   /* For architectures with insns smaller than the base-insn-bitsize,
00144      word_length may be too big.  */
00145   if (cd->min_insn_bitsize < cd->base_insn_bitsize)
00146     {
00147       if (word_offset == 0
00148          && word_length > total_length)
00149        word_length = total_length;
00150     }
00151 
00152   /* Ensure VALUE will fit.  */
00153   if (CGEN_BOOL_ATTR (attrs, CGEN_IFLD_SIGN_OPT))
00154     {
00155       long minval = - (1L << (length - 1));
00156       unsigned long maxval = mask;
00157       
00158       if ((value > 0 && (unsigned long) value > maxval)
00159          || value < minval)
00160        {
00161          /* xgettext:c-format */
00162          sprintf (errbuf,
00163                  _("operand out of range (%ld not between %ld and %lu)"),
00164                  value, minval, maxval);
00165          return errbuf;
00166        }
00167     }
00168   else if (! CGEN_BOOL_ATTR (attrs, CGEN_IFLD_SIGNED))
00169     {
00170       unsigned long maxval = mask;
00171       unsigned long val = (unsigned long) value;
00172 
00173       /* For hosts with a word size > 32 check to see if value has been sign
00174         extended beyond 32 bits.  If so then ignore these higher sign bits
00175         as the user is attempting to store a 32-bit signed value into an
00176         unsigned 32-bit field which is allowed.  */
00177       if (sizeof (unsigned long) > 4 && ((value >> 32) == -1))
00178        val &= 0xFFFFFFFF;
00179 
00180       if (val > maxval)
00181        {
00182          /* xgettext:c-format */
00183          sprintf (errbuf,
00184                  _("operand out of range (0x%lx not between 0 and 0x%lx)"),
00185                  val, maxval);
00186          return errbuf;
00187        }
00188     }
00189   else
00190     {
00191       if (! cgen_signed_overflow_ok_p (cd))
00192        {
00193          long minval = - (1L << (length - 1));
00194          long maxval =   (1L << (length - 1)) - 1;
00195          
00196          if (value < minval || value > maxval)
00197            {
00198              sprintf
00199               /* xgettext:c-format */
00200               (errbuf, _("operand out of range (%ld not between %ld and %ld)"),
00201                value, minval, maxval);
00202              return errbuf;
00203            }
00204        }
00205     }
00206 
00207 #if CGEN_INT_INSN_P
00208 
00209   {
00210     int shift;
00211 
00212     if (CGEN_INSN_LSB0_P)
00213       shift = (word_offset + start + 1) - length;
00214     else
00215       shift = total_length - (word_offset + start + length);
00216     *buffer = (*buffer & ~(mask << shift)) | ((value & mask) << shift);
00217   }
00218 
00219 #else /* ! CGEN_INT_INSN_P */
00220 
00221   {
00222     unsigned char *bufp = (unsigned char *) buffer + word_offset / 8;
00223 
00224     insert_1 (cd, value, start, length, word_length, bufp);
00225   }
00226 
00227 #endif /* ! CGEN_INT_INSN_P */
00228 
00229   return NULL;
00230 }
00231 
00232 /* Default insn builder (insert handler).
00233    The instruction is recorded in CGEN_INT_INSN_P byte order (meaning
00234    that if CGEN_INSN_BYTES_PTR is an int * and thus, the value is
00235    recorded in host byte order, otherwise BUFFER is an array of bytes
00236    and the value is recorded in target byte order).
00237    The result is an error message or NULL if success.  */
00238 
00239 static const char *
00240 insert_insn_normal (CGEN_CPU_DESC cd,
00241                   const CGEN_INSN * insn,
00242                   CGEN_FIELDS * fields,
00243                   CGEN_INSN_BYTES_PTR buffer,
00244                   bfd_vma pc)
00245 {
00246   const CGEN_SYNTAX *syntax = CGEN_INSN_SYNTAX (insn);
00247   unsigned long value;
00248   const CGEN_SYNTAX_CHAR_TYPE * syn;
00249 
00250   CGEN_INIT_INSERT (cd);
00251   value = CGEN_INSN_BASE_VALUE (insn);
00252 
00253   /* If we're recording insns as numbers (rather than a string of bytes),
00254      target byte order handling is deferred until later.  */
00255 
00256 #if CGEN_INT_INSN_P
00257 
00258   put_insn_int_value (cd, buffer, cd->base_insn_bitsize,
00259                     CGEN_FIELDS_BITSIZE (fields), value);
00260 
00261 #else
00262 
00263   cgen_put_insn_value (cd, buffer, min ((unsigned) cd->base_insn_bitsize,
00264                                    (unsigned) CGEN_FIELDS_BITSIZE (fields)),
00265                      value);
00266 
00267 #endif /* ! CGEN_INT_INSN_P */
00268 
00269   /* ??? It would be better to scan the format's fields.
00270      Still need to be able to insert a value based on the operand though;
00271      e.g. storing a branch displacement that got resolved later.
00272      Needs more thought first.  */
00273 
00274   for (syn = CGEN_SYNTAX_STRING (syntax); * syn; ++ syn)
00275     {
00276       const char *errmsg;
00277 
00278       if (CGEN_SYNTAX_CHAR_P (* syn))
00279        continue;
00280 
00281       errmsg = (* cd->insert_operand) (cd, CGEN_SYNTAX_FIELD (*syn),
00282                                    fields, buffer, pc);
00283       if (errmsg)
00284        return errmsg;
00285     }
00286 
00287   return NULL;
00288 }
00289 
00290 #if CGEN_INT_INSN_P
00291 /* Cover function to store an insn value into an integral insn.  Must go here
00292    because it needs <prefix>-desc.h for CGEN_INT_INSN_P.  */
00293 
00294 static void
00295 put_insn_int_value (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
00296                   CGEN_INSN_BYTES_PTR buf,
00297                   int length,
00298                   int insn_length,
00299                   CGEN_INSN_INT value)
00300 {
00301   /* For architectures with insns smaller than the base-insn-bitsize,
00302      length may be too big.  */
00303   if (length > insn_length)
00304     *buf = value;
00305   else
00306     {
00307       int shift = insn_length - length;
00308       /* Written this way to avoid undefined behaviour.  */
00309       CGEN_INSN_INT mask = (((1L << (length - 1)) - 1) << 1) | 1;
00310 
00311       *buf = (*buf & ~(mask << shift)) | ((value & mask) << shift);
00312     }
00313 }
00314 #endif
00315 
00316 /* Operand extraction.  */
00317 
00318 #if ! CGEN_INT_INSN_P
00319 
00320 /* Subroutine of extract_normal.
00321    Ensure sufficient bytes are cached in EX_INFO.
00322    OFFSET is the offset in bytes from the start of the insn of the value.
00323    BYTES is the length of the needed value.
00324    Returns 1 for success, 0 for failure.  */
00325 
00326 static CGEN_INLINE int
00327 fill_cache (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
00328            CGEN_EXTRACT_INFO *ex_info,
00329            int offset,
00330            int bytes,
00331            bfd_vma pc)
00332 {
00333   /* It's doubtful that the middle part has already been fetched so
00334      we don't optimize that case.  kiss.  */
00335   unsigned int mask;
00336   disassemble_info *info = (disassemble_info *) ex_info->dis_info;
00337 
00338   /* First do a quick check.  */
00339   mask = (1 << bytes) - 1;
00340   if (((ex_info->valid >> offset) & mask) == mask)
00341     return 1;
00342 
00343   /* Search for the first byte we need to read.  */
00344   for (mask = 1 << offset; bytes > 0; --bytes, ++offset, mask <<= 1)
00345     if (! (mask & ex_info->valid))
00346       break;
00347 
00348   if (bytes)
00349     {
00350       int status;
00351 
00352       pc += offset;
00353       status = (*info->read_memory_func)
00354        (pc, ex_info->insn_bytes + offset, bytes, info);
00355 
00356       if (status != 0)
00357        {
00358          (*info->memory_error_func) (status, pc, info);
00359          return 0;
00360        }
00361 
00362       ex_info->valid |= ((1 << bytes) - 1) << offset;
00363     }
00364 
00365   return 1;
00366 }
00367 
00368 /* Subroutine of extract_normal.  */
00369 
00370 static CGEN_INLINE long
00371 extract_1 (CGEN_CPU_DESC cd,
00372           CGEN_EXTRACT_INFO *ex_info ATTRIBUTE_UNUSED,
00373           int start,
00374           int length,
00375           int word_length,
00376           unsigned char *bufp,
00377           bfd_vma pc ATTRIBUTE_UNUSED)
00378 {
00379   unsigned long x;
00380   int shift;
00381 
00382   x = cgen_get_insn_value (cd, bufp, word_length);
00383 
00384   if (CGEN_INSN_LSB0_P)
00385     shift = (start + 1) - length;
00386   else
00387     shift = (word_length - (start + length));
00388   return x >> shift;
00389 }
00390 
00391 #endif /* ! CGEN_INT_INSN_P */
00392 
00393 /* Default extraction routine.
00394 
00395    INSN_VALUE is the first base_insn_bitsize bits of the insn in host order,
00396    or sometimes less for cases like the m32r where the base insn size is 32
00397    but some insns are 16 bits.
00398    ATTRS is a mask of the boolean attributes.  We only need `SIGNED',
00399    but for generality we take a bitmask of all of them.
00400    WORD_OFFSET is the offset in bits from the start of the insn of the value.
00401    WORD_LENGTH is the length of the word in bits in which the value resides.
00402    START is the starting bit number in the word, architecture origin.
00403    LENGTH is the length of VALUE in bits.
00404    TOTAL_LENGTH is the total length of the insn in bits.
00405 
00406    Returns 1 for success, 0 for failure.  */
00407 
00408 /* ??? The return code isn't properly used.  wip.  */
00409 
00410 /* ??? This doesn't handle bfd_vma's.  Create another function when
00411    necessary.  */
00412 
00413 static int
00414 extract_normal (CGEN_CPU_DESC cd,
00415 #if ! CGEN_INT_INSN_P
00416               CGEN_EXTRACT_INFO *ex_info,
00417 #else
00418               CGEN_EXTRACT_INFO *ex_info ATTRIBUTE_UNUSED,
00419 #endif
00420               CGEN_INSN_INT insn_value,
00421               unsigned int attrs,
00422               unsigned int word_offset,
00423               unsigned int start,
00424               unsigned int length,
00425               unsigned int word_length,
00426               unsigned int total_length,
00427 #if ! CGEN_INT_INSN_P
00428               bfd_vma pc,
00429 #else
00430               bfd_vma pc ATTRIBUTE_UNUSED,
00431 #endif
00432               long *valuep)
00433 {
00434   long value, mask;
00435 
00436   /* If LENGTH is zero, this operand doesn't contribute to the value
00437      so give it a standard value of zero.  */
00438   if (length == 0)
00439     {
00440       *valuep = 0;
00441       return 1;
00442     }
00443 
00444   if (word_length > 32)
00445     abort ();
00446 
00447   /* For architectures with insns smaller than the insn-base-bitsize,
00448      word_length may be too big.  */
00449   if (cd->min_insn_bitsize < cd->base_insn_bitsize)
00450     {
00451       if (word_offset + word_length > total_length)
00452        word_length = total_length - word_offset;
00453     }
00454 
00455   /* Does the value reside in INSN_VALUE, and at the right alignment?  */
00456 
00457   if (CGEN_INT_INSN_P || (word_offset == 0 && word_length == total_length))
00458     {
00459       if (CGEN_INSN_LSB0_P)
00460        value = insn_value >> ((word_offset + start + 1) - length);
00461       else
00462        value = insn_value >> (total_length - ( word_offset + start + length));
00463     }
00464 
00465 #if ! CGEN_INT_INSN_P
00466 
00467   else
00468     {
00469       unsigned char *bufp = ex_info->insn_bytes + word_offset / 8;
00470 
00471       if (word_length > 32)
00472        abort ();
00473 
00474       if (fill_cache (cd, ex_info, word_offset / 8, word_length / 8, pc) == 0)
00475        return 0;
00476 
00477       value = extract_1 (cd, ex_info, start, length, word_length, bufp, pc);
00478     }
00479 
00480 #endif /* ! CGEN_INT_INSN_P */
00481 
00482   /* Written this way to avoid undefined behaviour.  */
00483   mask = (((1L << (length - 1)) - 1) << 1) | 1;
00484 
00485   value &= mask;
00486   /* sign extend? */
00487   if (CGEN_BOOL_ATTR (attrs, CGEN_IFLD_SIGNED)
00488       && (value & (1L << (length - 1))))
00489     value |= ~mask;
00490 
00491   *valuep = value;
00492 
00493   return 1;
00494 }
00495 
00496 /* Default insn extractor.
00497 
00498    INSN_VALUE is the first base_insn_bitsize bits, translated to host order.
00499    The extracted fields are stored in FIELDS.
00500    EX_INFO is used to handle reading variable length insns.
00501    Return the length of the insn in bits, or 0 if no match,
00502    or -1 if an error occurs fetching data (memory_error_func will have
00503    been called).  */
00504 
00505 static int
00506 extract_insn_normal (CGEN_CPU_DESC cd,
00507                    const CGEN_INSN *insn,
00508                    CGEN_EXTRACT_INFO *ex_info,
00509                    CGEN_INSN_INT insn_value,
00510                    CGEN_FIELDS *fields,
00511                    bfd_vma pc)
00512 {
00513   const CGEN_SYNTAX *syntax = CGEN_INSN_SYNTAX (insn);
00514   const CGEN_SYNTAX_CHAR_TYPE *syn;
00515 
00516   CGEN_FIELDS_BITSIZE (fields) = CGEN_INSN_BITSIZE (insn);
00517 
00518   CGEN_INIT_EXTRACT (cd);
00519 
00520   for (syn = CGEN_SYNTAX_STRING (syntax); *syn; ++syn)
00521     {
00522       int length;
00523 
00524       if (CGEN_SYNTAX_CHAR_P (*syn))
00525        continue;
00526 
00527       length = (* cd->extract_operand) (cd, CGEN_SYNTAX_FIELD (*syn),
00528                                    ex_info, insn_value, fields, pc);
00529       if (length <= 0)
00530        return length;
00531     }
00532 
00533   /* We recognized and successfully extracted this insn.  */
00534   return CGEN_INSN_BITSIZE (insn);
00535 }
00536 
00537 /* Machine generated code added here.  */
00538 
00539 const char * xstormy16_cgen_insert_operand
00540   (CGEN_CPU_DESC, int, CGEN_FIELDS *, CGEN_INSN_BYTES_PTR, bfd_vma);
00541 
00542 /* Main entry point for operand insertion.
00543 
00544    This function is basically just a big switch statement.  Earlier versions
00545    used tables to look up the function to use, but
00546    - if the table contains both assembler and disassembler functions then
00547      the disassembler contains much of the assembler and vice-versa,
00548    - there's a lot of inlining possibilities as things grow,
00549    - using a switch statement avoids the function call overhead.
00550 
00551    This function could be moved into `parse_insn_normal', but keeping it
00552    separate makes clear the interface between `parse_insn_normal' and each of
00553    the handlers.  It's also needed by GAS to insert operands that couldn't be
00554    resolved during parsing.  */
00555 
00556 const char *
00557 xstormy16_cgen_insert_operand (CGEN_CPU_DESC cd,
00558                           int opindex,
00559                           CGEN_FIELDS * fields,
00560                           CGEN_INSN_BYTES_PTR buffer,
00561                           bfd_vma pc ATTRIBUTE_UNUSED)
00562 {
00563   const char * errmsg = NULL;
00564   unsigned int total_length = CGEN_FIELDS_BITSIZE (fields);
00565 
00566   switch (opindex)
00567     {
00568     case XSTORMY16_OPERAND_RB :
00569       errmsg = insert_normal (cd, fields->f_Rb, 0, 0, 17, 3, 32, total_length, buffer);
00570       break;
00571     case XSTORMY16_OPERAND_RBJ :
00572       errmsg = insert_normal (cd, fields->f_Rbj, 0, 0, 11, 1, 32, total_length, buffer);
00573       break;
00574     case XSTORMY16_OPERAND_RD :
00575       errmsg = insert_normal (cd, fields->f_Rd, 0, 0, 12, 4, 32, total_length, buffer);
00576       break;
00577     case XSTORMY16_OPERAND_RDM :
00578       errmsg = insert_normal (cd, fields->f_Rdm, 0, 0, 13, 3, 32, total_length, buffer);
00579       break;
00580     case XSTORMY16_OPERAND_RM :
00581       errmsg = insert_normal (cd, fields->f_Rm, 0, 0, 4, 3, 32, total_length, buffer);
00582       break;
00583     case XSTORMY16_OPERAND_RS :
00584       errmsg = insert_normal (cd, fields->f_Rs, 0, 0, 8, 4, 32, total_length, buffer);
00585       break;
00586     case XSTORMY16_OPERAND_ABS24 :
00587       {
00588 {
00589   FLD (f_abs24_1) = ((FLD (f_abs24)) & (255));
00590   FLD (f_abs24_2) = ((unsigned int) (FLD (f_abs24)) >> (8));
00591 }
00592         errmsg = insert_normal (cd, fields->f_abs24_1, 0, 0, 8, 8, 32, total_length, buffer);
00593         if (errmsg)
00594           break;
00595         errmsg = insert_normal (cd, fields->f_abs24_2, 0, 0, 16, 16, 32, total_length, buffer);
00596         if (errmsg)
00597           break;
00598       }
00599       break;
00600     case XSTORMY16_OPERAND_BCOND2 :
00601       errmsg = insert_normal (cd, fields->f_op2, 0, 0, 4, 4, 32, total_length, buffer);
00602       break;
00603     case XSTORMY16_OPERAND_BCOND5 :
00604       errmsg = insert_normal (cd, fields->f_op5, 0, 0, 16, 4, 32, total_length, buffer);
00605       break;
00606     case XSTORMY16_OPERAND_HMEM8 :
00607       {
00608         long value = fields->f_hmem8;
00609         value = ((value) - (32512));
00610         errmsg = insert_normal (cd, value, 0|(1<<CGEN_IFLD_ABS_ADDR), 0, 8, 8, 32, total_length, buffer);
00611       }
00612       break;
00613     case XSTORMY16_OPERAND_IMM12 :
00614       errmsg = insert_normal (cd, fields->f_imm12, 0|(1<<CGEN_IFLD_SIGNED), 0, 20, 12, 32, total_length, buffer);
00615       break;
00616     case XSTORMY16_OPERAND_IMM16 :
00617       errmsg = insert_normal (cd, fields->f_imm16, 0|(1<<CGEN_IFLD_SIGN_OPT), 0, 16, 16, 32, total_length, buffer);
00618       break;
00619     case XSTORMY16_OPERAND_IMM2 :
00620       errmsg = insert_normal (cd, fields->f_imm2, 0, 0, 10, 2, 32, total_length, buffer);
00621       break;
00622     case XSTORMY16_OPERAND_IMM3 :
00623       errmsg = insert_normal (cd, fields->f_imm3, 0, 0, 4, 3, 32, total_length, buffer);
00624       break;
00625     case XSTORMY16_OPERAND_IMM3B :
00626       errmsg = insert_normal (cd, fields->f_imm3b, 0, 0, 17, 3, 32, total_length, buffer);
00627       break;
00628     case XSTORMY16_OPERAND_IMM4 :
00629       errmsg = insert_normal (cd, fields->f_imm4, 0, 0, 8, 4, 32, total_length, buffer);
00630       break;
00631     case XSTORMY16_OPERAND_IMM8 :
00632       errmsg = insert_normal (cd, fields->f_imm8, 0, 0, 8, 8, 32, total_length, buffer);
00633       break;
00634     case XSTORMY16_OPERAND_IMM8SMALL :
00635       errmsg = insert_normal (cd, fields->f_imm8, 0, 0, 8, 8, 32, total_length, buffer);
00636       break;
00637     case XSTORMY16_OPERAND_LMEM8 :
00638       errmsg = insert_normal (cd, fields->f_lmem8, 0|(1<<CGEN_IFLD_ABS_ADDR), 0, 8, 8, 32, total_length, buffer);
00639       break;
00640     case XSTORMY16_OPERAND_REL12 :
00641       {
00642         long value = fields->f_rel12;
00643         value = ((value) - (((pc) + (4))));
00644         errmsg = insert_normal (cd, value, 0|(1<<CGEN_IFLD_SIGNED)|(1<<CGEN_IFLD_PCREL_ADDR), 0, 20, 12, 32, total_length, buffer);
00645       }
00646       break;
00647     case XSTORMY16_OPERAND_REL12A :
00648       {
00649         long value = fields->f_rel12a;
00650         value = ((int) (((value) - (((pc) + (2))))) >> (1));
00651         errmsg = insert_normal (cd, value, 0|(1<<CGEN_IFLD_SIGNED)|(1<<CGEN_IFLD_PCREL_ADDR), 0, 4, 11, 32, total_length, buffer);
00652       }
00653       break;
00654     case XSTORMY16_OPERAND_REL8_2 :
00655       {
00656         long value = fields->f_rel8_2;
00657         value = ((value) - (((pc) + (2))));
00658         errmsg = insert_normal (cd, value, 0|(1<<CGEN_IFLD_SIGNED)|(1<<CGEN_IFLD_PCREL_ADDR), 0, 8, 8, 32, total_length, buffer);
00659       }
00660       break;
00661     case XSTORMY16_OPERAND_REL8_4 :
00662       {
00663         long value = fields->f_rel8_4;
00664         value = ((value) - (((pc) + (4))));
00665         errmsg = insert_normal (cd, value, 0|(1<<CGEN_IFLD_SIGNED)|(1<<CGEN_IFLD_PCREL_ADDR), 0, 8, 8, 32, total_length, buffer);
00666       }
00667       break;
00668     case XSTORMY16_OPERAND_WS2 :
00669       errmsg = insert_normal (cd, fields->f_op2m, 0, 0, 7, 1, 32, total_length, buffer);
00670       break;
00671 
00672     default :
00673       /* xgettext:c-format */
00674       fprintf (stderr, _("Unrecognized field %d while building insn.\n"),
00675               opindex);
00676       abort ();
00677   }
00678 
00679   return errmsg;
00680 }
00681 
00682 int xstormy16_cgen_extract_operand
00683   (CGEN_CPU_DESC, int, CGEN_EXTRACT_INFO *, CGEN_INSN_INT, CGEN_FIELDS *, bfd_vma);
00684 
00685 /* Main entry point for operand extraction.
00686    The result is <= 0 for error, >0 for success.
00687    ??? Actual values aren't well defined right now.
00688 
00689    This function is basically just a big switch statement.  Earlier versions
00690    used tables to look up the function to use, but
00691    - if the table contains both assembler and disassembler functions then
00692      the disassembler contains much of the assembler and vice-versa,
00693    - there's a lot of inlining possibilities as things grow,
00694    - using a switch statement avoids the function call overhead.
00695 
00696    This function could be moved into `print_insn_normal', but keeping it
00697    separate makes clear the interface between `print_insn_normal' and each of
00698    the handlers.  */
00699 
00700 int
00701 xstormy16_cgen_extract_operand (CGEN_CPU_DESC cd,
00702                           int opindex,
00703                           CGEN_EXTRACT_INFO *ex_info,
00704                           CGEN_INSN_INT insn_value,
00705                           CGEN_FIELDS * fields,
00706                           bfd_vma pc)
00707 {
00708   /* Assume success (for those operands that are nops).  */
00709   int length = 1;
00710   unsigned int total_length = CGEN_FIELDS_BITSIZE (fields);
00711 
00712   switch (opindex)
00713     {
00714     case XSTORMY16_OPERAND_RB :
00715       length = extract_normal (cd, ex_info, insn_value, 0, 0, 17, 3, 32, total_length, pc, & fields->f_Rb);
00716       break;
00717     case XSTORMY16_OPERAND_RBJ :
00718       length = extract_normal (cd, ex_info, insn_value, 0, 0, 11, 1, 32, total_length, pc, & fields->f_Rbj);
00719       break;
00720     case XSTORMY16_OPERAND_RD :
00721       length = extract_normal (cd, ex_info, insn_value, 0, 0, 12, 4, 32, total_length, pc, & fields->f_Rd);
00722       break;
00723     case XSTORMY16_OPERAND_RDM :
00724       length = extract_normal (cd, ex_info, insn_value, 0, 0, 13, 3, 32, total_length, pc, & fields->f_Rdm);
00725       break;
00726     case XSTORMY16_OPERAND_RM :
00727       length = extract_normal (cd, ex_info, insn_value, 0, 0, 4, 3, 32, total_length, pc, & fields->f_Rm);
00728       break;
00729     case XSTORMY16_OPERAND_RS :
00730       length = extract_normal (cd, ex_info, insn_value, 0, 0, 8, 4, 32, total_length, pc, & fields->f_Rs);
00731       break;
00732     case XSTORMY16_OPERAND_ABS24 :
00733       {
00734         length = extract_normal (cd, ex_info, insn_value, 0, 0, 8, 8, 32, total_length, pc, & fields->f_abs24_1);
00735         if (length <= 0) break;
00736         length = extract_normal (cd, ex_info, insn_value, 0, 0, 16, 16, 32, total_length, pc, & fields->f_abs24_2);
00737         if (length <= 0) break;
00738   FLD (f_abs24) = ((((FLD (f_abs24_2)) << (8))) | (FLD (f_abs24_1)));
00739       }
00740       break;
00741     case XSTORMY16_OPERAND_BCOND2 :
00742       length = extract_normal (cd, ex_info, insn_value, 0, 0, 4, 4, 32, total_length, pc, & fields->f_op2);
00743       break;
00744     case XSTORMY16_OPERAND_BCOND5 :
00745       length = extract_normal (cd, ex_info, insn_value, 0, 0, 16, 4, 32, total_length, pc, & fields->f_op5);
00746       break;
00747     case XSTORMY16_OPERAND_HMEM8 :
00748       {
00749         long value;
00750         length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_ABS_ADDR), 0, 8, 8, 32, total_length, pc, & value);
00751         value = ((value) + (32512));
00752         fields->f_hmem8 = value;
00753       }
00754       break;
00755     case XSTORMY16_OPERAND_IMM12 :
00756       length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_SIGNED), 0, 20, 12, 32, total_length, pc, & fields->f_imm12);
00757       break;
00758     case XSTORMY16_OPERAND_IMM16 :
00759       length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_SIGN_OPT), 0, 16, 16, 32, total_length, pc, & fields->f_imm16);
00760       break;
00761     case XSTORMY16_OPERAND_IMM2 :
00762       length = extract_normal (cd, ex_info, insn_value, 0, 0, 10, 2, 32, total_length, pc, & fields->f_imm2);
00763       break;
00764     case XSTORMY16_OPERAND_IMM3 :
00765       length = extract_normal (cd, ex_info, insn_value, 0, 0, 4, 3, 32, total_length, pc, & fields->f_imm3);
00766       break;
00767     case XSTORMY16_OPERAND_IMM3B :
00768       length = extract_normal (cd, ex_info, insn_value, 0, 0, 17, 3, 32, total_length, pc, & fields->f_imm3b);
00769       break;
00770     case XSTORMY16_OPERAND_IMM4 :
00771       length = extract_normal (cd, ex_info, insn_value, 0, 0, 8, 4, 32, total_length, pc, & fields->f_imm4);
00772       break;
00773     case XSTORMY16_OPERAND_IMM8 :
00774       length = extract_normal (cd, ex_info, insn_value, 0, 0, 8, 8, 32, total_length, pc, & fields->f_imm8);
00775       break;
00776     case XSTORMY16_OPERAND_IMM8SMALL :
00777       length = extract_normal (cd, ex_info, insn_value, 0, 0, 8, 8, 32, total_length, pc, & fields->f_imm8);
00778       break;
00779     case XSTORMY16_OPERAND_LMEM8 :
00780       length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_ABS_ADDR), 0, 8, 8, 32, total_length, pc, & fields->f_lmem8);
00781       break;
00782     case XSTORMY16_OPERAND_REL12 :
00783       {
00784         long value;
00785         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);
00786         value = ((value) + (((pc) + (4))));
00787         fields->f_rel12 = value;
00788       }
00789       break;
00790     case XSTORMY16_OPERAND_REL12A :
00791       {
00792         long value;
00793         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);
00794         value = ((((value) << (1))) + (((pc) + (2))));
00795         fields->f_rel12a = value;
00796       }
00797       break;
00798     case XSTORMY16_OPERAND_REL8_2 :
00799       {
00800         long value;
00801         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);
00802         value = ((value) + (((pc) + (2))));
00803         fields->f_rel8_2 = value;
00804       }
00805       break;
00806     case XSTORMY16_OPERAND_REL8_4 :
00807       {
00808         long value;
00809         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);
00810         value = ((value) + (((pc) + (4))));
00811         fields->f_rel8_4 = value;
00812       }
00813       break;
00814     case XSTORMY16_OPERAND_WS2 :
00815       length = extract_normal (cd, ex_info, insn_value, 0, 0, 7, 1, 32, total_length, pc, & fields->f_op2m);
00816       break;
00817 
00818     default :
00819       /* xgettext:c-format */
00820       fprintf (stderr, _("Unrecognized field %d while decoding insn.\n"),
00821               opindex);
00822       abort ();
00823     }
00824 
00825   return length;
00826 }
00827 
00828 cgen_insert_fn * const xstormy16_cgen_insert_handlers[] = 
00829 {
00830   insert_insn_normal,
00831 };
00832 
00833 cgen_extract_fn * const xstormy16_cgen_extract_handlers[] = 
00834 {
00835   extract_insn_normal,
00836 };
00837 
00838 int xstormy16_cgen_get_int_operand     (CGEN_CPU_DESC, int, const CGEN_FIELDS *);
00839 bfd_vma xstormy16_cgen_get_vma_operand (CGEN_CPU_DESC, int, const CGEN_FIELDS *);
00840 
00841 /* Getting values from cgen_fields is handled by a collection of functions.
00842    They are distinguished by the type of the VALUE argument they return.
00843    TODO: floating point, inlining support, remove cases where result type
00844    not appropriate.  */
00845 
00846 int
00847 xstormy16_cgen_get_int_operand (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
00848                           int opindex,
00849                           const CGEN_FIELDS * fields)
00850 {
00851   int value;
00852 
00853   switch (opindex)
00854     {
00855     case XSTORMY16_OPERAND_RB :
00856       value = fields->f_Rb;
00857       break;
00858     case XSTORMY16_OPERAND_RBJ :
00859       value = fields->f_Rbj;
00860       break;
00861     case XSTORMY16_OPERAND_RD :
00862       value = fields->f_Rd;
00863       break;
00864     case XSTORMY16_OPERAND_RDM :
00865       value = fields->f_Rdm;
00866       break;
00867     case XSTORMY16_OPERAND_RM :
00868       value = fields->f_Rm;
00869       break;
00870     case XSTORMY16_OPERAND_RS :
00871       value = fields->f_Rs;
00872       break;
00873     case XSTORMY16_OPERAND_ABS24 :
00874       value = fields->f_abs24;
00875       break;
00876     case XSTORMY16_OPERAND_BCOND2 :
00877       value = fields->f_op2;
00878       break;
00879     case XSTORMY16_OPERAND_BCOND5 :
00880       value = fields->f_op5;
00881       break;
00882     case XSTORMY16_OPERAND_HMEM8 :
00883       value = fields->f_hmem8;
00884       break;
00885     case XSTORMY16_OPERAND_IMM12 :
00886       value = fields->f_imm12;
00887       break;
00888     case XSTORMY16_OPERAND_IMM16 :
00889       value = fields->f_imm16;
00890       break;
00891     case XSTORMY16_OPERAND_IMM2 :
00892       value = fields->f_imm2;
00893       break;
00894     case XSTORMY16_OPERAND_IMM3 :
00895       value = fields->f_imm3;
00896       break;
00897     case XSTORMY16_OPERAND_IMM3B :
00898       value = fields->f_imm3b;
00899       break;
00900     case XSTORMY16_OPERAND_IMM4 :
00901       value = fields->f_imm4;
00902       break;
00903     case XSTORMY16_OPERAND_IMM8 :
00904       value = fields->f_imm8;
00905       break;
00906     case XSTORMY16_OPERAND_IMM8SMALL :
00907       value = fields->f_imm8;
00908       break;
00909     case XSTORMY16_OPERAND_LMEM8 :
00910       value = fields->f_lmem8;
00911       break;
00912     case XSTORMY16_OPERAND_REL12 :
00913       value = fields->f_rel12;
00914       break;
00915     case XSTORMY16_OPERAND_REL12A :
00916       value = fields->f_rel12a;
00917       break;
00918     case XSTORMY16_OPERAND_REL8_2 :
00919       value = fields->f_rel8_2;
00920       break;
00921     case XSTORMY16_OPERAND_REL8_4 :
00922       value = fields->f_rel8_4;
00923       break;
00924     case XSTORMY16_OPERAND_WS2 :
00925       value = fields->f_op2m;
00926       break;
00927 
00928     default :
00929       /* xgettext:c-format */
00930       fprintf (stderr, _("Unrecognized field %d while getting int operand.\n"),
00931                      opindex);
00932       abort ();
00933   }
00934 
00935   return value;
00936 }
00937 
00938 bfd_vma
00939 xstormy16_cgen_get_vma_operand (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
00940                           int opindex,
00941                           const CGEN_FIELDS * fields)
00942 {
00943   bfd_vma value;
00944 
00945   switch (opindex)
00946     {
00947     case XSTORMY16_OPERAND_RB :
00948       value = fields->f_Rb;
00949       break;
00950     case XSTORMY16_OPERAND_RBJ :
00951       value = fields->f_Rbj;
00952       break;
00953     case XSTORMY16_OPERAND_RD :
00954       value = fields->f_Rd;
00955       break;
00956     case XSTORMY16_OPERAND_RDM :
00957       value = fields->f_Rdm;
00958       break;
00959     case XSTORMY16_OPERAND_RM :
00960       value = fields->f_Rm;
00961       break;
00962     case XSTORMY16_OPERAND_RS :
00963       value = fields->f_Rs;
00964       break;
00965     case XSTORMY16_OPERAND_ABS24 :
00966       value = fields->f_abs24;
00967       break;
00968     case XSTORMY16_OPERAND_BCOND2 :
00969       value = fields->f_op2;
00970       break;
00971     case XSTORMY16_OPERAND_BCOND5 :
00972       value = fields->f_op5;
00973       break;
00974     case XSTORMY16_OPERAND_HMEM8 :
00975       value = fields->f_hmem8;
00976       break;
00977     case XSTORMY16_OPERAND_IMM12 :
00978       value = fields->f_imm12;
00979       break;
00980     case XSTORMY16_OPERAND_IMM16 :
00981       value = fields->f_imm16;
00982       break;
00983     case XSTORMY16_OPERAND_IMM2 :
00984       value = fields->f_imm2;
00985       break;
00986     case XSTORMY16_OPERAND_IMM3 :
00987       value = fields->f_imm3;
00988       break;
00989     case XSTORMY16_OPERAND_IMM3B :
00990       value = fields->f_imm3b;
00991       break;
00992     case XSTORMY16_OPERAND_IMM4 :
00993       value = fields->f_imm4;
00994       break;
00995     case XSTORMY16_OPERAND_IMM8 :
00996       value = fields->f_imm8;
00997       break;
00998     case XSTORMY16_OPERAND_IMM8SMALL :
00999       value = fields->f_imm8;
01000       break;
01001     case XSTORMY16_OPERAND_LMEM8 :
01002       value = fields->f_lmem8;
01003       break;
01004     case XSTORMY16_OPERAND_REL12 :
01005       value = fields->f_rel12;
01006       break;
01007     case XSTORMY16_OPERAND_REL12A :
01008       value = fields->f_rel12a;
01009       break;
01010     case XSTORMY16_OPERAND_REL8_2 :
01011       value = fields->f_rel8_2;
01012       break;
01013     case XSTORMY16_OPERAND_REL8_4 :
01014       value = fields->f_rel8_4;
01015       break;
01016     case XSTORMY16_OPERAND_WS2 :
01017       value = fields->f_op2m;
01018       break;
01019 
01020     default :
01021       /* xgettext:c-format */
01022       fprintf (stderr, _("Unrecognized field %d while getting vma operand.\n"),
01023                      opindex);
01024       abort ();
01025   }
01026 
01027   return value;
01028 }
01029 
01030 void xstormy16_cgen_set_int_operand  (CGEN_CPU_DESC, int, CGEN_FIELDS *, int);
01031 void xstormy16_cgen_set_vma_operand  (CGEN_CPU_DESC, int, CGEN_FIELDS *, bfd_vma);
01032 
01033 /* Stuffing values in cgen_fields is handled by a collection of functions.
01034    They are distinguished by the type of the VALUE argument they accept.
01035    TODO: floating point, inlining support, remove cases where argument type
01036    not appropriate.  */
01037 
01038 void
01039 xstormy16_cgen_set_int_operand (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
01040                           int opindex,
01041                           CGEN_FIELDS * fields,
01042                           int value)
01043 {
01044   switch (opindex)
01045     {
01046     case XSTORMY16_OPERAND_RB :
01047       fields->f_Rb = value;
01048       break;
01049     case XSTORMY16_OPERAND_RBJ :
01050       fields->f_Rbj = value;
01051       break;
01052     case XSTORMY16_OPERAND_RD :
01053       fields->f_Rd = value;
01054       break;
01055     case XSTORMY16_OPERAND_RDM :
01056       fields->f_Rdm = value;
01057       break;
01058     case XSTORMY16_OPERAND_RM :
01059       fields->f_Rm = value;
01060       break;
01061     case XSTORMY16_OPERAND_RS :
01062       fields->f_Rs = value;
01063       break;
01064     case XSTORMY16_OPERAND_ABS24 :
01065       fields->f_abs24 = value;
01066       break;
01067     case XSTORMY16_OPERAND_BCOND2 :
01068       fields->f_op2 = value;
01069       break;
01070     case XSTORMY16_OPERAND_BCOND5 :
01071       fields->f_op5 = value;
01072       break;
01073     case XSTORMY16_OPERAND_HMEM8 :
01074       fields->f_hmem8 = value;
01075       break;
01076     case XSTORMY16_OPERAND_IMM12 :
01077       fields->f_imm12 = value;
01078       break;
01079     case XSTORMY16_OPERAND_IMM16 :
01080       fields->f_imm16 = value;
01081       break;
01082     case XSTORMY16_OPERAND_IMM2 :
01083       fields->f_imm2 = value;
01084       break;
01085     case XSTORMY16_OPERAND_IMM3 :
01086       fields->f_imm3 = value;
01087       break;
01088     case XSTORMY16_OPERAND_IMM3B :
01089       fields->f_imm3b = value;
01090       break;
01091     case XSTORMY16_OPERAND_IMM4 :
01092       fields->f_imm4 = value;
01093       break;
01094     case XSTORMY16_OPERAND_IMM8 :
01095       fields->f_imm8 = value;
01096       break;
01097     case XSTORMY16_OPERAND_IMM8SMALL :
01098       fields->f_imm8 = value;
01099       break;
01100     case XSTORMY16_OPERAND_LMEM8 :
01101       fields->f_lmem8 = value;
01102       break;
01103     case XSTORMY16_OPERAND_REL12 :
01104       fields->f_rel12 = value;
01105       break;
01106     case XSTORMY16_OPERAND_REL12A :
01107       fields->f_rel12a = value;
01108       break;
01109     case XSTORMY16_OPERAND_REL8_2 :
01110       fields->f_rel8_2 = value;
01111       break;
01112     case XSTORMY16_OPERAND_REL8_4 :
01113       fields->f_rel8_4 = value;
01114       break;
01115     case XSTORMY16_OPERAND_WS2 :
01116       fields->f_op2m = value;
01117       break;
01118 
01119     default :
01120       /* xgettext:c-format */
01121       fprintf (stderr, _("Unrecognized field %d while setting int operand.\n"),
01122                      opindex);
01123       abort ();
01124   }
01125 }
01126 
01127 void
01128 xstormy16_cgen_set_vma_operand (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
01129                           int opindex,
01130                           CGEN_FIELDS * fields,
01131                           bfd_vma value)
01132 {
01133   switch (opindex)
01134     {
01135     case XSTORMY16_OPERAND_RB :
01136       fields->f_Rb = value;
01137       break;
01138     case XSTORMY16_OPERAND_RBJ :
01139       fields->f_Rbj = value;
01140       break;
01141     case XSTORMY16_OPERAND_RD :
01142       fields->f_Rd = value;
01143       break;
01144     case XSTORMY16_OPERAND_RDM :
01145       fields->f_Rdm = value;
01146       break;
01147     case XSTORMY16_OPERAND_RM :
01148       fields->f_Rm = value;
01149       break;
01150     case XSTORMY16_OPERAND_RS :
01151       fields->f_Rs = value;
01152       break;
01153     case XSTORMY16_OPERAND_ABS24 :
01154       fields->f_abs24 = value;
01155       break;
01156     case XSTORMY16_OPERAND_BCOND2 :
01157       fields->f_op2 = value;
01158       break;
01159     case XSTORMY16_OPERAND_BCOND5 :
01160       fields->f_op5 = value;
01161       break;
01162     case XSTORMY16_OPERAND_HMEM8 :
01163       fields->f_hmem8 = value;
01164       break;
01165     case XSTORMY16_OPERAND_IMM12 :
01166       fields->f_imm12 = value;
01167       break;
01168     case XSTORMY16_OPERAND_IMM16 :
01169       fields->f_imm16 = value;
01170       break;
01171     case XSTORMY16_OPERAND_IMM2 :
01172       fields->f_imm2 = value;
01173       break;
01174     case XSTORMY16_OPERAND_IMM3 :
01175       fields->f_imm3 = value;
01176       break;
01177     case XSTORMY16_OPERAND_IMM3B :
01178       fields->f_imm3b = value;
01179       break;
01180     case XSTORMY16_OPERAND_IMM4 :
01181       fields->f_imm4 = value;
01182       break;
01183     case XSTORMY16_OPERAND_IMM8 :
01184       fields->f_imm8 = value;
01185       break;
01186     case XSTORMY16_OPERAND_IMM8SMALL :
01187       fields->f_imm8 = value;
01188       break;
01189     case XSTORMY16_OPERAND_LMEM8 :
01190       fields->f_lmem8 = value;
01191       break;
01192     case XSTORMY16_OPERAND_REL12 :
01193       fields->f_rel12 = value;
01194       break;
01195     case XSTORMY16_OPERAND_REL12A :
01196       fields->f_rel12a = value;
01197       break;
01198     case XSTORMY16_OPERAND_REL8_2 :
01199       fields->f_rel8_2 = value;
01200       break;
01201     case XSTORMY16_OPERAND_REL8_4 :
01202       fields->f_rel8_4 = value;
01203       break;
01204     case XSTORMY16_OPERAND_WS2 :
01205       fields->f_op2m = value;
01206       break;
01207 
01208     default :
01209       /* xgettext:c-format */
01210       fprintf (stderr, _("Unrecognized field %d while setting vma operand.\n"),
01211                      opindex);
01212       abort ();
01213   }
01214 }
01215 
01216 /* Function to call before using the instruction builder tables.  */
01217 
01218 void
01219 xstormy16_cgen_init_ibld_table (CGEN_CPU_DESC cd)
01220 {
01221   cd->insert_handlers = & xstormy16_cgen_insert_handlers[0];
01222   cd->extract_handlers = & xstormy16_cgen_extract_handlers[0];
01223 
01224   cd->insert_operand = xstormy16_cgen_insert_operand;
01225   cd->extract_operand = xstormy16_cgen_extract_operand;
01226 
01227   cd->get_int_operand = xstormy16_cgen_get_int_operand;
01228   cd->set_int_operand = xstormy16_cgen_set_int_operand;
01229   cd->get_vma_operand = xstormy16_cgen_get_vma_operand;
01230   cd->set_vma_operand = xstormy16_cgen_set_vma_operand;
01231 }