xref: /netbsd-src/external/gpl3/gdb/dist/opcodes/mt-ibld.c (revision 46e6a27c540fbdc2aa1f9372911c2ce9e27d6dff)
1 /* DO NOT EDIT!  -*- buffer-read-only: t -*- vi:set ro:  */
2 /* Instruction building/extraction support for mt. -*- 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-2024 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 "mt-desc.h"
35 #include "mt-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
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 *
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 *
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
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
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
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
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
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 * mt_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 *
570 mt_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 MT_OPERAND_A23 :
582       errmsg = insert_normal (cd, fields->f_a23, 0, 0, 23, 1, 32, total_length, buffer);
583       break;
584     case MT_OPERAND_BALL :
585       errmsg = insert_normal (cd, fields->f_ball, 0, 0, 19, 1, 32, total_length, buffer);
586       break;
587     case MT_OPERAND_BALL2 :
588       errmsg = insert_normal (cd, fields->f_ball2, 0, 0, 15, 1, 32, total_length, buffer);
589       break;
590     case MT_OPERAND_BANKADDR :
591       errmsg = insert_normal (cd, fields->f_bankaddr, 0, 0, 25, 13, 32, total_length, buffer);
592       break;
593     case MT_OPERAND_BRC :
594       errmsg = insert_normal (cd, fields->f_brc, 0, 0, 18, 3, 32, total_length, buffer);
595       break;
596     case MT_OPERAND_BRC2 :
597       errmsg = insert_normal (cd, fields->f_brc2, 0, 0, 14, 3, 32, total_length, buffer);
598       break;
599     case MT_OPERAND_CB1INCR :
600       errmsg = insert_normal (cd, fields->f_cb1incr, 0|(1<<CGEN_IFLD_SIGNED), 0, 19, 6, 32, total_length, buffer);
601       break;
602     case MT_OPERAND_CB1SEL :
603       errmsg = insert_normal (cd, fields->f_cb1sel, 0, 0, 25, 3, 32, total_length, buffer);
604       break;
605     case MT_OPERAND_CB2INCR :
606       errmsg = insert_normal (cd, fields->f_cb2incr, 0|(1<<CGEN_IFLD_SIGNED), 0, 13, 6, 32, total_length, buffer);
607       break;
608     case MT_OPERAND_CB2SEL :
609       errmsg = insert_normal (cd, fields->f_cb2sel, 0, 0, 22, 3, 32, total_length, buffer);
610       break;
611     case MT_OPERAND_CBRB :
612       errmsg = insert_normal (cd, fields->f_cbrb, 0, 0, 10, 1, 32, total_length, buffer);
613       break;
614     case MT_OPERAND_CBS :
615       errmsg = insert_normal (cd, fields->f_cbs, 0, 0, 19, 2, 32, total_length, buffer);
616       break;
617     case MT_OPERAND_CBX :
618       errmsg = insert_normal (cd, fields->f_cbx, 0, 0, 14, 3, 32, total_length, buffer);
619       break;
620     case MT_OPERAND_CCB :
621       errmsg = insert_normal (cd, fields->f_ccb, 0, 0, 11, 1, 32, total_length, buffer);
622       break;
623     case MT_OPERAND_CDB :
624       errmsg = insert_normal (cd, fields->f_cdb, 0, 0, 10, 1, 32, total_length, buffer);
625       break;
626     case MT_OPERAND_CELL :
627       errmsg = insert_normal (cd, fields->f_cell, 0, 0, 9, 3, 32, total_length, buffer);
628       break;
629     case MT_OPERAND_COLNUM :
630       errmsg = insert_normal (cd, fields->f_colnum, 0, 0, 18, 3, 32, total_length, buffer);
631       break;
632     case MT_OPERAND_CONTNUM :
633       errmsg = insert_normal (cd, fields->f_contnum, 0, 0, 8, 9, 32, total_length, buffer);
634       break;
635     case MT_OPERAND_CR :
636       errmsg = insert_normal (cd, fields->f_cr, 0, 0, 22, 3, 32, total_length, buffer);
637       break;
638     case MT_OPERAND_CTXDISP :
639       errmsg = insert_normal (cd, fields->f_ctxdisp, 0, 0, 5, 6, 32, total_length, buffer);
640       break;
641     case MT_OPERAND_DUP :
642       errmsg = insert_normal (cd, fields->f_dup, 0, 0, 6, 1, 32, total_length, buffer);
643       break;
644     case MT_OPERAND_FBDISP :
645       errmsg = insert_normal (cd, fields->f_fbdisp, 0, 0, 15, 6, 32, total_length, buffer);
646       break;
647     case MT_OPERAND_FBINCR :
648       errmsg = insert_normal (cd, fields->f_fbincr, 0, 0, 23, 4, 32, total_length, buffer);
649       break;
650     case MT_OPERAND_FRDR :
651       errmsg = insert_normal (cd, fields->f_dr, 0|(1<<CGEN_IFLD_ABS_ADDR), 0, 19, 4, 32, total_length, buffer);
652       break;
653     case MT_OPERAND_FRDRRR :
654       errmsg = insert_normal (cd, fields->f_drrr, 0|(1<<CGEN_IFLD_ABS_ADDR), 0, 15, 4, 32, total_length, buffer);
655       break;
656     case MT_OPERAND_FRSR1 :
657       errmsg = insert_normal (cd, fields->f_sr1, 0|(1<<CGEN_IFLD_ABS_ADDR), 0, 23, 4, 32, total_length, buffer);
658       break;
659     case MT_OPERAND_FRSR2 :
660       errmsg = insert_normal (cd, fields->f_sr2, 0|(1<<CGEN_IFLD_ABS_ADDR), 0, 19, 4, 32, total_length, buffer);
661       break;
662     case MT_OPERAND_ID :
663       errmsg = insert_normal (cd, fields->f_id, 0, 0, 14, 1, 32, total_length, buffer);
664       break;
665     case MT_OPERAND_IMM16 :
666       {
667         long value = fields->f_imm16s;
668         value = ((value) + (0));
669         errmsg = insert_normal (cd, value, 0|(1<<CGEN_IFLD_SIGNED), 0, 15, 16, 32, total_length, buffer);
670       }
671       break;
672     case MT_OPERAND_IMM16L :
673       errmsg = insert_normal (cd, fields->f_imm16l, 0, 0, 23, 16, 32, total_length, buffer);
674       break;
675     case MT_OPERAND_IMM16O :
676       {
677         long value = fields->f_imm16s;
678         value = ((value) + (0));
679         errmsg = insert_normal (cd, value, 0|(1<<CGEN_IFLD_SIGNED), 0, 15, 16, 32, total_length, buffer);
680       }
681       break;
682     case MT_OPERAND_IMM16Z :
683       errmsg = insert_normal (cd, fields->f_imm16u, 0, 0, 15, 16, 32, total_length, buffer);
684       break;
685     case MT_OPERAND_INCAMT :
686       errmsg = insert_normal (cd, fields->f_incamt, 0, 0, 19, 8, 32, total_length, buffer);
687       break;
688     case MT_OPERAND_INCR :
689       errmsg = insert_normal (cd, fields->f_incr, 0, 0, 17, 6, 32, total_length, buffer);
690       break;
691     case MT_OPERAND_LENGTH :
692       errmsg = insert_normal (cd, fields->f_length, 0, 0, 15, 3, 32, total_length, buffer);
693       break;
694     case MT_OPERAND_LOOPSIZE :
695       {
696         long value = fields->f_loopo;
697         value = ((USI) (value) >> (2));
698         errmsg = insert_normal (cd, value, 0, 0, 7, 8, 32, total_length, buffer);
699       }
700       break;
701     case MT_OPERAND_MASK :
702       errmsg = insert_normal (cd, fields->f_mask, 0, 0, 25, 16, 32, total_length, buffer);
703       break;
704     case MT_OPERAND_MASK1 :
705       errmsg = insert_normal (cd, fields->f_mask1, 0, 0, 22, 3, 32, total_length, buffer);
706       break;
707     case MT_OPERAND_MODE :
708       errmsg = insert_normal (cd, fields->f_mode, 0, 0, 25, 2, 32, total_length, buffer);
709       break;
710     case MT_OPERAND_PERM :
711       errmsg = insert_normal (cd, fields->f_perm, 0, 0, 25, 2, 32, total_length, buffer);
712       break;
713     case MT_OPERAND_RBBC :
714       errmsg = insert_normal (cd, fields->f_rbbc, 0, 0, 25, 2, 32, total_length, buffer);
715       break;
716     case MT_OPERAND_RC :
717       errmsg = insert_normal (cd, fields->f_rc, 0, 0, 15, 1, 32, total_length, buffer);
718       break;
719     case MT_OPERAND_RC1 :
720       errmsg = insert_normal (cd, fields->f_rc1, 0, 0, 11, 1, 32, total_length, buffer);
721       break;
722     case MT_OPERAND_RC2 :
723       errmsg = insert_normal (cd, fields->f_rc2, 0, 0, 6, 1, 32, total_length, buffer);
724       break;
725     case MT_OPERAND_RC3 :
726       errmsg = insert_normal (cd, fields->f_rc3, 0, 0, 7, 1, 32, total_length, buffer);
727       break;
728     case MT_OPERAND_RCNUM :
729       errmsg = insert_normal (cd, fields->f_rcnum, 0, 0, 14, 3, 32, total_length, buffer);
730       break;
731     case MT_OPERAND_RDA :
732       errmsg = insert_normal (cd, fields->f_rda, 0, 0, 25, 1, 32, total_length, buffer);
733       break;
734     case MT_OPERAND_ROWNUM :
735       errmsg = insert_normal (cd, fields->f_rownum, 0, 0, 14, 3, 32, total_length, buffer);
736       break;
737     case MT_OPERAND_ROWNUM1 :
738       errmsg = insert_normal (cd, fields->f_rownum1, 0, 0, 12, 3, 32, total_length, buffer);
739       break;
740     case MT_OPERAND_ROWNUM2 :
741       errmsg = insert_normal (cd, fields->f_rownum2, 0, 0, 9, 3, 32, total_length, buffer);
742       break;
743     case MT_OPERAND_SIZE :
744       errmsg = insert_normal (cd, fields->f_size, 0, 0, 13, 14, 32, total_length, buffer);
745       break;
746     case MT_OPERAND_TYPE :
747       errmsg = insert_normal (cd, fields->f_type, 0, 0, 21, 2, 32, total_length, buffer);
748       break;
749     case MT_OPERAND_WR :
750       errmsg = insert_normal (cd, fields->f_wr, 0, 0, 24, 1, 32, total_length, buffer);
751       break;
752     case MT_OPERAND_XMODE :
753       errmsg = insert_normal (cd, fields->f_xmode, 0, 0, 23, 1, 32, total_length, buffer);
754       break;
755 
756     default :
757       /* xgettext:c-format */
758       opcodes_error_handler
759 	(_("internal error: unrecognized field %d while building insn"),
760 	 opindex);
761       abort ();
762   }
763 
764   return errmsg;
765 }
766 
767 int mt_cgen_extract_operand
768   (CGEN_CPU_DESC, int, CGEN_EXTRACT_INFO *, CGEN_INSN_INT, CGEN_FIELDS *, bfd_vma);
769 
770 /* Main entry point for operand extraction.
771    The result is <= 0 for error, >0 for success.
772    ??? Actual values aren't well defined right now.
773 
774    This function is basically just a big switch statement.  Earlier versions
775    used tables to look up the function to use, but
776    - if the table contains both assembler and disassembler functions then
777      the disassembler contains much of the assembler and vice-versa,
778    - there's a lot of inlining possibilities as things grow,
779    - using a switch statement avoids the function call overhead.
780 
781    This function could be moved into `print_insn_normal', but keeping it
782    separate makes clear the interface between `print_insn_normal' and each of
783    the handlers.  */
784 
785 int
786 mt_cgen_extract_operand (CGEN_CPU_DESC cd,
787 			     int opindex,
788 			     CGEN_EXTRACT_INFO *ex_info,
789 			     CGEN_INSN_INT insn_value,
790 			     CGEN_FIELDS * fields,
791 			     bfd_vma pc)
792 {
793   /* Assume success (for those operands that are nops).  */
794   int length = 1;
795   unsigned int total_length = CGEN_FIELDS_BITSIZE (fields);
796 
797   switch (opindex)
798     {
799     case MT_OPERAND_A23 :
800       length = extract_normal (cd, ex_info, insn_value, 0, 0, 23, 1, 32, total_length, pc, & fields->f_a23);
801       break;
802     case MT_OPERAND_BALL :
803       length = extract_normal (cd, ex_info, insn_value, 0, 0, 19, 1, 32, total_length, pc, & fields->f_ball);
804       break;
805     case MT_OPERAND_BALL2 :
806       length = extract_normal (cd, ex_info, insn_value, 0, 0, 15, 1, 32, total_length, pc, & fields->f_ball2);
807       break;
808     case MT_OPERAND_BANKADDR :
809       length = extract_normal (cd, ex_info, insn_value, 0, 0, 25, 13, 32, total_length, pc, & fields->f_bankaddr);
810       break;
811     case MT_OPERAND_BRC :
812       length = extract_normal (cd, ex_info, insn_value, 0, 0, 18, 3, 32, total_length, pc, & fields->f_brc);
813       break;
814     case MT_OPERAND_BRC2 :
815       length = extract_normal (cd, ex_info, insn_value, 0, 0, 14, 3, 32, total_length, pc, & fields->f_brc2);
816       break;
817     case MT_OPERAND_CB1INCR :
818       length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_SIGNED), 0, 19, 6, 32, total_length, pc, & fields->f_cb1incr);
819       break;
820     case MT_OPERAND_CB1SEL :
821       length = extract_normal (cd, ex_info, insn_value, 0, 0, 25, 3, 32, total_length, pc, & fields->f_cb1sel);
822       break;
823     case MT_OPERAND_CB2INCR :
824       length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_SIGNED), 0, 13, 6, 32, total_length, pc, & fields->f_cb2incr);
825       break;
826     case MT_OPERAND_CB2SEL :
827       length = extract_normal (cd, ex_info, insn_value, 0, 0, 22, 3, 32, total_length, pc, & fields->f_cb2sel);
828       break;
829     case MT_OPERAND_CBRB :
830       length = extract_normal (cd, ex_info, insn_value, 0, 0, 10, 1, 32, total_length, pc, & fields->f_cbrb);
831       break;
832     case MT_OPERAND_CBS :
833       length = extract_normal (cd, ex_info, insn_value, 0, 0, 19, 2, 32, total_length, pc, & fields->f_cbs);
834       break;
835     case MT_OPERAND_CBX :
836       length = extract_normal (cd, ex_info, insn_value, 0, 0, 14, 3, 32, total_length, pc, & fields->f_cbx);
837       break;
838     case MT_OPERAND_CCB :
839       length = extract_normal (cd, ex_info, insn_value, 0, 0, 11, 1, 32, total_length, pc, & fields->f_ccb);
840       break;
841     case MT_OPERAND_CDB :
842       length = extract_normal (cd, ex_info, insn_value, 0, 0, 10, 1, 32, total_length, pc, & fields->f_cdb);
843       break;
844     case MT_OPERAND_CELL :
845       length = extract_normal (cd, ex_info, insn_value, 0, 0, 9, 3, 32, total_length, pc, & fields->f_cell);
846       break;
847     case MT_OPERAND_COLNUM :
848       length = extract_normal (cd, ex_info, insn_value, 0, 0, 18, 3, 32, total_length, pc, & fields->f_colnum);
849       break;
850     case MT_OPERAND_CONTNUM :
851       length = extract_normal (cd, ex_info, insn_value, 0, 0, 8, 9, 32, total_length, pc, & fields->f_contnum);
852       break;
853     case MT_OPERAND_CR :
854       length = extract_normal (cd, ex_info, insn_value, 0, 0, 22, 3, 32, total_length, pc, & fields->f_cr);
855       break;
856     case MT_OPERAND_CTXDISP :
857       length = extract_normal (cd, ex_info, insn_value, 0, 0, 5, 6, 32, total_length, pc, & fields->f_ctxdisp);
858       break;
859     case MT_OPERAND_DUP :
860       length = extract_normal (cd, ex_info, insn_value, 0, 0, 6, 1, 32, total_length, pc, & fields->f_dup);
861       break;
862     case MT_OPERAND_FBDISP :
863       length = extract_normal (cd, ex_info, insn_value, 0, 0, 15, 6, 32, total_length, pc, & fields->f_fbdisp);
864       break;
865     case MT_OPERAND_FBINCR :
866       length = extract_normal (cd, ex_info, insn_value, 0, 0, 23, 4, 32, total_length, pc, & fields->f_fbincr);
867       break;
868     case MT_OPERAND_FRDR :
869       length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_ABS_ADDR), 0, 19, 4, 32, total_length, pc, & fields->f_dr);
870       break;
871     case MT_OPERAND_FRDRRR :
872       length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_ABS_ADDR), 0, 15, 4, 32, total_length, pc, & fields->f_drrr);
873       break;
874     case MT_OPERAND_FRSR1 :
875       length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_ABS_ADDR), 0, 23, 4, 32, total_length, pc, & fields->f_sr1);
876       break;
877     case MT_OPERAND_FRSR2 :
878       length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_ABS_ADDR), 0, 19, 4, 32, total_length, pc, & fields->f_sr2);
879       break;
880     case MT_OPERAND_ID :
881       length = extract_normal (cd, ex_info, insn_value, 0, 0, 14, 1, 32, total_length, pc, & fields->f_id);
882       break;
883     case MT_OPERAND_IMM16 :
884       {
885         long value;
886         length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_SIGNED), 0, 15, 16, 32, total_length, pc, & value);
887         value = ((value) + (0));
888         fields->f_imm16s = value;
889       }
890       break;
891     case MT_OPERAND_IMM16L :
892       length = extract_normal (cd, ex_info, insn_value, 0, 0, 23, 16, 32, total_length, pc, & fields->f_imm16l);
893       break;
894     case MT_OPERAND_IMM16O :
895       {
896         long value;
897         length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_SIGNED), 0, 15, 16, 32, total_length, pc, & value);
898         value = ((value) + (0));
899         fields->f_imm16s = value;
900       }
901       break;
902     case MT_OPERAND_IMM16Z :
903       length = extract_normal (cd, ex_info, insn_value, 0, 0, 15, 16, 32, total_length, pc, & fields->f_imm16u);
904       break;
905     case MT_OPERAND_INCAMT :
906       length = extract_normal (cd, ex_info, insn_value, 0, 0, 19, 8, 32, total_length, pc, & fields->f_incamt);
907       break;
908     case MT_OPERAND_INCR :
909       length = extract_normal (cd, ex_info, insn_value, 0, 0, 17, 6, 32, total_length, pc, & fields->f_incr);
910       break;
911     case MT_OPERAND_LENGTH :
912       length = extract_normal (cd, ex_info, insn_value, 0, 0, 15, 3, 32, total_length, pc, & fields->f_length);
913       break;
914     case MT_OPERAND_LOOPSIZE :
915       {
916         long value;
917         length = extract_normal (cd, ex_info, insn_value, 0, 0, 7, 8, 32, total_length, pc, & value);
918         value = ((((value) << (2))) + (8));
919         fields->f_loopo = value;
920       }
921       break;
922     case MT_OPERAND_MASK :
923       length = extract_normal (cd, ex_info, insn_value, 0, 0, 25, 16, 32, total_length, pc, & fields->f_mask);
924       break;
925     case MT_OPERAND_MASK1 :
926       length = extract_normal (cd, ex_info, insn_value, 0, 0, 22, 3, 32, total_length, pc, & fields->f_mask1);
927       break;
928     case MT_OPERAND_MODE :
929       length = extract_normal (cd, ex_info, insn_value, 0, 0, 25, 2, 32, total_length, pc, & fields->f_mode);
930       break;
931     case MT_OPERAND_PERM :
932       length = extract_normal (cd, ex_info, insn_value, 0, 0, 25, 2, 32, total_length, pc, & fields->f_perm);
933       break;
934     case MT_OPERAND_RBBC :
935       length = extract_normal (cd, ex_info, insn_value, 0, 0, 25, 2, 32, total_length, pc, & fields->f_rbbc);
936       break;
937     case MT_OPERAND_RC :
938       length = extract_normal (cd, ex_info, insn_value, 0, 0, 15, 1, 32, total_length, pc, & fields->f_rc);
939       break;
940     case MT_OPERAND_RC1 :
941       length = extract_normal (cd, ex_info, insn_value, 0, 0, 11, 1, 32, total_length, pc, & fields->f_rc1);
942       break;
943     case MT_OPERAND_RC2 :
944       length = extract_normal (cd, ex_info, insn_value, 0, 0, 6, 1, 32, total_length, pc, & fields->f_rc2);
945       break;
946     case MT_OPERAND_RC3 :
947       length = extract_normal (cd, ex_info, insn_value, 0, 0, 7, 1, 32, total_length, pc, & fields->f_rc3);
948       break;
949     case MT_OPERAND_RCNUM :
950       length = extract_normal (cd, ex_info, insn_value, 0, 0, 14, 3, 32, total_length, pc, & fields->f_rcnum);
951       break;
952     case MT_OPERAND_RDA :
953       length = extract_normal (cd, ex_info, insn_value, 0, 0, 25, 1, 32, total_length, pc, & fields->f_rda);
954       break;
955     case MT_OPERAND_ROWNUM :
956       length = extract_normal (cd, ex_info, insn_value, 0, 0, 14, 3, 32, total_length, pc, & fields->f_rownum);
957       break;
958     case MT_OPERAND_ROWNUM1 :
959       length = extract_normal (cd, ex_info, insn_value, 0, 0, 12, 3, 32, total_length, pc, & fields->f_rownum1);
960       break;
961     case MT_OPERAND_ROWNUM2 :
962       length = extract_normal (cd, ex_info, insn_value, 0, 0, 9, 3, 32, total_length, pc, & fields->f_rownum2);
963       break;
964     case MT_OPERAND_SIZE :
965       length = extract_normal (cd, ex_info, insn_value, 0, 0, 13, 14, 32, total_length, pc, & fields->f_size);
966       break;
967     case MT_OPERAND_TYPE :
968       length = extract_normal (cd, ex_info, insn_value, 0, 0, 21, 2, 32, total_length, pc, & fields->f_type);
969       break;
970     case MT_OPERAND_WR :
971       length = extract_normal (cd, ex_info, insn_value, 0, 0, 24, 1, 32, total_length, pc, & fields->f_wr);
972       break;
973     case MT_OPERAND_XMODE :
974       length = extract_normal (cd, ex_info, insn_value, 0, 0, 23, 1, 32, total_length, pc, & fields->f_xmode);
975       break;
976 
977     default :
978       /* xgettext:c-format */
979       opcodes_error_handler
980 	(_("internal error: unrecognized field %d while decoding insn"),
981 	 opindex);
982       abort ();
983     }
984 
985   return length;
986 }
987 
988 cgen_insert_fn * const mt_cgen_insert_handlers[] =
989 {
990   insert_insn_normal,
991 };
992 
993 cgen_extract_fn * const mt_cgen_extract_handlers[] =
994 {
995   extract_insn_normal,
996 };
997 
998 int mt_cgen_get_int_operand     (CGEN_CPU_DESC, int, const CGEN_FIELDS *);
999 bfd_vma mt_cgen_get_vma_operand (CGEN_CPU_DESC, int, const CGEN_FIELDS *);
1000 
1001 /* Getting values from cgen_fields is handled by a collection of functions.
1002    They are distinguished by the type of the VALUE argument they return.
1003    TODO: floating point, inlining support, remove cases where result type
1004    not appropriate.  */
1005 
1006 int
1007 mt_cgen_get_int_operand (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
1008 			     int opindex,
1009 			     const CGEN_FIELDS * fields)
1010 {
1011   int value;
1012 
1013   switch (opindex)
1014     {
1015     case MT_OPERAND_A23 :
1016       value = fields->f_a23;
1017       break;
1018     case MT_OPERAND_BALL :
1019       value = fields->f_ball;
1020       break;
1021     case MT_OPERAND_BALL2 :
1022       value = fields->f_ball2;
1023       break;
1024     case MT_OPERAND_BANKADDR :
1025       value = fields->f_bankaddr;
1026       break;
1027     case MT_OPERAND_BRC :
1028       value = fields->f_brc;
1029       break;
1030     case MT_OPERAND_BRC2 :
1031       value = fields->f_brc2;
1032       break;
1033     case MT_OPERAND_CB1INCR :
1034       value = fields->f_cb1incr;
1035       break;
1036     case MT_OPERAND_CB1SEL :
1037       value = fields->f_cb1sel;
1038       break;
1039     case MT_OPERAND_CB2INCR :
1040       value = fields->f_cb2incr;
1041       break;
1042     case MT_OPERAND_CB2SEL :
1043       value = fields->f_cb2sel;
1044       break;
1045     case MT_OPERAND_CBRB :
1046       value = fields->f_cbrb;
1047       break;
1048     case MT_OPERAND_CBS :
1049       value = fields->f_cbs;
1050       break;
1051     case MT_OPERAND_CBX :
1052       value = fields->f_cbx;
1053       break;
1054     case MT_OPERAND_CCB :
1055       value = fields->f_ccb;
1056       break;
1057     case MT_OPERAND_CDB :
1058       value = fields->f_cdb;
1059       break;
1060     case MT_OPERAND_CELL :
1061       value = fields->f_cell;
1062       break;
1063     case MT_OPERAND_COLNUM :
1064       value = fields->f_colnum;
1065       break;
1066     case MT_OPERAND_CONTNUM :
1067       value = fields->f_contnum;
1068       break;
1069     case MT_OPERAND_CR :
1070       value = fields->f_cr;
1071       break;
1072     case MT_OPERAND_CTXDISP :
1073       value = fields->f_ctxdisp;
1074       break;
1075     case MT_OPERAND_DUP :
1076       value = fields->f_dup;
1077       break;
1078     case MT_OPERAND_FBDISP :
1079       value = fields->f_fbdisp;
1080       break;
1081     case MT_OPERAND_FBINCR :
1082       value = fields->f_fbincr;
1083       break;
1084     case MT_OPERAND_FRDR :
1085       value = fields->f_dr;
1086       break;
1087     case MT_OPERAND_FRDRRR :
1088       value = fields->f_drrr;
1089       break;
1090     case MT_OPERAND_FRSR1 :
1091       value = fields->f_sr1;
1092       break;
1093     case MT_OPERAND_FRSR2 :
1094       value = fields->f_sr2;
1095       break;
1096     case MT_OPERAND_ID :
1097       value = fields->f_id;
1098       break;
1099     case MT_OPERAND_IMM16 :
1100       value = fields->f_imm16s;
1101       break;
1102     case MT_OPERAND_IMM16L :
1103       value = fields->f_imm16l;
1104       break;
1105     case MT_OPERAND_IMM16O :
1106       value = fields->f_imm16s;
1107       break;
1108     case MT_OPERAND_IMM16Z :
1109       value = fields->f_imm16u;
1110       break;
1111     case MT_OPERAND_INCAMT :
1112       value = fields->f_incamt;
1113       break;
1114     case MT_OPERAND_INCR :
1115       value = fields->f_incr;
1116       break;
1117     case MT_OPERAND_LENGTH :
1118       value = fields->f_length;
1119       break;
1120     case MT_OPERAND_LOOPSIZE :
1121       value = fields->f_loopo;
1122       break;
1123     case MT_OPERAND_MASK :
1124       value = fields->f_mask;
1125       break;
1126     case MT_OPERAND_MASK1 :
1127       value = fields->f_mask1;
1128       break;
1129     case MT_OPERAND_MODE :
1130       value = fields->f_mode;
1131       break;
1132     case MT_OPERAND_PERM :
1133       value = fields->f_perm;
1134       break;
1135     case MT_OPERAND_RBBC :
1136       value = fields->f_rbbc;
1137       break;
1138     case MT_OPERAND_RC :
1139       value = fields->f_rc;
1140       break;
1141     case MT_OPERAND_RC1 :
1142       value = fields->f_rc1;
1143       break;
1144     case MT_OPERAND_RC2 :
1145       value = fields->f_rc2;
1146       break;
1147     case MT_OPERAND_RC3 :
1148       value = fields->f_rc3;
1149       break;
1150     case MT_OPERAND_RCNUM :
1151       value = fields->f_rcnum;
1152       break;
1153     case MT_OPERAND_RDA :
1154       value = fields->f_rda;
1155       break;
1156     case MT_OPERAND_ROWNUM :
1157       value = fields->f_rownum;
1158       break;
1159     case MT_OPERAND_ROWNUM1 :
1160       value = fields->f_rownum1;
1161       break;
1162     case MT_OPERAND_ROWNUM2 :
1163       value = fields->f_rownum2;
1164       break;
1165     case MT_OPERAND_SIZE :
1166       value = fields->f_size;
1167       break;
1168     case MT_OPERAND_TYPE :
1169       value = fields->f_type;
1170       break;
1171     case MT_OPERAND_WR :
1172       value = fields->f_wr;
1173       break;
1174     case MT_OPERAND_XMODE :
1175       value = fields->f_xmode;
1176       break;
1177 
1178     default :
1179       /* xgettext:c-format */
1180       opcodes_error_handler
1181 	(_("internal error: unrecognized field %d while getting int operand"),
1182 	 opindex);
1183       abort ();
1184   }
1185 
1186   return value;
1187 }
1188 
1189 bfd_vma
1190 mt_cgen_get_vma_operand (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
1191 			     int opindex,
1192 			     const CGEN_FIELDS * fields)
1193 {
1194   bfd_vma value;
1195 
1196   switch (opindex)
1197     {
1198     case MT_OPERAND_A23 :
1199       value = fields->f_a23;
1200       break;
1201     case MT_OPERAND_BALL :
1202       value = fields->f_ball;
1203       break;
1204     case MT_OPERAND_BALL2 :
1205       value = fields->f_ball2;
1206       break;
1207     case MT_OPERAND_BANKADDR :
1208       value = fields->f_bankaddr;
1209       break;
1210     case MT_OPERAND_BRC :
1211       value = fields->f_brc;
1212       break;
1213     case MT_OPERAND_BRC2 :
1214       value = fields->f_brc2;
1215       break;
1216     case MT_OPERAND_CB1INCR :
1217       value = fields->f_cb1incr;
1218       break;
1219     case MT_OPERAND_CB1SEL :
1220       value = fields->f_cb1sel;
1221       break;
1222     case MT_OPERAND_CB2INCR :
1223       value = fields->f_cb2incr;
1224       break;
1225     case MT_OPERAND_CB2SEL :
1226       value = fields->f_cb2sel;
1227       break;
1228     case MT_OPERAND_CBRB :
1229       value = fields->f_cbrb;
1230       break;
1231     case MT_OPERAND_CBS :
1232       value = fields->f_cbs;
1233       break;
1234     case MT_OPERAND_CBX :
1235       value = fields->f_cbx;
1236       break;
1237     case MT_OPERAND_CCB :
1238       value = fields->f_ccb;
1239       break;
1240     case MT_OPERAND_CDB :
1241       value = fields->f_cdb;
1242       break;
1243     case MT_OPERAND_CELL :
1244       value = fields->f_cell;
1245       break;
1246     case MT_OPERAND_COLNUM :
1247       value = fields->f_colnum;
1248       break;
1249     case MT_OPERAND_CONTNUM :
1250       value = fields->f_contnum;
1251       break;
1252     case MT_OPERAND_CR :
1253       value = fields->f_cr;
1254       break;
1255     case MT_OPERAND_CTXDISP :
1256       value = fields->f_ctxdisp;
1257       break;
1258     case MT_OPERAND_DUP :
1259       value = fields->f_dup;
1260       break;
1261     case MT_OPERAND_FBDISP :
1262       value = fields->f_fbdisp;
1263       break;
1264     case MT_OPERAND_FBINCR :
1265       value = fields->f_fbincr;
1266       break;
1267     case MT_OPERAND_FRDR :
1268       value = fields->f_dr;
1269       break;
1270     case MT_OPERAND_FRDRRR :
1271       value = fields->f_drrr;
1272       break;
1273     case MT_OPERAND_FRSR1 :
1274       value = fields->f_sr1;
1275       break;
1276     case MT_OPERAND_FRSR2 :
1277       value = fields->f_sr2;
1278       break;
1279     case MT_OPERAND_ID :
1280       value = fields->f_id;
1281       break;
1282     case MT_OPERAND_IMM16 :
1283       value = fields->f_imm16s;
1284       break;
1285     case MT_OPERAND_IMM16L :
1286       value = fields->f_imm16l;
1287       break;
1288     case MT_OPERAND_IMM16O :
1289       value = fields->f_imm16s;
1290       break;
1291     case MT_OPERAND_IMM16Z :
1292       value = fields->f_imm16u;
1293       break;
1294     case MT_OPERAND_INCAMT :
1295       value = fields->f_incamt;
1296       break;
1297     case MT_OPERAND_INCR :
1298       value = fields->f_incr;
1299       break;
1300     case MT_OPERAND_LENGTH :
1301       value = fields->f_length;
1302       break;
1303     case MT_OPERAND_LOOPSIZE :
1304       value = fields->f_loopo;
1305       break;
1306     case MT_OPERAND_MASK :
1307       value = fields->f_mask;
1308       break;
1309     case MT_OPERAND_MASK1 :
1310       value = fields->f_mask1;
1311       break;
1312     case MT_OPERAND_MODE :
1313       value = fields->f_mode;
1314       break;
1315     case MT_OPERAND_PERM :
1316       value = fields->f_perm;
1317       break;
1318     case MT_OPERAND_RBBC :
1319       value = fields->f_rbbc;
1320       break;
1321     case MT_OPERAND_RC :
1322       value = fields->f_rc;
1323       break;
1324     case MT_OPERAND_RC1 :
1325       value = fields->f_rc1;
1326       break;
1327     case MT_OPERAND_RC2 :
1328       value = fields->f_rc2;
1329       break;
1330     case MT_OPERAND_RC3 :
1331       value = fields->f_rc3;
1332       break;
1333     case MT_OPERAND_RCNUM :
1334       value = fields->f_rcnum;
1335       break;
1336     case MT_OPERAND_RDA :
1337       value = fields->f_rda;
1338       break;
1339     case MT_OPERAND_ROWNUM :
1340       value = fields->f_rownum;
1341       break;
1342     case MT_OPERAND_ROWNUM1 :
1343       value = fields->f_rownum1;
1344       break;
1345     case MT_OPERAND_ROWNUM2 :
1346       value = fields->f_rownum2;
1347       break;
1348     case MT_OPERAND_SIZE :
1349       value = fields->f_size;
1350       break;
1351     case MT_OPERAND_TYPE :
1352       value = fields->f_type;
1353       break;
1354     case MT_OPERAND_WR :
1355       value = fields->f_wr;
1356       break;
1357     case MT_OPERAND_XMODE :
1358       value = fields->f_xmode;
1359       break;
1360 
1361     default :
1362       /* xgettext:c-format */
1363       opcodes_error_handler
1364 	(_("internal error: unrecognized field %d while getting vma operand"),
1365 	 opindex);
1366       abort ();
1367   }
1368 
1369   return value;
1370 }
1371 
1372 void mt_cgen_set_int_operand  (CGEN_CPU_DESC, int, CGEN_FIELDS *, int);
1373 void mt_cgen_set_vma_operand  (CGEN_CPU_DESC, int, CGEN_FIELDS *, bfd_vma);
1374 
1375 /* Stuffing values in cgen_fields is handled by a collection of functions.
1376    They are distinguished by the type of the VALUE argument they accept.
1377    TODO: floating point, inlining support, remove cases where argument type
1378    not appropriate.  */
1379 
1380 void
1381 mt_cgen_set_int_operand (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
1382 			     int opindex,
1383 			     CGEN_FIELDS * fields,
1384 			     int value)
1385 {
1386   switch (opindex)
1387     {
1388     case MT_OPERAND_A23 :
1389       fields->f_a23 = value;
1390       break;
1391     case MT_OPERAND_BALL :
1392       fields->f_ball = value;
1393       break;
1394     case MT_OPERAND_BALL2 :
1395       fields->f_ball2 = value;
1396       break;
1397     case MT_OPERAND_BANKADDR :
1398       fields->f_bankaddr = value;
1399       break;
1400     case MT_OPERAND_BRC :
1401       fields->f_brc = value;
1402       break;
1403     case MT_OPERAND_BRC2 :
1404       fields->f_brc2 = value;
1405       break;
1406     case MT_OPERAND_CB1INCR :
1407       fields->f_cb1incr = value;
1408       break;
1409     case MT_OPERAND_CB1SEL :
1410       fields->f_cb1sel = value;
1411       break;
1412     case MT_OPERAND_CB2INCR :
1413       fields->f_cb2incr = value;
1414       break;
1415     case MT_OPERAND_CB2SEL :
1416       fields->f_cb2sel = value;
1417       break;
1418     case MT_OPERAND_CBRB :
1419       fields->f_cbrb = value;
1420       break;
1421     case MT_OPERAND_CBS :
1422       fields->f_cbs = value;
1423       break;
1424     case MT_OPERAND_CBX :
1425       fields->f_cbx = value;
1426       break;
1427     case MT_OPERAND_CCB :
1428       fields->f_ccb = value;
1429       break;
1430     case MT_OPERAND_CDB :
1431       fields->f_cdb = value;
1432       break;
1433     case MT_OPERAND_CELL :
1434       fields->f_cell = value;
1435       break;
1436     case MT_OPERAND_COLNUM :
1437       fields->f_colnum = value;
1438       break;
1439     case MT_OPERAND_CONTNUM :
1440       fields->f_contnum = value;
1441       break;
1442     case MT_OPERAND_CR :
1443       fields->f_cr = value;
1444       break;
1445     case MT_OPERAND_CTXDISP :
1446       fields->f_ctxdisp = value;
1447       break;
1448     case MT_OPERAND_DUP :
1449       fields->f_dup = value;
1450       break;
1451     case MT_OPERAND_FBDISP :
1452       fields->f_fbdisp = value;
1453       break;
1454     case MT_OPERAND_FBINCR :
1455       fields->f_fbincr = value;
1456       break;
1457     case MT_OPERAND_FRDR :
1458       fields->f_dr = value;
1459       break;
1460     case MT_OPERAND_FRDRRR :
1461       fields->f_drrr = value;
1462       break;
1463     case MT_OPERAND_FRSR1 :
1464       fields->f_sr1 = value;
1465       break;
1466     case MT_OPERAND_FRSR2 :
1467       fields->f_sr2 = value;
1468       break;
1469     case MT_OPERAND_ID :
1470       fields->f_id = value;
1471       break;
1472     case MT_OPERAND_IMM16 :
1473       fields->f_imm16s = value;
1474       break;
1475     case MT_OPERAND_IMM16L :
1476       fields->f_imm16l = value;
1477       break;
1478     case MT_OPERAND_IMM16O :
1479       fields->f_imm16s = value;
1480       break;
1481     case MT_OPERAND_IMM16Z :
1482       fields->f_imm16u = value;
1483       break;
1484     case MT_OPERAND_INCAMT :
1485       fields->f_incamt = value;
1486       break;
1487     case MT_OPERAND_INCR :
1488       fields->f_incr = value;
1489       break;
1490     case MT_OPERAND_LENGTH :
1491       fields->f_length = value;
1492       break;
1493     case MT_OPERAND_LOOPSIZE :
1494       fields->f_loopo = value;
1495       break;
1496     case MT_OPERAND_MASK :
1497       fields->f_mask = value;
1498       break;
1499     case MT_OPERAND_MASK1 :
1500       fields->f_mask1 = value;
1501       break;
1502     case MT_OPERAND_MODE :
1503       fields->f_mode = value;
1504       break;
1505     case MT_OPERAND_PERM :
1506       fields->f_perm = value;
1507       break;
1508     case MT_OPERAND_RBBC :
1509       fields->f_rbbc = value;
1510       break;
1511     case MT_OPERAND_RC :
1512       fields->f_rc = value;
1513       break;
1514     case MT_OPERAND_RC1 :
1515       fields->f_rc1 = value;
1516       break;
1517     case MT_OPERAND_RC2 :
1518       fields->f_rc2 = value;
1519       break;
1520     case MT_OPERAND_RC3 :
1521       fields->f_rc3 = value;
1522       break;
1523     case MT_OPERAND_RCNUM :
1524       fields->f_rcnum = value;
1525       break;
1526     case MT_OPERAND_RDA :
1527       fields->f_rda = value;
1528       break;
1529     case MT_OPERAND_ROWNUM :
1530       fields->f_rownum = value;
1531       break;
1532     case MT_OPERAND_ROWNUM1 :
1533       fields->f_rownum1 = value;
1534       break;
1535     case MT_OPERAND_ROWNUM2 :
1536       fields->f_rownum2 = value;
1537       break;
1538     case MT_OPERAND_SIZE :
1539       fields->f_size = value;
1540       break;
1541     case MT_OPERAND_TYPE :
1542       fields->f_type = value;
1543       break;
1544     case MT_OPERAND_WR :
1545       fields->f_wr = value;
1546       break;
1547     case MT_OPERAND_XMODE :
1548       fields->f_xmode = value;
1549       break;
1550 
1551     default :
1552       /* xgettext:c-format */
1553       opcodes_error_handler
1554 	(_("internal error: unrecognized field %d while setting int operand"),
1555 	 opindex);
1556       abort ();
1557   }
1558 }
1559 
1560 void
1561 mt_cgen_set_vma_operand (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
1562 			     int opindex,
1563 			     CGEN_FIELDS * fields,
1564 			     bfd_vma value)
1565 {
1566   switch (opindex)
1567     {
1568     case MT_OPERAND_A23 :
1569       fields->f_a23 = value;
1570       break;
1571     case MT_OPERAND_BALL :
1572       fields->f_ball = value;
1573       break;
1574     case MT_OPERAND_BALL2 :
1575       fields->f_ball2 = value;
1576       break;
1577     case MT_OPERAND_BANKADDR :
1578       fields->f_bankaddr = value;
1579       break;
1580     case MT_OPERAND_BRC :
1581       fields->f_brc = value;
1582       break;
1583     case MT_OPERAND_BRC2 :
1584       fields->f_brc2 = value;
1585       break;
1586     case MT_OPERAND_CB1INCR :
1587       fields->f_cb1incr = value;
1588       break;
1589     case MT_OPERAND_CB1SEL :
1590       fields->f_cb1sel = value;
1591       break;
1592     case MT_OPERAND_CB2INCR :
1593       fields->f_cb2incr = value;
1594       break;
1595     case MT_OPERAND_CB2SEL :
1596       fields->f_cb2sel = value;
1597       break;
1598     case MT_OPERAND_CBRB :
1599       fields->f_cbrb = value;
1600       break;
1601     case MT_OPERAND_CBS :
1602       fields->f_cbs = value;
1603       break;
1604     case MT_OPERAND_CBX :
1605       fields->f_cbx = value;
1606       break;
1607     case MT_OPERAND_CCB :
1608       fields->f_ccb = value;
1609       break;
1610     case MT_OPERAND_CDB :
1611       fields->f_cdb = value;
1612       break;
1613     case MT_OPERAND_CELL :
1614       fields->f_cell = value;
1615       break;
1616     case MT_OPERAND_COLNUM :
1617       fields->f_colnum = value;
1618       break;
1619     case MT_OPERAND_CONTNUM :
1620       fields->f_contnum = value;
1621       break;
1622     case MT_OPERAND_CR :
1623       fields->f_cr = value;
1624       break;
1625     case MT_OPERAND_CTXDISP :
1626       fields->f_ctxdisp = value;
1627       break;
1628     case MT_OPERAND_DUP :
1629       fields->f_dup = value;
1630       break;
1631     case MT_OPERAND_FBDISP :
1632       fields->f_fbdisp = value;
1633       break;
1634     case MT_OPERAND_FBINCR :
1635       fields->f_fbincr = value;
1636       break;
1637     case MT_OPERAND_FRDR :
1638       fields->f_dr = value;
1639       break;
1640     case MT_OPERAND_FRDRRR :
1641       fields->f_drrr = value;
1642       break;
1643     case MT_OPERAND_FRSR1 :
1644       fields->f_sr1 = value;
1645       break;
1646     case MT_OPERAND_FRSR2 :
1647       fields->f_sr2 = value;
1648       break;
1649     case MT_OPERAND_ID :
1650       fields->f_id = value;
1651       break;
1652     case MT_OPERAND_IMM16 :
1653       fields->f_imm16s = value;
1654       break;
1655     case MT_OPERAND_IMM16L :
1656       fields->f_imm16l = value;
1657       break;
1658     case MT_OPERAND_IMM16O :
1659       fields->f_imm16s = value;
1660       break;
1661     case MT_OPERAND_IMM16Z :
1662       fields->f_imm16u = value;
1663       break;
1664     case MT_OPERAND_INCAMT :
1665       fields->f_incamt = value;
1666       break;
1667     case MT_OPERAND_INCR :
1668       fields->f_incr = value;
1669       break;
1670     case MT_OPERAND_LENGTH :
1671       fields->f_length = value;
1672       break;
1673     case MT_OPERAND_LOOPSIZE :
1674       fields->f_loopo = value;
1675       break;
1676     case MT_OPERAND_MASK :
1677       fields->f_mask = value;
1678       break;
1679     case MT_OPERAND_MASK1 :
1680       fields->f_mask1 = value;
1681       break;
1682     case MT_OPERAND_MODE :
1683       fields->f_mode = value;
1684       break;
1685     case MT_OPERAND_PERM :
1686       fields->f_perm = value;
1687       break;
1688     case MT_OPERAND_RBBC :
1689       fields->f_rbbc = value;
1690       break;
1691     case MT_OPERAND_RC :
1692       fields->f_rc = value;
1693       break;
1694     case MT_OPERAND_RC1 :
1695       fields->f_rc1 = value;
1696       break;
1697     case MT_OPERAND_RC2 :
1698       fields->f_rc2 = value;
1699       break;
1700     case MT_OPERAND_RC3 :
1701       fields->f_rc3 = value;
1702       break;
1703     case MT_OPERAND_RCNUM :
1704       fields->f_rcnum = value;
1705       break;
1706     case MT_OPERAND_RDA :
1707       fields->f_rda = value;
1708       break;
1709     case MT_OPERAND_ROWNUM :
1710       fields->f_rownum = value;
1711       break;
1712     case MT_OPERAND_ROWNUM1 :
1713       fields->f_rownum1 = value;
1714       break;
1715     case MT_OPERAND_ROWNUM2 :
1716       fields->f_rownum2 = value;
1717       break;
1718     case MT_OPERAND_SIZE :
1719       fields->f_size = value;
1720       break;
1721     case MT_OPERAND_TYPE :
1722       fields->f_type = value;
1723       break;
1724     case MT_OPERAND_WR :
1725       fields->f_wr = value;
1726       break;
1727     case MT_OPERAND_XMODE :
1728       fields->f_xmode = value;
1729       break;
1730 
1731     default :
1732       /* xgettext:c-format */
1733       opcodes_error_handler
1734 	(_("internal error: unrecognized field %d while setting vma operand"),
1735 	 opindex);
1736       abort ();
1737   }
1738 }
1739 
1740 /* Function to call before using the instruction builder tables.  */
1741 
1742 void
1743 mt_cgen_init_ibld_table (CGEN_CPU_DESC cd)
1744 {
1745   cd->insert_handlers = & mt_cgen_insert_handlers[0];
1746   cd->extract_handlers = & mt_cgen_extract_handlers[0];
1747 
1748   cd->insert_operand = mt_cgen_insert_operand;
1749   cd->extract_operand = mt_cgen_extract_operand;
1750 
1751   cd->get_int_operand = mt_cgen_get_int_operand;
1752   cd->set_int_operand = mt_cgen_set_int_operand;
1753   cd->get_vma_operand = mt_cgen_get_vma_operand;
1754   cd->set_vma_operand = mt_cgen_set_vma_operand;
1755 }
1756