OSDN Git Service

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