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