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