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