[BINUTILS, AARCH64, 6/8] Add Tag getting instruction in Memory Tagging Extension
[external/binutils.git] / opcodes / mt-ibld.c
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-2018 Free Software Foundation, Inc.
8
9    This file is part of libopcodes.
10
11    This library is free software; you can redistribute it and/or modify
12    it under the terms of the GNU General Public License as published by
13    the Free Software Foundation; either version 3, or (at your option)
14    any later version.
15
16    It is distributed in the hope that it will be useful, but WITHOUT
17    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
18    or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
19    License for more details.
20
21    You should have received a copy of the GNU General Public License
22    along with this program; if not, write to the Free Software Foundation, Inc.,
23    51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.  */
24
25 /* ??? Eventually more and more of this stuff can go to cpu-independent files.
26    Keep that in mind.  */
27
28 #include "sysdep.h"
29 #include <stdio.h>
30 #include "ansidecl.h"
31 #include "dis-asm.h"
32 #include "bfd.h"
33 #include "symcat.h"
34 #include "mt-desc.h"
35 #include "mt-opc.h"
36 #include "cgen/basic-modes.h"
37 #include "opintl.h"
38 #include "safe-ctype.h"
39
40 #undef  min
41 #define min(a,b) ((a) < (b) ? (a) : (b))
42 #undef  max
43 #define max(a,b) ((a) > (b) ? (a) : (b))
44
45 /* Used by the ifield rtx function.  */
46 #define FLD(f) (fields->f)
47
48 static const char * insert_normal
49   (CGEN_CPU_DESC, long, unsigned int, unsigned int, unsigned int,
50    unsigned int, unsigned int, unsigned int, CGEN_INSN_BYTES_PTR);
51 static const char * insert_insn_normal
52   (CGEN_CPU_DESC, const CGEN_INSN *,
53    CGEN_FIELDS *, CGEN_INSN_BYTES_PTR, bfd_vma);
54 static int extract_normal
55   (CGEN_CPU_DESC, CGEN_EXTRACT_INFO *, CGEN_INSN_INT,
56    unsigned int, unsigned int, unsigned int, unsigned int,
57    unsigned int, unsigned int, bfd_vma, long *);
58 static int extract_insn_normal
59   (CGEN_CPU_DESC, const CGEN_INSN *, CGEN_EXTRACT_INFO *,
60    CGEN_INSN_INT, CGEN_FIELDS *, bfd_vma);
61 #if CGEN_INT_INSN_P
62 static void put_insn_int_value
63   (CGEN_CPU_DESC, CGEN_INSN_BYTES_PTR, int, int, CGEN_INSN_INT);
64 #endif
65 #if ! CGEN_INT_INSN_P
66 static CGEN_INLINE void insert_1
67   (CGEN_CPU_DESC, unsigned long, int, int, int, unsigned char *);
68 static CGEN_INLINE int fill_cache
69   (CGEN_CPU_DESC, CGEN_EXTRACT_INFO *,  int, int, bfd_vma);
70 static CGEN_INLINE long extract_1
71   (CGEN_CPU_DESC, CGEN_EXTRACT_INFO *, int, int, int, unsigned char *, bfd_vma);
72 #endif
73 \f
74 /* Operand insertion.  */
75
76 #if ! CGEN_INT_INSN_P
77
78 /* Subroutine of insert_normal.  */
79
80 static CGEN_INLINE void
81 insert_1 (CGEN_CPU_DESC cd,
82           unsigned long value,
83           int start,
84           int length,
85           int word_length,
86           unsigned char *bufp)
87 {
88   unsigned long x,mask;
89   int shift;
90
91   x = cgen_get_insn_value (cd, bufp, word_length);
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
122 static const char *
123 insert_normal (CGEN_CPU_DESC cd,
124                long value,
125                unsigned int attrs,
126                unsigned int word_offset,
127                unsigned int start,
128                unsigned int length,
129                unsigned int word_length,
130                unsigned int total_length,
131                CGEN_INSN_BYTES_PTR buffer)
132 {
133   static char errbuf[100];
134   /* 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
247 static const char *
248 insert_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
302 static void
303 put_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 \f
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
334 static CGEN_INLINE int
335 fill_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
378 static CGEN_INLINE long
379 extract_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
421 static int
422 extract_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
513 static int
514 extract_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 \f
545 /* Machine generated code added here.  */
546
547 const 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
564 const char *
565 mt_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
762 int 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
780 int
781 mt_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
983 cgen_insert_fn * const mt_cgen_insert_handlers[] =
984 {
985   insert_insn_normal,
986 };
987
988 cgen_extract_fn * const mt_cgen_extract_handlers[] =
989 {
990   extract_insn_normal,
991 };
992
993 int mt_cgen_get_int_operand     (CGEN_CPU_DESC, int, const CGEN_FIELDS *);
994 bfd_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
1001 int
1002 mt_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
1184 bfd_vma
1185 mt_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
1367 void mt_cgen_set_int_operand  (CGEN_CPU_DESC, int, CGEN_FIELDS *, int);
1368 void 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
1375 void
1376 mt_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
1555 void
1556 mt_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
1737 void
1738 mt_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 }