OSDN Git Service

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