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