(root)/
binutils-2.41/
opcodes/
fr30-ibld.c
       1  /* DO NOT EDIT!  -*- buffer-read-only: t -*- vi:set ro:  */
       2  /* Instruction building/extraction support for fr30. -*- C -*-
       3  
       4     THIS FILE IS MACHINE GENERATED WITH CGEN: Cpu tools GENerator.
       5     - the resultant file is machine generated, cgen-ibld.in isn't
       6  
       7     Copyright (C) 1996-2023 Free Software Foundation, Inc.
       8  
       9     This file is part of libopcodes.
      10  
      11     This library is free software; you can redistribute it and/or modify
      12     it under the terms of the GNU General Public License as published by
      13     the Free Software Foundation; either version 3, or (at your option)
      14     any later version.
      15  
      16     It is distributed in the hope that it will be useful, but WITHOUT
      17     ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
      18     or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
      19     License for more details.
      20  
      21     You should have received a copy of the GNU General Public License
      22     along with this program; if not, write to the Free Software Foundation, Inc.,
      23     51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.  */
      24  
      25  /* ??? Eventually more and more of this stuff can go to cpu-independent files.
      26     Keep that in mind.  */
      27  
      28  #include "sysdep.h"
      29  #include <stdio.h>
      30  #include "ansidecl.h"
      31  #include "dis-asm.h"
      32  #include "bfd.h"
      33  #include "symcat.h"
      34  #include "fr30-desc.h"
      35  #include "fr30-opc.h"
      36  #include "cgen/basic-modes.h"
      37  #include "opintl.h"
      38  #include "safe-ctype.h"
      39  
      40  #undef  min
      41  #define min(a,b) ((a) < (b) ? (a) : (b))
      42  #undef  max
      43  #define max(a,b) ((a) > (b) ? (a) : (b))
      44  
      45  /* Used by the ifield rtx function.  */
      46  #define FLD(f) (fields->f)
      47  
      48  static const char * insert_normal
      49    (CGEN_CPU_DESC, long, unsigned int, unsigned int, unsigned int,
      50     unsigned int, unsigned int, unsigned int, CGEN_INSN_BYTES_PTR);
      51  static const char * insert_insn_normal
      52    (CGEN_CPU_DESC, const CGEN_INSN *,
      53     CGEN_FIELDS *, CGEN_INSN_BYTES_PTR, bfd_vma);
      54  static int extract_normal
      55    (CGEN_CPU_DESC, CGEN_EXTRACT_INFO *, CGEN_INSN_INT,
      56     unsigned int, unsigned int, unsigned int, unsigned int,
      57     unsigned int, unsigned int, bfd_vma, long *);
      58  static int extract_insn_normal
      59    (CGEN_CPU_DESC, const CGEN_INSN *, CGEN_EXTRACT_INFO *,
      60     CGEN_INSN_INT, CGEN_FIELDS *, bfd_vma);
      61  #if CGEN_INT_INSN_P
      62  static void put_insn_int_value
      63    (CGEN_CPU_DESC, CGEN_INSN_BYTES_PTR, int, int, CGEN_INSN_INT);
      64  #endif
      65  #if ! CGEN_INT_INSN_P
      66  static CGEN_INLINE void insert_1
      67    (CGEN_CPU_DESC, unsigned long, int, int, int, unsigned char *);
      68  static CGEN_INLINE int fill_cache
      69    (CGEN_CPU_DESC, CGEN_EXTRACT_INFO *,  int, int, bfd_vma);
      70  static CGEN_INLINE long extract_1
      71    (CGEN_CPU_DESC, CGEN_EXTRACT_INFO *, int, int, int, unsigned char *, bfd_vma);
      72  #endif
      73  
      74  /* Operand insertion.  */
      75  
      76  #if ! CGEN_INT_INSN_P
      77  
      78  /* Subroutine of insert_normal.  */
      79  
      80  static CGEN_INLINE void
      81  insert_1 (CGEN_CPU_DESC cd,
      82  	  unsigned long value,
      83  	  int start,
      84  	  int length,
      85  	  int word_length,
      86  	  unsigned char *bufp)
      87  {
      88    unsigned long x, mask;
      89    int shift;
      90  
      91    x = cgen_get_insn_value (cd, bufp, word_length, cd->endian);
      92  
      93    /* Written this way to avoid undefined behaviour.  */
      94    mask = (1UL << (length - 1) << 1) - 1;
      95    if (CGEN_INSN_LSB0_P)
      96      shift = (start + 1) - length;
      97    else
      98      shift = (word_length - (start + length));
      99    x = (x & ~(mask << shift)) | ((value & mask) << shift);
     100  
     101    cgen_put_insn_value (cd, bufp, word_length, (bfd_vma) x, cd->endian);
     102  }
     103  
     104  #endif /* ! CGEN_INT_INSN_P */
     105  
     106  /* Default insertion routine.
     107  
     108     ATTRS is a mask of the boolean attributes.
     109     WORD_OFFSET is the offset in bits from the start of the insn of the value.
     110     WORD_LENGTH is the length of the word in bits in which the value resides.
     111     START is the starting bit number in the word, architecture origin.
     112     LENGTH is the length of VALUE in bits.
     113     TOTAL_LENGTH is the total length of the insn in bits.
     114  
     115     The result is an error message or NULL if success.  */
     116  
     117  /* ??? This duplicates functionality with bfd's howto table and
     118     bfd_install_relocation.  */
     119  /* ??? This doesn't handle bfd_vma's.  Create another function when
     120     necessary.  */
     121  
     122  static const char *
     123  insert_normal (CGEN_CPU_DESC cd,
     124  	       long value,
     125  	       unsigned int attrs,
     126  	       unsigned int word_offset,
     127  	       unsigned int start,
     128  	       unsigned int length,
     129  	       unsigned int word_length,
     130  	       unsigned int total_length,
     131  	       CGEN_INSN_BYTES_PTR buffer)
     132  {
     133    static char errbuf[100];
     134    unsigned long mask;
     135  
     136    /* If LENGTH is zero, this operand doesn't contribute to the value.  */
     137    if (length == 0)
     138      return NULL;
     139  
     140    /* Written this way to avoid undefined behaviour.  */
     141    mask = (1UL << (length - 1) << 1) - 1;
     142  
     143    if (word_length > 8 * sizeof (CGEN_INSN_INT))
     144      abort ();
     145  
     146    /* For architectures with insns smaller than the base-insn-bitsize,
     147       word_length may be too big.  */
     148    if (cd->min_insn_bitsize < cd->base_insn_bitsize)
     149      {
     150        if (word_offset == 0
     151  	  && word_length > total_length)
     152  	word_length = total_length;
     153      }
     154  
     155    /* Ensure VALUE will fit.  */
     156    if (CGEN_BOOL_ATTR (attrs, CGEN_IFLD_SIGN_OPT))
     157      {
     158        long minval = - (1UL << (length - 1));
     159        unsigned long maxval = mask;
     160  
     161        if ((value > 0 && (unsigned long) value > maxval)
     162  	  || value < minval)
     163  	{
     164  	  /* xgettext:c-format */
     165  	  sprintf (errbuf,
     166  		   _("operand out of range (%ld not between %ld and %lu)"),
     167  		   value, minval, maxval);
     168  	  return errbuf;
     169  	}
     170      }
     171    else if (! CGEN_BOOL_ATTR (attrs, CGEN_IFLD_SIGNED))
     172      {
     173        unsigned long maxval = mask;
     174        unsigned long val = (unsigned long) value;
     175  
     176        /* For hosts with a word size > 32 check to see if value has been sign
     177  	 extended beyond 32 bits.  If so then ignore these higher sign bits
     178  	 as the user is attempting to store a 32-bit signed value into an
     179  	 unsigned 32-bit field which is allowed.  */
     180        if (sizeof (unsigned long) > 4 && ((value >> 32) == -1))
     181  	val &= 0xFFFFFFFF;
     182  
     183        if (val > maxval)
     184  	{
     185  	  /* xgettext:c-format */
     186  	  sprintf (errbuf,
     187  		   _("operand out of range (0x%lx not between 0 and 0x%lx)"),
     188  		   val, maxval);
     189  	  return errbuf;
     190  	}
     191      }
     192    else
     193      {
     194        if (! cgen_signed_overflow_ok_p (cd))
     195  	{
     196  	  long minval = - (1UL << (length - 1));
     197  	  long maxval =   (1UL << (length - 1)) - 1;
     198  
     199  	  if (value < minval || value > maxval)
     200  	    {
     201  	      sprintf
     202  		/* xgettext:c-format */
     203  		(errbuf, _("operand out of range (%ld not between %ld and %ld)"),
     204  		 value, minval, maxval);
     205  	      return errbuf;
     206  	    }
     207  	}
     208      }
     209  
     210  #if CGEN_INT_INSN_P
     211  
     212    {
     213      int shift_within_word, shift_to_word, shift;
     214  
     215      /* How to shift the value to BIT0 of the word.  */
     216      shift_to_word = total_length - (word_offset + word_length);
     217  
     218      /* How to shift the value to the field within the word.  */
     219      if (CGEN_INSN_LSB0_P)
     220        shift_within_word = start + 1 - length;
     221      else
     222        shift_within_word = word_length - start - length;
     223  
     224      /* The total SHIFT, then mask in the value.  */
     225      shift = shift_to_word + shift_within_word;
     226      *buffer = (*buffer & ~(mask << shift)) | ((value & mask) << shift);
     227    }
     228  
     229  #else /* ! CGEN_INT_INSN_P */
     230  
     231    {
     232      unsigned char *bufp = (unsigned char *) buffer + word_offset / 8;
     233  
     234      insert_1 (cd, value, start, length, word_length, bufp);
     235    }
     236  
     237  #endif /* ! CGEN_INT_INSN_P */
     238  
     239    return NULL;
     240  }
     241  
     242  /* Default insn builder (insert handler).
     243     The instruction is recorded in CGEN_INT_INSN_P byte order (meaning
     244     that if CGEN_INSN_BYTES_PTR is an int * and thus, the value is
     245     recorded in host byte order, otherwise BUFFER is an array of bytes
     246     and the value is recorded in target byte order).
     247     The result is an error message or NULL if success.  */
     248  
     249  static const char *
     250  insert_insn_normal (CGEN_CPU_DESC cd,
     251  		    const CGEN_INSN * insn,
     252  		    CGEN_FIELDS * fields,
     253  		    CGEN_INSN_BYTES_PTR buffer,
     254  		    bfd_vma pc)
     255  {
     256    const CGEN_SYNTAX *syntax = CGEN_INSN_SYNTAX (insn);
     257    unsigned long value;
     258    const CGEN_SYNTAX_CHAR_TYPE * syn;
     259  
     260    CGEN_INIT_INSERT (cd);
     261    value = CGEN_INSN_BASE_VALUE (insn);
     262  
     263    /* If we're recording insns as numbers (rather than a string of bytes),
     264       target byte order handling is deferred until later.  */
     265  
     266  #if CGEN_INT_INSN_P
     267  
     268    put_insn_int_value (cd, buffer, cd->base_insn_bitsize,
     269  		      CGEN_FIELDS_BITSIZE (fields), value);
     270  
     271  #else
     272  
     273    cgen_put_insn_value (cd, buffer, min ((unsigned) cd->base_insn_bitsize,
     274                                          (unsigned) CGEN_FIELDS_BITSIZE (fields)),
     275  		       value, cd->insn_endian);
     276  
     277  #endif /* ! CGEN_INT_INSN_P */
     278  
     279    /* ??? It would be better to scan the format's fields.
     280       Still need to be able to insert a value based on the operand though;
     281       e.g. storing a branch displacement that got resolved later.
     282       Needs more thought first.  */
     283  
     284    for (syn = CGEN_SYNTAX_STRING (syntax); * syn; ++ syn)
     285      {
     286        const char *errmsg;
     287  
     288        if (CGEN_SYNTAX_CHAR_P (* syn))
     289  	continue;
     290  
     291        errmsg = (* cd->insert_operand) (cd, CGEN_SYNTAX_FIELD (*syn),
     292  				       fields, buffer, pc);
     293        if (errmsg)
     294  	return errmsg;
     295      }
     296  
     297    return NULL;
     298  }
     299  
     300  #if CGEN_INT_INSN_P
     301  /* Cover function to store an insn value into an integral insn.  Must go here
     302     because it needs <prefix>-desc.h for CGEN_INT_INSN_P.  */
     303  
     304  static void
     305  put_insn_int_value (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
     306  		    CGEN_INSN_BYTES_PTR buf,
     307  		    int length,
     308  		    int insn_length,
     309  		    CGEN_INSN_INT value)
     310  {
     311    /* For architectures with insns smaller than the base-insn-bitsize,
     312       length may be too big.  */
     313    if (length > insn_length)
     314      *buf = value;
     315    else
     316      {
     317        int shift = insn_length - length;
     318        /* Written this way to avoid undefined behaviour.  */
     319        CGEN_INSN_INT mask = length == 0 ? 0 : (1UL << (length - 1) << 1) - 1;
     320  
     321        *buf = (*buf & ~(mask << shift)) | ((value & mask) << shift);
     322      }
     323  }
     324  #endif
     325  
     326  /* Operand extraction.  */
     327  
     328  #if ! CGEN_INT_INSN_P
     329  
     330  /* Subroutine of extract_normal.
     331     Ensure sufficient bytes are cached in EX_INFO.
     332     OFFSET is the offset in bytes from the start of the insn of the value.
     333     BYTES is the length of the needed value.
     334     Returns 1 for success, 0 for failure.  */
     335  
     336  static CGEN_INLINE int
     337  fill_cache (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
     338  	    CGEN_EXTRACT_INFO *ex_info,
     339  	    int offset,
     340  	    int bytes,
     341  	    bfd_vma pc)
     342  {
     343    /* It's doubtful that the middle part has already been fetched so
     344       we don't optimize that case.  kiss.  */
     345    unsigned int mask;
     346    disassemble_info *info = (disassemble_info *) ex_info->dis_info;
     347  
     348    /* First do a quick check.  */
     349    mask = (1 << bytes) - 1;
     350    if (((ex_info->valid >> offset) & mask) == mask)
     351      return 1;
     352  
     353    /* Search for the first byte we need to read.  */
     354    for (mask = 1 << offset; bytes > 0; --bytes, ++offset, mask <<= 1)
     355      if (! (mask & ex_info->valid))
     356        break;
     357  
     358    if (bytes)
     359      {
     360        int status;
     361  
     362        pc += offset;
     363        status = (*info->read_memory_func)
     364  	(pc, ex_info->insn_bytes + offset, bytes, info);
     365  
     366        if (status != 0)
     367  	{
     368  	  (*info->memory_error_func) (status, pc, info);
     369  	  return 0;
     370  	}
     371  
     372        ex_info->valid |= ((1 << bytes) - 1) << offset;
     373      }
     374  
     375    return 1;
     376  }
     377  
     378  /* Subroutine of extract_normal.  */
     379  
     380  static CGEN_INLINE long
     381  extract_1 (CGEN_CPU_DESC cd,
     382  	   CGEN_EXTRACT_INFO *ex_info ATTRIBUTE_UNUSED,
     383  	   int start,
     384  	   int length,
     385  	   int word_length,
     386  	   unsigned char *bufp,
     387  	   bfd_vma pc ATTRIBUTE_UNUSED)
     388  {
     389    unsigned long x;
     390    int shift;
     391  
     392    x = cgen_get_insn_value (cd, bufp, word_length, cd->endian);
     393  
     394    if (CGEN_INSN_LSB0_P)
     395      shift = (start + 1) - length;
     396    else
     397      shift = (word_length - (start + length));
     398    return x >> shift;
     399  }
     400  
     401  #endif /* ! CGEN_INT_INSN_P */
     402  
     403  /* Default extraction routine.
     404  
     405     INSN_VALUE is the first base_insn_bitsize bits of the insn in host order,
     406     or sometimes less for cases like the m32r where the base insn size is 32
     407     but some insns are 16 bits.
     408     ATTRS is a mask of the boolean attributes.  We only need `SIGNED',
     409     but for generality we take a bitmask of all of them.
     410     WORD_OFFSET is the offset in bits from the start of the insn of the value.
     411     WORD_LENGTH is the length of the word in bits in which the value resides.
     412     START is the starting bit number in the word, architecture origin.
     413     LENGTH is the length of VALUE in bits.
     414     TOTAL_LENGTH is the total length of the insn in bits.
     415  
     416     Returns 1 for success, 0 for failure.  */
     417  
     418  /* ??? The return code isn't properly used.  wip.  */
     419  
     420  /* ??? This doesn't handle bfd_vma's.  Create another function when
     421     necessary.  */
     422  
     423  static int
     424  extract_normal (CGEN_CPU_DESC cd,
     425  #if ! CGEN_INT_INSN_P
     426  		CGEN_EXTRACT_INFO *ex_info,
     427  #else
     428  		CGEN_EXTRACT_INFO *ex_info ATTRIBUTE_UNUSED,
     429  #endif
     430  		CGEN_INSN_INT insn_value,
     431  		unsigned int attrs,
     432  		unsigned int word_offset,
     433  		unsigned int start,
     434  		unsigned int length,
     435  		unsigned int word_length,
     436  		unsigned int total_length,
     437  #if ! CGEN_INT_INSN_P
     438  		bfd_vma pc,
     439  #else
     440  		bfd_vma pc ATTRIBUTE_UNUSED,
     441  #endif
     442  		long *valuep)
     443  {
     444    long value, mask;
     445  
     446    /* If LENGTH is zero, this operand doesn't contribute to the value
     447       so give it a standard value of zero.  */
     448    if (length == 0)
     449      {
     450        *valuep = 0;
     451        return 1;
     452      }
     453  
     454    if (word_length > 8 * sizeof (CGEN_INSN_INT))
     455      abort ();
     456  
     457    /* For architectures with insns smaller than the insn-base-bitsize,
     458       word_length may be too big.  */
     459    if (cd->min_insn_bitsize < cd->base_insn_bitsize)
     460      {
     461        if (word_offset + word_length > total_length)
     462  	word_length = total_length - word_offset;
     463      }
     464  
     465    /* Does the value reside in INSN_VALUE, and at the right alignment?  */
     466  
     467    if (CGEN_INT_INSN_P || (word_offset == 0 && word_length == total_length))
     468      {
     469        if (CGEN_INSN_LSB0_P)
     470  	value = insn_value >> ((word_offset + start + 1) - length);
     471        else
     472  	value = insn_value >> (total_length - ( word_offset + start + length));
     473      }
     474  
     475  #if ! CGEN_INT_INSN_P
     476  
     477    else
     478      {
     479        unsigned char *bufp = ex_info->insn_bytes + word_offset / 8;
     480  
     481        if (word_length > 8 * sizeof (CGEN_INSN_INT))
     482  	abort ();
     483  
     484        if (fill_cache (cd, ex_info, word_offset / 8, word_length / 8, pc) == 0)
     485  	{
     486  	  *valuep = 0;
     487  	  return 0;
     488  	}
     489  
     490        value = extract_1 (cd, ex_info, start, length, word_length, bufp, pc);
     491      }
     492  
     493  #endif /* ! CGEN_INT_INSN_P */
     494  
     495    /* Written this way to avoid undefined behaviour.  */
     496    mask = (1UL << (length - 1) << 1) - 1;
     497  
     498    value &= mask;
     499    /* sign extend? */
     500    if (CGEN_BOOL_ATTR (attrs, CGEN_IFLD_SIGNED)
     501        && (value & (1UL << (length - 1))))
     502      value |= ~mask;
     503  
     504    *valuep = value;
     505  
     506    return 1;
     507  }
     508  
     509  /* Default insn extractor.
     510  
     511     INSN_VALUE is the first base_insn_bitsize bits, translated to host order.
     512     The extracted fields are stored in FIELDS.
     513     EX_INFO is used to handle reading variable length insns.
     514     Return the length of the insn in bits, or 0 if no match,
     515     or -1 if an error occurs fetching data (memory_error_func will have
     516     been called).  */
     517  
     518  static int
     519  extract_insn_normal (CGEN_CPU_DESC cd,
     520  		     const CGEN_INSN *insn,
     521  		     CGEN_EXTRACT_INFO *ex_info,
     522  		     CGEN_INSN_INT insn_value,
     523  		     CGEN_FIELDS *fields,
     524  		     bfd_vma pc)
     525  {
     526    const CGEN_SYNTAX *syntax = CGEN_INSN_SYNTAX (insn);
     527    const CGEN_SYNTAX_CHAR_TYPE *syn;
     528  
     529    CGEN_FIELDS_BITSIZE (fields) = CGEN_INSN_BITSIZE (insn);
     530  
     531    CGEN_INIT_EXTRACT (cd);
     532  
     533    for (syn = CGEN_SYNTAX_STRING (syntax); *syn; ++syn)
     534      {
     535        int length;
     536  
     537        if (CGEN_SYNTAX_CHAR_P (*syn))
     538  	continue;
     539  
     540        length = (* cd->extract_operand) (cd, CGEN_SYNTAX_FIELD (*syn),
     541  					ex_info, insn_value, fields, pc);
     542        if (length <= 0)
     543  	return length;
     544      }
     545  
     546    /* We recognized and successfully extracted this insn.  */
     547    return CGEN_INSN_BITSIZE (insn);
     548  }
     549  
     550  /* Machine generated code added here.  */
     551  
     552  const char * fr30_cgen_insert_operand
     553    (CGEN_CPU_DESC, int, CGEN_FIELDS *, CGEN_INSN_BYTES_PTR, bfd_vma);
     554  
     555  /* Main entry point for operand insertion.
     556  
     557     This function is basically just a big switch statement.  Earlier versions
     558     used tables to look up the function to use, but
     559     - if the table contains both assembler and disassembler functions then
     560       the disassembler contains much of the assembler and vice-versa,
     561     - there's a lot of inlining possibilities as things grow,
     562     - using a switch statement avoids the function call overhead.
     563  
     564     This function could be moved into `parse_insn_normal', but keeping it
     565     separate makes clear the interface between `parse_insn_normal' and each of
     566     the handlers.  It's also needed by GAS to insert operands that couldn't be
     567     resolved during parsing.  */
     568  
     569  const char *
     570  fr30_cgen_insert_operand (CGEN_CPU_DESC cd,
     571  			     int opindex,
     572  			     CGEN_FIELDS * fields,
     573  			     CGEN_INSN_BYTES_PTR buffer,
     574  			     bfd_vma pc ATTRIBUTE_UNUSED)
     575  {
     576    const char * errmsg = NULL;
     577    unsigned int total_length = CGEN_FIELDS_BITSIZE (fields);
     578  
     579    switch (opindex)
     580      {
     581      case FR30_OPERAND_CRI :
     582        errmsg = insert_normal (cd, fields->f_CRi, 0, 16, 12, 4, 16, total_length, buffer);
     583        break;
     584      case FR30_OPERAND_CRJ :
     585        errmsg = insert_normal (cd, fields->f_CRj, 0, 16, 8, 4, 16, total_length, buffer);
     586        break;
     587      case FR30_OPERAND_R13 :
     588        break;
     589      case FR30_OPERAND_R14 :
     590        break;
     591      case FR30_OPERAND_R15 :
     592        break;
     593      case FR30_OPERAND_RI :
     594        errmsg = insert_normal (cd, fields->f_Ri, 0, 0, 12, 4, 16, total_length, buffer);
     595        break;
     596      case FR30_OPERAND_RIC :
     597        errmsg = insert_normal (cd, fields->f_Ric, 0, 16, 12, 4, 16, total_length, buffer);
     598        break;
     599      case FR30_OPERAND_RJ :
     600        errmsg = insert_normal (cd, fields->f_Rj, 0, 0, 8, 4, 16, total_length, buffer);
     601        break;
     602      case FR30_OPERAND_RJC :
     603        errmsg = insert_normal (cd, fields->f_Rjc, 0, 16, 8, 4, 16, total_length, buffer);
     604        break;
     605      case FR30_OPERAND_RS1 :
     606        errmsg = insert_normal (cd, fields->f_Rs1, 0, 0, 8, 4, 16, total_length, buffer);
     607        break;
     608      case FR30_OPERAND_RS2 :
     609        errmsg = insert_normal (cd, fields->f_Rs2, 0, 0, 12, 4, 16, total_length, buffer);
     610        break;
     611      case FR30_OPERAND_CC :
     612        errmsg = insert_normal (cd, fields->f_cc, 0, 0, 4, 4, 16, total_length, buffer);
     613        break;
     614      case FR30_OPERAND_CCC :
     615        errmsg = insert_normal (cd, fields->f_ccc, 0, 16, 0, 8, 16, total_length, buffer);
     616        break;
     617      case FR30_OPERAND_DIR10 :
     618        {
     619          long value = fields->f_dir10;
     620          value = ((USI) (value) >> (2));
     621          errmsg = insert_normal (cd, value, 0, 0, 8, 8, 16, total_length, buffer);
     622        }
     623        break;
     624      case FR30_OPERAND_DIR8 :
     625        errmsg = insert_normal (cd, fields->f_dir8, 0, 0, 8, 8, 16, total_length, buffer);
     626        break;
     627      case FR30_OPERAND_DIR9 :
     628        {
     629          long value = fields->f_dir9;
     630          value = ((USI) (value) >> (1));
     631          errmsg = insert_normal (cd, value, 0, 0, 8, 8, 16, total_length, buffer);
     632        }
     633        break;
     634      case FR30_OPERAND_DISP10 :
     635        {
     636          long value = fields->f_disp10;
     637          value = ((SI) (value) >> (2));
     638          errmsg = insert_normal (cd, value, 0|(1<<CGEN_IFLD_SIGNED), 0, 4, 8, 16, total_length, buffer);
     639        }
     640        break;
     641      case FR30_OPERAND_DISP8 :
     642        errmsg = insert_normal (cd, fields->f_disp8, 0|(1<<CGEN_IFLD_SIGNED), 0, 4, 8, 16, total_length, buffer);
     643        break;
     644      case FR30_OPERAND_DISP9 :
     645        {
     646          long value = fields->f_disp9;
     647          value = ((SI) (value) >> (1));
     648          errmsg = insert_normal (cd, value, 0|(1<<CGEN_IFLD_SIGNED), 0, 4, 8, 16, total_length, buffer);
     649        }
     650        break;
     651      case FR30_OPERAND_I20 :
     652        {
     653  {
     654    FLD (f_i20_4) = ((UINT) (FLD (f_i20)) >> (16));
     655    FLD (f_i20_16) = ((FLD (f_i20)) & (65535));
     656  }
     657          errmsg = insert_normal (cd, fields->f_i20_4, 0, 0, 8, 4, 16, total_length, buffer);
     658          if (errmsg)
     659            break;
     660          errmsg = insert_normal (cd, fields->f_i20_16, 0, 16, 0, 16, 16, total_length, buffer);
     661          if (errmsg)
     662            break;
     663        }
     664        break;
     665      case FR30_OPERAND_I32 :
     666        errmsg = insert_normal (cd, fields->f_i32, 0|(1<<CGEN_IFLD_SIGN_OPT), 16, 0, 32, 32, total_length, buffer);
     667        break;
     668      case FR30_OPERAND_I8 :
     669        errmsg = insert_normal (cd, fields->f_i8, 0, 0, 4, 8, 16, total_length, buffer);
     670        break;
     671      case FR30_OPERAND_LABEL12 :
     672        {
     673          long value = fields->f_rel12;
     674          value = ((SI) (((value) - (((pc) + (2))))) >> (1));
     675          errmsg = insert_normal (cd, value, 0|(1<<CGEN_IFLD_SIGNED)|(1<<CGEN_IFLD_PCREL_ADDR), 0, 5, 11, 16, total_length, buffer);
     676        }
     677        break;
     678      case FR30_OPERAND_LABEL9 :
     679        {
     680          long value = fields->f_rel9;
     681          value = ((SI) (((value) - (((pc) + (2))))) >> (1));
     682          errmsg = insert_normal (cd, value, 0|(1<<CGEN_IFLD_SIGNED)|(1<<CGEN_IFLD_PCREL_ADDR), 0, 8, 8, 16, total_length, buffer);
     683        }
     684        break;
     685      case FR30_OPERAND_M4 :
     686        {
     687          long value = fields->f_m4;
     688          value = ((value) & (15));
     689          errmsg = insert_normal (cd, value, 0, 0, 8, 4, 16, total_length, buffer);
     690        }
     691        break;
     692      case FR30_OPERAND_PS :
     693        break;
     694      case FR30_OPERAND_REGLIST_HI_LD :
     695        errmsg = insert_normal (cd, fields->f_reglist_hi_ld, 0, 0, 8, 8, 16, total_length, buffer);
     696        break;
     697      case FR30_OPERAND_REGLIST_HI_ST :
     698        errmsg = insert_normal (cd, fields->f_reglist_hi_st, 0, 0, 8, 8, 16, total_length, buffer);
     699        break;
     700      case FR30_OPERAND_REGLIST_LOW_LD :
     701        errmsg = insert_normal (cd, fields->f_reglist_low_ld, 0, 0, 8, 8, 16, total_length, buffer);
     702        break;
     703      case FR30_OPERAND_REGLIST_LOW_ST :
     704        errmsg = insert_normal (cd, fields->f_reglist_low_st, 0, 0, 8, 8, 16, total_length, buffer);
     705        break;
     706      case FR30_OPERAND_S10 :
     707        {
     708          long value = fields->f_s10;
     709          value = ((SI) (value) >> (2));
     710          errmsg = insert_normal (cd, value, 0|(1<<CGEN_IFLD_SIGNED), 0, 8, 8, 16, total_length, buffer);
     711        }
     712        break;
     713      case FR30_OPERAND_U10 :
     714        {
     715          long value = fields->f_u10;
     716          value = ((USI) (value) >> (2));
     717          errmsg = insert_normal (cd, value, 0, 0, 8, 8, 16, total_length, buffer);
     718        }
     719        break;
     720      case FR30_OPERAND_U4 :
     721        errmsg = insert_normal (cd, fields->f_u4, 0, 0, 8, 4, 16, total_length, buffer);
     722        break;
     723      case FR30_OPERAND_U4C :
     724        errmsg = insert_normal (cd, fields->f_u4c, 0, 0, 12, 4, 16, total_length, buffer);
     725        break;
     726      case FR30_OPERAND_U8 :
     727        errmsg = insert_normal (cd, fields->f_u8, 0, 0, 8, 8, 16, total_length, buffer);
     728        break;
     729      case FR30_OPERAND_UDISP6 :
     730        {
     731          long value = fields->f_udisp6;
     732          value = ((USI) (value) >> (2));
     733          errmsg = insert_normal (cd, value, 0, 0, 8, 4, 16, total_length, buffer);
     734        }
     735        break;
     736  
     737      default :
     738        /* xgettext:c-format */
     739        opcodes_error_handler
     740  	(_("internal error: unrecognized field %d while building insn"),
     741  	 opindex);
     742        abort ();
     743    }
     744  
     745    return errmsg;
     746  }
     747  
     748  int fr30_cgen_extract_operand
     749    (CGEN_CPU_DESC, int, CGEN_EXTRACT_INFO *, CGEN_INSN_INT, CGEN_FIELDS *, bfd_vma);
     750  
     751  /* Main entry point for operand extraction.
     752     The result is <= 0 for error, >0 for success.
     753     ??? Actual values aren't well defined right now.
     754  
     755     This function is basically just a big switch statement.  Earlier versions
     756     used tables to look up the function to use, but
     757     - if the table contains both assembler and disassembler functions then
     758       the disassembler contains much of the assembler and vice-versa,
     759     - there's a lot of inlining possibilities as things grow,
     760     - using a switch statement avoids the function call overhead.
     761  
     762     This function could be moved into `print_insn_normal', but keeping it
     763     separate makes clear the interface between `print_insn_normal' and each of
     764     the handlers.  */
     765  
     766  int
     767  fr30_cgen_extract_operand (CGEN_CPU_DESC cd,
     768  			     int opindex,
     769  			     CGEN_EXTRACT_INFO *ex_info,
     770  			     CGEN_INSN_INT insn_value,
     771  			     CGEN_FIELDS * fields,
     772  			     bfd_vma pc)
     773  {
     774    /* Assume success (for those operands that are nops).  */
     775    int length = 1;
     776    unsigned int total_length = CGEN_FIELDS_BITSIZE (fields);
     777  
     778    switch (opindex)
     779      {
     780      case FR30_OPERAND_CRI :
     781        length = extract_normal (cd, ex_info, insn_value, 0, 16, 12, 4, 16, total_length, pc, & fields->f_CRi);
     782        break;
     783      case FR30_OPERAND_CRJ :
     784        length = extract_normal (cd, ex_info, insn_value, 0, 16, 8, 4, 16, total_length, pc, & fields->f_CRj);
     785        break;
     786      case FR30_OPERAND_R13 :
     787        break;
     788      case FR30_OPERAND_R14 :
     789        break;
     790      case FR30_OPERAND_R15 :
     791        break;
     792      case FR30_OPERAND_RI :
     793        length = extract_normal (cd, ex_info, insn_value, 0, 0, 12, 4, 16, total_length, pc, & fields->f_Ri);
     794        break;
     795      case FR30_OPERAND_RIC :
     796        length = extract_normal (cd, ex_info, insn_value, 0, 16, 12, 4, 16, total_length, pc, & fields->f_Ric);
     797        break;
     798      case FR30_OPERAND_RJ :
     799        length = extract_normal (cd, ex_info, insn_value, 0, 0, 8, 4, 16, total_length, pc, & fields->f_Rj);
     800        break;
     801      case FR30_OPERAND_RJC :
     802        length = extract_normal (cd, ex_info, insn_value, 0, 16, 8, 4, 16, total_length, pc, & fields->f_Rjc);
     803        break;
     804      case FR30_OPERAND_RS1 :
     805        length = extract_normal (cd, ex_info, insn_value, 0, 0, 8, 4, 16, total_length, pc, & fields->f_Rs1);
     806        break;
     807      case FR30_OPERAND_RS2 :
     808        length = extract_normal (cd, ex_info, insn_value, 0, 0, 12, 4, 16, total_length, pc, & fields->f_Rs2);
     809        break;
     810      case FR30_OPERAND_CC :
     811        length = extract_normal (cd, ex_info, insn_value, 0, 0, 4, 4, 16, total_length, pc, & fields->f_cc);
     812        break;
     813      case FR30_OPERAND_CCC :
     814        length = extract_normal (cd, ex_info, insn_value, 0, 16, 0, 8, 16, total_length, pc, & fields->f_ccc);
     815        break;
     816      case FR30_OPERAND_DIR10 :
     817        {
     818          long value;
     819          length = extract_normal (cd, ex_info, insn_value, 0, 0, 8, 8, 16, total_length, pc, & value);
     820          value = ((value) << (2));
     821          fields->f_dir10 = value;
     822        }
     823        break;
     824      case FR30_OPERAND_DIR8 :
     825        length = extract_normal (cd, ex_info, insn_value, 0, 0, 8, 8, 16, total_length, pc, & fields->f_dir8);
     826        break;
     827      case FR30_OPERAND_DIR9 :
     828        {
     829          long value;
     830          length = extract_normal (cd, ex_info, insn_value, 0, 0, 8, 8, 16, total_length, pc, & value);
     831          value = ((value) << (1));
     832          fields->f_dir9 = value;
     833        }
     834        break;
     835      case FR30_OPERAND_DISP10 :
     836        {
     837          long value;
     838          length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_SIGNED), 0, 4, 8, 16, total_length, pc, & value);
     839          value = ((value) * (4));
     840          fields->f_disp10 = value;
     841        }
     842        break;
     843      case FR30_OPERAND_DISP8 :
     844        length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_SIGNED), 0, 4, 8, 16, total_length, pc, & fields->f_disp8);
     845        break;
     846      case FR30_OPERAND_DISP9 :
     847        {
     848          long value;
     849          length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_SIGNED), 0, 4, 8, 16, total_length, pc, & value);
     850          value = ((value) * (2));
     851          fields->f_disp9 = value;
     852        }
     853        break;
     854      case FR30_OPERAND_I20 :
     855        {
     856          length = extract_normal (cd, ex_info, insn_value, 0, 0, 8, 4, 16, total_length, pc, & fields->f_i20_4);
     857          if (length <= 0) break;
     858          length = extract_normal (cd, ex_info, insn_value, 0, 16, 0, 16, 16, total_length, pc, & fields->f_i20_16);
     859          if (length <= 0) break;
     860  {
     861    FLD (f_i20) = ((((FLD (f_i20_4)) << (16))) | (FLD (f_i20_16)));
     862  }
     863        }
     864        break;
     865      case FR30_OPERAND_I32 :
     866        length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_SIGN_OPT), 16, 0, 32, 32, total_length, pc, & fields->f_i32);
     867        break;
     868      case FR30_OPERAND_I8 :
     869        length = extract_normal (cd, ex_info, insn_value, 0, 0, 4, 8, 16, total_length, pc, & fields->f_i8);
     870        break;
     871      case FR30_OPERAND_LABEL12 :
     872        {
     873          long value;
     874          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);
     875          value = ((((value) * (2))) + (((pc) + (2))));
     876          fields->f_rel12 = value;
     877        }
     878        break;
     879      case FR30_OPERAND_LABEL9 :
     880        {
     881          long value;
     882          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);
     883          value = ((((value) * (2))) + (((pc) + (2))));
     884          fields->f_rel9 = value;
     885        }
     886        break;
     887      case FR30_OPERAND_M4 :
     888        {
     889          long value;
     890          length = extract_normal (cd, ex_info, insn_value, 0, 0, 8, 4, 16, total_length, pc, & value);
     891          value = ((value) | (-16));
     892          fields->f_m4 = value;
     893        }
     894        break;
     895      case FR30_OPERAND_PS :
     896        break;
     897      case FR30_OPERAND_REGLIST_HI_LD :
     898        length = extract_normal (cd, ex_info, insn_value, 0, 0, 8, 8, 16, total_length, pc, & fields->f_reglist_hi_ld);
     899        break;
     900      case FR30_OPERAND_REGLIST_HI_ST :
     901        length = extract_normal (cd, ex_info, insn_value, 0, 0, 8, 8, 16, total_length, pc, & fields->f_reglist_hi_st);
     902        break;
     903      case FR30_OPERAND_REGLIST_LOW_LD :
     904        length = extract_normal (cd, ex_info, insn_value, 0, 0, 8, 8, 16, total_length, pc, & fields->f_reglist_low_ld);
     905        break;
     906      case FR30_OPERAND_REGLIST_LOW_ST :
     907        length = extract_normal (cd, ex_info, insn_value, 0, 0, 8, 8, 16, total_length, pc, & fields->f_reglist_low_st);
     908        break;
     909      case FR30_OPERAND_S10 :
     910        {
     911          long value;
     912          length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_SIGNED), 0, 8, 8, 16, total_length, pc, & value);
     913          value = ((value) * (4));
     914          fields->f_s10 = value;
     915        }
     916        break;
     917      case FR30_OPERAND_U10 :
     918        {
     919          long value;
     920          length = extract_normal (cd, ex_info, insn_value, 0, 0, 8, 8, 16, total_length, pc, & value);
     921          value = ((value) << (2));
     922          fields->f_u10 = value;
     923        }
     924        break;
     925      case FR30_OPERAND_U4 :
     926        length = extract_normal (cd, ex_info, insn_value, 0, 0, 8, 4, 16, total_length, pc, & fields->f_u4);
     927        break;
     928      case FR30_OPERAND_U4C :
     929        length = extract_normal (cd, ex_info, insn_value, 0, 0, 12, 4, 16, total_length, pc, & fields->f_u4c);
     930        break;
     931      case FR30_OPERAND_U8 :
     932        length = extract_normal (cd, ex_info, insn_value, 0, 0, 8, 8, 16, total_length, pc, & fields->f_u8);
     933        break;
     934      case FR30_OPERAND_UDISP6 :
     935        {
     936          long value;
     937          length = extract_normal (cd, ex_info, insn_value, 0, 0, 8, 4, 16, total_length, pc, & value);
     938          value = ((value) << (2));
     939          fields->f_udisp6 = value;
     940        }
     941        break;
     942  
     943      default :
     944        /* xgettext:c-format */
     945        opcodes_error_handler
     946  	(_("internal error: unrecognized field %d while decoding insn"),
     947  	 opindex);
     948        abort ();
     949      }
     950  
     951    return length;
     952  }
     953  
     954  cgen_insert_fn * const fr30_cgen_insert_handlers[] =
     955  {
     956    insert_insn_normal,
     957  };
     958  
     959  cgen_extract_fn * const fr30_cgen_extract_handlers[] =
     960  {
     961    extract_insn_normal,
     962  };
     963  
     964  int fr30_cgen_get_int_operand     (CGEN_CPU_DESC, int, const CGEN_FIELDS *);
     965  bfd_vma fr30_cgen_get_vma_operand (CGEN_CPU_DESC, int, const CGEN_FIELDS *);
     966  
     967  /* Getting values from cgen_fields is handled by a collection of functions.
     968     They are distinguished by the type of the VALUE argument they return.
     969     TODO: floating point, inlining support, remove cases where result type
     970     not appropriate.  */
     971  
     972  int
     973  fr30_cgen_get_int_operand (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
     974  			     int opindex,
     975  			     const CGEN_FIELDS * fields)
     976  {
     977    int value;
     978  
     979    switch (opindex)
     980      {
     981      case FR30_OPERAND_CRI :
     982        value = fields->f_CRi;
     983        break;
     984      case FR30_OPERAND_CRJ :
     985        value = fields->f_CRj;
     986        break;
     987      case FR30_OPERAND_R13 :
     988        value = 0;
     989        break;
     990      case FR30_OPERAND_R14 :
     991        value = 0;
     992        break;
     993      case FR30_OPERAND_R15 :
     994        value = 0;
     995        break;
     996      case FR30_OPERAND_RI :
     997        value = fields->f_Ri;
     998        break;
     999      case FR30_OPERAND_RIC :
    1000        value = fields->f_Ric;
    1001        break;
    1002      case FR30_OPERAND_RJ :
    1003        value = fields->f_Rj;
    1004        break;
    1005      case FR30_OPERAND_RJC :
    1006        value = fields->f_Rjc;
    1007        break;
    1008      case FR30_OPERAND_RS1 :
    1009        value = fields->f_Rs1;
    1010        break;
    1011      case FR30_OPERAND_RS2 :
    1012        value = fields->f_Rs2;
    1013        break;
    1014      case FR30_OPERAND_CC :
    1015        value = fields->f_cc;
    1016        break;
    1017      case FR30_OPERAND_CCC :
    1018        value = fields->f_ccc;
    1019        break;
    1020      case FR30_OPERAND_DIR10 :
    1021        value = fields->f_dir10;
    1022        break;
    1023      case FR30_OPERAND_DIR8 :
    1024        value = fields->f_dir8;
    1025        break;
    1026      case FR30_OPERAND_DIR9 :
    1027        value = fields->f_dir9;
    1028        break;
    1029      case FR30_OPERAND_DISP10 :
    1030        value = fields->f_disp10;
    1031        break;
    1032      case FR30_OPERAND_DISP8 :
    1033        value = fields->f_disp8;
    1034        break;
    1035      case FR30_OPERAND_DISP9 :
    1036        value = fields->f_disp9;
    1037        break;
    1038      case FR30_OPERAND_I20 :
    1039        value = fields->f_i20;
    1040        break;
    1041      case FR30_OPERAND_I32 :
    1042        value = fields->f_i32;
    1043        break;
    1044      case FR30_OPERAND_I8 :
    1045        value = fields->f_i8;
    1046        break;
    1047      case FR30_OPERAND_LABEL12 :
    1048        value = fields->f_rel12;
    1049        break;
    1050      case FR30_OPERAND_LABEL9 :
    1051        value = fields->f_rel9;
    1052        break;
    1053      case FR30_OPERAND_M4 :
    1054        value = fields->f_m4;
    1055        break;
    1056      case FR30_OPERAND_PS :
    1057        value = 0;
    1058        break;
    1059      case FR30_OPERAND_REGLIST_HI_LD :
    1060        value = fields->f_reglist_hi_ld;
    1061        break;
    1062      case FR30_OPERAND_REGLIST_HI_ST :
    1063        value = fields->f_reglist_hi_st;
    1064        break;
    1065      case FR30_OPERAND_REGLIST_LOW_LD :
    1066        value = fields->f_reglist_low_ld;
    1067        break;
    1068      case FR30_OPERAND_REGLIST_LOW_ST :
    1069        value = fields->f_reglist_low_st;
    1070        break;
    1071      case FR30_OPERAND_S10 :
    1072        value = fields->f_s10;
    1073        break;
    1074      case FR30_OPERAND_U10 :
    1075        value = fields->f_u10;
    1076        break;
    1077      case FR30_OPERAND_U4 :
    1078        value = fields->f_u4;
    1079        break;
    1080      case FR30_OPERAND_U4C :
    1081        value = fields->f_u4c;
    1082        break;
    1083      case FR30_OPERAND_U8 :
    1084        value = fields->f_u8;
    1085        break;
    1086      case FR30_OPERAND_UDISP6 :
    1087        value = fields->f_udisp6;
    1088        break;
    1089  
    1090      default :
    1091        /* xgettext:c-format */
    1092        opcodes_error_handler
    1093  	(_("internal error: unrecognized field %d while getting int operand"),
    1094  	 opindex);
    1095        abort ();
    1096    }
    1097  
    1098    return value;
    1099  }
    1100  
    1101  bfd_vma
    1102  fr30_cgen_get_vma_operand (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
    1103  			     int opindex,
    1104  			     const CGEN_FIELDS * fields)
    1105  {
    1106    bfd_vma value;
    1107  
    1108    switch (opindex)
    1109      {
    1110      case FR30_OPERAND_CRI :
    1111        value = fields->f_CRi;
    1112        break;
    1113      case FR30_OPERAND_CRJ :
    1114        value = fields->f_CRj;
    1115        break;
    1116      case FR30_OPERAND_R13 :
    1117        value = 0;
    1118        break;
    1119      case FR30_OPERAND_R14 :
    1120        value = 0;
    1121        break;
    1122      case FR30_OPERAND_R15 :
    1123        value = 0;
    1124        break;
    1125      case FR30_OPERAND_RI :
    1126        value = fields->f_Ri;
    1127        break;
    1128      case FR30_OPERAND_RIC :
    1129        value = fields->f_Ric;
    1130        break;
    1131      case FR30_OPERAND_RJ :
    1132        value = fields->f_Rj;
    1133        break;
    1134      case FR30_OPERAND_RJC :
    1135        value = fields->f_Rjc;
    1136        break;
    1137      case FR30_OPERAND_RS1 :
    1138        value = fields->f_Rs1;
    1139        break;
    1140      case FR30_OPERAND_RS2 :
    1141        value = fields->f_Rs2;
    1142        break;
    1143      case FR30_OPERAND_CC :
    1144        value = fields->f_cc;
    1145        break;
    1146      case FR30_OPERAND_CCC :
    1147        value = fields->f_ccc;
    1148        break;
    1149      case FR30_OPERAND_DIR10 :
    1150        value = fields->f_dir10;
    1151        break;
    1152      case FR30_OPERAND_DIR8 :
    1153        value = fields->f_dir8;
    1154        break;
    1155      case FR30_OPERAND_DIR9 :
    1156        value = fields->f_dir9;
    1157        break;
    1158      case FR30_OPERAND_DISP10 :
    1159        value = fields->f_disp10;
    1160        break;
    1161      case FR30_OPERAND_DISP8 :
    1162        value = fields->f_disp8;
    1163        break;
    1164      case FR30_OPERAND_DISP9 :
    1165        value = fields->f_disp9;
    1166        break;
    1167      case FR30_OPERAND_I20 :
    1168        value = fields->f_i20;
    1169        break;
    1170      case FR30_OPERAND_I32 :
    1171        value = fields->f_i32;
    1172        break;
    1173      case FR30_OPERAND_I8 :
    1174        value = fields->f_i8;
    1175        break;
    1176      case FR30_OPERAND_LABEL12 :
    1177        value = fields->f_rel12;
    1178        break;
    1179      case FR30_OPERAND_LABEL9 :
    1180        value = fields->f_rel9;
    1181        break;
    1182      case FR30_OPERAND_M4 :
    1183        value = fields->f_m4;
    1184        break;
    1185      case FR30_OPERAND_PS :
    1186        value = 0;
    1187        break;
    1188      case FR30_OPERAND_REGLIST_HI_LD :
    1189        value = fields->f_reglist_hi_ld;
    1190        break;
    1191      case FR30_OPERAND_REGLIST_HI_ST :
    1192        value = fields->f_reglist_hi_st;
    1193        break;
    1194      case FR30_OPERAND_REGLIST_LOW_LD :
    1195        value = fields->f_reglist_low_ld;
    1196        break;
    1197      case FR30_OPERAND_REGLIST_LOW_ST :
    1198        value = fields->f_reglist_low_st;
    1199        break;
    1200      case FR30_OPERAND_S10 :
    1201        value = fields->f_s10;
    1202        break;
    1203      case FR30_OPERAND_U10 :
    1204        value = fields->f_u10;
    1205        break;
    1206      case FR30_OPERAND_U4 :
    1207        value = fields->f_u4;
    1208        break;
    1209      case FR30_OPERAND_U4C :
    1210        value = fields->f_u4c;
    1211        break;
    1212      case FR30_OPERAND_U8 :
    1213        value = fields->f_u8;
    1214        break;
    1215      case FR30_OPERAND_UDISP6 :
    1216        value = fields->f_udisp6;
    1217        break;
    1218  
    1219      default :
    1220        /* xgettext:c-format */
    1221        opcodes_error_handler
    1222  	(_("internal error: unrecognized field %d while getting vma operand"),
    1223  	 opindex);
    1224        abort ();
    1225    }
    1226  
    1227    return value;
    1228  }
    1229  
    1230  void fr30_cgen_set_int_operand  (CGEN_CPU_DESC, int, CGEN_FIELDS *, int);
    1231  void fr30_cgen_set_vma_operand  (CGEN_CPU_DESC, int, CGEN_FIELDS *, bfd_vma);
    1232  
    1233  /* Stuffing values in cgen_fields is handled by a collection of functions.
    1234     They are distinguished by the type of the VALUE argument they accept.
    1235     TODO: floating point, inlining support, remove cases where argument type
    1236     not appropriate.  */
    1237  
    1238  void
    1239  fr30_cgen_set_int_operand (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
    1240  			     int opindex,
    1241  			     CGEN_FIELDS * fields,
    1242  			     int value)
    1243  {
    1244    switch (opindex)
    1245      {
    1246      case FR30_OPERAND_CRI :
    1247        fields->f_CRi = value;
    1248        break;
    1249      case FR30_OPERAND_CRJ :
    1250        fields->f_CRj = value;
    1251        break;
    1252      case FR30_OPERAND_R13 :
    1253        break;
    1254      case FR30_OPERAND_R14 :
    1255        break;
    1256      case FR30_OPERAND_R15 :
    1257        break;
    1258      case FR30_OPERAND_RI :
    1259        fields->f_Ri = value;
    1260        break;
    1261      case FR30_OPERAND_RIC :
    1262        fields->f_Ric = value;
    1263        break;
    1264      case FR30_OPERAND_RJ :
    1265        fields->f_Rj = value;
    1266        break;
    1267      case FR30_OPERAND_RJC :
    1268        fields->f_Rjc = value;
    1269        break;
    1270      case FR30_OPERAND_RS1 :
    1271        fields->f_Rs1 = value;
    1272        break;
    1273      case FR30_OPERAND_RS2 :
    1274        fields->f_Rs2 = value;
    1275        break;
    1276      case FR30_OPERAND_CC :
    1277        fields->f_cc = value;
    1278        break;
    1279      case FR30_OPERAND_CCC :
    1280        fields->f_ccc = value;
    1281        break;
    1282      case FR30_OPERAND_DIR10 :
    1283        fields->f_dir10 = value;
    1284        break;
    1285      case FR30_OPERAND_DIR8 :
    1286        fields->f_dir8 = value;
    1287        break;
    1288      case FR30_OPERAND_DIR9 :
    1289        fields->f_dir9 = value;
    1290        break;
    1291      case FR30_OPERAND_DISP10 :
    1292        fields->f_disp10 = value;
    1293        break;
    1294      case FR30_OPERAND_DISP8 :
    1295        fields->f_disp8 = value;
    1296        break;
    1297      case FR30_OPERAND_DISP9 :
    1298        fields->f_disp9 = value;
    1299        break;
    1300      case FR30_OPERAND_I20 :
    1301        fields->f_i20 = value;
    1302        break;
    1303      case FR30_OPERAND_I32 :
    1304        fields->f_i32 = value;
    1305        break;
    1306      case FR30_OPERAND_I8 :
    1307        fields->f_i8 = value;
    1308        break;
    1309      case FR30_OPERAND_LABEL12 :
    1310        fields->f_rel12 = value;
    1311        break;
    1312      case FR30_OPERAND_LABEL9 :
    1313        fields->f_rel9 = value;
    1314        break;
    1315      case FR30_OPERAND_M4 :
    1316        fields->f_m4 = value;
    1317        break;
    1318      case FR30_OPERAND_PS :
    1319        break;
    1320      case FR30_OPERAND_REGLIST_HI_LD :
    1321        fields->f_reglist_hi_ld = value;
    1322        break;
    1323      case FR30_OPERAND_REGLIST_HI_ST :
    1324        fields->f_reglist_hi_st = value;
    1325        break;
    1326      case FR30_OPERAND_REGLIST_LOW_LD :
    1327        fields->f_reglist_low_ld = value;
    1328        break;
    1329      case FR30_OPERAND_REGLIST_LOW_ST :
    1330        fields->f_reglist_low_st = value;
    1331        break;
    1332      case FR30_OPERAND_S10 :
    1333        fields->f_s10 = value;
    1334        break;
    1335      case FR30_OPERAND_U10 :
    1336        fields->f_u10 = value;
    1337        break;
    1338      case FR30_OPERAND_U4 :
    1339        fields->f_u4 = value;
    1340        break;
    1341      case FR30_OPERAND_U4C :
    1342        fields->f_u4c = value;
    1343        break;
    1344      case FR30_OPERAND_U8 :
    1345        fields->f_u8 = value;
    1346        break;
    1347      case FR30_OPERAND_UDISP6 :
    1348        fields->f_udisp6 = value;
    1349        break;
    1350  
    1351      default :
    1352        /* xgettext:c-format */
    1353        opcodes_error_handler
    1354  	(_("internal error: unrecognized field %d while setting int operand"),
    1355  	 opindex);
    1356        abort ();
    1357    }
    1358  }
    1359  
    1360  void
    1361  fr30_cgen_set_vma_operand (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
    1362  			     int opindex,
    1363  			     CGEN_FIELDS * fields,
    1364  			     bfd_vma value)
    1365  {
    1366    switch (opindex)
    1367      {
    1368      case FR30_OPERAND_CRI :
    1369        fields->f_CRi = value;
    1370        break;
    1371      case FR30_OPERAND_CRJ :
    1372        fields->f_CRj = value;
    1373        break;
    1374      case FR30_OPERAND_R13 :
    1375        break;
    1376      case FR30_OPERAND_R14 :
    1377        break;
    1378      case FR30_OPERAND_R15 :
    1379        break;
    1380      case FR30_OPERAND_RI :
    1381        fields->f_Ri = value;
    1382        break;
    1383      case FR30_OPERAND_RIC :
    1384        fields->f_Ric = value;
    1385        break;
    1386      case FR30_OPERAND_RJ :
    1387        fields->f_Rj = value;
    1388        break;
    1389      case FR30_OPERAND_RJC :
    1390        fields->f_Rjc = value;
    1391        break;
    1392      case FR30_OPERAND_RS1 :
    1393        fields->f_Rs1 = value;
    1394        break;
    1395      case FR30_OPERAND_RS2 :
    1396        fields->f_Rs2 = value;
    1397        break;
    1398      case FR30_OPERAND_CC :
    1399        fields->f_cc = value;
    1400        break;
    1401      case FR30_OPERAND_CCC :
    1402        fields->f_ccc = value;
    1403        break;
    1404      case FR30_OPERAND_DIR10 :
    1405        fields->f_dir10 = value;
    1406        break;
    1407      case FR30_OPERAND_DIR8 :
    1408        fields->f_dir8 = value;
    1409        break;
    1410      case FR30_OPERAND_DIR9 :
    1411        fields->f_dir9 = value;
    1412        break;
    1413      case FR30_OPERAND_DISP10 :
    1414        fields->f_disp10 = value;
    1415        break;
    1416      case FR30_OPERAND_DISP8 :
    1417        fields->f_disp8 = value;
    1418        break;
    1419      case FR30_OPERAND_DISP9 :
    1420        fields->f_disp9 = value;
    1421        break;
    1422      case FR30_OPERAND_I20 :
    1423        fields->f_i20 = value;
    1424        break;
    1425      case FR30_OPERAND_I32 :
    1426        fields->f_i32 = value;
    1427        break;
    1428      case FR30_OPERAND_I8 :
    1429        fields->f_i8 = value;
    1430        break;
    1431      case FR30_OPERAND_LABEL12 :
    1432        fields->f_rel12 = value;
    1433        break;
    1434      case FR30_OPERAND_LABEL9 :
    1435        fields->f_rel9 = value;
    1436        break;
    1437      case FR30_OPERAND_M4 :
    1438        fields->f_m4 = value;
    1439        break;
    1440      case FR30_OPERAND_PS :
    1441        break;
    1442      case FR30_OPERAND_REGLIST_HI_LD :
    1443        fields->f_reglist_hi_ld = value;
    1444        break;
    1445      case FR30_OPERAND_REGLIST_HI_ST :
    1446        fields->f_reglist_hi_st = value;
    1447        break;
    1448      case FR30_OPERAND_REGLIST_LOW_LD :
    1449        fields->f_reglist_low_ld = value;
    1450        break;
    1451      case FR30_OPERAND_REGLIST_LOW_ST :
    1452        fields->f_reglist_low_st = value;
    1453        break;
    1454      case FR30_OPERAND_S10 :
    1455        fields->f_s10 = value;
    1456        break;
    1457      case FR30_OPERAND_U10 :
    1458        fields->f_u10 = value;
    1459        break;
    1460      case FR30_OPERAND_U4 :
    1461        fields->f_u4 = value;
    1462        break;
    1463      case FR30_OPERAND_U4C :
    1464        fields->f_u4c = value;
    1465        break;
    1466      case FR30_OPERAND_U8 :
    1467        fields->f_u8 = value;
    1468        break;
    1469      case FR30_OPERAND_UDISP6 :
    1470        fields->f_udisp6 = value;
    1471        break;
    1472  
    1473      default :
    1474        /* xgettext:c-format */
    1475        opcodes_error_handler
    1476  	(_("internal error: unrecognized field %d while setting vma operand"),
    1477  	 opindex);
    1478        abort ();
    1479    }
    1480  }
    1481  
    1482  /* Function to call before using the instruction builder tables.  */
    1483  
    1484  void
    1485  fr30_cgen_init_ibld_table (CGEN_CPU_DESC cd)
    1486  {
    1487    cd->insert_handlers = & fr30_cgen_insert_handlers[0];
    1488    cd->extract_handlers = & fr30_cgen_extract_handlers[0];
    1489  
    1490    cd->insert_operand = fr30_cgen_insert_operand;
    1491    cd->extract_operand = fr30_cgen_extract_operand;
    1492  
    1493    cd->get_int_operand = fr30_cgen_get_int_operand;
    1494    cd->set_int_operand = fr30_cgen_set_int_operand;
    1495    cd->get_vma_operand = fr30_cgen_get_vma_operand;
    1496    cd->set_vma_operand = fr30_cgen_set_vma_operand;
    1497  }