1 /* Instruction building/extraction support for iq2000. -*- 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 "iq2000-desc.h"
35 #include "iq2000-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 * iq2000_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 *
iq2000_cgen_insert_operand(CGEN_CPU_DESC cd,int opindex,CGEN_FIELDS * fields,CGEN_INSN_BYTES_PTR buffer,bfd_vma pc ATTRIBUTE_UNUSED)550 iq2000_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 IQ2000_OPERAND__INDEX :
562       errmsg = insert_normal (cd, fields->f_index, 0, 0, 8, 9, 32, total_length, buffer);
563       break;
564     case IQ2000_OPERAND_BASE :
565       errmsg = insert_normal (cd, fields->f_rs, 0, 0, 25, 5, 32, total_length, buffer);
566       break;
567     case IQ2000_OPERAND_BASEOFF :
568       errmsg = insert_normal (cd, fields->f_imm, 0, 0, 15, 16, 32, total_length, buffer);
569       break;
570     case IQ2000_OPERAND_BITNUM :
571       errmsg = insert_normal (cd, fields->f_rt, 0, 0, 20, 5, 32, total_length, buffer);
572       break;
573     case IQ2000_OPERAND_BYTECOUNT :
574       errmsg = insert_normal (cd, fields->f_bytecount, 0, 0, 7, 8, 32, total_length, buffer);
575       break;
576     case IQ2000_OPERAND_CAM_Y :
577       errmsg = insert_normal (cd, fields->f_cam_y, 0, 0, 2, 3, 32, total_length, buffer);
578       break;
579     case IQ2000_OPERAND_CAM_Z :
580       errmsg = insert_normal (cd, fields->f_cam_z, 0, 0, 5, 3, 32, total_length, buffer);
581       break;
582     case IQ2000_OPERAND_CM_3FUNC :
583       errmsg = insert_normal (cd, fields->f_cm_3func, 0, 0, 5, 3, 32, total_length, buffer);
584       break;
585     case IQ2000_OPERAND_CM_3Z :
586       errmsg = insert_normal (cd, fields->f_cm_3z, 0, 0, 1, 2, 32, total_length, buffer);
587       break;
588     case IQ2000_OPERAND_CM_4FUNC :
589       errmsg = insert_normal (cd, fields->f_cm_4func, 0, 0, 5, 4, 32, total_length, buffer);
590       break;
591     case IQ2000_OPERAND_CM_4Z :
592       errmsg = insert_normal (cd, fields->f_cm_4z, 0, 0, 2, 3, 32, total_length, buffer);
593       break;
594     case IQ2000_OPERAND_COUNT :
595       errmsg = insert_normal (cd, fields->f_count, 0, 0, 15, 7, 32, total_length, buffer);
596       break;
597     case IQ2000_OPERAND_EXECODE :
598       errmsg = insert_normal (cd, fields->f_excode, 0, 0, 25, 20, 32, total_length, buffer);
599       break;
600     case IQ2000_OPERAND_HI16 :
601       errmsg = insert_normal (cd, fields->f_imm, 0, 0, 15, 16, 32, total_length, buffer);
602       break;
603     case IQ2000_OPERAND_IMM :
604       errmsg = insert_normal (cd, fields->f_imm, 0, 0, 15, 16, 32, total_length, buffer);
605       break;
606     case IQ2000_OPERAND_JMPTARG :
607       {
608         long value = fields->f_jtarg;
609         value = ((unsigned int) (((value) & (262143))) >> (2));
610         errmsg = insert_normal (cd, value, 0|(1<<CGEN_IFLD_ABS_ADDR), 0, 15, 16, 32, total_length, buffer);
611       }
612       break;
613     case IQ2000_OPERAND_JMPTARGQ10 :
614       {
615         long value = fields->f_jtargq10;
616         value = ((unsigned int) (((value) & (8388607))) >> (2));
617         errmsg = insert_normal (cd, value, 0|(1<<CGEN_IFLD_ABS_ADDR), 0, 20, 21, 32, total_length, buffer);
618       }
619       break;
620     case IQ2000_OPERAND_LO16 :
621       errmsg = insert_normal (cd, fields->f_imm, 0, 0, 15, 16, 32, total_length, buffer);
622       break;
623     case IQ2000_OPERAND_MASK :
624       errmsg = insert_normal (cd, fields->f_mask, 0, 0, 9, 4, 32, total_length, buffer);
625       break;
626     case IQ2000_OPERAND_MASKL :
627       errmsg = insert_normal (cd, fields->f_maskl, 0, 0, 4, 5, 32, total_length, buffer);
628       break;
629     case IQ2000_OPERAND_MASKQ10 :
630       errmsg = insert_normal (cd, fields->f_maskq10, 0, 0, 10, 5, 32, total_length, buffer);
631       break;
632     case IQ2000_OPERAND_MASKR :
633       errmsg = insert_normal (cd, fields->f_rs, 0, 0, 25, 5, 32, total_length, buffer);
634       break;
635     case IQ2000_OPERAND_MLO16 :
636       errmsg = insert_normal (cd, fields->f_imm, 0, 0, 15, 16, 32, total_length, buffer);
637       break;
638     case IQ2000_OPERAND_OFFSET :
639       {
640         long value = fields->f_offset;
641         value = ((int) (((value) - (pc))) >> (2));
642         errmsg = insert_normal (cd, value, 0|(1<<CGEN_IFLD_SIGNED)|(1<<CGEN_IFLD_PCREL_ADDR), 0, 15, 16, 32, total_length, buffer);
643       }
644       break;
645     case IQ2000_OPERAND_RD :
646       errmsg = insert_normal (cd, fields->f_rd, 0, 0, 15, 5, 32, total_length, buffer);
647       break;
648     case IQ2000_OPERAND_RD_RS :
649       {
650 {
651   FLD (f_rd) = FLD (f_rd_rs);
652   FLD (f_rs) = FLD (f_rd_rs);
653 }
654         errmsg = insert_normal (cd, fields->f_rd, 0, 0, 15, 5, 32, total_length, buffer);
655         if (errmsg)
656           break;
657         errmsg = insert_normal (cd, fields->f_rs, 0, 0, 25, 5, 32, total_length, buffer);
658         if (errmsg)
659           break;
660       }
661       break;
662     case IQ2000_OPERAND_RD_RT :
663       {
664 {
665   FLD (f_rd) = FLD (f_rd_rt);
666   FLD (f_rt) = FLD (f_rd_rt);
667 }
668         errmsg = insert_normal (cd, fields->f_rd, 0, 0, 15, 5, 32, total_length, buffer);
669         if (errmsg)
670           break;
671         errmsg = insert_normal (cd, fields->f_rt, 0, 0, 20, 5, 32, total_length, buffer);
672         if (errmsg)
673           break;
674       }
675       break;
676     case IQ2000_OPERAND_RS :
677       errmsg = insert_normal (cd, fields->f_rs, 0, 0, 25, 5, 32, total_length, buffer);
678       break;
679     case IQ2000_OPERAND_RT :
680       errmsg = insert_normal (cd, fields->f_rt, 0, 0, 20, 5, 32, total_length, buffer);
681       break;
682     case IQ2000_OPERAND_RT_RS :
683       {
684 {
685   FLD (f_rt) = FLD (f_rt_rs);
686   FLD (f_rs) = FLD (f_rt_rs);
687 }
688         errmsg = insert_normal (cd, fields->f_rt, 0, 0, 20, 5, 32, total_length, buffer);
689         if (errmsg)
690           break;
691         errmsg = insert_normal (cd, fields->f_rs, 0, 0, 25, 5, 32, total_length, buffer);
692         if (errmsg)
693           break;
694       }
695       break;
696     case IQ2000_OPERAND_SHAMT :
697       errmsg = insert_normal (cd, fields->f_shamt, 0, 0, 10, 5, 32, total_length, buffer);
698       break;
699 
700     default :
701       /* xgettext:c-format */
702       fprintf (stderr, _("Unrecognized field %d while building insn.\n"),
703 	       opindex);
704       abort ();
705   }
706 
707   return errmsg;
708 }
709 
710 int iq2000_cgen_extract_operand
711   (CGEN_CPU_DESC, int, CGEN_EXTRACT_INFO *, CGEN_INSN_INT, CGEN_FIELDS *, bfd_vma);
712 
713 /* Main entry point for operand extraction.
714    The result is <= 0 for error, >0 for success.
715    ??? Actual values aren't well defined right now.
716 
717    This function is basically just a big switch statement.  Earlier versions
718    used tables to look up the function to use, but
719    - if the table contains both assembler and disassembler functions then
720      the disassembler contains much of the assembler and vice-versa,
721    - there's a lot of inlining possibilities as things grow,
722    - using a switch statement avoids the function call overhead.
723 
724    This function could be moved into `print_insn_normal', but keeping it
725    separate makes clear the interface between `print_insn_normal' and each of
726    the handlers.  */
727 
728 int
iq2000_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)729 iq2000_cgen_extract_operand (CGEN_CPU_DESC cd,
730 			     int opindex,
731 			     CGEN_EXTRACT_INFO *ex_info,
732 			     CGEN_INSN_INT insn_value,
733 			     CGEN_FIELDS * fields,
734 			     bfd_vma pc)
735 {
736   /* Assume success (for those operands that are nops).  */
737   int length = 1;
738   unsigned int total_length = CGEN_FIELDS_BITSIZE (fields);
739 
740   switch (opindex)
741     {
742     case IQ2000_OPERAND__INDEX :
743       length = extract_normal (cd, ex_info, insn_value, 0, 0, 8, 9, 32, total_length, pc, & fields->f_index);
744       break;
745     case IQ2000_OPERAND_BASE :
746       length = extract_normal (cd, ex_info, insn_value, 0, 0, 25, 5, 32, total_length, pc, & fields->f_rs);
747       break;
748     case IQ2000_OPERAND_BASEOFF :
749       length = extract_normal (cd, ex_info, insn_value, 0, 0, 15, 16, 32, total_length, pc, & fields->f_imm);
750       break;
751     case IQ2000_OPERAND_BITNUM :
752       length = extract_normal (cd, ex_info, insn_value, 0, 0, 20, 5, 32, total_length, pc, & fields->f_rt);
753       break;
754     case IQ2000_OPERAND_BYTECOUNT :
755       length = extract_normal (cd, ex_info, insn_value, 0, 0, 7, 8, 32, total_length, pc, & fields->f_bytecount);
756       break;
757     case IQ2000_OPERAND_CAM_Y :
758       length = extract_normal (cd, ex_info, insn_value, 0, 0, 2, 3, 32, total_length, pc, & fields->f_cam_y);
759       break;
760     case IQ2000_OPERAND_CAM_Z :
761       length = extract_normal (cd, ex_info, insn_value, 0, 0, 5, 3, 32, total_length, pc, & fields->f_cam_z);
762       break;
763     case IQ2000_OPERAND_CM_3FUNC :
764       length = extract_normal (cd, ex_info, insn_value, 0, 0, 5, 3, 32, total_length, pc, & fields->f_cm_3func);
765       break;
766     case IQ2000_OPERAND_CM_3Z :
767       length = extract_normal (cd, ex_info, insn_value, 0, 0, 1, 2, 32, total_length, pc, & fields->f_cm_3z);
768       break;
769     case IQ2000_OPERAND_CM_4FUNC :
770       length = extract_normal (cd, ex_info, insn_value, 0, 0, 5, 4, 32, total_length, pc, & fields->f_cm_4func);
771       break;
772     case IQ2000_OPERAND_CM_4Z :
773       length = extract_normal (cd, ex_info, insn_value, 0, 0, 2, 3, 32, total_length, pc, & fields->f_cm_4z);
774       break;
775     case IQ2000_OPERAND_COUNT :
776       length = extract_normal (cd, ex_info, insn_value, 0, 0, 15, 7, 32, total_length, pc, & fields->f_count);
777       break;
778     case IQ2000_OPERAND_EXECODE :
779       length = extract_normal (cd, ex_info, insn_value, 0, 0, 25, 20, 32, total_length, pc, & fields->f_excode);
780       break;
781     case IQ2000_OPERAND_HI16 :
782       length = extract_normal (cd, ex_info, insn_value, 0, 0, 15, 16, 32, total_length, pc, & fields->f_imm);
783       break;
784     case IQ2000_OPERAND_IMM :
785       length = extract_normal (cd, ex_info, insn_value, 0, 0, 15, 16, 32, total_length, pc, & fields->f_imm);
786       break;
787     case IQ2000_OPERAND_JMPTARG :
788       {
789         long value;
790         length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_ABS_ADDR), 0, 15, 16, 32, total_length, pc, & value);
791         value = ((((pc) & (0xf0000000))) | (((value) << (2))));
792         fields->f_jtarg = value;
793       }
794       break;
795     case IQ2000_OPERAND_JMPTARGQ10 :
796       {
797         long value;
798         length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_ABS_ADDR), 0, 20, 21, 32, total_length, pc, & value);
799         value = ((((pc) & (0xf0000000))) | (((value) << (2))));
800         fields->f_jtargq10 = value;
801       }
802       break;
803     case IQ2000_OPERAND_LO16 :
804       length = extract_normal (cd, ex_info, insn_value, 0, 0, 15, 16, 32, total_length, pc, & fields->f_imm);
805       break;
806     case IQ2000_OPERAND_MASK :
807       length = extract_normal (cd, ex_info, insn_value, 0, 0, 9, 4, 32, total_length, pc, & fields->f_mask);
808       break;
809     case IQ2000_OPERAND_MASKL :
810       length = extract_normal (cd, ex_info, insn_value, 0, 0, 4, 5, 32, total_length, pc, & fields->f_maskl);
811       break;
812     case IQ2000_OPERAND_MASKQ10 :
813       length = extract_normal (cd, ex_info, insn_value, 0, 0, 10, 5, 32, total_length, pc, & fields->f_maskq10);
814       break;
815     case IQ2000_OPERAND_MASKR :
816       length = extract_normal (cd, ex_info, insn_value, 0, 0, 25, 5, 32, total_length, pc, & fields->f_rs);
817       break;
818     case IQ2000_OPERAND_MLO16 :
819       length = extract_normal (cd, ex_info, insn_value, 0, 0, 15, 16, 32, total_length, pc, & fields->f_imm);
820       break;
821     case IQ2000_OPERAND_OFFSET :
822       {
823         long value;
824         length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_SIGNED)|(1<<CGEN_IFLD_PCREL_ADDR), 0, 15, 16, 32, total_length, pc, & value);
825         value = ((((value) << (2))) + (((pc) + (4))));
826         fields->f_offset = value;
827       }
828       break;
829     case IQ2000_OPERAND_RD :
830       length = extract_normal (cd, ex_info, insn_value, 0, 0, 15, 5, 32, total_length, pc, & fields->f_rd);
831       break;
832     case IQ2000_OPERAND_RD_RS :
833       {
834         length = extract_normal (cd, ex_info, insn_value, 0, 0, 15, 5, 32, total_length, pc, & fields->f_rd);
835         if (length <= 0) break;
836         length = extract_normal (cd, ex_info, insn_value, 0, 0, 25, 5, 32, total_length, pc, & fields->f_rs);
837         if (length <= 0) break;
838 {
839   FLD (f_rd_rs) = FLD (f_rs);
840 }
841       }
842       break;
843     case IQ2000_OPERAND_RD_RT :
844       {
845         length = extract_normal (cd, ex_info, insn_value, 0, 0, 15, 5, 32, total_length, pc, & fields->f_rd);
846         if (length <= 0) break;
847         length = extract_normal (cd, ex_info, insn_value, 0, 0, 20, 5, 32, total_length, pc, & fields->f_rt);
848         if (length <= 0) break;
849 {
850   FLD (f_rd_rt) = FLD (f_rt);
851 }
852       }
853       break;
854     case IQ2000_OPERAND_RS :
855       length = extract_normal (cd, ex_info, insn_value, 0, 0, 25, 5, 32, total_length, pc, & fields->f_rs);
856       break;
857     case IQ2000_OPERAND_RT :
858       length = extract_normal (cd, ex_info, insn_value, 0, 0, 20, 5, 32, total_length, pc, & fields->f_rt);
859       break;
860     case IQ2000_OPERAND_RT_RS :
861       {
862         length = extract_normal (cd, ex_info, insn_value, 0, 0, 20, 5, 32, total_length, pc, & fields->f_rt);
863         if (length <= 0) break;
864         length = extract_normal (cd, ex_info, insn_value, 0, 0, 25, 5, 32, total_length, pc, & fields->f_rs);
865         if (length <= 0) break;
866 {
867   FLD (f_rd_rs) = FLD (f_rs);
868 }
869       }
870       break;
871     case IQ2000_OPERAND_SHAMT :
872       length = extract_normal (cd, ex_info, insn_value, 0, 0, 10, 5, 32, total_length, pc, & fields->f_shamt);
873       break;
874 
875     default :
876       /* xgettext:c-format */
877       fprintf (stderr, _("Unrecognized field %d while decoding insn.\n"),
878 	       opindex);
879       abort ();
880     }
881 
882   return length;
883 }
884 
885 cgen_insert_fn * const iq2000_cgen_insert_handlers[] =
886 {
887   insert_insn_normal,
888 };
889 
890 cgen_extract_fn * const iq2000_cgen_extract_handlers[] =
891 {
892   extract_insn_normal,
893 };
894 
895 int iq2000_cgen_get_int_operand     (CGEN_CPU_DESC, int, const CGEN_FIELDS *);
896 bfd_vma iq2000_cgen_get_vma_operand (CGEN_CPU_DESC, int, const CGEN_FIELDS *);
897 
898 /* Getting values from cgen_fields is handled by a collection of functions.
899    They are distinguished by the type of the VALUE argument they return.
900    TODO: floating point, inlining support, remove cases where result type
901    not appropriate.  */
902 
903 int
iq2000_cgen_get_int_operand(CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,int opindex,const CGEN_FIELDS * fields)904 iq2000_cgen_get_int_operand (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
905 			     int opindex,
906 			     const CGEN_FIELDS * fields)
907 {
908   int value;
909 
910   switch (opindex)
911     {
912     case IQ2000_OPERAND__INDEX :
913       value = fields->f_index;
914       break;
915     case IQ2000_OPERAND_BASE :
916       value = fields->f_rs;
917       break;
918     case IQ2000_OPERAND_BASEOFF :
919       value = fields->f_imm;
920       break;
921     case IQ2000_OPERAND_BITNUM :
922       value = fields->f_rt;
923       break;
924     case IQ2000_OPERAND_BYTECOUNT :
925       value = fields->f_bytecount;
926       break;
927     case IQ2000_OPERAND_CAM_Y :
928       value = fields->f_cam_y;
929       break;
930     case IQ2000_OPERAND_CAM_Z :
931       value = fields->f_cam_z;
932       break;
933     case IQ2000_OPERAND_CM_3FUNC :
934       value = fields->f_cm_3func;
935       break;
936     case IQ2000_OPERAND_CM_3Z :
937       value = fields->f_cm_3z;
938       break;
939     case IQ2000_OPERAND_CM_4FUNC :
940       value = fields->f_cm_4func;
941       break;
942     case IQ2000_OPERAND_CM_4Z :
943       value = fields->f_cm_4z;
944       break;
945     case IQ2000_OPERAND_COUNT :
946       value = fields->f_count;
947       break;
948     case IQ2000_OPERAND_EXECODE :
949       value = fields->f_excode;
950       break;
951     case IQ2000_OPERAND_HI16 :
952       value = fields->f_imm;
953       break;
954     case IQ2000_OPERAND_IMM :
955       value = fields->f_imm;
956       break;
957     case IQ2000_OPERAND_JMPTARG :
958       value = fields->f_jtarg;
959       break;
960     case IQ2000_OPERAND_JMPTARGQ10 :
961       value = fields->f_jtargq10;
962       break;
963     case IQ2000_OPERAND_LO16 :
964       value = fields->f_imm;
965       break;
966     case IQ2000_OPERAND_MASK :
967       value = fields->f_mask;
968       break;
969     case IQ2000_OPERAND_MASKL :
970       value = fields->f_maskl;
971       break;
972     case IQ2000_OPERAND_MASKQ10 :
973       value = fields->f_maskq10;
974       break;
975     case IQ2000_OPERAND_MASKR :
976       value = fields->f_rs;
977       break;
978     case IQ2000_OPERAND_MLO16 :
979       value = fields->f_imm;
980       break;
981     case IQ2000_OPERAND_OFFSET :
982       value = fields->f_offset;
983       break;
984     case IQ2000_OPERAND_RD :
985       value = fields->f_rd;
986       break;
987     case IQ2000_OPERAND_RD_RS :
988       value = fields->f_rd_rs;
989       break;
990     case IQ2000_OPERAND_RD_RT :
991       value = fields->f_rd_rt;
992       break;
993     case IQ2000_OPERAND_RS :
994       value = fields->f_rs;
995       break;
996     case IQ2000_OPERAND_RT :
997       value = fields->f_rt;
998       break;
999     case IQ2000_OPERAND_RT_RS :
1000       value = fields->f_rt_rs;
1001       break;
1002     case IQ2000_OPERAND_SHAMT :
1003       value = fields->f_shamt;
1004       break;
1005 
1006     default :
1007       /* xgettext:c-format */
1008       fprintf (stderr, _("Unrecognized field %d while getting int operand.\n"),
1009 		       opindex);
1010       abort ();
1011   }
1012 
1013   return value;
1014 }
1015 
1016 bfd_vma
iq2000_cgen_get_vma_operand(CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,int opindex,const CGEN_FIELDS * fields)1017 iq2000_cgen_get_vma_operand (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
1018 			     int opindex,
1019 			     const CGEN_FIELDS * fields)
1020 {
1021   bfd_vma value;
1022 
1023   switch (opindex)
1024     {
1025     case IQ2000_OPERAND__INDEX :
1026       value = fields->f_index;
1027       break;
1028     case IQ2000_OPERAND_BASE :
1029       value = fields->f_rs;
1030       break;
1031     case IQ2000_OPERAND_BASEOFF :
1032       value = fields->f_imm;
1033       break;
1034     case IQ2000_OPERAND_BITNUM :
1035       value = fields->f_rt;
1036       break;
1037     case IQ2000_OPERAND_BYTECOUNT :
1038       value = fields->f_bytecount;
1039       break;
1040     case IQ2000_OPERAND_CAM_Y :
1041       value = fields->f_cam_y;
1042       break;
1043     case IQ2000_OPERAND_CAM_Z :
1044       value = fields->f_cam_z;
1045       break;
1046     case IQ2000_OPERAND_CM_3FUNC :
1047       value = fields->f_cm_3func;
1048       break;
1049     case IQ2000_OPERAND_CM_3Z :
1050       value = fields->f_cm_3z;
1051       break;
1052     case IQ2000_OPERAND_CM_4FUNC :
1053       value = fields->f_cm_4func;
1054       break;
1055     case IQ2000_OPERAND_CM_4Z :
1056       value = fields->f_cm_4z;
1057       break;
1058     case IQ2000_OPERAND_COUNT :
1059       value = fields->f_count;
1060       break;
1061     case IQ2000_OPERAND_EXECODE :
1062       value = fields->f_excode;
1063       break;
1064     case IQ2000_OPERAND_HI16 :
1065       value = fields->f_imm;
1066       break;
1067     case IQ2000_OPERAND_IMM :
1068       value = fields->f_imm;
1069       break;
1070     case IQ2000_OPERAND_JMPTARG :
1071       value = fields->f_jtarg;
1072       break;
1073     case IQ2000_OPERAND_JMPTARGQ10 :
1074       value = fields->f_jtargq10;
1075       break;
1076     case IQ2000_OPERAND_LO16 :
1077       value = fields->f_imm;
1078       break;
1079     case IQ2000_OPERAND_MASK :
1080       value = fields->f_mask;
1081       break;
1082     case IQ2000_OPERAND_MASKL :
1083       value = fields->f_maskl;
1084       break;
1085     case IQ2000_OPERAND_MASKQ10 :
1086       value = fields->f_maskq10;
1087       break;
1088     case IQ2000_OPERAND_MASKR :
1089       value = fields->f_rs;
1090       break;
1091     case IQ2000_OPERAND_MLO16 :
1092       value = fields->f_imm;
1093       break;
1094     case IQ2000_OPERAND_OFFSET :
1095       value = fields->f_offset;
1096       break;
1097     case IQ2000_OPERAND_RD :
1098       value = fields->f_rd;
1099       break;
1100     case IQ2000_OPERAND_RD_RS :
1101       value = fields->f_rd_rs;
1102       break;
1103     case IQ2000_OPERAND_RD_RT :
1104       value = fields->f_rd_rt;
1105       break;
1106     case IQ2000_OPERAND_RS :
1107       value = fields->f_rs;
1108       break;
1109     case IQ2000_OPERAND_RT :
1110       value = fields->f_rt;
1111       break;
1112     case IQ2000_OPERAND_RT_RS :
1113       value = fields->f_rt_rs;
1114       break;
1115     case IQ2000_OPERAND_SHAMT :
1116       value = fields->f_shamt;
1117       break;
1118 
1119     default :
1120       /* xgettext:c-format */
1121       fprintf (stderr, _("Unrecognized field %d while getting vma operand.\n"),
1122 		       opindex);
1123       abort ();
1124   }
1125 
1126   return value;
1127 }
1128 
1129 void iq2000_cgen_set_int_operand  (CGEN_CPU_DESC, int, CGEN_FIELDS *, int);
1130 void iq2000_cgen_set_vma_operand  (CGEN_CPU_DESC, int, CGEN_FIELDS *, bfd_vma);
1131 
1132 /* Stuffing values in cgen_fields is handled by a collection of functions.
1133    They are distinguished by the type of the VALUE argument they accept.
1134    TODO: floating point, inlining support, remove cases where argument type
1135    not appropriate.  */
1136 
1137 void
iq2000_cgen_set_int_operand(CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,int opindex,CGEN_FIELDS * fields,int value)1138 iq2000_cgen_set_int_operand (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
1139 			     int opindex,
1140 			     CGEN_FIELDS * fields,
1141 			     int value)
1142 {
1143   switch (opindex)
1144     {
1145     case IQ2000_OPERAND__INDEX :
1146       fields->f_index = value;
1147       break;
1148     case IQ2000_OPERAND_BASE :
1149       fields->f_rs = value;
1150       break;
1151     case IQ2000_OPERAND_BASEOFF :
1152       fields->f_imm = value;
1153       break;
1154     case IQ2000_OPERAND_BITNUM :
1155       fields->f_rt = value;
1156       break;
1157     case IQ2000_OPERAND_BYTECOUNT :
1158       fields->f_bytecount = value;
1159       break;
1160     case IQ2000_OPERAND_CAM_Y :
1161       fields->f_cam_y = value;
1162       break;
1163     case IQ2000_OPERAND_CAM_Z :
1164       fields->f_cam_z = value;
1165       break;
1166     case IQ2000_OPERAND_CM_3FUNC :
1167       fields->f_cm_3func = value;
1168       break;
1169     case IQ2000_OPERAND_CM_3Z :
1170       fields->f_cm_3z = value;
1171       break;
1172     case IQ2000_OPERAND_CM_4FUNC :
1173       fields->f_cm_4func = value;
1174       break;
1175     case IQ2000_OPERAND_CM_4Z :
1176       fields->f_cm_4z = value;
1177       break;
1178     case IQ2000_OPERAND_COUNT :
1179       fields->f_count = value;
1180       break;
1181     case IQ2000_OPERAND_EXECODE :
1182       fields->f_excode = value;
1183       break;
1184     case IQ2000_OPERAND_HI16 :
1185       fields->f_imm = value;
1186       break;
1187     case IQ2000_OPERAND_IMM :
1188       fields->f_imm = value;
1189       break;
1190     case IQ2000_OPERAND_JMPTARG :
1191       fields->f_jtarg = value;
1192       break;
1193     case IQ2000_OPERAND_JMPTARGQ10 :
1194       fields->f_jtargq10 = value;
1195       break;
1196     case IQ2000_OPERAND_LO16 :
1197       fields->f_imm = value;
1198       break;
1199     case IQ2000_OPERAND_MASK :
1200       fields->f_mask = value;
1201       break;
1202     case IQ2000_OPERAND_MASKL :
1203       fields->f_maskl = value;
1204       break;
1205     case IQ2000_OPERAND_MASKQ10 :
1206       fields->f_maskq10 = value;
1207       break;
1208     case IQ2000_OPERAND_MASKR :
1209       fields->f_rs = value;
1210       break;
1211     case IQ2000_OPERAND_MLO16 :
1212       fields->f_imm = value;
1213       break;
1214     case IQ2000_OPERAND_OFFSET :
1215       fields->f_offset = value;
1216       break;
1217     case IQ2000_OPERAND_RD :
1218       fields->f_rd = value;
1219       break;
1220     case IQ2000_OPERAND_RD_RS :
1221       fields->f_rd_rs = value;
1222       break;
1223     case IQ2000_OPERAND_RD_RT :
1224       fields->f_rd_rt = value;
1225       break;
1226     case IQ2000_OPERAND_RS :
1227       fields->f_rs = value;
1228       break;
1229     case IQ2000_OPERAND_RT :
1230       fields->f_rt = value;
1231       break;
1232     case IQ2000_OPERAND_RT_RS :
1233       fields->f_rt_rs = value;
1234       break;
1235     case IQ2000_OPERAND_SHAMT :
1236       fields->f_shamt = value;
1237       break;
1238 
1239     default :
1240       /* xgettext:c-format */
1241       fprintf (stderr, _("Unrecognized field %d while setting int operand.\n"),
1242 		       opindex);
1243       abort ();
1244   }
1245 }
1246 
1247 void
iq2000_cgen_set_vma_operand(CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,int opindex,CGEN_FIELDS * fields,bfd_vma value)1248 iq2000_cgen_set_vma_operand (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
1249 			     int opindex,
1250 			     CGEN_FIELDS * fields,
1251 			     bfd_vma value)
1252 {
1253   switch (opindex)
1254     {
1255     case IQ2000_OPERAND__INDEX :
1256       fields->f_index = value;
1257       break;
1258     case IQ2000_OPERAND_BASE :
1259       fields->f_rs = value;
1260       break;
1261     case IQ2000_OPERAND_BASEOFF :
1262       fields->f_imm = value;
1263       break;
1264     case IQ2000_OPERAND_BITNUM :
1265       fields->f_rt = value;
1266       break;
1267     case IQ2000_OPERAND_BYTECOUNT :
1268       fields->f_bytecount = value;
1269       break;
1270     case IQ2000_OPERAND_CAM_Y :
1271       fields->f_cam_y = value;
1272       break;
1273     case IQ2000_OPERAND_CAM_Z :
1274       fields->f_cam_z = value;
1275       break;
1276     case IQ2000_OPERAND_CM_3FUNC :
1277       fields->f_cm_3func = value;
1278       break;
1279     case IQ2000_OPERAND_CM_3Z :
1280       fields->f_cm_3z = value;
1281       break;
1282     case IQ2000_OPERAND_CM_4FUNC :
1283       fields->f_cm_4func = value;
1284       break;
1285     case IQ2000_OPERAND_CM_4Z :
1286       fields->f_cm_4z = value;
1287       break;
1288     case IQ2000_OPERAND_COUNT :
1289       fields->f_count = value;
1290       break;
1291     case IQ2000_OPERAND_EXECODE :
1292       fields->f_excode = value;
1293       break;
1294     case IQ2000_OPERAND_HI16 :
1295       fields->f_imm = value;
1296       break;
1297     case IQ2000_OPERAND_IMM :
1298       fields->f_imm = value;
1299       break;
1300     case IQ2000_OPERAND_JMPTARG :
1301       fields->f_jtarg = value;
1302       break;
1303     case IQ2000_OPERAND_JMPTARGQ10 :
1304       fields->f_jtargq10 = value;
1305       break;
1306     case IQ2000_OPERAND_LO16 :
1307       fields->f_imm = value;
1308       break;
1309     case IQ2000_OPERAND_MASK :
1310       fields->f_mask = value;
1311       break;
1312     case IQ2000_OPERAND_MASKL :
1313       fields->f_maskl = value;
1314       break;
1315     case IQ2000_OPERAND_MASKQ10 :
1316       fields->f_maskq10 = value;
1317       break;
1318     case IQ2000_OPERAND_MASKR :
1319       fields->f_rs = value;
1320       break;
1321     case IQ2000_OPERAND_MLO16 :
1322       fields->f_imm = value;
1323       break;
1324     case IQ2000_OPERAND_OFFSET :
1325       fields->f_offset = value;
1326       break;
1327     case IQ2000_OPERAND_RD :
1328       fields->f_rd = value;
1329       break;
1330     case IQ2000_OPERAND_RD_RS :
1331       fields->f_rd_rs = value;
1332       break;
1333     case IQ2000_OPERAND_RD_RT :
1334       fields->f_rd_rt = value;
1335       break;
1336     case IQ2000_OPERAND_RS :
1337       fields->f_rs = value;
1338       break;
1339     case IQ2000_OPERAND_RT :
1340       fields->f_rt = value;
1341       break;
1342     case IQ2000_OPERAND_RT_RS :
1343       fields->f_rt_rs = value;
1344       break;
1345     case IQ2000_OPERAND_SHAMT :
1346       fields->f_shamt = value;
1347       break;
1348 
1349     default :
1350       /* xgettext:c-format */
1351       fprintf (stderr, _("Unrecognized field %d while setting vma operand.\n"),
1352 		       opindex);
1353       abort ();
1354   }
1355 }
1356 
1357 /* Function to call before using the instruction builder tables.  */
1358 
1359 void
iq2000_cgen_init_ibld_table(CGEN_CPU_DESC cd)1360 iq2000_cgen_init_ibld_table (CGEN_CPU_DESC cd)
1361 {
1362   cd->insert_handlers = & iq2000_cgen_insert_handlers[0];
1363   cd->extract_handlers = & iq2000_cgen_extract_handlers[0];
1364 
1365   cd->insert_operand = iq2000_cgen_insert_operand;
1366   cd->extract_operand = iq2000_cgen_extract_operand;
1367 
1368   cd->get_int_operand = iq2000_cgen_get_int_operand;
1369   cd->set_int_operand = iq2000_cgen_set_int_operand;
1370   cd->get_vma_operand = iq2000_cgen_get_vma_operand;
1371   cd->set_vma_operand = iq2000_cgen_set_vma_operand;
1372 }
1373