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