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