Back to index

cell-binutils  2.17cvs20070401
fr30-ibld.c
Go to the documentation of this file.
00001 /* Instruction building/extraction support for fr30. -*- 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 "fr30-desc.h"
00035 #include "fr30-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 * fr30_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 fr30_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 FR30_OPERAND_CRI :
00569       errmsg = insert_normal (cd, fields->f_CRi, 0, 16, 12, 4, 16, total_length, buffer);
00570       break;
00571     case FR30_OPERAND_CRJ :
00572       errmsg = insert_normal (cd, fields->f_CRj, 0, 16, 8, 4, 16, total_length, buffer);
00573       break;
00574     case FR30_OPERAND_R13 :
00575       break;
00576     case FR30_OPERAND_R14 :
00577       break;
00578     case FR30_OPERAND_R15 :
00579       break;
00580     case FR30_OPERAND_RI :
00581       errmsg = insert_normal (cd, fields->f_Ri, 0, 0, 12, 4, 16, total_length, buffer);
00582       break;
00583     case FR30_OPERAND_RIC :
00584       errmsg = insert_normal (cd, fields->f_Ric, 0, 16, 12, 4, 16, total_length, buffer);
00585       break;
00586     case FR30_OPERAND_RJ :
00587       errmsg = insert_normal (cd, fields->f_Rj, 0, 0, 8, 4, 16, total_length, buffer);
00588       break;
00589     case FR30_OPERAND_RJC :
00590       errmsg = insert_normal (cd, fields->f_Rjc, 0, 16, 8, 4, 16, total_length, buffer);
00591       break;
00592     case FR30_OPERAND_RS1 :
00593       errmsg = insert_normal (cd, fields->f_Rs1, 0, 0, 8, 4, 16, total_length, buffer);
00594       break;
00595     case FR30_OPERAND_RS2 :
00596       errmsg = insert_normal (cd, fields->f_Rs2, 0, 0, 12, 4, 16, total_length, buffer);
00597       break;
00598     case FR30_OPERAND_CC :
00599       errmsg = insert_normal (cd, fields->f_cc, 0, 0, 4, 4, 16, total_length, buffer);
00600       break;
00601     case FR30_OPERAND_CCC :
00602       errmsg = insert_normal (cd, fields->f_ccc, 0, 16, 0, 8, 16, total_length, buffer);
00603       break;
00604     case FR30_OPERAND_DIR10 :
00605       {
00606         long value = fields->f_dir10;
00607         value = ((unsigned int) (value) >> (2));
00608         errmsg = insert_normal (cd, value, 0, 0, 8, 8, 16, total_length, buffer);
00609       }
00610       break;
00611     case FR30_OPERAND_DIR8 :
00612       errmsg = insert_normal (cd, fields->f_dir8, 0, 0, 8, 8, 16, total_length, buffer);
00613       break;
00614     case FR30_OPERAND_DIR9 :
00615       {
00616         long value = fields->f_dir9;
00617         value = ((unsigned int) (value) >> (1));
00618         errmsg = insert_normal (cd, value, 0, 0, 8, 8, 16, total_length, buffer);
00619       }
00620       break;
00621     case FR30_OPERAND_DISP10 :
00622       {
00623         long value = fields->f_disp10;
00624         value = ((int) (value) >> (2));
00625         errmsg = insert_normal (cd, value, 0|(1<<CGEN_IFLD_SIGNED), 0, 4, 8, 16, total_length, buffer);
00626       }
00627       break;
00628     case FR30_OPERAND_DISP8 :
00629       errmsg = insert_normal (cd, fields->f_disp8, 0|(1<<CGEN_IFLD_SIGNED), 0, 4, 8, 16, total_length, buffer);
00630       break;
00631     case FR30_OPERAND_DISP9 :
00632       {
00633         long value = fields->f_disp9;
00634         value = ((int) (value) >> (1));
00635         errmsg = insert_normal (cd, value, 0|(1<<CGEN_IFLD_SIGNED), 0, 4, 8, 16, total_length, buffer);
00636       }
00637       break;
00638     case FR30_OPERAND_I20 :
00639       {
00640 {
00641   FLD (f_i20_4) = ((unsigned int) (FLD (f_i20)) >> (16));
00642   FLD (f_i20_16) = ((FLD (f_i20)) & (65535));
00643 }
00644         errmsg = insert_normal (cd, fields->f_i20_4, 0, 0, 8, 4, 16, total_length, buffer);
00645         if (errmsg)
00646           break;
00647         errmsg = insert_normal (cd, fields->f_i20_16, 0, 16, 0, 16, 16, total_length, buffer);
00648         if (errmsg)
00649           break;
00650       }
00651       break;
00652     case FR30_OPERAND_I32 :
00653       errmsg = insert_normal (cd, fields->f_i32, 0|(1<<CGEN_IFLD_SIGN_OPT), 16, 0, 32, 32, total_length, buffer);
00654       break;
00655     case FR30_OPERAND_I8 :
00656       errmsg = insert_normal (cd, fields->f_i8, 0, 0, 4, 8, 16, total_length, buffer);
00657       break;
00658     case FR30_OPERAND_LABEL12 :
00659       {
00660         long value = fields->f_rel12;
00661         value = ((int) (((value) - (((pc) + (2))))) >> (1));
00662         errmsg = insert_normal (cd, value, 0|(1<<CGEN_IFLD_SIGNED)|(1<<CGEN_IFLD_PCREL_ADDR), 0, 5, 11, 16, total_length, buffer);
00663       }
00664       break;
00665     case FR30_OPERAND_LABEL9 :
00666       {
00667         long value = fields->f_rel9;
00668         value = ((int) (((value) - (((pc) + (2))))) >> (1));
00669         errmsg = insert_normal (cd, value, 0|(1<<CGEN_IFLD_SIGNED)|(1<<CGEN_IFLD_PCREL_ADDR), 0, 8, 8, 16, total_length, buffer);
00670       }
00671       break;
00672     case FR30_OPERAND_M4 :
00673       {
00674         long value = fields->f_m4;
00675         value = ((value) & (15));
00676         errmsg = insert_normal (cd, value, 0, 0, 8, 4, 16, total_length, buffer);
00677       }
00678       break;
00679     case FR30_OPERAND_PS :
00680       break;
00681     case FR30_OPERAND_REGLIST_HI_LD :
00682       errmsg = insert_normal (cd, fields->f_reglist_hi_ld, 0, 0, 8, 8, 16, total_length, buffer);
00683       break;
00684     case FR30_OPERAND_REGLIST_HI_ST :
00685       errmsg = insert_normal (cd, fields->f_reglist_hi_st, 0, 0, 8, 8, 16, total_length, buffer);
00686       break;
00687     case FR30_OPERAND_REGLIST_LOW_LD :
00688       errmsg = insert_normal (cd, fields->f_reglist_low_ld, 0, 0, 8, 8, 16, total_length, buffer);
00689       break;
00690     case FR30_OPERAND_REGLIST_LOW_ST :
00691       errmsg = insert_normal (cd, fields->f_reglist_low_st, 0, 0, 8, 8, 16, total_length, buffer);
00692       break;
00693     case FR30_OPERAND_S10 :
00694       {
00695         long value = fields->f_s10;
00696         value = ((int) (value) >> (2));
00697         errmsg = insert_normal (cd, value, 0|(1<<CGEN_IFLD_SIGNED), 0, 8, 8, 16, total_length, buffer);
00698       }
00699       break;
00700     case FR30_OPERAND_U10 :
00701       {
00702         long value = fields->f_u10;
00703         value = ((unsigned int) (value) >> (2));
00704         errmsg = insert_normal (cd, value, 0, 0, 8, 8, 16, total_length, buffer);
00705       }
00706       break;
00707     case FR30_OPERAND_U4 :
00708       errmsg = insert_normal (cd, fields->f_u4, 0, 0, 8, 4, 16, total_length, buffer);
00709       break;
00710     case FR30_OPERAND_U4C :
00711       errmsg = insert_normal (cd, fields->f_u4c, 0, 0, 12, 4, 16, total_length, buffer);
00712       break;
00713     case FR30_OPERAND_U8 :
00714       errmsg = insert_normal (cd, fields->f_u8, 0, 0, 8, 8, 16, total_length, buffer);
00715       break;
00716     case FR30_OPERAND_UDISP6 :
00717       {
00718         long value = fields->f_udisp6;
00719         value = ((unsigned int) (value) >> (2));
00720         errmsg = insert_normal (cd, value, 0, 0, 8, 4, 16, total_length, buffer);
00721       }
00722       break;
00723 
00724     default :
00725       /* xgettext:c-format */
00726       fprintf (stderr, _("Unrecognized field %d while building insn.\n"),
00727               opindex);
00728       abort ();
00729   }
00730 
00731   return errmsg;
00732 }
00733 
00734 int fr30_cgen_extract_operand
00735   (CGEN_CPU_DESC, int, CGEN_EXTRACT_INFO *, CGEN_INSN_INT, CGEN_FIELDS *, bfd_vma);
00736 
00737 /* Main entry point for operand extraction.
00738    The result is <= 0 for error, >0 for success.
00739    ??? Actual values aren't well defined right now.
00740 
00741    This function is basically just a big switch statement.  Earlier versions
00742    used tables to look up the function to use, but
00743    - if the table contains both assembler and disassembler functions then
00744      the disassembler contains much of the assembler and vice-versa,
00745    - there's a lot of inlining possibilities as things grow,
00746    - using a switch statement avoids the function call overhead.
00747 
00748    This function could be moved into `print_insn_normal', but keeping it
00749    separate makes clear the interface between `print_insn_normal' and each of
00750    the handlers.  */
00751 
00752 int
00753 fr30_cgen_extract_operand (CGEN_CPU_DESC cd,
00754                           int opindex,
00755                           CGEN_EXTRACT_INFO *ex_info,
00756                           CGEN_INSN_INT insn_value,
00757                           CGEN_FIELDS * fields,
00758                           bfd_vma pc)
00759 {
00760   /* Assume success (for those operands that are nops).  */
00761   int length = 1;
00762   unsigned int total_length = CGEN_FIELDS_BITSIZE (fields);
00763 
00764   switch (opindex)
00765     {
00766     case FR30_OPERAND_CRI :
00767       length = extract_normal (cd, ex_info, insn_value, 0, 16, 12, 4, 16, total_length, pc, & fields->f_CRi);
00768       break;
00769     case FR30_OPERAND_CRJ :
00770       length = extract_normal (cd, ex_info, insn_value, 0, 16, 8, 4, 16, total_length, pc, & fields->f_CRj);
00771       break;
00772     case FR30_OPERAND_R13 :
00773       break;
00774     case FR30_OPERAND_R14 :
00775       break;
00776     case FR30_OPERAND_R15 :
00777       break;
00778     case FR30_OPERAND_RI :
00779       length = extract_normal (cd, ex_info, insn_value, 0, 0, 12, 4, 16, total_length, pc, & fields->f_Ri);
00780       break;
00781     case FR30_OPERAND_RIC :
00782       length = extract_normal (cd, ex_info, insn_value, 0, 16, 12, 4, 16, total_length, pc, & fields->f_Ric);
00783       break;
00784     case FR30_OPERAND_RJ :
00785       length = extract_normal (cd, ex_info, insn_value, 0, 0, 8, 4, 16, total_length, pc, & fields->f_Rj);
00786       break;
00787     case FR30_OPERAND_RJC :
00788       length = extract_normal (cd, ex_info, insn_value, 0, 16, 8, 4, 16, total_length, pc, & fields->f_Rjc);
00789       break;
00790     case FR30_OPERAND_RS1 :
00791       length = extract_normal (cd, ex_info, insn_value, 0, 0, 8, 4, 16, total_length, pc, & fields->f_Rs1);
00792       break;
00793     case FR30_OPERAND_RS2 :
00794       length = extract_normal (cd, ex_info, insn_value, 0, 0, 12, 4, 16, total_length, pc, & fields->f_Rs2);
00795       break;
00796     case FR30_OPERAND_CC :
00797       length = extract_normal (cd, ex_info, insn_value, 0, 0, 4, 4, 16, total_length, pc, & fields->f_cc);
00798       break;
00799     case FR30_OPERAND_CCC :
00800       length = extract_normal (cd, ex_info, insn_value, 0, 16, 0, 8, 16, total_length, pc, & fields->f_ccc);
00801       break;
00802     case FR30_OPERAND_DIR10 :
00803       {
00804         long value;
00805         length = extract_normal (cd, ex_info, insn_value, 0, 0, 8, 8, 16, total_length, pc, & value);
00806         value = ((value) << (2));
00807         fields->f_dir10 = value;
00808       }
00809       break;
00810     case FR30_OPERAND_DIR8 :
00811       length = extract_normal (cd, ex_info, insn_value, 0, 0, 8, 8, 16, total_length, pc, & fields->f_dir8);
00812       break;
00813     case FR30_OPERAND_DIR9 :
00814       {
00815         long value;
00816         length = extract_normal (cd, ex_info, insn_value, 0, 0, 8, 8, 16, total_length, pc, & value);
00817         value = ((value) << (1));
00818         fields->f_dir9 = value;
00819       }
00820       break;
00821     case FR30_OPERAND_DISP10 :
00822       {
00823         long value;
00824         length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_SIGNED), 0, 4, 8, 16, total_length, pc, & value);
00825         value = ((value) << (2));
00826         fields->f_disp10 = value;
00827       }
00828       break;
00829     case FR30_OPERAND_DISP8 :
00830       length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_SIGNED), 0, 4, 8, 16, total_length, pc, & fields->f_disp8);
00831       break;
00832     case FR30_OPERAND_DISP9 :
00833       {
00834         long value;
00835         length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_SIGNED), 0, 4, 8, 16, total_length, pc, & value);
00836         value = ((value) << (1));
00837         fields->f_disp9 = value;
00838       }
00839       break;
00840     case FR30_OPERAND_I20 :
00841       {
00842         length = extract_normal (cd, ex_info, insn_value, 0, 0, 8, 4, 16, total_length, pc, & fields->f_i20_4);
00843         if (length <= 0) break;
00844         length = extract_normal (cd, ex_info, insn_value, 0, 16, 0, 16, 16, total_length, pc, & fields->f_i20_16);
00845         if (length <= 0) break;
00846 {
00847   FLD (f_i20) = ((((FLD (f_i20_4)) << (16))) | (FLD (f_i20_16)));
00848 }
00849       }
00850       break;
00851     case FR30_OPERAND_I32 :
00852       length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_SIGN_OPT), 16, 0, 32, 32, total_length, pc, & fields->f_i32);
00853       break;
00854     case FR30_OPERAND_I8 :
00855       length = extract_normal (cd, ex_info, insn_value, 0, 0, 4, 8, 16, total_length, pc, & fields->f_i8);
00856       break;
00857     case FR30_OPERAND_LABEL12 :
00858       {
00859         long value;
00860         length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_SIGNED)|(1<<CGEN_IFLD_PCREL_ADDR), 0, 5, 11, 16, total_length, pc, & value);
00861         value = ((((value) << (1))) + (((pc) + (2))));
00862         fields->f_rel12 = value;
00863       }
00864       break;
00865     case FR30_OPERAND_LABEL9 :
00866       {
00867         long value;
00868         length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_SIGNED)|(1<<CGEN_IFLD_PCREL_ADDR), 0, 8, 8, 16, total_length, pc, & value);
00869         value = ((((value) << (1))) + (((pc) + (2))));
00870         fields->f_rel9 = value;
00871       }
00872       break;
00873     case FR30_OPERAND_M4 :
00874       {
00875         long value;
00876         length = extract_normal (cd, ex_info, insn_value, 0, 0, 8, 4, 16, total_length, pc, & value);
00877         value = ((value) | (((-1) << (4))));
00878         fields->f_m4 = value;
00879       }
00880       break;
00881     case FR30_OPERAND_PS :
00882       break;
00883     case FR30_OPERAND_REGLIST_HI_LD :
00884       length = extract_normal (cd, ex_info, insn_value, 0, 0, 8, 8, 16, total_length, pc, & fields->f_reglist_hi_ld);
00885       break;
00886     case FR30_OPERAND_REGLIST_HI_ST :
00887       length = extract_normal (cd, ex_info, insn_value, 0, 0, 8, 8, 16, total_length, pc, & fields->f_reglist_hi_st);
00888       break;
00889     case FR30_OPERAND_REGLIST_LOW_LD :
00890       length = extract_normal (cd, ex_info, insn_value, 0, 0, 8, 8, 16, total_length, pc, & fields->f_reglist_low_ld);
00891       break;
00892     case FR30_OPERAND_REGLIST_LOW_ST :
00893       length = extract_normal (cd, ex_info, insn_value, 0, 0, 8, 8, 16, total_length, pc, & fields->f_reglist_low_st);
00894       break;
00895     case FR30_OPERAND_S10 :
00896       {
00897         long value;
00898         length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_SIGNED), 0, 8, 8, 16, total_length, pc, & value);
00899         value = ((value) << (2));
00900         fields->f_s10 = value;
00901       }
00902       break;
00903     case FR30_OPERAND_U10 :
00904       {
00905         long value;
00906         length = extract_normal (cd, ex_info, insn_value, 0, 0, 8, 8, 16, total_length, pc, & value);
00907         value = ((value) << (2));
00908         fields->f_u10 = value;
00909       }
00910       break;
00911     case FR30_OPERAND_U4 :
00912       length = extract_normal (cd, ex_info, insn_value, 0, 0, 8, 4, 16, total_length, pc, & fields->f_u4);
00913       break;
00914     case FR30_OPERAND_U4C :
00915       length = extract_normal (cd, ex_info, insn_value, 0, 0, 12, 4, 16, total_length, pc, & fields->f_u4c);
00916       break;
00917     case FR30_OPERAND_U8 :
00918       length = extract_normal (cd, ex_info, insn_value, 0, 0, 8, 8, 16, total_length, pc, & fields->f_u8);
00919       break;
00920     case FR30_OPERAND_UDISP6 :
00921       {
00922         long value;
00923         length = extract_normal (cd, ex_info, insn_value, 0, 0, 8, 4, 16, total_length, pc, & value);
00924         value = ((value) << (2));
00925         fields->f_udisp6 = value;
00926       }
00927       break;
00928 
00929     default :
00930       /* xgettext:c-format */
00931       fprintf (stderr, _("Unrecognized field %d while decoding insn.\n"),
00932               opindex);
00933       abort ();
00934     }
00935 
00936   return length;
00937 }
00938 
00939 cgen_insert_fn * const fr30_cgen_insert_handlers[] = 
00940 {
00941   insert_insn_normal,
00942 };
00943 
00944 cgen_extract_fn * const fr30_cgen_extract_handlers[] = 
00945 {
00946   extract_insn_normal,
00947 };
00948 
00949 int fr30_cgen_get_int_operand     (CGEN_CPU_DESC, int, const CGEN_FIELDS *);
00950 bfd_vma fr30_cgen_get_vma_operand (CGEN_CPU_DESC, int, const CGEN_FIELDS *);
00951 
00952 /* Getting values from cgen_fields is handled by a collection of functions.
00953    They are distinguished by the type of the VALUE argument they return.
00954    TODO: floating point, inlining support, remove cases where result type
00955    not appropriate.  */
00956 
00957 int
00958 fr30_cgen_get_int_operand (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
00959                           int opindex,
00960                           const CGEN_FIELDS * fields)
00961 {
00962   int value;
00963 
00964   switch (opindex)
00965     {
00966     case FR30_OPERAND_CRI :
00967       value = fields->f_CRi;
00968       break;
00969     case FR30_OPERAND_CRJ :
00970       value = fields->f_CRj;
00971       break;
00972     case FR30_OPERAND_R13 :
00973       value = 0;
00974       break;
00975     case FR30_OPERAND_R14 :
00976       value = 0;
00977       break;
00978     case FR30_OPERAND_R15 :
00979       value = 0;
00980       break;
00981     case FR30_OPERAND_RI :
00982       value = fields->f_Ri;
00983       break;
00984     case FR30_OPERAND_RIC :
00985       value = fields->f_Ric;
00986       break;
00987     case FR30_OPERAND_RJ :
00988       value = fields->f_Rj;
00989       break;
00990     case FR30_OPERAND_RJC :
00991       value = fields->f_Rjc;
00992       break;
00993     case FR30_OPERAND_RS1 :
00994       value = fields->f_Rs1;
00995       break;
00996     case FR30_OPERAND_RS2 :
00997       value = fields->f_Rs2;
00998       break;
00999     case FR30_OPERAND_CC :
01000       value = fields->f_cc;
01001       break;
01002     case FR30_OPERAND_CCC :
01003       value = fields->f_ccc;
01004       break;
01005     case FR30_OPERAND_DIR10 :
01006       value = fields->f_dir10;
01007       break;
01008     case FR30_OPERAND_DIR8 :
01009       value = fields->f_dir8;
01010       break;
01011     case FR30_OPERAND_DIR9 :
01012       value = fields->f_dir9;
01013       break;
01014     case FR30_OPERAND_DISP10 :
01015       value = fields->f_disp10;
01016       break;
01017     case FR30_OPERAND_DISP8 :
01018       value = fields->f_disp8;
01019       break;
01020     case FR30_OPERAND_DISP9 :
01021       value = fields->f_disp9;
01022       break;
01023     case FR30_OPERAND_I20 :
01024       value = fields->f_i20;
01025       break;
01026     case FR30_OPERAND_I32 :
01027       value = fields->f_i32;
01028       break;
01029     case FR30_OPERAND_I8 :
01030       value = fields->f_i8;
01031       break;
01032     case FR30_OPERAND_LABEL12 :
01033       value = fields->f_rel12;
01034       break;
01035     case FR30_OPERAND_LABEL9 :
01036       value = fields->f_rel9;
01037       break;
01038     case FR30_OPERAND_M4 :
01039       value = fields->f_m4;
01040       break;
01041     case FR30_OPERAND_PS :
01042       value = 0;
01043       break;
01044     case FR30_OPERAND_REGLIST_HI_LD :
01045       value = fields->f_reglist_hi_ld;
01046       break;
01047     case FR30_OPERAND_REGLIST_HI_ST :
01048       value = fields->f_reglist_hi_st;
01049       break;
01050     case FR30_OPERAND_REGLIST_LOW_LD :
01051       value = fields->f_reglist_low_ld;
01052       break;
01053     case FR30_OPERAND_REGLIST_LOW_ST :
01054       value = fields->f_reglist_low_st;
01055       break;
01056     case FR30_OPERAND_S10 :
01057       value = fields->f_s10;
01058       break;
01059     case FR30_OPERAND_U10 :
01060       value = fields->f_u10;
01061       break;
01062     case FR30_OPERAND_U4 :
01063       value = fields->f_u4;
01064       break;
01065     case FR30_OPERAND_U4C :
01066       value = fields->f_u4c;
01067       break;
01068     case FR30_OPERAND_U8 :
01069       value = fields->f_u8;
01070       break;
01071     case FR30_OPERAND_UDISP6 :
01072       value = fields->f_udisp6;
01073       break;
01074 
01075     default :
01076       /* xgettext:c-format */
01077       fprintf (stderr, _("Unrecognized field %d while getting int operand.\n"),
01078                      opindex);
01079       abort ();
01080   }
01081 
01082   return value;
01083 }
01084 
01085 bfd_vma
01086 fr30_cgen_get_vma_operand (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
01087                           int opindex,
01088                           const CGEN_FIELDS * fields)
01089 {
01090   bfd_vma value;
01091 
01092   switch (opindex)
01093     {
01094     case FR30_OPERAND_CRI :
01095       value = fields->f_CRi;
01096       break;
01097     case FR30_OPERAND_CRJ :
01098       value = fields->f_CRj;
01099       break;
01100     case FR30_OPERAND_R13 :
01101       value = 0;
01102       break;
01103     case FR30_OPERAND_R14 :
01104       value = 0;
01105       break;
01106     case FR30_OPERAND_R15 :
01107       value = 0;
01108       break;
01109     case FR30_OPERAND_RI :
01110       value = fields->f_Ri;
01111       break;
01112     case FR30_OPERAND_RIC :
01113       value = fields->f_Ric;
01114       break;
01115     case FR30_OPERAND_RJ :
01116       value = fields->f_Rj;
01117       break;
01118     case FR30_OPERAND_RJC :
01119       value = fields->f_Rjc;
01120       break;
01121     case FR30_OPERAND_RS1 :
01122       value = fields->f_Rs1;
01123       break;
01124     case FR30_OPERAND_RS2 :
01125       value = fields->f_Rs2;
01126       break;
01127     case FR30_OPERAND_CC :
01128       value = fields->f_cc;
01129       break;
01130     case FR30_OPERAND_CCC :
01131       value = fields->f_ccc;
01132       break;
01133     case FR30_OPERAND_DIR10 :
01134       value = fields->f_dir10;
01135       break;
01136     case FR30_OPERAND_DIR8 :
01137       value = fields->f_dir8;
01138       break;
01139     case FR30_OPERAND_DIR9 :
01140       value = fields->f_dir9;
01141       break;
01142     case FR30_OPERAND_DISP10 :
01143       value = fields->f_disp10;
01144       break;
01145     case FR30_OPERAND_DISP8 :
01146       value = fields->f_disp8;
01147       break;
01148     case FR30_OPERAND_DISP9 :
01149       value = fields->f_disp9;
01150       break;
01151     case FR30_OPERAND_I20 :
01152       value = fields->f_i20;
01153       break;
01154     case FR30_OPERAND_I32 :
01155       value = fields->f_i32;
01156       break;
01157     case FR30_OPERAND_I8 :
01158       value = fields->f_i8;
01159       break;
01160     case FR30_OPERAND_LABEL12 :
01161       value = fields->f_rel12;
01162       break;
01163     case FR30_OPERAND_LABEL9 :
01164       value = fields->f_rel9;
01165       break;
01166     case FR30_OPERAND_M4 :
01167       value = fields->f_m4;
01168       break;
01169     case FR30_OPERAND_PS :
01170       value = 0;
01171       break;
01172     case FR30_OPERAND_REGLIST_HI_LD :
01173       value = fields->f_reglist_hi_ld;
01174       break;
01175     case FR30_OPERAND_REGLIST_HI_ST :
01176       value = fields->f_reglist_hi_st;
01177       break;
01178     case FR30_OPERAND_REGLIST_LOW_LD :
01179       value = fields->f_reglist_low_ld;
01180       break;
01181     case FR30_OPERAND_REGLIST_LOW_ST :
01182       value = fields->f_reglist_low_st;
01183       break;
01184     case FR30_OPERAND_S10 :
01185       value = fields->f_s10;
01186       break;
01187     case FR30_OPERAND_U10 :
01188       value = fields->f_u10;
01189       break;
01190     case FR30_OPERAND_U4 :
01191       value = fields->f_u4;
01192       break;
01193     case FR30_OPERAND_U4C :
01194       value = fields->f_u4c;
01195       break;
01196     case FR30_OPERAND_U8 :
01197       value = fields->f_u8;
01198       break;
01199     case FR30_OPERAND_UDISP6 :
01200       value = fields->f_udisp6;
01201       break;
01202 
01203     default :
01204       /* xgettext:c-format */
01205       fprintf (stderr, _("Unrecognized field %d while getting vma operand.\n"),
01206                      opindex);
01207       abort ();
01208   }
01209 
01210   return value;
01211 }
01212 
01213 void fr30_cgen_set_int_operand  (CGEN_CPU_DESC, int, CGEN_FIELDS *, int);
01214 void fr30_cgen_set_vma_operand  (CGEN_CPU_DESC, int, CGEN_FIELDS *, bfd_vma);
01215 
01216 /* Stuffing values in cgen_fields is handled by a collection of functions.
01217    They are distinguished by the type of the VALUE argument they accept.
01218    TODO: floating point, inlining support, remove cases where argument type
01219    not appropriate.  */
01220 
01221 void
01222 fr30_cgen_set_int_operand (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
01223                           int opindex,
01224                           CGEN_FIELDS * fields,
01225                           int value)
01226 {
01227   switch (opindex)
01228     {
01229     case FR30_OPERAND_CRI :
01230       fields->f_CRi = value;
01231       break;
01232     case FR30_OPERAND_CRJ :
01233       fields->f_CRj = value;
01234       break;
01235     case FR30_OPERAND_R13 :
01236       break;
01237     case FR30_OPERAND_R14 :
01238       break;
01239     case FR30_OPERAND_R15 :
01240       break;
01241     case FR30_OPERAND_RI :
01242       fields->f_Ri = value;
01243       break;
01244     case FR30_OPERAND_RIC :
01245       fields->f_Ric = value;
01246       break;
01247     case FR30_OPERAND_RJ :
01248       fields->f_Rj = value;
01249       break;
01250     case FR30_OPERAND_RJC :
01251       fields->f_Rjc = value;
01252       break;
01253     case FR30_OPERAND_RS1 :
01254       fields->f_Rs1 = value;
01255       break;
01256     case FR30_OPERAND_RS2 :
01257       fields->f_Rs2 = value;
01258       break;
01259     case FR30_OPERAND_CC :
01260       fields->f_cc = value;
01261       break;
01262     case FR30_OPERAND_CCC :
01263       fields->f_ccc = value;
01264       break;
01265     case FR30_OPERAND_DIR10 :
01266       fields->f_dir10 = value;
01267       break;
01268     case FR30_OPERAND_DIR8 :
01269       fields->f_dir8 = value;
01270       break;
01271     case FR30_OPERAND_DIR9 :
01272       fields->f_dir9 = value;
01273       break;
01274     case FR30_OPERAND_DISP10 :
01275       fields->f_disp10 = value;
01276       break;
01277     case FR30_OPERAND_DISP8 :
01278       fields->f_disp8 = value;
01279       break;
01280     case FR30_OPERAND_DISP9 :
01281       fields->f_disp9 = value;
01282       break;
01283     case FR30_OPERAND_I20 :
01284       fields->f_i20 = value;
01285       break;
01286     case FR30_OPERAND_I32 :
01287       fields->f_i32 = value;
01288       break;
01289     case FR30_OPERAND_I8 :
01290       fields->f_i8 = value;
01291       break;
01292     case FR30_OPERAND_LABEL12 :
01293       fields->f_rel12 = value;
01294       break;
01295     case FR30_OPERAND_LABEL9 :
01296       fields->f_rel9 = value;
01297       break;
01298     case FR30_OPERAND_M4 :
01299       fields->f_m4 = value;
01300       break;
01301     case FR30_OPERAND_PS :
01302       break;
01303     case FR30_OPERAND_REGLIST_HI_LD :
01304       fields->f_reglist_hi_ld = value;
01305       break;
01306     case FR30_OPERAND_REGLIST_HI_ST :
01307       fields->f_reglist_hi_st = value;
01308       break;
01309     case FR30_OPERAND_REGLIST_LOW_LD :
01310       fields->f_reglist_low_ld = value;
01311       break;
01312     case FR30_OPERAND_REGLIST_LOW_ST :
01313       fields->f_reglist_low_st = value;
01314       break;
01315     case FR30_OPERAND_S10 :
01316       fields->f_s10 = value;
01317       break;
01318     case FR30_OPERAND_U10 :
01319       fields->f_u10 = value;
01320       break;
01321     case FR30_OPERAND_U4 :
01322       fields->f_u4 = value;
01323       break;
01324     case FR30_OPERAND_U4C :
01325       fields->f_u4c = value;
01326       break;
01327     case FR30_OPERAND_U8 :
01328       fields->f_u8 = value;
01329       break;
01330     case FR30_OPERAND_UDISP6 :
01331       fields->f_udisp6 = value;
01332       break;
01333 
01334     default :
01335       /* xgettext:c-format */
01336       fprintf (stderr, _("Unrecognized field %d while setting int operand.\n"),
01337                      opindex);
01338       abort ();
01339   }
01340 }
01341 
01342 void
01343 fr30_cgen_set_vma_operand (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
01344                           int opindex,
01345                           CGEN_FIELDS * fields,
01346                           bfd_vma value)
01347 {
01348   switch (opindex)
01349     {
01350     case FR30_OPERAND_CRI :
01351       fields->f_CRi = value;
01352       break;
01353     case FR30_OPERAND_CRJ :
01354       fields->f_CRj = value;
01355       break;
01356     case FR30_OPERAND_R13 :
01357       break;
01358     case FR30_OPERAND_R14 :
01359       break;
01360     case FR30_OPERAND_R15 :
01361       break;
01362     case FR30_OPERAND_RI :
01363       fields->f_Ri = value;
01364       break;
01365     case FR30_OPERAND_RIC :
01366       fields->f_Ric = value;
01367       break;
01368     case FR30_OPERAND_RJ :
01369       fields->f_Rj = value;
01370       break;
01371     case FR30_OPERAND_RJC :
01372       fields->f_Rjc = value;
01373       break;
01374     case FR30_OPERAND_RS1 :
01375       fields->f_Rs1 = value;
01376       break;
01377     case FR30_OPERAND_RS2 :
01378       fields->f_Rs2 = value;
01379       break;
01380     case FR30_OPERAND_CC :
01381       fields->f_cc = value;
01382       break;
01383     case FR30_OPERAND_CCC :
01384       fields->f_ccc = value;
01385       break;
01386     case FR30_OPERAND_DIR10 :
01387       fields->f_dir10 = value;
01388       break;
01389     case FR30_OPERAND_DIR8 :
01390       fields->f_dir8 = value;
01391       break;
01392     case FR30_OPERAND_DIR9 :
01393       fields->f_dir9 = value;
01394       break;
01395     case FR30_OPERAND_DISP10 :
01396       fields->f_disp10 = value;
01397       break;
01398     case FR30_OPERAND_DISP8 :
01399       fields->f_disp8 = value;
01400       break;
01401     case FR30_OPERAND_DISP9 :
01402       fields->f_disp9 = value;
01403       break;
01404     case FR30_OPERAND_I20 :
01405       fields->f_i20 = value;
01406       break;
01407     case FR30_OPERAND_I32 :
01408       fields->f_i32 = value;
01409       break;
01410     case FR30_OPERAND_I8 :
01411       fields->f_i8 = value;
01412       break;
01413     case FR30_OPERAND_LABEL12 :
01414       fields->f_rel12 = value;
01415       break;
01416     case FR30_OPERAND_LABEL9 :
01417       fields->f_rel9 = value;
01418       break;
01419     case FR30_OPERAND_M4 :
01420       fields->f_m4 = value;
01421       break;
01422     case FR30_OPERAND_PS :
01423       break;
01424     case FR30_OPERAND_REGLIST_HI_LD :
01425       fields->f_reglist_hi_ld = value;
01426       break;
01427     case FR30_OPERAND_REGLIST_HI_ST :
01428       fields->f_reglist_hi_st = value;
01429       break;
01430     case FR30_OPERAND_REGLIST_LOW_LD :
01431       fields->f_reglist_low_ld = value;
01432       break;
01433     case FR30_OPERAND_REGLIST_LOW_ST :
01434       fields->f_reglist_low_st = value;
01435       break;
01436     case FR30_OPERAND_S10 :
01437       fields->f_s10 = value;
01438       break;
01439     case FR30_OPERAND_U10 :
01440       fields->f_u10 = value;
01441       break;
01442     case FR30_OPERAND_U4 :
01443       fields->f_u4 = value;
01444       break;
01445     case FR30_OPERAND_U4C :
01446       fields->f_u4c = value;
01447       break;
01448     case FR30_OPERAND_U8 :
01449       fields->f_u8 = value;
01450       break;
01451     case FR30_OPERAND_UDISP6 :
01452       fields->f_udisp6 = value;
01453       break;
01454 
01455     default :
01456       /* xgettext:c-format */
01457       fprintf (stderr, _("Unrecognized field %d while setting vma operand.\n"),
01458                      opindex);
01459       abort ();
01460   }
01461 }
01462 
01463 /* Function to call before using the instruction builder tables.  */
01464 
01465 void
01466 fr30_cgen_init_ibld_table (CGEN_CPU_DESC cd)
01467 {
01468   cd->insert_handlers = & fr30_cgen_insert_handlers[0];
01469   cd->extract_handlers = & fr30_cgen_extract_handlers[0];
01470 
01471   cd->insert_operand = fr30_cgen_insert_operand;
01472   cd->extract_operand = fr30_cgen_extract_operand;
01473 
01474   cd->get_int_operand = fr30_cgen_get_int_operand;
01475   cd->set_int_operand = fr30_cgen_set_int_operand;
01476   cd->get_vma_operand = fr30_cgen_get_vma_operand;
01477   cd->set_vma_operand = fr30_cgen_set_vma_operand;
01478 }