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;
583   unsigned int total_length = CGEN_FIELDS_BITSIZE (fields);
584
585   switch (opindex)
586     {
587     case M32R_OPERAND_DCR :
588       errmsg = insert_normal (cd, fields->f_r1, 0, 0, 4, 4, 32, total_length, buffer);
589       break;
590     case M32R_OPERAND_DISP16 :
591       {
592         long value = fields->f_disp16;
593         value = ((int) (((value) - (pc))) >> (2));
594         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);
595       }
596       break;
597     case M32R_OPERAND_DISP24 :
598       {
599         long value = fields->f_disp24;
600         value = ((int) (((value) - (pc))) >> (2));
601         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);
602       }
603       break;
604     case M32R_OPERAND_DISP8 :
605       {
606         long value = fields->f_disp8;
607         value = ((int) (((value) - (((pc) & (-4))))) >> (2));
608         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);
609       }
610       break;
611     case M32R_OPERAND_DR :
612       errmsg = insert_normal (cd, fields->f_r1, 0, 0, 4, 4, 32, total_length, buffer);
613       break;
614     case M32R_OPERAND_HASH :
615       errmsg = insert_normal (cd, fields->f_nil, 0, 0, 0, 0, 0, total_length, buffer);
616       break;
617     case M32R_OPERAND_HI16 :
618       errmsg = insert_normal (cd, fields->f_hi16, 0|(1<<CGEN_IFLD_SIGN_OPT), 0, 16, 16, 32, total_length, buffer);
619       break;
620     case M32R_OPERAND_SCR :
621       errmsg = insert_normal (cd, fields->f_r2, 0, 0, 12, 4, 32, total_length, buffer);
622       break;
623     case M32R_OPERAND_SIMM16 :
624       errmsg = insert_normal (cd, fields->f_simm16, 0|(1<<CGEN_IFLD_SIGNED), 0, 16, 16, 32, total_length, buffer);
625       break;
626     case M32R_OPERAND_SIMM8 :
627       errmsg = insert_normal (cd, fields->f_simm8, 0|(1<<CGEN_IFLD_SIGNED), 0, 8, 8, 32, total_length, buffer);
628       break;
629     case M32R_OPERAND_SLO16 :
630       errmsg = insert_normal (cd, fields->f_simm16, 0|(1<<CGEN_IFLD_SIGNED), 0, 16, 16, 32, total_length, buffer);
631       break;
632     case M32R_OPERAND_SR :
633       errmsg = insert_normal (cd, fields->f_r2, 0, 0, 12, 4, 32, total_length, buffer);
634       break;
635     case M32R_OPERAND_SRC1 :
636       errmsg = insert_normal (cd, fields->f_r1, 0, 0, 4, 4, 32, total_length, buffer);
637       break;
638     case M32R_OPERAND_SRC2 :
639       errmsg = insert_normal (cd, fields->f_r2, 0, 0, 12, 4, 32, total_length, buffer);
640       break;
641     case M32R_OPERAND_UIMM16 :
642       errmsg = insert_normal (cd, fields->f_uimm16, 0, 0, 16, 16, 32, total_length, buffer);
643       break;
644     case M32R_OPERAND_UIMM24 :
645       errmsg = insert_normal (cd, fields->f_uimm24, 0|(1<<CGEN_IFLD_RELOC)|(1<<CGEN_IFLD_ABS_ADDR), 0, 8, 24, 32, total_length, buffer);
646       break;
647     case M32R_OPERAND_UIMM4 :
648       errmsg = insert_normal (cd, fields->f_uimm4, 0, 0, 12, 4, 32, total_length, buffer);
649       break;
650     case M32R_OPERAND_UIMM5 :
651       errmsg = insert_normal (cd, fields->f_uimm5, 0, 0, 11, 5, 32, total_length, buffer);
652       break;
653     case M32R_OPERAND_ULO16 :
654       errmsg = insert_normal (cd, fields->f_uimm16, 0, 0, 16, 16, 32, total_length, buffer);
655       break;
656
657     default :
658       /* xgettext:c-format */
659       fprintf (stderr, _("Unrecognized field %d while building insn.\n"),
660                opindex);
661       abort ();
662   }
663
664   return errmsg;
665 }
666
667 /* Main entry point for operand extraction.
668
669    This function is basically just a big switch statement.  Earlier versions
670    used tables to look up the function to use, but
671    - if the table contains both assembler and disassembler functions then
672      the disassembler contains much of the assembler and vice-versa,
673    - there's a lot of inlining possibilities as things grow,
674    - using a switch statement avoids the function call overhead.
675
676    This function could be moved into `print_insn_normal', but keeping it
677    separate makes clear the interface between `print_insn_normal' and each of
678    the handlers.
679 */
680
681 int
682 m32r_cgen_extract_operand (cd, opindex, ex_info, insn_value, fields, pc)
683      CGEN_CPU_DESC cd;
684      int opindex;
685      CGEN_EXTRACT_INFO *ex_info;
686      CGEN_INSN_INT insn_value;
687      CGEN_FIELDS * fields;
688      bfd_vma pc;
689 {
690   int length;
691   unsigned int total_length = CGEN_FIELDS_BITSIZE (fields);
692
693   switch (opindex)
694     {
695     case M32R_OPERAND_DCR :
696       length = extract_normal (cd, ex_info, insn_value, 0, 0, 4, 4, 32, total_length, pc, & fields->f_r1);
697       break;
698     case M32R_OPERAND_DISP16 :
699       {
700         long value;
701         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);
702         value = ((((value) << (2))) + (pc));
703         fields->f_disp16 = value;
704       }
705       break;
706     case M32R_OPERAND_DISP24 :
707       {
708         long value;
709         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);
710         value = ((((value) << (2))) + (pc));
711         fields->f_disp24 = value;
712       }
713       break;
714     case M32R_OPERAND_DISP8 :
715       {
716         long value;
717         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);
718         value = ((((value) << (2))) + (((pc) & (-4))));
719         fields->f_disp8 = value;
720       }
721       break;
722     case M32R_OPERAND_DR :
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_HASH :
726       length = extract_normal (cd, ex_info, insn_value, 0, 0, 0, 0, 0, total_length, pc, & fields->f_nil);
727       break;
728     case M32R_OPERAND_HI16 :
729       length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_SIGN_OPT), 0, 16, 16, 32, total_length, pc, & fields->f_hi16);
730       break;
731     case M32R_OPERAND_SCR :
732       length = extract_normal (cd, ex_info, insn_value, 0, 0, 12, 4, 32, total_length, pc, & fields->f_r2);
733       break;
734     case M32R_OPERAND_SIMM16 :
735       length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_SIGNED), 0, 16, 16, 32, total_length, pc, & fields->f_simm16);
736       break;
737     case M32R_OPERAND_SIMM8 :
738       length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_SIGNED), 0, 8, 8, 32, total_length, pc, & fields->f_simm8);
739       break;
740     case M32R_OPERAND_SLO16 :
741       length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_SIGNED), 0, 16, 16, 32, total_length, pc, & fields->f_simm16);
742       break;
743     case M32R_OPERAND_SR :
744       length = extract_normal (cd, ex_info, insn_value, 0, 0, 12, 4, 32, total_length, pc, & fields->f_r2);
745       break;
746     case M32R_OPERAND_SRC1 :
747       length = extract_normal (cd, ex_info, insn_value, 0, 0, 4, 4, 32, total_length, pc, & fields->f_r1);
748       break;
749     case M32R_OPERAND_SRC2 :
750       length = extract_normal (cd, ex_info, insn_value, 0, 0, 12, 4, 32, total_length, pc, & fields->f_r2);
751       break;
752     case M32R_OPERAND_UIMM16 :
753       length = extract_normal (cd, ex_info, insn_value, 0, 0, 16, 16, 32, total_length, pc, & fields->f_uimm16);
754       break;
755     case M32R_OPERAND_UIMM24 :
756       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);
757       break;
758     case M32R_OPERAND_UIMM4 :
759       length = extract_normal (cd, ex_info, insn_value, 0, 0, 12, 4, 32, total_length, pc, & fields->f_uimm4);
760       break;
761     case M32R_OPERAND_UIMM5 :
762       length = extract_normal (cd, ex_info, insn_value, 0, 0, 11, 5, 32, total_length, pc, & fields->f_uimm5);
763       break;
764     case M32R_OPERAND_ULO16 :
765       length = extract_normal (cd, ex_info, insn_value, 0, 0, 16, 16, 32, total_length, pc, & fields->f_uimm16);
766       break;
767
768     default :
769       /* xgettext:c-format */
770       fprintf (stderr, _("Unrecognized field %d while decoding insn.\n"),
771                opindex);
772       abort ();
773     }
774
775   return length;
776 }
777
778 cgen_insert_fn * const m32r_cgen_insert_handlers[] = 
779 {
780   insert_insn_normal,
781 };
782
783 cgen_extract_fn * const m32r_cgen_extract_handlers[] = 
784 {
785   extract_insn_normal,
786 };
787
788 /* Getting values from cgen_fields is handled by a collection of functions.
789    They are distinguished by the type of the VALUE argument they return.
790    TODO: floating point, inlining support, remove cases where result type
791    not appropriate.  */
792
793 int
794 m32r_cgen_get_int_operand (cd, opindex, fields)
795      CGEN_CPU_DESC cd;
796      int opindex;
797      const CGEN_FIELDS * fields;
798 {
799   int value;
800
801   switch (opindex)
802     {
803     case M32R_OPERAND_DCR :
804       value = fields->f_r1;
805       break;
806     case M32R_OPERAND_DISP16 :
807       value = fields->f_disp16;
808       break;
809     case M32R_OPERAND_DISP24 :
810       value = fields->f_disp24;
811       break;
812     case M32R_OPERAND_DISP8 :
813       value = fields->f_disp8;
814       break;
815     case M32R_OPERAND_DR :
816       value = fields->f_r1;
817       break;
818     case M32R_OPERAND_HASH :
819       value = fields->f_nil;
820       break;
821     case M32R_OPERAND_HI16 :
822       value = fields->f_hi16;
823       break;
824     case M32R_OPERAND_SCR :
825       value = fields->f_r2;
826       break;
827     case M32R_OPERAND_SIMM16 :
828       value = fields->f_simm16;
829       break;
830     case M32R_OPERAND_SIMM8 :
831       value = fields->f_simm8;
832       break;
833     case M32R_OPERAND_SLO16 :
834       value = fields->f_simm16;
835       break;
836     case M32R_OPERAND_SR :
837       value = fields->f_r2;
838       break;
839     case M32R_OPERAND_SRC1 :
840       value = fields->f_r1;
841       break;
842     case M32R_OPERAND_SRC2 :
843       value = fields->f_r2;
844       break;
845     case M32R_OPERAND_UIMM16 :
846       value = fields->f_uimm16;
847       break;
848     case M32R_OPERAND_UIMM24 :
849       value = fields->f_uimm24;
850       break;
851     case M32R_OPERAND_UIMM4 :
852       value = fields->f_uimm4;
853       break;
854     case M32R_OPERAND_UIMM5 :
855       value = fields->f_uimm5;
856       break;
857     case M32R_OPERAND_ULO16 :
858       value = fields->f_uimm16;
859       break;
860
861     default :
862       /* xgettext:c-format */
863       fprintf (stderr, _("Unrecognized field %d while getting int operand.\n"),
864                        opindex);
865       abort ();
866   }
867
868   return value;
869 }
870
871 bfd_vma
872 m32r_cgen_get_vma_operand (cd, opindex, fields)
873      CGEN_CPU_DESC cd;
874      int opindex;
875      const CGEN_FIELDS * fields;
876 {
877   bfd_vma value;
878
879   switch (opindex)
880     {
881     case M32R_OPERAND_DCR :
882       value = fields->f_r1;
883       break;
884     case M32R_OPERAND_DISP16 :
885       value = fields->f_disp16;
886       break;
887     case M32R_OPERAND_DISP24 :
888       value = fields->f_disp24;
889       break;
890     case M32R_OPERAND_DISP8 :
891       value = fields->f_disp8;
892       break;
893     case M32R_OPERAND_DR :
894       value = fields->f_r1;
895       break;
896     case M32R_OPERAND_HASH :
897       value = fields->f_nil;
898       break;
899     case M32R_OPERAND_HI16 :
900       value = fields->f_hi16;
901       break;
902     case M32R_OPERAND_SCR :
903       value = fields->f_r2;
904       break;
905     case M32R_OPERAND_SIMM16 :
906       value = fields->f_simm16;
907       break;
908     case M32R_OPERAND_SIMM8 :
909       value = fields->f_simm8;
910       break;
911     case M32R_OPERAND_SLO16 :
912       value = fields->f_simm16;
913       break;
914     case M32R_OPERAND_SR :
915       value = fields->f_r2;
916       break;
917     case M32R_OPERAND_SRC1 :
918       value = fields->f_r1;
919       break;
920     case M32R_OPERAND_SRC2 :
921       value = fields->f_r2;
922       break;
923     case M32R_OPERAND_UIMM16 :
924       value = fields->f_uimm16;
925       break;
926     case M32R_OPERAND_UIMM24 :
927       value = fields->f_uimm24;
928       break;
929     case M32R_OPERAND_UIMM4 :
930       value = fields->f_uimm4;
931       break;
932     case M32R_OPERAND_UIMM5 :
933       value = fields->f_uimm5;
934       break;
935     case M32R_OPERAND_ULO16 :
936       value = fields->f_uimm16;
937       break;
938
939     default :
940       /* xgettext:c-format */
941       fprintf (stderr, _("Unrecognized field %d while getting vma operand.\n"),
942                        opindex);
943       abort ();
944   }
945
946   return value;
947 }
948
949 /* Stuffing values in cgen_fields is handled by a collection of functions.
950    They are distinguished by the type of the VALUE argument they accept.
951    TODO: floating point, inlining support, remove cases where argument type
952    not appropriate.  */
953
954 void
955 m32r_cgen_set_int_operand (cd, opindex, fields, value)
956      CGEN_CPU_DESC cd;
957      int opindex;
958      CGEN_FIELDS * fields;
959      int value;
960 {
961   switch (opindex)
962     {
963     case M32R_OPERAND_DCR :
964       fields->f_r1 = value;
965       break;
966     case M32R_OPERAND_DISP16 :
967       fields->f_disp16 = value;
968       break;
969     case M32R_OPERAND_DISP24 :
970       fields->f_disp24 = value;
971       break;
972     case M32R_OPERAND_DISP8 :
973       fields->f_disp8 = value;
974       break;
975     case M32R_OPERAND_DR :
976       fields->f_r1 = value;
977       break;
978     case M32R_OPERAND_HASH :
979       fields->f_nil = value;
980       break;
981     case M32R_OPERAND_HI16 :
982       fields->f_hi16 = value;
983       break;
984     case M32R_OPERAND_SCR :
985       fields->f_r2 = value;
986       break;
987     case M32R_OPERAND_SIMM16 :
988       fields->f_simm16 = value;
989       break;
990     case M32R_OPERAND_SIMM8 :
991       fields->f_simm8 = value;
992       break;
993     case M32R_OPERAND_SLO16 :
994       fields->f_simm16 = value;
995       break;
996     case M32R_OPERAND_SR :
997       fields->f_r2 = value;
998       break;
999     case M32R_OPERAND_SRC1 :
1000       fields->f_r1 = value;
1001       break;
1002     case M32R_OPERAND_SRC2 :
1003       fields->f_r2 = value;
1004       break;
1005     case M32R_OPERAND_UIMM16 :
1006       fields->f_uimm16 = value;
1007       break;
1008     case M32R_OPERAND_UIMM24 :
1009       fields->f_uimm24 = value;
1010       break;
1011     case M32R_OPERAND_UIMM4 :
1012       fields->f_uimm4 = value;
1013       break;
1014     case M32R_OPERAND_UIMM5 :
1015       fields->f_uimm5 = value;
1016       break;
1017     case M32R_OPERAND_ULO16 :
1018       fields->f_uimm16 = value;
1019       break;
1020
1021     default :
1022       /* xgettext:c-format */
1023       fprintf (stderr, _("Unrecognized field %d while setting int operand.\n"),
1024                        opindex);
1025       abort ();
1026   }
1027 }
1028
1029 void
1030 m32r_cgen_set_vma_operand (cd, opindex, fields, value)
1031      CGEN_CPU_DESC cd;
1032      int opindex;
1033      CGEN_FIELDS * fields;
1034      bfd_vma value;
1035 {
1036   switch (opindex)
1037     {
1038     case M32R_OPERAND_DCR :
1039       fields->f_r1 = value;
1040       break;
1041     case M32R_OPERAND_DISP16 :
1042       fields->f_disp16 = value;
1043       break;
1044     case M32R_OPERAND_DISP24 :
1045       fields->f_disp24 = value;
1046       break;
1047     case M32R_OPERAND_DISP8 :
1048       fields->f_disp8 = value;
1049       break;
1050     case M32R_OPERAND_DR :
1051       fields->f_r1 = value;
1052       break;
1053     case M32R_OPERAND_HASH :
1054       fields->f_nil = value;
1055       break;
1056     case M32R_OPERAND_HI16 :
1057       fields->f_hi16 = value;
1058       break;
1059     case M32R_OPERAND_SCR :
1060       fields->f_r2 = value;
1061       break;
1062     case M32R_OPERAND_SIMM16 :
1063       fields->f_simm16 = value;
1064       break;
1065     case M32R_OPERAND_SIMM8 :
1066       fields->f_simm8 = value;
1067       break;
1068     case M32R_OPERAND_SLO16 :
1069       fields->f_simm16 = value;
1070       break;
1071     case M32R_OPERAND_SR :
1072       fields->f_r2 = value;
1073       break;
1074     case M32R_OPERAND_SRC1 :
1075       fields->f_r1 = value;
1076       break;
1077     case M32R_OPERAND_SRC2 :
1078       fields->f_r2 = value;
1079       break;
1080     case M32R_OPERAND_UIMM16 :
1081       fields->f_uimm16 = value;
1082       break;
1083     case M32R_OPERAND_UIMM24 :
1084       fields->f_uimm24 = value;
1085       break;
1086     case M32R_OPERAND_UIMM4 :
1087       fields->f_uimm4 = value;
1088       break;
1089     case M32R_OPERAND_UIMM5 :
1090       fields->f_uimm5 = value;
1091       break;
1092     case M32R_OPERAND_ULO16 :
1093       fields->f_uimm16 = value;
1094       break;
1095
1096     default :
1097       /* xgettext:c-format */
1098       fprintf (stderr, _("Unrecognized field %d while setting vma operand.\n"),
1099                        opindex);
1100       abort ();
1101   }
1102 }
1103
1104 /* Function to call before using the instruction builder tables.  */
1105
1106 void
1107 m32r_cgen_init_ibld_table (cd)
1108      CGEN_CPU_DESC cd;
1109 {
1110   cd->insert_handlers = & m32r_cgen_insert_handlers[0];
1111   cd->extract_handlers = & m32r_cgen_extract_handlers[0];
1112
1113   cd->insert_operand = m32r_cgen_insert_operand;
1114   cd->extract_operand = m32r_cgen_extract_operand;
1115
1116   cd->get_int_operand = m32r_cgen_get_int_operand;
1117   cd->set_int_operand = m32r_cgen_set_int_operand;
1118   cd->get_vma_operand = m32r_cgen_get_vma_operand;
1119   cd->set_vma_operand = m32r_cgen_set_vma_operand;
1120 }