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