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