* Makefile.am (stamp-m32r): Fix path to cpu files.
[external/binutils.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_CBRB :
580       errmsg = insert_normal (cd, fields->f_cbrb, 0, 0, 10, 1, 32, total_length, buffer);
581       break;
582     case MS1_OPERAND_CBS :
583       errmsg = insert_normal (cd, fields->f_cbs, 0, 0, 19, 2, 32, total_length, buffer);
584       break;
585     case MS1_OPERAND_CBX :
586       errmsg = insert_normal (cd, fields->f_cbx, 0, 0, 14, 3, 32, total_length, buffer);
587       break;
588     case MS1_OPERAND_CCB :
589       errmsg = insert_normal (cd, fields->f_ccb, 0, 0, 11, 1, 32, total_length, buffer);
590       break;
591     case MS1_OPERAND_CDB :
592       errmsg = insert_normal (cd, fields->f_cdb, 0, 0, 10, 1, 32, total_length, buffer);
593       break;
594     case MS1_OPERAND_CELL :
595       errmsg = insert_normal (cd, fields->f_cell, 0, 0, 9, 3, 32, total_length, buffer);
596       break;
597     case MS1_OPERAND_COLNUM :
598       errmsg = insert_normal (cd, fields->f_colnum, 0, 0, 18, 3, 32, total_length, buffer);
599       break;
600     case MS1_OPERAND_CONTNUM :
601       errmsg = insert_normal (cd, fields->f_contnum, 0, 0, 8, 9, 32, total_length, buffer);
602       break;
603     case MS1_OPERAND_CR :
604       errmsg = insert_normal (cd, fields->f_cr, 0, 0, 22, 3, 32, total_length, buffer);
605       break;
606     case MS1_OPERAND_CTXDISP :
607       errmsg = insert_normal (cd, fields->f_ctxdisp, 0, 0, 5, 6, 32, total_length, buffer);
608       break;
609     case MS1_OPERAND_DUP :
610       errmsg = insert_normal (cd, fields->f_dup, 0, 0, 6, 1, 32, total_length, buffer);
611       break;
612     case MS1_OPERAND_FBDISP :
613       errmsg = insert_normal (cd, fields->f_fbdisp, 0, 0, 15, 6, 32, total_length, buffer);
614       break;
615     case MS1_OPERAND_FBINCR :
616       errmsg = insert_normal (cd, fields->f_fbincr, 0, 0, 23, 4, 32, total_length, buffer);
617       break;
618     case MS1_OPERAND_FRDR :
619       errmsg = insert_normal (cd, fields->f_dr, 0|(1<<CGEN_IFLD_ABS_ADDR), 0, 19, 4, 32, total_length, buffer);
620       break;
621     case MS1_OPERAND_FRDRRR :
622       errmsg = insert_normal (cd, fields->f_drrr, 0|(1<<CGEN_IFLD_ABS_ADDR), 0, 15, 4, 32, total_length, buffer);
623       break;
624     case MS1_OPERAND_FRSR1 :
625       errmsg = insert_normal (cd, fields->f_sr1, 0|(1<<CGEN_IFLD_ABS_ADDR), 0, 23, 4, 32, total_length, buffer);
626       break;
627     case MS1_OPERAND_FRSR2 :
628       errmsg = insert_normal (cd, fields->f_sr2, 0|(1<<CGEN_IFLD_ABS_ADDR), 0, 19, 4, 32, total_length, buffer);
629       break;
630     case MS1_OPERAND_ID :
631       errmsg = insert_normal (cd, fields->f_id, 0, 0, 14, 1, 32, total_length, buffer);
632       break;
633     case MS1_OPERAND_IMM16 :
634       {
635         long value = fields->f_imm16s;
636         value = ((value) + (0));
637         errmsg = insert_normal (cd, value, 0|(1<<CGEN_IFLD_SIGNED), 0, 15, 16, 32, total_length, buffer);
638       }
639       break;
640     case MS1_OPERAND_IMM16O :
641       {
642         long value = fields->f_imm16s;
643         value = ((value) + (0));
644         errmsg = insert_normal (cd, value, 0|(1<<CGEN_IFLD_SIGNED), 0, 15, 16, 32, total_length, buffer);
645       }
646       break;
647     case MS1_OPERAND_IMM16Z :
648       errmsg = insert_normal (cd, fields->f_imm16u, 0, 0, 15, 16, 32, total_length, buffer);
649       break;
650     case MS1_OPERAND_INCAMT :
651       errmsg = insert_normal (cd, fields->f_incamt, 0, 0, 19, 8, 32, total_length, buffer);
652       break;
653     case MS1_OPERAND_INCR :
654       errmsg = insert_normal (cd, fields->f_incr, 0, 0, 17, 6, 32, total_length, buffer);
655       break;
656     case MS1_OPERAND_LENGTH :
657       errmsg = insert_normal (cd, fields->f_length, 0, 0, 15, 3, 32, total_length, buffer);
658       break;
659     case MS1_OPERAND_MASK :
660       errmsg = insert_normal (cd, fields->f_mask, 0, 0, 25, 16, 32, total_length, buffer);
661       break;
662     case MS1_OPERAND_MASK1 :
663       errmsg = insert_normal (cd, fields->f_mask1, 0, 0, 22, 3, 32, total_length, buffer);
664       break;
665     case MS1_OPERAND_MODE :
666       errmsg = insert_normal (cd, fields->f_mode, 0, 0, 25, 2, 32, total_length, buffer);
667       break;
668     case MS1_OPERAND_PERM :
669       errmsg = insert_normal (cd, fields->f_perm, 0, 0, 25, 2, 32, total_length, buffer);
670       break;
671     case MS1_OPERAND_RBBC :
672       errmsg = insert_normal (cd, fields->f_rbbc, 0, 0, 25, 2, 32, total_length, buffer);
673       break;
674     case MS1_OPERAND_RC :
675       errmsg = insert_normal (cd, fields->f_rc, 0, 0, 15, 1, 32, total_length, buffer);
676       break;
677     case MS1_OPERAND_RC1 :
678       errmsg = insert_normal (cd, fields->f_rc1, 0, 0, 11, 1, 32, total_length, buffer);
679       break;
680     case MS1_OPERAND_RC2 :
681       errmsg = insert_normal (cd, fields->f_rc2, 0, 0, 6, 1, 32, total_length, buffer);
682       break;
683     case MS1_OPERAND_RCNUM :
684       errmsg = insert_normal (cd, fields->f_rcnum, 0, 0, 14, 3, 32, total_length, buffer);
685       break;
686     case MS1_OPERAND_RDA :
687       errmsg = insert_normal (cd, fields->f_rda, 0, 0, 25, 1, 32, total_length, buffer);
688       break;
689     case MS1_OPERAND_ROWNUM :
690       errmsg = insert_normal (cd, fields->f_rownum, 0, 0, 14, 3, 32, total_length, buffer);
691       break;
692     case MS1_OPERAND_ROWNUM1 :
693       errmsg = insert_normal (cd, fields->f_rownum1, 0, 0, 12, 3, 32, total_length, buffer);
694       break;
695     case MS1_OPERAND_ROWNUM2 :
696       errmsg = insert_normal (cd, fields->f_rownum2, 0, 0, 9, 3, 32, total_length, buffer);
697       break;
698     case MS1_OPERAND_SIZE :
699       errmsg = insert_normal (cd, fields->f_size, 0, 0, 13, 14, 32, total_length, buffer);
700       break;
701     case MS1_OPERAND_TYPE :
702       errmsg = insert_normal (cd, fields->f_type, 0, 0, 21, 2, 32, total_length, buffer);
703       break;
704     case MS1_OPERAND_WR :
705       errmsg = insert_normal (cd, fields->f_wr, 0, 0, 24, 1, 32, total_length, buffer);
706       break;
707     case MS1_OPERAND_XMODE :
708       errmsg = insert_normal (cd, fields->f_xmode, 0, 0, 23, 1, 32, total_length, buffer);
709       break;
710
711     default :
712       /* xgettext:c-format */
713       fprintf (stderr, _("Unrecognized field %d while building insn.\n"),
714                opindex);
715       abort ();
716   }
717
718   return errmsg;
719 }
720
721 int ms1_cgen_extract_operand
722   (CGEN_CPU_DESC, int, CGEN_EXTRACT_INFO *, CGEN_INSN_INT, CGEN_FIELDS *, bfd_vma);
723
724 /* Main entry point for operand extraction.
725    The result is <= 0 for error, >0 for success.
726    ??? Actual values aren't well defined right now.
727
728    This function is basically just a big switch statement.  Earlier versions
729    used tables to look up the function to use, but
730    - if the table contains both assembler and disassembler functions then
731      the disassembler contains much of the assembler and vice-versa,
732    - there's a lot of inlining possibilities as things grow,
733    - using a switch statement avoids the function call overhead.
734
735    This function could be moved into `print_insn_normal', but keeping it
736    separate makes clear the interface between `print_insn_normal' and each of
737    the handlers.  */
738
739 int
740 ms1_cgen_extract_operand (CGEN_CPU_DESC cd,
741                              int opindex,
742                              CGEN_EXTRACT_INFO *ex_info,
743                              CGEN_INSN_INT insn_value,
744                              CGEN_FIELDS * fields,
745                              bfd_vma pc)
746 {
747   /* Assume success (for those operands that are nops).  */
748   int length = 1;
749   unsigned int total_length = CGEN_FIELDS_BITSIZE (fields);
750
751   switch (opindex)
752     {
753     case MS1_OPERAND_A23 :
754       length = extract_normal (cd, ex_info, insn_value, 0, 0, 23, 1, 32, total_length, pc, & fields->f_a23);
755       break;
756     case MS1_OPERAND_BALL :
757       length = extract_normal (cd, ex_info, insn_value, 0, 0, 19, 1, 32, total_length, pc, & fields->f_ball);
758       break;
759     case MS1_OPERAND_BALL2 :
760       length = extract_normal (cd, ex_info, insn_value, 0, 0, 15, 1, 32, total_length, pc, & fields->f_ball2);
761       break;
762     case MS1_OPERAND_BANKADDR :
763       length = extract_normal (cd, ex_info, insn_value, 0, 0, 25, 13, 32, total_length, pc, & fields->f_bankaddr);
764       break;
765     case MS1_OPERAND_BRC :
766       length = extract_normal (cd, ex_info, insn_value, 0, 0, 18, 3, 32, total_length, pc, & fields->f_brc);
767       break;
768     case MS1_OPERAND_BRC2 :
769       length = extract_normal (cd, ex_info, insn_value, 0, 0, 14, 3, 32, total_length, pc, & fields->f_brc2);
770       break;
771     case MS1_OPERAND_CBRB :
772       length = extract_normal (cd, ex_info, insn_value, 0, 0, 10, 1, 32, total_length, pc, & fields->f_cbrb);
773       break;
774     case MS1_OPERAND_CBS :
775       length = extract_normal (cd, ex_info, insn_value, 0, 0, 19, 2, 32, total_length, pc, & fields->f_cbs);
776       break;
777     case MS1_OPERAND_CBX :
778       length = extract_normal (cd, ex_info, insn_value, 0, 0, 14, 3, 32, total_length, pc, & fields->f_cbx);
779       break;
780     case MS1_OPERAND_CCB :
781       length = extract_normal (cd, ex_info, insn_value, 0, 0, 11, 1, 32, total_length, pc, & fields->f_ccb);
782       break;
783     case MS1_OPERAND_CDB :
784       length = extract_normal (cd, ex_info, insn_value, 0, 0, 10, 1, 32, total_length, pc, & fields->f_cdb);
785       break;
786     case MS1_OPERAND_CELL :
787       length = extract_normal (cd, ex_info, insn_value, 0, 0, 9, 3, 32, total_length, pc, & fields->f_cell);
788       break;
789     case MS1_OPERAND_COLNUM :
790       length = extract_normal (cd, ex_info, insn_value, 0, 0, 18, 3, 32, total_length, pc, & fields->f_colnum);
791       break;
792     case MS1_OPERAND_CONTNUM :
793       length = extract_normal (cd, ex_info, insn_value, 0, 0, 8, 9, 32, total_length, pc, & fields->f_contnum);
794       break;
795     case MS1_OPERAND_CR :
796       length = extract_normal (cd, ex_info, insn_value, 0, 0, 22, 3, 32, total_length, pc, & fields->f_cr);
797       break;
798     case MS1_OPERAND_CTXDISP :
799       length = extract_normal (cd, ex_info, insn_value, 0, 0, 5, 6, 32, total_length, pc, & fields->f_ctxdisp);
800       break;
801     case MS1_OPERAND_DUP :
802       length = extract_normal (cd, ex_info, insn_value, 0, 0, 6, 1, 32, total_length, pc, & fields->f_dup);
803       break;
804     case MS1_OPERAND_FBDISP :
805       length = extract_normal (cd, ex_info, insn_value, 0, 0, 15, 6, 32, total_length, pc, & fields->f_fbdisp);
806       break;
807     case MS1_OPERAND_FBINCR :
808       length = extract_normal (cd, ex_info, insn_value, 0, 0, 23, 4, 32, total_length, pc, & fields->f_fbincr);
809       break;
810     case MS1_OPERAND_FRDR :
811       length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_ABS_ADDR), 0, 19, 4, 32, total_length, pc, & fields->f_dr);
812       break;
813     case MS1_OPERAND_FRDRRR :
814       length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_ABS_ADDR), 0, 15, 4, 32, total_length, pc, & fields->f_drrr);
815       break;
816     case MS1_OPERAND_FRSR1 :
817       length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_ABS_ADDR), 0, 23, 4, 32, total_length, pc, & fields->f_sr1);
818       break;
819     case MS1_OPERAND_FRSR2 :
820       length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_ABS_ADDR), 0, 19, 4, 32, total_length, pc, & fields->f_sr2);
821       break;
822     case MS1_OPERAND_ID :
823       length = extract_normal (cd, ex_info, insn_value, 0, 0, 14, 1, 32, total_length, pc, & fields->f_id);
824       break;
825     case MS1_OPERAND_IMM16 :
826       {
827         long value;
828         length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_SIGNED), 0, 15, 16, 32, total_length, pc, & value);
829         value = ((value) + (0));
830         fields->f_imm16s = value;
831       }
832       break;
833     case MS1_OPERAND_IMM16O :
834       {
835         long value;
836         length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_SIGNED), 0, 15, 16, 32, total_length, pc, & value);
837         value = ((value) + (0));
838         fields->f_imm16s = value;
839       }
840       break;
841     case MS1_OPERAND_IMM16Z :
842       length = extract_normal (cd, ex_info, insn_value, 0, 0, 15, 16, 32, total_length, pc, & fields->f_imm16u);
843       break;
844     case MS1_OPERAND_INCAMT :
845       length = extract_normal (cd, ex_info, insn_value, 0, 0, 19, 8, 32, total_length, pc, & fields->f_incamt);
846       break;
847     case MS1_OPERAND_INCR :
848       length = extract_normal (cd, ex_info, insn_value, 0, 0, 17, 6, 32, total_length, pc, & fields->f_incr);
849       break;
850     case MS1_OPERAND_LENGTH :
851       length = extract_normal (cd, ex_info, insn_value, 0, 0, 15, 3, 32, total_length, pc, & fields->f_length);
852       break;
853     case MS1_OPERAND_MASK :
854       length = extract_normal (cd, ex_info, insn_value, 0, 0, 25, 16, 32, total_length, pc, & fields->f_mask);
855       break;
856     case MS1_OPERAND_MASK1 :
857       length = extract_normal (cd, ex_info, insn_value, 0, 0, 22, 3, 32, total_length, pc, & fields->f_mask1);
858       break;
859     case MS1_OPERAND_MODE :
860       length = extract_normal (cd, ex_info, insn_value, 0, 0, 25, 2, 32, total_length, pc, & fields->f_mode);
861       break;
862     case MS1_OPERAND_PERM :
863       length = extract_normal (cd, ex_info, insn_value, 0, 0, 25, 2, 32, total_length, pc, & fields->f_perm);
864       break;
865     case MS1_OPERAND_RBBC :
866       length = extract_normal (cd, ex_info, insn_value, 0, 0, 25, 2, 32, total_length, pc, & fields->f_rbbc);
867       break;
868     case MS1_OPERAND_RC :
869       length = extract_normal (cd, ex_info, insn_value, 0, 0, 15, 1, 32, total_length, pc, & fields->f_rc);
870       break;
871     case MS1_OPERAND_RC1 :
872       length = extract_normal (cd, ex_info, insn_value, 0, 0, 11, 1, 32, total_length, pc, & fields->f_rc1);
873       break;
874     case MS1_OPERAND_RC2 :
875       length = extract_normal (cd, ex_info, insn_value, 0, 0, 6, 1, 32, total_length, pc, & fields->f_rc2);
876       break;
877     case MS1_OPERAND_RCNUM :
878       length = extract_normal (cd, ex_info, insn_value, 0, 0, 14, 3, 32, total_length, pc, & fields->f_rcnum);
879       break;
880     case MS1_OPERAND_RDA :
881       length = extract_normal (cd, ex_info, insn_value, 0, 0, 25, 1, 32, total_length, pc, & fields->f_rda);
882       break;
883     case MS1_OPERAND_ROWNUM :
884       length = extract_normal (cd, ex_info, insn_value, 0, 0, 14, 3, 32, total_length, pc, & fields->f_rownum);
885       break;
886     case MS1_OPERAND_ROWNUM1 :
887       length = extract_normal (cd, ex_info, insn_value, 0, 0, 12, 3, 32, total_length, pc, & fields->f_rownum1);
888       break;
889     case MS1_OPERAND_ROWNUM2 :
890       length = extract_normal (cd, ex_info, insn_value, 0, 0, 9, 3, 32, total_length, pc, & fields->f_rownum2);
891       break;
892     case MS1_OPERAND_SIZE :
893       length = extract_normal (cd, ex_info, insn_value, 0, 0, 13, 14, 32, total_length, pc, & fields->f_size);
894       break;
895     case MS1_OPERAND_TYPE :
896       length = extract_normal (cd, ex_info, insn_value, 0, 0, 21, 2, 32, total_length, pc, & fields->f_type);
897       break;
898     case MS1_OPERAND_WR :
899       length = extract_normal (cd, ex_info, insn_value, 0, 0, 24, 1, 32, total_length, pc, & fields->f_wr);
900       break;
901     case MS1_OPERAND_XMODE :
902       length = extract_normal (cd, ex_info, insn_value, 0, 0, 23, 1, 32, total_length, pc, & fields->f_xmode);
903       break;
904
905     default :
906       /* xgettext:c-format */
907       fprintf (stderr, _("Unrecognized field %d while decoding insn.\n"),
908                opindex);
909       abort ();
910     }
911
912   return length;
913 }
914
915 cgen_insert_fn * const ms1_cgen_insert_handlers[] = 
916 {
917   insert_insn_normal,
918 };
919
920 cgen_extract_fn * const ms1_cgen_extract_handlers[] = 
921 {
922   extract_insn_normal,
923 };
924
925 int ms1_cgen_get_int_operand     (CGEN_CPU_DESC, int, const CGEN_FIELDS *);
926 bfd_vma ms1_cgen_get_vma_operand (CGEN_CPU_DESC, int, const CGEN_FIELDS *);
927
928 /* Getting values from cgen_fields is handled by a collection of functions.
929    They are distinguished by the type of the VALUE argument they return.
930    TODO: floating point, inlining support, remove cases where result type
931    not appropriate.  */
932
933 int
934 ms1_cgen_get_int_operand (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
935                              int opindex,
936                              const CGEN_FIELDS * fields)
937 {
938   int value;
939
940   switch (opindex)
941     {
942     case MS1_OPERAND_A23 :
943       value = fields->f_a23;
944       break;
945     case MS1_OPERAND_BALL :
946       value = fields->f_ball;
947       break;
948     case MS1_OPERAND_BALL2 :
949       value = fields->f_ball2;
950       break;
951     case MS1_OPERAND_BANKADDR :
952       value = fields->f_bankaddr;
953       break;
954     case MS1_OPERAND_BRC :
955       value = fields->f_brc;
956       break;
957     case MS1_OPERAND_BRC2 :
958       value = fields->f_brc2;
959       break;
960     case MS1_OPERAND_CBRB :
961       value = fields->f_cbrb;
962       break;
963     case MS1_OPERAND_CBS :
964       value = fields->f_cbs;
965       break;
966     case MS1_OPERAND_CBX :
967       value = fields->f_cbx;
968       break;
969     case MS1_OPERAND_CCB :
970       value = fields->f_ccb;
971       break;
972     case MS1_OPERAND_CDB :
973       value = fields->f_cdb;
974       break;
975     case MS1_OPERAND_CELL :
976       value = fields->f_cell;
977       break;
978     case MS1_OPERAND_COLNUM :
979       value = fields->f_colnum;
980       break;
981     case MS1_OPERAND_CONTNUM :
982       value = fields->f_contnum;
983       break;
984     case MS1_OPERAND_CR :
985       value = fields->f_cr;
986       break;
987     case MS1_OPERAND_CTXDISP :
988       value = fields->f_ctxdisp;
989       break;
990     case MS1_OPERAND_DUP :
991       value = fields->f_dup;
992       break;
993     case MS1_OPERAND_FBDISP :
994       value = fields->f_fbdisp;
995       break;
996     case MS1_OPERAND_FBINCR :
997       value = fields->f_fbincr;
998       break;
999     case MS1_OPERAND_FRDR :
1000       value = fields->f_dr;
1001       break;
1002     case MS1_OPERAND_FRDRRR :
1003       value = fields->f_drrr;
1004       break;
1005     case MS1_OPERAND_FRSR1 :
1006       value = fields->f_sr1;
1007       break;
1008     case MS1_OPERAND_FRSR2 :
1009       value = fields->f_sr2;
1010       break;
1011     case MS1_OPERAND_ID :
1012       value = fields->f_id;
1013       break;
1014     case MS1_OPERAND_IMM16 :
1015       value = fields->f_imm16s;
1016       break;
1017     case MS1_OPERAND_IMM16O :
1018       value = fields->f_imm16s;
1019       break;
1020     case MS1_OPERAND_IMM16Z :
1021       value = fields->f_imm16u;
1022       break;
1023     case MS1_OPERAND_INCAMT :
1024       value = fields->f_incamt;
1025       break;
1026     case MS1_OPERAND_INCR :
1027       value = fields->f_incr;
1028       break;
1029     case MS1_OPERAND_LENGTH :
1030       value = fields->f_length;
1031       break;
1032     case MS1_OPERAND_MASK :
1033       value = fields->f_mask;
1034       break;
1035     case MS1_OPERAND_MASK1 :
1036       value = fields->f_mask1;
1037       break;
1038     case MS1_OPERAND_MODE :
1039       value = fields->f_mode;
1040       break;
1041     case MS1_OPERAND_PERM :
1042       value = fields->f_perm;
1043       break;
1044     case MS1_OPERAND_RBBC :
1045       value = fields->f_rbbc;
1046       break;
1047     case MS1_OPERAND_RC :
1048       value = fields->f_rc;
1049       break;
1050     case MS1_OPERAND_RC1 :
1051       value = fields->f_rc1;
1052       break;
1053     case MS1_OPERAND_RC2 :
1054       value = fields->f_rc2;
1055       break;
1056     case MS1_OPERAND_RCNUM :
1057       value = fields->f_rcnum;
1058       break;
1059     case MS1_OPERAND_RDA :
1060       value = fields->f_rda;
1061       break;
1062     case MS1_OPERAND_ROWNUM :
1063       value = fields->f_rownum;
1064       break;
1065     case MS1_OPERAND_ROWNUM1 :
1066       value = fields->f_rownum1;
1067       break;
1068     case MS1_OPERAND_ROWNUM2 :
1069       value = fields->f_rownum2;
1070       break;
1071     case MS1_OPERAND_SIZE :
1072       value = fields->f_size;
1073       break;
1074     case MS1_OPERAND_TYPE :
1075       value = fields->f_type;
1076       break;
1077     case MS1_OPERAND_WR :
1078       value = fields->f_wr;
1079       break;
1080     case MS1_OPERAND_XMODE :
1081       value = fields->f_xmode;
1082       break;
1083
1084     default :
1085       /* xgettext:c-format */
1086       fprintf (stderr, _("Unrecognized field %d while getting int operand.\n"),
1087                        opindex);
1088       abort ();
1089   }
1090
1091   return value;
1092 }
1093
1094 bfd_vma
1095 ms1_cgen_get_vma_operand (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
1096                              int opindex,
1097                              const CGEN_FIELDS * fields)
1098 {
1099   bfd_vma value;
1100
1101   switch (opindex)
1102     {
1103     case MS1_OPERAND_A23 :
1104       value = fields->f_a23;
1105       break;
1106     case MS1_OPERAND_BALL :
1107       value = fields->f_ball;
1108       break;
1109     case MS1_OPERAND_BALL2 :
1110       value = fields->f_ball2;
1111       break;
1112     case MS1_OPERAND_BANKADDR :
1113       value = fields->f_bankaddr;
1114       break;
1115     case MS1_OPERAND_BRC :
1116       value = fields->f_brc;
1117       break;
1118     case MS1_OPERAND_BRC2 :
1119       value = fields->f_brc2;
1120       break;
1121     case MS1_OPERAND_CBRB :
1122       value = fields->f_cbrb;
1123       break;
1124     case MS1_OPERAND_CBS :
1125       value = fields->f_cbs;
1126       break;
1127     case MS1_OPERAND_CBX :
1128       value = fields->f_cbx;
1129       break;
1130     case MS1_OPERAND_CCB :
1131       value = fields->f_ccb;
1132       break;
1133     case MS1_OPERAND_CDB :
1134       value = fields->f_cdb;
1135       break;
1136     case MS1_OPERAND_CELL :
1137       value = fields->f_cell;
1138       break;
1139     case MS1_OPERAND_COLNUM :
1140       value = fields->f_colnum;
1141       break;
1142     case MS1_OPERAND_CONTNUM :
1143       value = fields->f_contnum;
1144       break;
1145     case MS1_OPERAND_CR :
1146       value = fields->f_cr;
1147       break;
1148     case MS1_OPERAND_CTXDISP :
1149       value = fields->f_ctxdisp;
1150       break;
1151     case MS1_OPERAND_DUP :
1152       value = fields->f_dup;
1153       break;
1154     case MS1_OPERAND_FBDISP :
1155       value = fields->f_fbdisp;
1156       break;
1157     case MS1_OPERAND_FBINCR :
1158       value = fields->f_fbincr;
1159       break;
1160     case MS1_OPERAND_FRDR :
1161       value = fields->f_dr;
1162       break;
1163     case MS1_OPERAND_FRDRRR :
1164       value = fields->f_drrr;
1165       break;
1166     case MS1_OPERAND_FRSR1 :
1167       value = fields->f_sr1;
1168       break;
1169     case MS1_OPERAND_FRSR2 :
1170       value = fields->f_sr2;
1171       break;
1172     case MS1_OPERAND_ID :
1173       value = fields->f_id;
1174       break;
1175     case MS1_OPERAND_IMM16 :
1176       value = fields->f_imm16s;
1177       break;
1178     case MS1_OPERAND_IMM16O :
1179       value = fields->f_imm16s;
1180       break;
1181     case MS1_OPERAND_IMM16Z :
1182       value = fields->f_imm16u;
1183       break;
1184     case MS1_OPERAND_INCAMT :
1185       value = fields->f_incamt;
1186       break;
1187     case MS1_OPERAND_INCR :
1188       value = fields->f_incr;
1189       break;
1190     case MS1_OPERAND_LENGTH :
1191       value = fields->f_length;
1192       break;
1193     case MS1_OPERAND_MASK :
1194       value = fields->f_mask;
1195       break;
1196     case MS1_OPERAND_MASK1 :
1197       value = fields->f_mask1;
1198       break;
1199     case MS1_OPERAND_MODE :
1200       value = fields->f_mode;
1201       break;
1202     case MS1_OPERAND_PERM :
1203       value = fields->f_perm;
1204       break;
1205     case MS1_OPERAND_RBBC :
1206       value = fields->f_rbbc;
1207       break;
1208     case MS1_OPERAND_RC :
1209       value = fields->f_rc;
1210       break;
1211     case MS1_OPERAND_RC1 :
1212       value = fields->f_rc1;
1213       break;
1214     case MS1_OPERAND_RC2 :
1215       value = fields->f_rc2;
1216       break;
1217     case MS1_OPERAND_RCNUM :
1218       value = fields->f_rcnum;
1219       break;
1220     case MS1_OPERAND_RDA :
1221       value = fields->f_rda;
1222       break;
1223     case MS1_OPERAND_ROWNUM :
1224       value = fields->f_rownum;
1225       break;
1226     case MS1_OPERAND_ROWNUM1 :
1227       value = fields->f_rownum1;
1228       break;
1229     case MS1_OPERAND_ROWNUM2 :
1230       value = fields->f_rownum2;
1231       break;
1232     case MS1_OPERAND_SIZE :
1233       value = fields->f_size;
1234       break;
1235     case MS1_OPERAND_TYPE :
1236       value = fields->f_type;
1237       break;
1238     case MS1_OPERAND_WR :
1239       value = fields->f_wr;
1240       break;
1241     case MS1_OPERAND_XMODE :
1242       value = fields->f_xmode;
1243       break;
1244
1245     default :
1246       /* xgettext:c-format */
1247       fprintf (stderr, _("Unrecognized field %d while getting vma operand.\n"),
1248                        opindex);
1249       abort ();
1250   }
1251
1252   return value;
1253 }
1254
1255 void ms1_cgen_set_int_operand  (CGEN_CPU_DESC, int, CGEN_FIELDS *, int);
1256 void ms1_cgen_set_vma_operand  (CGEN_CPU_DESC, int, CGEN_FIELDS *, bfd_vma);
1257
1258 /* Stuffing values in cgen_fields is handled by a collection of functions.
1259    They are distinguished by the type of the VALUE argument they accept.
1260    TODO: floating point, inlining support, remove cases where argument type
1261    not appropriate.  */
1262
1263 void
1264 ms1_cgen_set_int_operand (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
1265                              int opindex,
1266                              CGEN_FIELDS * fields,
1267                              int value)
1268 {
1269   switch (opindex)
1270     {
1271     case MS1_OPERAND_A23 :
1272       fields->f_a23 = value;
1273       break;
1274     case MS1_OPERAND_BALL :
1275       fields->f_ball = value;
1276       break;
1277     case MS1_OPERAND_BALL2 :
1278       fields->f_ball2 = value;
1279       break;
1280     case MS1_OPERAND_BANKADDR :
1281       fields->f_bankaddr = value;
1282       break;
1283     case MS1_OPERAND_BRC :
1284       fields->f_brc = value;
1285       break;
1286     case MS1_OPERAND_BRC2 :
1287       fields->f_brc2 = value;
1288       break;
1289     case MS1_OPERAND_CBRB :
1290       fields->f_cbrb = value;
1291       break;
1292     case MS1_OPERAND_CBS :
1293       fields->f_cbs = value;
1294       break;
1295     case MS1_OPERAND_CBX :
1296       fields->f_cbx = value;
1297       break;
1298     case MS1_OPERAND_CCB :
1299       fields->f_ccb = value;
1300       break;
1301     case MS1_OPERAND_CDB :
1302       fields->f_cdb = value;
1303       break;
1304     case MS1_OPERAND_CELL :
1305       fields->f_cell = value;
1306       break;
1307     case MS1_OPERAND_COLNUM :
1308       fields->f_colnum = value;
1309       break;
1310     case MS1_OPERAND_CONTNUM :
1311       fields->f_contnum = value;
1312       break;
1313     case MS1_OPERAND_CR :
1314       fields->f_cr = value;
1315       break;
1316     case MS1_OPERAND_CTXDISP :
1317       fields->f_ctxdisp = value;
1318       break;
1319     case MS1_OPERAND_DUP :
1320       fields->f_dup = value;
1321       break;
1322     case MS1_OPERAND_FBDISP :
1323       fields->f_fbdisp = value;
1324       break;
1325     case MS1_OPERAND_FBINCR :
1326       fields->f_fbincr = value;
1327       break;
1328     case MS1_OPERAND_FRDR :
1329       fields->f_dr = value;
1330       break;
1331     case MS1_OPERAND_FRDRRR :
1332       fields->f_drrr = value;
1333       break;
1334     case MS1_OPERAND_FRSR1 :
1335       fields->f_sr1 = value;
1336       break;
1337     case MS1_OPERAND_FRSR2 :
1338       fields->f_sr2 = value;
1339       break;
1340     case MS1_OPERAND_ID :
1341       fields->f_id = value;
1342       break;
1343     case MS1_OPERAND_IMM16 :
1344       fields->f_imm16s = value;
1345       break;
1346     case MS1_OPERAND_IMM16O :
1347       fields->f_imm16s = value;
1348       break;
1349     case MS1_OPERAND_IMM16Z :
1350       fields->f_imm16u = value;
1351       break;
1352     case MS1_OPERAND_INCAMT :
1353       fields->f_incamt = value;
1354       break;
1355     case MS1_OPERAND_INCR :
1356       fields->f_incr = value;
1357       break;
1358     case MS1_OPERAND_LENGTH :
1359       fields->f_length = value;
1360       break;
1361     case MS1_OPERAND_MASK :
1362       fields->f_mask = value;
1363       break;
1364     case MS1_OPERAND_MASK1 :
1365       fields->f_mask1 = value;
1366       break;
1367     case MS1_OPERAND_MODE :
1368       fields->f_mode = value;
1369       break;
1370     case MS1_OPERAND_PERM :
1371       fields->f_perm = value;
1372       break;
1373     case MS1_OPERAND_RBBC :
1374       fields->f_rbbc = value;
1375       break;
1376     case MS1_OPERAND_RC :
1377       fields->f_rc = value;
1378       break;
1379     case MS1_OPERAND_RC1 :
1380       fields->f_rc1 = value;
1381       break;
1382     case MS1_OPERAND_RC2 :
1383       fields->f_rc2 = value;
1384       break;
1385     case MS1_OPERAND_RCNUM :
1386       fields->f_rcnum = value;
1387       break;
1388     case MS1_OPERAND_RDA :
1389       fields->f_rda = value;
1390       break;
1391     case MS1_OPERAND_ROWNUM :
1392       fields->f_rownum = value;
1393       break;
1394     case MS1_OPERAND_ROWNUM1 :
1395       fields->f_rownum1 = value;
1396       break;
1397     case MS1_OPERAND_ROWNUM2 :
1398       fields->f_rownum2 = value;
1399       break;
1400     case MS1_OPERAND_SIZE :
1401       fields->f_size = value;
1402       break;
1403     case MS1_OPERAND_TYPE :
1404       fields->f_type = value;
1405       break;
1406     case MS1_OPERAND_WR :
1407       fields->f_wr = value;
1408       break;
1409     case MS1_OPERAND_XMODE :
1410       fields->f_xmode = value;
1411       break;
1412
1413     default :
1414       /* xgettext:c-format */
1415       fprintf (stderr, _("Unrecognized field %d while setting int operand.\n"),
1416                        opindex);
1417       abort ();
1418   }
1419 }
1420
1421 void
1422 ms1_cgen_set_vma_operand (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
1423                              int opindex,
1424                              CGEN_FIELDS * fields,
1425                              bfd_vma value)
1426 {
1427   switch (opindex)
1428     {
1429     case MS1_OPERAND_A23 :
1430       fields->f_a23 = value;
1431       break;
1432     case MS1_OPERAND_BALL :
1433       fields->f_ball = value;
1434       break;
1435     case MS1_OPERAND_BALL2 :
1436       fields->f_ball2 = value;
1437       break;
1438     case MS1_OPERAND_BANKADDR :
1439       fields->f_bankaddr = value;
1440       break;
1441     case MS1_OPERAND_BRC :
1442       fields->f_brc = value;
1443       break;
1444     case MS1_OPERAND_BRC2 :
1445       fields->f_brc2 = value;
1446       break;
1447     case MS1_OPERAND_CBRB :
1448       fields->f_cbrb = value;
1449       break;
1450     case MS1_OPERAND_CBS :
1451       fields->f_cbs = value;
1452       break;
1453     case MS1_OPERAND_CBX :
1454       fields->f_cbx = value;
1455       break;
1456     case MS1_OPERAND_CCB :
1457       fields->f_ccb = value;
1458       break;
1459     case MS1_OPERAND_CDB :
1460       fields->f_cdb = value;
1461       break;
1462     case MS1_OPERAND_CELL :
1463       fields->f_cell = value;
1464       break;
1465     case MS1_OPERAND_COLNUM :
1466       fields->f_colnum = value;
1467       break;
1468     case MS1_OPERAND_CONTNUM :
1469       fields->f_contnum = value;
1470       break;
1471     case MS1_OPERAND_CR :
1472       fields->f_cr = value;
1473       break;
1474     case MS1_OPERAND_CTXDISP :
1475       fields->f_ctxdisp = value;
1476       break;
1477     case MS1_OPERAND_DUP :
1478       fields->f_dup = value;
1479       break;
1480     case MS1_OPERAND_FBDISP :
1481       fields->f_fbdisp = value;
1482       break;
1483     case MS1_OPERAND_FBINCR :
1484       fields->f_fbincr = value;
1485       break;
1486     case MS1_OPERAND_FRDR :
1487       fields->f_dr = value;
1488       break;
1489     case MS1_OPERAND_FRDRRR :
1490       fields->f_drrr = value;
1491       break;
1492     case MS1_OPERAND_FRSR1 :
1493       fields->f_sr1 = value;
1494       break;
1495     case MS1_OPERAND_FRSR2 :
1496       fields->f_sr2 = value;
1497       break;
1498     case MS1_OPERAND_ID :
1499       fields->f_id = value;
1500       break;
1501     case MS1_OPERAND_IMM16 :
1502       fields->f_imm16s = value;
1503       break;
1504     case MS1_OPERAND_IMM16O :
1505       fields->f_imm16s = value;
1506       break;
1507     case MS1_OPERAND_IMM16Z :
1508       fields->f_imm16u = value;
1509       break;
1510     case MS1_OPERAND_INCAMT :
1511       fields->f_incamt = value;
1512       break;
1513     case MS1_OPERAND_INCR :
1514       fields->f_incr = value;
1515       break;
1516     case MS1_OPERAND_LENGTH :
1517       fields->f_length = value;
1518       break;
1519     case MS1_OPERAND_MASK :
1520       fields->f_mask = value;
1521       break;
1522     case MS1_OPERAND_MASK1 :
1523       fields->f_mask1 = value;
1524       break;
1525     case MS1_OPERAND_MODE :
1526       fields->f_mode = value;
1527       break;
1528     case MS1_OPERAND_PERM :
1529       fields->f_perm = value;
1530       break;
1531     case MS1_OPERAND_RBBC :
1532       fields->f_rbbc = value;
1533       break;
1534     case MS1_OPERAND_RC :
1535       fields->f_rc = value;
1536       break;
1537     case MS1_OPERAND_RC1 :
1538       fields->f_rc1 = value;
1539       break;
1540     case MS1_OPERAND_RC2 :
1541       fields->f_rc2 = value;
1542       break;
1543     case MS1_OPERAND_RCNUM :
1544       fields->f_rcnum = value;
1545       break;
1546     case MS1_OPERAND_RDA :
1547       fields->f_rda = value;
1548       break;
1549     case MS1_OPERAND_ROWNUM :
1550       fields->f_rownum = value;
1551       break;
1552     case MS1_OPERAND_ROWNUM1 :
1553       fields->f_rownum1 = value;
1554       break;
1555     case MS1_OPERAND_ROWNUM2 :
1556       fields->f_rownum2 = value;
1557       break;
1558     case MS1_OPERAND_SIZE :
1559       fields->f_size = value;
1560       break;
1561     case MS1_OPERAND_TYPE :
1562       fields->f_type = value;
1563       break;
1564     case MS1_OPERAND_WR :
1565       fields->f_wr = value;
1566       break;
1567     case MS1_OPERAND_XMODE :
1568       fields->f_xmode = value;
1569       break;
1570
1571     default :
1572       /* xgettext:c-format */
1573       fprintf (stderr, _("Unrecognized field %d while setting vma operand.\n"),
1574                        opindex);
1575       abort ();
1576   }
1577 }
1578
1579 /* Function to call before using the instruction builder tables.  */
1580
1581 void
1582 ms1_cgen_init_ibld_table (CGEN_CPU_DESC cd)
1583 {
1584   cd->insert_handlers = & ms1_cgen_insert_handlers[0];
1585   cd->extract_handlers = & ms1_cgen_extract_handlers[0];
1586
1587   cd->insert_operand = ms1_cgen_insert_operand;
1588   cd->extract_operand = ms1_cgen_extract_operand;
1589
1590   cd->get_int_operand = ms1_cgen_get_int_operand;
1591   cd->set_int_operand = ms1_cgen_set_int_operand;
1592   cd->get_vma_operand = ms1_cgen_get_vma_operand;
1593   cd->set_vma_operand = ms1_cgen_set_vma_operand;
1594 }