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