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