This commit was generated by cvs2svn to track changes on a CVS vendor
[platform/upstream/binutils.git] / opcodes / m32r-ibld.c
1 /* Instruction building/extraction support for m32r. -*- 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 (C) 1996, 1997, 1998, 1999 Free Software Foundation, Inc.
7
8 This file is part of the GNU Binutils and GDB, the GNU debugger.
9
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2, or (at your option)
13 any later version.
14
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18 GNU General Public License for more details.
19
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software Foundation, Inc.,
22 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
23
24 /* ??? Eventually more and more of this stuff can go to cpu-independent files.
25    Keep that in mind.  */
26
27 #include "sysdep.h"
28 #include <ctype.h>
29 #include <stdio.h>
30 #include "ansidecl.h"
31 #include "dis-asm.h"
32 #include "bfd.h"
33 #include "symcat.h"
34 #include "m32r-desc.h"
35 #include "m32r-opc.h"
36 #include "opintl.h"
37
38 #undef min
39 #define min(a,b) ((a) < (b) ? (a) : (b))
40 #undef max
41 #define max(a,b) ((a) > (b) ? (a) : (b))
42
43 /* Used by the ifield rtx function.  */
44 #define FLD(f) (fields->f)
45
46 static const char * insert_normal
47      PARAMS ((CGEN_CPU_DESC, long, unsigned int, unsigned int, unsigned int,
48               unsigned int, unsigned int, unsigned int, CGEN_INSN_BYTES_PTR));
49 static const char * insert_insn_normal
50      PARAMS ((CGEN_CPU_DESC, const CGEN_INSN *,
51               CGEN_FIELDS *, CGEN_INSN_BYTES_PTR, bfd_vma));
52
53 static int extract_normal
54      PARAMS ((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      PARAMS ((CGEN_CPU_DESC, const CGEN_INSN *, CGEN_EXTRACT_INFO *,
59               CGEN_INSN_INT, CGEN_FIELDS *, bfd_vma));
60 \f
61 /* Operand insertion.  */
62
63 #if ! CGEN_INT_INSN_P
64
65 /* Subroutine of insert_normal.  */
66
67 static CGEN_INLINE void
68 insert_1 (cd, value, start, length, word_length, bufp)
69      CGEN_CPU_DESC cd;
70      unsigned long value;
71      int start,length,word_length;
72      unsigned char *bufp;
73 {
74   unsigned long x,mask;
75   int shift;
76   int big_p = CGEN_CPU_INSN_ENDIAN (cd) == CGEN_ENDIAN_BIG;
77
78   switch (word_length)
79     {
80     case 8:
81       x = *bufp;
82       break;
83     case 16:
84       if (big_p)
85         x = bfd_getb16 (bufp);
86       else
87         x = bfd_getl16 (bufp);
88       break;
89     case 24:
90       /* ??? This may need reworking as these cases don't necessarily
91          want the first byte and the last two bytes handled like this.  */
92       if (big_p)
93         x = (bufp[0] << 16) | bfd_getb16 (bufp + 1);
94       else
95         x = bfd_getl16 (bufp) | (bufp[2] << 16);
96       break;
97     case 32:
98       if (big_p)
99         x = bfd_getb32 (bufp);
100       else
101         x = bfd_getl32 (bufp);
102       break;
103     default :
104       abort ();
105     }
106
107   /* Written this way to avoid undefined behaviour.  */
108   mask = (((1L << (length - 1)) - 1) << 1) | 1;
109   if (CGEN_INSN_LSB0_P)
110     shift = (start + 1) - length;
111   else
112     shift = (word_length - (start + length));
113   x = (x & ~(mask << shift)) | ((value & mask) << shift);
114
115   switch (word_length)
116     {
117     case 8:
118       *bufp = x;
119       break;
120     case 16:
121       if (big_p)
122         bfd_putb16 (x, bufp);
123       else
124         bfd_putl16 (x, bufp);
125       break;
126     case 24:
127       /* ??? This may need reworking as these cases don't necessarily
128          want the first byte and the last two bytes handled like this.  */
129       if (big_p)
130         {
131           bufp[0] = x >> 16;
132           bfd_putb16 (x, bufp + 1);
133         }
134       else
135         {
136           bfd_putl16 (x, bufp);
137           bufp[2] = x >> 16;
138         }
139       break;
140     case 32:
141       if (big_p)
142         bfd_putb32 (x, bufp);
143       else
144         bfd_putl32 (x, bufp);
145       break;
146     default :
147       abort ();
148     }
149 }
150
151 #endif /* ! CGEN_INT_INSN_P */
152
153 /* Default insertion routine.
154
155    ATTRS is a mask of the boolean attributes.
156    WORD_OFFSET is the offset in bits from the start of the insn of the value.
157    WORD_LENGTH is the length of the word in bits in which the value resides.
158    START is the starting bit number in the word, architecture origin.
159    LENGTH is the length of VALUE in bits.
160    TOTAL_LENGTH is the total length of the insn in bits.
161
162    The result is an error message or NULL if success.  */
163
164 /* ??? This duplicates functionality with bfd's howto table and
165    bfd_install_relocation.  */
166 /* ??? This doesn't handle bfd_vma's.  Create another function when
167    necessary.  */
168
169 static const char *
170 insert_normal (cd, value, attrs, word_offset, start, length, word_length,
171                total_length, buffer)
172      CGEN_CPU_DESC cd;
173      long value;
174      unsigned int attrs;
175      unsigned int word_offset, start, length, word_length, total_length;
176      CGEN_INSN_BYTES_PTR buffer;
177 {
178   static char errbuf[100];
179   /* Written this way to avoid undefined behaviour.  */
180   unsigned long mask = (((1L << (length - 1)) - 1) << 1) | 1;
181
182   /* If LENGTH is zero, this operand doesn't contribute to the value.  */
183   if (length == 0)
184     return NULL;
185
186   if (CGEN_INT_INSN_P
187       && word_offset != 0)
188     abort ();
189
190   if (word_length > 32)
191     abort ();
192
193   /* For architectures with insns smaller than the base-insn-bitsize,
194      word_length may be too big.  */
195   if (cd->min_insn_bitsize < cd->base_insn_bitsize)
196     {
197       if (word_offset == 0
198           && word_length > total_length)
199         word_length = total_length;
200     }
201
202   /* Ensure VALUE will fit.  */
203   if (! CGEN_BOOL_ATTR (attrs, CGEN_IFLD_SIGNED))
204     {
205       unsigned long maxval = mask;
206       if ((unsigned long) value > maxval)
207         {
208           /* xgettext:c-format */
209           sprintf (errbuf,
210                    _("operand out of range (%lu not between 0 and %lu)"),
211                    value, maxval);
212           return errbuf;
213         }
214     }
215   else
216     {
217       long minval = - (1L << (length - 1));
218       long maxval = (1L << (length - 1)) - 1;
219       if (value < minval || value > maxval)
220         {
221           sprintf
222             /* xgettext:c-format */
223             (errbuf, _("operand out of range (%ld not between %ld and %ld)"),
224              value, minval, maxval);
225           return errbuf;
226         }
227     }
228
229 #if CGEN_INT_INSN_P
230
231   {
232     int shift;
233
234     if (CGEN_INSN_LSB0_P)
235       shift = (start + 1) - length;
236     else
237       shift = word_length - (start + length);
238     *buffer = (*buffer & ~(mask << shift)) | ((value & mask) << shift);
239   }
240
241 #else /* ! CGEN_INT_INSN_P */
242
243   {
244     unsigned char *bufp = (unsigned char *) buffer + word_offset / 8;
245
246     insert_1 (cd, value, start, length, word_length, bufp);
247   }
248
249 #endif /* ! CGEN_INT_INSN_P */
250
251   return NULL;
252 }
253
254 /* Default insn builder (insert handler).
255    The instruction is recorded in CGEN_INT_INSN_P byte order
256    (meaning that if CGEN_INT_INSN_P BUFFER is an int * and thus the value is
257    recorded in host byte order, otherwise BUFFER is an array of bytes and the
258    value is recorded in target byte order).
259    The result is an error message or NULL if success.  */
260
261 static const char *
262 insert_insn_normal (cd, insn, fields, buffer, pc)
263      CGEN_CPU_DESC cd;
264      const CGEN_INSN * insn;
265      CGEN_FIELDS * fields;
266      CGEN_INSN_BYTES_PTR buffer;
267      bfd_vma pc;
268 {
269   const CGEN_SYNTAX *syntax = CGEN_INSN_SYNTAX (insn);
270   unsigned long value;
271   const unsigned char * syn;
272
273   CGEN_INIT_INSERT (cd);
274   value = CGEN_INSN_BASE_VALUE (insn);
275
276   /* If we're recording insns as numbers (rather than a string of bytes),
277      target byte order handling is deferred until later.  */
278
279 #if CGEN_INT_INSN_P
280
281   *buffer = value;
282
283 #else
284
285   cgen_put_insn_value (cd, buffer, min (cd->base_insn_bitsize,
286                                         CGEN_FIELDS_BITSIZE (fields)),
287                        value);
288
289 #endif /* ! CGEN_INT_INSN_P */
290
291   /* ??? It would be better to scan the format's fields.
292      Still need to be able to insert a value based on the operand though;
293      e.g. storing a branch displacement that got resolved later.
294      Needs more thought first.  */
295
296   for (syn = CGEN_SYNTAX_STRING (syntax); * syn != '\0'; ++ syn)
297     {
298       const char *errmsg;
299
300       if (CGEN_SYNTAX_CHAR_P (* syn))
301         continue;
302
303       errmsg = (* cd->insert_operand) (cd, CGEN_SYNTAX_FIELD (*syn),
304                                        fields, buffer, pc);
305       if (errmsg)
306         return errmsg;
307     }
308
309   return NULL;
310 }
311 \f
312 /* Operand extraction.  */
313
314 #if ! CGEN_INT_INSN_P
315
316 /* Subroutine of extract_normal.
317    Ensure sufficient bytes are cached in EX_INFO.
318    OFFSET is the offset in bytes from the start of the insn of the value.
319    BYTES is the length of the needed value.
320    Returns 1 for success, 0 for failure.  */
321
322 static CGEN_INLINE int
323 fill_cache (cd, ex_info, offset, bytes, pc)
324      CGEN_CPU_DESC cd;
325      CGEN_EXTRACT_INFO *ex_info;
326      int offset, bytes;
327      bfd_vma pc;
328 {
329   /* It's doubtful that the middle part has already been fetched so
330      we don't optimize that case.  kiss.  */
331   int mask;
332   disassemble_info *info = (disassemble_info *) ex_info->dis_info;
333
334   /* First do a quick check.  */
335   mask = (1 << bytes) - 1;
336   if (((ex_info->valid >> offset) & mask) == mask)
337     return 1;
338
339   /* Search for the first byte we need to read.  */
340   for (mask = 1 << offset; bytes > 0; --bytes, ++offset, mask <<= 1)
341     if (! (mask & ex_info->valid))
342       break;
343
344   if (bytes)
345     {
346       int status;
347
348       pc += offset;
349       status = (*info->read_memory_func)
350         (pc, ex_info->insn_bytes + offset, bytes, info);
351
352       if (status != 0)
353         {
354           (*info->memory_error_func) (status, pc, info);
355           return 0;
356         }
357
358       ex_info->valid |= ((1 << bytes) - 1) << offset;
359     }
360
361   return 1;
362 }
363
364 /* Subroutine of extract_normal.  */
365
366 static CGEN_INLINE long
367 extract_1 (cd, ex_info, start, length, word_length, bufp, pc)
368      CGEN_CPU_DESC cd;
369      CGEN_EXTRACT_INFO *ex_info;
370      int start,length,word_length;
371      unsigned char *bufp;
372      bfd_vma pc;
373 {
374   unsigned long x,mask;
375   int shift;
376   int big_p = CGEN_CPU_INSN_ENDIAN (cd) == CGEN_ENDIAN_BIG;
377
378   switch (word_length)
379     {
380     case 8:
381       x = *bufp;
382       break;
383     case 16:
384       if (big_p)
385         x = bfd_getb16 (bufp);
386       else
387         x = bfd_getl16 (bufp);
388       break;
389     case 24:
390       /* ??? This may need reworking as these cases don't necessarily
391          want the first byte and the last two bytes handled like this.  */
392       if (big_p)
393         x = (bufp[0] << 16) | bfd_getb16 (bufp + 1);
394       else
395         x = bfd_getl16 (bufp) | (bufp[2] << 16);
396       break;
397     case 32:
398       if (big_p)
399         x = bfd_getb32 (bufp);
400       else
401         x = bfd_getl32 (bufp);
402       break;
403     default :
404       abort ();
405     }
406
407   /* Written this way to avoid undefined behaviour.  */
408   mask = (((1L << (length - 1)) - 1) << 1) | 1;
409   if (CGEN_INSN_LSB0_P)
410     shift = (start + 1) - length;
411   else
412     shift = (word_length - (start + length));
413   return (x >> shift) & mask;
414 }
415
416 #endif /* ! CGEN_INT_INSN_P */
417
418 /* Default extraction routine.
419
420    INSN_VALUE is the first base_insn_bitsize bits of the insn in host order,
421    or sometimes less for cases like the m32r where the base insn size is 32
422    but some insns are 16 bits.
423    ATTRS is a mask of the boolean attributes.  We only need `SIGNED',
424    but for generality we take a bitmask of all of them.
425    WORD_OFFSET is the offset in bits from the start of the insn of the value.
426    WORD_LENGTH is the length of the word in bits in which the value resides.
427    START is the starting bit number in the word, architecture origin.
428    LENGTH is the length of VALUE in bits.
429    TOTAL_LENGTH is the total length of the insn in bits.
430
431    Returns 1 for success, 0 for failure.  */
432
433 /* ??? The return code isn't properly used.  wip.  */
434
435 /* ??? This doesn't handle bfd_vma's.  Create another function when
436    necessary.  */
437
438 static int
439 extract_normal (cd, ex_info, insn_value, attrs, word_offset, start, length,
440                 word_length, total_length, pc, valuep)
441      CGEN_CPU_DESC cd;
442      CGEN_EXTRACT_INFO *ex_info;
443      CGEN_INSN_INT insn_value;
444      unsigned int attrs;
445      unsigned int word_offset, start, length, word_length, total_length;
446      bfd_vma pc;
447      long *valuep;
448 {
449   CGEN_INSN_INT value;
450
451   /* If LENGTH is zero, this operand doesn't contribute to the value
452      so give it a standard value of zero.  */
453   if (length == 0)
454     {
455       *valuep = 0;
456       return 1;
457     }
458
459   if (CGEN_INT_INSN_P
460       && word_offset != 0)
461     abort ();
462
463   if (word_length > 32)
464     abort ();
465
466   /* For architectures with insns smaller than the insn-base-bitsize,
467      word_length may be too big.  */
468   if (cd->min_insn_bitsize < cd->base_insn_bitsize)
469     {
470       if (word_offset == 0
471           && word_length > total_length)
472         word_length = total_length;
473     }
474
475   /* Does the value reside in INSN_VALUE?  */
476
477   if (word_offset == 0)
478     {
479       /* Written this way to avoid undefined behaviour.  */
480       CGEN_INSN_INT mask = (((1L << (length - 1)) - 1) << 1) | 1;
481
482       if (CGEN_INSN_LSB0_P)
483         value = insn_value >> ((start + 1) - length);
484       else
485         value = insn_value >> (word_length - (start + length));
486       value &= mask;
487       /* sign extend? */
488       if (CGEN_BOOL_ATTR (attrs, CGEN_IFLD_SIGNED)
489           && (value & (1L << (length - 1))))
490         value |= ~mask;
491     }
492
493 #if ! CGEN_INT_INSN_P
494
495   else
496     {
497       unsigned char *bufp = ex_info->insn_bytes + word_offset / 8;
498
499       if (word_length > 32)
500         abort ();
501
502       if (fill_cache (cd, ex_info, word_offset / 8, word_length / 8, pc) == 0)
503         return 0;
504
505       value = extract_1 (cd, ex_info, start, length, word_length, bufp, pc);
506     }
507
508 #endif /* ! CGEN_INT_INSN_P */
509
510   *valuep = value;
511
512   return 1;
513 }
514
515 /* Default insn extractor.
516
517    INSN_VALUE is the first base_insn_bitsize bits, translated to host order.
518    The extracted fields are stored in FIELDS.
519    EX_INFO is used to handle reading variable length insns.
520    Return the length of the insn in bits, or 0 if no match,
521    or -1 if an error occurs fetching data (memory_error_func will have
522    been called).  */
523
524 static int
525 extract_insn_normal (cd, insn, ex_info, insn_value, fields, pc)
526      CGEN_CPU_DESC cd;
527      const CGEN_INSN *insn;
528      CGEN_EXTRACT_INFO *ex_info;
529      CGEN_INSN_INT insn_value;
530      CGEN_FIELDS *fields;
531      bfd_vma pc;
532 {
533   const CGEN_SYNTAX *syntax = CGEN_INSN_SYNTAX (insn);
534   const unsigned char *syn;
535
536   CGEN_FIELDS_BITSIZE (fields) = CGEN_INSN_BITSIZE (insn);
537
538   CGEN_INIT_EXTRACT (cd);
539
540   for (syn = CGEN_SYNTAX_STRING (syntax); *syn; ++syn)
541     {
542       int length;
543
544       if (CGEN_SYNTAX_CHAR_P (*syn))
545         continue;
546
547       length = (* cd->extract_operand) (cd, CGEN_SYNTAX_FIELD (*syn),
548                                         ex_info, insn_value, fields, pc);
549       if (length <= 0)
550         return length;
551     }
552
553   /* We recognized and successfully extracted this insn.  */
554   return CGEN_INSN_BITSIZE (insn);
555 }
556 \f
557 /* machine generated code added here */
558
559 /* Main entry point for operand insertion.
560
561    This function is basically just a big switch statement.  Earlier versions
562    used tables to look up the function to use, but
563    - if the table contains both assembler and disassembler functions then
564      the disassembler contains much of the assembler and vice-versa,
565    - there's a lot of inlining possibilities as things grow,
566    - using a switch statement avoids the function call overhead.
567
568    This function could be moved into `parse_insn_normal', but keeping it
569    separate makes clear the interface between `parse_insn_normal' and each of
570    the handlers.  It's also needed by GAS to insert operands that couldn't be
571    resolved during parsing.
572 */
573
574 const char *
575 m32r_cgen_insert_operand (cd, opindex, fields, buffer, pc)
576      CGEN_CPU_DESC cd;
577      int opindex;
578      CGEN_FIELDS * fields;
579      CGEN_INSN_BYTES_PTR buffer;
580      bfd_vma pc;
581 {
582   const char * errmsg = NULL;
583   unsigned int total_length = CGEN_FIELDS_BITSIZE (fields);
584
585   switch (opindex)
586     {
587     case M32R_OPERAND_ACC :
588       errmsg = insert_normal (cd, fields->f_acc, 0, 0, 8, 1, 32, total_length, buffer);
589       break;
590     case M32R_OPERAND_ACCD :
591       errmsg = insert_normal (cd, fields->f_accd, 0, 0, 4, 2, 32, total_length, buffer);
592       break;
593     case M32R_OPERAND_ACCS :
594       errmsg = insert_normal (cd, fields->f_accs, 0, 0, 12, 2, 32, total_length, buffer);
595       break;
596     case M32R_OPERAND_DCR :
597       errmsg = insert_normal (cd, fields->f_r1, 0, 0, 4, 4, 32, total_length, buffer);
598       break;
599     case M32R_OPERAND_DISP16 :
600       {
601         long value = fields->f_disp16;
602         value = ((int) (((value) - (pc))) >> (2));
603         errmsg = insert_normal (cd, value, 0|(1<<CGEN_IFLD_SIGNED)|(1<<CGEN_IFLD_RELOC)|(1<<CGEN_IFLD_PCREL_ADDR), 0, 16, 16, 32, total_length, buffer);
604       }
605       break;
606     case M32R_OPERAND_DISP24 :
607       {
608         long value = fields->f_disp24;
609         value = ((int) (((value) - (pc))) >> (2));
610         errmsg = insert_normal (cd, value, 0|(1<<CGEN_IFLD_SIGNED)|(1<<CGEN_IFLD_RELOC)|(1<<CGEN_IFLD_PCREL_ADDR), 0, 8, 24, 32, total_length, buffer);
611       }
612       break;
613     case M32R_OPERAND_DISP8 :
614       {
615         long value = fields->f_disp8;
616         value = ((int) (((value) - (((pc) & (-4))))) >> (2));
617         errmsg = insert_normal (cd, value, 0|(1<<CGEN_IFLD_SIGNED)|(1<<CGEN_IFLD_RELOC)|(1<<CGEN_IFLD_PCREL_ADDR), 0, 8, 8, 32, total_length, buffer);
618       }
619       break;
620     case M32R_OPERAND_DR :
621       errmsg = insert_normal (cd, fields->f_r1, 0, 0, 4, 4, 32, total_length, buffer);
622       break;
623     case M32R_OPERAND_HASH :
624       break;
625     case M32R_OPERAND_HI16 :
626       errmsg = insert_normal (cd, fields->f_hi16, 0|(1<<CGEN_IFLD_SIGN_OPT), 0, 16, 16, 32, total_length, buffer);
627       break;
628     case M32R_OPERAND_IMM1 :
629       {
630         long value = fields->f_imm1;
631         value = ((value) - (1));
632         errmsg = insert_normal (cd, value, 0, 0, 15, 1, 32, total_length, buffer);
633       }
634       break;
635     case M32R_OPERAND_SCR :
636       errmsg = insert_normal (cd, fields->f_r2, 0, 0, 12, 4, 32, total_length, buffer);
637       break;
638     case M32R_OPERAND_SIMM16 :
639       errmsg = insert_normal (cd, fields->f_simm16, 0|(1<<CGEN_IFLD_SIGNED), 0, 16, 16, 32, total_length, buffer);
640       break;
641     case M32R_OPERAND_SIMM8 :
642       errmsg = insert_normal (cd, fields->f_simm8, 0|(1<<CGEN_IFLD_SIGNED), 0, 8, 8, 32, total_length, buffer);
643       break;
644     case M32R_OPERAND_SLO16 :
645       errmsg = insert_normal (cd, fields->f_simm16, 0|(1<<CGEN_IFLD_SIGNED), 0, 16, 16, 32, total_length, buffer);
646       break;
647     case M32R_OPERAND_SR :
648       errmsg = insert_normal (cd, fields->f_r2, 0, 0, 12, 4, 32, total_length, buffer);
649       break;
650     case M32R_OPERAND_SRC1 :
651       errmsg = insert_normal (cd, fields->f_r1, 0, 0, 4, 4, 32, total_length, buffer);
652       break;
653     case M32R_OPERAND_SRC2 :
654       errmsg = insert_normal (cd, fields->f_r2, 0, 0, 12, 4, 32, total_length, buffer);
655       break;
656     case M32R_OPERAND_UIMM16 :
657       errmsg = insert_normal (cd, fields->f_uimm16, 0, 0, 16, 16, 32, total_length, buffer);
658       break;
659     case M32R_OPERAND_UIMM24 :
660       errmsg = insert_normal (cd, fields->f_uimm24, 0|(1<<CGEN_IFLD_RELOC)|(1<<CGEN_IFLD_ABS_ADDR), 0, 8, 24, 32, total_length, buffer);
661       break;
662     case M32R_OPERAND_UIMM4 :
663       errmsg = insert_normal (cd, fields->f_uimm4, 0, 0, 12, 4, 32, total_length, buffer);
664       break;
665     case M32R_OPERAND_UIMM5 :
666       errmsg = insert_normal (cd, fields->f_uimm5, 0, 0, 11, 5, 32, total_length, buffer);
667       break;
668     case M32R_OPERAND_ULO16 :
669       errmsg = insert_normal (cd, fields->f_uimm16, 0, 0, 16, 16, 32, total_length, buffer);
670       break;
671
672     default :
673       /* xgettext:c-format */
674       fprintf (stderr, _("Unrecognized field %d while building insn.\n"),
675                opindex);
676       abort ();
677   }
678
679   return errmsg;
680 }
681
682 /* Main entry point for operand extraction.
683    The result is <= 0 for error, >0 for success.
684    ??? Actual values aren't well defined right now.
685
686    This function is basically just a big switch statement.  Earlier versions
687    used tables to look up the function to use, but
688    - if the table contains both assembler and disassembler functions then
689      the disassembler contains much of the assembler and vice-versa,
690    - there's a lot of inlining possibilities as things grow,
691    - using a switch statement avoids the function call overhead.
692
693    This function could be moved into `print_insn_normal', but keeping it
694    separate makes clear the interface between `print_insn_normal' and each of
695    the handlers.
696 */
697
698 int
699 m32r_cgen_extract_operand (cd, opindex, ex_info, insn_value, fields, pc)
700      CGEN_CPU_DESC cd;
701      int opindex;
702      CGEN_EXTRACT_INFO *ex_info;
703      CGEN_INSN_INT insn_value;
704      CGEN_FIELDS * fields;
705      bfd_vma pc;
706 {
707   /* Assume success (for those operands that are nops).  */
708   int length = 1;
709   unsigned int total_length = CGEN_FIELDS_BITSIZE (fields);
710
711   switch (opindex)
712     {
713     case M32R_OPERAND_ACC :
714       length = extract_normal (cd, ex_info, insn_value, 0, 0, 8, 1, 32, total_length, pc, & fields->f_acc);
715       break;
716     case M32R_OPERAND_ACCD :
717       length = extract_normal (cd, ex_info, insn_value, 0, 0, 4, 2, 32, total_length, pc, & fields->f_accd);
718       break;
719     case M32R_OPERAND_ACCS :
720       length = extract_normal (cd, ex_info, insn_value, 0, 0, 12, 2, 32, total_length, pc, & fields->f_accs);
721       break;
722     case M32R_OPERAND_DCR :
723       length = extract_normal (cd, ex_info, insn_value, 0, 0, 4, 4, 32, total_length, pc, & fields->f_r1);
724       break;
725     case M32R_OPERAND_DISP16 :
726       {
727         long value;
728         length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_SIGNED)|(1<<CGEN_IFLD_RELOC)|(1<<CGEN_IFLD_PCREL_ADDR), 0, 16, 16, 32, total_length, pc, & value);
729         value = ((((value) << (2))) + (pc));
730         fields->f_disp16 = value;
731       }
732       break;
733     case M32R_OPERAND_DISP24 :
734       {
735         long value;
736         length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_SIGNED)|(1<<CGEN_IFLD_RELOC)|(1<<CGEN_IFLD_PCREL_ADDR), 0, 8, 24, 32, total_length, pc, & value);
737         value = ((((value) << (2))) + (pc));
738         fields->f_disp24 = value;
739       }
740       break;
741     case M32R_OPERAND_DISP8 :
742       {
743         long value;
744         length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_SIGNED)|(1<<CGEN_IFLD_RELOC)|(1<<CGEN_IFLD_PCREL_ADDR), 0, 8, 8, 32, total_length, pc, & value);
745         value = ((((value) << (2))) + (((pc) & (-4))));
746         fields->f_disp8 = value;
747       }
748       break;
749     case M32R_OPERAND_DR :
750       length = extract_normal (cd, ex_info, insn_value, 0, 0, 4, 4, 32, total_length, pc, & fields->f_r1);
751       break;
752     case M32R_OPERAND_HASH :
753       break;
754     case M32R_OPERAND_HI16 :
755       length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_SIGN_OPT), 0, 16, 16, 32, total_length, pc, & fields->f_hi16);
756       break;
757     case M32R_OPERAND_IMM1 :
758       {
759         long value;
760         length = extract_normal (cd, ex_info, insn_value, 0, 0, 15, 1, 32, total_length, pc, & value);
761         value = ((value) + (1));
762         fields->f_imm1 = value;
763       }
764       break;
765     case M32R_OPERAND_SCR :
766       length = extract_normal (cd, ex_info, insn_value, 0, 0, 12, 4, 32, total_length, pc, & fields->f_r2);
767       break;
768     case M32R_OPERAND_SIMM16 :
769       length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_SIGNED), 0, 16, 16, 32, total_length, pc, & fields->f_simm16);
770       break;
771     case M32R_OPERAND_SIMM8 :
772       length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_SIGNED), 0, 8, 8, 32, total_length, pc, & fields->f_simm8);
773       break;
774     case M32R_OPERAND_SLO16 :
775       length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_SIGNED), 0, 16, 16, 32, total_length, pc, & fields->f_simm16);
776       break;
777     case M32R_OPERAND_SR :
778       length = extract_normal (cd, ex_info, insn_value, 0, 0, 12, 4, 32, total_length, pc, & fields->f_r2);
779       break;
780     case M32R_OPERAND_SRC1 :
781       length = extract_normal (cd, ex_info, insn_value, 0, 0, 4, 4, 32, total_length, pc, & fields->f_r1);
782       break;
783     case M32R_OPERAND_SRC2 :
784       length = extract_normal (cd, ex_info, insn_value, 0, 0, 12, 4, 32, total_length, pc, & fields->f_r2);
785       break;
786     case M32R_OPERAND_UIMM16 :
787       length = extract_normal (cd, ex_info, insn_value, 0, 0, 16, 16, 32, total_length, pc, & fields->f_uimm16);
788       break;
789     case M32R_OPERAND_UIMM24 :
790       length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_RELOC)|(1<<CGEN_IFLD_ABS_ADDR), 0, 8, 24, 32, total_length, pc, & fields->f_uimm24);
791       break;
792     case M32R_OPERAND_UIMM4 :
793       length = extract_normal (cd, ex_info, insn_value, 0, 0, 12, 4, 32, total_length, pc, & fields->f_uimm4);
794       break;
795     case M32R_OPERAND_UIMM5 :
796       length = extract_normal (cd, ex_info, insn_value, 0, 0, 11, 5, 32, total_length, pc, & fields->f_uimm5);
797       break;
798     case M32R_OPERAND_ULO16 :
799       length = extract_normal (cd, ex_info, insn_value, 0, 0, 16, 16, 32, total_length, pc, & fields->f_uimm16);
800       break;
801
802     default :
803       /* xgettext:c-format */
804       fprintf (stderr, _("Unrecognized field %d while decoding insn.\n"),
805                opindex);
806       abort ();
807     }
808
809   return length;
810 }
811
812 cgen_insert_fn * const m32r_cgen_insert_handlers[] = 
813 {
814   insert_insn_normal,
815 };
816
817 cgen_extract_fn * const m32r_cgen_extract_handlers[] = 
818 {
819   extract_insn_normal,
820 };
821
822 /* Getting values from cgen_fields is handled by a collection of functions.
823    They are distinguished by the type of the VALUE argument they return.
824    TODO: floating point, inlining support, remove cases where result type
825    not appropriate.  */
826
827 int
828 m32r_cgen_get_int_operand (cd, opindex, fields)
829      CGEN_CPU_DESC cd;
830      int opindex;
831      const CGEN_FIELDS * fields;
832 {
833   int value;
834
835   switch (opindex)
836     {
837     case M32R_OPERAND_ACC :
838       value = fields->f_acc;
839       break;
840     case M32R_OPERAND_ACCD :
841       value = fields->f_accd;
842       break;
843     case M32R_OPERAND_ACCS :
844       value = fields->f_accs;
845       break;
846     case M32R_OPERAND_DCR :
847       value = fields->f_r1;
848       break;
849     case M32R_OPERAND_DISP16 :
850       value = fields->f_disp16;
851       break;
852     case M32R_OPERAND_DISP24 :
853       value = fields->f_disp24;
854       break;
855     case M32R_OPERAND_DISP8 :
856       value = fields->f_disp8;
857       break;
858     case M32R_OPERAND_DR :
859       value = fields->f_r1;
860       break;
861     case M32R_OPERAND_HASH :
862       value = 0;
863       break;
864     case M32R_OPERAND_HI16 :
865       value = fields->f_hi16;
866       break;
867     case M32R_OPERAND_IMM1 :
868       value = fields->f_imm1;
869       break;
870     case M32R_OPERAND_SCR :
871       value = fields->f_r2;
872       break;
873     case M32R_OPERAND_SIMM16 :
874       value = fields->f_simm16;
875       break;
876     case M32R_OPERAND_SIMM8 :
877       value = fields->f_simm8;
878       break;
879     case M32R_OPERAND_SLO16 :
880       value = fields->f_simm16;
881       break;
882     case M32R_OPERAND_SR :
883       value = fields->f_r2;
884       break;
885     case M32R_OPERAND_SRC1 :
886       value = fields->f_r1;
887       break;
888     case M32R_OPERAND_SRC2 :
889       value = fields->f_r2;
890       break;
891     case M32R_OPERAND_UIMM16 :
892       value = fields->f_uimm16;
893       break;
894     case M32R_OPERAND_UIMM24 :
895       value = fields->f_uimm24;
896       break;
897     case M32R_OPERAND_UIMM4 :
898       value = fields->f_uimm4;
899       break;
900     case M32R_OPERAND_UIMM5 :
901       value = fields->f_uimm5;
902       break;
903     case M32R_OPERAND_ULO16 :
904       value = fields->f_uimm16;
905       break;
906
907     default :
908       /* xgettext:c-format */
909       fprintf (stderr, _("Unrecognized field %d while getting int operand.\n"),
910                        opindex);
911       abort ();
912   }
913
914   return value;
915 }
916
917 bfd_vma
918 m32r_cgen_get_vma_operand (cd, opindex, fields)
919      CGEN_CPU_DESC cd;
920      int opindex;
921      const CGEN_FIELDS * fields;
922 {
923   bfd_vma value;
924
925   switch (opindex)
926     {
927     case M32R_OPERAND_ACC :
928       value = fields->f_acc;
929       break;
930     case M32R_OPERAND_ACCD :
931       value = fields->f_accd;
932       break;
933     case M32R_OPERAND_ACCS :
934       value = fields->f_accs;
935       break;
936     case M32R_OPERAND_DCR :
937       value = fields->f_r1;
938       break;
939     case M32R_OPERAND_DISP16 :
940       value = fields->f_disp16;
941       break;
942     case M32R_OPERAND_DISP24 :
943       value = fields->f_disp24;
944       break;
945     case M32R_OPERAND_DISP8 :
946       value = fields->f_disp8;
947       break;
948     case M32R_OPERAND_DR :
949       value = fields->f_r1;
950       break;
951     case M32R_OPERAND_HASH :
952       value = 0;
953       break;
954     case M32R_OPERAND_HI16 :
955       value = fields->f_hi16;
956       break;
957     case M32R_OPERAND_IMM1 :
958       value = fields->f_imm1;
959       break;
960     case M32R_OPERAND_SCR :
961       value = fields->f_r2;
962       break;
963     case M32R_OPERAND_SIMM16 :
964       value = fields->f_simm16;
965       break;
966     case M32R_OPERAND_SIMM8 :
967       value = fields->f_simm8;
968       break;
969     case M32R_OPERAND_SLO16 :
970       value = fields->f_simm16;
971       break;
972     case M32R_OPERAND_SR :
973       value = fields->f_r2;
974       break;
975     case M32R_OPERAND_SRC1 :
976       value = fields->f_r1;
977       break;
978     case M32R_OPERAND_SRC2 :
979       value = fields->f_r2;
980       break;
981     case M32R_OPERAND_UIMM16 :
982       value = fields->f_uimm16;
983       break;
984     case M32R_OPERAND_UIMM24 :
985       value = fields->f_uimm24;
986       break;
987     case M32R_OPERAND_UIMM4 :
988       value = fields->f_uimm4;
989       break;
990     case M32R_OPERAND_UIMM5 :
991       value = fields->f_uimm5;
992       break;
993     case M32R_OPERAND_ULO16 :
994       value = fields->f_uimm16;
995       break;
996
997     default :
998       /* xgettext:c-format */
999       fprintf (stderr, _("Unrecognized field %d while getting vma operand.\n"),
1000                        opindex);
1001       abort ();
1002   }
1003
1004   return value;
1005 }
1006
1007 /* Stuffing values in cgen_fields is handled by a collection of functions.
1008    They are distinguished by the type of the VALUE argument they accept.
1009    TODO: floating point, inlining support, remove cases where argument type
1010    not appropriate.  */
1011
1012 void
1013 m32r_cgen_set_int_operand (cd, opindex, fields, value)
1014      CGEN_CPU_DESC cd;
1015      int opindex;
1016      CGEN_FIELDS * fields;
1017      int value;
1018 {
1019   switch (opindex)
1020     {
1021     case M32R_OPERAND_ACC :
1022       fields->f_acc = value;
1023       break;
1024     case M32R_OPERAND_ACCD :
1025       fields->f_accd = value;
1026       break;
1027     case M32R_OPERAND_ACCS :
1028       fields->f_accs = value;
1029       break;
1030     case M32R_OPERAND_DCR :
1031       fields->f_r1 = value;
1032       break;
1033     case M32R_OPERAND_DISP16 :
1034       fields->f_disp16 = value;
1035       break;
1036     case M32R_OPERAND_DISP24 :
1037       fields->f_disp24 = value;
1038       break;
1039     case M32R_OPERAND_DISP8 :
1040       fields->f_disp8 = value;
1041       break;
1042     case M32R_OPERAND_DR :
1043       fields->f_r1 = value;
1044       break;
1045     case M32R_OPERAND_HASH :
1046       break;
1047     case M32R_OPERAND_HI16 :
1048       fields->f_hi16 = value;
1049       break;
1050     case M32R_OPERAND_IMM1 :
1051       fields->f_imm1 = value;
1052       break;
1053     case M32R_OPERAND_SCR :
1054       fields->f_r2 = value;
1055       break;
1056     case M32R_OPERAND_SIMM16 :
1057       fields->f_simm16 = value;
1058       break;
1059     case M32R_OPERAND_SIMM8 :
1060       fields->f_simm8 = value;
1061       break;
1062     case M32R_OPERAND_SLO16 :
1063       fields->f_simm16 = value;
1064       break;
1065     case M32R_OPERAND_SR :
1066       fields->f_r2 = value;
1067       break;
1068     case M32R_OPERAND_SRC1 :
1069       fields->f_r1 = value;
1070       break;
1071     case M32R_OPERAND_SRC2 :
1072       fields->f_r2 = value;
1073       break;
1074     case M32R_OPERAND_UIMM16 :
1075       fields->f_uimm16 = value;
1076       break;
1077     case M32R_OPERAND_UIMM24 :
1078       fields->f_uimm24 = value;
1079       break;
1080     case M32R_OPERAND_UIMM4 :
1081       fields->f_uimm4 = value;
1082       break;
1083     case M32R_OPERAND_UIMM5 :
1084       fields->f_uimm5 = value;
1085       break;
1086     case M32R_OPERAND_ULO16 :
1087       fields->f_uimm16 = value;
1088       break;
1089
1090     default :
1091       /* xgettext:c-format */
1092       fprintf (stderr, _("Unrecognized field %d while setting int operand.\n"),
1093                        opindex);
1094       abort ();
1095   }
1096 }
1097
1098 void
1099 m32r_cgen_set_vma_operand (cd, opindex, fields, value)
1100      CGEN_CPU_DESC cd;
1101      int opindex;
1102      CGEN_FIELDS * fields;
1103      bfd_vma value;
1104 {
1105   switch (opindex)
1106     {
1107     case M32R_OPERAND_ACC :
1108       fields->f_acc = value;
1109       break;
1110     case M32R_OPERAND_ACCD :
1111       fields->f_accd = value;
1112       break;
1113     case M32R_OPERAND_ACCS :
1114       fields->f_accs = value;
1115       break;
1116     case M32R_OPERAND_DCR :
1117       fields->f_r1 = value;
1118       break;
1119     case M32R_OPERAND_DISP16 :
1120       fields->f_disp16 = value;
1121       break;
1122     case M32R_OPERAND_DISP24 :
1123       fields->f_disp24 = value;
1124       break;
1125     case M32R_OPERAND_DISP8 :
1126       fields->f_disp8 = value;
1127       break;
1128     case M32R_OPERAND_DR :
1129       fields->f_r1 = value;
1130       break;
1131     case M32R_OPERAND_HASH :
1132       break;
1133     case M32R_OPERAND_HI16 :
1134       fields->f_hi16 = value;
1135       break;
1136     case M32R_OPERAND_IMM1 :
1137       fields->f_imm1 = value;
1138       break;
1139     case M32R_OPERAND_SCR :
1140       fields->f_r2 = value;
1141       break;
1142     case M32R_OPERAND_SIMM16 :
1143       fields->f_simm16 = value;
1144       break;
1145     case M32R_OPERAND_SIMM8 :
1146       fields->f_simm8 = value;
1147       break;
1148     case M32R_OPERAND_SLO16 :
1149       fields->f_simm16 = value;
1150       break;
1151     case M32R_OPERAND_SR :
1152       fields->f_r2 = value;
1153       break;
1154     case M32R_OPERAND_SRC1 :
1155       fields->f_r1 = value;
1156       break;
1157     case M32R_OPERAND_SRC2 :
1158       fields->f_r2 = value;
1159       break;
1160     case M32R_OPERAND_UIMM16 :
1161       fields->f_uimm16 = value;
1162       break;
1163     case M32R_OPERAND_UIMM24 :
1164       fields->f_uimm24 = value;
1165       break;
1166     case M32R_OPERAND_UIMM4 :
1167       fields->f_uimm4 = value;
1168       break;
1169     case M32R_OPERAND_UIMM5 :
1170       fields->f_uimm5 = value;
1171       break;
1172     case M32R_OPERAND_ULO16 :
1173       fields->f_uimm16 = value;
1174       break;
1175
1176     default :
1177       /* xgettext:c-format */
1178       fprintf (stderr, _("Unrecognized field %d while setting vma operand.\n"),
1179                        opindex);
1180       abort ();
1181   }
1182 }
1183
1184 /* Function to call before using the instruction builder tables.  */
1185
1186 void
1187 m32r_cgen_init_ibld_table (cd)
1188      CGEN_CPU_DESC cd;
1189 {
1190   cd->insert_handlers = & m32r_cgen_insert_handlers[0];
1191   cd->extract_handlers = & m32r_cgen_extract_handlers[0];
1192
1193   cd->insert_operand = m32r_cgen_insert_operand;
1194   cd->extract_operand = m32r_cgen_extract_operand;
1195
1196   cd->get_int_operand = m32r_cgen_get_int_operand;
1197   cd->set_int_operand = m32r_cgen_set_int_operand;
1198   cd->get_vma_operand = m32r_cgen_get_vma_operand;
1199   cd->set_vma_operand = m32r_cgen_set_vma_operand;
1200 }