OSDN Git Service

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