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