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