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