Back to index

cell-binutils  2.17cvs20070401
iq2000-ibld.c
Go to the documentation of this file.
00001 /* Instruction building/extraction support for iq2000. -*- 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 "iq2000-desc.h"
00035 #include "iq2000-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 * iq2000_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 iq2000_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 IQ2000_OPERAND__INDEX :
00569       errmsg = insert_normal (cd, fields->f_index, 0, 0, 8, 9, 32, total_length, buffer);
00570       break;
00571     case IQ2000_OPERAND_BASE :
00572       errmsg = insert_normal (cd, fields->f_rs, 0, 0, 25, 5, 32, total_length, buffer);
00573       break;
00574     case IQ2000_OPERAND_BASEOFF :
00575       errmsg = insert_normal (cd, fields->f_imm, 0, 0, 15, 16, 32, total_length, buffer);
00576       break;
00577     case IQ2000_OPERAND_BITNUM :
00578       errmsg = insert_normal (cd, fields->f_rt, 0, 0, 20, 5, 32, total_length, buffer);
00579       break;
00580     case IQ2000_OPERAND_BYTECOUNT :
00581       errmsg = insert_normal (cd, fields->f_bytecount, 0, 0, 7, 8, 32, total_length, buffer);
00582       break;
00583     case IQ2000_OPERAND_CAM_Y :
00584       errmsg = insert_normal (cd, fields->f_cam_y, 0, 0, 2, 3, 32, total_length, buffer);
00585       break;
00586     case IQ2000_OPERAND_CAM_Z :
00587       errmsg = insert_normal (cd, fields->f_cam_z, 0, 0, 5, 3, 32, total_length, buffer);
00588       break;
00589     case IQ2000_OPERAND_CM_3FUNC :
00590       errmsg = insert_normal (cd, fields->f_cm_3func, 0, 0, 5, 3, 32, total_length, buffer);
00591       break;
00592     case IQ2000_OPERAND_CM_3Z :
00593       errmsg = insert_normal (cd, fields->f_cm_3z, 0, 0, 1, 2, 32, total_length, buffer);
00594       break;
00595     case IQ2000_OPERAND_CM_4FUNC :
00596       errmsg = insert_normal (cd, fields->f_cm_4func, 0, 0, 5, 4, 32, total_length, buffer);
00597       break;
00598     case IQ2000_OPERAND_CM_4Z :
00599       errmsg = insert_normal (cd, fields->f_cm_4z, 0, 0, 2, 3, 32, total_length, buffer);
00600       break;
00601     case IQ2000_OPERAND_COUNT :
00602       errmsg = insert_normal (cd, fields->f_count, 0, 0, 15, 7, 32, total_length, buffer);
00603       break;
00604     case IQ2000_OPERAND_EXECODE :
00605       errmsg = insert_normal (cd, fields->f_excode, 0, 0, 25, 20, 32, total_length, buffer);
00606       break;
00607     case IQ2000_OPERAND_HI16 :
00608       errmsg = insert_normal (cd, fields->f_imm, 0, 0, 15, 16, 32, total_length, buffer);
00609       break;
00610     case IQ2000_OPERAND_IMM :
00611       errmsg = insert_normal (cd, fields->f_imm, 0, 0, 15, 16, 32, total_length, buffer);
00612       break;
00613     case IQ2000_OPERAND_JMPTARG :
00614       {
00615         long value = fields->f_jtarg;
00616         value = ((unsigned int) (((value) & (262143))) >> (2));
00617         errmsg = insert_normal (cd, value, 0|(1<<CGEN_IFLD_ABS_ADDR), 0, 15, 16, 32, total_length, buffer);
00618       }
00619       break;
00620     case IQ2000_OPERAND_JMPTARGQ10 :
00621       {
00622         long value = fields->f_jtargq10;
00623         value = ((unsigned int) (((value) & (8388607))) >> (2));
00624         errmsg = insert_normal (cd, value, 0|(1<<CGEN_IFLD_ABS_ADDR), 0, 20, 21, 32, total_length, buffer);
00625       }
00626       break;
00627     case IQ2000_OPERAND_LO16 :
00628       errmsg = insert_normal (cd, fields->f_imm, 0, 0, 15, 16, 32, total_length, buffer);
00629       break;
00630     case IQ2000_OPERAND_MASK :
00631       errmsg = insert_normal (cd, fields->f_mask, 0, 0, 9, 4, 32, total_length, buffer);
00632       break;
00633     case IQ2000_OPERAND_MASKL :
00634       errmsg = insert_normal (cd, fields->f_maskl, 0, 0, 4, 5, 32, total_length, buffer);
00635       break;
00636     case IQ2000_OPERAND_MASKQ10 :
00637       errmsg = insert_normal (cd, fields->f_maskq10, 0, 0, 10, 5, 32, total_length, buffer);
00638       break;
00639     case IQ2000_OPERAND_MASKR :
00640       errmsg = insert_normal (cd, fields->f_rs, 0, 0, 25, 5, 32, total_length, buffer);
00641       break;
00642     case IQ2000_OPERAND_MLO16 :
00643       errmsg = insert_normal (cd, fields->f_imm, 0, 0, 15, 16, 32, total_length, buffer);
00644       break;
00645     case IQ2000_OPERAND_OFFSET :
00646       {
00647         long value = fields->f_offset;
00648         value = ((int) (((value) - (pc))) >> (2));
00649         errmsg = insert_normal (cd, value, 0|(1<<CGEN_IFLD_SIGNED)|(1<<CGEN_IFLD_PCREL_ADDR), 0, 15, 16, 32, total_length, buffer);
00650       }
00651       break;
00652     case IQ2000_OPERAND_RD :
00653       errmsg = insert_normal (cd, fields->f_rd, 0, 0, 15, 5, 32, total_length, buffer);
00654       break;
00655     case IQ2000_OPERAND_RD_RS :
00656       {
00657 {
00658   FLD (f_rd) = FLD (f_rd_rs);
00659   FLD (f_rs) = FLD (f_rd_rs);
00660 }
00661         errmsg = insert_normal (cd, fields->f_rd, 0, 0, 15, 5, 32, total_length, buffer);
00662         if (errmsg)
00663           break;
00664         errmsg = insert_normal (cd, fields->f_rs, 0, 0, 25, 5, 32, total_length, buffer);
00665         if (errmsg)
00666           break;
00667       }
00668       break;
00669     case IQ2000_OPERAND_RD_RT :
00670       {
00671 {
00672   FLD (f_rd) = FLD (f_rd_rt);
00673   FLD (f_rt) = FLD (f_rd_rt);
00674 }
00675         errmsg = insert_normal (cd, fields->f_rd, 0, 0, 15, 5, 32, total_length, buffer);
00676         if (errmsg)
00677           break;
00678         errmsg = insert_normal (cd, fields->f_rt, 0, 0, 20, 5, 32, total_length, buffer);
00679         if (errmsg)
00680           break;
00681       }
00682       break;
00683     case IQ2000_OPERAND_RS :
00684       errmsg = insert_normal (cd, fields->f_rs, 0, 0, 25, 5, 32, total_length, buffer);
00685       break;
00686     case IQ2000_OPERAND_RT :
00687       errmsg = insert_normal (cd, fields->f_rt, 0, 0, 20, 5, 32, total_length, buffer);
00688       break;
00689     case IQ2000_OPERAND_RT_RS :
00690       {
00691 {
00692   FLD (f_rt) = FLD (f_rt_rs);
00693   FLD (f_rs) = FLD (f_rt_rs);
00694 }
00695         errmsg = insert_normal (cd, fields->f_rt, 0, 0, 20, 5, 32, total_length, buffer);
00696         if (errmsg)
00697           break;
00698         errmsg = insert_normal (cd, fields->f_rs, 0, 0, 25, 5, 32, total_length, buffer);
00699         if (errmsg)
00700           break;
00701       }
00702       break;
00703     case IQ2000_OPERAND_SHAMT :
00704       errmsg = insert_normal (cd, fields->f_shamt, 0, 0, 10, 5, 32, total_length, buffer);
00705       break;
00706 
00707     default :
00708       /* xgettext:c-format */
00709       fprintf (stderr, _("Unrecognized field %d while building insn.\n"),
00710               opindex);
00711       abort ();
00712   }
00713 
00714   return errmsg;
00715 }
00716 
00717 int iq2000_cgen_extract_operand
00718   (CGEN_CPU_DESC, int, CGEN_EXTRACT_INFO *, CGEN_INSN_INT, CGEN_FIELDS *, bfd_vma);
00719 
00720 /* Main entry point for operand extraction.
00721    The result is <= 0 for error, >0 for success.
00722    ??? Actual values aren't well defined right now.
00723 
00724    This function is basically just a big switch statement.  Earlier versions
00725    used tables to look up the function to use, but
00726    - if the table contains both assembler and disassembler functions then
00727      the disassembler contains much of the assembler and vice-versa,
00728    - there's a lot of inlining possibilities as things grow,
00729    - using a switch statement avoids the function call overhead.
00730 
00731    This function could be moved into `print_insn_normal', but keeping it
00732    separate makes clear the interface between `print_insn_normal' and each of
00733    the handlers.  */
00734 
00735 int
00736 iq2000_cgen_extract_operand (CGEN_CPU_DESC cd,
00737                           int opindex,
00738                           CGEN_EXTRACT_INFO *ex_info,
00739                           CGEN_INSN_INT insn_value,
00740                           CGEN_FIELDS * fields,
00741                           bfd_vma pc)
00742 {
00743   /* Assume success (for those operands that are nops).  */
00744   int length = 1;
00745   unsigned int total_length = CGEN_FIELDS_BITSIZE (fields);
00746 
00747   switch (opindex)
00748     {
00749     case IQ2000_OPERAND__INDEX :
00750       length = extract_normal (cd, ex_info, insn_value, 0, 0, 8, 9, 32, total_length, pc, & fields->f_index);
00751       break;
00752     case IQ2000_OPERAND_BASE :
00753       length = extract_normal (cd, ex_info, insn_value, 0, 0, 25, 5, 32, total_length, pc, & fields->f_rs);
00754       break;
00755     case IQ2000_OPERAND_BASEOFF :
00756       length = extract_normal (cd, ex_info, insn_value, 0, 0, 15, 16, 32, total_length, pc, & fields->f_imm);
00757       break;
00758     case IQ2000_OPERAND_BITNUM :
00759       length = extract_normal (cd, ex_info, insn_value, 0, 0, 20, 5, 32, total_length, pc, & fields->f_rt);
00760       break;
00761     case IQ2000_OPERAND_BYTECOUNT :
00762       length = extract_normal (cd, ex_info, insn_value, 0, 0, 7, 8, 32, total_length, pc, & fields->f_bytecount);
00763       break;
00764     case IQ2000_OPERAND_CAM_Y :
00765       length = extract_normal (cd, ex_info, insn_value, 0, 0, 2, 3, 32, total_length, pc, & fields->f_cam_y);
00766       break;
00767     case IQ2000_OPERAND_CAM_Z :
00768       length = extract_normal (cd, ex_info, insn_value, 0, 0, 5, 3, 32, total_length, pc, & fields->f_cam_z);
00769       break;
00770     case IQ2000_OPERAND_CM_3FUNC :
00771       length = extract_normal (cd, ex_info, insn_value, 0, 0, 5, 3, 32, total_length, pc, & fields->f_cm_3func);
00772       break;
00773     case IQ2000_OPERAND_CM_3Z :
00774       length = extract_normal (cd, ex_info, insn_value, 0, 0, 1, 2, 32, total_length, pc, & fields->f_cm_3z);
00775       break;
00776     case IQ2000_OPERAND_CM_4FUNC :
00777       length = extract_normal (cd, ex_info, insn_value, 0, 0, 5, 4, 32, total_length, pc, & fields->f_cm_4func);
00778       break;
00779     case IQ2000_OPERAND_CM_4Z :
00780       length = extract_normal (cd, ex_info, insn_value, 0, 0, 2, 3, 32, total_length, pc, & fields->f_cm_4z);
00781       break;
00782     case IQ2000_OPERAND_COUNT :
00783       length = extract_normal (cd, ex_info, insn_value, 0, 0, 15, 7, 32, total_length, pc, & fields->f_count);
00784       break;
00785     case IQ2000_OPERAND_EXECODE :
00786       length = extract_normal (cd, ex_info, insn_value, 0, 0, 25, 20, 32, total_length, pc, & fields->f_excode);
00787       break;
00788     case IQ2000_OPERAND_HI16 :
00789       length = extract_normal (cd, ex_info, insn_value, 0, 0, 15, 16, 32, total_length, pc, & fields->f_imm);
00790       break;
00791     case IQ2000_OPERAND_IMM :
00792       length = extract_normal (cd, ex_info, insn_value, 0, 0, 15, 16, 32, total_length, pc, & fields->f_imm);
00793       break;
00794     case IQ2000_OPERAND_JMPTARG :
00795       {
00796         long value;
00797         length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_ABS_ADDR), 0, 15, 16, 32, total_length, pc, & value);
00798         value = ((((pc) & (0xf0000000))) | (((value) << (2))));
00799         fields->f_jtarg = value;
00800       }
00801       break;
00802     case IQ2000_OPERAND_JMPTARGQ10 :
00803       {
00804         long value;
00805         length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_ABS_ADDR), 0, 20, 21, 32, total_length, pc, & value);
00806         value = ((((pc) & (0xf0000000))) | (((value) << (2))));
00807         fields->f_jtargq10 = value;
00808       }
00809       break;
00810     case IQ2000_OPERAND_LO16 :
00811       length = extract_normal (cd, ex_info, insn_value, 0, 0, 15, 16, 32, total_length, pc, & fields->f_imm);
00812       break;
00813     case IQ2000_OPERAND_MASK :
00814       length = extract_normal (cd, ex_info, insn_value, 0, 0, 9, 4, 32, total_length, pc, & fields->f_mask);
00815       break;
00816     case IQ2000_OPERAND_MASKL :
00817       length = extract_normal (cd, ex_info, insn_value, 0, 0, 4, 5, 32, total_length, pc, & fields->f_maskl);
00818       break;
00819     case IQ2000_OPERAND_MASKQ10 :
00820       length = extract_normal (cd, ex_info, insn_value, 0, 0, 10, 5, 32, total_length, pc, & fields->f_maskq10);
00821       break;
00822     case IQ2000_OPERAND_MASKR :
00823       length = extract_normal (cd, ex_info, insn_value, 0, 0, 25, 5, 32, total_length, pc, & fields->f_rs);
00824       break;
00825     case IQ2000_OPERAND_MLO16 :
00826       length = extract_normal (cd, ex_info, insn_value, 0, 0, 15, 16, 32, total_length, pc, & fields->f_imm);
00827       break;
00828     case IQ2000_OPERAND_OFFSET :
00829       {
00830         long value;
00831         length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_SIGNED)|(1<<CGEN_IFLD_PCREL_ADDR), 0, 15, 16, 32, total_length, pc, & value);
00832         value = ((((value) << (2))) + (((pc) + (4))));
00833         fields->f_offset = value;
00834       }
00835       break;
00836     case IQ2000_OPERAND_RD :
00837       length = extract_normal (cd, ex_info, insn_value, 0, 0, 15, 5, 32, total_length, pc, & fields->f_rd);
00838       break;
00839     case IQ2000_OPERAND_RD_RS :
00840       {
00841         length = extract_normal (cd, ex_info, insn_value, 0, 0, 15, 5, 32, total_length, pc, & fields->f_rd);
00842         if (length <= 0) break;
00843         length = extract_normal (cd, ex_info, insn_value, 0, 0, 25, 5, 32, total_length, pc, & fields->f_rs);
00844         if (length <= 0) break;
00845 {
00846   FLD (f_rd_rs) = FLD (f_rs);
00847 }
00848       }
00849       break;
00850     case IQ2000_OPERAND_RD_RT :
00851       {
00852         length = extract_normal (cd, ex_info, insn_value, 0, 0, 15, 5, 32, total_length, pc, & fields->f_rd);
00853         if (length <= 0) break;
00854         length = extract_normal (cd, ex_info, insn_value, 0, 0, 20, 5, 32, total_length, pc, & fields->f_rt);
00855         if (length <= 0) break;
00856 {
00857   FLD (f_rd_rt) = FLD (f_rt);
00858 }
00859       }
00860       break;
00861     case IQ2000_OPERAND_RS :
00862       length = extract_normal (cd, ex_info, insn_value, 0, 0, 25, 5, 32, total_length, pc, & fields->f_rs);
00863       break;
00864     case IQ2000_OPERAND_RT :
00865       length = extract_normal (cd, ex_info, insn_value, 0, 0, 20, 5, 32, total_length, pc, & fields->f_rt);
00866       break;
00867     case IQ2000_OPERAND_RT_RS :
00868       {
00869         length = extract_normal (cd, ex_info, insn_value, 0, 0, 20, 5, 32, total_length, pc, & fields->f_rt);
00870         if (length <= 0) break;
00871         length = extract_normal (cd, ex_info, insn_value, 0, 0, 25, 5, 32, total_length, pc, & fields->f_rs);
00872         if (length <= 0) break;
00873 {
00874   FLD (f_rd_rs) = FLD (f_rs);
00875 }
00876       }
00877       break;
00878     case IQ2000_OPERAND_SHAMT :
00879       length = extract_normal (cd, ex_info, insn_value, 0, 0, 10, 5, 32, total_length, pc, & fields->f_shamt);
00880       break;
00881 
00882     default :
00883       /* xgettext:c-format */
00884       fprintf (stderr, _("Unrecognized field %d while decoding insn.\n"),
00885               opindex);
00886       abort ();
00887     }
00888 
00889   return length;
00890 }
00891 
00892 cgen_insert_fn * const iq2000_cgen_insert_handlers[] = 
00893 {
00894   insert_insn_normal,
00895 };
00896 
00897 cgen_extract_fn * const iq2000_cgen_extract_handlers[] = 
00898 {
00899   extract_insn_normal,
00900 };
00901 
00902 int iq2000_cgen_get_int_operand     (CGEN_CPU_DESC, int, const CGEN_FIELDS *);
00903 bfd_vma iq2000_cgen_get_vma_operand (CGEN_CPU_DESC, int, const CGEN_FIELDS *);
00904 
00905 /* Getting values from cgen_fields is handled by a collection of functions.
00906    They are distinguished by the type of the VALUE argument they return.
00907    TODO: floating point, inlining support, remove cases where result type
00908    not appropriate.  */
00909 
00910 int
00911 iq2000_cgen_get_int_operand (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
00912                           int opindex,
00913                           const CGEN_FIELDS * fields)
00914 {
00915   int value;
00916 
00917   switch (opindex)
00918     {
00919     case IQ2000_OPERAND__INDEX :
00920       value = fields->f_index;
00921       break;
00922     case IQ2000_OPERAND_BASE :
00923       value = fields->f_rs;
00924       break;
00925     case IQ2000_OPERAND_BASEOFF :
00926       value = fields->f_imm;
00927       break;
00928     case IQ2000_OPERAND_BITNUM :
00929       value = fields->f_rt;
00930       break;
00931     case IQ2000_OPERAND_BYTECOUNT :
00932       value = fields->f_bytecount;
00933       break;
00934     case IQ2000_OPERAND_CAM_Y :
00935       value = fields->f_cam_y;
00936       break;
00937     case IQ2000_OPERAND_CAM_Z :
00938       value = fields->f_cam_z;
00939       break;
00940     case IQ2000_OPERAND_CM_3FUNC :
00941       value = fields->f_cm_3func;
00942       break;
00943     case IQ2000_OPERAND_CM_3Z :
00944       value = fields->f_cm_3z;
00945       break;
00946     case IQ2000_OPERAND_CM_4FUNC :
00947       value = fields->f_cm_4func;
00948       break;
00949     case IQ2000_OPERAND_CM_4Z :
00950       value = fields->f_cm_4z;
00951       break;
00952     case IQ2000_OPERAND_COUNT :
00953       value = fields->f_count;
00954       break;
00955     case IQ2000_OPERAND_EXECODE :
00956       value = fields->f_excode;
00957       break;
00958     case IQ2000_OPERAND_HI16 :
00959       value = fields->f_imm;
00960       break;
00961     case IQ2000_OPERAND_IMM :
00962       value = fields->f_imm;
00963       break;
00964     case IQ2000_OPERAND_JMPTARG :
00965       value = fields->f_jtarg;
00966       break;
00967     case IQ2000_OPERAND_JMPTARGQ10 :
00968       value = fields->f_jtargq10;
00969       break;
00970     case IQ2000_OPERAND_LO16 :
00971       value = fields->f_imm;
00972       break;
00973     case IQ2000_OPERAND_MASK :
00974       value = fields->f_mask;
00975       break;
00976     case IQ2000_OPERAND_MASKL :
00977       value = fields->f_maskl;
00978       break;
00979     case IQ2000_OPERAND_MASKQ10 :
00980       value = fields->f_maskq10;
00981       break;
00982     case IQ2000_OPERAND_MASKR :
00983       value = fields->f_rs;
00984       break;
00985     case IQ2000_OPERAND_MLO16 :
00986       value = fields->f_imm;
00987       break;
00988     case IQ2000_OPERAND_OFFSET :
00989       value = fields->f_offset;
00990       break;
00991     case IQ2000_OPERAND_RD :
00992       value = fields->f_rd;
00993       break;
00994     case IQ2000_OPERAND_RD_RS :
00995       value = fields->f_rd_rs;
00996       break;
00997     case IQ2000_OPERAND_RD_RT :
00998       value = fields->f_rd_rt;
00999       break;
01000     case IQ2000_OPERAND_RS :
01001       value = fields->f_rs;
01002       break;
01003     case IQ2000_OPERAND_RT :
01004       value = fields->f_rt;
01005       break;
01006     case IQ2000_OPERAND_RT_RS :
01007       value = fields->f_rt_rs;
01008       break;
01009     case IQ2000_OPERAND_SHAMT :
01010       value = fields->f_shamt;
01011       break;
01012 
01013     default :
01014       /* xgettext:c-format */
01015       fprintf (stderr, _("Unrecognized field %d while getting int operand.\n"),
01016                      opindex);
01017       abort ();
01018   }
01019 
01020   return value;
01021 }
01022 
01023 bfd_vma
01024 iq2000_cgen_get_vma_operand (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
01025                           int opindex,
01026                           const CGEN_FIELDS * fields)
01027 {
01028   bfd_vma value;
01029 
01030   switch (opindex)
01031     {
01032     case IQ2000_OPERAND__INDEX :
01033       value = fields->f_index;
01034       break;
01035     case IQ2000_OPERAND_BASE :
01036       value = fields->f_rs;
01037       break;
01038     case IQ2000_OPERAND_BASEOFF :
01039       value = fields->f_imm;
01040       break;
01041     case IQ2000_OPERAND_BITNUM :
01042       value = fields->f_rt;
01043       break;
01044     case IQ2000_OPERAND_BYTECOUNT :
01045       value = fields->f_bytecount;
01046       break;
01047     case IQ2000_OPERAND_CAM_Y :
01048       value = fields->f_cam_y;
01049       break;
01050     case IQ2000_OPERAND_CAM_Z :
01051       value = fields->f_cam_z;
01052       break;
01053     case IQ2000_OPERAND_CM_3FUNC :
01054       value = fields->f_cm_3func;
01055       break;
01056     case IQ2000_OPERAND_CM_3Z :
01057       value = fields->f_cm_3z;
01058       break;
01059     case IQ2000_OPERAND_CM_4FUNC :
01060       value = fields->f_cm_4func;
01061       break;
01062     case IQ2000_OPERAND_CM_4Z :
01063       value = fields->f_cm_4z;
01064       break;
01065     case IQ2000_OPERAND_COUNT :
01066       value = fields->f_count;
01067       break;
01068     case IQ2000_OPERAND_EXECODE :
01069       value = fields->f_excode;
01070       break;
01071     case IQ2000_OPERAND_HI16 :
01072       value = fields->f_imm;
01073       break;
01074     case IQ2000_OPERAND_IMM :
01075       value = fields->f_imm;
01076       break;
01077     case IQ2000_OPERAND_JMPTARG :
01078       value = fields->f_jtarg;
01079       break;
01080     case IQ2000_OPERAND_JMPTARGQ10 :
01081       value = fields->f_jtargq10;
01082       break;
01083     case IQ2000_OPERAND_LO16 :
01084       value = fields->f_imm;
01085       break;
01086     case IQ2000_OPERAND_MASK :
01087       value = fields->f_mask;
01088       break;
01089     case IQ2000_OPERAND_MASKL :
01090       value = fields->f_maskl;
01091       break;
01092     case IQ2000_OPERAND_MASKQ10 :
01093       value = fields->f_maskq10;
01094       break;
01095     case IQ2000_OPERAND_MASKR :
01096       value = fields->f_rs;
01097       break;
01098     case IQ2000_OPERAND_MLO16 :
01099       value = fields->f_imm;
01100       break;
01101     case IQ2000_OPERAND_OFFSET :
01102       value = fields->f_offset;
01103       break;
01104     case IQ2000_OPERAND_RD :
01105       value = fields->f_rd;
01106       break;
01107     case IQ2000_OPERAND_RD_RS :
01108       value = fields->f_rd_rs;
01109       break;
01110     case IQ2000_OPERAND_RD_RT :
01111       value = fields->f_rd_rt;
01112       break;
01113     case IQ2000_OPERAND_RS :
01114       value = fields->f_rs;
01115       break;
01116     case IQ2000_OPERAND_RT :
01117       value = fields->f_rt;
01118       break;
01119     case IQ2000_OPERAND_RT_RS :
01120       value = fields->f_rt_rs;
01121       break;
01122     case IQ2000_OPERAND_SHAMT :
01123       value = fields->f_shamt;
01124       break;
01125 
01126     default :
01127       /* xgettext:c-format */
01128       fprintf (stderr, _("Unrecognized field %d while getting vma operand.\n"),
01129                      opindex);
01130       abort ();
01131   }
01132 
01133   return value;
01134 }
01135 
01136 void iq2000_cgen_set_int_operand  (CGEN_CPU_DESC, int, CGEN_FIELDS *, int);
01137 void iq2000_cgen_set_vma_operand  (CGEN_CPU_DESC, int, CGEN_FIELDS *, bfd_vma);
01138 
01139 /* Stuffing values in cgen_fields is handled by a collection of functions.
01140    They are distinguished by the type of the VALUE argument they accept.
01141    TODO: floating point, inlining support, remove cases where argument type
01142    not appropriate.  */
01143 
01144 void
01145 iq2000_cgen_set_int_operand (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
01146                           int opindex,
01147                           CGEN_FIELDS * fields,
01148                           int value)
01149 {
01150   switch (opindex)
01151     {
01152     case IQ2000_OPERAND__INDEX :
01153       fields->f_index = value;
01154       break;
01155     case IQ2000_OPERAND_BASE :
01156       fields->f_rs = value;
01157       break;
01158     case IQ2000_OPERAND_BASEOFF :
01159       fields->f_imm = value;
01160       break;
01161     case IQ2000_OPERAND_BITNUM :
01162       fields->f_rt = value;
01163       break;
01164     case IQ2000_OPERAND_BYTECOUNT :
01165       fields->f_bytecount = value;
01166       break;
01167     case IQ2000_OPERAND_CAM_Y :
01168       fields->f_cam_y = value;
01169       break;
01170     case IQ2000_OPERAND_CAM_Z :
01171       fields->f_cam_z = value;
01172       break;
01173     case IQ2000_OPERAND_CM_3FUNC :
01174       fields->f_cm_3func = value;
01175       break;
01176     case IQ2000_OPERAND_CM_3Z :
01177       fields->f_cm_3z = value;
01178       break;
01179     case IQ2000_OPERAND_CM_4FUNC :
01180       fields->f_cm_4func = value;
01181       break;
01182     case IQ2000_OPERAND_CM_4Z :
01183       fields->f_cm_4z = value;
01184       break;
01185     case IQ2000_OPERAND_COUNT :
01186       fields->f_count = value;
01187       break;
01188     case IQ2000_OPERAND_EXECODE :
01189       fields->f_excode = value;
01190       break;
01191     case IQ2000_OPERAND_HI16 :
01192       fields->f_imm = value;
01193       break;
01194     case IQ2000_OPERAND_IMM :
01195       fields->f_imm = value;
01196       break;
01197     case IQ2000_OPERAND_JMPTARG :
01198       fields->f_jtarg = value;
01199       break;
01200     case IQ2000_OPERAND_JMPTARGQ10 :
01201       fields->f_jtargq10 = value;
01202       break;
01203     case IQ2000_OPERAND_LO16 :
01204       fields->f_imm = value;
01205       break;
01206     case IQ2000_OPERAND_MASK :
01207       fields->f_mask = value;
01208       break;
01209     case IQ2000_OPERAND_MASKL :
01210       fields->f_maskl = value;
01211       break;
01212     case IQ2000_OPERAND_MASKQ10 :
01213       fields->f_maskq10 = value;
01214       break;
01215     case IQ2000_OPERAND_MASKR :
01216       fields->f_rs = value;
01217       break;
01218     case IQ2000_OPERAND_MLO16 :
01219       fields->f_imm = value;
01220       break;
01221     case IQ2000_OPERAND_OFFSET :
01222       fields->f_offset = value;
01223       break;
01224     case IQ2000_OPERAND_RD :
01225       fields->f_rd = value;
01226       break;
01227     case IQ2000_OPERAND_RD_RS :
01228       fields->f_rd_rs = value;
01229       break;
01230     case IQ2000_OPERAND_RD_RT :
01231       fields->f_rd_rt = value;
01232       break;
01233     case IQ2000_OPERAND_RS :
01234       fields->f_rs = value;
01235       break;
01236     case IQ2000_OPERAND_RT :
01237       fields->f_rt = value;
01238       break;
01239     case IQ2000_OPERAND_RT_RS :
01240       fields->f_rt_rs = value;
01241       break;
01242     case IQ2000_OPERAND_SHAMT :
01243       fields->f_shamt = value;
01244       break;
01245 
01246     default :
01247       /* xgettext:c-format */
01248       fprintf (stderr, _("Unrecognized field %d while setting int operand.\n"),
01249                      opindex);
01250       abort ();
01251   }
01252 }
01253 
01254 void
01255 iq2000_cgen_set_vma_operand (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
01256                           int opindex,
01257                           CGEN_FIELDS * fields,
01258                           bfd_vma value)
01259 {
01260   switch (opindex)
01261     {
01262     case IQ2000_OPERAND__INDEX :
01263       fields->f_index = value;
01264       break;
01265     case IQ2000_OPERAND_BASE :
01266       fields->f_rs = value;
01267       break;
01268     case IQ2000_OPERAND_BASEOFF :
01269       fields->f_imm = value;
01270       break;
01271     case IQ2000_OPERAND_BITNUM :
01272       fields->f_rt = value;
01273       break;
01274     case IQ2000_OPERAND_BYTECOUNT :
01275       fields->f_bytecount = value;
01276       break;
01277     case IQ2000_OPERAND_CAM_Y :
01278       fields->f_cam_y = value;
01279       break;
01280     case IQ2000_OPERAND_CAM_Z :
01281       fields->f_cam_z = value;
01282       break;
01283     case IQ2000_OPERAND_CM_3FUNC :
01284       fields->f_cm_3func = value;
01285       break;
01286     case IQ2000_OPERAND_CM_3Z :
01287       fields->f_cm_3z = value;
01288       break;
01289     case IQ2000_OPERAND_CM_4FUNC :
01290       fields->f_cm_4func = value;
01291       break;
01292     case IQ2000_OPERAND_CM_4Z :
01293       fields->f_cm_4z = value;
01294       break;
01295     case IQ2000_OPERAND_COUNT :
01296       fields->f_count = value;
01297       break;
01298     case IQ2000_OPERAND_EXECODE :
01299       fields->f_excode = value;
01300       break;
01301     case IQ2000_OPERAND_HI16 :
01302       fields->f_imm = value;
01303       break;
01304     case IQ2000_OPERAND_IMM :
01305       fields->f_imm = value;
01306       break;
01307     case IQ2000_OPERAND_JMPTARG :
01308       fields->f_jtarg = value;
01309       break;
01310     case IQ2000_OPERAND_JMPTARGQ10 :
01311       fields->f_jtargq10 = value;
01312       break;
01313     case IQ2000_OPERAND_LO16 :
01314       fields->f_imm = value;
01315       break;
01316     case IQ2000_OPERAND_MASK :
01317       fields->f_mask = value;
01318       break;
01319     case IQ2000_OPERAND_MASKL :
01320       fields->f_maskl = value;
01321       break;
01322     case IQ2000_OPERAND_MASKQ10 :
01323       fields->f_maskq10 = value;
01324       break;
01325     case IQ2000_OPERAND_MASKR :
01326       fields->f_rs = value;
01327       break;
01328     case IQ2000_OPERAND_MLO16 :
01329       fields->f_imm = value;
01330       break;
01331     case IQ2000_OPERAND_OFFSET :
01332       fields->f_offset = value;
01333       break;
01334     case IQ2000_OPERAND_RD :
01335       fields->f_rd = value;
01336       break;
01337     case IQ2000_OPERAND_RD_RS :
01338       fields->f_rd_rs = value;
01339       break;
01340     case IQ2000_OPERAND_RD_RT :
01341       fields->f_rd_rt = value;
01342       break;
01343     case IQ2000_OPERAND_RS :
01344       fields->f_rs = value;
01345       break;
01346     case IQ2000_OPERAND_RT :
01347       fields->f_rt = value;
01348       break;
01349     case IQ2000_OPERAND_RT_RS :
01350       fields->f_rt_rs = value;
01351       break;
01352     case IQ2000_OPERAND_SHAMT :
01353       fields->f_shamt = value;
01354       break;
01355 
01356     default :
01357       /* xgettext:c-format */
01358       fprintf (stderr, _("Unrecognized field %d while setting vma operand.\n"),
01359                      opindex);
01360       abort ();
01361   }
01362 }
01363 
01364 /* Function to call before using the instruction builder tables.  */
01365 
01366 void
01367 iq2000_cgen_init_ibld_table (CGEN_CPU_DESC cd)
01368 {
01369   cd->insert_handlers = & iq2000_cgen_insert_handlers[0];
01370   cd->extract_handlers = & iq2000_cgen_extract_handlers[0];
01371 
01372   cd->insert_operand = iq2000_cgen_insert_operand;
01373   cd->extract_operand = iq2000_cgen_extract_operand;
01374 
01375   cd->get_int_operand = iq2000_cgen_get_int_operand;
01376   cd->set_int_operand = iq2000_cgen_set_int_operand;
01377   cd->get_vma_operand = iq2000_cgen_get_vma_operand;
01378   cd->set_vma_operand = iq2000_cgen_set_vma_operand;
01379 }