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