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