OSDN Git Service

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