xref: /netbsd-src/external/gpl3/binutils.old/dist/opcodes/m32r-ibld.c (revision e992f068c547fd6e84b3f104dc2340adcc955732)
1ede78133Schristos /* DO NOT EDIT!  -*- buffer-read-only: t -*- vi:set ro:  */
275fd0b74Schristos /* Instruction building/extraction support for m32r. -*- C -*-
375fd0b74Schristos 
475fd0b74Schristos    THIS FILE IS MACHINE GENERATED WITH CGEN: Cpu tools GENerator.
575fd0b74Schristos    - the resultant file is machine generated, cgen-ibld.in isn't
675fd0b74Schristos 
7*e992f068Schristos    Copyright (C) 1996-2022 Free Software Foundation, Inc.
875fd0b74Schristos 
975fd0b74Schristos    This file is part of libopcodes.
1075fd0b74Schristos 
1175fd0b74Schristos    This library is free software; you can redistribute it and/or modify
1275fd0b74Schristos    it under the terms of the GNU General Public License as published by
1375fd0b74Schristos    the Free Software Foundation; either version 3, or (at your option)
1475fd0b74Schristos    any later version.
1575fd0b74Schristos 
1675fd0b74Schristos    It is distributed in the hope that it will be useful, but WITHOUT
1775fd0b74Schristos    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
1875fd0b74Schristos    or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
1975fd0b74Schristos    License for more details.
2075fd0b74Schristos 
2175fd0b74Schristos    You should have received a copy of the GNU General Public License
2275fd0b74Schristos    along with this program; if not, write to the Free Software Foundation, Inc.,
2375fd0b74Schristos    51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.  */
2475fd0b74Schristos 
2575fd0b74Schristos /* ??? Eventually more and more of this stuff can go to cpu-independent files.
2675fd0b74Schristos    Keep that in mind.  */
2775fd0b74Schristos 
2875fd0b74Schristos #include "sysdep.h"
2975fd0b74Schristos #include <stdio.h>
3075fd0b74Schristos #include "ansidecl.h"
3175fd0b74Schristos #include "dis-asm.h"
3275fd0b74Schristos #include "bfd.h"
3375fd0b74Schristos #include "symcat.h"
3475fd0b74Schristos #include "m32r-desc.h"
3575fd0b74Schristos #include "m32r-opc.h"
3675fd0b74Schristos #include "cgen/basic-modes.h"
3775fd0b74Schristos #include "opintl.h"
3875fd0b74Schristos #include "safe-ctype.h"
3975fd0b74Schristos 
4075fd0b74Schristos #undef  min
4175fd0b74Schristos #define min(a,b) ((a) < (b) ? (a) : (b))
4275fd0b74Schristos #undef  max
4375fd0b74Schristos #define max(a,b) ((a) > (b) ? (a) : (b))
4475fd0b74Schristos 
4575fd0b74Schristos /* Used by the ifield rtx function.  */
4675fd0b74Schristos #define FLD(f) (fields->f)
4775fd0b74Schristos 
4875fd0b74Schristos static const char * insert_normal
4975fd0b74Schristos   (CGEN_CPU_DESC, long, unsigned int, unsigned int, unsigned int,
5075fd0b74Schristos    unsigned int, unsigned int, unsigned int, CGEN_INSN_BYTES_PTR);
5175fd0b74Schristos static const char * insert_insn_normal
5275fd0b74Schristos   (CGEN_CPU_DESC, const CGEN_INSN *,
5375fd0b74Schristos    CGEN_FIELDS *, CGEN_INSN_BYTES_PTR, bfd_vma);
5475fd0b74Schristos static int extract_normal
5575fd0b74Schristos   (CGEN_CPU_DESC, CGEN_EXTRACT_INFO *, CGEN_INSN_INT,
5675fd0b74Schristos    unsigned int, unsigned int, unsigned int, unsigned int,
5775fd0b74Schristos    unsigned int, unsigned int, bfd_vma, long *);
5875fd0b74Schristos static int extract_insn_normal
5975fd0b74Schristos   (CGEN_CPU_DESC, const CGEN_INSN *, CGEN_EXTRACT_INFO *,
6075fd0b74Schristos    CGEN_INSN_INT, CGEN_FIELDS *, bfd_vma);
6175fd0b74Schristos #if CGEN_INT_INSN_P
6275fd0b74Schristos static void put_insn_int_value
6375fd0b74Schristos   (CGEN_CPU_DESC, CGEN_INSN_BYTES_PTR, int, int, CGEN_INSN_INT);
6475fd0b74Schristos #endif
6575fd0b74Schristos #if ! CGEN_INT_INSN_P
6675fd0b74Schristos static CGEN_INLINE void insert_1
6775fd0b74Schristos   (CGEN_CPU_DESC, unsigned long, int, int, int, unsigned char *);
6875fd0b74Schristos static CGEN_INLINE int fill_cache
6975fd0b74Schristos   (CGEN_CPU_DESC, CGEN_EXTRACT_INFO *,  int, int, bfd_vma);
7075fd0b74Schristos static CGEN_INLINE long extract_1
7175fd0b74Schristos   (CGEN_CPU_DESC, CGEN_EXTRACT_INFO *, int, int, int, unsigned char *, bfd_vma);
7275fd0b74Schristos #endif
7375fd0b74Schristos 
7475fd0b74Schristos /* Operand insertion.  */
7575fd0b74Schristos 
7675fd0b74Schristos #if ! CGEN_INT_INSN_P
7775fd0b74Schristos 
7875fd0b74Schristos /* Subroutine of insert_normal.  */
7975fd0b74Schristos 
8075fd0b74Schristos static CGEN_INLINE void
insert_1(CGEN_CPU_DESC cd,unsigned long value,int start,int length,int word_length,unsigned char * bufp)8175fd0b74Schristos insert_1 (CGEN_CPU_DESC cd,
8275fd0b74Schristos 	  unsigned long value,
8375fd0b74Schristos 	  int start,
8475fd0b74Schristos 	  int length,
8575fd0b74Schristos 	  int word_length,
8675fd0b74Schristos 	  unsigned char *bufp)
8775fd0b74Schristos {
8875fd0b74Schristos   unsigned long x, mask;
8975fd0b74Schristos   int shift;
9075fd0b74Schristos 
91*e992f068Schristos   x = cgen_get_insn_value (cd, bufp, word_length, cd->endian);
9275fd0b74Schristos 
9375fd0b74Schristos   /* Written this way to avoid undefined behaviour.  */
94*e992f068Schristos   mask = (1UL << (length - 1) << 1) - 1;
9575fd0b74Schristos   if (CGEN_INSN_LSB0_P)
9675fd0b74Schristos     shift = (start + 1) - length;
9775fd0b74Schristos   else
9875fd0b74Schristos     shift = (word_length - (start + length));
9975fd0b74Schristos   x = (x & ~(mask << shift)) | ((value & mask) << shift);
10075fd0b74Schristos 
101*e992f068Schristos   cgen_put_insn_value (cd, bufp, word_length, (bfd_vma) x, cd->endian);
10275fd0b74Schristos }
10375fd0b74Schristos 
10475fd0b74Schristos #endif /* ! CGEN_INT_INSN_P */
10575fd0b74Schristos 
10675fd0b74Schristos /* Default insertion routine.
10775fd0b74Schristos 
10875fd0b74Schristos    ATTRS is a mask of the boolean attributes.
10975fd0b74Schristos    WORD_OFFSET is the offset in bits from the start of the insn of the value.
11075fd0b74Schristos    WORD_LENGTH is the length of the word in bits in which the value resides.
11175fd0b74Schristos    START is the starting bit number in the word, architecture origin.
11275fd0b74Schristos    LENGTH is the length of VALUE in bits.
11375fd0b74Schristos    TOTAL_LENGTH is the total length of the insn in bits.
11475fd0b74Schristos 
11575fd0b74Schristos    The result is an error message or NULL if success.  */
11675fd0b74Schristos 
11775fd0b74Schristos /* ??? This duplicates functionality with bfd's howto table and
11875fd0b74Schristos    bfd_install_relocation.  */
11975fd0b74Schristos /* ??? This doesn't handle bfd_vma's.  Create another function when
12075fd0b74Schristos    necessary.  */
12175fd0b74Schristos 
12275fd0b74Schristos static const char *
insert_normal(CGEN_CPU_DESC cd,long value,unsigned int attrs,unsigned int word_offset,unsigned int start,unsigned int length,unsigned int word_length,unsigned int total_length,CGEN_INSN_BYTES_PTR buffer)12375fd0b74Schristos insert_normal (CGEN_CPU_DESC cd,
12475fd0b74Schristos 	       long value,
12575fd0b74Schristos 	       unsigned int attrs,
12675fd0b74Schristos 	       unsigned int word_offset,
12775fd0b74Schristos 	       unsigned int start,
12875fd0b74Schristos 	       unsigned int length,
12975fd0b74Schristos 	       unsigned int word_length,
13075fd0b74Schristos 	       unsigned int total_length,
13175fd0b74Schristos 	       CGEN_INSN_BYTES_PTR buffer)
13275fd0b74Schristos {
13375fd0b74Schristos   static char errbuf[100];
134*e992f068Schristos   unsigned long mask;
13575fd0b74Schristos 
13675fd0b74Schristos   /* If LENGTH is zero, this operand doesn't contribute to the value.  */
13775fd0b74Schristos   if (length == 0)
13875fd0b74Schristos     return NULL;
13975fd0b74Schristos 
140*e992f068Schristos   /* Written this way to avoid undefined behaviour.  */
141*e992f068Schristos   mask = (1UL << (length - 1) << 1) - 1;
142*e992f068Schristos 
14375fd0b74Schristos   if (word_length > 8 * sizeof (CGEN_INSN_INT))
14475fd0b74Schristos     abort ();
14575fd0b74Schristos 
14675fd0b74Schristos   /* For architectures with insns smaller than the base-insn-bitsize,
14775fd0b74Schristos      word_length may be too big.  */
14875fd0b74Schristos   if (cd->min_insn_bitsize < cd->base_insn_bitsize)
14975fd0b74Schristos     {
15075fd0b74Schristos       if (word_offset == 0
15175fd0b74Schristos 	  && word_length > total_length)
15275fd0b74Schristos 	word_length = total_length;
15375fd0b74Schristos     }
15475fd0b74Schristos 
15575fd0b74Schristos   /* Ensure VALUE will fit.  */
15675fd0b74Schristos   if (CGEN_BOOL_ATTR (attrs, CGEN_IFLD_SIGN_OPT))
15775fd0b74Schristos     {
158*e992f068Schristos       long minval = - (1UL << (length - 1));
15975fd0b74Schristos       unsigned long maxval = mask;
16075fd0b74Schristos 
16175fd0b74Schristos       if ((value > 0 && (unsigned long) value > maxval)
16275fd0b74Schristos 	  || value < minval)
16375fd0b74Schristos 	{
16475fd0b74Schristos 	  /* xgettext:c-format */
16575fd0b74Schristos 	  sprintf (errbuf,
16675fd0b74Schristos 		   _("operand out of range (%ld not between %ld and %lu)"),
16775fd0b74Schristos 		   value, minval, maxval);
16875fd0b74Schristos 	  return errbuf;
16975fd0b74Schristos 	}
17075fd0b74Schristos     }
17175fd0b74Schristos   else if (! CGEN_BOOL_ATTR (attrs, CGEN_IFLD_SIGNED))
17275fd0b74Schristos     {
17375fd0b74Schristos       unsigned long maxval = mask;
17475fd0b74Schristos       unsigned long val = (unsigned long) value;
17575fd0b74Schristos 
17675fd0b74Schristos       /* For hosts with a word size > 32 check to see if value has been sign
17775fd0b74Schristos 	 extended beyond 32 bits.  If so then ignore these higher sign bits
17875fd0b74Schristos 	 as the user is attempting to store a 32-bit signed value into an
17975fd0b74Schristos 	 unsigned 32-bit field which is allowed.  */
18075fd0b74Schristos       if (sizeof (unsigned long) > 4 && ((value >> 32) == -1))
18175fd0b74Schristos 	val &= 0xFFFFFFFF;
18275fd0b74Schristos 
18375fd0b74Schristos       if (val > maxval)
18475fd0b74Schristos 	{
18575fd0b74Schristos 	  /* xgettext:c-format */
18675fd0b74Schristos 	  sprintf (errbuf,
18775fd0b74Schristos 		   _("operand out of range (0x%lx not between 0 and 0x%lx)"),
18875fd0b74Schristos 		   val, maxval);
18975fd0b74Schristos 	  return errbuf;
19075fd0b74Schristos 	}
19175fd0b74Schristos     }
19275fd0b74Schristos   else
19375fd0b74Schristos     {
19475fd0b74Schristos       if (! cgen_signed_overflow_ok_p (cd))
19575fd0b74Schristos 	{
196*e992f068Schristos 	  long minval = - (1UL << (length - 1));
197*e992f068Schristos 	  long maxval =   (1UL << (length - 1)) - 1;
19875fd0b74Schristos 
19975fd0b74Schristos 	  if (value < minval || value > maxval)
20075fd0b74Schristos 	    {
20175fd0b74Schristos 	      sprintf
20275fd0b74Schristos 		/* xgettext:c-format */
20375fd0b74Schristos 		(errbuf, _("operand out of range (%ld not between %ld and %ld)"),
20475fd0b74Schristos 		 value, minval, maxval);
20575fd0b74Schristos 	      return errbuf;
20675fd0b74Schristos 	    }
20775fd0b74Schristos 	}
20875fd0b74Schristos     }
20975fd0b74Schristos 
21075fd0b74Schristos #if CGEN_INT_INSN_P
21175fd0b74Schristos 
21275fd0b74Schristos   {
21375fd0b74Schristos     int shift_within_word, shift_to_word, shift;
21475fd0b74Schristos 
21575fd0b74Schristos     /* How to shift the value to BIT0 of the word.  */
21675fd0b74Schristos     shift_to_word = total_length - (word_offset + word_length);
21775fd0b74Schristos 
21875fd0b74Schristos     /* How to shift the value to the field within the word.  */
21975fd0b74Schristos     if (CGEN_INSN_LSB0_P)
22075fd0b74Schristos       shift_within_word = start + 1 - length;
22175fd0b74Schristos     else
22275fd0b74Schristos       shift_within_word = word_length - start - length;
22375fd0b74Schristos 
22475fd0b74Schristos     /* The total SHIFT, then mask in the value.  */
22575fd0b74Schristos     shift = shift_to_word + shift_within_word;
22675fd0b74Schristos     *buffer = (*buffer & ~(mask << shift)) | ((value & mask) << shift);
22775fd0b74Schristos   }
22875fd0b74Schristos 
22975fd0b74Schristos #else /* ! CGEN_INT_INSN_P */
23075fd0b74Schristos 
23175fd0b74Schristos   {
23275fd0b74Schristos     unsigned char *bufp = (unsigned char *) buffer + word_offset / 8;
23375fd0b74Schristos 
23475fd0b74Schristos     insert_1 (cd, value, start, length, word_length, bufp);
23575fd0b74Schristos   }
23675fd0b74Schristos 
23775fd0b74Schristos #endif /* ! CGEN_INT_INSN_P */
23875fd0b74Schristos 
23975fd0b74Schristos   return NULL;
24075fd0b74Schristos }
24175fd0b74Schristos 
24275fd0b74Schristos /* Default insn builder (insert handler).
24375fd0b74Schristos    The instruction is recorded in CGEN_INT_INSN_P byte order (meaning
24475fd0b74Schristos    that if CGEN_INSN_BYTES_PTR is an int * and thus, the value is
24575fd0b74Schristos    recorded in host byte order, otherwise BUFFER is an array of bytes
24675fd0b74Schristos    and the value is recorded in target byte order).
24775fd0b74Schristos    The result is an error message or NULL if success.  */
24875fd0b74Schristos 
24975fd0b74Schristos static const char *
insert_insn_normal(CGEN_CPU_DESC cd,const CGEN_INSN * insn,CGEN_FIELDS * fields,CGEN_INSN_BYTES_PTR buffer,bfd_vma pc)25075fd0b74Schristos insert_insn_normal (CGEN_CPU_DESC cd,
25175fd0b74Schristos 		    const CGEN_INSN * insn,
25275fd0b74Schristos 		    CGEN_FIELDS * fields,
25375fd0b74Schristos 		    CGEN_INSN_BYTES_PTR buffer,
25475fd0b74Schristos 		    bfd_vma pc)
25575fd0b74Schristos {
25675fd0b74Schristos   const CGEN_SYNTAX *syntax = CGEN_INSN_SYNTAX (insn);
25775fd0b74Schristos   unsigned long value;
25875fd0b74Schristos   const CGEN_SYNTAX_CHAR_TYPE * syn;
25975fd0b74Schristos 
26075fd0b74Schristos   CGEN_INIT_INSERT (cd);
26175fd0b74Schristos   value = CGEN_INSN_BASE_VALUE (insn);
26275fd0b74Schristos 
26375fd0b74Schristos   /* If we're recording insns as numbers (rather than a string of bytes),
26475fd0b74Schristos      target byte order handling is deferred until later.  */
26575fd0b74Schristos 
26675fd0b74Schristos #if CGEN_INT_INSN_P
26775fd0b74Schristos 
26875fd0b74Schristos   put_insn_int_value (cd, buffer, cd->base_insn_bitsize,
26975fd0b74Schristos 		      CGEN_FIELDS_BITSIZE (fields), value);
27075fd0b74Schristos 
27175fd0b74Schristos #else
27275fd0b74Schristos 
27375fd0b74Schristos   cgen_put_insn_value (cd, buffer, min ((unsigned) cd->base_insn_bitsize,
27475fd0b74Schristos                                         (unsigned) CGEN_FIELDS_BITSIZE (fields)),
275*e992f068Schristos 		       value, cd->insn_endian);
27675fd0b74Schristos 
27775fd0b74Schristos #endif /* ! CGEN_INT_INSN_P */
27875fd0b74Schristos 
27975fd0b74Schristos   /* ??? It would be better to scan the format's fields.
28075fd0b74Schristos      Still need to be able to insert a value based on the operand though;
28175fd0b74Schristos      e.g. storing a branch displacement that got resolved later.
28275fd0b74Schristos      Needs more thought first.  */
28375fd0b74Schristos 
28475fd0b74Schristos   for (syn = CGEN_SYNTAX_STRING (syntax); * syn; ++ syn)
28575fd0b74Schristos     {
28675fd0b74Schristos       const char *errmsg;
28775fd0b74Schristos 
28875fd0b74Schristos       if (CGEN_SYNTAX_CHAR_P (* syn))
28975fd0b74Schristos 	continue;
29075fd0b74Schristos 
29175fd0b74Schristos       errmsg = (* cd->insert_operand) (cd, CGEN_SYNTAX_FIELD (*syn),
29275fd0b74Schristos 				       fields, buffer, pc);
29375fd0b74Schristos       if (errmsg)
29475fd0b74Schristos 	return errmsg;
29575fd0b74Schristos     }
29675fd0b74Schristos 
29775fd0b74Schristos   return NULL;
29875fd0b74Schristos }
29975fd0b74Schristos 
30075fd0b74Schristos #if CGEN_INT_INSN_P
30175fd0b74Schristos /* Cover function to store an insn value into an integral insn.  Must go here
30275fd0b74Schristos    because it needs <prefix>-desc.h for CGEN_INT_INSN_P.  */
30375fd0b74Schristos 
30475fd0b74Schristos static void
put_insn_int_value(CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,CGEN_INSN_BYTES_PTR buf,int length,int insn_length,CGEN_INSN_INT value)30575fd0b74Schristos put_insn_int_value (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
30675fd0b74Schristos 		    CGEN_INSN_BYTES_PTR buf,
30775fd0b74Schristos 		    int length,
30875fd0b74Schristos 		    int insn_length,
30975fd0b74Schristos 		    CGEN_INSN_INT value)
31075fd0b74Schristos {
31175fd0b74Schristos   /* For architectures with insns smaller than the base-insn-bitsize,
31275fd0b74Schristos      length may be too big.  */
31375fd0b74Schristos   if (length > insn_length)
31475fd0b74Schristos     *buf = value;
31575fd0b74Schristos   else
31675fd0b74Schristos     {
31775fd0b74Schristos       int shift = insn_length - length;
31875fd0b74Schristos       /* Written this way to avoid undefined behaviour.  */
319*e992f068Schristos       CGEN_INSN_INT mask = length == 0 ? 0 : (1UL << (length - 1) << 1) - 1;
32075fd0b74Schristos 
32175fd0b74Schristos       *buf = (*buf & ~(mask << shift)) | ((value & mask) << shift);
32275fd0b74Schristos     }
32375fd0b74Schristos }
32475fd0b74Schristos #endif
32575fd0b74Schristos 
32675fd0b74Schristos /* Operand extraction.  */
32775fd0b74Schristos 
32875fd0b74Schristos #if ! CGEN_INT_INSN_P
32975fd0b74Schristos 
33075fd0b74Schristos /* Subroutine of extract_normal.
33175fd0b74Schristos    Ensure sufficient bytes are cached in EX_INFO.
33275fd0b74Schristos    OFFSET is the offset in bytes from the start of the insn of the value.
33375fd0b74Schristos    BYTES is the length of the needed value.
33475fd0b74Schristos    Returns 1 for success, 0 for failure.  */
33575fd0b74Schristos 
33675fd0b74Schristos static CGEN_INLINE int
fill_cache(CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,CGEN_EXTRACT_INFO * ex_info,int offset,int bytes,bfd_vma pc)33775fd0b74Schristos fill_cache (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
33875fd0b74Schristos 	    CGEN_EXTRACT_INFO *ex_info,
33975fd0b74Schristos 	    int offset,
34075fd0b74Schristos 	    int bytes,
34175fd0b74Schristos 	    bfd_vma pc)
34275fd0b74Schristos {
34375fd0b74Schristos   /* It's doubtful that the middle part has already been fetched so
34475fd0b74Schristos      we don't optimize that case.  kiss.  */
34575fd0b74Schristos   unsigned int mask;
34675fd0b74Schristos   disassemble_info *info = (disassemble_info *) ex_info->dis_info;
34775fd0b74Schristos 
34875fd0b74Schristos   /* First do a quick check.  */
34975fd0b74Schristos   mask = (1 << bytes) - 1;
35075fd0b74Schristos   if (((ex_info->valid >> offset) & mask) == mask)
35175fd0b74Schristos     return 1;
35275fd0b74Schristos 
35375fd0b74Schristos   /* Search for the first byte we need to read.  */
35475fd0b74Schristos   for (mask = 1 << offset; bytes > 0; --bytes, ++offset, mask <<= 1)
35575fd0b74Schristos     if (! (mask & ex_info->valid))
35675fd0b74Schristos       break;
35775fd0b74Schristos 
35875fd0b74Schristos   if (bytes)
35975fd0b74Schristos     {
36075fd0b74Schristos       int status;
36175fd0b74Schristos 
36275fd0b74Schristos       pc += offset;
36375fd0b74Schristos       status = (*info->read_memory_func)
36475fd0b74Schristos 	(pc, ex_info->insn_bytes + offset, bytes, info);
36575fd0b74Schristos 
36675fd0b74Schristos       if (status != 0)
36775fd0b74Schristos 	{
36875fd0b74Schristos 	  (*info->memory_error_func) (status, pc, info);
36975fd0b74Schristos 	  return 0;
37075fd0b74Schristos 	}
37175fd0b74Schristos 
37275fd0b74Schristos       ex_info->valid |= ((1 << bytes) - 1) << offset;
37375fd0b74Schristos     }
37475fd0b74Schristos 
37575fd0b74Schristos   return 1;
37675fd0b74Schristos }
37775fd0b74Schristos 
37875fd0b74Schristos /* Subroutine of extract_normal.  */
37975fd0b74Schristos 
38075fd0b74Schristos static CGEN_INLINE long
extract_1(CGEN_CPU_DESC cd,CGEN_EXTRACT_INFO * ex_info ATTRIBUTE_UNUSED,int start,int length,int word_length,unsigned char * bufp,bfd_vma pc ATTRIBUTE_UNUSED)38175fd0b74Schristos extract_1 (CGEN_CPU_DESC cd,
38275fd0b74Schristos 	   CGEN_EXTRACT_INFO *ex_info ATTRIBUTE_UNUSED,
38375fd0b74Schristos 	   int start,
38475fd0b74Schristos 	   int length,
38575fd0b74Schristos 	   int word_length,
38675fd0b74Schristos 	   unsigned char *bufp,
38775fd0b74Schristos 	   bfd_vma pc ATTRIBUTE_UNUSED)
38875fd0b74Schristos {
38975fd0b74Schristos   unsigned long x;
39075fd0b74Schristos   int shift;
39175fd0b74Schristos 
392*e992f068Schristos   x = cgen_get_insn_value (cd, bufp, word_length, cd->endian);
39375fd0b74Schristos 
39475fd0b74Schristos   if (CGEN_INSN_LSB0_P)
39575fd0b74Schristos     shift = (start + 1) - length;
39675fd0b74Schristos   else
39775fd0b74Schristos     shift = (word_length - (start + length));
39875fd0b74Schristos   return x >> shift;
39975fd0b74Schristos }
40075fd0b74Schristos 
40175fd0b74Schristos #endif /* ! CGEN_INT_INSN_P */
40275fd0b74Schristos 
40375fd0b74Schristos /* Default extraction routine.
40475fd0b74Schristos 
40575fd0b74Schristos    INSN_VALUE is the first base_insn_bitsize bits of the insn in host order,
40675fd0b74Schristos    or sometimes less for cases like the m32r where the base insn size is 32
40775fd0b74Schristos    but some insns are 16 bits.
40875fd0b74Schristos    ATTRS is a mask of the boolean attributes.  We only need `SIGNED',
40975fd0b74Schristos    but for generality we take a bitmask of all of them.
41075fd0b74Schristos    WORD_OFFSET is the offset in bits from the start of the insn of the value.
41175fd0b74Schristos    WORD_LENGTH is the length of the word in bits in which the value resides.
41275fd0b74Schristos    START is the starting bit number in the word, architecture origin.
41375fd0b74Schristos    LENGTH is the length of VALUE in bits.
41475fd0b74Schristos    TOTAL_LENGTH is the total length of the insn in bits.
41575fd0b74Schristos 
41675fd0b74Schristos    Returns 1 for success, 0 for failure.  */
41775fd0b74Schristos 
41875fd0b74Schristos /* ??? The return code isn't properly used.  wip.  */
41975fd0b74Schristos 
42075fd0b74Schristos /* ??? This doesn't handle bfd_vma's.  Create another function when
42175fd0b74Schristos    necessary.  */
42275fd0b74Schristos 
42375fd0b74Schristos static int
extract_normal(CGEN_CPU_DESC cd,CGEN_EXTRACT_INFO * ex_info,CGEN_INSN_INT insn_value,unsigned int attrs,unsigned int word_offset,unsigned int start,unsigned int length,unsigned int word_length,unsigned int total_length,bfd_vma pc,long * valuep)42475fd0b74Schristos extract_normal (CGEN_CPU_DESC cd,
42575fd0b74Schristos #if ! CGEN_INT_INSN_P
42675fd0b74Schristos 		CGEN_EXTRACT_INFO *ex_info,
42775fd0b74Schristos #else
42875fd0b74Schristos 		CGEN_EXTRACT_INFO *ex_info ATTRIBUTE_UNUSED,
42975fd0b74Schristos #endif
43075fd0b74Schristos 		CGEN_INSN_INT insn_value,
43175fd0b74Schristos 		unsigned int attrs,
43275fd0b74Schristos 		unsigned int word_offset,
43375fd0b74Schristos 		unsigned int start,
43475fd0b74Schristos 		unsigned int length,
43575fd0b74Schristos 		unsigned int word_length,
43675fd0b74Schristos 		unsigned int total_length,
43775fd0b74Schristos #if ! CGEN_INT_INSN_P
43875fd0b74Schristos 		bfd_vma pc,
43975fd0b74Schristos #else
44075fd0b74Schristos 		bfd_vma pc ATTRIBUTE_UNUSED,
44175fd0b74Schristos #endif
44275fd0b74Schristos 		long *valuep)
44375fd0b74Schristos {
44475fd0b74Schristos   long value, mask;
44575fd0b74Schristos 
44675fd0b74Schristos   /* If LENGTH is zero, this operand doesn't contribute to the value
44775fd0b74Schristos      so give it a standard value of zero.  */
44875fd0b74Schristos   if (length == 0)
44975fd0b74Schristos     {
45075fd0b74Schristos       *valuep = 0;
45175fd0b74Schristos       return 1;
45275fd0b74Schristos     }
45375fd0b74Schristos 
45475fd0b74Schristos   if (word_length > 8 * sizeof (CGEN_INSN_INT))
45575fd0b74Schristos     abort ();
45675fd0b74Schristos 
45775fd0b74Schristos   /* For architectures with insns smaller than the insn-base-bitsize,
45875fd0b74Schristos      word_length may be too big.  */
45975fd0b74Schristos   if (cd->min_insn_bitsize < cd->base_insn_bitsize)
46075fd0b74Schristos     {
46175fd0b74Schristos       if (word_offset + word_length > total_length)
46275fd0b74Schristos 	word_length = total_length - word_offset;
46375fd0b74Schristos     }
46475fd0b74Schristos 
46575fd0b74Schristos   /* Does the value reside in INSN_VALUE, and at the right alignment?  */
46675fd0b74Schristos 
46775fd0b74Schristos   if (CGEN_INT_INSN_P || (word_offset == 0 && word_length == total_length))
46875fd0b74Schristos     {
46975fd0b74Schristos       if (CGEN_INSN_LSB0_P)
47075fd0b74Schristos 	value = insn_value >> ((word_offset + start + 1) - length);
47175fd0b74Schristos       else
47275fd0b74Schristos 	value = insn_value >> (total_length - ( word_offset + start + length));
47375fd0b74Schristos     }
47475fd0b74Schristos 
47575fd0b74Schristos #if ! CGEN_INT_INSN_P
47675fd0b74Schristos 
47775fd0b74Schristos   else
47875fd0b74Schristos     {
47975fd0b74Schristos       unsigned char *bufp = ex_info->insn_bytes + word_offset / 8;
48075fd0b74Schristos 
48175fd0b74Schristos       if (word_length > 8 * sizeof (CGEN_INSN_INT))
48275fd0b74Schristos 	abort ();
48375fd0b74Schristos 
48475fd0b74Schristos       if (fill_cache (cd, ex_info, word_offset / 8, word_length / 8, pc) == 0)
485*e992f068Schristos 	{
486*e992f068Schristos 	  *valuep = 0;
48775fd0b74Schristos 	  return 0;
488*e992f068Schristos 	}
48975fd0b74Schristos 
49075fd0b74Schristos       value = extract_1 (cd, ex_info, start, length, word_length, bufp, pc);
49175fd0b74Schristos     }
49275fd0b74Schristos 
49375fd0b74Schristos #endif /* ! CGEN_INT_INSN_P */
49475fd0b74Schristos 
49575fd0b74Schristos   /* Written this way to avoid undefined behaviour.  */
496*e992f068Schristos   mask = (1UL << (length - 1) << 1) - 1;
49775fd0b74Schristos 
49875fd0b74Schristos   value &= mask;
49975fd0b74Schristos   /* sign extend? */
50075fd0b74Schristos   if (CGEN_BOOL_ATTR (attrs, CGEN_IFLD_SIGNED)
501*e992f068Schristos       && (value & (1UL << (length - 1))))
50275fd0b74Schristos     value |= ~mask;
50375fd0b74Schristos 
50475fd0b74Schristos   *valuep = value;
50575fd0b74Schristos 
50675fd0b74Schristos   return 1;
50775fd0b74Schristos }
50875fd0b74Schristos 
50975fd0b74Schristos /* Default insn extractor.
51075fd0b74Schristos 
51175fd0b74Schristos    INSN_VALUE is the first base_insn_bitsize bits, translated to host order.
51275fd0b74Schristos    The extracted fields are stored in FIELDS.
51375fd0b74Schristos    EX_INFO is used to handle reading variable length insns.
51475fd0b74Schristos    Return the length of the insn in bits, or 0 if no match,
51575fd0b74Schristos    or -1 if an error occurs fetching data (memory_error_func will have
51675fd0b74Schristos    been called).  */
51775fd0b74Schristos 
51875fd0b74Schristos static int
extract_insn_normal(CGEN_CPU_DESC cd,const CGEN_INSN * insn,CGEN_EXTRACT_INFO * ex_info,CGEN_INSN_INT insn_value,CGEN_FIELDS * fields,bfd_vma pc)51975fd0b74Schristos extract_insn_normal (CGEN_CPU_DESC cd,
52075fd0b74Schristos 		     const CGEN_INSN *insn,
52175fd0b74Schristos 		     CGEN_EXTRACT_INFO *ex_info,
52275fd0b74Schristos 		     CGEN_INSN_INT insn_value,
52375fd0b74Schristos 		     CGEN_FIELDS *fields,
52475fd0b74Schristos 		     bfd_vma pc)
52575fd0b74Schristos {
52675fd0b74Schristos   const CGEN_SYNTAX *syntax = CGEN_INSN_SYNTAX (insn);
52775fd0b74Schristos   const CGEN_SYNTAX_CHAR_TYPE *syn;
52875fd0b74Schristos 
52975fd0b74Schristos   CGEN_FIELDS_BITSIZE (fields) = CGEN_INSN_BITSIZE (insn);
53075fd0b74Schristos 
53175fd0b74Schristos   CGEN_INIT_EXTRACT (cd);
53275fd0b74Schristos 
53375fd0b74Schristos   for (syn = CGEN_SYNTAX_STRING (syntax); *syn; ++syn)
53475fd0b74Schristos     {
53575fd0b74Schristos       int length;
53675fd0b74Schristos 
53775fd0b74Schristos       if (CGEN_SYNTAX_CHAR_P (*syn))
53875fd0b74Schristos 	continue;
53975fd0b74Schristos 
54075fd0b74Schristos       length = (* cd->extract_operand) (cd, CGEN_SYNTAX_FIELD (*syn),
54175fd0b74Schristos 					ex_info, insn_value, fields, pc);
54275fd0b74Schristos       if (length <= 0)
54375fd0b74Schristos 	return length;
54475fd0b74Schristos     }
54575fd0b74Schristos 
54675fd0b74Schristos   /* We recognized and successfully extracted this insn.  */
54775fd0b74Schristos   return CGEN_INSN_BITSIZE (insn);
54875fd0b74Schristos }
54975fd0b74Schristos 
55075fd0b74Schristos /* Machine generated code added here.  */
55175fd0b74Schristos 
55275fd0b74Schristos const char * m32r_cgen_insert_operand
55375fd0b74Schristos   (CGEN_CPU_DESC, int, CGEN_FIELDS *, CGEN_INSN_BYTES_PTR, bfd_vma);
55475fd0b74Schristos 
55575fd0b74Schristos /* Main entry point for operand insertion.
55675fd0b74Schristos 
55775fd0b74Schristos    This function is basically just a big switch statement.  Earlier versions
55875fd0b74Schristos    used tables to look up the function to use, but
55975fd0b74Schristos    - if the table contains both assembler and disassembler functions then
56075fd0b74Schristos      the disassembler contains much of the assembler and vice-versa,
56175fd0b74Schristos    - there's a lot of inlining possibilities as things grow,
56275fd0b74Schristos    - using a switch statement avoids the function call overhead.
56375fd0b74Schristos 
56475fd0b74Schristos    This function could be moved into `parse_insn_normal', but keeping it
56575fd0b74Schristos    separate makes clear the interface between `parse_insn_normal' and each of
56675fd0b74Schristos    the handlers.  It's also needed by GAS to insert operands that couldn't be
56775fd0b74Schristos    resolved during parsing.  */
56875fd0b74Schristos 
56975fd0b74Schristos const char *
m32r_cgen_insert_operand(CGEN_CPU_DESC cd,int opindex,CGEN_FIELDS * fields,CGEN_INSN_BYTES_PTR buffer,bfd_vma pc ATTRIBUTE_UNUSED)57075fd0b74Schristos m32r_cgen_insert_operand (CGEN_CPU_DESC cd,
57175fd0b74Schristos 			     int opindex,
57275fd0b74Schristos 			     CGEN_FIELDS * fields,
57375fd0b74Schristos 			     CGEN_INSN_BYTES_PTR buffer,
57475fd0b74Schristos 			     bfd_vma pc ATTRIBUTE_UNUSED)
57575fd0b74Schristos {
57675fd0b74Schristos   const char * errmsg = NULL;
57775fd0b74Schristos   unsigned int total_length = CGEN_FIELDS_BITSIZE (fields);
57875fd0b74Schristos 
57975fd0b74Schristos   switch (opindex)
58075fd0b74Schristos     {
58175fd0b74Schristos     case M32R_OPERAND_ACC :
58275fd0b74Schristos       errmsg = insert_normal (cd, fields->f_acc, 0, 0, 8, 1, 32, total_length, buffer);
58375fd0b74Schristos       break;
58475fd0b74Schristos     case M32R_OPERAND_ACCD :
58575fd0b74Schristos       errmsg = insert_normal (cd, fields->f_accd, 0, 0, 4, 2, 32, total_length, buffer);
58675fd0b74Schristos       break;
58775fd0b74Schristos     case M32R_OPERAND_ACCS :
58875fd0b74Schristos       errmsg = insert_normal (cd, fields->f_accs, 0, 0, 12, 2, 32, total_length, buffer);
58975fd0b74Schristos       break;
59075fd0b74Schristos     case M32R_OPERAND_DCR :
59175fd0b74Schristos       errmsg = insert_normal (cd, fields->f_r1, 0, 0, 4, 4, 32, total_length, buffer);
59275fd0b74Schristos       break;
59375fd0b74Schristos     case M32R_OPERAND_DISP16 :
59475fd0b74Schristos       {
59575fd0b74Schristos         long value = fields->f_disp16;
59675fd0b74Schristos         value = ((SI) (((value) - (pc))) >> (2));
59775fd0b74Schristos         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);
59875fd0b74Schristos       }
59975fd0b74Schristos       break;
60075fd0b74Schristos     case M32R_OPERAND_DISP24 :
60175fd0b74Schristos       {
60275fd0b74Schristos         long value = fields->f_disp24;
60375fd0b74Schristos         value = ((SI) (((value) - (pc))) >> (2));
60475fd0b74Schristos         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);
60575fd0b74Schristos       }
60675fd0b74Schristos       break;
60775fd0b74Schristos     case M32R_OPERAND_DISP8 :
60875fd0b74Schristos       {
60975fd0b74Schristos         long value = fields->f_disp8;
61075fd0b74Schristos         value = ((SI) (((value) - (((pc) & (-4))))) >> (2));
61175fd0b74Schristos         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);
61275fd0b74Schristos       }
61375fd0b74Schristos       break;
61475fd0b74Schristos     case M32R_OPERAND_DR :
61575fd0b74Schristos       errmsg = insert_normal (cd, fields->f_r1, 0, 0, 4, 4, 32, total_length, buffer);
61675fd0b74Schristos       break;
61775fd0b74Schristos     case M32R_OPERAND_HASH :
61875fd0b74Schristos       break;
61975fd0b74Schristos     case M32R_OPERAND_HI16 :
62075fd0b74Schristos       errmsg = insert_normal (cd, fields->f_hi16, 0|(1<<CGEN_IFLD_SIGN_OPT), 0, 16, 16, 32, total_length, buffer);
62175fd0b74Schristos       break;
62275fd0b74Schristos     case M32R_OPERAND_IMM1 :
62375fd0b74Schristos       {
62475fd0b74Schristos         long value = fields->f_imm1;
62575fd0b74Schristos         value = ((value) - (1));
62675fd0b74Schristos         errmsg = insert_normal (cd, value, 0, 0, 15, 1, 32, total_length, buffer);
62775fd0b74Schristos       }
62875fd0b74Schristos       break;
62975fd0b74Schristos     case M32R_OPERAND_SCR :
63075fd0b74Schristos       errmsg = insert_normal (cd, fields->f_r2, 0, 0, 12, 4, 32, total_length, buffer);
63175fd0b74Schristos       break;
63275fd0b74Schristos     case M32R_OPERAND_SIMM16 :
63375fd0b74Schristos       errmsg = insert_normal (cd, fields->f_simm16, 0|(1<<CGEN_IFLD_SIGNED), 0, 16, 16, 32, total_length, buffer);
63475fd0b74Schristos       break;
63575fd0b74Schristos     case M32R_OPERAND_SIMM8 :
63675fd0b74Schristos       errmsg = insert_normal (cd, fields->f_simm8, 0|(1<<CGEN_IFLD_SIGNED), 0, 8, 8, 32, total_length, buffer);
63775fd0b74Schristos       break;
63875fd0b74Schristos     case M32R_OPERAND_SLO16 :
63975fd0b74Schristos       errmsg = insert_normal (cd, fields->f_simm16, 0|(1<<CGEN_IFLD_SIGNED), 0, 16, 16, 32, total_length, buffer);
64075fd0b74Schristos       break;
64175fd0b74Schristos     case M32R_OPERAND_SR :
64275fd0b74Schristos       errmsg = insert_normal (cd, fields->f_r2, 0, 0, 12, 4, 32, total_length, buffer);
64375fd0b74Schristos       break;
64475fd0b74Schristos     case M32R_OPERAND_SRC1 :
64575fd0b74Schristos       errmsg = insert_normal (cd, fields->f_r1, 0, 0, 4, 4, 32, total_length, buffer);
64675fd0b74Schristos       break;
64775fd0b74Schristos     case M32R_OPERAND_SRC2 :
64875fd0b74Schristos       errmsg = insert_normal (cd, fields->f_r2, 0, 0, 12, 4, 32, total_length, buffer);
64975fd0b74Schristos       break;
65075fd0b74Schristos     case M32R_OPERAND_UIMM16 :
65175fd0b74Schristos       errmsg = insert_normal (cd, fields->f_uimm16, 0, 0, 16, 16, 32, total_length, buffer);
65275fd0b74Schristos       break;
65375fd0b74Schristos     case M32R_OPERAND_UIMM24 :
65475fd0b74Schristos       errmsg = insert_normal (cd, fields->f_uimm24, 0|(1<<CGEN_IFLD_RELOC)|(1<<CGEN_IFLD_ABS_ADDR), 0, 8, 24, 32, total_length, buffer);
65575fd0b74Schristos       break;
65675fd0b74Schristos     case M32R_OPERAND_UIMM3 :
65775fd0b74Schristos       errmsg = insert_normal (cd, fields->f_uimm3, 0, 0, 5, 3, 32, total_length, buffer);
65875fd0b74Schristos       break;
65975fd0b74Schristos     case M32R_OPERAND_UIMM4 :
66075fd0b74Schristos       errmsg = insert_normal (cd, fields->f_uimm4, 0, 0, 12, 4, 32, total_length, buffer);
66175fd0b74Schristos       break;
66275fd0b74Schristos     case M32R_OPERAND_UIMM5 :
66375fd0b74Schristos       errmsg = insert_normal (cd, fields->f_uimm5, 0, 0, 11, 5, 32, total_length, buffer);
66475fd0b74Schristos       break;
66575fd0b74Schristos     case M32R_OPERAND_UIMM8 :
66675fd0b74Schristos       errmsg = insert_normal (cd, fields->f_uimm8, 0, 0, 8, 8, 32, total_length, buffer);
66775fd0b74Schristos       break;
66875fd0b74Schristos     case M32R_OPERAND_ULO16 :
66975fd0b74Schristos       errmsg = insert_normal (cd, fields->f_uimm16, 0, 0, 16, 16, 32, total_length, buffer);
67075fd0b74Schristos       break;
67175fd0b74Schristos 
67275fd0b74Schristos     default :
67375fd0b74Schristos       /* xgettext:c-format */
674ede78133Schristos       opcodes_error_handler
675ede78133Schristos 	(_("internal error: unrecognized field %d while building insn"),
67675fd0b74Schristos 	 opindex);
67775fd0b74Schristos       abort ();
67875fd0b74Schristos   }
67975fd0b74Schristos 
68075fd0b74Schristos   return errmsg;
68175fd0b74Schristos }
68275fd0b74Schristos 
68375fd0b74Schristos int m32r_cgen_extract_operand
68475fd0b74Schristos   (CGEN_CPU_DESC, int, CGEN_EXTRACT_INFO *, CGEN_INSN_INT, CGEN_FIELDS *, bfd_vma);
68575fd0b74Schristos 
68675fd0b74Schristos /* Main entry point for operand extraction.
68775fd0b74Schristos    The result is <= 0 for error, >0 for success.
68875fd0b74Schristos    ??? Actual values aren't well defined right now.
68975fd0b74Schristos 
69075fd0b74Schristos    This function is basically just a big switch statement.  Earlier versions
69175fd0b74Schristos    used tables to look up the function to use, but
69275fd0b74Schristos    - if the table contains both assembler and disassembler functions then
69375fd0b74Schristos      the disassembler contains much of the assembler and vice-versa,
69475fd0b74Schristos    - there's a lot of inlining possibilities as things grow,
69575fd0b74Schristos    - using a switch statement avoids the function call overhead.
69675fd0b74Schristos 
69775fd0b74Schristos    This function could be moved into `print_insn_normal', but keeping it
69875fd0b74Schristos    separate makes clear the interface between `print_insn_normal' and each of
69975fd0b74Schristos    the handlers.  */
70075fd0b74Schristos 
70175fd0b74Schristos int
m32r_cgen_extract_operand(CGEN_CPU_DESC cd,int opindex,CGEN_EXTRACT_INFO * ex_info,CGEN_INSN_INT insn_value,CGEN_FIELDS * fields,bfd_vma pc)70275fd0b74Schristos m32r_cgen_extract_operand (CGEN_CPU_DESC cd,
70375fd0b74Schristos 			     int opindex,
70475fd0b74Schristos 			     CGEN_EXTRACT_INFO *ex_info,
70575fd0b74Schristos 			     CGEN_INSN_INT insn_value,
70675fd0b74Schristos 			     CGEN_FIELDS * fields,
70775fd0b74Schristos 			     bfd_vma pc)
70875fd0b74Schristos {
70975fd0b74Schristos   /* Assume success (for those operands that are nops).  */
71075fd0b74Schristos   int length = 1;
71175fd0b74Schristos   unsigned int total_length = CGEN_FIELDS_BITSIZE (fields);
71275fd0b74Schristos 
71375fd0b74Schristos   switch (opindex)
71475fd0b74Schristos     {
71575fd0b74Schristos     case M32R_OPERAND_ACC :
71675fd0b74Schristos       length = extract_normal (cd, ex_info, insn_value, 0, 0, 8, 1, 32, total_length, pc, & fields->f_acc);
71775fd0b74Schristos       break;
71875fd0b74Schristos     case M32R_OPERAND_ACCD :
71975fd0b74Schristos       length = extract_normal (cd, ex_info, insn_value, 0, 0, 4, 2, 32, total_length, pc, & fields->f_accd);
72075fd0b74Schristos       break;
72175fd0b74Schristos     case M32R_OPERAND_ACCS :
72275fd0b74Schristos       length = extract_normal (cd, ex_info, insn_value, 0, 0, 12, 2, 32, total_length, pc, & fields->f_accs);
72375fd0b74Schristos       break;
72475fd0b74Schristos     case M32R_OPERAND_DCR :
72575fd0b74Schristos       length = extract_normal (cd, ex_info, insn_value, 0, 0, 4, 4, 32, total_length, pc, & fields->f_r1);
72675fd0b74Schristos       break;
72775fd0b74Schristos     case M32R_OPERAND_DISP16 :
72875fd0b74Schristos       {
72975fd0b74Schristos         long value;
73075fd0b74Schristos         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);
731012573ebSchristos         value = ((((value) * (4))) + (pc));
73275fd0b74Schristos         fields->f_disp16 = value;
73375fd0b74Schristos       }
73475fd0b74Schristos       break;
73575fd0b74Schristos     case M32R_OPERAND_DISP24 :
73675fd0b74Schristos       {
73775fd0b74Schristos         long value;
73875fd0b74Schristos         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);
739012573ebSchristos         value = ((((value) * (4))) + (pc));
74075fd0b74Schristos         fields->f_disp24 = value;
74175fd0b74Schristos       }
74275fd0b74Schristos       break;
74375fd0b74Schristos     case M32R_OPERAND_DISP8 :
74475fd0b74Schristos       {
74575fd0b74Schristos         long value;
74675fd0b74Schristos         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);
747012573ebSchristos         value = ((((value) * (4))) + (((pc) & (-4))));
74875fd0b74Schristos         fields->f_disp8 = value;
74975fd0b74Schristos       }
75075fd0b74Schristos       break;
75175fd0b74Schristos     case M32R_OPERAND_DR :
75275fd0b74Schristos       length = extract_normal (cd, ex_info, insn_value, 0, 0, 4, 4, 32, total_length, pc, & fields->f_r1);
75375fd0b74Schristos       break;
75475fd0b74Schristos     case M32R_OPERAND_HASH :
75575fd0b74Schristos       break;
75675fd0b74Schristos     case M32R_OPERAND_HI16 :
75775fd0b74Schristos       length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_SIGN_OPT), 0, 16, 16, 32, total_length, pc, & fields->f_hi16);
75875fd0b74Schristos       break;
75975fd0b74Schristos     case M32R_OPERAND_IMM1 :
76075fd0b74Schristos       {
76175fd0b74Schristos         long value;
76275fd0b74Schristos         length = extract_normal (cd, ex_info, insn_value, 0, 0, 15, 1, 32, total_length, pc, & value);
76375fd0b74Schristos         value = ((value) + (1));
76475fd0b74Schristos         fields->f_imm1 = value;
76575fd0b74Schristos       }
76675fd0b74Schristos       break;
76775fd0b74Schristos     case M32R_OPERAND_SCR :
76875fd0b74Schristos       length = extract_normal (cd, ex_info, insn_value, 0, 0, 12, 4, 32, total_length, pc, & fields->f_r2);
76975fd0b74Schristos       break;
77075fd0b74Schristos     case M32R_OPERAND_SIMM16 :
77175fd0b74Schristos       length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_SIGNED), 0, 16, 16, 32, total_length, pc, & fields->f_simm16);
77275fd0b74Schristos       break;
77375fd0b74Schristos     case M32R_OPERAND_SIMM8 :
77475fd0b74Schristos       length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_SIGNED), 0, 8, 8, 32, total_length, pc, & fields->f_simm8);
77575fd0b74Schristos       break;
77675fd0b74Schristos     case M32R_OPERAND_SLO16 :
77775fd0b74Schristos       length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_SIGNED), 0, 16, 16, 32, total_length, pc, & fields->f_simm16);
77875fd0b74Schristos       break;
77975fd0b74Schristos     case M32R_OPERAND_SR :
78075fd0b74Schristos       length = extract_normal (cd, ex_info, insn_value, 0, 0, 12, 4, 32, total_length, pc, & fields->f_r2);
78175fd0b74Schristos       break;
78275fd0b74Schristos     case M32R_OPERAND_SRC1 :
78375fd0b74Schristos       length = extract_normal (cd, ex_info, insn_value, 0, 0, 4, 4, 32, total_length, pc, & fields->f_r1);
78475fd0b74Schristos       break;
78575fd0b74Schristos     case M32R_OPERAND_SRC2 :
78675fd0b74Schristos       length = extract_normal (cd, ex_info, insn_value, 0, 0, 12, 4, 32, total_length, pc, & fields->f_r2);
78775fd0b74Schristos       break;
78875fd0b74Schristos     case M32R_OPERAND_UIMM16 :
78975fd0b74Schristos       length = extract_normal (cd, ex_info, insn_value, 0, 0, 16, 16, 32, total_length, pc, & fields->f_uimm16);
79075fd0b74Schristos       break;
79175fd0b74Schristos     case M32R_OPERAND_UIMM24 :
79275fd0b74Schristos       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);
79375fd0b74Schristos       break;
79475fd0b74Schristos     case M32R_OPERAND_UIMM3 :
79575fd0b74Schristos       length = extract_normal (cd, ex_info, insn_value, 0, 0, 5, 3, 32, total_length, pc, & fields->f_uimm3);
79675fd0b74Schristos       break;
79775fd0b74Schristos     case M32R_OPERAND_UIMM4 :
79875fd0b74Schristos       length = extract_normal (cd, ex_info, insn_value, 0, 0, 12, 4, 32, total_length, pc, & fields->f_uimm4);
79975fd0b74Schristos       break;
80075fd0b74Schristos     case M32R_OPERAND_UIMM5 :
80175fd0b74Schristos       length = extract_normal (cd, ex_info, insn_value, 0, 0, 11, 5, 32, total_length, pc, & fields->f_uimm5);
80275fd0b74Schristos       break;
80375fd0b74Schristos     case M32R_OPERAND_UIMM8 :
80475fd0b74Schristos       length = extract_normal (cd, ex_info, insn_value, 0, 0, 8, 8, 32, total_length, pc, & fields->f_uimm8);
80575fd0b74Schristos       break;
80675fd0b74Schristos     case M32R_OPERAND_ULO16 :
80775fd0b74Schristos       length = extract_normal (cd, ex_info, insn_value, 0, 0, 16, 16, 32, total_length, pc, & fields->f_uimm16);
80875fd0b74Schristos       break;
80975fd0b74Schristos 
81075fd0b74Schristos     default :
81175fd0b74Schristos       /* xgettext:c-format */
812ede78133Schristos       opcodes_error_handler
813ede78133Schristos 	(_("internal error: unrecognized field %d while decoding insn"),
81475fd0b74Schristos 	 opindex);
81575fd0b74Schristos       abort ();
81675fd0b74Schristos     }
81775fd0b74Schristos 
81875fd0b74Schristos   return length;
81975fd0b74Schristos }
82075fd0b74Schristos 
82175fd0b74Schristos cgen_insert_fn * const m32r_cgen_insert_handlers[] =
82275fd0b74Schristos {
82375fd0b74Schristos   insert_insn_normal,
82475fd0b74Schristos };
82575fd0b74Schristos 
82675fd0b74Schristos cgen_extract_fn * const m32r_cgen_extract_handlers[] =
82775fd0b74Schristos {
82875fd0b74Schristos   extract_insn_normal,
82975fd0b74Schristos };
83075fd0b74Schristos 
83175fd0b74Schristos int m32r_cgen_get_int_operand     (CGEN_CPU_DESC, int, const CGEN_FIELDS *);
83275fd0b74Schristos bfd_vma m32r_cgen_get_vma_operand (CGEN_CPU_DESC, int, const CGEN_FIELDS *);
83375fd0b74Schristos 
83475fd0b74Schristos /* Getting values from cgen_fields is handled by a collection of functions.
83575fd0b74Schristos    They are distinguished by the type of the VALUE argument they return.
83675fd0b74Schristos    TODO: floating point, inlining support, remove cases where result type
83775fd0b74Schristos    not appropriate.  */
83875fd0b74Schristos 
83975fd0b74Schristos int
m32r_cgen_get_int_operand(CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,int opindex,const CGEN_FIELDS * fields)84075fd0b74Schristos m32r_cgen_get_int_operand (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
84175fd0b74Schristos 			     int opindex,
84275fd0b74Schristos 			     const CGEN_FIELDS * fields)
84375fd0b74Schristos {
84475fd0b74Schristos   int value;
84575fd0b74Schristos 
84675fd0b74Schristos   switch (opindex)
84775fd0b74Schristos     {
84875fd0b74Schristos     case M32R_OPERAND_ACC :
84975fd0b74Schristos       value = fields->f_acc;
85075fd0b74Schristos       break;
85175fd0b74Schristos     case M32R_OPERAND_ACCD :
85275fd0b74Schristos       value = fields->f_accd;
85375fd0b74Schristos       break;
85475fd0b74Schristos     case M32R_OPERAND_ACCS :
85575fd0b74Schristos       value = fields->f_accs;
85675fd0b74Schristos       break;
85775fd0b74Schristos     case M32R_OPERAND_DCR :
85875fd0b74Schristos       value = fields->f_r1;
85975fd0b74Schristos       break;
86075fd0b74Schristos     case M32R_OPERAND_DISP16 :
86175fd0b74Schristos       value = fields->f_disp16;
86275fd0b74Schristos       break;
86375fd0b74Schristos     case M32R_OPERAND_DISP24 :
86475fd0b74Schristos       value = fields->f_disp24;
86575fd0b74Schristos       break;
86675fd0b74Schristos     case M32R_OPERAND_DISP8 :
86775fd0b74Schristos       value = fields->f_disp8;
86875fd0b74Schristos       break;
86975fd0b74Schristos     case M32R_OPERAND_DR :
87075fd0b74Schristos       value = fields->f_r1;
87175fd0b74Schristos       break;
87275fd0b74Schristos     case M32R_OPERAND_HASH :
87375fd0b74Schristos       value = 0;
87475fd0b74Schristos       break;
87575fd0b74Schristos     case M32R_OPERAND_HI16 :
87675fd0b74Schristos       value = fields->f_hi16;
87775fd0b74Schristos       break;
87875fd0b74Schristos     case M32R_OPERAND_IMM1 :
87975fd0b74Schristos       value = fields->f_imm1;
88075fd0b74Schristos       break;
88175fd0b74Schristos     case M32R_OPERAND_SCR :
88275fd0b74Schristos       value = fields->f_r2;
88375fd0b74Schristos       break;
88475fd0b74Schristos     case M32R_OPERAND_SIMM16 :
88575fd0b74Schristos       value = fields->f_simm16;
88675fd0b74Schristos       break;
88775fd0b74Schristos     case M32R_OPERAND_SIMM8 :
88875fd0b74Schristos       value = fields->f_simm8;
88975fd0b74Schristos       break;
89075fd0b74Schristos     case M32R_OPERAND_SLO16 :
89175fd0b74Schristos       value = fields->f_simm16;
89275fd0b74Schristos       break;
89375fd0b74Schristos     case M32R_OPERAND_SR :
89475fd0b74Schristos       value = fields->f_r2;
89575fd0b74Schristos       break;
89675fd0b74Schristos     case M32R_OPERAND_SRC1 :
89775fd0b74Schristos       value = fields->f_r1;
89875fd0b74Schristos       break;
89975fd0b74Schristos     case M32R_OPERAND_SRC2 :
90075fd0b74Schristos       value = fields->f_r2;
90175fd0b74Schristos       break;
90275fd0b74Schristos     case M32R_OPERAND_UIMM16 :
90375fd0b74Schristos       value = fields->f_uimm16;
90475fd0b74Schristos       break;
90575fd0b74Schristos     case M32R_OPERAND_UIMM24 :
90675fd0b74Schristos       value = fields->f_uimm24;
90775fd0b74Schristos       break;
90875fd0b74Schristos     case M32R_OPERAND_UIMM3 :
90975fd0b74Schristos       value = fields->f_uimm3;
91075fd0b74Schristos       break;
91175fd0b74Schristos     case M32R_OPERAND_UIMM4 :
91275fd0b74Schristos       value = fields->f_uimm4;
91375fd0b74Schristos       break;
91475fd0b74Schristos     case M32R_OPERAND_UIMM5 :
91575fd0b74Schristos       value = fields->f_uimm5;
91675fd0b74Schristos       break;
91775fd0b74Schristos     case M32R_OPERAND_UIMM8 :
91875fd0b74Schristos       value = fields->f_uimm8;
91975fd0b74Schristos       break;
92075fd0b74Schristos     case M32R_OPERAND_ULO16 :
92175fd0b74Schristos       value = fields->f_uimm16;
92275fd0b74Schristos       break;
92375fd0b74Schristos 
92475fd0b74Schristos     default :
92575fd0b74Schristos       /* xgettext:c-format */
926ede78133Schristos       opcodes_error_handler
927ede78133Schristos 	(_("internal error: unrecognized field %d while getting int operand"),
92875fd0b74Schristos 	 opindex);
92975fd0b74Schristos       abort ();
93075fd0b74Schristos   }
93175fd0b74Schristos 
93275fd0b74Schristos   return value;
93375fd0b74Schristos }
93475fd0b74Schristos 
93575fd0b74Schristos bfd_vma
m32r_cgen_get_vma_operand(CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,int opindex,const CGEN_FIELDS * fields)93675fd0b74Schristos m32r_cgen_get_vma_operand (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
93775fd0b74Schristos 			     int opindex,
93875fd0b74Schristos 			     const CGEN_FIELDS * fields)
93975fd0b74Schristos {
94075fd0b74Schristos   bfd_vma value;
94175fd0b74Schristos 
94275fd0b74Schristos   switch (opindex)
94375fd0b74Schristos     {
94475fd0b74Schristos     case M32R_OPERAND_ACC :
94575fd0b74Schristos       value = fields->f_acc;
94675fd0b74Schristos       break;
94775fd0b74Schristos     case M32R_OPERAND_ACCD :
94875fd0b74Schristos       value = fields->f_accd;
94975fd0b74Schristos       break;
95075fd0b74Schristos     case M32R_OPERAND_ACCS :
95175fd0b74Schristos       value = fields->f_accs;
95275fd0b74Schristos       break;
95375fd0b74Schristos     case M32R_OPERAND_DCR :
95475fd0b74Schristos       value = fields->f_r1;
95575fd0b74Schristos       break;
95675fd0b74Schristos     case M32R_OPERAND_DISP16 :
95775fd0b74Schristos       value = fields->f_disp16;
95875fd0b74Schristos       break;
95975fd0b74Schristos     case M32R_OPERAND_DISP24 :
96075fd0b74Schristos       value = fields->f_disp24;
96175fd0b74Schristos       break;
96275fd0b74Schristos     case M32R_OPERAND_DISP8 :
96375fd0b74Schristos       value = fields->f_disp8;
96475fd0b74Schristos       break;
96575fd0b74Schristos     case M32R_OPERAND_DR :
96675fd0b74Schristos       value = fields->f_r1;
96775fd0b74Schristos       break;
96875fd0b74Schristos     case M32R_OPERAND_HASH :
96975fd0b74Schristos       value = 0;
97075fd0b74Schristos       break;
97175fd0b74Schristos     case M32R_OPERAND_HI16 :
97275fd0b74Schristos       value = fields->f_hi16;
97375fd0b74Schristos       break;
97475fd0b74Schristos     case M32R_OPERAND_IMM1 :
97575fd0b74Schristos       value = fields->f_imm1;
97675fd0b74Schristos       break;
97775fd0b74Schristos     case M32R_OPERAND_SCR :
97875fd0b74Schristos       value = fields->f_r2;
97975fd0b74Schristos       break;
98075fd0b74Schristos     case M32R_OPERAND_SIMM16 :
98175fd0b74Schristos       value = fields->f_simm16;
98275fd0b74Schristos       break;
98375fd0b74Schristos     case M32R_OPERAND_SIMM8 :
98475fd0b74Schristos       value = fields->f_simm8;
98575fd0b74Schristos       break;
98675fd0b74Schristos     case M32R_OPERAND_SLO16 :
98775fd0b74Schristos       value = fields->f_simm16;
98875fd0b74Schristos       break;
98975fd0b74Schristos     case M32R_OPERAND_SR :
99075fd0b74Schristos       value = fields->f_r2;
99175fd0b74Schristos       break;
99275fd0b74Schristos     case M32R_OPERAND_SRC1 :
99375fd0b74Schristos       value = fields->f_r1;
99475fd0b74Schristos       break;
99575fd0b74Schristos     case M32R_OPERAND_SRC2 :
99675fd0b74Schristos       value = fields->f_r2;
99775fd0b74Schristos       break;
99875fd0b74Schristos     case M32R_OPERAND_UIMM16 :
99975fd0b74Schristos       value = fields->f_uimm16;
100075fd0b74Schristos       break;
100175fd0b74Schristos     case M32R_OPERAND_UIMM24 :
100275fd0b74Schristos       value = fields->f_uimm24;
100375fd0b74Schristos       break;
100475fd0b74Schristos     case M32R_OPERAND_UIMM3 :
100575fd0b74Schristos       value = fields->f_uimm3;
100675fd0b74Schristos       break;
100775fd0b74Schristos     case M32R_OPERAND_UIMM4 :
100875fd0b74Schristos       value = fields->f_uimm4;
100975fd0b74Schristos       break;
101075fd0b74Schristos     case M32R_OPERAND_UIMM5 :
101175fd0b74Schristos       value = fields->f_uimm5;
101275fd0b74Schristos       break;
101375fd0b74Schristos     case M32R_OPERAND_UIMM8 :
101475fd0b74Schristos       value = fields->f_uimm8;
101575fd0b74Schristos       break;
101675fd0b74Schristos     case M32R_OPERAND_ULO16 :
101775fd0b74Schristos       value = fields->f_uimm16;
101875fd0b74Schristos       break;
101975fd0b74Schristos 
102075fd0b74Schristos     default :
102175fd0b74Schristos       /* xgettext:c-format */
1022ede78133Schristos       opcodes_error_handler
1023ede78133Schristos 	(_("internal error: unrecognized field %d while getting vma operand"),
102475fd0b74Schristos 	 opindex);
102575fd0b74Schristos       abort ();
102675fd0b74Schristos   }
102775fd0b74Schristos 
102875fd0b74Schristos   return value;
102975fd0b74Schristos }
103075fd0b74Schristos 
103175fd0b74Schristos void m32r_cgen_set_int_operand  (CGEN_CPU_DESC, int, CGEN_FIELDS *, int);
103275fd0b74Schristos void m32r_cgen_set_vma_operand  (CGEN_CPU_DESC, int, CGEN_FIELDS *, bfd_vma);
103375fd0b74Schristos 
103475fd0b74Schristos /* Stuffing values in cgen_fields is handled by a collection of functions.
103575fd0b74Schristos    They are distinguished by the type of the VALUE argument they accept.
103675fd0b74Schristos    TODO: floating point, inlining support, remove cases where argument type
103775fd0b74Schristos    not appropriate.  */
103875fd0b74Schristos 
103975fd0b74Schristos void
m32r_cgen_set_int_operand(CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,int opindex,CGEN_FIELDS * fields,int value)104075fd0b74Schristos m32r_cgen_set_int_operand (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
104175fd0b74Schristos 			     int opindex,
104275fd0b74Schristos 			     CGEN_FIELDS * fields,
104375fd0b74Schristos 			     int value)
104475fd0b74Schristos {
104575fd0b74Schristos   switch (opindex)
104675fd0b74Schristos     {
104775fd0b74Schristos     case M32R_OPERAND_ACC :
104875fd0b74Schristos       fields->f_acc = value;
104975fd0b74Schristos       break;
105075fd0b74Schristos     case M32R_OPERAND_ACCD :
105175fd0b74Schristos       fields->f_accd = value;
105275fd0b74Schristos       break;
105375fd0b74Schristos     case M32R_OPERAND_ACCS :
105475fd0b74Schristos       fields->f_accs = value;
105575fd0b74Schristos       break;
105675fd0b74Schristos     case M32R_OPERAND_DCR :
105775fd0b74Schristos       fields->f_r1 = value;
105875fd0b74Schristos       break;
105975fd0b74Schristos     case M32R_OPERAND_DISP16 :
106075fd0b74Schristos       fields->f_disp16 = value;
106175fd0b74Schristos       break;
106275fd0b74Schristos     case M32R_OPERAND_DISP24 :
106375fd0b74Schristos       fields->f_disp24 = value;
106475fd0b74Schristos       break;
106575fd0b74Schristos     case M32R_OPERAND_DISP8 :
106675fd0b74Schristos       fields->f_disp8 = value;
106775fd0b74Schristos       break;
106875fd0b74Schristos     case M32R_OPERAND_DR :
106975fd0b74Schristos       fields->f_r1 = value;
107075fd0b74Schristos       break;
107175fd0b74Schristos     case M32R_OPERAND_HASH :
107275fd0b74Schristos       break;
107375fd0b74Schristos     case M32R_OPERAND_HI16 :
107475fd0b74Schristos       fields->f_hi16 = value;
107575fd0b74Schristos       break;
107675fd0b74Schristos     case M32R_OPERAND_IMM1 :
107775fd0b74Schristos       fields->f_imm1 = value;
107875fd0b74Schristos       break;
107975fd0b74Schristos     case M32R_OPERAND_SCR :
108075fd0b74Schristos       fields->f_r2 = value;
108175fd0b74Schristos       break;
108275fd0b74Schristos     case M32R_OPERAND_SIMM16 :
108375fd0b74Schristos       fields->f_simm16 = value;
108475fd0b74Schristos       break;
108575fd0b74Schristos     case M32R_OPERAND_SIMM8 :
108675fd0b74Schristos       fields->f_simm8 = value;
108775fd0b74Schristos       break;
108875fd0b74Schristos     case M32R_OPERAND_SLO16 :
108975fd0b74Schristos       fields->f_simm16 = value;
109075fd0b74Schristos       break;
109175fd0b74Schristos     case M32R_OPERAND_SR :
109275fd0b74Schristos       fields->f_r2 = value;
109375fd0b74Schristos       break;
109475fd0b74Schristos     case M32R_OPERAND_SRC1 :
109575fd0b74Schristos       fields->f_r1 = value;
109675fd0b74Schristos       break;
109775fd0b74Schristos     case M32R_OPERAND_SRC2 :
109875fd0b74Schristos       fields->f_r2 = value;
109975fd0b74Schristos       break;
110075fd0b74Schristos     case M32R_OPERAND_UIMM16 :
110175fd0b74Schristos       fields->f_uimm16 = value;
110275fd0b74Schristos       break;
110375fd0b74Schristos     case M32R_OPERAND_UIMM24 :
110475fd0b74Schristos       fields->f_uimm24 = value;
110575fd0b74Schristos       break;
110675fd0b74Schristos     case M32R_OPERAND_UIMM3 :
110775fd0b74Schristos       fields->f_uimm3 = value;
110875fd0b74Schristos       break;
110975fd0b74Schristos     case M32R_OPERAND_UIMM4 :
111075fd0b74Schristos       fields->f_uimm4 = value;
111175fd0b74Schristos       break;
111275fd0b74Schristos     case M32R_OPERAND_UIMM5 :
111375fd0b74Schristos       fields->f_uimm5 = value;
111475fd0b74Schristos       break;
111575fd0b74Schristos     case M32R_OPERAND_UIMM8 :
111675fd0b74Schristos       fields->f_uimm8 = value;
111775fd0b74Schristos       break;
111875fd0b74Schristos     case M32R_OPERAND_ULO16 :
111975fd0b74Schristos       fields->f_uimm16 = value;
112075fd0b74Schristos       break;
112175fd0b74Schristos 
112275fd0b74Schristos     default :
112375fd0b74Schristos       /* xgettext:c-format */
1124ede78133Schristos       opcodes_error_handler
1125ede78133Schristos 	(_("internal error: unrecognized field %d while setting int operand"),
112675fd0b74Schristos 	 opindex);
112775fd0b74Schristos       abort ();
112875fd0b74Schristos   }
112975fd0b74Schristos }
113075fd0b74Schristos 
113175fd0b74Schristos void
m32r_cgen_set_vma_operand(CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,int opindex,CGEN_FIELDS * fields,bfd_vma value)113275fd0b74Schristos m32r_cgen_set_vma_operand (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
113375fd0b74Schristos 			     int opindex,
113475fd0b74Schristos 			     CGEN_FIELDS * fields,
113575fd0b74Schristos 			     bfd_vma value)
113675fd0b74Schristos {
113775fd0b74Schristos   switch (opindex)
113875fd0b74Schristos     {
113975fd0b74Schristos     case M32R_OPERAND_ACC :
114075fd0b74Schristos       fields->f_acc = value;
114175fd0b74Schristos       break;
114275fd0b74Schristos     case M32R_OPERAND_ACCD :
114375fd0b74Schristos       fields->f_accd = value;
114475fd0b74Schristos       break;
114575fd0b74Schristos     case M32R_OPERAND_ACCS :
114675fd0b74Schristos       fields->f_accs = value;
114775fd0b74Schristos       break;
114875fd0b74Schristos     case M32R_OPERAND_DCR :
114975fd0b74Schristos       fields->f_r1 = value;
115075fd0b74Schristos       break;
115175fd0b74Schristos     case M32R_OPERAND_DISP16 :
115275fd0b74Schristos       fields->f_disp16 = value;
115375fd0b74Schristos       break;
115475fd0b74Schristos     case M32R_OPERAND_DISP24 :
115575fd0b74Schristos       fields->f_disp24 = value;
115675fd0b74Schristos       break;
115775fd0b74Schristos     case M32R_OPERAND_DISP8 :
115875fd0b74Schristos       fields->f_disp8 = value;
115975fd0b74Schristos       break;
116075fd0b74Schristos     case M32R_OPERAND_DR :
116175fd0b74Schristos       fields->f_r1 = value;
116275fd0b74Schristos       break;
116375fd0b74Schristos     case M32R_OPERAND_HASH :
116475fd0b74Schristos       break;
116575fd0b74Schristos     case M32R_OPERAND_HI16 :
116675fd0b74Schristos       fields->f_hi16 = value;
116775fd0b74Schristos       break;
116875fd0b74Schristos     case M32R_OPERAND_IMM1 :
116975fd0b74Schristos       fields->f_imm1 = value;
117075fd0b74Schristos       break;
117175fd0b74Schristos     case M32R_OPERAND_SCR :
117275fd0b74Schristos       fields->f_r2 = value;
117375fd0b74Schristos       break;
117475fd0b74Schristos     case M32R_OPERAND_SIMM16 :
117575fd0b74Schristos       fields->f_simm16 = value;
117675fd0b74Schristos       break;
117775fd0b74Schristos     case M32R_OPERAND_SIMM8 :
117875fd0b74Schristos       fields->f_simm8 = value;
117975fd0b74Schristos       break;
118075fd0b74Schristos     case M32R_OPERAND_SLO16 :
118175fd0b74Schristos       fields->f_simm16 = value;
118275fd0b74Schristos       break;
118375fd0b74Schristos     case M32R_OPERAND_SR :
118475fd0b74Schristos       fields->f_r2 = value;
118575fd0b74Schristos       break;
118675fd0b74Schristos     case M32R_OPERAND_SRC1 :
118775fd0b74Schristos       fields->f_r1 = value;
118875fd0b74Schristos       break;
118975fd0b74Schristos     case M32R_OPERAND_SRC2 :
119075fd0b74Schristos       fields->f_r2 = value;
119175fd0b74Schristos       break;
119275fd0b74Schristos     case M32R_OPERAND_UIMM16 :
119375fd0b74Schristos       fields->f_uimm16 = value;
119475fd0b74Schristos       break;
119575fd0b74Schristos     case M32R_OPERAND_UIMM24 :
119675fd0b74Schristos       fields->f_uimm24 = value;
119775fd0b74Schristos       break;
119875fd0b74Schristos     case M32R_OPERAND_UIMM3 :
119975fd0b74Schristos       fields->f_uimm3 = value;
120075fd0b74Schristos       break;
120175fd0b74Schristos     case M32R_OPERAND_UIMM4 :
120275fd0b74Schristos       fields->f_uimm4 = value;
120375fd0b74Schristos       break;
120475fd0b74Schristos     case M32R_OPERAND_UIMM5 :
120575fd0b74Schristos       fields->f_uimm5 = value;
120675fd0b74Schristos       break;
120775fd0b74Schristos     case M32R_OPERAND_UIMM8 :
120875fd0b74Schristos       fields->f_uimm8 = value;
120975fd0b74Schristos       break;
121075fd0b74Schristos     case M32R_OPERAND_ULO16 :
121175fd0b74Schristos       fields->f_uimm16 = value;
121275fd0b74Schristos       break;
121375fd0b74Schristos 
121475fd0b74Schristos     default :
121575fd0b74Schristos       /* xgettext:c-format */
1216ede78133Schristos       opcodes_error_handler
1217ede78133Schristos 	(_("internal error: unrecognized field %d while setting vma operand"),
121875fd0b74Schristos 	 opindex);
121975fd0b74Schristos       abort ();
122075fd0b74Schristos   }
122175fd0b74Schristos }
122275fd0b74Schristos 
122375fd0b74Schristos /* Function to call before using the instruction builder tables.  */
122475fd0b74Schristos 
122575fd0b74Schristos void
m32r_cgen_init_ibld_table(CGEN_CPU_DESC cd)122675fd0b74Schristos m32r_cgen_init_ibld_table (CGEN_CPU_DESC cd)
122775fd0b74Schristos {
122875fd0b74Schristos   cd->insert_handlers = & m32r_cgen_insert_handlers[0];
122975fd0b74Schristos   cd->extract_handlers = & m32r_cgen_extract_handlers[0];
123075fd0b74Schristos 
123175fd0b74Schristos   cd->insert_operand = m32r_cgen_insert_operand;
123275fd0b74Schristos   cd->extract_operand = m32r_cgen_extract_operand;
123375fd0b74Schristos 
123475fd0b74Schristos   cd->get_int_operand = m32r_cgen_get_int_operand;
123575fd0b74Schristos   cd->set_int_operand = m32r_cgen_set_int_operand;
123675fd0b74Schristos   cd->get_vma_operand = m32r_cgen_get_vma_operand;
123775fd0b74Schristos   cd->set_vma_operand = m32r_cgen_set_vma_operand;
123875fd0b74Schristos }
1239