OSDN Git Service

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