Back to index

cell-binutils  2.17cvs20070401
mt-ibld.c
Go to the documentation of this file.
00001 /* Instruction building/extraction support for mt. -*- 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 "mt-desc.h"
00035 #include "mt-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 * mt_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 mt_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 MT_OPERAND_A23 :
00569       errmsg = insert_normal (cd, fields->f_a23, 0, 0, 23, 1, 32, total_length, buffer);
00570       break;
00571     case MT_OPERAND_BALL :
00572       errmsg = insert_normal (cd, fields->f_ball, 0, 0, 19, 1, 32, total_length, buffer);
00573       break;
00574     case MT_OPERAND_BALL2 :
00575       errmsg = insert_normal (cd, fields->f_ball2, 0, 0, 15, 1, 32, total_length, buffer);
00576       break;
00577     case MT_OPERAND_BANKADDR :
00578       errmsg = insert_normal (cd, fields->f_bankaddr, 0, 0, 25, 13, 32, total_length, buffer);
00579       break;
00580     case MT_OPERAND_BRC :
00581       errmsg = insert_normal (cd, fields->f_brc, 0, 0, 18, 3, 32, total_length, buffer);
00582       break;
00583     case MT_OPERAND_BRC2 :
00584       errmsg = insert_normal (cd, fields->f_brc2, 0, 0, 14, 3, 32, total_length, buffer);
00585       break;
00586     case MT_OPERAND_CB1INCR :
00587       errmsg = insert_normal (cd, fields->f_cb1incr, 0|(1<<CGEN_IFLD_SIGNED), 0, 19, 6, 32, total_length, buffer);
00588       break;
00589     case MT_OPERAND_CB1SEL :
00590       errmsg = insert_normal (cd, fields->f_cb1sel, 0, 0, 25, 3, 32, total_length, buffer);
00591       break;
00592     case MT_OPERAND_CB2INCR :
00593       errmsg = insert_normal (cd, fields->f_cb2incr, 0|(1<<CGEN_IFLD_SIGNED), 0, 13, 6, 32, total_length, buffer);
00594       break;
00595     case MT_OPERAND_CB2SEL :
00596       errmsg = insert_normal (cd, fields->f_cb2sel, 0, 0, 22, 3, 32, total_length, buffer);
00597       break;
00598     case MT_OPERAND_CBRB :
00599       errmsg = insert_normal (cd, fields->f_cbrb, 0, 0, 10, 1, 32, total_length, buffer);
00600       break;
00601     case MT_OPERAND_CBS :
00602       errmsg = insert_normal (cd, fields->f_cbs, 0, 0, 19, 2, 32, total_length, buffer);
00603       break;
00604     case MT_OPERAND_CBX :
00605       errmsg = insert_normal (cd, fields->f_cbx, 0, 0, 14, 3, 32, total_length, buffer);
00606       break;
00607     case MT_OPERAND_CCB :
00608       errmsg = insert_normal (cd, fields->f_ccb, 0, 0, 11, 1, 32, total_length, buffer);
00609       break;
00610     case MT_OPERAND_CDB :
00611       errmsg = insert_normal (cd, fields->f_cdb, 0, 0, 10, 1, 32, total_length, buffer);
00612       break;
00613     case MT_OPERAND_CELL :
00614       errmsg = insert_normal (cd, fields->f_cell, 0, 0, 9, 3, 32, total_length, buffer);
00615       break;
00616     case MT_OPERAND_COLNUM :
00617       errmsg = insert_normal (cd, fields->f_colnum, 0, 0, 18, 3, 32, total_length, buffer);
00618       break;
00619     case MT_OPERAND_CONTNUM :
00620       errmsg = insert_normal (cd, fields->f_contnum, 0, 0, 8, 9, 32, total_length, buffer);
00621       break;
00622     case MT_OPERAND_CR :
00623       errmsg = insert_normal (cd, fields->f_cr, 0, 0, 22, 3, 32, total_length, buffer);
00624       break;
00625     case MT_OPERAND_CTXDISP :
00626       errmsg = insert_normal (cd, fields->f_ctxdisp, 0, 0, 5, 6, 32, total_length, buffer);
00627       break;
00628     case MT_OPERAND_DUP :
00629       errmsg = insert_normal (cd, fields->f_dup, 0, 0, 6, 1, 32, total_length, buffer);
00630       break;
00631     case MT_OPERAND_FBDISP :
00632       errmsg = insert_normal (cd, fields->f_fbdisp, 0, 0, 15, 6, 32, total_length, buffer);
00633       break;
00634     case MT_OPERAND_FBINCR :
00635       errmsg = insert_normal (cd, fields->f_fbincr, 0, 0, 23, 4, 32, total_length, buffer);
00636       break;
00637     case MT_OPERAND_FRDR :
00638       errmsg = insert_normal (cd, fields->f_dr, 0|(1<<CGEN_IFLD_ABS_ADDR), 0, 19, 4, 32, total_length, buffer);
00639       break;
00640     case MT_OPERAND_FRDRRR :
00641       errmsg = insert_normal (cd, fields->f_drrr, 0|(1<<CGEN_IFLD_ABS_ADDR), 0, 15, 4, 32, total_length, buffer);
00642       break;
00643     case MT_OPERAND_FRSR1 :
00644       errmsg = insert_normal (cd, fields->f_sr1, 0|(1<<CGEN_IFLD_ABS_ADDR), 0, 23, 4, 32, total_length, buffer);
00645       break;
00646     case MT_OPERAND_FRSR2 :
00647       errmsg = insert_normal (cd, fields->f_sr2, 0|(1<<CGEN_IFLD_ABS_ADDR), 0, 19, 4, 32, total_length, buffer);
00648       break;
00649     case MT_OPERAND_ID :
00650       errmsg = insert_normal (cd, fields->f_id, 0, 0, 14, 1, 32, total_length, buffer);
00651       break;
00652     case MT_OPERAND_IMM16 :
00653       {
00654         long value = fields->f_imm16s;
00655         value = ((value) + (0));
00656         errmsg = insert_normal (cd, value, 0|(1<<CGEN_IFLD_SIGNED), 0, 15, 16, 32, total_length, buffer);
00657       }
00658       break;
00659     case MT_OPERAND_IMM16L :
00660       errmsg = insert_normal (cd, fields->f_imm16l, 0, 0, 23, 16, 32, total_length, buffer);
00661       break;
00662     case MT_OPERAND_IMM16O :
00663       {
00664         long value = fields->f_imm16s;
00665         value = ((value) + (0));
00666         errmsg = insert_normal (cd, value, 0|(1<<CGEN_IFLD_SIGNED), 0, 15, 16, 32, total_length, buffer);
00667       }
00668       break;
00669     case MT_OPERAND_IMM16Z :
00670       errmsg = insert_normal (cd, fields->f_imm16u, 0, 0, 15, 16, 32, total_length, buffer);
00671       break;
00672     case MT_OPERAND_INCAMT :
00673       errmsg = insert_normal (cd, fields->f_incamt, 0, 0, 19, 8, 32, total_length, buffer);
00674       break;
00675     case MT_OPERAND_INCR :
00676       errmsg = insert_normal (cd, fields->f_incr, 0, 0, 17, 6, 32, total_length, buffer);
00677       break;
00678     case MT_OPERAND_LENGTH :
00679       errmsg = insert_normal (cd, fields->f_length, 0, 0, 15, 3, 32, total_length, buffer);
00680       break;
00681     case MT_OPERAND_LOOPSIZE :
00682       {
00683         long value = fields->f_loopo;
00684         value = ((unsigned int) (value) >> (2));
00685         errmsg = insert_normal (cd, value, 0, 0, 7, 8, 32, total_length, buffer);
00686       }
00687       break;
00688     case MT_OPERAND_MASK :
00689       errmsg = insert_normal (cd, fields->f_mask, 0, 0, 25, 16, 32, total_length, buffer);
00690       break;
00691     case MT_OPERAND_MASK1 :
00692       errmsg = insert_normal (cd, fields->f_mask1, 0, 0, 22, 3, 32, total_length, buffer);
00693       break;
00694     case MT_OPERAND_MODE :
00695       errmsg = insert_normal (cd, fields->f_mode, 0, 0, 25, 2, 32, total_length, buffer);
00696       break;
00697     case MT_OPERAND_PERM :
00698       errmsg = insert_normal (cd, fields->f_perm, 0, 0, 25, 2, 32, total_length, buffer);
00699       break;
00700     case MT_OPERAND_RBBC :
00701       errmsg = insert_normal (cd, fields->f_rbbc, 0, 0, 25, 2, 32, total_length, buffer);
00702       break;
00703     case MT_OPERAND_RC :
00704       errmsg = insert_normal (cd, fields->f_rc, 0, 0, 15, 1, 32, total_length, buffer);
00705       break;
00706     case MT_OPERAND_RC1 :
00707       errmsg = insert_normal (cd, fields->f_rc1, 0, 0, 11, 1, 32, total_length, buffer);
00708       break;
00709     case MT_OPERAND_RC2 :
00710       errmsg = insert_normal (cd, fields->f_rc2, 0, 0, 6, 1, 32, total_length, buffer);
00711       break;
00712     case MT_OPERAND_RC3 :
00713       errmsg = insert_normal (cd, fields->f_rc3, 0, 0, 7, 1, 32, total_length, buffer);
00714       break;
00715     case MT_OPERAND_RCNUM :
00716       errmsg = insert_normal (cd, fields->f_rcnum, 0, 0, 14, 3, 32, total_length, buffer);
00717       break;
00718     case MT_OPERAND_RDA :
00719       errmsg = insert_normal (cd, fields->f_rda, 0, 0, 25, 1, 32, total_length, buffer);
00720       break;
00721     case MT_OPERAND_ROWNUM :
00722       errmsg = insert_normal (cd, fields->f_rownum, 0, 0, 14, 3, 32, total_length, buffer);
00723       break;
00724     case MT_OPERAND_ROWNUM1 :
00725       errmsg = insert_normal (cd, fields->f_rownum1, 0, 0, 12, 3, 32, total_length, buffer);
00726       break;
00727     case MT_OPERAND_ROWNUM2 :
00728       errmsg = insert_normal (cd, fields->f_rownum2, 0, 0, 9, 3, 32, total_length, buffer);
00729       break;
00730     case MT_OPERAND_SIZE :
00731       errmsg = insert_normal (cd, fields->f_size, 0, 0, 13, 14, 32, total_length, buffer);
00732       break;
00733     case MT_OPERAND_TYPE :
00734       errmsg = insert_normal (cd, fields->f_type, 0, 0, 21, 2, 32, total_length, buffer);
00735       break;
00736     case MT_OPERAND_WR :
00737       errmsg = insert_normal (cd, fields->f_wr, 0, 0, 24, 1, 32, total_length, buffer);
00738       break;
00739     case MT_OPERAND_XMODE :
00740       errmsg = insert_normal (cd, fields->f_xmode, 0, 0, 23, 1, 32, total_length, buffer);
00741       break;
00742 
00743     default :
00744       /* xgettext:c-format */
00745       fprintf (stderr, _("Unrecognized field %d while building insn.\n"),
00746               opindex);
00747       abort ();
00748   }
00749 
00750   return errmsg;
00751 }
00752 
00753 int mt_cgen_extract_operand
00754   (CGEN_CPU_DESC, int, CGEN_EXTRACT_INFO *, CGEN_INSN_INT, CGEN_FIELDS *, bfd_vma);
00755 
00756 /* Main entry point for operand extraction.
00757    The result is <= 0 for error, >0 for success.
00758    ??? Actual values aren't well defined right now.
00759 
00760    This function is basically just a big switch statement.  Earlier versions
00761    used tables to look up the function to use, but
00762    - if the table contains both assembler and disassembler functions then
00763      the disassembler contains much of the assembler and vice-versa,
00764    - there's a lot of inlining possibilities as things grow,
00765    - using a switch statement avoids the function call overhead.
00766 
00767    This function could be moved into `print_insn_normal', but keeping it
00768    separate makes clear the interface between `print_insn_normal' and each of
00769    the handlers.  */
00770 
00771 int
00772 mt_cgen_extract_operand (CGEN_CPU_DESC cd,
00773                           int opindex,
00774                           CGEN_EXTRACT_INFO *ex_info,
00775                           CGEN_INSN_INT insn_value,
00776                           CGEN_FIELDS * fields,
00777                           bfd_vma pc)
00778 {
00779   /* Assume success (for those operands that are nops).  */
00780   int length = 1;
00781   unsigned int total_length = CGEN_FIELDS_BITSIZE (fields);
00782 
00783   switch (opindex)
00784     {
00785     case MT_OPERAND_A23 :
00786       length = extract_normal (cd, ex_info, insn_value, 0, 0, 23, 1, 32, total_length, pc, & fields->f_a23);
00787       break;
00788     case MT_OPERAND_BALL :
00789       length = extract_normal (cd, ex_info, insn_value, 0, 0, 19, 1, 32, total_length, pc, & fields->f_ball);
00790       break;
00791     case MT_OPERAND_BALL2 :
00792       length = extract_normal (cd, ex_info, insn_value, 0, 0, 15, 1, 32, total_length, pc, & fields->f_ball2);
00793       break;
00794     case MT_OPERAND_BANKADDR :
00795       length = extract_normal (cd, ex_info, insn_value, 0, 0, 25, 13, 32, total_length, pc, & fields->f_bankaddr);
00796       break;
00797     case MT_OPERAND_BRC :
00798       length = extract_normal (cd, ex_info, insn_value, 0, 0, 18, 3, 32, total_length, pc, & fields->f_brc);
00799       break;
00800     case MT_OPERAND_BRC2 :
00801       length = extract_normal (cd, ex_info, insn_value, 0, 0, 14, 3, 32, total_length, pc, & fields->f_brc2);
00802       break;
00803     case MT_OPERAND_CB1INCR :
00804       length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_SIGNED), 0, 19, 6, 32, total_length, pc, & fields->f_cb1incr);
00805       break;
00806     case MT_OPERAND_CB1SEL :
00807       length = extract_normal (cd, ex_info, insn_value, 0, 0, 25, 3, 32, total_length, pc, & fields->f_cb1sel);
00808       break;
00809     case MT_OPERAND_CB2INCR :
00810       length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_SIGNED), 0, 13, 6, 32, total_length, pc, & fields->f_cb2incr);
00811       break;
00812     case MT_OPERAND_CB2SEL :
00813       length = extract_normal (cd, ex_info, insn_value, 0, 0, 22, 3, 32, total_length, pc, & fields->f_cb2sel);
00814       break;
00815     case MT_OPERAND_CBRB :
00816       length = extract_normal (cd, ex_info, insn_value, 0, 0, 10, 1, 32, total_length, pc, & fields->f_cbrb);
00817       break;
00818     case MT_OPERAND_CBS :
00819       length = extract_normal (cd, ex_info, insn_value, 0, 0, 19, 2, 32, total_length, pc, & fields->f_cbs);
00820       break;
00821     case MT_OPERAND_CBX :
00822       length = extract_normal (cd, ex_info, insn_value, 0, 0, 14, 3, 32, total_length, pc, & fields->f_cbx);
00823       break;
00824     case MT_OPERAND_CCB :
00825       length = extract_normal (cd, ex_info, insn_value, 0, 0, 11, 1, 32, total_length, pc, & fields->f_ccb);
00826       break;
00827     case MT_OPERAND_CDB :
00828       length = extract_normal (cd, ex_info, insn_value, 0, 0, 10, 1, 32, total_length, pc, & fields->f_cdb);
00829       break;
00830     case MT_OPERAND_CELL :
00831       length = extract_normal (cd, ex_info, insn_value, 0, 0, 9, 3, 32, total_length, pc, & fields->f_cell);
00832       break;
00833     case MT_OPERAND_COLNUM :
00834       length = extract_normal (cd, ex_info, insn_value, 0, 0, 18, 3, 32, total_length, pc, & fields->f_colnum);
00835       break;
00836     case MT_OPERAND_CONTNUM :
00837       length = extract_normal (cd, ex_info, insn_value, 0, 0, 8, 9, 32, total_length, pc, & fields->f_contnum);
00838       break;
00839     case MT_OPERAND_CR :
00840       length = extract_normal (cd, ex_info, insn_value, 0, 0, 22, 3, 32, total_length, pc, & fields->f_cr);
00841       break;
00842     case MT_OPERAND_CTXDISP :
00843       length = extract_normal (cd, ex_info, insn_value, 0, 0, 5, 6, 32, total_length, pc, & fields->f_ctxdisp);
00844       break;
00845     case MT_OPERAND_DUP :
00846       length = extract_normal (cd, ex_info, insn_value, 0, 0, 6, 1, 32, total_length, pc, & fields->f_dup);
00847       break;
00848     case MT_OPERAND_FBDISP :
00849       length = extract_normal (cd, ex_info, insn_value, 0, 0, 15, 6, 32, total_length, pc, & fields->f_fbdisp);
00850       break;
00851     case MT_OPERAND_FBINCR :
00852       length = extract_normal (cd, ex_info, insn_value, 0, 0, 23, 4, 32, total_length, pc, & fields->f_fbincr);
00853       break;
00854     case MT_OPERAND_FRDR :
00855       length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_ABS_ADDR), 0, 19, 4, 32, total_length, pc, & fields->f_dr);
00856       break;
00857     case MT_OPERAND_FRDRRR :
00858       length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_ABS_ADDR), 0, 15, 4, 32, total_length, pc, & fields->f_drrr);
00859       break;
00860     case MT_OPERAND_FRSR1 :
00861       length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_ABS_ADDR), 0, 23, 4, 32, total_length, pc, & fields->f_sr1);
00862       break;
00863     case MT_OPERAND_FRSR2 :
00864       length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_ABS_ADDR), 0, 19, 4, 32, total_length, pc, & fields->f_sr2);
00865       break;
00866     case MT_OPERAND_ID :
00867       length = extract_normal (cd, ex_info, insn_value, 0, 0, 14, 1, 32, total_length, pc, & fields->f_id);
00868       break;
00869     case MT_OPERAND_IMM16 :
00870       {
00871         long value;
00872         length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_SIGNED), 0, 15, 16, 32, total_length, pc, & value);
00873         value = ((value) + (0));
00874         fields->f_imm16s = value;
00875       }
00876       break;
00877     case MT_OPERAND_IMM16L :
00878       length = extract_normal (cd, ex_info, insn_value, 0, 0, 23, 16, 32, total_length, pc, & fields->f_imm16l);
00879       break;
00880     case MT_OPERAND_IMM16O :
00881       {
00882         long value;
00883         length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_SIGNED), 0, 15, 16, 32, total_length, pc, & value);
00884         value = ((value) + (0));
00885         fields->f_imm16s = value;
00886       }
00887       break;
00888     case MT_OPERAND_IMM16Z :
00889       length = extract_normal (cd, ex_info, insn_value, 0, 0, 15, 16, 32, total_length, pc, & fields->f_imm16u);
00890       break;
00891     case MT_OPERAND_INCAMT :
00892       length = extract_normal (cd, ex_info, insn_value, 0, 0, 19, 8, 32, total_length, pc, & fields->f_incamt);
00893       break;
00894     case MT_OPERAND_INCR :
00895       length = extract_normal (cd, ex_info, insn_value, 0, 0, 17, 6, 32, total_length, pc, & fields->f_incr);
00896       break;
00897     case MT_OPERAND_LENGTH :
00898       length = extract_normal (cd, ex_info, insn_value, 0, 0, 15, 3, 32, total_length, pc, & fields->f_length);
00899       break;
00900     case MT_OPERAND_LOOPSIZE :
00901       {
00902         long value;
00903         length = extract_normal (cd, ex_info, insn_value, 0, 0, 7, 8, 32, total_length, pc, & value);
00904         value = ((((value) << (2))) + (8));
00905         fields->f_loopo = value;
00906       }
00907       break;
00908     case MT_OPERAND_MASK :
00909       length = extract_normal (cd, ex_info, insn_value, 0, 0, 25, 16, 32, total_length, pc, & fields->f_mask);
00910       break;
00911     case MT_OPERAND_MASK1 :
00912       length = extract_normal (cd, ex_info, insn_value, 0, 0, 22, 3, 32, total_length, pc, & fields->f_mask1);
00913       break;
00914     case MT_OPERAND_MODE :
00915       length = extract_normal (cd, ex_info, insn_value, 0, 0, 25, 2, 32, total_length, pc, & fields->f_mode);
00916       break;
00917     case MT_OPERAND_PERM :
00918       length = extract_normal (cd, ex_info, insn_value, 0, 0, 25, 2, 32, total_length, pc, & fields->f_perm);
00919       break;
00920     case MT_OPERAND_RBBC :
00921       length = extract_normal (cd, ex_info, insn_value, 0, 0, 25, 2, 32, total_length, pc, & fields->f_rbbc);
00922       break;
00923     case MT_OPERAND_RC :
00924       length = extract_normal (cd, ex_info, insn_value, 0, 0, 15, 1, 32, total_length, pc, & fields->f_rc);
00925       break;
00926     case MT_OPERAND_RC1 :
00927       length = extract_normal (cd, ex_info, insn_value, 0, 0, 11, 1, 32, total_length, pc, & fields->f_rc1);
00928       break;
00929     case MT_OPERAND_RC2 :
00930       length = extract_normal (cd, ex_info, insn_value, 0, 0, 6, 1, 32, total_length, pc, & fields->f_rc2);
00931       break;
00932     case MT_OPERAND_RC3 :
00933       length = extract_normal (cd, ex_info, insn_value, 0, 0, 7, 1, 32, total_length, pc, & fields->f_rc3);
00934       break;
00935     case MT_OPERAND_RCNUM :
00936       length = extract_normal (cd, ex_info, insn_value, 0, 0, 14, 3, 32, total_length, pc, & fields->f_rcnum);
00937       break;
00938     case MT_OPERAND_RDA :
00939       length = extract_normal (cd, ex_info, insn_value, 0, 0, 25, 1, 32, total_length, pc, & fields->f_rda);
00940       break;
00941     case MT_OPERAND_ROWNUM :
00942       length = extract_normal (cd, ex_info, insn_value, 0, 0, 14, 3, 32, total_length, pc, & fields->f_rownum);
00943       break;
00944     case MT_OPERAND_ROWNUM1 :
00945       length = extract_normal (cd, ex_info, insn_value, 0, 0, 12, 3, 32, total_length, pc, & fields->f_rownum1);
00946       break;
00947     case MT_OPERAND_ROWNUM2 :
00948       length = extract_normal (cd, ex_info, insn_value, 0, 0, 9, 3, 32, total_length, pc, & fields->f_rownum2);
00949       break;
00950     case MT_OPERAND_SIZE :
00951       length = extract_normal (cd, ex_info, insn_value, 0, 0, 13, 14, 32, total_length, pc, & fields->f_size);
00952       break;
00953     case MT_OPERAND_TYPE :
00954       length = extract_normal (cd, ex_info, insn_value, 0, 0, 21, 2, 32, total_length, pc, & fields->f_type);
00955       break;
00956     case MT_OPERAND_WR :
00957       length = extract_normal (cd, ex_info, insn_value, 0, 0, 24, 1, 32, total_length, pc, & fields->f_wr);
00958       break;
00959     case MT_OPERAND_XMODE :
00960       length = extract_normal (cd, ex_info, insn_value, 0, 0, 23, 1, 32, total_length, pc, & fields->f_xmode);
00961       break;
00962 
00963     default :
00964       /* xgettext:c-format */
00965       fprintf (stderr, _("Unrecognized field %d while decoding insn.\n"),
00966               opindex);
00967       abort ();
00968     }
00969 
00970   return length;
00971 }
00972 
00973 cgen_insert_fn * const mt_cgen_insert_handlers[] = 
00974 {
00975   insert_insn_normal,
00976 };
00977 
00978 cgen_extract_fn * const mt_cgen_extract_handlers[] = 
00979 {
00980   extract_insn_normal,
00981 };
00982 
00983 int mt_cgen_get_int_operand     (CGEN_CPU_DESC, int, const CGEN_FIELDS *);
00984 bfd_vma mt_cgen_get_vma_operand (CGEN_CPU_DESC, int, const CGEN_FIELDS *);
00985 
00986 /* Getting values from cgen_fields is handled by a collection of functions.
00987    They are distinguished by the type of the VALUE argument they return.
00988    TODO: floating point, inlining support, remove cases where result type
00989    not appropriate.  */
00990 
00991 int
00992 mt_cgen_get_int_operand (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
00993                           int opindex,
00994                           const CGEN_FIELDS * fields)
00995 {
00996   int value;
00997 
00998   switch (opindex)
00999     {
01000     case MT_OPERAND_A23 :
01001       value = fields->f_a23;
01002       break;
01003     case MT_OPERAND_BALL :
01004       value = fields->f_ball;
01005       break;
01006     case MT_OPERAND_BALL2 :
01007       value = fields->f_ball2;
01008       break;
01009     case MT_OPERAND_BANKADDR :
01010       value = fields->f_bankaddr;
01011       break;
01012     case MT_OPERAND_BRC :
01013       value = fields->f_brc;
01014       break;
01015     case MT_OPERAND_BRC2 :
01016       value = fields->f_brc2;
01017       break;
01018     case MT_OPERAND_CB1INCR :
01019       value = fields->f_cb1incr;
01020       break;
01021     case MT_OPERAND_CB1SEL :
01022       value = fields->f_cb1sel;
01023       break;
01024     case MT_OPERAND_CB2INCR :
01025       value = fields->f_cb2incr;
01026       break;
01027     case MT_OPERAND_CB2SEL :
01028       value = fields->f_cb2sel;
01029       break;
01030     case MT_OPERAND_CBRB :
01031       value = fields->f_cbrb;
01032       break;
01033     case MT_OPERAND_CBS :
01034       value = fields->f_cbs;
01035       break;
01036     case MT_OPERAND_CBX :
01037       value = fields->f_cbx;
01038       break;
01039     case MT_OPERAND_CCB :
01040       value = fields->f_ccb;
01041       break;
01042     case MT_OPERAND_CDB :
01043       value = fields->f_cdb;
01044       break;
01045     case MT_OPERAND_CELL :
01046       value = fields->f_cell;
01047       break;
01048     case MT_OPERAND_COLNUM :
01049       value = fields->f_colnum;
01050       break;
01051     case MT_OPERAND_CONTNUM :
01052       value = fields->f_contnum;
01053       break;
01054     case MT_OPERAND_CR :
01055       value = fields->f_cr;
01056       break;
01057     case MT_OPERAND_CTXDISP :
01058       value = fields->f_ctxdisp;
01059       break;
01060     case MT_OPERAND_DUP :
01061       value = fields->f_dup;
01062       break;
01063     case MT_OPERAND_FBDISP :
01064       value = fields->f_fbdisp;
01065       break;
01066     case MT_OPERAND_FBINCR :
01067       value = fields->f_fbincr;
01068       break;
01069     case MT_OPERAND_FRDR :
01070       value = fields->f_dr;
01071       break;
01072     case MT_OPERAND_FRDRRR :
01073       value = fields->f_drrr;
01074       break;
01075     case MT_OPERAND_FRSR1 :
01076       value = fields->f_sr1;
01077       break;
01078     case MT_OPERAND_FRSR2 :
01079       value = fields->f_sr2;
01080       break;
01081     case MT_OPERAND_ID :
01082       value = fields->f_id;
01083       break;
01084     case MT_OPERAND_IMM16 :
01085       value = fields->f_imm16s;
01086       break;
01087     case MT_OPERAND_IMM16L :
01088       value = fields->f_imm16l;
01089       break;
01090     case MT_OPERAND_IMM16O :
01091       value = fields->f_imm16s;
01092       break;
01093     case MT_OPERAND_IMM16Z :
01094       value = fields->f_imm16u;
01095       break;
01096     case MT_OPERAND_INCAMT :
01097       value = fields->f_incamt;
01098       break;
01099     case MT_OPERAND_INCR :
01100       value = fields->f_incr;
01101       break;
01102     case MT_OPERAND_LENGTH :
01103       value = fields->f_length;
01104       break;
01105     case MT_OPERAND_LOOPSIZE :
01106       value = fields->f_loopo;
01107       break;
01108     case MT_OPERAND_MASK :
01109       value = fields->f_mask;
01110       break;
01111     case MT_OPERAND_MASK1 :
01112       value = fields->f_mask1;
01113       break;
01114     case MT_OPERAND_MODE :
01115       value = fields->f_mode;
01116       break;
01117     case MT_OPERAND_PERM :
01118       value = fields->f_perm;
01119       break;
01120     case MT_OPERAND_RBBC :
01121       value = fields->f_rbbc;
01122       break;
01123     case MT_OPERAND_RC :
01124       value = fields->f_rc;
01125       break;
01126     case MT_OPERAND_RC1 :
01127       value = fields->f_rc1;
01128       break;
01129     case MT_OPERAND_RC2 :
01130       value = fields->f_rc2;
01131       break;
01132     case MT_OPERAND_RC3 :
01133       value = fields->f_rc3;
01134       break;
01135     case MT_OPERAND_RCNUM :
01136       value = fields->f_rcnum;
01137       break;
01138     case MT_OPERAND_RDA :
01139       value = fields->f_rda;
01140       break;
01141     case MT_OPERAND_ROWNUM :
01142       value = fields->f_rownum;
01143       break;
01144     case MT_OPERAND_ROWNUM1 :
01145       value = fields->f_rownum1;
01146       break;
01147     case MT_OPERAND_ROWNUM2 :
01148       value = fields->f_rownum2;
01149       break;
01150     case MT_OPERAND_SIZE :
01151       value = fields->f_size;
01152       break;
01153     case MT_OPERAND_TYPE :
01154       value = fields->f_type;
01155       break;
01156     case MT_OPERAND_WR :
01157       value = fields->f_wr;
01158       break;
01159     case MT_OPERAND_XMODE :
01160       value = fields->f_xmode;
01161       break;
01162 
01163     default :
01164       /* xgettext:c-format */
01165       fprintf (stderr, _("Unrecognized field %d while getting int operand.\n"),
01166                      opindex);
01167       abort ();
01168   }
01169 
01170   return value;
01171 }
01172 
01173 bfd_vma
01174 mt_cgen_get_vma_operand (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
01175                           int opindex,
01176                           const CGEN_FIELDS * fields)
01177 {
01178   bfd_vma value;
01179 
01180   switch (opindex)
01181     {
01182     case MT_OPERAND_A23 :
01183       value = fields->f_a23;
01184       break;
01185     case MT_OPERAND_BALL :
01186       value = fields->f_ball;
01187       break;
01188     case MT_OPERAND_BALL2 :
01189       value = fields->f_ball2;
01190       break;
01191     case MT_OPERAND_BANKADDR :
01192       value = fields->f_bankaddr;
01193       break;
01194     case MT_OPERAND_BRC :
01195       value = fields->f_brc;
01196       break;
01197     case MT_OPERAND_BRC2 :
01198       value = fields->f_brc2;
01199       break;
01200     case MT_OPERAND_CB1INCR :
01201       value = fields->f_cb1incr;
01202       break;
01203     case MT_OPERAND_CB1SEL :
01204       value = fields->f_cb1sel;
01205       break;
01206     case MT_OPERAND_CB2INCR :
01207       value = fields->f_cb2incr;
01208       break;
01209     case MT_OPERAND_CB2SEL :
01210       value = fields->f_cb2sel;
01211       break;
01212     case MT_OPERAND_CBRB :
01213       value = fields->f_cbrb;
01214       break;
01215     case MT_OPERAND_CBS :
01216       value = fields->f_cbs;
01217       break;
01218     case MT_OPERAND_CBX :
01219       value = fields->f_cbx;
01220       break;
01221     case MT_OPERAND_CCB :
01222       value = fields->f_ccb;
01223       break;
01224     case MT_OPERAND_CDB :
01225       value = fields->f_cdb;
01226       break;
01227     case MT_OPERAND_CELL :
01228       value = fields->f_cell;
01229       break;
01230     case MT_OPERAND_COLNUM :
01231       value = fields->f_colnum;
01232       break;
01233     case MT_OPERAND_CONTNUM :
01234       value = fields->f_contnum;
01235       break;
01236     case MT_OPERAND_CR :
01237       value = fields->f_cr;
01238       break;
01239     case MT_OPERAND_CTXDISP :
01240       value = fields->f_ctxdisp;
01241       break;
01242     case MT_OPERAND_DUP :
01243       value = fields->f_dup;
01244       break;
01245     case MT_OPERAND_FBDISP :
01246       value = fields->f_fbdisp;
01247       break;
01248     case MT_OPERAND_FBINCR :
01249       value = fields->f_fbincr;
01250       break;
01251     case MT_OPERAND_FRDR :
01252       value = fields->f_dr;
01253       break;
01254     case MT_OPERAND_FRDRRR :
01255       value = fields->f_drrr;
01256       break;
01257     case MT_OPERAND_FRSR1 :
01258       value = fields->f_sr1;
01259       break;
01260     case MT_OPERAND_FRSR2 :
01261       value = fields->f_sr2;
01262       break;
01263     case MT_OPERAND_ID :
01264       value = fields->f_id;
01265       break;
01266     case MT_OPERAND_IMM16 :
01267       value = fields->f_imm16s;
01268       break;
01269     case MT_OPERAND_IMM16L :
01270       value = fields->f_imm16l;
01271       break;
01272     case MT_OPERAND_IMM16O :
01273       value = fields->f_imm16s;
01274       break;
01275     case MT_OPERAND_IMM16Z :
01276       value = fields->f_imm16u;
01277       break;
01278     case MT_OPERAND_INCAMT :
01279       value = fields->f_incamt;
01280       break;
01281     case MT_OPERAND_INCR :
01282       value = fields->f_incr;
01283       break;
01284     case MT_OPERAND_LENGTH :
01285       value = fields->f_length;
01286       break;
01287     case MT_OPERAND_LOOPSIZE :
01288       value = fields->f_loopo;
01289       break;
01290     case MT_OPERAND_MASK :
01291       value = fields->f_mask;
01292       break;
01293     case MT_OPERAND_MASK1 :
01294       value = fields->f_mask1;
01295       break;
01296     case MT_OPERAND_MODE :
01297       value = fields->f_mode;
01298       break;
01299     case MT_OPERAND_PERM :
01300       value = fields->f_perm;
01301       break;
01302     case MT_OPERAND_RBBC :
01303       value = fields->f_rbbc;
01304       break;
01305     case MT_OPERAND_RC :
01306       value = fields->f_rc;
01307       break;
01308     case MT_OPERAND_RC1 :
01309       value = fields->f_rc1;
01310       break;
01311     case MT_OPERAND_RC2 :
01312       value = fields->f_rc2;
01313       break;
01314     case MT_OPERAND_RC3 :
01315       value = fields->f_rc3;
01316       break;
01317     case MT_OPERAND_RCNUM :
01318       value = fields->f_rcnum;
01319       break;
01320     case MT_OPERAND_RDA :
01321       value = fields->f_rda;
01322       break;
01323     case MT_OPERAND_ROWNUM :
01324       value = fields->f_rownum;
01325       break;
01326     case MT_OPERAND_ROWNUM1 :
01327       value = fields->f_rownum1;
01328       break;
01329     case MT_OPERAND_ROWNUM2 :
01330       value = fields->f_rownum2;
01331       break;
01332     case MT_OPERAND_SIZE :
01333       value = fields->f_size;
01334       break;
01335     case MT_OPERAND_TYPE :
01336       value = fields->f_type;
01337       break;
01338     case MT_OPERAND_WR :
01339       value = fields->f_wr;
01340       break;
01341     case MT_OPERAND_XMODE :
01342       value = fields->f_xmode;
01343       break;
01344 
01345     default :
01346       /* xgettext:c-format */
01347       fprintf (stderr, _("Unrecognized field %d while getting vma operand.\n"),
01348                      opindex);
01349       abort ();
01350   }
01351 
01352   return value;
01353 }
01354 
01355 void mt_cgen_set_int_operand  (CGEN_CPU_DESC, int, CGEN_FIELDS *, int);
01356 void mt_cgen_set_vma_operand  (CGEN_CPU_DESC, int, CGEN_FIELDS *, bfd_vma);
01357 
01358 /* Stuffing values in cgen_fields is handled by a collection of functions.
01359    They are distinguished by the type of the VALUE argument they accept.
01360    TODO: floating point, inlining support, remove cases where argument type
01361    not appropriate.  */
01362 
01363 void
01364 mt_cgen_set_int_operand (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
01365                           int opindex,
01366                           CGEN_FIELDS * fields,
01367                           int value)
01368 {
01369   switch (opindex)
01370     {
01371     case MT_OPERAND_A23 :
01372       fields->f_a23 = value;
01373       break;
01374     case MT_OPERAND_BALL :
01375       fields->f_ball = value;
01376       break;
01377     case MT_OPERAND_BALL2 :
01378       fields->f_ball2 = value;
01379       break;
01380     case MT_OPERAND_BANKADDR :
01381       fields->f_bankaddr = value;
01382       break;
01383     case MT_OPERAND_BRC :
01384       fields->f_brc = value;
01385       break;
01386     case MT_OPERAND_BRC2 :
01387       fields->f_brc2 = value;
01388       break;
01389     case MT_OPERAND_CB1INCR :
01390       fields->f_cb1incr = value;
01391       break;
01392     case MT_OPERAND_CB1SEL :
01393       fields->f_cb1sel = value;
01394       break;
01395     case MT_OPERAND_CB2INCR :
01396       fields->f_cb2incr = value;
01397       break;
01398     case MT_OPERAND_CB2SEL :
01399       fields->f_cb2sel = value;
01400       break;
01401     case MT_OPERAND_CBRB :
01402       fields->f_cbrb = value;
01403       break;
01404     case MT_OPERAND_CBS :
01405       fields->f_cbs = value;
01406       break;
01407     case MT_OPERAND_CBX :
01408       fields->f_cbx = value;
01409       break;
01410     case MT_OPERAND_CCB :
01411       fields->f_ccb = value;
01412       break;
01413     case MT_OPERAND_CDB :
01414       fields->f_cdb = value;
01415       break;
01416     case MT_OPERAND_CELL :
01417       fields->f_cell = value;
01418       break;
01419     case MT_OPERAND_COLNUM :
01420       fields->f_colnum = value;
01421       break;
01422     case MT_OPERAND_CONTNUM :
01423       fields->f_contnum = value;
01424       break;
01425     case MT_OPERAND_CR :
01426       fields->f_cr = value;
01427       break;
01428     case MT_OPERAND_CTXDISP :
01429       fields->f_ctxdisp = value;
01430       break;
01431     case MT_OPERAND_DUP :
01432       fields->f_dup = value;
01433       break;
01434     case MT_OPERAND_FBDISP :
01435       fields->f_fbdisp = value;
01436       break;
01437     case MT_OPERAND_FBINCR :
01438       fields->f_fbincr = value;
01439       break;
01440     case MT_OPERAND_FRDR :
01441       fields->f_dr = value;
01442       break;
01443     case MT_OPERAND_FRDRRR :
01444       fields->f_drrr = value;
01445       break;
01446     case MT_OPERAND_FRSR1 :
01447       fields->f_sr1 = value;
01448       break;
01449     case MT_OPERAND_FRSR2 :
01450       fields->f_sr2 = value;
01451       break;
01452     case MT_OPERAND_ID :
01453       fields->f_id = value;
01454       break;
01455     case MT_OPERAND_IMM16 :
01456       fields->f_imm16s = value;
01457       break;
01458     case MT_OPERAND_IMM16L :
01459       fields->f_imm16l = value;
01460       break;
01461     case MT_OPERAND_IMM16O :
01462       fields->f_imm16s = value;
01463       break;
01464     case MT_OPERAND_IMM16Z :
01465       fields->f_imm16u = value;
01466       break;
01467     case MT_OPERAND_INCAMT :
01468       fields->f_incamt = value;
01469       break;
01470     case MT_OPERAND_INCR :
01471       fields->f_incr = value;
01472       break;
01473     case MT_OPERAND_LENGTH :
01474       fields->f_length = value;
01475       break;
01476     case MT_OPERAND_LOOPSIZE :
01477       fields->f_loopo = value;
01478       break;
01479     case MT_OPERAND_MASK :
01480       fields->f_mask = value;
01481       break;
01482     case MT_OPERAND_MASK1 :
01483       fields->f_mask1 = value;
01484       break;
01485     case MT_OPERAND_MODE :
01486       fields->f_mode = value;
01487       break;
01488     case MT_OPERAND_PERM :
01489       fields->f_perm = value;
01490       break;
01491     case MT_OPERAND_RBBC :
01492       fields->f_rbbc = value;
01493       break;
01494     case MT_OPERAND_RC :
01495       fields->f_rc = value;
01496       break;
01497     case MT_OPERAND_RC1 :
01498       fields->f_rc1 = value;
01499       break;
01500     case MT_OPERAND_RC2 :
01501       fields->f_rc2 = value;
01502       break;
01503     case MT_OPERAND_RC3 :
01504       fields->f_rc3 = value;
01505       break;
01506     case MT_OPERAND_RCNUM :
01507       fields->f_rcnum = value;
01508       break;
01509     case MT_OPERAND_RDA :
01510       fields->f_rda = value;
01511       break;
01512     case MT_OPERAND_ROWNUM :
01513       fields->f_rownum = value;
01514       break;
01515     case MT_OPERAND_ROWNUM1 :
01516       fields->f_rownum1 = value;
01517       break;
01518     case MT_OPERAND_ROWNUM2 :
01519       fields->f_rownum2 = value;
01520       break;
01521     case MT_OPERAND_SIZE :
01522       fields->f_size = value;
01523       break;
01524     case MT_OPERAND_TYPE :
01525       fields->f_type = value;
01526       break;
01527     case MT_OPERAND_WR :
01528       fields->f_wr = value;
01529       break;
01530     case MT_OPERAND_XMODE :
01531       fields->f_xmode = value;
01532       break;
01533 
01534     default :
01535       /* xgettext:c-format */
01536       fprintf (stderr, _("Unrecognized field %d while setting int operand.\n"),
01537                      opindex);
01538       abort ();
01539   }
01540 }
01541 
01542 void
01543 mt_cgen_set_vma_operand (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
01544                           int opindex,
01545                           CGEN_FIELDS * fields,
01546                           bfd_vma value)
01547 {
01548   switch (opindex)
01549     {
01550     case MT_OPERAND_A23 :
01551       fields->f_a23 = value;
01552       break;
01553     case MT_OPERAND_BALL :
01554       fields->f_ball = value;
01555       break;
01556     case MT_OPERAND_BALL2 :
01557       fields->f_ball2 = value;
01558       break;
01559     case MT_OPERAND_BANKADDR :
01560       fields->f_bankaddr = value;
01561       break;
01562     case MT_OPERAND_BRC :
01563       fields->f_brc = value;
01564       break;
01565     case MT_OPERAND_BRC2 :
01566       fields->f_brc2 = value;
01567       break;
01568     case MT_OPERAND_CB1INCR :
01569       fields->f_cb1incr = value;
01570       break;
01571     case MT_OPERAND_CB1SEL :
01572       fields->f_cb1sel = value;
01573       break;
01574     case MT_OPERAND_CB2INCR :
01575       fields->f_cb2incr = value;
01576       break;
01577     case MT_OPERAND_CB2SEL :
01578       fields->f_cb2sel = value;
01579       break;
01580     case MT_OPERAND_CBRB :
01581       fields->f_cbrb = value;
01582       break;
01583     case MT_OPERAND_CBS :
01584       fields->f_cbs = value;
01585       break;
01586     case MT_OPERAND_CBX :
01587       fields->f_cbx = value;
01588       break;
01589     case MT_OPERAND_CCB :
01590       fields->f_ccb = value;
01591       break;
01592     case MT_OPERAND_CDB :
01593       fields->f_cdb = value;
01594       break;
01595     case MT_OPERAND_CELL :
01596       fields->f_cell = value;
01597       break;
01598     case MT_OPERAND_COLNUM :
01599       fields->f_colnum = value;
01600       break;
01601     case MT_OPERAND_CONTNUM :
01602       fields->f_contnum = value;
01603       break;
01604     case MT_OPERAND_CR :
01605       fields->f_cr = value;
01606       break;
01607     case MT_OPERAND_CTXDISP :
01608       fields->f_ctxdisp = value;
01609       break;
01610     case MT_OPERAND_DUP :
01611       fields->f_dup = value;
01612       break;
01613     case MT_OPERAND_FBDISP :
01614       fields->f_fbdisp = value;
01615       break;
01616     case MT_OPERAND_FBINCR :
01617       fields->f_fbincr = value;
01618       break;
01619     case MT_OPERAND_FRDR :
01620       fields->f_dr = value;
01621       break;
01622     case MT_OPERAND_FRDRRR :
01623       fields->f_drrr = value;
01624       break;
01625     case MT_OPERAND_FRSR1 :
01626       fields->f_sr1 = value;
01627       break;
01628     case MT_OPERAND_FRSR2 :
01629       fields->f_sr2 = value;
01630       break;
01631     case MT_OPERAND_ID :
01632       fields->f_id = value;
01633       break;
01634     case MT_OPERAND_IMM16 :
01635       fields->f_imm16s = value;
01636       break;
01637     case MT_OPERAND_IMM16L :
01638       fields->f_imm16l = value;
01639       break;
01640     case MT_OPERAND_IMM16O :
01641       fields->f_imm16s = value;
01642       break;
01643     case MT_OPERAND_IMM16Z :
01644       fields->f_imm16u = value;
01645       break;
01646     case MT_OPERAND_INCAMT :
01647       fields->f_incamt = value;
01648       break;
01649     case MT_OPERAND_INCR :
01650       fields->f_incr = value;
01651       break;
01652     case MT_OPERAND_LENGTH :
01653       fields->f_length = value;
01654       break;
01655     case MT_OPERAND_LOOPSIZE :
01656       fields->f_loopo = value;
01657       break;
01658     case MT_OPERAND_MASK :
01659       fields->f_mask = value;
01660       break;
01661     case MT_OPERAND_MASK1 :
01662       fields->f_mask1 = value;
01663       break;
01664     case MT_OPERAND_MODE :
01665       fields->f_mode = value;
01666       break;
01667     case MT_OPERAND_PERM :
01668       fields->f_perm = value;
01669       break;
01670     case MT_OPERAND_RBBC :
01671       fields->f_rbbc = value;
01672       break;
01673     case MT_OPERAND_RC :
01674       fields->f_rc = value;
01675       break;
01676     case MT_OPERAND_RC1 :
01677       fields->f_rc1 = value;
01678       break;
01679     case MT_OPERAND_RC2 :
01680       fields->f_rc2 = value;
01681       break;
01682     case MT_OPERAND_RC3 :
01683       fields->f_rc3 = value;
01684       break;
01685     case MT_OPERAND_RCNUM :
01686       fields->f_rcnum = value;
01687       break;
01688     case MT_OPERAND_RDA :
01689       fields->f_rda = value;
01690       break;
01691     case MT_OPERAND_ROWNUM :
01692       fields->f_rownum = value;
01693       break;
01694     case MT_OPERAND_ROWNUM1 :
01695       fields->f_rownum1 = value;
01696       break;
01697     case MT_OPERAND_ROWNUM2 :
01698       fields->f_rownum2 = value;
01699       break;
01700     case MT_OPERAND_SIZE :
01701       fields->f_size = value;
01702       break;
01703     case MT_OPERAND_TYPE :
01704       fields->f_type = value;
01705       break;
01706     case MT_OPERAND_WR :
01707       fields->f_wr = value;
01708       break;
01709     case MT_OPERAND_XMODE :
01710       fields->f_xmode = value;
01711       break;
01712 
01713     default :
01714       /* xgettext:c-format */
01715       fprintf (stderr, _("Unrecognized field %d while setting vma operand.\n"),
01716                      opindex);
01717       abort ();
01718   }
01719 }
01720 
01721 /* Function to call before using the instruction builder tables.  */
01722 
01723 void
01724 mt_cgen_init_ibld_table (CGEN_CPU_DESC cd)
01725 {
01726   cd->insert_handlers = & mt_cgen_insert_handlers[0];
01727   cd->extract_handlers = & mt_cgen_extract_handlers[0];
01728 
01729   cd->insert_operand = mt_cgen_insert_operand;
01730   cd->extract_operand = mt_cgen_extract_operand;
01731 
01732   cd->get_int_operand = mt_cgen_get_int_operand;
01733   cd->set_int_operand = mt_cgen_set_int_operand;
01734   cd->get_vma_operand = mt_cgen_get_vma_operand;
01735   cd->set_vma_operand = mt_cgen_set_vma_operand;
01736 }