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 (C) 1996-2017 Free Software Foundation, Inc.
7
8   This file is part of libopcodes.
9
10   This library 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 3, or (at your option)
13   any later version.
14
15   It is distributed in the hope that it will be useful, but WITHOUT
16   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
17   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
18   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   51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, 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 "cgen/basic-modes.h"
36#include "opintl.h"
37#include "safe-ctype.h"
38
39#undef  min
40#define min(a,b) ((a) < (b) ? (a) : (b))
41#undef  max
42#define max(a,b) ((a) > (b) ? (a) : (b))
43
44/* Used by the ifield rtx function.  */
45#define FLD(f) (fields->f)
46
47static const char * insert_normal
48  (CGEN_CPU_DESC, long, unsigned int, unsigned int, unsigned int,
49   unsigned int, unsigned int, unsigned int, CGEN_INSN_BYTES_PTR);
50static const char * insert_insn_normal
51  (CGEN_CPU_DESC, const CGEN_INSN *,
52   CGEN_FIELDS *, CGEN_INSN_BYTES_PTR, bfd_vma);
53static int extract_normal
54  (CGEN_CPU_DESC, CGEN_EXTRACT_INFO *, CGEN_INSN_INT,
55   unsigned int, unsigned int, unsigned int, unsigned int,
56   unsigned int, unsigned int, bfd_vma, long *);
57static int extract_insn_normal
58  (CGEN_CPU_DESC, const CGEN_INSN *, CGEN_EXTRACT_INFO *,
59   CGEN_INSN_INT, CGEN_FIELDS *, bfd_vma);
60#if CGEN_INT_INSN_P
61static void put_insn_int_value
62  (CGEN_CPU_DESC, CGEN_INSN_BYTES_PTR, int, int, CGEN_INSN_INT);
63#endif
64#if ! CGEN_INT_INSN_P
65static CGEN_INLINE void insert_1
66  (CGEN_CPU_DESC, unsigned long, int, int, int, unsigned char *);
67static CGEN_INLINE int fill_cache
68  (CGEN_CPU_DESC, CGEN_EXTRACT_INFO *,  int, int, bfd_vma);
69static CGEN_INLINE long extract_1
70  (CGEN_CPU_DESC, CGEN_EXTRACT_INFO *, int, int, int, unsigned char *, bfd_vma);
71#endif
72
73/* Operand insertion.  */
74
75#if ! CGEN_INT_INSN_P
76
77/* Subroutine of insert_normal.  */
78
79static CGEN_INLINE void
80insert_1 (CGEN_CPU_DESC cd,
81	  unsigned long value,
82	  int start,
83	  int length,
84	  int word_length,
85	  unsigned char *bufp)
86{
87  unsigned long x,mask;
88  int shift;
89
90  x = cgen_get_insn_value (cd, bufp, word_length);
91
92  /* Written this way to avoid undefined behaviour.  */
93  mask = (((1L << (length - 1)) - 1) << 1) | 1;
94  if (CGEN_INSN_LSB0_P)
95    shift = (start + 1) - length;
96  else
97    shift = (word_length - (start + length));
98  x = (x & ~(mask << shift)) | ((value & mask) << shift);
99
100  cgen_put_insn_value (cd, bufp, word_length, (bfd_vma) x);
101}
102
103#endif /* ! CGEN_INT_INSN_P */
104
105/* Default insertion routine.
106
107   ATTRS is a mask of the boolean attributes.
108   WORD_OFFSET is the offset in bits from the start of the insn of the value.
109   WORD_LENGTH is the length of the word in bits in which the value resides.
110   START is the starting bit number in the word, architecture origin.
111   LENGTH is the length of VALUE in bits.
112   TOTAL_LENGTH is the total length of the insn in bits.
113
114   The result is an error message or NULL if success.  */
115
116/* ??? This duplicates functionality with bfd's howto table and
117   bfd_install_relocation.  */
118/* ??? This doesn't handle bfd_vma's.  Create another function when
119   necessary.  */
120
121static const char *
122insert_normal (CGEN_CPU_DESC cd,
123	       long value,
124	       unsigned int attrs,
125	       unsigned int word_offset,
126	       unsigned int start,
127	       unsigned int length,
128	       unsigned int word_length,
129	       unsigned int total_length,
130	       CGEN_INSN_BYTES_PTR buffer)
131{
132  static char errbuf[100];
133  /* Written this way to avoid undefined behaviour.  */
134  unsigned long mask = (((1L << (length - 1)) - 1) << 1) | 1;
135
136  /* If LENGTH is zero, this operand doesn't contribute to the value.  */
137  if (length == 0)
138    return NULL;
139
140  if (word_length > 8 * sizeof (CGEN_INSN_INT))
141    abort ();
142
143  /* For architectures with insns smaller than the base-insn-bitsize,
144     word_length may be too big.  */
145  if (cd->min_insn_bitsize < cd->base_insn_bitsize)
146    {
147      if (word_offset == 0
148	  && word_length > total_length)
149	word_length = total_length;
150    }
151
152  /* Ensure VALUE will fit.  */
153  if (CGEN_BOOL_ATTR (attrs, CGEN_IFLD_SIGN_OPT))
154    {
155      long minval = - (1L << (length - 1));
156      unsigned long maxval = mask;
157
158      if ((value > 0 && (unsigned long) value > maxval)
159	  || value < minval)
160	{
161	  /* xgettext:c-format */
162	  sprintf (errbuf,
163		   _("operand out of range (%ld not between %ld and %lu)"),
164		   value, minval, maxval);
165	  return errbuf;
166	}
167    }
168  else if (! CGEN_BOOL_ATTR (attrs, CGEN_IFLD_SIGNED))
169    {
170      unsigned long maxval = mask;
171      unsigned long val = (unsigned long) value;
172
173      /* For hosts with a word size > 32 check to see if value has been sign
174	 extended beyond 32 bits.  If so then ignore these higher sign bits
175	 as the user is attempting to store a 32-bit signed value into an
176	 unsigned 32-bit field which is allowed.  */
177      if (sizeof (unsigned long) > 4 && ((value >> 32) == -1))
178	val &= 0xFFFFFFFF;
179
180      if (val > maxval)
181	{
182	  /* xgettext:c-format */
183	  sprintf (errbuf,
184		   _("operand out of range (0x%lx not between 0 and 0x%lx)"),
185		   val, maxval);
186	  return errbuf;
187	}
188    }
189  else
190    {
191      if (! cgen_signed_overflow_ok_p (cd))
192	{
193	  long minval = - (1L << (length - 1));
194	  long maxval =   (1L << (length - 1)) - 1;
195
196	  if (value < minval || value > maxval)
197	    {
198	      sprintf
199		/* xgettext:c-format */
200		(errbuf, _("operand out of range (%ld not between %ld and %ld)"),
201		 value, minval, maxval);
202	      return errbuf;
203	    }
204	}
205    }
206
207#if CGEN_INT_INSN_P
208
209  {
210    int shift_within_word, shift_to_word, shift;
211
212    /* How to shift the value to BIT0 of the word.  */
213    shift_to_word = total_length - (word_offset + word_length);
214
215    /* How to shift the value to the field within the word.  */
216    if (CGEN_INSN_LSB0_P)
217      shift_within_word = start + 1 - length;
218    else
219      shift_within_word = word_length - start - length;
220
221    /* The total SHIFT, then mask in the value.  */
222    shift = shift_to_word + shift_within_word;
223    *buffer = (*buffer & ~(mask << shift)) | ((value & mask) << shift);
224  }
225
226#else /* ! CGEN_INT_INSN_P */
227
228  {
229    unsigned char *bufp = (unsigned char *) buffer + word_offset / 8;
230
231    insert_1 (cd, value, start, length, word_length, bufp);
232  }
233
234#endif /* ! CGEN_INT_INSN_P */
235
236  return NULL;
237}
238
239/* Default insn builder (insert handler).
240   The instruction is recorded in CGEN_INT_INSN_P byte order (meaning
241   that if CGEN_INSN_BYTES_PTR is an int * and thus, the value is
242   recorded in host byte order, otherwise BUFFER is an array of bytes
243   and the value is recorded in target byte order).
244   The result is an error message or NULL if success.  */
245
246static const char *
247insert_insn_normal (CGEN_CPU_DESC cd,
248		    const CGEN_INSN * insn,
249		    CGEN_FIELDS * fields,
250		    CGEN_INSN_BYTES_PTR buffer,
251		    bfd_vma pc)
252{
253  const CGEN_SYNTAX *syntax = CGEN_INSN_SYNTAX (insn);
254  unsigned long value;
255  const CGEN_SYNTAX_CHAR_TYPE * syn;
256
257  CGEN_INIT_INSERT (cd);
258  value = CGEN_INSN_BASE_VALUE (insn);
259
260  /* If we're recording insns as numbers (rather than a string of bytes),
261     target byte order handling is deferred until later.  */
262
263#if CGEN_INT_INSN_P
264
265  put_insn_int_value (cd, buffer, cd->base_insn_bitsize,
266		      CGEN_FIELDS_BITSIZE (fields), value);
267
268#else
269
270  cgen_put_insn_value (cd, buffer, min ((unsigned) cd->base_insn_bitsize,
271					(unsigned) CGEN_FIELDS_BITSIZE (fields)),
272		       value);
273
274#endif /* ! CGEN_INT_INSN_P */
275
276  /* ??? It would be better to scan the format's fields.
277     Still need to be able to insert a value based on the operand though;
278     e.g. storing a branch displacement that got resolved later.
279     Needs more thought first.  */
280
281  for (syn = CGEN_SYNTAX_STRING (syntax); * syn; ++ syn)
282    {
283      const char *errmsg;
284
285      if (CGEN_SYNTAX_CHAR_P (* syn))
286	continue;
287
288      errmsg = (* cd->insert_operand) (cd, CGEN_SYNTAX_FIELD (*syn),
289				       fields, buffer, pc);
290      if (errmsg)
291	return errmsg;
292    }
293
294  return NULL;
295}
296
297#if CGEN_INT_INSN_P
298/* Cover function to store an insn value into an integral insn.  Must go here
299   because it needs <prefix>-desc.h for CGEN_INT_INSN_P.  */
300
301static void
302put_insn_int_value (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
303		    CGEN_INSN_BYTES_PTR buf,
304		    int length,
305		    int insn_length,
306		    CGEN_INSN_INT value)
307{
308  /* For architectures with insns smaller than the base-insn-bitsize,
309     length may be too big.  */
310  if (length > insn_length)
311    *buf = value;
312  else
313    {
314      int shift = insn_length - length;
315      /* Written this way to avoid undefined behaviour.  */
316      CGEN_INSN_INT mask = (((1L << (length - 1)) - 1) << 1) | 1;
317
318      *buf = (*buf & ~(mask << shift)) | ((value & mask) << shift);
319    }
320}
321#endif
322
323/* Operand extraction.  */
324
325#if ! CGEN_INT_INSN_P
326
327/* Subroutine of extract_normal.
328   Ensure sufficient bytes are cached in EX_INFO.
329   OFFSET is the offset in bytes from the start of the insn of the value.
330   BYTES is the length of the needed value.
331   Returns 1 for success, 0 for failure.  */
332
333static CGEN_INLINE int
334fill_cache (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
335	    CGEN_EXTRACT_INFO *ex_info,
336	    int offset,
337	    int bytes,
338	    bfd_vma pc)
339{
340  /* It's doubtful that the middle part has already been fetched so
341     we don't optimize that case.  kiss.  */
342  unsigned int mask;
343  disassemble_info *info = (disassemble_info *) ex_info->dis_info;
344
345  /* First do a quick check.  */
346  mask = (1 << bytes) - 1;
347  if (((ex_info->valid >> offset) & mask) == mask)
348    return 1;
349
350  /* Search for the first byte we need to read.  */
351  for (mask = 1 << offset; bytes > 0; --bytes, ++offset, mask <<= 1)
352    if (! (mask & ex_info->valid))
353      break;
354
355  if (bytes)
356    {
357      int status;
358
359      pc += offset;
360      status = (*info->read_memory_func)
361	(pc, ex_info->insn_bytes + offset, bytes, info);
362
363      if (status != 0)
364	{
365	  (*info->memory_error_func) (status, pc, info);
366	  return 0;
367	}
368
369      ex_info->valid |= ((1 << bytes) - 1) << offset;
370    }
371
372  return 1;
373}
374
375/* Subroutine of extract_normal.  */
376
377static CGEN_INLINE long
378extract_1 (CGEN_CPU_DESC cd,
379	   CGEN_EXTRACT_INFO *ex_info ATTRIBUTE_UNUSED,
380	   int start,
381	   int length,
382	   int word_length,
383	   unsigned char *bufp,
384	   bfd_vma pc ATTRIBUTE_UNUSED)
385{
386  unsigned long x;
387  int shift;
388
389  x = cgen_get_insn_value (cd, bufp, word_length);
390
391  if (CGEN_INSN_LSB0_P)
392    shift = (start + 1) - length;
393  else
394    shift = (word_length - (start + length));
395  return x >> shift;
396}
397
398#endif /* ! CGEN_INT_INSN_P */
399
400/* Default extraction routine.
401
402   INSN_VALUE is the first base_insn_bitsize bits of the insn in host order,
403   or sometimes less for cases like the m32r where the base insn size is 32
404   but some insns are 16 bits.
405   ATTRS is a mask of the boolean attributes.  We only need `SIGNED',
406   but for generality we take a bitmask of all of them.
407   WORD_OFFSET is the offset in bits from the start of the insn of the value.
408   WORD_LENGTH is the length of the word in bits in which the value resides.
409   START is the starting bit number in the word, architecture origin.
410   LENGTH is the length of VALUE in bits.
411   TOTAL_LENGTH is the total length of the insn in bits.
412
413   Returns 1 for success, 0 for failure.  */
414
415/* ??? The return code isn't properly used.  wip.  */
416
417/* ??? This doesn't handle bfd_vma's.  Create another function when
418   necessary.  */
419
420static int
421extract_normal (CGEN_CPU_DESC cd,
422#if ! CGEN_INT_INSN_P
423		CGEN_EXTRACT_INFO *ex_info,
424#else
425		CGEN_EXTRACT_INFO *ex_info ATTRIBUTE_UNUSED,
426#endif
427		CGEN_INSN_INT insn_value,
428		unsigned int attrs,
429		unsigned int word_offset,
430		unsigned int start,
431		unsigned int length,
432		unsigned int word_length,
433		unsigned int total_length,
434#if ! CGEN_INT_INSN_P
435		bfd_vma pc,
436#else
437		bfd_vma pc ATTRIBUTE_UNUSED,
438#endif
439		long *valuep)
440{
441  long value, mask;
442
443  /* If LENGTH is zero, this operand doesn't contribute to the value
444     so give it a standard value of zero.  */
445  if (length == 0)
446    {
447      *valuep = 0;
448      return 1;
449    }
450
451  if (word_length > 8 * sizeof (CGEN_INSN_INT))
452    abort ();
453
454  /* For architectures with insns smaller than the insn-base-bitsize,
455     word_length may be too big.  */
456  if (cd->min_insn_bitsize < cd->base_insn_bitsize)
457    {
458      if (word_offset + word_length > total_length)
459	word_length = total_length - word_offset;
460    }
461
462  /* Does the value reside in INSN_VALUE, and at the right alignment?  */
463
464  if (CGEN_INT_INSN_P || (word_offset == 0 && word_length == total_length))
465    {
466      if (CGEN_INSN_LSB0_P)
467	value = insn_value >> ((word_offset + start + 1) - length);
468      else
469	value = insn_value >> (total_length - ( word_offset + start + length));
470    }
471
472#if ! CGEN_INT_INSN_P
473
474  else
475    {
476      unsigned char *bufp = ex_info->insn_bytes + word_offset / 8;
477
478      if (word_length > 8 * sizeof (CGEN_INSN_INT))
479	abort ();
480
481      if (fill_cache (cd, ex_info, word_offset / 8, word_length / 8, pc) == 0)
482	return 0;
483
484      value = extract_1 (cd, ex_info, start, length, word_length, bufp, pc);
485    }
486
487#endif /* ! CGEN_INT_INSN_P */
488
489  /* Written this way to avoid undefined behaviour.  */
490  mask = (((1L << (length - 1)) - 1) << 1) | 1;
491
492  value &= mask;
493  /* sign extend? */
494  if (CGEN_BOOL_ATTR (attrs, CGEN_IFLD_SIGNED)
495      && (value & (1L << (length - 1))))
496    value |= ~mask;
497
498  *valuep = value;
499
500  return 1;
501}
502
503/* Default insn extractor.
504
505   INSN_VALUE is the first base_insn_bitsize bits, translated to host order.
506   The extracted fields are stored in FIELDS.
507   EX_INFO is used to handle reading variable length insns.
508   Return the length of the insn in bits, or 0 if no match,
509   or -1 if an error occurs fetching data (memory_error_func will have
510   been called).  */
511
512static int
513extract_insn_normal (CGEN_CPU_DESC cd,
514		     const CGEN_INSN *insn,
515		     CGEN_EXTRACT_INFO *ex_info,
516		     CGEN_INSN_INT insn_value,
517		     CGEN_FIELDS *fields,
518		     bfd_vma pc)
519{
520  const CGEN_SYNTAX *syntax = CGEN_INSN_SYNTAX (insn);
521  const CGEN_SYNTAX_CHAR_TYPE *syn;
522
523  CGEN_FIELDS_BITSIZE (fields) = CGEN_INSN_BITSIZE (insn);
524
525  CGEN_INIT_EXTRACT (cd);
526
527  for (syn = CGEN_SYNTAX_STRING (syntax); *syn; ++syn)
528    {
529      int length;
530
531      if (CGEN_SYNTAX_CHAR_P (*syn))
532	continue;
533
534      length = (* cd->extract_operand) (cd, CGEN_SYNTAX_FIELD (*syn),
535					ex_info, insn_value, fields, pc);
536      if (length <= 0)
537	return length;
538    }
539
540  /* We recognized and successfully extracted this insn.  */
541  return CGEN_INSN_BITSIZE (insn);
542}
543
544/* Machine generated code added here.  */
545
546const char * fr30_cgen_insert_operand
547  (CGEN_CPU_DESC, int, CGEN_FIELDS *, CGEN_INSN_BYTES_PTR, bfd_vma);
548
549/* Main entry point for operand insertion.
550
551   This function is basically just a big switch statement.  Earlier versions
552   used tables to look up the function to use, but
553   - if the table contains both assembler and disassembler functions then
554     the disassembler contains much of the assembler and vice-versa,
555   - there's a lot of inlining possibilities as things grow,
556   - using a switch statement avoids the function call overhead.
557
558   This function could be moved into `parse_insn_normal', but keeping it
559   separate makes clear the interface between `parse_insn_normal' and each of
560   the handlers.  It's also needed by GAS to insert operands that couldn't be
561   resolved during parsing.  */
562
563const char *
564fr30_cgen_insert_operand (CGEN_CPU_DESC cd,
565			     int opindex,
566			     CGEN_FIELDS * fields,
567			     CGEN_INSN_BYTES_PTR buffer,
568			     bfd_vma pc ATTRIBUTE_UNUSED)
569{
570  const char * errmsg = NULL;
571  unsigned int total_length = CGEN_FIELDS_BITSIZE (fields);
572
573  switch (opindex)
574    {
575    case FR30_OPERAND_CRI :
576      errmsg = insert_normal (cd, fields->f_CRi, 0, 16, 12, 4, 16, total_length, buffer);
577      break;
578    case FR30_OPERAND_CRJ :
579      errmsg = insert_normal (cd, fields->f_CRj, 0, 16, 8, 4, 16, total_length, buffer);
580      break;
581    case FR30_OPERAND_R13 :
582      break;
583    case FR30_OPERAND_R14 :
584      break;
585    case FR30_OPERAND_R15 :
586      break;
587    case FR30_OPERAND_RI :
588      errmsg = insert_normal (cd, fields->f_Ri, 0, 0, 12, 4, 16, total_length, buffer);
589      break;
590    case FR30_OPERAND_RIC :
591      errmsg = insert_normal (cd, fields->f_Ric, 0, 16, 12, 4, 16, total_length, buffer);
592      break;
593    case FR30_OPERAND_RJ :
594      errmsg = insert_normal (cd, fields->f_Rj, 0, 0, 8, 4, 16, total_length, buffer);
595      break;
596    case FR30_OPERAND_RJC :
597      errmsg = insert_normal (cd, fields->f_Rjc, 0, 16, 8, 4, 16, total_length, buffer);
598      break;
599    case FR30_OPERAND_RS1 :
600      errmsg = insert_normal (cd, fields->f_Rs1, 0, 0, 8, 4, 16, total_length, buffer);
601      break;
602    case FR30_OPERAND_RS2 :
603      errmsg = insert_normal (cd, fields->f_Rs2, 0, 0, 12, 4, 16, total_length, buffer);
604      break;
605    case FR30_OPERAND_CC :
606      errmsg = insert_normal (cd, fields->f_cc, 0, 0, 4, 4, 16, total_length, buffer);
607      break;
608    case FR30_OPERAND_CCC :
609      errmsg = insert_normal (cd, fields->f_ccc, 0, 16, 0, 8, 16, total_length, buffer);
610      break;
611    case FR30_OPERAND_DIR10 :
612      {
613        long value = fields->f_dir10;
614        value = ((USI) (value) >> (2));
615        errmsg = insert_normal (cd, value, 0, 0, 8, 8, 16, total_length, buffer);
616      }
617      break;
618    case FR30_OPERAND_DIR8 :
619      errmsg = insert_normal (cd, fields->f_dir8, 0, 0, 8, 8, 16, total_length, buffer);
620      break;
621    case FR30_OPERAND_DIR9 :
622      {
623        long value = fields->f_dir9;
624        value = ((USI) (value) >> (1));
625        errmsg = insert_normal (cd, value, 0, 0, 8, 8, 16, total_length, buffer);
626      }
627      break;
628    case FR30_OPERAND_DISP10 :
629      {
630        long value = fields->f_disp10;
631        value = ((SI) (value) >> (2));
632        errmsg = insert_normal (cd, value, 0|(1<<CGEN_IFLD_SIGNED), 0, 4, 8, 16, total_length, buffer);
633      }
634      break;
635    case FR30_OPERAND_DISP8 :
636      errmsg = insert_normal (cd, fields->f_disp8, 0|(1<<CGEN_IFLD_SIGNED), 0, 4, 8, 16, total_length, buffer);
637      break;
638    case FR30_OPERAND_DISP9 :
639      {
640        long value = fields->f_disp9;
641        value = ((SI) (value) >> (1));
642        errmsg = insert_normal (cd, value, 0|(1<<CGEN_IFLD_SIGNED), 0, 4, 8, 16, total_length, buffer);
643      }
644      break;
645    case FR30_OPERAND_I20 :
646      {
647{
648  FLD (f_i20_4) = ((UINT) (FLD (f_i20)) >> (16));
649  FLD (f_i20_16) = ((FLD (f_i20)) & (65535));
650}
651        errmsg = insert_normal (cd, fields->f_i20_4, 0, 0, 8, 4, 16, total_length, buffer);
652        if (errmsg)
653          break;
654        errmsg = insert_normal (cd, fields->f_i20_16, 0, 16, 0, 16, 16, total_length, buffer);
655        if (errmsg)
656          break;
657      }
658      break;
659    case FR30_OPERAND_I32 :
660      errmsg = insert_normal (cd, fields->f_i32, 0|(1<<CGEN_IFLD_SIGN_OPT), 16, 0, 32, 32, total_length, buffer);
661      break;
662    case FR30_OPERAND_I8 :
663      errmsg = insert_normal (cd, fields->f_i8, 0, 0, 4, 8, 16, total_length, buffer);
664      break;
665    case FR30_OPERAND_LABEL12 :
666      {
667        long value = fields->f_rel12;
668        value = ((SI) (((value) - (((pc) + (2))))) >> (1));
669        errmsg = insert_normal (cd, value, 0|(1<<CGEN_IFLD_SIGNED)|(1<<CGEN_IFLD_PCREL_ADDR), 0, 5, 11, 16, total_length, buffer);
670      }
671      break;
672    case FR30_OPERAND_LABEL9 :
673      {
674        long value = fields->f_rel9;
675        value = ((SI) (((value) - (((pc) + (2))))) >> (1));
676        errmsg = insert_normal (cd, value, 0|(1<<CGEN_IFLD_SIGNED)|(1<<CGEN_IFLD_PCREL_ADDR), 0, 8, 8, 16, total_length, buffer);
677      }
678      break;
679    case FR30_OPERAND_M4 :
680      {
681        long value = fields->f_m4;
682        value = ((value) & (15));
683        errmsg = insert_normal (cd, value, 0, 0, 8, 4, 16, total_length, buffer);
684      }
685      break;
686    case FR30_OPERAND_PS :
687      break;
688    case FR30_OPERAND_REGLIST_HI_LD :
689      errmsg = insert_normal (cd, fields->f_reglist_hi_ld, 0, 0, 8, 8, 16, total_length, buffer);
690      break;
691    case FR30_OPERAND_REGLIST_HI_ST :
692      errmsg = insert_normal (cd, fields->f_reglist_hi_st, 0, 0, 8, 8, 16, total_length, buffer);
693      break;
694    case FR30_OPERAND_REGLIST_LOW_LD :
695      errmsg = insert_normal (cd, fields->f_reglist_low_ld, 0, 0, 8, 8, 16, total_length, buffer);
696      break;
697    case FR30_OPERAND_REGLIST_LOW_ST :
698      errmsg = insert_normal (cd, fields->f_reglist_low_st, 0, 0, 8, 8, 16, total_length, buffer);
699      break;
700    case FR30_OPERAND_S10 :
701      {
702        long value = fields->f_s10;
703        value = ((SI) (value) >> (2));
704        errmsg = insert_normal (cd, value, 0|(1<<CGEN_IFLD_SIGNED), 0, 8, 8, 16, total_length, buffer);
705      }
706      break;
707    case FR30_OPERAND_U10 :
708      {
709        long value = fields->f_u10;
710        value = ((USI) (value) >> (2));
711        errmsg = insert_normal (cd, value, 0, 0, 8, 8, 16, total_length, buffer);
712      }
713      break;
714    case FR30_OPERAND_U4 :
715      errmsg = insert_normal (cd, fields->f_u4, 0, 0, 8, 4, 16, total_length, buffer);
716      break;
717    case FR30_OPERAND_U4C :
718      errmsg = insert_normal (cd, fields->f_u4c, 0, 0, 12, 4, 16, total_length, buffer);
719      break;
720    case FR30_OPERAND_U8 :
721      errmsg = insert_normal (cd, fields->f_u8, 0, 0, 8, 8, 16, total_length, buffer);
722      break;
723    case FR30_OPERAND_UDISP6 :
724      {
725        long value = fields->f_udisp6;
726        value = ((USI) (value) >> (2));
727        errmsg = insert_normal (cd, value, 0, 0, 8, 4, 16, total_length, buffer);
728      }
729      break;
730
731    default :
732      /* xgettext:c-format */
733      fprintf (stderr, _("Unrecognized field %d while building insn.\n"),
734	       opindex);
735      abort ();
736  }
737
738  return errmsg;
739}
740
741int fr30_cgen_extract_operand
742  (CGEN_CPU_DESC, int, CGEN_EXTRACT_INFO *, CGEN_INSN_INT, CGEN_FIELDS *, bfd_vma);
743
744/* Main entry point for operand extraction.
745   The result is <= 0 for error, >0 for success.
746   ??? Actual values aren't well defined right now.
747
748   This function is basically just a big switch statement.  Earlier versions
749   used tables to look up the function to use, but
750   - if the table contains both assembler and disassembler functions then
751     the disassembler contains much of the assembler and vice-versa,
752   - there's a lot of inlining possibilities as things grow,
753   - using a switch statement avoids the function call overhead.
754
755   This function could be moved into `print_insn_normal', but keeping it
756   separate makes clear the interface between `print_insn_normal' and each of
757   the handlers.  */
758
759int
760fr30_cgen_extract_operand (CGEN_CPU_DESC cd,
761			     int opindex,
762			     CGEN_EXTRACT_INFO *ex_info,
763			     CGEN_INSN_INT insn_value,
764			     CGEN_FIELDS * fields,
765			     bfd_vma pc)
766{
767  /* Assume success (for those operands that are nops).  */
768  int length = 1;
769  unsigned int total_length = CGEN_FIELDS_BITSIZE (fields);
770
771  switch (opindex)
772    {
773    case FR30_OPERAND_CRI :
774      length = extract_normal (cd, ex_info, insn_value, 0, 16, 12, 4, 16, total_length, pc, & fields->f_CRi);
775      break;
776    case FR30_OPERAND_CRJ :
777      length = extract_normal (cd, ex_info, insn_value, 0, 16, 8, 4, 16, total_length, pc, & fields->f_CRj);
778      break;
779    case FR30_OPERAND_R13 :
780      break;
781    case FR30_OPERAND_R14 :
782      break;
783    case FR30_OPERAND_R15 :
784      break;
785    case FR30_OPERAND_RI :
786      length = extract_normal (cd, ex_info, insn_value, 0, 0, 12, 4, 16, total_length, pc, & fields->f_Ri);
787      break;
788    case FR30_OPERAND_RIC :
789      length = extract_normal (cd, ex_info, insn_value, 0, 16, 12, 4, 16, total_length, pc, & fields->f_Ric);
790      break;
791    case FR30_OPERAND_RJ :
792      length = extract_normal (cd, ex_info, insn_value, 0, 0, 8, 4, 16, total_length, pc, & fields->f_Rj);
793      break;
794    case FR30_OPERAND_RJC :
795      length = extract_normal (cd, ex_info, insn_value, 0, 16, 8, 4, 16, total_length, pc, & fields->f_Rjc);
796      break;
797    case FR30_OPERAND_RS1 :
798      length = extract_normal (cd, ex_info, insn_value, 0, 0, 8, 4, 16, total_length, pc, & fields->f_Rs1);
799      break;
800    case FR30_OPERAND_RS2 :
801      length = extract_normal (cd, ex_info, insn_value, 0, 0, 12, 4, 16, total_length, pc, & fields->f_Rs2);
802      break;
803    case FR30_OPERAND_CC :
804      length = extract_normal (cd, ex_info, insn_value, 0, 0, 4, 4, 16, total_length, pc, & fields->f_cc);
805      break;
806    case FR30_OPERAND_CCC :
807      length = extract_normal (cd, ex_info, insn_value, 0, 16, 0, 8, 16, total_length, pc, & fields->f_ccc);
808      break;
809    case FR30_OPERAND_DIR10 :
810      {
811        long value;
812        length = extract_normal (cd, ex_info, insn_value, 0, 0, 8, 8, 16, total_length, pc, & value);
813        value = ((value) << (2));
814        fields->f_dir10 = value;
815      }
816      break;
817    case FR30_OPERAND_DIR8 :
818      length = extract_normal (cd, ex_info, insn_value, 0, 0, 8, 8, 16, total_length, pc, & fields->f_dir8);
819      break;
820    case FR30_OPERAND_DIR9 :
821      {
822        long value;
823        length = extract_normal (cd, ex_info, insn_value, 0, 0, 8, 8, 16, total_length, pc, & value);
824        value = ((value) << (1));
825        fields->f_dir9 = value;
826      }
827      break;
828    case FR30_OPERAND_DISP10 :
829      {
830        long value;
831        length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_SIGNED), 0, 4, 8, 16, total_length, pc, & value);
832        value = ((value) << (2));
833        fields->f_disp10 = value;
834      }
835      break;
836    case FR30_OPERAND_DISP8 :
837      length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_SIGNED), 0, 4, 8, 16, total_length, pc, & fields->f_disp8);
838      break;
839    case FR30_OPERAND_DISP9 :
840      {
841        long value;
842        length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_SIGNED), 0, 4, 8, 16, total_length, pc, & value);
843        value = ((value) << (1));
844        fields->f_disp9 = value;
845      }
846      break;
847    case FR30_OPERAND_I20 :
848      {
849        length = extract_normal (cd, ex_info, insn_value, 0, 0, 8, 4, 16, total_length, pc, & fields->f_i20_4);
850        if (length <= 0) break;
851        length = extract_normal (cd, ex_info, insn_value, 0, 16, 0, 16, 16, total_length, pc, & fields->f_i20_16);
852        if (length <= 0) break;
853{
854  FLD (f_i20) = ((((FLD (f_i20_4)) << (16))) | (FLD (f_i20_16)));
855}
856      }
857      break;
858    case FR30_OPERAND_I32 :
859      length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_SIGN_OPT), 16, 0, 32, 32, total_length, pc, & fields->f_i32);
860      break;
861    case FR30_OPERAND_I8 :
862      length = extract_normal (cd, ex_info, insn_value, 0, 0, 4, 8, 16, total_length, pc, & fields->f_i8);
863      break;
864    case FR30_OPERAND_LABEL12 :
865      {
866        long value;
867        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);
868        value = ((((value) << (1))) + (((pc) + (2))));
869        fields->f_rel12 = value;
870      }
871      break;
872    case FR30_OPERAND_LABEL9 :
873      {
874        long value;
875        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);
876        value = ((((value) << (1))) + (((pc) + (2))));
877        fields->f_rel9 = value;
878      }
879      break;
880    case FR30_OPERAND_M4 :
881      {
882        long value;
883        length = extract_normal (cd, ex_info, insn_value, 0, 0, 8, 4, 16, total_length, pc, & value);
884        value = ((value) | (-16));
885        fields->f_m4 = value;
886      }
887      break;
888    case FR30_OPERAND_PS :
889      break;
890    case FR30_OPERAND_REGLIST_HI_LD :
891      length = extract_normal (cd, ex_info, insn_value, 0, 0, 8, 8, 16, total_length, pc, & fields->f_reglist_hi_ld);
892      break;
893    case FR30_OPERAND_REGLIST_HI_ST :
894      length = extract_normal (cd, ex_info, insn_value, 0, 0, 8, 8, 16, total_length, pc, & fields->f_reglist_hi_st);
895      break;
896    case FR30_OPERAND_REGLIST_LOW_LD :
897      length = extract_normal (cd, ex_info, insn_value, 0, 0, 8, 8, 16, total_length, pc, & fields->f_reglist_low_ld);
898      break;
899    case FR30_OPERAND_REGLIST_LOW_ST :
900      length = extract_normal (cd, ex_info, insn_value, 0, 0, 8, 8, 16, total_length, pc, & fields->f_reglist_low_st);
901      break;
902    case FR30_OPERAND_S10 :
903      {
904        long value;
905        length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_SIGNED), 0, 8, 8, 16, total_length, pc, & value);
906        value = ((value) << (2));
907        fields->f_s10 = value;
908      }
909      break;
910    case FR30_OPERAND_U10 :
911      {
912        long value;
913        length = extract_normal (cd, ex_info, insn_value, 0, 0, 8, 8, 16, total_length, pc, & value);
914        value = ((value) << (2));
915        fields->f_u10 = value;
916      }
917      break;
918    case FR30_OPERAND_U4 :
919      length = extract_normal (cd, ex_info, insn_value, 0, 0, 8, 4, 16, total_length, pc, & fields->f_u4);
920      break;
921    case FR30_OPERAND_U4C :
922      length = extract_normal (cd, ex_info, insn_value, 0, 0, 12, 4, 16, total_length, pc, & fields->f_u4c);
923      break;
924    case FR30_OPERAND_U8 :
925      length = extract_normal (cd, ex_info, insn_value, 0, 0, 8, 8, 16, total_length, pc, & fields->f_u8);
926      break;
927    case FR30_OPERAND_UDISP6 :
928      {
929        long value;
930        length = extract_normal (cd, ex_info, insn_value, 0, 0, 8, 4, 16, total_length, pc, & value);
931        value = ((value) << (2));
932        fields->f_udisp6 = value;
933      }
934      break;
935
936    default :
937      /* xgettext:c-format */
938      fprintf (stderr, _("Unrecognized field %d while decoding insn.\n"),
939	       opindex);
940      abort ();
941    }
942
943  return length;
944}
945
946cgen_insert_fn * const fr30_cgen_insert_handlers[] =
947{
948  insert_insn_normal,
949};
950
951cgen_extract_fn * const fr30_cgen_extract_handlers[] =
952{
953  extract_insn_normal,
954};
955
956int fr30_cgen_get_int_operand     (CGEN_CPU_DESC, int, const CGEN_FIELDS *);
957bfd_vma fr30_cgen_get_vma_operand (CGEN_CPU_DESC, int, const CGEN_FIELDS *);
958
959/* Getting values from cgen_fields is handled by a collection of functions.
960   They are distinguished by the type of the VALUE argument they return.
961   TODO: floating point, inlining support, remove cases where result type
962   not appropriate.  */
963
964int
965fr30_cgen_get_int_operand (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
966			     int opindex,
967			     const CGEN_FIELDS * fields)
968{
969  int value;
970
971  switch (opindex)
972    {
973    case FR30_OPERAND_CRI :
974      value = fields->f_CRi;
975      break;
976    case FR30_OPERAND_CRJ :
977      value = fields->f_CRj;
978      break;
979    case FR30_OPERAND_R13 :
980      value = 0;
981      break;
982    case FR30_OPERAND_R14 :
983      value = 0;
984      break;
985    case FR30_OPERAND_R15 :
986      value = 0;
987      break;
988    case FR30_OPERAND_RI :
989      value = fields->f_Ri;
990      break;
991    case FR30_OPERAND_RIC :
992      value = fields->f_Ric;
993      break;
994    case FR30_OPERAND_RJ :
995      value = fields->f_Rj;
996      break;
997    case FR30_OPERAND_RJC :
998      value = fields->f_Rjc;
999      break;
1000    case FR30_OPERAND_RS1 :
1001      value = fields->f_Rs1;
1002      break;
1003    case FR30_OPERAND_RS2 :
1004      value = fields->f_Rs2;
1005      break;
1006    case FR30_OPERAND_CC :
1007      value = fields->f_cc;
1008      break;
1009    case FR30_OPERAND_CCC :
1010      value = fields->f_ccc;
1011      break;
1012    case FR30_OPERAND_DIR10 :
1013      value = fields->f_dir10;
1014      break;
1015    case FR30_OPERAND_DIR8 :
1016      value = fields->f_dir8;
1017      break;
1018    case FR30_OPERAND_DIR9 :
1019      value = fields->f_dir9;
1020      break;
1021    case FR30_OPERAND_DISP10 :
1022      value = fields->f_disp10;
1023      break;
1024    case FR30_OPERAND_DISP8 :
1025      value = fields->f_disp8;
1026      break;
1027    case FR30_OPERAND_DISP9 :
1028      value = fields->f_disp9;
1029      break;
1030    case FR30_OPERAND_I20 :
1031      value = fields->f_i20;
1032      break;
1033    case FR30_OPERAND_I32 :
1034      value = fields->f_i32;
1035      break;
1036    case FR30_OPERAND_I8 :
1037      value = fields->f_i8;
1038      break;
1039    case FR30_OPERAND_LABEL12 :
1040      value = fields->f_rel12;
1041      break;
1042    case FR30_OPERAND_LABEL9 :
1043      value = fields->f_rel9;
1044      break;
1045    case FR30_OPERAND_M4 :
1046      value = fields->f_m4;
1047      break;
1048    case FR30_OPERAND_PS :
1049      value = 0;
1050      break;
1051    case FR30_OPERAND_REGLIST_HI_LD :
1052      value = fields->f_reglist_hi_ld;
1053      break;
1054    case FR30_OPERAND_REGLIST_HI_ST :
1055      value = fields->f_reglist_hi_st;
1056      break;
1057    case FR30_OPERAND_REGLIST_LOW_LD :
1058      value = fields->f_reglist_low_ld;
1059      break;
1060    case FR30_OPERAND_REGLIST_LOW_ST :
1061      value = fields->f_reglist_low_st;
1062      break;
1063    case FR30_OPERAND_S10 :
1064      value = fields->f_s10;
1065      break;
1066    case FR30_OPERAND_U10 :
1067      value = fields->f_u10;
1068      break;
1069    case FR30_OPERAND_U4 :
1070      value = fields->f_u4;
1071      break;
1072    case FR30_OPERAND_U4C :
1073      value = fields->f_u4c;
1074      break;
1075    case FR30_OPERAND_U8 :
1076      value = fields->f_u8;
1077      break;
1078    case FR30_OPERAND_UDISP6 :
1079      value = fields->f_udisp6;
1080      break;
1081
1082    default :
1083      /* xgettext:c-format */
1084      fprintf (stderr, _("Unrecognized field %d while getting int operand.\n"),
1085		       opindex);
1086      abort ();
1087  }
1088
1089  return value;
1090}
1091
1092bfd_vma
1093fr30_cgen_get_vma_operand (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
1094			     int opindex,
1095			     const CGEN_FIELDS * fields)
1096{
1097  bfd_vma value;
1098
1099  switch (opindex)
1100    {
1101    case FR30_OPERAND_CRI :
1102      value = fields->f_CRi;
1103      break;
1104    case FR30_OPERAND_CRJ :
1105      value = fields->f_CRj;
1106      break;
1107    case FR30_OPERAND_R13 :
1108      value = 0;
1109      break;
1110    case FR30_OPERAND_R14 :
1111      value = 0;
1112      break;
1113    case FR30_OPERAND_R15 :
1114      value = 0;
1115      break;
1116    case FR30_OPERAND_RI :
1117      value = fields->f_Ri;
1118      break;
1119    case FR30_OPERAND_RIC :
1120      value = fields->f_Ric;
1121      break;
1122    case FR30_OPERAND_RJ :
1123      value = fields->f_Rj;
1124      break;
1125    case FR30_OPERAND_RJC :
1126      value = fields->f_Rjc;
1127      break;
1128    case FR30_OPERAND_RS1 :
1129      value = fields->f_Rs1;
1130      break;
1131    case FR30_OPERAND_RS2 :
1132      value = fields->f_Rs2;
1133      break;
1134    case FR30_OPERAND_CC :
1135      value = fields->f_cc;
1136      break;
1137    case FR30_OPERAND_CCC :
1138      value = fields->f_ccc;
1139      break;
1140    case FR30_OPERAND_DIR10 :
1141      value = fields->f_dir10;
1142      break;
1143    case FR30_OPERAND_DIR8 :
1144      value = fields->f_dir8;
1145      break;
1146    case FR30_OPERAND_DIR9 :
1147      value = fields->f_dir9;
1148      break;
1149    case FR30_OPERAND_DISP10 :
1150      value = fields->f_disp10;
1151      break;
1152    case FR30_OPERAND_DISP8 :
1153      value = fields->f_disp8;
1154      break;
1155    case FR30_OPERAND_DISP9 :
1156      value = fields->f_disp9;
1157      break;
1158    case FR30_OPERAND_I20 :
1159      value = fields->f_i20;
1160      break;
1161    case FR30_OPERAND_I32 :
1162      value = fields->f_i32;
1163      break;
1164    case FR30_OPERAND_I8 :
1165      value = fields->f_i8;
1166      break;
1167    case FR30_OPERAND_LABEL12 :
1168      value = fields->f_rel12;
1169      break;
1170    case FR30_OPERAND_LABEL9 :
1171      value = fields->f_rel9;
1172      break;
1173    case FR30_OPERAND_M4 :
1174      value = fields->f_m4;
1175      break;
1176    case FR30_OPERAND_PS :
1177      value = 0;
1178      break;
1179    case FR30_OPERAND_REGLIST_HI_LD :
1180      value = fields->f_reglist_hi_ld;
1181      break;
1182    case FR30_OPERAND_REGLIST_HI_ST :
1183      value = fields->f_reglist_hi_st;
1184      break;
1185    case FR30_OPERAND_REGLIST_LOW_LD :
1186      value = fields->f_reglist_low_ld;
1187      break;
1188    case FR30_OPERAND_REGLIST_LOW_ST :
1189      value = fields->f_reglist_low_st;
1190      break;
1191    case FR30_OPERAND_S10 :
1192      value = fields->f_s10;
1193      break;
1194    case FR30_OPERAND_U10 :
1195      value = fields->f_u10;
1196      break;
1197    case FR30_OPERAND_U4 :
1198      value = fields->f_u4;
1199      break;
1200    case FR30_OPERAND_U4C :
1201      value = fields->f_u4c;
1202      break;
1203    case FR30_OPERAND_U8 :
1204      value = fields->f_u8;
1205      break;
1206    case FR30_OPERAND_UDISP6 :
1207      value = fields->f_udisp6;
1208      break;
1209
1210    default :
1211      /* xgettext:c-format */
1212      fprintf (stderr, _("Unrecognized field %d while getting vma operand.\n"),
1213		       opindex);
1214      abort ();
1215  }
1216
1217  return value;
1218}
1219
1220void fr30_cgen_set_int_operand  (CGEN_CPU_DESC, int, CGEN_FIELDS *, int);
1221void fr30_cgen_set_vma_operand  (CGEN_CPU_DESC, int, CGEN_FIELDS *, bfd_vma);
1222
1223/* Stuffing values in cgen_fields is handled by a collection of functions.
1224   They are distinguished by the type of the VALUE argument they accept.
1225   TODO: floating point, inlining support, remove cases where argument type
1226   not appropriate.  */
1227
1228void
1229fr30_cgen_set_int_operand (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
1230			     int opindex,
1231			     CGEN_FIELDS * fields,
1232			     int value)
1233{
1234  switch (opindex)
1235    {
1236    case FR30_OPERAND_CRI :
1237      fields->f_CRi = value;
1238      break;
1239    case FR30_OPERAND_CRJ :
1240      fields->f_CRj = value;
1241      break;
1242    case FR30_OPERAND_R13 :
1243      break;
1244    case FR30_OPERAND_R14 :
1245      break;
1246    case FR30_OPERAND_R15 :
1247      break;
1248    case FR30_OPERAND_RI :
1249      fields->f_Ri = value;
1250      break;
1251    case FR30_OPERAND_RIC :
1252      fields->f_Ric = value;
1253      break;
1254    case FR30_OPERAND_RJ :
1255      fields->f_Rj = value;
1256      break;
1257    case FR30_OPERAND_RJC :
1258      fields->f_Rjc = value;
1259      break;
1260    case FR30_OPERAND_RS1 :
1261      fields->f_Rs1 = value;
1262      break;
1263    case FR30_OPERAND_RS2 :
1264      fields->f_Rs2 = value;
1265      break;
1266    case FR30_OPERAND_CC :
1267      fields->f_cc = value;
1268      break;
1269    case FR30_OPERAND_CCC :
1270      fields->f_ccc = value;
1271      break;
1272    case FR30_OPERAND_DIR10 :
1273      fields->f_dir10 = value;
1274      break;
1275    case FR30_OPERAND_DIR8 :
1276      fields->f_dir8 = value;
1277      break;
1278    case FR30_OPERAND_DIR9 :
1279      fields->f_dir9 = value;
1280      break;
1281    case FR30_OPERAND_DISP10 :
1282      fields->f_disp10 = value;
1283      break;
1284    case FR30_OPERAND_DISP8 :
1285      fields->f_disp8 = value;
1286      break;
1287    case FR30_OPERAND_DISP9 :
1288      fields->f_disp9 = value;
1289      break;
1290    case FR30_OPERAND_I20 :
1291      fields->f_i20 = value;
1292      break;
1293    case FR30_OPERAND_I32 :
1294      fields->f_i32 = value;
1295      break;
1296    case FR30_OPERAND_I8 :
1297      fields->f_i8 = value;
1298      break;
1299    case FR30_OPERAND_LABEL12 :
1300      fields->f_rel12 = value;
1301      break;
1302    case FR30_OPERAND_LABEL9 :
1303      fields->f_rel9 = value;
1304      break;
1305    case FR30_OPERAND_M4 :
1306      fields->f_m4 = value;
1307      break;
1308    case FR30_OPERAND_PS :
1309      break;
1310    case FR30_OPERAND_REGLIST_HI_LD :
1311      fields->f_reglist_hi_ld = value;
1312      break;
1313    case FR30_OPERAND_REGLIST_HI_ST :
1314      fields->f_reglist_hi_st = value;
1315      break;
1316    case FR30_OPERAND_REGLIST_LOW_LD :
1317      fields->f_reglist_low_ld = value;
1318      break;
1319    case FR30_OPERAND_REGLIST_LOW_ST :
1320      fields->f_reglist_low_st = value;
1321      break;
1322    case FR30_OPERAND_S10 :
1323      fields->f_s10 = value;
1324      break;
1325    case FR30_OPERAND_U10 :
1326      fields->f_u10 = value;
1327      break;
1328    case FR30_OPERAND_U4 :
1329      fields->f_u4 = value;
1330      break;
1331    case FR30_OPERAND_U4C :
1332      fields->f_u4c = value;
1333      break;
1334    case FR30_OPERAND_U8 :
1335      fields->f_u8 = value;
1336      break;
1337    case FR30_OPERAND_UDISP6 :
1338      fields->f_udisp6 = value;
1339      break;
1340
1341    default :
1342      /* xgettext:c-format */
1343      fprintf (stderr, _("Unrecognized field %d while setting int operand.\n"),
1344		       opindex);
1345      abort ();
1346  }
1347}
1348
1349void
1350fr30_cgen_set_vma_operand (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
1351			     int opindex,
1352			     CGEN_FIELDS * fields,
1353			     bfd_vma value)
1354{
1355  switch (opindex)
1356    {
1357    case FR30_OPERAND_CRI :
1358      fields->f_CRi = value;
1359      break;
1360    case FR30_OPERAND_CRJ :
1361      fields->f_CRj = value;
1362      break;
1363    case FR30_OPERAND_R13 :
1364      break;
1365    case FR30_OPERAND_R14 :
1366      break;
1367    case FR30_OPERAND_R15 :
1368      break;
1369    case FR30_OPERAND_RI :
1370      fields->f_Ri = value;
1371      break;
1372    case FR30_OPERAND_RIC :
1373      fields->f_Ric = value;
1374      break;
1375    case FR30_OPERAND_RJ :
1376      fields->f_Rj = value;
1377      break;
1378    case FR30_OPERAND_RJC :
1379      fields->f_Rjc = value;
1380      break;
1381    case FR30_OPERAND_RS1 :
1382      fields->f_Rs1 = value;
1383      break;
1384    case FR30_OPERAND_RS2 :
1385      fields->f_Rs2 = value;
1386      break;
1387    case FR30_OPERAND_CC :
1388      fields->f_cc = value;
1389      break;
1390    case FR30_OPERAND_CCC :
1391      fields->f_ccc = value;
1392      break;
1393    case FR30_OPERAND_DIR10 :
1394      fields->f_dir10 = value;
1395      break;
1396    case FR30_OPERAND_DIR8 :
1397      fields->f_dir8 = value;
1398      break;
1399    case FR30_OPERAND_DIR9 :
1400      fields->f_dir9 = value;
1401      break;
1402    case FR30_OPERAND_DISP10 :
1403      fields->f_disp10 = value;
1404      break;
1405    case FR30_OPERAND_DISP8 :
1406      fields->f_disp8 = value;
1407      break;
1408    case FR30_OPERAND_DISP9 :
1409      fields->f_disp9 = value;
1410      break;
1411    case FR30_OPERAND_I20 :
1412      fields->f_i20 = value;
1413      break;
1414    case FR30_OPERAND_I32 :
1415      fields->f_i32 = value;
1416      break;
1417    case FR30_OPERAND_I8 :
1418      fields->f_i8 = value;
1419      break;
1420    case FR30_OPERAND_LABEL12 :
1421      fields->f_rel12 = value;
1422      break;
1423    case FR30_OPERAND_LABEL9 :
1424      fields->f_rel9 = value;
1425      break;
1426    case FR30_OPERAND_M4 :
1427      fields->f_m4 = value;
1428      break;
1429    case FR30_OPERAND_PS :
1430      break;
1431    case FR30_OPERAND_REGLIST_HI_LD :
1432      fields->f_reglist_hi_ld = value;
1433      break;
1434    case FR30_OPERAND_REGLIST_HI_ST :
1435      fields->f_reglist_hi_st = value;
1436      break;
1437    case FR30_OPERAND_REGLIST_LOW_LD :
1438      fields->f_reglist_low_ld = value;
1439      break;
1440    case FR30_OPERAND_REGLIST_LOW_ST :
1441      fields->f_reglist_low_st = value;
1442      break;
1443    case FR30_OPERAND_S10 :
1444      fields->f_s10 = value;
1445      break;
1446    case FR30_OPERAND_U10 :
1447      fields->f_u10 = value;
1448      break;
1449    case FR30_OPERAND_U4 :
1450      fields->f_u4 = value;
1451      break;
1452    case FR30_OPERAND_U4C :
1453      fields->f_u4c = value;
1454      break;
1455    case FR30_OPERAND_U8 :
1456      fields->f_u8 = value;
1457      break;
1458    case FR30_OPERAND_UDISP6 :
1459      fields->f_udisp6 = value;
1460      break;
1461
1462    default :
1463      /* xgettext:c-format */
1464      fprintf (stderr, _("Unrecognized field %d while setting vma operand.\n"),
1465		       opindex);
1466      abort ();
1467  }
1468}
1469
1470/* Function to call before using the instruction builder tables.  */
1471
1472void
1473fr30_cgen_init_ibld_table (CGEN_CPU_DESC cd)
1474{
1475  cd->insert_handlers = & fr30_cgen_insert_handlers[0];
1476  cd->extract_handlers = & fr30_cgen_extract_handlers[0];
1477
1478  cd->insert_operand = fr30_cgen_insert_operand;
1479  cd->extract_operand = fr30_cgen_extract_operand;
1480
1481  cd->get_int_operand = fr30_cgen_get_int_operand;
1482  cd->set_int_operand = fr30_cgen_set_int_operand;
1483  cd->get_vma_operand = fr30_cgen_get_vma_operand;
1484  cd->set_vma_operand = fr30_cgen_set_vma_operand;
1485}
1486