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