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