[ARC] Update disassembler opcode selection
[external/binutils.git] / opcodes / fr30-ibld.c
1 /* DO NOT EDIT!  -*- buffer-read-only: t -*- vi:set ro:  */
2 /* Instruction building/extraction support for fr30. -*- 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-2019 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 "fr30-desc.h"
35 #include "fr30-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 \f
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 \f
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 \f
545 /* Machine generated code added here.  */
546
547 const char * fr30_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 fr30_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 FR30_OPERAND_CRI :
577       errmsg = insert_normal (cd, fields->f_CRi, 0, 16, 12, 4, 16, total_length, buffer);
578       break;
579     case FR30_OPERAND_CRJ :
580       errmsg = insert_normal (cd, fields->f_CRj, 0, 16, 8, 4, 16, total_length, buffer);
581       break;
582     case FR30_OPERAND_R13 :
583       break;
584     case FR30_OPERAND_R14 :
585       break;
586     case FR30_OPERAND_R15 :
587       break;
588     case FR30_OPERAND_RI :
589       errmsg = insert_normal (cd, fields->f_Ri, 0, 0, 12, 4, 16, total_length, buffer);
590       break;
591     case FR30_OPERAND_RIC :
592       errmsg = insert_normal (cd, fields->f_Ric, 0, 16, 12, 4, 16, total_length, buffer);
593       break;
594     case FR30_OPERAND_RJ :
595       errmsg = insert_normal (cd, fields->f_Rj, 0, 0, 8, 4, 16, total_length, buffer);
596       break;
597     case FR30_OPERAND_RJC :
598       errmsg = insert_normal (cd, fields->f_Rjc, 0, 16, 8, 4, 16, total_length, buffer);
599       break;
600     case FR30_OPERAND_RS1 :
601       errmsg = insert_normal (cd, fields->f_Rs1, 0, 0, 8, 4, 16, total_length, buffer);
602       break;
603     case FR30_OPERAND_RS2 :
604       errmsg = insert_normal (cd, fields->f_Rs2, 0, 0, 12, 4, 16, total_length, buffer);
605       break;
606     case FR30_OPERAND_CC :
607       errmsg = insert_normal (cd, fields->f_cc, 0, 0, 4, 4, 16, total_length, buffer);
608       break;
609     case FR30_OPERAND_CCC :
610       errmsg = insert_normal (cd, fields->f_ccc, 0, 16, 0, 8, 16, total_length, buffer);
611       break;
612     case FR30_OPERAND_DIR10 :
613       {
614         long value = fields->f_dir10;
615         value = ((USI) (value) >> (2));
616         errmsg = insert_normal (cd, value, 0, 0, 8, 8, 16, total_length, buffer);
617       }
618       break;
619     case FR30_OPERAND_DIR8 :
620       errmsg = insert_normal (cd, fields->f_dir8, 0, 0, 8, 8, 16, total_length, buffer);
621       break;
622     case FR30_OPERAND_DIR9 :
623       {
624         long value = fields->f_dir9;
625         value = ((USI) (value) >> (1));
626         errmsg = insert_normal (cd, value, 0, 0, 8, 8, 16, total_length, buffer);
627       }
628       break;
629     case FR30_OPERAND_DISP10 :
630       {
631         long value = fields->f_disp10;
632         value = ((SI) (value) >> (2));
633         errmsg = insert_normal (cd, value, 0|(1<<CGEN_IFLD_SIGNED), 0, 4, 8, 16, total_length, buffer);
634       }
635       break;
636     case FR30_OPERAND_DISP8 :
637       errmsg = insert_normal (cd, fields->f_disp8, 0|(1<<CGEN_IFLD_SIGNED), 0, 4, 8, 16, total_length, buffer);
638       break;
639     case FR30_OPERAND_DISP9 :
640       {
641         long value = fields->f_disp9;
642         value = ((SI) (value) >> (1));
643         errmsg = insert_normal (cd, value, 0|(1<<CGEN_IFLD_SIGNED), 0, 4, 8, 16, total_length, buffer);
644       }
645       break;
646     case FR30_OPERAND_I20 :
647       {
648 {
649   FLD (f_i20_4) = ((UINT) (FLD (f_i20)) >> (16));
650   FLD (f_i20_16) = ((FLD (f_i20)) & (65535));
651 }
652         errmsg = insert_normal (cd, fields->f_i20_4, 0, 0, 8, 4, 16, total_length, buffer);
653         if (errmsg)
654           break;
655         errmsg = insert_normal (cd, fields->f_i20_16, 0, 16, 0, 16, 16, total_length, buffer);
656         if (errmsg)
657           break;
658       }
659       break;
660     case FR30_OPERAND_I32 :
661       errmsg = insert_normal (cd, fields->f_i32, 0|(1<<CGEN_IFLD_SIGN_OPT), 16, 0, 32, 32, total_length, buffer);
662       break;
663     case FR30_OPERAND_I8 :
664       errmsg = insert_normal (cd, fields->f_i8, 0, 0, 4, 8, 16, total_length, buffer);
665       break;
666     case FR30_OPERAND_LABEL12 :
667       {
668         long value = fields->f_rel12;
669         value = ((SI) (((value) - (((pc) + (2))))) >> (1));
670         errmsg = insert_normal (cd, value, 0|(1<<CGEN_IFLD_SIGNED)|(1<<CGEN_IFLD_PCREL_ADDR), 0, 5, 11, 16, total_length, buffer);
671       }
672       break;
673     case FR30_OPERAND_LABEL9 :
674       {
675         long value = fields->f_rel9;
676         value = ((SI) (((value) - (((pc) + (2))))) >> (1));
677         errmsg = insert_normal (cd, value, 0|(1<<CGEN_IFLD_SIGNED)|(1<<CGEN_IFLD_PCREL_ADDR), 0, 8, 8, 16, total_length, buffer);
678       }
679       break;
680     case FR30_OPERAND_M4 :
681       {
682         long value = fields->f_m4;
683         value = ((value) & (15));
684         errmsg = insert_normal (cd, value, 0, 0, 8, 4, 16, total_length, buffer);
685       }
686       break;
687     case FR30_OPERAND_PS :
688       break;
689     case FR30_OPERAND_REGLIST_HI_LD :
690       errmsg = insert_normal (cd, fields->f_reglist_hi_ld, 0, 0, 8, 8, 16, total_length, buffer);
691       break;
692     case FR30_OPERAND_REGLIST_HI_ST :
693       errmsg = insert_normal (cd, fields->f_reglist_hi_st, 0, 0, 8, 8, 16, total_length, buffer);
694       break;
695     case FR30_OPERAND_REGLIST_LOW_LD :
696       errmsg = insert_normal (cd, fields->f_reglist_low_ld, 0, 0, 8, 8, 16, total_length, buffer);
697       break;
698     case FR30_OPERAND_REGLIST_LOW_ST :
699       errmsg = insert_normal (cd, fields->f_reglist_low_st, 0, 0, 8, 8, 16, total_length, buffer);
700       break;
701     case FR30_OPERAND_S10 :
702       {
703         long value = fields->f_s10;
704         value = ((SI) (value) >> (2));
705         errmsg = insert_normal (cd, value, 0|(1<<CGEN_IFLD_SIGNED), 0, 8, 8, 16, total_length, buffer);
706       }
707       break;
708     case FR30_OPERAND_U10 :
709       {
710         long value = fields->f_u10;
711         value = ((USI) (value) >> (2));
712         errmsg = insert_normal (cd, value, 0, 0, 8, 8, 16, total_length, buffer);
713       }
714       break;
715     case FR30_OPERAND_U4 :
716       errmsg = insert_normal (cd, fields->f_u4, 0, 0, 8, 4, 16, total_length, buffer);
717       break;
718     case FR30_OPERAND_U4C :
719       errmsg = insert_normal (cd, fields->f_u4c, 0, 0, 12, 4, 16, total_length, buffer);
720       break;
721     case FR30_OPERAND_U8 :
722       errmsg = insert_normal (cd, fields->f_u8, 0, 0, 8, 8, 16, total_length, buffer);
723       break;
724     case FR30_OPERAND_UDISP6 :
725       {
726         long value = fields->f_udisp6;
727         value = ((USI) (value) >> (2));
728         errmsg = insert_normal (cd, value, 0, 0, 8, 4, 16, total_length, buffer);
729       }
730       break;
731
732     default :
733       /* xgettext:c-format */
734       opcodes_error_handler
735         (_("internal error: unrecognized field %d while building insn"),
736          opindex);
737       abort ();
738   }
739
740   return errmsg;
741 }
742
743 int fr30_cgen_extract_operand
744   (CGEN_CPU_DESC, int, CGEN_EXTRACT_INFO *, CGEN_INSN_INT, CGEN_FIELDS *, bfd_vma);
745
746 /* Main entry point for operand extraction.
747    The result is <= 0 for error, >0 for success.
748    ??? Actual values aren't well defined right now.
749
750    This function is basically just a big switch statement.  Earlier versions
751    used tables to look up the function to use, but
752    - if the table contains both assembler and disassembler functions then
753      the disassembler contains much of the assembler and vice-versa,
754    - there's a lot of inlining possibilities as things grow,
755    - using a switch statement avoids the function call overhead.
756
757    This function could be moved into `print_insn_normal', but keeping it
758    separate makes clear the interface between `print_insn_normal' and each of
759    the handlers.  */
760
761 int
762 fr30_cgen_extract_operand (CGEN_CPU_DESC cd,
763                              int opindex,
764                              CGEN_EXTRACT_INFO *ex_info,
765                              CGEN_INSN_INT insn_value,
766                              CGEN_FIELDS * fields,
767                              bfd_vma pc)
768 {
769   /* Assume success (for those operands that are nops).  */
770   int length = 1;
771   unsigned int total_length = CGEN_FIELDS_BITSIZE (fields);
772
773   switch (opindex)
774     {
775     case FR30_OPERAND_CRI :
776       length = extract_normal (cd, ex_info, insn_value, 0, 16, 12, 4, 16, total_length, pc, & fields->f_CRi);
777       break;
778     case FR30_OPERAND_CRJ :
779       length = extract_normal (cd, ex_info, insn_value, 0, 16, 8, 4, 16, total_length, pc, & fields->f_CRj);
780       break;
781     case FR30_OPERAND_R13 :
782       break;
783     case FR30_OPERAND_R14 :
784       break;
785     case FR30_OPERAND_R15 :
786       break;
787     case FR30_OPERAND_RI :
788       length = extract_normal (cd, ex_info, insn_value, 0, 0, 12, 4, 16, total_length, pc, & fields->f_Ri);
789       break;
790     case FR30_OPERAND_RIC :
791       length = extract_normal (cd, ex_info, insn_value, 0, 16, 12, 4, 16, total_length, pc, & fields->f_Ric);
792       break;
793     case FR30_OPERAND_RJ :
794       length = extract_normal (cd, ex_info, insn_value, 0, 0, 8, 4, 16, total_length, pc, & fields->f_Rj);
795       break;
796     case FR30_OPERAND_RJC :
797       length = extract_normal (cd, ex_info, insn_value, 0, 16, 8, 4, 16, total_length, pc, & fields->f_Rjc);
798       break;
799     case FR30_OPERAND_RS1 :
800       length = extract_normal (cd, ex_info, insn_value, 0, 0, 8, 4, 16, total_length, pc, & fields->f_Rs1);
801       break;
802     case FR30_OPERAND_RS2 :
803       length = extract_normal (cd, ex_info, insn_value, 0, 0, 12, 4, 16, total_length, pc, & fields->f_Rs2);
804       break;
805     case FR30_OPERAND_CC :
806       length = extract_normal (cd, ex_info, insn_value, 0, 0, 4, 4, 16, total_length, pc, & fields->f_cc);
807       break;
808     case FR30_OPERAND_CCC :
809       length = extract_normal (cd, ex_info, insn_value, 0, 16, 0, 8, 16, total_length, pc, & fields->f_ccc);
810       break;
811     case FR30_OPERAND_DIR10 :
812       {
813         long value;
814         length = extract_normal (cd, ex_info, insn_value, 0, 0, 8, 8, 16, total_length, pc, & value);
815         value = ((value) << (2));
816         fields->f_dir10 = value;
817       }
818       break;
819     case FR30_OPERAND_DIR8 :
820       length = extract_normal (cd, ex_info, insn_value, 0, 0, 8, 8, 16, total_length, pc, & fields->f_dir8);
821       break;
822     case FR30_OPERAND_DIR9 :
823       {
824         long value;
825         length = extract_normal (cd, ex_info, insn_value, 0, 0, 8, 8, 16, total_length, pc, & value);
826         value = ((value) << (1));
827         fields->f_dir9 = value;
828       }
829       break;
830     case FR30_OPERAND_DISP10 :
831       {
832         long value;
833         length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_SIGNED), 0, 4, 8, 16, total_length, pc, & value);
834         value = ((value) << (2));
835         fields->f_disp10 = value;
836       }
837       break;
838     case FR30_OPERAND_DISP8 :
839       length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_SIGNED), 0, 4, 8, 16, total_length, pc, & fields->f_disp8);
840       break;
841     case FR30_OPERAND_DISP9 :
842       {
843         long value;
844         length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_SIGNED), 0, 4, 8, 16, total_length, pc, & value);
845         value = ((value) << (1));
846         fields->f_disp9 = value;
847       }
848       break;
849     case FR30_OPERAND_I20 :
850       {
851         length = extract_normal (cd, ex_info, insn_value, 0, 0, 8, 4, 16, total_length, pc, & fields->f_i20_4);
852         if (length <= 0) break;
853         length = extract_normal (cd, ex_info, insn_value, 0, 16, 0, 16, 16, total_length, pc, & fields->f_i20_16);
854         if (length <= 0) break;
855 {
856   FLD (f_i20) = ((((FLD (f_i20_4)) << (16))) | (FLD (f_i20_16)));
857 }
858       }
859       break;
860     case FR30_OPERAND_I32 :
861       length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_SIGN_OPT), 16, 0, 32, 32, total_length, pc, & fields->f_i32);
862       break;
863     case FR30_OPERAND_I8 :
864       length = extract_normal (cd, ex_info, insn_value, 0, 0, 4, 8, 16, total_length, pc, & fields->f_i8);
865       break;
866     case FR30_OPERAND_LABEL12 :
867       {
868         long value;
869         length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_SIGNED)|(1<<CGEN_IFLD_PCREL_ADDR), 0, 5, 11, 16, total_length, pc, & value);
870         value = ((((value) << (1))) + (((pc) + (2))));
871         fields->f_rel12 = value;
872       }
873       break;
874     case FR30_OPERAND_LABEL9 :
875       {
876         long value;
877         length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_SIGNED)|(1<<CGEN_IFLD_PCREL_ADDR), 0, 8, 8, 16, total_length, pc, & value);
878         value = ((((value) << (1))) + (((pc) + (2))));
879         fields->f_rel9 = value;
880       }
881       break;
882     case FR30_OPERAND_M4 :
883       {
884         long value;
885         length = extract_normal (cd, ex_info, insn_value, 0, 0, 8, 4, 16, total_length, pc, & value);
886         value = ((value) | (-16));
887         fields->f_m4 = value;
888       }
889       break;
890     case FR30_OPERAND_PS :
891       break;
892     case FR30_OPERAND_REGLIST_HI_LD :
893       length = extract_normal (cd, ex_info, insn_value, 0, 0, 8, 8, 16, total_length, pc, & fields->f_reglist_hi_ld);
894       break;
895     case FR30_OPERAND_REGLIST_HI_ST :
896       length = extract_normal (cd, ex_info, insn_value, 0, 0, 8, 8, 16, total_length, pc, & fields->f_reglist_hi_st);
897       break;
898     case FR30_OPERAND_REGLIST_LOW_LD :
899       length = extract_normal (cd, ex_info, insn_value, 0, 0, 8, 8, 16, total_length, pc, & fields->f_reglist_low_ld);
900       break;
901     case FR30_OPERAND_REGLIST_LOW_ST :
902       length = extract_normal (cd, ex_info, insn_value, 0, 0, 8, 8, 16, total_length, pc, & fields->f_reglist_low_st);
903       break;
904     case FR30_OPERAND_S10 :
905       {
906         long value;
907         length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_SIGNED), 0, 8, 8, 16, total_length, pc, & value);
908         value = ((value) << (2));
909         fields->f_s10 = value;
910       }
911       break;
912     case FR30_OPERAND_U10 :
913       {
914         long value;
915         length = extract_normal (cd, ex_info, insn_value, 0, 0, 8, 8, 16, total_length, pc, & value);
916         value = ((value) << (2));
917         fields->f_u10 = value;
918       }
919       break;
920     case FR30_OPERAND_U4 :
921       length = extract_normal (cd, ex_info, insn_value, 0, 0, 8, 4, 16, total_length, pc, & fields->f_u4);
922       break;
923     case FR30_OPERAND_U4C :
924       length = extract_normal (cd, ex_info, insn_value, 0, 0, 12, 4, 16, total_length, pc, & fields->f_u4c);
925       break;
926     case FR30_OPERAND_U8 :
927       length = extract_normal (cd, ex_info, insn_value, 0, 0, 8, 8, 16, total_length, pc, & fields->f_u8);
928       break;
929     case FR30_OPERAND_UDISP6 :
930       {
931         long value;
932         length = extract_normal (cd, ex_info, insn_value, 0, 0, 8, 4, 16, total_length, pc, & value);
933         value = ((value) << (2));
934         fields->f_udisp6 = value;
935       }
936       break;
937
938     default :
939       /* xgettext:c-format */
940       opcodes_error_handler
941         (_("internal error: unrecognized field %d while decoding insn"),
942          opindex);
943       abort ();
944     }
945
946   return length;
947 }
948
949 cgen_insert_fn * const fr30_cgen_insert_handlers[] =
950 {
951   insert_insn_normal,
952 };
953
954 cgen_extract_fn * const fr30_cgen_extract_handlers[] =
955 {
956   extract_insn_normal,
957 };
958
959 int fr30_cgen_get_int_operand     (CGEN_CPU_DESC, int, const CGEN_FIELDS *);
960 bfd_vma fr30_cgen_get_vma_operand (CGEN_CPU_DESC, int, const CGEN_FIELDS *);
961
962 /* Getting values from cgen_fields is handled by a collection of functions.
963    They are distinguished by the type of the VALUE argument they return.
964    TODO: floating point, inlining support, remove cases where result type
965    not appropriate.  */
966
967 int
968 fr30_cgen_get_int_operand (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
969                              int opindex,
970                              const CGEN_FIELDS * fields)
971 {
972   int value;
973
974   switch (opindex)
975     {
976     case FR30_OPERAND_CRI :
977       value = fields->f_CRi;
978       break;
979     case FR30_OPERAND_CRJ :
980       value = fields->f_CRj;
981       break;
982     case FR30_OPERAND_R13 :
983       value = 0;
984       break;
985     case FR30_OPERAND_R14 :
986       value = 0;
987       break;
988     case FR30_OPERAND_R15 :
989       value = 0;
990       break;
991     case FR30_OPERAND_RI :
992       value = fields->f_Ri;
993       break;
994     case FR30_OPERAND_RIC :
995       value = fields->f_Ric;
996       break;
997     case FR30_OPERAND_RJ :
998       value = fields->f_Rj;
999       break;
1000     case FR30_OPERAND_RJC :
1001       value = fields->f_Rjc;
1002       break;
1003     case FR30_OPERAND_RS1 :
1004       value = fields->f_Rs1;
1005       break;
1006     case FR30_OPERAND_RS2 :
1007       value = fields->f_Rs2;
1008       break;
1009     case FR30_OPERAND_CC :
1010       value = fields->f_cc;
1011       break;
1012     case FR30_OPERAND_CCC :
1013       value = fields->f_ccc;
1014       break;
1015     case FR30_OPERAND_DIR10 :
1016       value = fields->f_dir10;
1017       break;
1018     case FR30_OPERAND_DIR8 :
1019       value = fields->f_dir8;
1020       break;
1021     case FR30_OPERAND_DIR9 :
1022       value = fields->f_dir9;
1023       break;
1024     case FR30_OPERAND_DISP10 :
1025       value = fields->f_disp10;
1026       break;
1027     case FR30_OPERAND_DISP8 :
1028       value = fields->f_disp8;
1029       break;
1030     case FR30_OPERAND_DISP9 :
1031       value = fields->f_disp9;
1032       break;
1033     case FR30_OPERAND_I20 :
1034       value = fields->f_i20;
1035       break;
1036     case FR30_OPERAND_I32 :
1037       value = fields->f_i32;
1038       break;
1039     case FR30_OPERAND_I8 :
1040       value = fields->f_i8;
1041       break;
1042     case FR30_OPERAND_LABEL12 :
1043       value = fields->f_rel12;
1044       break;
1045     case FR30_OPERAND_LABEL9 :
1046       value = fields->f_rel9;
1047       break;
1048     case FR30_OPERAND_M4 :
1049       value = fields->f_m4;
1050       break;
1051     case FR30_OPERAND_PS :
1052       value = 0;
1053       break;
1054     case FR30_OPERAND_REGLIST_HI_LD :
1055       value = fields->f_reglist_hi_ld;
1056       break;
1057     case FR30_OPERAND_REGLIST_HI_ST :
1058       value = fields->f_reglist_hi_st;
1059       break;
1060     case FR30_OPERAND_REGLIST_LOW_LD :
1061       value = fields->f_reglist_low_ld;
1062       break;
1063     case FR30_OPERAND_REGLIST_LOW_ST :
1064       value = fields->f_reglist_low_st;
1065       break;
1066     case FR30_OPERAND_S10 :
1067       value = fields->f_s10;
1068       break;
1069     case FR30_OPERAND_U10 :
1070       value = fields->f_u10;
1071       break;
1072     case FR30_OPERAND_U4 :
1073       value = fields->f_u4;
1074       break;
1075     case FR30_OPERAND_U4C :
1076       value = fields->f_u4c;
1077       break;
1078     case FR30_OPERAND_U8 :
1079       value = fields->f_u8;
1080       break;
1081     case FR30_OPERAND_UDISP6 :
1082       value = fields->f_udisp6;
1083       break;
1084
1085     default :
1086       /* xgettext:c-format */
1087       opcodes_error_handler
1088         (_("internal error: unrecognized field %d while getting int operand"),
1089          opindex);
1090       abort ();
1091   }
1092
1093   return value;
1094 }
1095
1096 bfd_vma
1097 fr30_cgen_get_vma_operand (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
1098                              int opindex,
1099                              const CGEN_FIELDS * fields)
1100 {
1101   bfd_vma value;
1102
1103   switch (opindex)
1104     {
1105     case FR30_OPERAND_CRI :
1106       value = fields->f_CRi;
1107       break;
1108     case FR30_OPERAND_CRJ :
1109       value = fields->f_CRj;
1110       break;
1111     case FR30_OPERAND_R13 :
1112       value = 0;
1113       break;
1114     case FR30_OPERAND_R14 :
1115       value = 0;
1116       break;
1117     case FR30_OPERAND_R15 :
1118       value = 0;
1119       break;
1120     case FR30_OPERAND_RI :
1121       value = fields->f_Ri;
1122       break;
1123     case FR30_OPERAND_RIC :
1124       value = fields->f_Ric;
1125       break;
1126     case FR30_OPERAND_RJ :
1127       value = fields->f_Rj;
1128       break;
1129     case FR30_OPERAND_RJC :
1130       value = fields->f_Rjc;
1131       break;
1132     case FR30_OPERAND_RS1 :
1133       value = fields->f_Rs1;
1134       break;
1135     case FR30_OPERAND_RS2 :
1136       value = fields->f_Rs2;
1137       break;
1138     case FR30_OPERAND_CC :
1139       value = fields->f_cc;
1140       break;
1141     case FR30_OPERAND_CCC :
1142       value = fields->f_ccc;
1143       break;
1144     case FR30_OPERAND_DIR10 :
1145       value = fields->f_dir10;
1146       break;
1147     case FR30_OPERAND_DIR8 :
1148       value = fields->f_dir8;
1149       break;
1150     case FR30_OPERAND_DIR9 :
1151       value = fields->f_dir9;
1152       break;
1153     case FR30_OPERAND_DISP10 :
1154       value = fields->f_disp10;
1155       break;
1156     case FR30_OPERAND_DISP8 :
1157       value = fields->f_disp8;
1158       break;
1159     case FR30_OPERAND_DISP9 :
1160       value = fields->f_disp9;
1161       break;
1162     case FR30_OPERAND_I20 :
1163       value = fields->f_i20;
1164       break;
1165     case FR30_OPERAND_I32 :
1166       value = fields->f_i32;
1167       break;
1168     case FR30_OPERAND_I8 :
1169       value = fields->f_i8;
1170       break;
1171     case FR30_OPERAND_LABEL12 :
1172       value = fields->f_rel12;
1173       break;
1174     case FR30_OPERAND_LABEL9 :
1175       value = fields->f_rel9;
1176       break;
1177     case FR30_OPERAND_M4 :
1178       value = fields->f_m4;
1179       break;
1180     case FR30_OPERAND_PS :
1181       value = 0;
1182       break;
1183     case FR30_OPERAND_REGLIST_HI_LD :
1184       value = fields->f_reglist_hi_ld;
1185       break;
1186     case FR30_OPERAND_REGLIST_HI_ST :
1187       value = fields->f_reglist_hi_st;
1188       break;
1189     case FR30_OPERAND_REGLIST_LOW_LD :
1190       value = fields->f_reglist_low_ld;
1191       break;
1192     case FR30_OPERAND_REGLIST_LOW_ST :
1193       value = fields->f_reglist_low_st;
1194       break;
1195     case FR30_OPERAND_S10 :
1196       value = fields->f_s10;
1197       break;
1198     case FR30_OPERAND_U10 :
1199       value = fields->f_u10;
1200       break;
1201     case FR30_OPERAND_U4 :
1202       value = fields->f_u4;
1203       break;
1204     case FR30_OPERAND_U4C :
1205       value = fields->f_u4c;
1206       break;
1207     case FR30_OPERAND_U8 :
1208       value = fields->f_u8;
1209       break;
1210     case FR30_OPERAND_UDISP6 :
1211       value = fields->f_udisp6;
1212       break;
1213
1214     default :
1215       /* xgettext:c-format */
1216       opcodes_error_handler
1217         (_("internal error: unrecognized field %d while getting vma operand"),
1218          opindex);
1219       abort ();
1220   }
1221
1222   return value;
1223 }
1224
1225 void fr30_cgen_set_int_operand  (CGEN_CPU_DESC, int, CGEN_FIELDS *, int);
1226 void fr30_cgen_set_vma_operand  (CGEN_CPU_DESC, int, CGEN_FIELDS *, bfd_vma);
1227
1228 /* Stuffing values in cgen_fields is handled by a collection of functions.
1229    They are distinguished by the type of the VALUE argument they accept.
1230    TODO: floating point, inlining support, remove cases where argument type
1231    not appropriate.  */
1232
1233 void
1234 fr30_cgen_set_int_operand (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
1235                              int opindex,
1236                              CGEN_FIELDS * fields,
1237                              int value)
1238 {
1239   switch (opindex)
1240     {
1241     case FR30_OPERAND_CRI :
1242       fields->f_CRi = value;
1243       break;
1244     case FR30_OPERAND_CRJ :
1245       fields->f_CRj = value;
1246       break;
1247     case FR30_OPERAND_R13 :
1248       break;
1249     case FR30_OPERAND_R14 :
1250       break;
1251     case FR30_OPERAND_R15 :
1252       break;
1253     case FR30_OPERAND_RI :
1254       fields->f_Ri = value;
1255       break;
1256     case FR30_OPERAND_RIC :
1257       fields->f_Ric = value;
1258       break;
1259     case FR30_OPERAND_RJ :
1260       fields->f_Rj = value;
1261       break;
1262     case FR30_OPERAND_RJC :
1263       fields->f_Rjc = value;
1264       break;
1265     case FR30_OPERAND_RS1 :
1266       fields->f_Rs1 = value;
1267       break;
1268     case FR30_OPERAND_RS2 :
1269       fields->f_Rs2 = value;
1270       break;
1271     case FR30_OPERAND_CC :
1272       fields->f_cc = value;
1273       break;
1274     case FR30_OPERAND_CCC :
1275       fields->f_ccc = value;
1276       break;
1277     case FR30_OPERAND_DIR10 :
1278       fields->f_dir10 = value;
1279       break;
1280     case FR30_OPERAND_DIR8 :
1281       fields->f_dir8 = value;
1282       break;
1283     case FR30_OPERAND_DIR9 :
1284       fields->f_dir9 = value;
1285       break;
1286     case FR30_OPERAND_DISP10 :
1287       fields->f_disp10 = value;
1288       break;
1289     case FR30_OPERAND_DISP8 :
1290       fields->f_disp8 = value;
1291       break;
1292     case FR30_OPERAND_DISP9 :
1293       fields->f_disp9 = value;
1294       break;
1295     case FR30_OPERAND_I20 :
1296       fields->f_i20 = value;
1297       break;
1298     case FR30_OPERAND_I32 :
1299       fields->f_i32 = value;
1300       break;
1301     case FR30_OPERAND_I8 :
1302       fields->f_i8 = value;
1303       break;
1304     case FR30_OPERAND_LABEL12 :
1305       fields->f_rel12 = value;
1306       break;
1307     case FR30_OPERAND_LABEL9 :
1308       fields->f_rel9 = value;
1309       break;
1310     case FR30_OPERAND_M4 :
1311       fields->f_m4 = value;
1312       break;
1313     case FR30_OPERAND_PS :
1314       break;
1315     case FR30_OPERAND_REGLIST_HI_LD :
1316       fields->f_reglist_hi_ld = value;
1317       break;
1318     case FR30_OPERAND_REGLIST_HI_ST :
1319       fields->f_reglist_hi_st = value;
1320       break;
1321     case FR30_OPERAND_REGLIST_LOW_LD :
1322       fields->f_reglist_low_ld = value;
1323       break;
1324     case FR30_OPERAND_REGLIST_LOW_ST :
1325       fields->f_reglist_low_st = value;
1326       break;
1327     case FR30_OPERAND_S10 :
1328       fields->f_s10 = value;
1329       break;
1330     case FR30_OPERAND_U10 :
1331       fields->f_u10 = value;
1332       break;
1333     case FR30_OPERAND_U4 :
1334       fields->f_u4 = value;
1335       break;
1336     case FR30_OPERAND_U4C :
1337       fields->f_u4c = value;
1338       break;
1339     case FR30_OPERAND_U8 :
1340       fields->f_u8 = value;
1341       break;
1342     case FR30_OPERAND_UDISP6 :
1343       fields->f_udisp6 = value;
1344       break;
1345
1346     default :
1347       /* xgettext:c-format */
1348       opcodes_error_handler
1349         (_("internal error: unrecognized field %d while setting int operand"),
1350          opindex);
1351       abort ();
1352   }
1353 }
1354
1355 void
1356 fr30_cgen_set_vma_operand (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
1357                              int opindex,
1358                              CGEN_FIELDS * fields,
1359                              bfd_vma value)
1360 {
1361   switch (opindex)
1362     {
1363     case FR30_OPERAND_CRI :
1364       fields->f_CRi = value;
1365       break;
1366     case FR30_OPERAND_CRJ :
1367       fields->f_CRj = value;
1368       break;
1369     case FR30_OPERAND_R13 :
1370       break;
1371     case FR30_OPERAND_R14 :
1372       break;
1373     case FR30_OPERAND_R15 :
1374       break;
1375     case FR30_OPERAND_RI :
1376       fields->f_Ri = value;
1377       break;
1378     case FR30_OPERAND_RIC :
1379       fields->f_Ric = value;
1380       break;
1381     case FR30_OPERAND_RJ :
1382       fields->f_Rj = value;
1383       break;
1384     case FR30_OPERAND_RJC :
1385       fields->f_Rjc = value;
1386       break;
1387     case FR30_OPERAND_RS1 :
1388       fields->f_Rs1 = value;
1389       break;
1390     case FR30_OPERAND_RS2 :
1391       fields->f_Rs2 = value;
1392       break;
1393     case FR30_OPERAND_CC :
1394       fields->f_cc = value;
1395       break;
1396     case FR30_OPERAND_CCC :
1397       fields->f_ccc = value;
1398       break;
1399     case FR30_OPERAND_DIR10 :
1400       fields->f_dir10 = value;
1401       break;
1402     case FR30_OPERAND_DIR8 :
1403       fields->f_dir8 = value;
1404       break;
1405     case FR30_OPERAND_DIR9 :
1406       fields->f_dir9 = value;
1407       break;
1408     case FR30_OPERAND_DISP10 :
1409       fields->f_disp10 = value;
1410       break;
1411     case FR30_OPERAND_DISP8 :
1412       fields->f_disp8 = value;
1413       break;
1414     case FR30_OPERAND_DISP9 :
1415       fields->f_disp9 = value;
1416       break;
1417     case FR30_OPERAND_I20 :
1418       fields->f_i20 = value;
1419       break;
1420     case FR30_OPERAND_I32 :
1421       fields->f_i32 = value;
1422       break;
1423     case FR30_OPERAND_I8 :
1424       fields->f_i8 = value;
1425       break;
1426     case FR30_OPERAND_LABEL12 :
1427       fields->f_rel12 = value;
1428       break;
1429     case FR30_OPERAND_LABEL9 :
1430       fields->f_rel9 = value;
1431       break;
1432     case FR30_OPERAND_M4 :
1433       fields->f_m4 = value;
1434       break;
1435     case FR30_OPERAND_PS :
1436       break;
1437     case FR30_OPERAND_REGLIST_HI_LD :
1438       fields->f_reglist_hi_ld = value;
1439       break;
1440     case FR30_OPERAND_REGLIST_HI_ST :
1441       fields->f_reglist_hi_st = value;
1442       break;
1443     case FR30_OPERAND_REGLIST_LOW_LD :
1444       fields->f_reglist_low_ld = value;
1445       break;
1446     case FR30_OPERAND_REGLIST_LOW_ST :
1447       fields->f_reglist_low_st = value;
1448       break;
1449     case FR30_OPERAND_S10 :
1450       fields->f_s10 = value;
1451       break;
1452     case FR30_OPERAND_U10 :
1453       fields->f_u10 = value;
1454       break;
1455     case FR30_OPERAND_U4 :
1456       fields->f_u4 = value;
1457       break;
1458     case FR30_OPERAND_U4C :
1459       fields->f_u4c = value;
1460       break;
1461     case FR30_OPERAND_U8 :
1462       fields->f_u8 = value;
1463       break;
1464     case FR30_OPERAND_UDISP6 :
1465       fields->f_udisp6 = value;
1466       break;
1467
1468     default :
1469       /* xgettext:c-format */
1470       opcodes_error_handler
1471         (_("internal error: unrecognized field %d while setting vma operand"),
1472          opindex);
1473       abort ();
1474   }
1475 }
1476
1477 /* Function to call before using the instruction builder tables.  */
1478
1479 void
1480 fr30_cgen_init_ibld_table (CGEN_CPU_DESC cd)
1481 {
1482   cd->insert_handlers = & fr30_cgen_insert_handlers[0];
1483   cd->extract_handlers = & fr30_cgen_extract_handlers[0];
1484
1485   cd->insert_operand = fr30_cgen_insert_operand;
1486   cd->extract_operand = fr30_cgen_extract_operand;
1487
1488   cd->get_int_operand = fr30_cgen_get_int_operand;
1489   cd->set_int_operand = fr30_cgen_set_int_operand;
1490   cd->get_vma_operand = fr30_cgen_get_vma_operand;
1491   cd->set_vma_operand = fr30_cgen_set_vma_operand;
1492 }