(root)/
binutils-2.41/
opcodes/
iq2000-ibld.c
       1  /* DO NOT EDIT!  -*- buffer-read-only: t -*- vi:set ro:  */
       2  /* Instruction building/extraction support for iq2000. -*- 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 "iq2000-desc.h"
      35  #include "iq2000-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 * iq2000_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  iq2000_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 IQ2000_OPERAND__INDEX :
     582        errmsg = insert_normal (cd, fields->f_index, 0, 0, 8, 9, 32, total_length, buffer);
     583        break;
     584      case IQ2000_OPERAND_BASE :
     585        errmsg = insert_normal (cd, fields->f_rs, 0, 0, 25, 5, 32, total_length, buffer);
     586        break;
     587      case IQ2000_OPERAND_BASEOFF :
     588        errmsg = insert_normal (cd, fields->f_imm, 0, 0, 15, 16, 32, total_length, buffer);
     589        break;
     590      case IQ2000_OPERAND_BITNUM :
     591        errmsg = insert_normal (cd, fields->f_rt, 0, 0, 20, 5, 32, total_length, buffer);
     592        break;
     593      case IQ2000_OPERAND_BYTECOUNT :
     594        errmsg = insert_normal (cd, fields->f_bytecount, 0, 0, 7, 8, 32, total_length, buffer);
     595        break;
     596      case IQ2000_OPERAND_CAM_Y :
     597        errmsg = insert_normal (cd, fields->f_cam_y, 0, 0, 2, 3, 32, total_length, buffer);
     598        break;
     599      case IQ2000_OPERAND_CAM_Z :
     600        errmsg = insert_normal (cd, fields->f_cam_z, 0, 0, 5, 3, 32, total_length, buffer);
     601        break;
     602      case IQ2000_OPERAND_CM_3FUNC :
     603        errmsg = insert_normal (cd, fields->f_cm_3func, 0, 0, 5, 3, 32, total_length, buffer);
     604        break;
     605      case IQ2000_OPERAND_CM_3Z :
     606        errmsg = insert_normal (cd, fields->f_cm_3z, 0, 0, 1, 2, 32, total_length, buffer);
     607        break;
     608      case IQ2000_OPERAND_CM_4FUNC :
     609        errmsg = insert_normal (cd, fields->f_cm_4func, 0, 0, 5, 4, 32, total_length, buffer);
     610        break;
     611      case IQ2000_OPERAND_CM_4Z :
     612        errmsg = insert_normal (cd, fields->f_cm_4z, 0, 0, 2, 3, 32, total_length, buffer);
     613        break;
     614      case IQ2000_OPERAND_COUNT :
     615        errmsg = insert_normal (cd, fields->f_count, 0, 0, 15, 7, 32, total_length, buffer);
     616        break;
     617      case IQ2000_OPERAND_EXECODE :
     618        errmsg = insert_normal (cd, fields->f_excode, 0, 0, 25, 20, 32, total_length, buffer);
     619        break;
     620      case IQ2000_OPERAND_HI16 :
     621        errmsg = insert_normal (cd, fields->f_imm, 0, 0, 15, 16, 32, total_length, buffer);
     622        break;
     623      case IQ2000_OPERAND_IMM :
     624        errmsg = insert_normal (cd, fields->f_imm, 0, 0, 15, 16, 32, total_length, buffer);
     625        break;
     626      case IQ2000_OPERAND_JMPTARG :
     627        {
     628          long value = fields->f_jtarg;
     629          value = ((USI) (((value) & (262143))) >> (2));
     630          errmsg = insert_normal (cd, value, 0|(1<<CGEN_IFLD_ABS_ADDR), 0, 15, 16, 32, total_length, buffer);
     631        }
     632        break;
     633      case IQ2000_OPERAND_JMPTARGQ10 :
     634        {
     635          long value = fields->f_jtargq10;
     636          value = ((USI) (((value) & (8388607))) >> (2));
     637          errmsg = insert_normal (cd, value, 0|(1<<CGEN_IFLD_ABS_ADDR), 0, 20, 21, 32, total_length, buffer);
     638        }
     639        break;
     640      case IQ2000_OPERAND_LO16 :
     641        errmsg = insert_normal (cd, fields->f_imm, 0, 0, 15, 16, 32, total_length, buffer);
     642        break;
     643      case IQ2000_OPERAND_MASK :
     644        errmsg = insert_normal (cd, fields->f_mask, 0, 0, 9, 4, 32, total_length, buffer);
     645        break;
     646      case IQ2000_OPERAND_MASKL :
     647        errmsg = insert_normal (cd, fields->f_maskl, 0, 0, 4, 5, 32, total_length, buffer);
     648        break;
     649      case IQ2000_OPERAND_MASKQ10 :
     650        errmsg = insert_normal (cd, fields->f_maskq10, 0, 0, 10, 5, 32, total_length, buffer);
     651        break;
     652      case IQ2000_OPERAND_MASKR :
     653        errmsg = insert_normal (cd, fields->f_rs, 0, 0, 25, 5, 32, total_length, buffer);
     654        break;
     655      case IQ2000_OPERAND_MLO16 :
     656        errmsg = insert_normal (cd, fields->f_imm, 0, 0, 15, 16, 32, total_length, buffer);
     657        break;
     658      case IQ2000_OPERAND_OFFSET :
     659        {
     660          long value = fields->f_offset;
     661          value = ((SI) (((value) - (pc))) >> (2));
     662          errmsg = insert_normal (cd, value, 0|(1<<CGEN_IFLD_SIGNED)|(1<<CGEN_IFLD_PCREL_ADDR), 0, 15, 16, 32, total_length, buffer);
     663        }
     664        break;
     665      case IQ2000_OPERAND_RD :
     666        errmsg = insert_normal (cd, fields->f_rd, 0, 0, 15, 5, 32, total_length, buffer);
     667        break;
     668      case IQ2000_OPERAND_RD_RS :
     669        {
     670  {
     671    FLD (f_rd) = FLD (f_rd_rs);
     672    FLD (f_rs) = FLD (f_rd_rs);
     673  }
     674          errmsg = insert_normal (cd, fields->f_rd, 0, 0, 15, 5, 32, total_length, buffer);
     675          if (errmsg)
     676            break;
     677          errmsg = insert_normal (cd, fields->f_rs, 0, 0, 25, 5, 32, total_length, buffer);
     678          if (errmsg)
     679            break;
     680        }
     681        break;
     682      case IQ2000_OPERAND_RD_RT :
     683        {
     684  {
     685    FLD (f_rd) = FLD (f_rd_rt);
     686    FLD (f_rt) = FLD (f_rd_rt);
     687  }
     688          errmsg = insert_normal (cd, fields->f_rd, 0, 0, 15, 5, 32, total_length, buffer);
     689          if (errmsg)
     690            break;
     691          errmsg = insert_normal (cd, fields->f_rt, 0, 0, 20, 5, 32, total_length, buffer);
     692          if (errmsg)
     693            break;
     694        }
     695        break;
     696      case IQ2000_OPERAND_RS :
     697        errmsg = insert_normal (cd, fields->f_rs, 0, 0, 25, 5, 32, total_length, buffer);
     698        break;
     699      case IQ2000_OPERAND_RT :
     700        errmsg = insert_normal (cd, fields->f_rt, 0, 0, 20, 5, 32, total_length, buffer);
     701        break;
     702      case IQ2000_OPERAND_RT_RS :
     703        {
     704  {
     705    FLD (f_rt) = FLD (f_rt_rs);
     706    FLD (f_rs) = FLD (f_rt_rs);
     707  }
     708          errmsg = insert_normal (cd, fields->f_rt, 0, 0, 20, 5, 32, total_length, buffer);
     709          if (errmsg)
     710            break;
     711          errmsg = insert_normal (cd, fields->f_rs, 0, 0, 25, 5, 32, total_length, buffer);
     712          if (errmsg)
     713            break;
     714        }
     715        break;
     716      case IQ2000_OPERAND_SHAMT :
     717        errmsg = insert_normal (cd, fields->f_shamt, 0, 0, 10, 5, 32, total_length, buffer);
     718        break;
     719  
     720      default :
     721        /* xgettext:c-format */
     722        opcodes_error_handler
     723  	(_("internal error: unrecognized field %d while building insn"),
     724  	 opindex);
     725        abort ();
     726    }
     727  
     728    return errmsg;
     729  }
     730  
     731  int iq2000_cgen_extract_operand
     732    (CGEN_CPU_DESC, int, CGEN_EXTRACT_INFO *, CGEN_INSN_INT, CGEN_FIELDS *, bfd_vma);
     733  
     734  /* Main entry point for operand extraction.
     735     The result is <= 0 for error, >0 for success.
     736     ??? Actual values aren't well defined right now.
     737  
     738     This function is basically just a big switch statement.  Earlier versions
     739     used tables to look up the function to use, but
     740     - if the table contains both assembler and disassembler functions then
     741       the disassembler contains much of the assembler and vice-versa,
     742     - there's a lot of inlining possibilities as things grow,
     743     - using a switch statement avoids the function call overhead.
     744  
     745     This function could be moved into `print_insn_normal', but keeping it
     746     separate makes clear the interface between `print_insn_normal' and each of
     747     the handlers.  */
     748  
     749  int
     750  iq2000_cgen_extract_operand (CGEN_CPU_DESC cd,
     751  			     int opindex,
     752  			     CGEN_EXTRACT_INFO *ex_info,
     753  			     CGEN_INSN_INT insn_value,
     754  			     CGEN_FIELDS * fields,
     755  			     bfd_vma pc)
     756  {
     757    /* Assume success (for those operands that are nops).  */
     758    int length = 1;
     759    unsigned int total_length = CGEN_FIELDS_BITSIZE (fields);
     760  
     761    switch (opindex)
     762      {
     763      case IQ2000_OPERAND__INDEX :
     764        length = extract_normal (cd, ex_info, insn_value, 0, 0, 8, 9, 32, total_length, pc, & fields->f_index);
     765        break;
     766      case IQ2000_OPERAND_BASE :
     767        length = extract_normal (cd, ex_info, insn_value, 0, 0, 25, 5, 32, total_length, pc, & fields->f_rs);
     768        break;
     769      case IQ2000_OPERAND_BASEOFF :
     770        length = extract_normal (cd, ex_info, insn_value, 0, 0, 15, 16, 32, total_length, pc, & fields->f_imm);
     771        break;
     772      case IQ2000_OPERAND_BITNUM :
     773        length = extract_normal (cd, ex_info, insn_value, 0, 0, 20, 5, 32, total_length, pc, & fields->f_rt);
     774        break;
     775      case IQ2000_OPERAND_BYTECOUNT :
     776        length = extract_normal (cd, ex_info, insn_value, 0, 0, 7, 8, 32, total_length, pc, & fields->f_bytecount);
     777        break;
     778      case IQ2000_OPERAND_CAM_Y :
     779        length = extract_normal (cd, ex_info, insn_value, 0, 0, 2, 3, 32, total_length, pc, & fields->f_cam_y);
     780        break;
     781      case IQ2000_OPERAND_CAM_Z :
     782        length = extract_normal (cd, ex_info, insn_value, 0, 0, 5, 3, 32, total_length, pc, & fields->f_cam_z);
     783        break;
     784      case IQ2000_OPERAND_CM_3FUNC :
     785        length = extract_normal (cd, ex_info, insn_value, 0, 0, 5, 3, 32, total_length, pc, & fields->f_cm_3func);
     786        break;
     787      case IQ2000_OPERAND_CM_3Z :
     788        length = extract_normal (cd, ex_info, insn_value, 0, 0, 1, 2, 32, total_length, pc, & fields->f_cm_3z);
     789        break;
     790      case IQ2000_OPERAND_CM_4FUNC :
     791        length = extract_normal (cd, ex_info, insn_value, 0, 0, 5, 4, 32, total_length, pc, & fields->f_cm_4func);
     792        break;
     793      case IQ2000_OPERAND_CM_4Z :
     794        length = extract_normal (cd, ex_info, insn_value, 0, 0, 2, 3, 32, total_length, pc, & fields->f_cm_4z);
     795        break;
     796      case IQ2000_OPERAND_COUNT :
     797        length = extract_normal (cd, ex_info, insn_value, 0, 0, 15, 7, 32, total_length, pc, & fields->f_count);
     798        break;
     799      case IQ2000_OPERAND_EXECODE :
     800        length = extract_normal (cd, ex_info, insn_value, 0, 0, 25, 20, 32, total_length, pc, & fields->f_excode);
     801        break;
     802      case IQ2000_OPERAND_HI16 :
     803        length = extract_normal (cd, ex_info, insn_value, 0, 0, 15, 16, 32, total_length, pc, & fields->f_imm);
     804        break;
     805      case IQ2000_OPERAND_IMM :
     806        length = extract_normal (cd, ex_info, insn_value, 0, 0, 15, 16, 32, total_length, pc, & fields->f_imm);
     807        break;
     808      case IQ2000_OPERAND_JMPTARG :
     809        {
     810          long value;
     811          length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_ABS_ADDR), 0, 15, 16, 32, total_length, pc, & value);
     812          value = ((((pc) & (0xf0000000))) | (((value) << (2))));
     813          fields->f_jtarg = value;
     814        }
     815        break;
     816      case IQ2000_OPERAND_JMPTARGQ10 :
     817        {
     818          long value;
     819          length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_ABS_ADDR), 0, 20, 21, 32, total_length, pc, & value);
     820          value = ((((pc) & (0xf0000000))) | (((value) << (2))));
     821          fields->f_jtargq10 = value;
     822        }
     823        break;
     824      case IQ2000_OPERAND_LO16 :
     825        length = extract_normal (cd, ex_info, insn_value, 0, 0, 15, 16, 32, total_length, pc, & fields->f_imm);
     826        break;
     827      case IQ2000_OPERAND_MASK :
     828        length = extract_normal (cd, ex_info, insn_value, 0, 0, 9, 4, 32, total_length, pc, & fields->f_mask);
     829        break;
     830      case IQ2000_OPERAND_MASKL :
     831        length = extract_normal (cd, ex_info, insn_value, 0, 0, 4, 5, 32, total_length, pc, & fields->f_maskl);
     832        break;
     833      case IQ2000_OPERAND_MASKQ10 :
     834        length = extract_normal (cd, ex_info, insn_value, 0, 0, 10, 5, 32, total_length, pc, & fields->f_maskq10);
     835        break;
     836      case IQ2000_OPERAND_MASKR :
     837        length = extract_normal (cd, ex_info, insn_value, 0, 0, 25, 5, 32, total_length, pc, & fields->f_rs);
     838        break;
     839      case IQ2000_OPERAND_MLO16 :
     840        length = extract_normal (cd, ex_info, insn_value, 0, 0, 15, 16, 32, total_length, pc, & fields->f_imm);
     841        break;
     842      case IQ2000_OPERAND_OFFSET :
     843        {
     844          long value;
     845          length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_SIGNED)|(1<<CGEN_IFLD_PCREL_ADDR), 0, 15, 16, 32, total_length, pc, & value);
     846          value = ((((value) * (4))) + (((pc) + (4))));
     847          fields->f_offset = value;
     848        }
     849        break;
     850      case IQ2000_OPERAND_RD :
     851        length = extract_normal (cd, ex_info, insn_value, 0, 0, 15, 5, 32, total_length, pc, & fields->f_rd);
     852        break;
     853      case IQ2000_OPERAND_RD_RS :
     854        {
     855          length = extract_normal (cd, ex_info, insn_value, 0, 0, 15, 5, 32, total_length, pc, & fields->f_rd);
     856          if (length <= 0) break;
     857          length = extract_normal (cd, ex_info, insn_value, 0, 0, 25, 5, 32, total_length, pc, & fields->f_rs);
     858          if (length <= 0) break;
     859  {
     860    FLD (f_rd_rs) = FLD (f_rs);
     861  }
     862        }
     863        break;
     864      case IQ2000_OPERAND_RD_RT :
     865        {
     866          length = extract_normal (cd, ex_info, insn_value, 0, 0, 15, 5, 32, total_length, pc, & fields->f_rd);
     867          if (length <= 0) break;
     868          length = extract_normal (cd, ex_info, insn_value, 0, 0, 20, 5, 32, total_length, pc, & fields->f_rt);
     869          if (length <= 0) break;
     870  {
     871    FLD (f_rd_rt) = FLD (f_rt);
     872  }
     873        }
     874        break;
     875      case IQ2000_OPERAND_RS :
     876        length = extract_normal (cd, ex_info, insn_value, 0, 0, 25, 5, 32, total_length, pc, & fields->f_rs);
     877        break;
     878      case IQ2000_OPERAND_RT :
     879        length = extract_normal (cd, ex_info, insn_value, 0, 0, 20, 5, 32, total_length, pc, & fields->f_rt);
     880        break;
     881      case IQ2000_OPERAND_RT_RS :
     882        {
     883          length = extract_normal (cd, ex_info, insn_value, 0, 0, 20, 5, 32, total_length, pc, & fields->f_rt);
     884          if (length <= 0) break;
     885          length = extract_normal (cd, ex_info, insn_value, 0, 0, 25, 5, 32, total_length, pc, & fields->f_rs);
     886          if (length <= 0) break;
     887  {
     888    FLD (f_rd_rs) = FLD (f_rs);
     889  }
     890        }
     891        break;
     892      case IQ2000_OPERAND_SHAMT :
     893        length = extract_normal (cd, ex_info, insn_value, 0, 0, 10, 5, 32, total_length, pc, & fields->f_shamt);
     894        break;
     895  
     896      default :
     897        /* xgettext:c-format */
     898        opcodes_error_handler
     899  	(_("internal error: unrecognized field %d while decoding insn"),
     900  	 opindex);
     901        abort ();
     902      }
     903  
     904    return length;
     905  }
     906  
     907  cgen_insert_fn * const iq2000_cgen_insert_handlers[] =
     908  {
     909    insert_insn_normal,
     910  };
     911  
     912  cgen_extract_fn * const iq2000_cgen_extract_handlers[] =
     913  {
     914    extract_insn_normal,
     915  };
     916  
     917  int iq2000_cgen_get_int_operand     (CGEN_CPU_DESC, int, const CGEN_FIELDS *);
     918  bfd_vma iq2000_cgen_get_vma_operand (CGEN_CPU_DESC, int, const CGEN_FIELDS *);
     919  
     920  /* Getting values from cgen_fields is handled by a collection of functions.
     921     They are distinguished by the type of the VALUE argument they return.
     922     TODO: floating point, inlining support, remove cases where result type
     923     not appropriate.  */
     924  
     925  int
     926  iq2000_cgen_get_int_operand (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
     927  			     int opindex,
     928  			     const CGEN_FIELDS * fields)
     929  {
     930    int value;
     931  
     932    switch (opindex)
     933      {
     934      case IQ2000_OPERAND__INDEX :
     935        value = fields->f_index;
     936        break;
     937      case IQ2000_OPERAND_BASE :
     938        value = fields->f_rs;
     939        break;
     940      case IQ2000_OPERAND_BASEOFF :
     941        value = fields->f_imm;
     942        break;
     943      case IQ2000_OPERAND_BITNUM :
     944        value = fields->f_rt;
     945        break;
     946      case IQ2000_OPERAND_BYTECOUNT :
     947        value = fields->f_bytecount;
     948        break;
     949      case IQ2000_OPERAND_CAM_Y :
     950        value = fields->f_cam_y;
     951        break;
     952      case IQ2000_OPERAND_CAM_Z :
     953        value = fields->f_cam_z;
     954        break;
     955      case IQ2000_OPERAND_CM_3FUNC :
     956        value = fields->f_cm_3func;
     957        break;
     958      case IQ2000_OPERAND_CM_3Z :
     959        value = fields->f_cm_3z;
     960        break;
     961      case IQ2000_OPERAND_CM_4FUNC :
     962        value = fields->f_cm_4func;
     963        break;
     964      case IQ2000_OPERAND_CM_4Z :
     965        value = fields->f_cm_4z;
     966        break;
     967      case IQ2000_OPERAND_COUNT :
     968        value = fields->f_count;
     969        break;
     970      case IQ2000_OPERAND_EXECODE :
     971        value = fields->f_excode;
     972        break;
     973      case IQ2000_OPERAND_HI16 :
     974        value = fields->f_imm;
     975        break;
     976      case IQ2000_OPERAND_IMM :
     977        value = fields->f_imm;
     978        break;
     979      case IQ2000_OPERAND_JMPTARG :
     980        value = fields->f_jtarg;
     981        break;
     982      case IQ2000_OPERAND_JMPTARGQ10 :
     983        value = fields->f_jtargq10;
     984        break;
     985      case IQ2000_OPERAND_LO16 :
     986        value = fields->f_imm;
     987        break;
     988      case IQ2000_OPERAND_MASK :
     989        value = fields->f_mask;
     990        break;
     991      case IQ2000_OPERAND_MASKL :
     992        value = fields->f_maskl;
     993        break;
     994      case IQ2000_OPERAND_MASKQ10 :
     995        value = fields->f_maskq10;
     996        break;
     997      case IQ2000_OPERAND_MASKR :
     998        value = fields->f_rs;
     999        break;
    1000      case IQ2000_OPERAND_MLO16 :
    1001        value = fields->f_imm;
    1002        break;
    1003      case IQ2000_OPERAND_OFFSET :
    1004        value = fields->f_offset;
    1005        break;
    1006      case IQ2000_OPERAND_RD :
    1007        value = fields->f_rd;
    1008        break;
    1009      case IQ2000_OPERAND_RD_RS :
    1010        value = fields->f_rd_rs;
    1011        break;
    1012      case IQ2000_OPERAND_RD_RT :
    1013        value = fields->f_rd_rt;
    1014        break;
    1015      case IQ2000_OPERAND_RS :
    1016        value = fields->f_rs;
    1017        break;
    1018      case IQ2000_OPERAND_RT :
    1019        value = fields->f_rt;
    1020        break;
    1021      case IQ2000_OPERAND_RT_RS :
    1022        value = fields->f_rt_rs;
    1023        break;
    1024      case IQ2000_OPERAND_SHAMT :
    1025        value = fields->f_shamt;
    1026        break;
    1027  
    1028      default :
    1029        /* xgettext:c-format */
    1030        opcodes_error_handler
    1031  	(_("internal error: unrecognized field %d while getting int operand"),
    1032  	 opindex);
    1033        abort ();
    1034    }
    1035  
    1036    return value;
    1037  }
    1038  
    1039  bfd_vma
    1040  iq2000_cgen_get_vma_operand (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
    1041  			     int opindex,
    1042  			     const CGEN_FIELDS * fields)
    1043  {
    1044    bfd_vma value;
    1045  
    1046    switch (opindex)
    1047      {
    1048      case IQ2000_OPERAND__INDEX :
    1049        value = fields->f_index;
    1050        break;
    1051      case IQ2000_OPERAND_BASE :
    1052        value = fields->f_rs;
    1053        break;
    1054      case IQ2000_OPERAND_BASEOFF :
    1055        value = fields->f_imm;
    1056        break;
    1057      case IQ2000_OPERAND_BITNUM :
    1058        value = fields->f_rt;
    1059        break;
    1060      case IQ2000_OPERAND_BYTECOUNT :
    1061        value = fields->f_bytecount;
    1062        break;
    1063      case IQ2000_OPERAND_CAM_Y :
    1064        value = fields->f_cam_y;
    1065        break;
    1066      case IQ2000_OPERAND_CAM_Z :
    1067        value = fields->f_cam_z;
    1068        break;
    1069      case IQ2000_OPERAND_CM_3FUNC :
    1070        value = fields->f_cm_3func;
    1071        break;
    1072      case IQ2000_OPERAND_CM_3Z :
    1073        value = fields->f_cm_3z;
    1074        break;
    1075      case IQ2000_OPERAND_CM_4FUNC :
    1076        value = fields->f_cm_4func;
    1077        break;
    1078      case IQ2000_OPERAND_CM_4Z :
    1079        value = fields->f_cm_4z;
    1080        break;
    1081      case IQ2000_OPERAND_COUNT :
    1082        value = fields->f_count;
    1083        break;
    1084      case IQ2000_OPERAND_EXECODE :
    1085        value = fields->f_excode;
    1086        break;
    1087      case IQ2000_OPERAND_HI16 :
    1088        value = fields->f_imm;
    1089        break;
    1090      case IQ2000_OPERAND_IMM :
    1091        value = fields->f_imm;
    1092        break;
    1093      case IQ2000_OPERAND_JMPTARG :
    1094        value = fields->f_jtarg;
    1095        break;
    1096      case IQ2000_OPERAND_JMPTARGQ10 :
    1097        value = fields->f_jtargq10;
    1098        break;
    1099      case IQ2000_OPERAND_LO16 :
    1100        value = fields->f_imm;
    1101        break;
    1102      case IQ2000_OPERAND_MASK :
    1103        value = fields->f_mask;
    1104        break;
    1105      case IQ2000_OPERAND_MASKL :
    1106        value = fields->f_maskl;
    1107        break;
    1108      case IQ2000_OPERAND_MASKQ10 :
    1109        value = fields->f_maskq10;
    1110        break;
    1111      case IQ2000_OPERAND_MASKR :
    1112        value = fields->f_rs;
    1113        break;
    1114      case IQ2000_OPERAND_MLO16 :
    1115        value = fields->f_imm;
    1116        break;
    1117      case IQ2000_OPERAND_OFFSET :
    1118        value = fields->f_offset;
    1119        break;
    1120      case IQ2000_OPERAND_RD :
    1121        value = fields->f_rd;
    1122        break;
    1123      case IQ2000_OPERAND_RD_RS :
    1124        value = fields->f_rd_rs;
    1125        break;
    1126      case IQ2000_OPERAND_RD_RT :
    1127        value = fields->f_rd_rt;
    1128        break;
    1129      case IQ2000_OPERAND_RS :
    1130        value = fields->f_rs;
    1131        break;
    1132      case IQ2000_OPERAND_RT :
    1133        value = fields->f_rt;
    1134        break;
    1135      case IQ2000_OPERAND_RT_RS :
    1136        value = fields->f_rt_rs;
    1137        break;
    1138      case IQ2000_OPERAND_SHAMT :
    1139        value = fields->f_shamt;
    1140        break;
    1141  
    1142      default :
    1143        /* xgettext:c-format */
    1144        opcodes_error_handler
    1145  	(_("internal error: unrecognized field %d while getting vma operand"),
    1146  	 opindex);
    1147        abort ();
    1148    }
    1149  
    1150    return value;
    1151  }
    1152  
    1153  void iq2000_cgen_set_int_operand  (CGEN_CPU_DESC, int, CGEN_FIELDS *, int);
    1154  void iq2000_cgen_set_vma_operand  (CGEN_CPU_DESC, int, CGEN_FIELDS *, bfd_vma);
    1155  
    1156  /* Stuffing values in cgen_fields is handled by a collection of functions.
    1157     They are distinguished by the type of the VALUE argument they accept.
    1158     TODO: floating point, inlining support, remove cases where argument type
    1159     not appropriate.  */
    1160  
    1161  void
    1162  iq2000_cgen_set_int_operand (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
    1163  			     int opindex,
    1164  			     CGEN_FIELDS * fields,
    1165  			     int value)
    1166  {
    1167    switch (opindex)
    1168      {
    1169      case IQ2000_OPERAND__INDEX :
    1170        fields->f_index = value;
    1171        break;
    1172      case IQ2000_OPERAND_BASE :
    1173        fields->f_rs = value;
    1174        break;
    1175      case IQ2000_OPERAND_BASEOFF :
    1176        fields->f_imm = value;
    1177        break;
    1178      case IQ2000_OPERAND_BITNUM :
    1179        fields->f_rt = value;
    1180        break;
    1181      case IQ2000_OPERAND_BYTECOUNT :
    1182        fields->f_bytecount = value;
    1183        break;
    1184      case IQ2000_OPERAND_CAM_Y :
    1185        fields->f_cam_y = value;
    1186        break;
    1187      case IQ2000_OPERAND_CAM_Z :
    1188        fields->f_cam_z = value;
    1189        break;
    1190      case IQ2000_OPERAND_CM_3FUNC :
    1191        fields->f_cm_3func = value;
    1192        break;
    1193      case IQ2000_OPERAND_CM_3Z :
    1194        fields->f_cm_3z = value;
    1195        break;
    1196      case IQ2000_OPERAND_CM_4FUNC :
    1197        fields->f_cm_4func = value;
    1198        break;
    1199      case IQ2000_OPERAND_CM_4Z :
    1200        fields->f_cm_4z = value;
    1201        break;
    1202      case IQ2000_OPERAND_COUNT :
    1203        fields->f_count = value;
    1204        break;
    1205      case IQ2000_OPERAND_EXECODE :
    1206        fields->f_excode = value;
    1207        break;
    1208      case IQ2000_OPERAND_HI16 :
    1209        fields->f_imm = value;
    1210        break;
    1211      case IQ2000_OPERAND_IMM :
    1212        fields->f_imm = value;
    1213        break;
    1214      case IQ2000_OPERAND_JMPTARG :
    1215        fields->f_jtarg = value;
    1216        break;
    1217      case IQ2000_OPERAND_JMPTARGQ10 :
    1218        fields->f_jtargq10 = value;
    1219        break;
    1220      case IQ2000_OPERAND_LO16 :
    1221        fields->f_imm = value;
    1222        break;
    1223      case IQ2000_OPERAND_MASK :
    1224        fields->f_mask = value;
    1225        break;
    1226      case IQ2000_OPERAND_MASKL :
    1227        fields->f_maskl = value;
    1228        break;
    1229      case IQ2000_OPERAND_MASKQ10 :
    1230        fields->f_maskq10 = value;
    1231        break;
    1232      case IQ2000_OPERAND_MASKR :
    1233        fields->f_rs = value;
    1234        break;
    1235      case IQ2000_OPERAND_MLO16 :
    1236        fields->f_imm = value;
    1237        break;
    1238      case IQ2000_OPERAND_OFFSET :
    1239        fields->f_offset = value;
    1240        break;
    1241      case IQ2000_OPERAND_RD :
    1242        fields->f_rd = value;
    1243        break;
    1244      case IQ2000_OPERAND_RD_RS :
    1245        fields->f_rd_rs = value;
    1246        break;
    1247      case IQ2000_OPERAND_RD_RT :
    1248        fields->f_rd_rt = value;
    1249        break;
    1250      case IQ2000_OPERAND_RS :
    1251        fields->f_rs = value;
    1252        break;
    1253      case IQ2000_OPERAND_RT :
    1254        fields->f_rt = value;
    1255        break;
    1256      case IQ2000_OPERAND_RT_RS :
    1257        fields->f_rt_rs = value;
    1258        break;
    1259      case IQ2000_OPERAND_SHAMT :
    1260        fields->f_shamt = value;
    1261        break;
    1262  
    1263      default :
    1264        /* xgettext:c-format */
    1265        opcodes_error_handler
    1266  	(_("internal error: unrecognized field %d while setting int operand"),
    1267  	 opindex);
    1268        abort ();
    1269    }
    1270  }
    1271  
    1272  void
    1273  iq2000_cgen_set_vma_operand (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
    1274  			     int opindex,
    1275  			     CGEN_FIELDS * fields,
    1276  			     bfd_vma value)
    1277  {
    1278    switch (opindex)
    1279      {
    1280      case IQ2000_OPERAND__INDEX :
    1281        fields->f_index = value;
    1282        break;
    1283      case IQ2000_OPERAND_BASE :
    1284        fields->f_rs = value;
    1285        break;
    1286      case IQ2000_OPERAND_BASEOFF :
    1287        fields->f_imm = value;
    1288        break;
    1289      case IQ2000_OPERAND_BITNUM :
    1290        fields->f_rt = value;
    1291        break;
    1292      case IQ2000_OPERAND_BYTECOUNT :
    1293        fields->f_bytecount = value;
    1294        break;
    1295      case IQ2000_OPERAND_CAM_Y :
    1296        fields->f_cam_y = value;
    1297        break;
    1298      case IQ2000_OPERAND_CAM_Z :
    1299        fields->f_cam_z = value;
    1300        break;
    1301      case IQ2000_OPERAND_CM_3FUNC :
    1302        fields->f_cm_3func = value;
    1303        break;
    1304      case IQ2000_OPERAND_CM_3Z :
    1305        fields->f_cm_3z = value;
    1306        break;
    1307      case IQ2000_OPERAND_CM_4FUNC :
    1308        fields->f_cm_4func = value;
    1309        break;
    1310      case IQ2000_OPERAND_CM_4Z :
    1311        fields->f_cm_4z = value;
    1312        break;
    1313      case IQ2000_OPERAND_COUNT :
    1314        fields->f_count = value;
    1315        break;
    1316      case IQ2000_OPERAND_EXECODE :
    1317        fields->f_excode = value;
    1318        break;
    1319      case IQ2000_OPERAND_HI16 :
    1320        fields->f_imm = value;
    1321        break;
    1322      case IQ2000_OPERAND_IMM :
    1323        fields->f_imm = value;
    1324        break;
    1325      case IQ2000_OPERAND_JMPTARG :
    1326        fields->f_jtarg = value;
    1327        break;
    1328      case IQ2000_OPERAND_JMPTARGQ10 :
    1329        fields->f_jtargq10 = value;
    1330        break;
    1331      case IQ2000_OPERAND_LO16 :
    1332        fields->f_imm = value;
    1333        break;
    1334      case IQ2000_OPERAND_MASK :
    1335        fields->f_mask = value;
    1336        break;
    1337      case IQ2000_OPERAND_MASKL :
    1338        fields->f_maskl = value;
    1339        break;
    1340      case IQ2000_OPERAND_MASKQ10 :
    1341        fields->f_maskq10 = value;
    1342        break;
    1343      case IQ2000_OPERAND_MASKR :
    1344        fields->f_rs = value;
    1345        break;
    1346      case IQ2000_OPERAND_MLO16 :
    1347        fields->f_imm = value;
    1348        break;
    1349      case IQ2000_OPERAND_OFFSET :
    1350        fields->f_offset = value;
    1351        break;
    1352      case IQ2000_OPERAND_RD :
    1353        fields->f_rd = value;
    1354        break;
    1355      case IQ2000_OPERAND_RD_RS :
    1356        fields->f_rd_rs = value;
    1357        break;
    1358      case IQ2000_OPERAND_RD_RT :
    1359        fields->f_rd_rt = value;
    1360        break;
    1361      case IQ2000_OPERAND_RS :
    1362        fields->f_rs = value;
    1363        break;
    1364      case IQ2000_OPERAND_RT :
    1365        fields->f_rt = value;
    1366        break;
    1367      case IQ2000_OPERAND_RT_RS :
    1368        fields->f_rt_rs = value;
    1369        break;
    1370      case IQ2000_OPERAND_SHAMT :
    1371        fields->f_shamt = value;
    1372        break;
    1373  
    1374      default :
    1375        /* xgettext:c-format */
    1376        opcodes_error_handler
    1377  	(_("internal error: unrecognized field %d while setting vma operand"),
    1378  	 opindex);
    1379        abort ();
    1380    }
    1381  }
    1382  
    1383  /* Function to call before using the instruction builder tables.  */
    1384  
    1385  void
    1386  iq2000_cgen_init_ibld_table (CGEN_CPU_DESC cd)
    1387  {
    1388    cd->insert_handlers = & iq2000_cgen_insert_handlers[0];
    1389    cd->extract_handlers = & iq2000_cgen_extract_handlers[0];
    1390  
    1391    cd->insert_operand = iq2000_cgen_insert_operand;
    1392    cd->extract_operand = iq2000_cgen_extract_operand;
    1393  
    1394    cd->get_int_operand = iq2000_cgen_get_int_operand;
    1395    cd->set_int_operand = iq2000_cgen_set_int_operand;
    1396    cd->get_vma_operand = iq2000_cgen_get_vma_operand;
    1397    cd->set_vma_operand = iq2000_cgen_set_vma_operand;
    1398  }