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