[ include/opcode/ChangeLog ]
[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 <stdio.h>
29 #include "ansidecl.h"
30 #include "dis-asm.h"
31 #include "bfd.h"
32 #include "symcat.h"
33 #include "m32r-desc.h"
34 #include "m32r-opc.h"
35 #include "opintl.h"
36 #include "safe-ctype.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 #endif
379   x = cgen_get_insn_value (cd, bufp, word_length);
380
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 const char *
560 m32r_cgen_insert_operand (cd, opindex, fields, buffer, pc)
561      CGEN_CPU_DESC cd;
562      int opindex;
563      CGEN_FIELDS * fields;
564      CGEN_INSN_BYTES_PTR buffer;
565      bfd_vma pc ATTRIBUTE_UNUSED;
566 {
567   const char * errmsg = NULL;
568   unsigned int total_length = CGEN_FIELDS_BITSIZE (fields);
569
570   switch (opindex)
571     {
572     case M32R_OPERAND_ACC :
573       errmsg = insert_normal (cd, fields->f_acc, 0, 0, 8, 1, 32, total_length, buffer);
574       break;
575     case M32R_OPERAND_ACCD :
576       errmsg = insert_normal (cd, fields->f_accd, 0, 0, 4, 2, 32, total_length, buffer);
577       break;
578     case M32R_OPERAND_ACCS :
579       errmsg = insert_normal (cd, fields->f_accs, 0, 0, 12, 2, 32, total_length, buffer);
580       break;
581     case M32R_OPERAND_DCR :
582       errmsg = insert_normal (cd, fields->f_r1, 0, 0, 4, 4, 32, total_length, buffer);
583       break;
584     case M32R_OPERAND_DISP16 :
585       {
586         long value = fields->f_disp16;
587         value = ((int) (((value) - (pc))) >> (2));
588         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);
589       }
590       break;
591     case M32R_OPERAND_DISP24 :
592       {
593         long value = fields->f_disp24;
594         value = ((int) (((value) - (pc))) >> (2));
595         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);
596       }
597       break;
598     case M32R_OPERAND_DISP8 :
599       {
600         long value = fields->f_disp8;
601         value = ((int) (((value) - (((pc) & (-4))))) >> (2));
602         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);
603       }
604       break;
605     case M32R_OPERAND_DR :
606       errmsg = insert_normal (cd, fields->f_r1, 0, 0, 4, 4, 32, total_length, buffer);
607       break;
608     case M32R_OPERAND_HASH :
609       break;
610     case M32R_OPERAND_HI16 :
611       errmsg = insert_normal (cd, fields->f_hi16, 0|(1<<CGEN_IFLD_SIGN_OPT), 0, 16, 16, 32, total_length, buffer);
612       break;
613     case M32R_OPERAND_IMM1 :
614       {
615         long value = fields->f_imm1;
616         value = ((value) - (1));
617         errmsg = insert_normal (cd, value, 0, 0, 15, 1, 32, total_length, buffer);
618       }
619       break;
620     case M32R_OPERAND_SCR :
621       errmsg = insert_normal (cd, fields->f_r2, 0, 0, 12, 4, 32, total_length, buffer);
622       break;
623     case M32R_OPERAND_SIMM16 :
624       errmsg = insert_normal (cd, fields->f_simm16, 0|(1<<CGEN_IFLD_SIGNED), 0, 16, 16, 32, total_length, buffer);
625       break;
626     case M32R_OPERAND_SIMM8 :
627       errmsg = insert_normal (cd, fields->f_simm8, 0|(1<<CGEN_IFLD_SIGNED), 0, 8, 8, 32, total_length, buffer);
628       break;
629     case M32R_OPERAND_SLO16 :
630       errmsg = insert_normal (cd, fields->f_simm16, 0|(1<<CGEN_IFLD_SIGNED), 0, 16, 16, 32, total_length, buffer);
631       break;
632     case M32R_OPERAND_SR :
633       errmsg = insert_normal (cd, fields->f_r2, 0, 0, 12, 4, 32, total_length, buffer);
634       break;
635     case M32R_OPERAND_SRC1 :
636       errmsg = insert_normal (cd, fields->f_r1, 0, 0, 4, 4, 32, total_length, buffer);
637       break;
638     case M32R_OPERAND_SRC2 :
639       errmsg = insert_normal (cd, fields->f_r2, 0, 0, 12, 4, 32, total_length, buffer);
640       break;
641     case M32R_OPERAND_UIMM16 :
642       errmsg = insert_normal (cd, fields->f_uimm16, 0, 0, 16, 16, 32, total_length, buffer);
643       break;
644     case M32R_OPERAND_UIMM24 :
645       errmsg = insert_normal (cd, fields->f_uimm24, 0|(1<<CGEN_IFLD_RELOC)|(1<<CGEN_IFLD_ABS_ADDR), 0, 8, 24, 32, total_length, buffer);
646       break;
647     case M32R_OPERAND_UIMM4 :
648       errmsg = insert_normal (cd, fields->f_uimm4, 0, 0, 12, 4, 32, total_length, buffer);
649       break;
650     case M32R_OPERAND_UIMM5 :
651       errmsg = insert_normal (cd, fields->f_uimm5, 0, 0, 11, 5, 32, total_length, buffer);
652       break;
653     case M32R_OPERAND_ULO16 :
654       errmsg = insert_normal (cd, fields->f_uimm16, 0, 0, 16, 16, 32, total_length, buffer);
655       break;
656
657     default :
658       /* xgettext:c-format */
659       fprintf (stderr, _("Unrecognized field %d while building insn.\n"),
660                opindex);
661       abort ();
662   }
663
664   return errmsg;
665 }
666
667 int m32r_cgen_extract_operand
668   PARAMS ((CGEN_CPU_DESC, int, CGEN_EXTRACT_INFO *, CGEN_INSN_INT,
669            CGEN_FIELDS *, bfd_vma));
670
671 /* Main entry point for operand extraction.
672    The result is <= 0 for error, >0 for success.
673    ??? Actual values aren't well defined right now.
674
675    This function is basically just a big switch statement.  Earlier versions
676    used tables to look up the function to use, but
677    - if the table contains both assembler and disassembler functions then
678      the disassembler contains much of the assembler and vice-versa,
679    - there's a lot of inlining possibilities as things grow,
680    - using a switch statement avoids the function call overhead.
681
682    This function could be moved into `print_insn_normal', but keeping it
683    separate makes clear the interface between `print_insn_normal' and each of
684    the handlers.  */
685
686 int
687 m32r_cgen_extract_operand (cd, opindex, ex_info, insn_value, fields, pc)
688      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_UIMM4 :
781       length = extract_normal (cd, ex_info, insn_value, 0, 0, 12, 4, 32, total_length, pc, & fields->f_uimm4);
782       break;
783     case M32R_OPERAND_UIMM5 :
784       length = extract_normal (cd, ex_info, insn_value, 0, 0, 11, 5, 32, total_length, pc, & fields->f_uimm5);
785       break;
786     case M32R_OPERAND_ULO16 :
787       length = extract_normal (cd, ex_info, insn_value, 0, 0, 16, 16, 32, total_length, pc, & fields->f_uimm16);
788       break;
789
790     default :
791       /* xgettext:c-format */
792       fprintf (stderr, _("Unrecognized field %d while decoding insn.\n"),
793                opindex);
794       abort ();
795     }
796
797   return length;
798 }
799
800 cgen_insert_fn * const m32r_cgen_insert_handlers[] = 
801 {
802   insert_insn_normal,
803 };
804
805 cgen_extract_fn * const m32r_cgen_extract_handlers[] = 
806 {
807   extract_insn_normal,
808 };
809
810 int m32r_cgen_get_int_operand
811   PARAMS ((CGEN_CPU_DESC, int, const CGEN_FIELDS *));
812 bfd_vma m32r_cgen_get_vma_operand
813   PARAMS ((CGEN_CPU_DESC, int, const CGEN_FIELDS *));
814
815 /* Getting values from cgen_fields is handled by a collection of functions.
816    They are distinguished by the type of the VALUE argument they return.
817    TODO: floating point, inlining support, remove cases where result type
818    not appropriate.  */
819
820 int
821 m32r_cgen_get_int_operand (cd, opindex, fields)
822      CGEN_CPU_DESC cd ATTRIBUTE_UNUSED;
823      int opindex;
824      const CGEN_FIELDS * fields;
825 {
826   int value;
827
828   switch (opindex)
829     {
830     case M32R_OPERAND_ACC :
831       value = fields->f_acc;
832       break;
833     case M32R_OPERAND_ACCD :
834       value = fields->f_accd;
835       break;
836     case M32R_OPERAND_ACCS :
837       value = fields->f_accs;
838       break;
839     case M32R_OPERAND_DCR :
840       value = fields->f_r1;
841       break;
842     case M32R_OPERAND_DISP16 :
843       value = fields->f_disp16;
844       break;
845     case M32R_OPERAND_DISP24 :
846       value = fields->f_disp24;
847       break;
848     case M32R_OPERAND_DISP8 :
849       value = fields->f_disp8;
850       break;
851     case M32R_OPERAND_DR :
852       value = fields->f_r1;
853       break;
854     case M32R_OPERAND_HASH :
855       value = 0;
856       break;
857     case M32R_OPERAND_HI16 :
858       value = fields->f_hi16;
859       break;
860     case M32R_OPERAND_IMM1 :
861       value = fields->f_imm1;
862       break;
863     case M32R_OPERAND_SCR :
864       value = fields->f_r2;
865       break;
866     case M32R_OPERAND_SIMM16 :
867       value = fields->f_simm16;
868       break;
869     case M32R_OPERAND_SIMM8 :
870       value = fields->f_simm8;
871       break;
872     case M32R_OPERAND_SLO16 :
873       value = fields->f_simm16;
874       break;
875     case M32R_OPERAND_SR :
876       value = fields->f_r2;
877       break;
878     case M32R_OPERAND_SRC1 :
879       value = fields->f_r1;
880       break;
881     case M32R_OPERAND_SRC2 :
882       value = fields->f_r2;
883       break;
884     case M32R_OPERAND_UIMM16 :
885       value = fields->f_uimm16;
886       break;
887     case M32R_OPERAND_UIMM24 :
888       value = fields->f_uimm24;
889       break;
890     case M32R_OPERAND_UIMM4 :
891       value = fields->f_uimm4;
892       break;
893     case M32R_OPERAND_UIMM5 :
894       value = fields->f_uimm5;
895       break;
896     case M32R_OPERAND_ULO16 :
897       value = fields->f_uimm16;
898       break;
899
900     default :
901       /* xgettext:c-format */
902       fprintf (stderr, _("Unrecognized field %d while getting int operand.\n"),
903                        opindex);
904       abort ();
905   }
906
907   return value;
908 }
909
910 bfd_vma
911 m32r_cgen_get_vma_operand (cd, opindex, fields)
912      CGEN_CPU_DESC cd ATTRIBUTE_UNUSED;
913      int opindex;
914      const CGEN_FIELDS * fields;
915 {
916   bfd_vma value;
917
918   switch (opindex)
919     {
920     case M32R_OPERAND_ACC :
921       value = fields->f_acc;
922       break;
923     case M32R_OPERAND_ACCD :
924       value = fields->f_accd;
925       break;
926     case M32R_OPERAND_ACCS :
927       value = fields->f_accs;
928       break;
929     case M32R_OPERAND_DCR :
930       value = fields->f_r1;
931       break;
932     case M32R_OPERAND_DISP16 :
933       value = fields->f_disp16;
934       break;
935     case M32R_OPERAND_DISP24 :
936       value = fields->f_disp24;
937       break;
938     case M32R_OPERAND_DISP8 :
939       value = fields->f_disp8;
940       break;
941     case M32R_OPERAND_DR :
942       value = fields->f_r1;
943       break;
944     case M32R_OPERAND_HASH :
945       value = 0;
946       break;
947     case M32R_OPERAND_HI16 :
948       value = fields->f_hi16;
949       break;
950     case M32R_OPERAND_IMM1 :
951       value = fields->f_imm1;
952       break;
953     case M32R_OPERAND_SCR :
954       value = fields->f_r2;
955       break;
956     case M32R_OPERAND_SIMM16 :
957       value = fields->f_simm16;
958       break;
959     case M32R_OPERAND_SIMM8 :
960       value = fields->f_simm8;
961       break;
962     case M32R_OPERAND_SLO16 :
963       value = fields->f_simm16;
964       break;
965     case M32R_OPERAND_SR :
966       value = fields->f_r2;
967       break;
968     case M32R_OPERAND_SRC1 :
969       value = fields->f_r1;
970       break;
971     case M32R_OPERAND_SRC2 :
972       value = fields->f_r2;
973       break;
974     case M32R_OPERAND_UIMM16 :
975       value = fields->f_uimm16;
976       break;
977     case M32R_OPERAND_UIMM24 :
978       value = fields->f_uimm24;
979       break;
980     case M32R_OPERAND_UIMM4 :
981       value = fields->f_uimm4;
982       break;
983     case M32R_OPERAND_UIMM5 :
984       value = fields->f_uimm5;
985       break;
986     case M32R_OPERAND_ULO16 :
987       value = fields->f_uimm16;
988       break;
989
990     default :
991       /* xgettext:c-format */
992       fprintf (stderr, _("Unrecognized field %d while getting vma operand.\n"),
993                        opindex);
994       abort ();
995   }
996
997   return value;
998 }
999
1000 void m32r_cgen_set_int_operand
1001   PARAMS ((CGEN_CPU_DESC, int, CGEN_FIELDS *, int));
1002 void m32r_cgen_set_vma_operand
1003   PARAMS ((CGEN_CPU_DESC, int, CGEN_FIELDS *, bfd_vma));
1004
1005 /* Stuffing values in cgen_fields is handled by a collection of functions.
1006    They are distinguished by the type of the VALUE argument they accept.
1007    TODO: floating point, inlining support, remove cases where argument type
1008    not appropriate.  */
1009
1010 void
1011 m32r_cgen_set_int_operand (cd, opindex, fields, value)
1012      CGEN_CPU_DESC cd ATTRIBUTE_UNUSED;
1013      int opindex;
1014      CGEN_FIELDS * fields;
1015      int value;
1016 {
1017   switch (opindex)
1018     {
1019     case M32R_OPERAND_ACC :
1020       fields->f_acc = value;
1021       break;
1022     case M32R_OPERAND_ACCD :
1023       fields->f_accd = value;
1024       break;
1025     case M32R_OPERAND_ACCS :
1026       fields->f_accs = value;
1027       break;
1028     case M32R_OPERAND_DCR :
1029       fields->f_r1 = value;
1030       break;
1031     case M32R_OPERAND_DISP16 :
1032       fields->f_disp16 = value;
1033       break;
1034     case M32R_OPERAND_DISP24 :
1035       fields->f_disp24 = value;
1036       break;
1037     case M32R_OPERAND_DISP8 :
1038       fields->f_disp8 = value;
1039       break;
1040     case M32R_OPERAND_DR :
1041       fields->f_r1 = value;
1042       break;
1043     case M32R_OPERAND_HASH :
1044       break;
1045     case M32R_OPERAND_HI16 :
1046       fields->f_hi16 = value;
1047       break;
1048     case M32R_OPERAND_IMM1 :
1049       fields->f_imm1 = value;
1050       break;
1051     case M32R_OPERAND_SCR :
1052       fields->f_r2 = value;
1053       break;
1054     case M32R_OPERAND_SIMM16 :
1055       fields->f_simm16 = value;
1056       break;
1057     case M32R_OPERAND_SIMM8 :
1058       fields->f_simm8 = value;
1059       break;
1060     case M32R_OPERAND_SLO16 :
1061       fields->f_simm16 = value;
1062       break;
1063     case M32R_OPERAND_SR :
1064       fields->f_r2 = value;
1065       break;
1066     case M32R_OPERAND_SRC1 :
1067       fields->f_r1 = value;
1068       break;
1069     case M32R_OPERAND_SRC2 :
1070       fields->f_r2 = value;
1071       break;
1072     case M32R_OPERAND_UIMM16 :
1073       fields->f_uimm16 = value;
1074       break;
1075     case M32R_OPERAND_UIMM24 :
1076       fields->f_uimm24 = value;
1077       break;
1078     case M32R_OPERAND_UIMM4 :
1079       fields->f_uimm4 = value;
1080       break;
1081     case M32R_OPERAND_UIMM5 :
1082       fields->f_uimm5 = value;
1083       break;
1084     case M32R_OPERAND_ULO16 :
1085       fields->f_uimm16 = value;
1086       break;
1087
1088     default :
1089       /* xgettext:c-format */
1090       fprintf (stderr, _("Unrecognized field %d while setting int operand.\n"),
1091                        opindex);
1092       abort ();
1093   }
1094 }
1095
1096 void
1097 m32r_cgen_set_vma_operand (cd, opindex, fields, value)
1098      CGEN_CPU_DESC cd ATTRIBUTE_UNUSED;
1099      int opindex;
1100      CGEN_FIELDS * fields;
1101      bfd_vma value;
1102 {
1103   switch (opindex)
1104     {
1105     case M32R_OPERAND_ACC :
1106       fields->f_acc = value;
1107       break;
1108     case M32R_OPERAND_ACCD :
1109       fields->f_accd = value;
1110       break;
1111     case M32R_OPERAND_ACCS :
1112       fields->f_accs = value;
1113       break;
1114     case M32R_OPERAND_DCR :
1115       fields->f_r1 = value;
1116       break;
1117     case M32R_OPERAND_DISP16 :
1118       fields->f_disp16 = value;
1119       break;
1120     case M32R_OPERAND_DISP24 :
1121       fields->f_disp24 = value;
1122       break;
1123     case M32R_OPERAND_DISP8 :
1124       fields->f_disp8 = value;
1125       break;
1126     case M32R_OPERAND_DR :
1127       fields->f_r1 = value;
1128       break;
1129     case M32R_OPERAND_HASH :
1130       break;
1131     case M32R_OPERAND_HI16 :
1132       fields->f_hi16 = value;
1133       break;
1134     case M32R_OPERAND_IMM1 :
1135       fields->f_imm1 = value;
1136       break;
1137     case M32R_OPERAND_SCR :
1138       fields->f_r2 = value;
1139       break;
1140     case M32R_OPERAND_SIMM16 :
1141       fields->f_simm16 = value;
1142       break;
1143     case M32R_OPERAND_SIMM8 :
1144       fields->f_simm8 = value;
1145       break;
1146     case M32R_OPERAND_SLO16 :
1147       fields->f_simm16 = value;
1148       break;
1149     case M32R_OPERAND_SR :
1150       fields->f_r2 = value;
1151       break;
1152     case M32R_OPERAND_SRC1 :
1153       fields->f_r1 = value;
1154       break;
1155     case M32R_OPERAND_SRC2 :
1156       fields->f_r2 = value;
1157       break;
1158     case M32R_OPERAND_UIMM16 :
1159       fields->f_uimm16 = value;
1160       break;
1161     case M32R_OPERAND_UIMM24 :
1162       fields->f_uimm24 = value;
1163       break;
1164     case M32R_OPERAND_UIMM4 :
1165       fields->f_uimm4 = value;
1166       break;
1167     case M32R_OPERAND_UIMM5 :
1168       fields->f_uimm5 = value;
1169       break;
1170     case M32R_OPERAND_ULO16 :
1171       fields->f_uimm16 = value;
1172       break;
1173
1174     default :
1175       /* xgettext:c-format */
1176       fprintf (stderr, _("Unrecognized field %d while setting vma operand.\n"),
1177                        opindex);
1178       abort ();
1179   }
1180 }
1181
1182 /* Function to call before using the instruction builder tables.  */
1183
1184 void
1185 m32r_cgen_init_ibld_table (cd)
1186      CGEN_CPU_DESC cd;
1187 {
1188   cd->insert_handlers = & m32r_cgen_insert_handlers[0];
1189   cd->extract_handlers = & m32r_cgen_extract_handlers[0];
1190
1191   cd->insert_operand = m32r_cgen_insert_operand;
1192   cd->extract_operand = m32r_cgen_extract_operand;
1193
1194   cd->get_int_operand = m32r_cgen_get_int_operand;
1195   cd->set_int_operand = m32r_cgen_set_int_operand;
1196   cd->get_vma_operand = m32r_cgen_get_vma_operand;
1197   cd->set_vma_operand = m32r_cgen_set_vma_operand;
1198 }