1/* Instruction building/extraction support for mt. -*- C -*-
2
3   THIS FILE IS MACHINE GENERATED WITH CGEN: Cpu tools GENerator.
4   - the resultant file is machine generated, cgen-ibld.in isn't
5
6   Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2005, 2006, 2007
7   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 "opintl.h"
37#include "safe-ctype.h"
38
39#undef  min
40#define min(a,b) ((a) < (b) ? (a) : (b))
41#undef  max
42#define max(a,b) ((a) > (b) ? (a) : (b))
43
44/* Used by the ifield rtx function.  */
45#define FLD(f) (fields->f)
46
47static const char * insert_normal
48  (CGEN_CPU_DESC, long, unsigned int, unsigned int, unsigned int,
49   unsigned int, unsigned int, unsigned int, CGEN_INSN_BYTES_PTR);
50static const char * insert_insn_normal
51  (CGEN_CPU_DESC, const CGEN_INSN *,
52   CGEN_FIELDS *, CGEN_INSN_BYTES_PTR, bfd_vma);
53static int extract_normal
54  (CGEN_CPU_DESC, CGEN_EXTRACT_INFO *, CGEN_INSN_INT,
55   unsigned int, unsigned int, unsigned int, unsigned int,
56   unsigned int, unsigned int, bfd_vma, long *);
57static int extract_insn_normal
58  (CGEN_CPU_DESC, const CGEN_INSN *, CGEN_EXTRACT_INFO *,
59   CGEN_INSN_INT, CGEN_FIELDS *, bfd_vma);
60#if CGEN_INT_INSN_P
61static void put_insn_int_value
62  (CGEN_CPU_DESC, CGEN_INSN_BYTES_PTR, int, int, CGEN_INSN_INT);
63#endif
64#if ! CGEN_INT_INSN_P
65static CGEN_INLINE void insert_1
66  (CGEN_CPU_DESC, unsigned long, int, int, int, unsigned char *);
67static CGEN_INLINE int fill_cache
68  (CGEN_CPU_DESC, CGEN_EXTRACT_INFO *,  int, int, bfd_vma);
69static CGEN_INLINE long extract_1
70  (CGEN_CPU_DESC, CGEN_EXTRACT_INFO *, int, int, int, unsigned char *, bfd_vma);
71#endif
72
73/* Operand insertion.  */
74
75#if ! CGEN_INT_INSN_P
76
77/* Subroutine of insert_normal.  */
78
79static CGEN_INLINE void
80insert_1 (CGEN_CPU_DESC cd,
81	  unsigned long value,
82	  int start,
83	  int length,
84	  int word_length,
85	  unsigned char *bufp)
86{
87  unsigned long x,mask;
88  int shift;
89
90  x = cgen_get_insn_value (cd, bufp, word_length);
91
92  /* Written this way to avoid undefined behaviour.  */
93  mask = (((1L << (length - 1)) - 1) << 1) | 1;
94  if (CGEN_INSN_LSB0_P)
95    shift = (start + 1) - length;
96  else
97    shift = (word_length - (start + length));
98  x = (x & ~(mask << shift)) | ((value & mask) << shift);
99
100  cgen_put_insn_value (cd, bufp, word_length, (bfd_vma) x);
101}
102
103#endif /* ! CGEN_INT_INSN_P */
104
105/* Default insertion routine.
106
107   ATTRS is a mask of the boolean attributes.
108   WORD_OFFSET is the offset in bits from the start of the insn of the value.
109   WORD_LENGTH is the length of the word in bits in which the value resides.
110   START is the starting bit number in the word, architecture origin.
111   LENGTH is the length of VALUE in bits.
112   TOTAL_LENGTH is the total length of the insn in bits.
113
114   The result is an error message or NULL if success.  */
115
116/* ??? This duplicates functionality with bfd's howto table and
117   bfd_install_relocation.  */
118/* ??? This doesn't handle bfd_vma's.  Create another function when
119   necessary.  */
120
121static const char *
122insert_normal (CGEN_CPU_DESC cd,
123	       long value,
124	       unsigned int attrs,
125	       unsigned int word_offset,
126	       unsigned int start,
127	       unsigned int length,
128	       unsigned int word_length,
129	       unsigned int total_length,
130	       CGEN_INSN_BYTES_PTR buffer)
131{
132  static char errbuf[100];
133  /* Written this way to avoid undefined behaviour.  */
134  unsigned long mask = (((1L << (length - 1)) - 1) << 1) | 1;
135
136  /* If LENGTH is zero, this operand doesn't contribute to the value.  */
137  if (length == 0)
138    return NULL;
139
140  if (word_length > 32)
141    abort ();
142
143  /* For architectures with insns smaller than the base-insn-bitsize,
144     word_length may be too big.  */
145  if (cd->min_insn_bitsize < cd->base_insn_bitsize)
146    {
147      if (word_offset == 0
148	  && word_length > total_length)
149	word_length = total_length;
150    }
151
152  /* Ensure VALUE will fit.  */
153  if (CGEN_BOOL_ATTR (attrs, CGEN_IFLD_SIGN_OPT))
154    {
155      long minval = - (1L << (length - 1));
156      unsigned long maxval = mask;
157
158      if ((value > 0 && (unsigned long) value > maxval)
159	  || value < minval)
160	{
161	  /* xgettext:c-format */
162	  sprintf (errbuf,
163		   _("operand out of range (%ld not between %ld and %lu)"),
164		   value, minval, maxval);
165	  return errbuf;
166	}
167    }
168  else if (! CGEN_BOOL_ATTR (attrs, CGEN_IFLD_SIGNED))
169    {
170      unsigned long maxval = mask;
171      unsigned long val = (unsigned long) value;
172
173      /* For hosts with a word size > 32 check to see if value has been sign
174	 extended beyond 32 bits.  If so then ignore these higher sign bits
175	 as the user is attempting to store a 32-bit signed value into an
176	 unsigned 32-bit field which is allowed.  */
177      if (sizeof (unsigned long) > 4 && ((value >> 32) == -1))
178	val &= 0xFFFFFFFF;
179
180      if (val > maxval)
181	{
182	  /* xgettext:c-format */
183	  sprintf (errbuf,
184		   _("operand out of range (0x%lx not between 0 and 0x%lx)"),
185		   val, maxval);
186	  return errbuf;
187	}
188    }
189  else
190    {
191      if (! cgen_signed_overflow_ok_p (cd))
192	{
193	  long minval = - (1L << (length - 1));
194	  long maxval =   (1L << (length - 1)) - 1;
195
196	  if (value < minval || value > maxval)
197	    {
198	      sprintf
199		/* xgettext:c-format */
200		(errbuf, _("operand out of range (%ld not between %ld and %ld)"),
201		 value, minval, maxval);
202	      return errbuf;
203	    }
204	}
205    }
206
207#if CGEN_INT_INSN_P
208
209  {
210    int shift;
211
212    if (CGEN_INSN_LSB0_P)
213      shift = (word_offset + start + 1) - length;
214    else
215      shift = total_length - (word_offset + start + length);
216    *buffer = (*buffer & ~(mask << shift)) | ((value & mask) << shift);
217  }
218
219#else /* ! CGEN_INT_INSN_P */
220
221  {
222    unsigned char *bufp = (unsigned char *) buffer + word_offset / 8;
223
224    insert_1 (cd, value, start, length, word_length, bufp);
225  }
226
227#endif /* ! CGEN_INT_INSN_P */
228
229  return NULL;
230}
231
232/* Default insn builder (insert handler).
233   The instruction is recorded in CGEN_INT_INSN_P byte order (meaning
234   that if CGEN_INSN_BYTES_PTR is an int * and thus, the value is
235   recorded in host byte order, otherwise BUFFER is an array of bytes
236   and the value is recorded in target byte order).
237   The result is an error message or NULL if success.  */
238
239static const char *
240insert_insn_normal (CGEN_CPU_DESC cd,
241		    const CGEN_INSN * insn,
242		    CGEN_FIELDS * fields,
243		    CGEN_INSN_BYTES_PTR buffer,
244		    bfd_vma pc)
245{
246  const CGEN_SYNTAX *syntax = CGEN_INSN_SYNTAX (insn);
247  unsigned long value;
248  const CGEN_SYNTAX_CHAR_TYPE * syn;
249
250  CGEN_INIT_INSERT (cd);
251  value = CGEN_INSN_BASE_VALUE (insn);
252
253  /* If we're recording insns as numbers (rather than a string of bytes),
254     target byte order handling is deferred until later.  */
255
256#if CGEN_INT_INSN_P
257
258  put_insn_int_value (cd, buffer, cd->base_insn_bitsize,
259		      CGEN_FIELDS_BITSIZE (fields), value);
260
261#else
262
263  cgen_put_insn_value (cd, buffer, min ((unsigned) cd->base_insn_bitsize,
264					(unsigned) CGEN_FIELDS_BITSIZE (fields)),
265		       value);
266
267#endif /* ! CGEN_INT_INSN_P */
268
269  /* ??? It would be better to scan the format's fields.
270     Still need to be able to insert a value based on the operand though;
271     e.g. storing a branch displacement that got resolved later.
272     Needs more thought first.  */
273
274  for (syn = CGEN_SYNTAX_STRING (syntax); * syn; ++ syn)
275    {
276      const char *errmsg;
277
278      if (CGEN_SYNTAX_CHAR_P (* syn))
279	continue;
280
281      errmsg = (* cd->insert_operand) (cd, CGEN_SYNTAX_FIELD (*syn),
282				       fields, buffer, pc);
283      if (errmsg)
284	return errmsg;
285    }
286
287  return NULL;
288}
289
290#if CGEN_INT_INSN_P
291/* Cover function to store an insn value into an integral insn.  Must go here
292   because it needs <prefix>-desc.h for CGEN_INT_INSN_P.  */
293
294static void
295put_insn_int_value (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
296		    CGEN_INSN_BYTES_PTR buf,
297		    int length,
298		    int insn_length,
299		    CGEN_INSN_INT value)
300{
301  /* For architectures with insns smaller than the base-insn-bitsize,
302     length may be too big.  */
303  if (length > insn_length)
304    *buf = value;
305  else
306    {
307      int shift = insn_length - length;
308      /* Written this way to avoid undefined behaviour.  */
309      CGEN_INSN_INT mask = (((1L << (length - 1)) - 1) << 1) | 1;
310
311      *buf = (*buf & ~(mask << shift)) | ((value & mask) << shift);
312    }
313}
314#endif
315
316/* Operand extraction.  */
317
318#if ! CGEN_INT_INSN_P
319
320/* Subroutine of extract_normal.
321   Ensure sufficient bytes are cached in EX_INFO.
322   OFFSET is the offset in bytes from the start of the insn of the value.
323   BYTES is the length of the needed value.
324   Returns 1 for success, 0 for failure.  */
325
326static CGEN_INLINE int
327fill_cache (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
328	    CGEN_EXTRACT_INFO *ex_info,
329	    int offset,
330	    int bytes,
331	    bfd_vma pc)
332{
333  /* It's doubtful that the middle part has already been fetched so
334     we don't optimize that case.  kiss.  */
335  unsigned int mask;
336  disassemble_info *info = (disassemble_info *) ex_info->dis_info;
337
338  /* First do a quick check.  */
339  mask = (1 << bytes) - 1;
340  if (((ex_info->valid >> offset) & mask) == mask)
341    return 1;
342
343  /* Search for the first byte we need to read.  */
344  for (mask = 1 << offset; bytes > 0; --bytes, ++offset, mask <<= 1)
345    if (! (mask & ex_info->valid))
346      break;
347
348  if (bytes)
349    {
350      int status;
351
352      pc += offset;
353      status = (*info->read_memory_func)
354	(pc, ex_info->insn_bytes + offset, bytes, info);
355
356      if (status != 0)
357	{
358	  (*info->memory_error_func) (status, pc, info);
359	  return 0;
360	}
361
362      ex_info->valid |= ((1 << bytes) - 1) << offset;
363    }
364
365  return 1;
366}
367
368/* Subroutine of extract_normal.  */
369
370static CGEN_INLINE long
371extract_1 (CGEN_CPU_DESC cd,
372	   CGEN_EXTRACT_INFO *ex_info ATTRIBUTE_UNUSED,
373	   int start,
374	   int length,
375	   int word_length,
376	   unsigned char *bufp,
377	   bfd_vma pc ATTRIBUTE_UNUSED)
378{
379  unsigned long x;
380  int shift;
381
382  x = cgen_get_insn_value (cd, bufp, word_length);
383
384  if (CGEN_INSN_LSB0_P)
385    shift = (start + 1) - length;
386  else
387    shift = (word_length - (start + length));
388  return x >> shift;
389}
390
391#endif /* ! CGEN_INT_INSN_P */
392
393/* Default extraction routine.
394
395   INSN_VALUE is the first base_insn_bitsize bits of the insn in host order,
396   or sometimes less for cases like the m32r where the base insn size is 32
397   but some insns are 16 bits.
398   ATTRS is a mask of the boolean attributes.  We only need `SIGNED',
399   but for generality we take a bitmask of all of them.
400   WORD_OFFSET is the offset in bits from the start of the insn of the value.
401   WORD_LENGTH is the length of the word in bits in which the value resides.
402   START is the starting bit number in the word, architecture origin.
403   LENGTH is the length of VALUE in bits.
404   TOTAL_LENGTH is the total length of the insn in bits.
405
406   Returns 1 for success, 0 for failure.  */
407
408/* ??? The return code isn't properly used.  wip.  */
409
410/* ??? This doesn't handle bfd_vma's.  Create another function when
411   necessary.  */
412
413static int
414extract_normal (CGEN_CPU_DESC cd,
415#if ! CGEN_INT_INSN_P
416		CGEN_EXTRACT_INFO *ex_info,
417#else
418		CGEN_EXTRACT_INFO *ex_info ATTRIBUTE_UNUSED,
419#endif
420		CGEN_INSN_INT insn_value,
421		unsigned int attrs,
422		unsigned int word_offset,
423		unsigned int start,
424		unsigned int length,
425		unsigned int word_length,
426		unsigned int total_length,
427#if ! CGEN_INT_INSN_P
428		bfd_vma pc,
429#else
430		bfd_vma pc ATTRIBUTE_UNUSED,
431#endif
432		long *valuep)
433{
434  long value, mask;
435
436  /* If LENGTH is zero, this operand doesn't contribute to the value
437     so give it a standard value of zero.  */
438  if (length == 0)
439    {
440      *valuep = 0;
441      return 1;
442    }
443
444  if (word_length > 32)
445    abort ();
446
447  /* For architectures with insns smaller than the insn-base-bitsize,
448     word_length may be too big.  */
449  if (cd->min_insn_bitsize < cd->base_insn_bitsize)
450    {
451      if (word_offset + word_length > total_length)
452	word_length = total_length - word_offset;
453    }
454
455  /* Does the value reside in INSN_VALUE, and at the right alignment?  */
456
457  if (CGEN_INT_INSN_P || (word_offset == 0 && word_length == total_length))
458    {
459      if (CGEN_INSN_LSB0_P)
460	value = insn_value >> ((word_offset + start + 1) - length);
461      else
462	value = insn_value >> (total_length - ( word_offset + start + length));
463    }
464
465#if ! CGEN_INT_INSN_P
466
467  else
468    {
469      unsigned char *bufp = ex_info->insn_bytes + word_offset / 8;
470
471      if (word_length > 32)
472	abort ();
473
474      if (fill_cache (cd, ex_info, word_offset / 8, word_length / 8, pc) == 0)
475	return 0;
476
477      value = extract_1 (cd, ex_info, start, length, word_length, bufp, pc);
478    }
479
480#endif /* ! CGEN_INT_INSN_P */
481
482  /* Written this way to avoid undefined behaviour.  */
483  mask = (((1L << (length - 1)) - 1) << 1) | 1;
484
485  value &= mask;
486  /* sign extend? */
487  if (CGEN_BOOL_ATTR (attrs, CGEN_IFLD_SIGNED)
488      && (value & (1L << (length - 1))))
489    value |= ~mask;
490
491  *valuep = value;
492
493  return 1;
494}
495
496/* Default insn extractor.
497
498   INSN_VALUE is the first base_insn_bitsize bits, translated to host order.
499   The extracted fields are stored in FIELDS.
500   EX_INFO is used to handle reading variable length insns.
501   Return the length of the insn in bits, or 0 if no match,
502   or -1 if an error occurs fetching data (memory_error_func will have
503   been called).  */
504
505static int
506extract_insn_normal (CGEN_CPU_DESC cd,
507		     const CGEN_INSN *insn,
508		     CGEN_EXTRACT_INFO *ex_info,
509		     CGEN_INSN_INT insn_value,
510		     CGEN_FIELDS *fields,
511		     bfd_vma pc)
512{
513  const CGEN_SYNTAX *syntax = CGEN_INSN_SYNTAX (insn);
514  const CGEN_SYNTAX_CHAR_TYPE *syn;
515
516  CGEN_FIELDS_BITSIZE (fields) = CGEN_INSN_BITSIZE (insn);
517
518  CGEN_INIT_EXTRACT (cd);
519
520  for (syn = CGEN_SYNTAX_STRING (syntax); *syn; ++syn)
521    {
522      int length;
523
524      if (CGEN_SYNTAX_CHAR_P (*syn))
525	continue;
526
527      length = (* cd->extract_operand) (cd, CGEN_SYNTAX_FIELD (*syn),
528					ex_info, insn_value, fields, pc);
529      if (length <= 0)
530	return length;
531    }
532
533  /* We recognized and successfully extracted this insn.  */
534  return CGEN_INSN_BITSIZE (insn);
535}
536
537/* Machine generated code added here.  */
538
539const char * mt_cgen_insert_operand
540  (CGEN_CPU_DESC, int, CGEN_FIELDS *, CGEN_INSN_BYTES_PTR, bfd_vma);
541
542/* Main entry point for operand insertion.
543
544   This function is basically just a big switch statement.  Earlier versions
545   used tables to look up the function to use, but
546   - if the table contains both assembler and disassembler functions then
547     the disassembler contains much of the assembler and vice-versa,
548   - there's a lot of inlining possibilities as things grow,
549   - using a switch statement avoids the function call overhead.
550
551   This function could be moved into `parse_insn_normal', but keeping it
552   separate makes clear the interface between `parse_insn_normal' and each of
553   the handlers.  It's also needed by GAS to insert operands that couldn't be
554   resolved during parsing.  */
555
556const char *
557mt_cgen_insert_operand (CGEN_CPU_DESC cd,
558			     int opindex,
559			     CGEN_FIELDS * fields,
560			     CGEN_INSN_BYTES_PTR buffer,
561			     bfd_vma pc ATTRIBUTE_UNUSED)
562{
563  const char * errmsg = NULL;
564  unsigned int total_length = CGEN_FIELDS_BITSIZE (fields);
565
566  switch (opindex)
567    {
568    case MT_OPERAND_A23 :
569      errmsg = insert_normal (cd, fields->f_a23, 0, 0, 23, 1, 32, total_length, buffer);
570      break;
571    case MT_OPERAND_BALL :
572      errmsg = insert_normal (cd, fields->f_ball, 0, 0, 19, 1, 32, total_length, buffer);
573      break;
574    case MT_OPERAND_BALL2 :
575      errmsg = insert_normal (cd, fields->f_ball2, 0, 0, 15, 1, 32, total_length, buffer);
576      break;
577    case MT_OPERAND_BANKADDR :
578      errmsg = insert_normal (cd, fields->f_bankaddr, 0, 0, 25, 13, 32, total_length, buffer);
579      break;
580    case MT_OPERAND_BRC :
581      errmsg = insert_normal (cd, fields->f_brc, 0, 0, 18, 3, 32, total_length, buffer);
582      break;
583    case MT_OPERAND_BRC2 :
584      errmsg = insert_normal (cd, fields->f_brc2, 0, 0, 14, 3, 32, total_length, buffer);
585      break;
586    case MT_OPERAND_CB1INCR :
587      errmsg = insert_normal (cd, fields->f_cb1incr, 0|(1<<CGEN_IFLD_SIGNED), 0, 19, 6, 32, total_length, buffer);
588      break;
589    case MT_OPERAND_CB1SEL :
590      errmsg = insert_normal (cd, fields->f_cb1sel, 0, 0, 25, 3, 32, total_length, buffer);
591      break;
592    case MT_OPERAND_CB2INCR :
593      errmsg = insert_normal (cd, fields->f_cb2incr, 0|(1<<CGEN_IFLD_SIGNED), 0, 13, 6, 32, total_length, buffer);
594      break;
595    case MT_OPERAND_CB2SEL :
596      errmsg = insert_normal (cd, fields->f_cb2sel, 0, 0, 22, 3, 32, total_length, buffer);
597      break;
598    case MT_OPERAND_CBRB :
599      errmsg = insert_normal (cd, fields->f_cbrb, 0, 0, 10, 1, 32, total_length, buffer);
600      break;
601    case MT_OPERAND_CBS :
602      errmsg = insert_normal (cd, fields->f_cbs, 0, 0, 19, 2, 32, total_length, buffer);
603      break;
604    case MT_OPERAND_CBX :
605      errmsg = insert_normal (cd, fields->f_cbx, 0, 0, 14, 3, 32, total_length, buffer);
606      break;
607    case MT_OPERAND_CCB :
608      errmsg = insert_normal (cd, fields->f_ccb, 0, 0, 11, 1, 32, total_length, buffer);
609      break;
610    case MT_OPERAND_CDB :
611      errmsg = insert_normal (cd, fields->f_cdb, 0, 0, 10, 1, 32, total_length, buffer);
612      break;
613    case MT_OPERAND_CELL :
614      errmsg = insert_normal (cd, fields->f_cell, 0, 0, 9, 3, 32, total_length, buffer);
615      break;
616    case MT_OPERAND_COLNUM :
617      errmsg = insert_normal (cd, fields->f_colnum, 0, 0, 18, 3, 32, total_length, buffer);
618      break;
619    case MT_OPERAND_CONTNUM :
620      errmsg = insert_normal (cd, fields->f_contnum, 0, 0, 8, 9, 32, total_length, buffer);
621      break;
622    case MT_OPERAND_CR :
623      errmsg = insert_normal (cd, fields->f_cr, 0, 0, 22, 3, 32, total_length, buffer);
624      break;
625    case MT_OPERAND_CTXDISP :
626      errmsg = insert_normal (cd, fields->f_ctxdisp, 0, 0, 5, 6, 32, total_length, buffer);
627      break;
628    case MT_OPERAND_DUP :
629      errmsg = insert_normal (cd, fields->f_dup, 0, 0, 6, 1, 32, total_length, buffer);
630      break;
631    case MT_OPERAND_FBDISP :
632      errmsg = insert_normal (cd, fields->f_fbdisp, 0, 0, 15, 6, 32, total_length, buffer);
633      break;
634    case MT_OPERAND_FBINCR :
635      errmsg = insert_normal (cd, fields->f_fbincr, 0, 0, 23, 4, 32, total_length, buffer);
636      break;
637    case MT_OPERAND_FRDR :
638      errmsg = insert_normal (cd, fields->f_dr, 0|(1<<CGEN_IFLD_ABS_ADDR), 0, 19, 4, 32, total_length, buffer);
639      break;
640    case MT_OPERAND_FRDRRR :
641      errmsg = insert_normal (cd, fields->f_drrr, 0|(1<<CGEN_IFLD_ABS_ADDR), 0, 15, 4, 32, total_length, buffer);
642      break;
643    case MT_OPERAND_FRSR1 :
644      errmsg = insert_normal (cd, fields->f_sr1, 0|(1<<CGEN_IFLD_ABS_ADDR), 0, 23, 4, 32, total_length, buffer);
645      break;
646    case MT_OPERAND_FRSR2 :
647      errmsg = insert_normal (cd, fields->f_sr2, 0|(1<<CGEN_IFLD_ABS_ADDR), 0, 19, 4, 32, total_length, buffer);
648      break;
649    case MT_OPERAND_ID :
650      errmsg = insert_normal (cd, fields->f_id, 0, 0, 14, 1, 32, total_length, buffer);
651      break;
652    case MT_OPERAND_IMM16 :
653      {
654        long value = fields->f_imm16s;
655        value = ((value) + (0));
656        errmsg = insert_normal (cd, value, 0|(1<<CGEN_IFLD_SIGNED), 0, 15, 16, 32, total_length, buffer);
657      }
658      break;
659    case MT_OPERAND_IMM16L :
660      errmsg = insert_normal (cd, fields->f_imm16l, 0, 0, 23, 16, 32, total_length, buffer);
661      break;
662    case MT_OPERAND_IMM16O :
663      {
664        long value = fields->f_imm16s;
665        value = ((value) + (0));
666        errmsg = insert_normal (cd, value, 0|(1<<CGEN_IFLD_SIGNED), 0, 15, 16, 32, total_length, buffer);
667      }
668      break;
669    case MT_OPERAND_IMM16Z :
670      errmsg = insert_normal (cd, fields->f_imm16u, 0, 0, 15, 16, 32, total_length, buffer);
671      break;
672    case MT_OPERAND_INCAMT :
673      errmsg = insert_normal (cd, fields->f_incamt, 0, 0, 19, 8, 32, total_length, buffer);
674      break;
675    case MT_OPERAND_INCR :
676      errmsg = insert_normal (cd, fields->f_incr, 0, 0, 17, 6, 32, total_length, buffer);
677      break;
678    case MT_OPERAND_LENGTH :
679      errmsg = insert_normal (cd, fields->f_length, 0, 0, 15, 3, 32, total_length, buffer);
680      break;
681    case MT_OPERAND_LOOPSIZE :
682      {
683        long value = fields->f_loopo;
684        value = ((unsigned int) (value) >> (2));
685        errmsg = insert_normal (cd, value, 0, 0, 7, 8, 32, total_length, buffer);
686      }
687      break;
688    case MT_OPERAND_MASK :
689      errmsg = insert_normal (cd, fields->f_mask, 0, 0, 25, 16, 32, total_length, buffer);
690      break;
691    case MT_OPERAND_MASK1 :
692      errmsg = insert_normal (cd, fields->f_mask1, 0, 0, 22, 3, 32, total_length, buffer);
693      break;
694    case MT_OPERAND_MODE :
695      errmsg = insert_normal (cd, fields->f_mode, 0, 0, 25, 2, 32, total_length, buffer);
696      break;
697    case MT_OPERAND_PERM :
698      errmsg = insert_normal (cd, fields->f_perm, 0, 0, 25, 2, 32, total_length, buffer);
699      break;
700    case MT_OPERAND_RBBC :
701      errmsg = insert_normal (cd, fields->f_rbbc, 0, 0, 25, 2, 32, total_length, buffer);
702      break;
703    case MT_OPERAND_RC :
704      errmsg = insert_normal (cd, fields->f_rc, 0, 0, 15, 1, 32, total_length, buffer);
705      break;
706    case MT_OPERAND_RC1 :
707      errmsg = insert_normal (cd, fields->f_rc1, 0, 0, 11, 1, 32, total_length, buffer);
708      break;
709    case MT_OPERAND_RC2 :
710      errmsg = insert_normal (cd, fields->f_rc2, 0, 0, 6, 1, 32, total_length, buffer);
711      break;
712    case MT_OPERAND_RC3 :
713      errmsg = insert_normal (cd, fields->f_rc3, 0, 0, 7, 1, 32, total_length, buffer);
714      break;
715    case MT_OPERAND_RCNUM :
716      errmsg = insert_normal (cd, fields->f_rcnum, 0, 0, 14, 3, 32, total_length, buffer);
717      break;
718    case MT_OPERAND_RDA :
719      errmsg = insert_normal (cd, fields->f_rda, 0, 0, 25, 1, 32, total_length, buffer);
720      break;
721    case MT_OPERAND_ROWNUM :
722      errmsg = insert_normal (cd, fields->f_rownum, 0, 0, 14, 3, 32, total_length, buffer);
723      break;
724    case MT_OPERAND_ROWNUM1 :
725      errmsg = insert_normal (cd, fields->f_rownum1, 0, 0, 12, 3, 32, total_length, buffer);
726      break;
727    case MT_OPERAND_ROWNUM2 :
728      errmsg = insert_normal (cd, fields->f_rownum2, 0, 0, 9, 3, 32, total_length, buffer);
729      break;
730    case MT_OPERAND_SIZE :
731      errmsg = insert_normal (cd, fields->f_size, 0, 0, 13, 14, 32, total_length, buffer);
732      break;
733    case MT_OPERAND_TYPE :
734      errmsg = insert_normal (cd, fields->f_type, 0, 0, 21, 2, 32, total_length, buffer);
735      break;
736    case MT_OPERAND_WR :
737      errmsg = insert_normal (cd, fields->f_wr, 0, 0, 24, 1, 32, total_length, buffer);
738      break;
739    case MT_OPERAND_XMODE :
740      errmsg = insert_normal (cd, fields->f_xmode, 0, 0, 23, 1, 32, total_length, buffer);
741      break;
742
743    default :
744      /* xgettext:c-format */
745      fprintf (stderr, _("Unrecognized field %d while building insn.\n"),
746	       opindex);
747      abort ();
748  }
749
750  return errmsg;
751}
752
753int mt_cgen_extract_operand
754  (CGEN_CPU_DESC, int, CGEN_EXTRACT_INFO *, CGEN_INSN_INT, CGEN_FIELDS *, bfd_vma);
755
756/* Main entry point for operand extraction.
757   The result is <= 0 for error, >0 for success.
758   ??? Actual values aren't well defined right now.
759
760   This function is basically just a big switch statement.  Earlier versions
761   used tables to look up the function to use, but
762   - if the table contains both assembler and disassembler functions then
763     the disassembler contains much of the assembler and vice-versa,
764   - there's a lot of inlining possibilities as things grow,
765   - using a switch statement avoids the function call overhead.
766
767   This function could be moved into `print_insn_normal', but keeping it
768   separate makes clear the interface between `print_insn_normal' and each of
769   the handlers.  */
770
771int
772mt_cgen_extract_operand (CGEN_CPU_DESC cd,
773			     int opindex,
774			     CGEN_EXTRACT_INFO *ex_info,
775			     CGEN_INSN_INT insn_value,
776			     CGEN_FIELDS * fields,
777			     bfd_vma pc)
778{
779  /* Assume success (for those operands that are nops).  */
780  int length = 1;
781  unsigned int total_length = CGEN_FIELDS_BITSIZE (fields);
782
783  switch (opindex)
784    {
785    case MT_OPERAND_A23 :
786      length = extract_normal (cd, ex_info, insn_value, 0, 0, 23, 1, 32, total_length, pc, & fields->f_a23);
787      break;
788    case MT_OPERAND_BALL :
789      length = extract_normal (cd, ex_info, insn_value, 0, 0, 19, 1, 32, total_length, pc, & fields->f_ball);
790      break;
791    case MT_OPERAND_BALL2 :
792      length = extract_normal (cd, ex_info, insn_value, 0, 0, 15, 1, 32, total_length, pc, & fields->f_ball2);
793      break;
794    case MT_OPERAND_BANKADDR :
795      length = extract_normal (cd, ex_info, insn_value, 0, 0, 25, 13, 32, total_length, pc, & fields->f_bankaddr);
796      break;
797    case MT_OPERAND_BRC :
798      length = extract_normal (cd, ex_info, insn_value, 0, 0, 18, 3, 32, total_length, pc, & fields->f_brc);
799      break;
800    case MT_OPERAND_BRC2 :
801      length = extract_normal (cd, ex_info, insn_value, 0, 0, 14, 3, 32, total_length, pc, & fields->f_brc2);
802      break;
803    case MT_OPERAND_CB1INCR :
804      length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_SIGNED), 0, 19, 6, 32, total_length, pc, & fields->f_cb1incr);
805      break;
806    case MT_OPERAND_CB1SEL :
807      length = extract_normal (cd, ex_info, insn_value, 0, 0, 25, 3, 32, total_length, pc, & fields->f_cb1sel);
808      break;
809    case MT_OPERAND_CB2INCR :
810      length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_SIGNED), 0, 13, 6, 32, total_length, pc, & fields->f_cb2incr);
811      break;
812    case MT_OPERAND_CB2SEL :
813      length = extract_normal (cd, ex_info, insn_value, 0, 0, 22, 3, 32, total_length, pc, & fields->f_cb2sel);
814      break;
815    case MT_OPERAND_CBRB :
816      length = extract_normal (cd, ex_info, insn_value, 0, 0, 10, 1, 32, total_length, pc, & fields->f_cbrb);
817      break;
818    case MT_OPERAND_CBS :
819      length = extract_normal (cd, ex_info, insn_value, 0, 0, 19, 2, 32, total_length, pc, & fields->f_cbs);
820      break;
821    case MT_OPERAND_CBX :
822      length = extract_normal (cd, ex_info, insn_value, 0, 0, 14, 3, 32, total_length, pc, & fields->f_cbx);
823      break;
824    case MT_OPERAND_CCB :
825      length = extract_normal (cd, ex_info, insn_value, 0, 0, 11, 1, 32, total_length, pc, & fields->f_ccb);
826      break;
827    case MT_OPERAND_CDB :
828      length = extract_normal (cd, ex_info, insn_value, 0, 0, 10, 1, 32, total_length, pc, & fields->f_cdb);
829      break;
830    case MT_OPERAND_CELL :
831      length = extract_normal (cd, ex_info, insn_value, 0, 0, 9, 3, 32, total_length, pc, & fields->f_cell);
832      break;
833    case MT_OPERAND_COLNUM :
834      length = extract_normal (cd, ex_info, insn_value, 0, 0, 18, 3, 32, total_length, pc, & fields->f_colnum);
835      break;
836    case MT_OPERAND_CONTNUM :
837      length = extract_normal (cd, ex_info, insn_value, 0, 0, 8, 9, 32, total_length, pc, & fields->f_contnum);
838      break;
839    case MT_OPERAND_CR :
840      length = extract_normal (cd, ex_info, insn_value, 0, 0, 22, 3, 32, total_length, pc, & fields->f_cr);
841      break;
842    case MT_OPERAND_CTXDISP :
843      length = extract_normal (cd, ex_info, insn_value, 0, 0, 5, 6, 32, total_length, pc, & fields->f_ctxdisp);
844      break;
845    case MT_OPERAND_DUP :
846      length = extract_normal (cd, ex_info, insn_value, 0, 0, 6, 1, 32, total_length, pc, & fields->f_dup);
847      break;
848    case MT_OPERAND_FBDISP :
849      length = extract_normal (cd, ex_info, insn_value, 0, 0, 15, 6, 32, total_length, pc, & fields->f_fbdisp);
850      break;
851    case MT_OPERAND_FBINCR :
852      length = extract_normal (cd, ex_info, insn_value, 0, 0, 23, 4, 32, total_length, pc, & fields->f_fbincr);
853      break;
854    case MT_OPERAND_FRDR :
855      length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_ABS_ADDR), 0, 19, 4, 32, total_length, pc, & fields->f_dr);
856      break;
857    case MT_OPERAND_FRDRRR :
858      length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_ABS_ADDR), 0, 15, 4, 32, total_length, pc, & fields->f_drrr);
859      break;
860    case MT_OPERAND_FRSR1 :
861      length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_ABS_ADDR), 0, 23, 4, 32, total_length, pc, & fields->f_sr1);
862      break;
863    case MT_OPERAND_FRSR2 :
864      length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_ABS_ADDR), 0, 19, 4, 32, total_length, pc, & fields->f_sr2);
865      break;
866    case MT_OPERAND_ID :
867      length = extract_normal (cd, ex_info, insn_value, 0, 0, 14, 1, 32, total_length, pc, & fields->f_id);
868      break;
869    case MT_OPERAND_IMM16 :
870      {
871        long value;
872        length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_SIGNED), 0, 15, 16, 32, total_length, pc, & value);
873        value = ((value) + (0));
874        fields->f_imm16s = value;
875      }
876      break;
877    case MT_OPERAND_IMM16L :
878      length = extract_normal (cd, ex_info, insn_value, 0, 0, 23, 16, 32, total_length, pc, & fields->f_imm16l);
879      break;
880    case MT_OPERAND_IMM16O :
881      {
882        long value;
883        length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_SIGNED), 0, 15, 16, 32, total_length, pc, & value);
884        value = ((value) + (0));
885        fields->f_imm16s = value;
886      }
887      break;
888    case MT_OPERAND_IMM16Z :
889      length = extract_normal (cd, ex_info, insn_value, 0, 0, 15, 16, 32, total_length, pc, & fields->f_imm16u);
890      break;
891    case MT_OPERAND_INCAMT :
892      length = extract_normal (cd, ex_info, insn_value, 0, 0, 19, 8, 32, total_length, pc, & fields->f_incamt);
893      break;
894    case MT_OPERAND_INCR :
895      length = extract_normal (cd, ex_info, insn_value, 0, 0, 17, 6, 32, total_length, pc, & fields->f_incr);
896      break;
897    case MT_OPERAND_LENGTH :
898      length = extract_normal (cd, ex_info, insn_value, 0, 0, 15, 3, 32, total_length, pc, & fields->f_length);
899      break;
900    case MT_OPERAND_LOOPSIZE :
901      {
902        long value;
903        length = extract_normal (cd, ex_info, insn_value, 0, 0, 7, 8, 32, total_length, pc, & value);
904        value = ((((value) << (2))) + (8));
905        fields->f_loopo = value;
906      }
907      break;
908    case MT_OPERAND_MASK :
909      length = extract_normal (cd, ex_info, insn_value, 0, 0, 25, 16, 32, total_length, pc, & fields->f_mask);
910      break;
911    case MT_OPERAND_MASK1 :
912      length = extract_normal (cd, ex_info, insn_value, 0, 0, 22, 3, 32, total_length, pc, & fields->f_mask1);
913      break;
914    case MT_OPERAND_MODE :
915      length = extract_normal (cd, ex_info, insn_value, 0, 0, 25, 2, 32, total_length, pc, & fields->f_mode);
916      break;
917    case MT_OPERAND_PERM :
918      length = extract_normal (cd, ex_info, insn_value, 0, 0, 25, 2, 32, total_length, pc, & fields->f_perm);
919      break;
920    case MT_OPERAND_RBBC :
921      length = extract_normal (cd, ex_info, insn_value, 0, 0, 25, 2, 32, total_length, pc, & fields->f_rbbc);
922      break;
923    case MT_OPERAND_RC :
924      length = extract_normal (cd, ex_info, insn_value, 0, 0, 15, 1, 32, total_length, pc, & fields->f_rc);
925      break;
926    case MT_OPERAND_RC1 :
927      length = extract_normal (cd, ex_info, insn_value, 0, 0, 11, 1, 32, total_length, pc, & fields->f_rc1);
928      break;
929    case MT_OPERAND_RC2 :
930      length = extract_normal (cd, ex_info, insn_value, 0, 0, 6, 1, 32, total_length, pc, & fields->f_rc2);
931      break;
932    case MT_OPERAND_RC3 :
933      length = extract_normal (cd, ex_info, insn_value, 0, 0, 7, 1, 32, total_length, pc, & fields->f_rc3);
934      break;
935    case MT_OPERAND_RCNUM :
936      length = extract_normal (cd, ex_info, insn_value, 0, 0, 14, 3, 32, total_length, pc, & fields->f_rcnum);
937      break;
938    case MT_OPERAND_RDA :
939      length = extract_normal (cd, ex_info, insn_value, 0, 0, 25, 1, 32, total_length, pc, & fields->f_rda);
940      break;
941    case MT_OPERAND_ROWNUM :
942      length = extract_normal (cd, ex_info, insn_value, 0, 0, 14, 3, 32, total_length, pc, & fields->f_rownum);
943      break;
944    case MT_OPERAND_ROWNUM1 :
945      length = extract_normal (cd, ex_info, insn_value, 0, 0, 12, 3, 32, total_length, pc, & fields->f_rownum1);
946      break;
947    case MT_OPERAND_ROWNUM2 :
948      length = extract_normal (cd, ex_info, insn_value, 0, 0, 9, 3, 32, total_length, pc, & fields->f_rownum2);
949      break;
950    case MT_OPERAND_SIZE :
951      length = extract_normal (cd, ex_info, insn_value, 0, 0, 13, 14, 32, total_length, pc, & fields->f_size);
952      break;
953    case MT_OPERAND_TYPE :
954      length = extract_normal (cd, ex_info, insn_value, 0, 0, 21, 2, 32, total_length, pc, & fields->f_type);
955      break;
956    case MT_OPERAND_WR :
957      length = extract_normal (cd, ex_info, insn_value, 0, 0, 24, 1, 32, total_length, pc, & fields->f_wr);
958      break;
959    case MT_OPERAND_XMODE :
960      length = extract_normal (cd, ex_info, insn_value, 0, 0, 23, 1, 32, total_length, pc, & fields->f_xmode);
961      break;
962
963    default :
964      /* xgettext:c-format */
965      fprintf (stderr, _("Unrecognized field %d while decoding insn.\n"),
966	       opindex);
967      abort ();
968    }
969
970  return length;
971}
972
973cgen_insert_fn * const mt_cgen_insert_handlers[] =
974{
975  insert_insn_normal,
976};
977
978cgen_extract_fn * const mt_cgen_extract_handlers[] =
979{
980  extract_insn_normal,
981};
982
983int mt_cgen_get_int_operand     (CGEN_CPU_DESC, int, const CGEN_FIELDS *);
984bfd_vma mt_cgen_get_vma_operand (CGEN_CPU_DESC, int, const CGEN_FIELDS *);
985
986/* Getting values from cgen_fields is handled by a collection of functions.
987   They are distinguished by the type of the VALUE argument they return.
988   TODO: floating point, inlining support, remove cases where result type
989   not appropriate.  */
990
991int
992mt_cgen_get_int_operand (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
993			     int opindex,
994			     const CGEN_FIELDS * fields)
995{
996  int value;
997
998  switch (opindex)
999    {
1000    case MT_OPERAND_A23 :
1001      value = fields->f_a23;
1002      break;
1003    case MT_OPERAND_BALL :
1004      value = fields->f_ball;
1005      break;
1006    case MT_OPERAND_BALL2 :
1007      value = fields->f_ball2;
1008      break;
1009    case MT_OPERAND_BANKADDR :
1010      value = fields->f_bankaddr;
1011      break;
1012    case MT_OPERAND_BRC :
1013      value = fields->f_brc;
1014      break;
1015    case MT_OPERAND_BRC2 :
1016      value = fields->f_brc2;
1017      break;
1018    case MT_OPERAND_CB1INCR :
1019      value = fields->f_cb1incr;
1020      break;
1021    case MT_OPERAND_CB1SEL :
1022      value = fields->f_cb1sel;
1023      break;
1024    case MT_OPERAND_CB2INCR :
1025      value = fields->f_cb2incr;
1026      break;
1027    case MT_OPERAND_CB2SEL :
1028      value = fields->f_cb2sel;
1029      break;
1030    case MT_OPERAND_CBRB :
1031      value = fields->f_cbrb;
1032      break;
1033    case MT_OPERAND_CBS :
1034      value = fields->f_cbs;
1035      break;
1036    case MT_OPERAND_CBX :
1037      value = fields->f_cbx;
1038      break;
1039    case MT_OPERAND_CCB :
1040      value = fields->f_ccb;
1041      break;
1042    case MT_OPERAND_CDB :
1043      value = fields->f_cdb;
1044      break;
1045    case MT_OPERAND_CELL :
1046      value = fields->f_cell;
1047      break;
1048    case MT_OPERAND_COLNUM :
1049      value = fields->f_colnum;
1050      break;
1051    case MT_OPERAND_CONTNUM :
1052      value = fields->f_contnum;
1053      break;
1054    case MT_OPERAND_CR :
1055      value = fields->f_cr;
1056      break;
1057    case MT_OPERAND_CTXDISP :
1058      value = fields->f_ctxdisp;
1059      break;
1060    case MT_OPERAND_DUP :
1061      value = fields->f_dup;
1062      break;
1063    case MT_OPERAND_FBDISP :
1064      value = fields->f_fbdisp;
1065      break;
1066    case MT_OPERAND_FBINCR :
1067      value = fields->f_fbincr;
1068      break;
1069    case MT_OPERAND_FRDR :
1070      value = fields->f_dr;
1071      break;
1072    case MT_OPERAND_FRDRRR :
1073      value = fields->f_drrr;
1074      break;
1075    case MT_OPERAND_FRSR1 :
1076      value = fields->f_sr1;
1077      break;
1078    case MT_OPERAND_FRSR2 :
1079      value = fields->f_sr2;
1080      break;
1081    case MT_OPERAND_ID :
1082      value = fields->f_id;
1083      break;
1084    case MT_OPERAND_IMM16 :
1085      value = fields->f_imm16s;
1086      break;
1087    case MT_OPERAND_IMM16L :
1088      value = fields->f_imm16l;
1089      break;
1090    case MT_OPERAND_IMM16O :
1091      value = fields->f_imm16s;
1092      break;
1093    case MT_OPERAND_IMM16Z :
1094      value = fields->f_imm16u;
1095      break;
1096    case MT_OPERAND_INCAMT :
1097      value = fields->f_incamt;
1098      break;
1099    case MT_OPERAND_INCR :
1100      value = fields->f_incr;
1101      break;
1102    case MT_OPERAND_LENGTH :
1103      value = fields->f_length;
1104      break;
1105    case MT_OPERAND_LOOPSIZE :
1106      value = fields->f_loopo;
1107      break;
1108    case MT_OPERAND_MASK :
1109      value = fields->f_mask;
1110      break;
1111    case MT_OPERAND_MASK1 :
1112      value = fields->f_mask1;
1113      break;
1114    case MT_OPERAND_MODE :
1115      value = fields->f_mode;
1116      break;
1117    case MT_OPERAND_PERM :
1118      value = fields->f_perm;
1119      break;
1120    case MT_OPERAND_RBBC :
1121      value = fields->f_rbbc;
1122      break;
1123    case MT_OPERAND_RC :
1124      value = fields->f_rc;
1125      break;
1126    case MT_OPERAND_RC1 :
1127      value = fields->f_rc1;
1128      break;
1129    case MT_OPERAND_RC2 :
1130      value = fields->f_rc2;
1131      break;
1132    case MT_OPERAND_RC3 :
1133      value = fields->f_rc3;
1134      break;
1135    case MT_OPERAND_RCNUM :
1136      value = fields->f_rcnum;
1137      break;
1138    case MT_OPERAND_RDA :
1139      value = fields->f_rda;
1140      break;
1141    case MT_OPERAND_ROWNUM :
1142      value = fields->f_rownum;
1143      break;
1144    case MT_OPERAND_ROWNUM1 :
1145      value = fields->f_rownum1;
1146      break;
1147    case MT_OPERAND_ROWNUM2 :
1148      value = fields->f_rownum2;
1149      break;
1150    case MT_OPERAND_SIZE :
1151      value = fields->f_size;
1152      break;
1153    case MT_OPERAND_TYPE :
1154      value = fields->f_type;
1155      break;
1156    case MT_OPERAND_WR :
1157      value = fields->f_wr;
1158      break;
1159    case MT_OPERAND_XMODE :
1160      value = fields->f_xmode;
1161      break;
1162
1163    default :
1164      /* xgettext:c-format */
1165      fprintf (stderr, _("Unrecognized field %d while getting int operand.\n"),
1166		       opindex);
1167      abort ();
1168  }
1169
1170  return value;
1171}
1172
1173bfd_vma
1174mt_cgen_get_vma_operand (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
1175			     int opindex,
1176			     const CGEN_FIELDS * fields)
1177{
1178  bfd_vma value;
1179
1180  switch (opindex)
1181    {
1182    case MT_OPERAND_A23 :
1183      value = fields->f_a23;
1184      break;
1185    case MT_OPERAND_BALL :
1186      value = fields->f_ball;
1187      break;
1188    case MT_OPERAND_BALL2 :
1189      value = fields->f_ball2;
1190      break;
1191    case MT_OPERAND_BANKADDR :
1192      value = fields->f_bankaddr;
1193      break;
1194    case MT_OPERAND_BRC :
1195      value = fields->f_brc;
1196      break;
1197    case MT_OPERAND_BRC2 :
1198      value = fields->f_brc2;
1199      break;
1200    case MT_OPERAND_CB1INCR :
1201      value = fields->f_cb1incr;
1202      break;
1203    case MT_OPERAND_CB1SEL :
1204      value = fields->f_cb1sel;
1205      break;
1206    case MT_OPERAND_CB2INCR :
1207      value = fields->f_cb2incr;
1208      break;
1209    case MT_OPERAND_CB2SEL :
1210      value = fields->f_cb2sel;
1211      break;
1212    case MT_OPERAND_CBRB :
1213      value = fields->f_cbrb;
1214      break;
1215    case MT_OPERAND_CBS :
1216      value = fields->f_cbs;
1217      break;
1218    case MT_OPERAND_CBX :
1219      value = fields->f_cbx;
1220      break;
1221    case MT_OPERAND_CCB :
1222      value = fields->f_ccb;
1223      break;
1224    case MT_OPERAND_CDB :
1225      value = fields->f_cdb;
1226      break;
1227    case MT_OPERAND_CELL :
1228      value = fields->f_cell;
1229      break;
1230    case MT_OPERAND_COLNUM :
1231      value = fields->f_colnum;
1232      break;
1233    case MT_OPERAND_CONTNUM :
1234      value = fields->f_contnum;
1235      break;
1236    case MT_OPERAND_CR :
1237      value = fields->f_cr;
1238      break;
1239    case MT_OPERAND_CTXDISP :
1240      value = fields->f_ctxdisp;
1241      break;
1242    case MT_OPERAND_DUP :
1243      value = fields->f_dup;
1244      break;
1245    case MT_OPERAND_FBDISP :
1246      value = fields->f_fbdisp;
1247      break;
1248    case MT_OPERAND_FBINCR :
1249      value = fields->f_fbincr;
1250      break;
1251    case MT_OPERAND_FRDR :
1252      value = fields->f_dr;
1253      break;
1254    case MT_OPERAND_FRDRRR :
1255      value = fields->f_drrr;
1256      break;
1257    case MT_OPERAND_FRSR1 :
1258      value = fields->f_sr1;
1259      break;
1260    case MT_OPERAND_FRSR2 :
1261      value = fields->f_sr2;
1262      break;
1263    case MT_OPERAND_ID :
1264      value = fields->f_id;
1265      break;
1266    case MT_OPERAND_IMM16 :
1267      value = fields->f_imm16s;
1268      break;
1269    case MT_OPERAND_IMM16L :
1270      value = fields->f_imm16l;
1271      break;
1272    case MT_OPERAND_IMM16O :
1273      value = fields->f_imm16s;
1274      break;
1275    case MT_OPERAND_IMM16Z :
1276      value = fields->f_imm16u;
1277      break;
1278    case MT_OPERAND_INCAMT :
1279      value = fields->f_incamt;
1280      break;
1281    case MT_OPERAND_INCR :
1282      value = fields->f_incr;
1283      break;
1284    case MT_OPERAND_LENGTH :
1285      value = fields->f_length;
1286      break;
1287    case MT_OPERAND_LOOPSIZE :
1288      value = fields->f_loopo;
1289      break;
1290    case MT_OPERAND_MASK :
1291      value = fields->f_mask;
1292      break;
1293    case MT_OPERAND_MASK1 :
1294      value = fields->f_mask1;
1295      break;
1296    case MT_OPERAND_MODE :
1297      value = fields->f_mode;
1298      break;
1299    case MT_OPERAND_PERM :
1300      value = fields->f_perm;
1301      break;
1302    case MT_OPERAND_RBBC :
1303      value = fields->f_rbbc;
1304      break;
1305    case MT_OPERAND_RC :
1306      value = fields->f_rc;
1307      break;
1308    case MT_OPERAND_RC1 :
1309      value = fields->f_rc1;
1310      break;
1311    case MT_OPERAND_RC2 :
1312      value = fields->f_rc2;
1313      break;
1314    case MT_OPERAND_RC3 :
1315      value = fields->f_rc3;
1316      break;
1317    case MT_OPERAND_RCNUM :
1318      value = fields->f_rcnum;
1319      break;
1320    case MT_OPERAND_RDA :
1321      value = fields->f_rda;
1322      break;
1323    case MT_OPERAND_ROWNUM :
1324      value = fields->f_rownum;
1325      break;
1326    case MT_OPERAND_ROWNUM1 :
1327      value = fields->f_rownum1;
1328      break;
1329    case MT_OPERAND_ROWNUM2 :
1330      value = fields->f_rownum2;
1331      break;
1332    case MT_OPERAND_SIZE :
1333      value = fields->f_size;
1334      break;
1335    case MT_OPERAND_TYPE :
1336      value = fields->f_type;
1337      break;
1338    case MT_OPERAND_WR :
1339      value = fields->f_wr;
1340      break;
1341    case MT_OPERAND_XMODE :
1342      value = fields->f_xmode;
1343      break;
1344
1345    default :
1346      /* xgettext:c-format */
1347      fprintf (stderr, _("Unrecognized field %d while getting vma operand.\n"),
1348		       opindex);
1349      abort ();
1350  }
1351
1352  return value;
1353}
1354
1355void mt_cgen_set_int_operand  (CGEN_CPU_DESC, int, CGEN_FIELDS *, int);
1356void mt_cgen_set_vma_operand  (CGEN_CPU_DESC, int, CGEN_FIELDS *, bfd_vma);
1357
1358/* Stuffing values in cgen_fields is handled by a collection of functions.
1359   They are distinguished by the type of the VALUE argument they accept.
1360   TODO: floating point, inlining support, remove cases where argument type
1361   not appropriate.  */
1362
1363void
1364mt_cgen_set_int_operand (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
1365			     int opindex,
1366			     CGEN_FIELDS * fields,
1367			     int value)
1368{
1369  switch (opindex)
1370    {
1371    case MT_OPERAND_A23 :
1372      fields->f_a23 = value;
1373      break;
1374    case MT_OPERAND_BALL :
1375      fields->f_ball = value;
1376      break;
1377    case MT_OPERAND_BALL2 :
1378      fields->f_ball2 = value;
1379      break;
1380    case MT_OPERAND_BANKADDR :
1381      fields->f_bankaddr = value;
1382      break;
1383    case MT_OPERAND_BRC :
1384      fields->f_brc = value;
1385      break;
1386    case MT_OPERAND_BRC2 :
1387      fields->f_brc2 = value;
1388      break;
1389    case MT_OPERAND_CB1INCR :
1390      fields->f_cb1incr = value;
1391      break;
1392    case MT_OPERAND_CB1SEL :
1393      fields->f_cb1sel = value;
1394      break;
1395    case MT_OPERAND_CB2INCR :
1396      fields->f_cb2incr = value;
1397      break;
1398    case MT_OPERAND_CB2SEL :
1399      fields->f_cb2sel = value;
1400      break;
1401    case MT_OPERAND_CBRB :
1402      fields->f_cbrb = value;
1403      break;
1404    case MT_OPERAND_CBS :
1405      fields->f_cbs = value;
1406      break;
1407    case MT_OPERAND_CBX :
1408      fields->f_cbx = value;
1409      break;
1410    case MT_OPERAND_CCB :
1411      fields->f_ccb = value;
1412      break;
1413    case MT_OPERAND_CDB :
1414      fields->f_cdb = value;
1415      break;
1416    case MT_OPERAND_CELL :
1417      fields->f_cell = value;
1418      break;
1419    case MT_OPERAND_COLNUM :
1420      fields->f_colnum = value;
1421      break;
1422    case MT_OPERAND_CONTNUM :
1423      fields->f_contnum = value;
1424      break;
1425    case MT_OPERAND_CR :
1426      fields->f_cr = value;
1427      break;
1428    case MT_OPERAND_CTXDISP :
1429      fields->f_ctxdisp = value;
1430      break;
1431    case MT_OPERAND_DUP :
1432      fields->f_dup = value;
1433      break;
1434    case MT_OPERAND_FBDISP :
1435      fields->f_fbdisp = value;
1436      break;
1437    case MT_OPERAND_FBINCR :
1438      fields->f_fbincr = value;
1439      break;
1440    case MT_OPERAND_FRDR :
1441      fields->f_dr = value;
1442      break;
1443    case MT_OPERAND_FRDRRR :
1444      fields->f_drrr = value;
1445      break;
1446    case MT_OPERAND_FRSR1 :
1447      fields->f_sr1 = value;
1448      break;
1449    case MT_OPERAND_FRSR2 :
1450      fields->f_sr2 = value;
1451      break;
1452    case MT_OPERAND_ID :
1453      fields->f_id = value;
1454      break;
1455    case MT_OPERAND_IMM16 :
1456      fields->f_imm16s = value;
1457      break;
1458    case MT_OPERAND_IMM16L :
1459      fields->f_imm16l = value;
1460      break;
1461    case MT_OPERAND_IMM16O :
1462      fields->f_imm16s = value;
1463      break;
1464    case MT_OPERAND_IMM16Z :
1465      fields->f_imm16u = value;
1466      break;
1467    case MT_OPERAND_INCAMT :
1468      fields->f_incamt = value;
1469      break;
1470    case MT_OPERAND_INCR :
1471      fields->f_incr = value;
1472      break;
1473    case MT_OPERAND_LENGTH :
1474      fields->f_length = value;
1475      break;
1476    case MT_OPERAND_LOOPSIZE :
1477      fields->f_loopo = value;
1478      break;
1479    case MT_OPERAND_MASK :
1480      fields->f_mask = value;
1481      break;
1482    case MT_OPERAND_MASK1 :
1483      fields->f_mask1 = value;
1484      break;
1485    case MT_OPERAND_MODE :
1486      fields->f_mode = value;
1487      break;
1488    case MT_OPERAND_PERM :
1489      fields->f_perm = value;
1490      break;
1491    case MT_OPERAND_RBBC :
1492      fields->f_rbbc = value;
1493      break;
1494    case MT_OPERAND_RC :
1495      fields->f_rc = value;
1496      break;
1497    case MT_OPERAND_RC1 :
1498      fields->f_rc1 = value;
1499      break;
1500    case MT_OPERAND_RC2 :
1501      fields->f_rc2 = value;
1502      break;
1503    case MT_OPERAND_RC3 :
1504      fields->f_rc3 = value;
1505      break;
1506    case MT_OPERAND_RCNUM :
1507      fields->f_rcnum = value;
1508      break;
1509    case MT_OPERAND_RDA :
1510      fields->f_rda = value;
1511      break;
1512    case MT_OPERAND_ROWNUM :
1513      fields->f_rownum = value;
1514      break;
1515    case MT_OPERAND_ROWNUM1 :
1516      fields->f_rownum1 = value;
1517      break;
1518    case MT_OPERAND_ROWNUM2 :
1519      fields->f_rownum2 = value;
1520      break;
1521    case MT_OPERAND_SIZE :
1522      fields->f_size = value;
1523      break;
1524    case MT_OPERAND_TYPE :
1525      fields->f_type = value;
1526      break;
1527    case MT_OPERAND_WR :
1528      fields->f_wr = value;
1529      break;
1530    case MT_OPERAND_XMODE :
1531      fields->f_xmode = value;
1532      break;
1533
1534    default :
1535      /* xgettext:c-format */
1536      fprintf (stderr, _("Unrecognized field %d while setting int operand.\n"),
1537		       opindex);
1538      abort ();
1539  }
1540}
1541
1542void
1543mt_cgen_set_vma_operand (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
1544			     int opindex,
1545			     CGEN_FIELDS * fields,
1546			     bfd_vma value)
1547{
1548  switch (opindex)
1549    {
1550    case MT_OPERAND_A23 :
1551      fields->f_a23 = value;
1552      break;
1553    case MT_OPERAND_BALL :
1554      fields->f_ball = value;
1555      break;
1556    case MT_OPERAND_BALL2 :
1557      fields->f_ball2 = value;
1558      break;
1559    case MT_OPERAND_BANKADDR :
1560      fields->f_bankaddr = value;
1561      break;
1562    case MT_OPERAND_BRC :
1563      fields->f_brc = value;
1564      break;
1565    case MT_OPERAND_BRC2 :
1566      fields->f_brc2 = value;
1567      break;
1568    case MT_OPERAND_CB1INCR :
1569      fields->f_cb1incr = value;
1570      break;
1571    case MT_OPERAND_CB1SEL :
1572      fields->f_cb1sel = value;
1573      break;
1574    case MT_OPERAND_CB2INCR :
1575      fields->f_cb2incr = value;
1576      break;
1577    case MT_OPERAND_CB2SEL :
1578      fields->f_cb2sel = value;
1579      break;
1580    case MT_OPERAND_CBRB :
1581      fields->f_cbrb = value;
1582      break;
1583    case MT_OPERAND_CBS :
1584      fields->f_cbs = value;
1585      break;
1586    case MT_OPERAND_CBX :
1587      fields->f_cbx = value;
1588      break;
1589    case MT_OPERAND_CCB :
1590      fields->f_ccb = value;
1591      break;
1592    case MT_OPERAND_CDB :
1593      fields->f_cdb = value;
1594      break;
1595    case MT_OPERAND_CELL :
1596      fields->f_cell = value;
1597      break;
1598    case MT_OPERAND_COLNUM :
1599      fields->f_colnum = value;
1600      break;
1601    case MT_OPERAND_CONTNUM :
1602      fields->f_contnum = value;
1603      break;
1604    case MT_OPERAND_CR :
1605      fields->f_cr = value;
1606      break;
1607    case MT_OPERAND_CTXDISP :
1608      fields->f_ctxdisp = value;
1609      break;
1610    case MT_OPERAND_DUP :
1611      fields->f_dup = value;
1612      break;
1613    case MT_OPERAND_FBDISP :
1614      fields->f_fbdisp = value;
1615      break;
1616    case MT_OPERAND_FBINCR :
1617      fields->f_fbincr = value;
1618      break;
1619    case MT_OPERAND_FRDR :
1620      fields->f_dr = value;
1621      break;
1622    case MT_OPERAND_FRDRRR :
1623      fields->f_drrr = value;
1624      break;
1625    case MT_OPERAND_FRSR1 :
1626      fields->f_sr1 = value;
1627      break;
1628    case MT_OPERAND_FRSR2 :
1629      fields->f_sr2 = value;
1630      break;
1631    case MT_OPERAND_ID :
1632      fields->f_id = value;
1633      break;
1634    case MT_OPERAND_IMM16 :
1635      fields->f_imm16s = value;
1636      break;
1637    case MT_OPERAND_IMM16L :
1638      fields->f_imm16l = value;
1639      break;
1640    case MT_OPERAND_IMM16O :
1641      fields->f_imm16s = value;
1642      break;
1643    case MT_OPERAND_IMM16Z :
1644      fields->f_imm16u = value;
1645      break;
1646    case MT_OPERAND_INCAMT :
1647      fields->f_incamt = value;
1648      break;
1649    case MT_OPERAND_INCR :
1650      fields->f_incr = value;
1651      break;
1652    case MT_OPERAND_LENGTH :
1653      fields->f_length = value;
1654      break;
1655    case MT_OPERAND_LOOPSIZE :
1656      fields->f_loopo = value;
1657      break;
1658    case MT_OPERAND_MASK :
1659      fields->f_mask = value;
1660      break;
1661    case MT_OPERAND_MASK1 :
1662      fields->f_mask1 = value;
1663      break;
1664    case MT_OPERAND_MODE :
1665      fields->f_mode = value;
1666      break;
1667    case MT_OPERAND_PERM :
1668      fields->f_perm = value;
1669      break;
1670    case MT_OPERAND_RBBC :
1671      fields->f_rbbc = value;
1672      break;
1673    case MT_OPERAND_RC :
1674      fields->f_rc = value;
1675      break;
1676    case MT_OPERAND_RC1 :
1677      fields->f_rc1 = value;
1678      break;
1679    case MT_OPERAND_RC2 :
1680      fields->f_rc2 = value;
1681      break;
1682    case MT_OPERAND_RC3 :
1683      fields->f_rc3 = value;
1684      break;
1685    case MT_OPERAND_RCNUM :
1686      fields->f_rcnum = value;
1687      break;
1688    case MT_OPERAND_RDA :
1689      fields->f_rda = value;
1690      break;
1691    case MT_OPERAND_ROWNUM :
1692      fields->f_rownum = value;
1693      break;
1694    case MT_OPERAND_ROWNUM1 :
1695      fields->f_rownum1 = value;
1696      break;
1697    case MT_OPERAND_ROWNUM2 :
1698      fields->f_rownum2 = value;
1699      break;
1700    case MT_OPERAND_SIZE :
1701      fields->f_size = value;
1702      break;
1703    case MT_OPERAND_TYPE :
1704      fields->f_type = value;
1705      break;
1706    case MT_OPERAND_WR :
1707      fields->f_wr = value;
1708      break;
1709    case MT_OPERAND_XMODE :
1710      fields->f_xmode = value;
1711      break;
1712
1713    default :
1714      /* xgettext:c-format */
1715      fprintf (stderr, _("Unrecognized field %d while setting vma operand.\n"),
1716		       opindex);
1717      abort ();
1718  }
1719}
1720
1721/* Function to call before using the instruction builder tables.  */
1722
1723void
1724mt_cgen_init_ibld_table (CGEN_CPU_DESC cd)
1725{
1726  cd->insert_handlers = & mt_cgen_insert_handlers[0];
1727  cd->extract_handlers = & mt_cgen_extract_handlers[0];
1728
1729  cd->insert_operand = mt_cgen_insert_operand;
1730  cd->extract_operand = mt_cgen_extract_operand;
1731
1732  cd->get_int_operand = mt_cgen_get_int_operand;
1733  cd->set_int_operand = mt_cgen_set_int_operand;
1734  cd->get_vma_operand = mt_cgen_get_vma_operand;
1735  cd->set_vma_operand = mt_cgen_set_vma_operand;
1736}
1737