xref: /netbsd-src/external/gpl3/binutils.old/dist/opcodes/m32r-ibld.c (revision c42dbd0ed2e61fe6eda8590caa852ccf34719964)
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-2020 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 
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 
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 
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       opcodes_error_handler
670 	(_("internal error: unrecognized field %d while building insn"),
671 	 opindex);
672       abort ();
673   }
674 
675   return errmsg;
676 }
677 
678 int m32r_cgen_extract_operand
679   (CGEN_CPU_DESC, int, CGEN_EXTRACT_INFO *, CGEN_INSN_INT, CGEN_FIELDS *, bfd_vma);
680 
681 /* Main entry point for operand extraction.
682    The result is <= 0 for error, >0 for success.
683    ??? Actual values aren't well defined right now.
684 
685    This function is basically just a big switch statement.  Earlier versions
686    used tables to look up the function to use, but
687    - if the table contains both assembler and disassembler functions then
688      the disassembler contains much of the assembler and vice-versa,
689    - there's a lot of inlining possibilities as things grow,
690    - using a switch statement avoids the function call overhead.
691 
692    This function could be moved into `print_insn_normal', but keeping it
693    separate makes clear the interface between `print_insn_normal' and each of
694    the handlers.  */
695 
696 int
697 m32r_cgen_extract_operand (CGEN_CPU_DESC cd,
698 			     int opindex,
699 			     CGEN_EXTRACT_INFO *ex_info,
700 			     CGEN_INSN_INT insn_value,
701 			     CGEN_FIELDS * fields,
702 			     bfd_vma pc)
703 {
704   /* Assume success (for those operands that are nops).  */
705   int length = 1;
706   unsigned int total_length = CGEN_FIELDS_BITSIZE (fields);
707 
708   switch (opindex)
709     {
710     case M32R_OPERAND_ACC :
711       length = extract_normal (cd, ex_info, insn_value, 0, 0, 8, 1, 32, total_length, pc, & fields->f_acc);
712       break;
713     case M32R_OPERAND_ACCD :
714       length = extract_normal (cd, ex_info, insn_value, 0, 0, 4, 2, 32, total_length, pc, & fields->f_accd);
715       break;
716     case M32R_OPERAND_ACCS :
717       length = extract_normal (cd, ex_info, insn_value, 0, 0, 12, 2, 32, total_length, pc, & fields->f_accs);
718       break;
719     case M32R_OPERAND_DCR :
720       length = extract_normal (cd, ex_info, insn_value, 0, 0, 4, 4, 32, total_length, pc, & fields->f_r1);
721       break;
722     case M32R_OPERAND_DISP16 :
723       {
724         long value;
725         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);
726         value = ((((value) * (4))) + (pc));
727         fields->f_disp16 = value;
728       }
729       break;
730     case M32R_OPERAND_DISP24 :
731       {
732         long value;
733         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);
734         value = ((((value) * (4))) + (pc));
735         fields->f_disp24 = value;
736       }
737       break;
738     case M32R_OPERAND_DISP8 :
739       {
740         long value;
741         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);
742         value = ((((value) * (4))) + (((pc) & (-4))));
743         fields->f_disp8 = value;
744       }
745       break;
746     case M32R_OPERAND_DR :
747       length = extract_normal (cd, ex_info, insn_value, 0, 0, 4, 4, 32, total_length, pc, & fields->f_r1);
748       break;
749     case M32R_OPERAND_HASH :
750       break;
751     case M32R_OPERAND_HI16 :
752       length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_SIGN_OPT), 0, 16, 16, 32, total_length, pc, & fields->f_hi16);
753       break;
754     case M32R_OPERAND_IMM1 :
755       {
756         long value;
757         length = extract_normal (cd, ex_info, insn_value, 0, 0, 15, 1, 32, total_length, pc, & value);
758         value = ((value) + (1));
759         fields->f_imm1 = value;
760       }
761       break;
762     case M32R_OPERAND_SCR :
763       length = extract_normal (cd, ex_info, insn_value, 0, 0, 12, 4, 32, total_length, pc, & fields->f_r2);
764       break;
765     case M32R_OPERAND_SIMM16 :
766       length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_SIGNED), 0, 16, 16, 32, total_length, pc, & fields->f_simm16);
767       break;
768     case M32R_OPERAND_SIMM8 :
769       length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_SIGNED), 0, 8, 8, 32, total_length, pc, & fields->f_simm8);
770       break;
771     case M32R_OPERAND_SLO16 :
772       length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_SIGNED), 0, 16, 16, 32, total_length, pc, & fields->f_simm16);
773       break;
774     case M32R_OPERAND_SR :
775       length = extract_normal (cd, ex_info, insn_value, 0, 0, 12, 4, 32, total_length, pc, & fields->f_r2);
776       break;
777     case M32R_OPERAND_SRC1 :
778       length = extract_normal (cd, ex_info, insn_value, 0, 0, 4, 4, 32, total_length, pc, & fields->f_r1);
779       break;
780     case M32R_OPERAND_SRC2 :
781       length = extract_normal (cd, ex_info, insn_value, 0, 0, 12, 4, 32, total_length, pc, & fields->f_r2);
782       break;
783     case M32R_OPERAND_UIMM16 :
784       length = extract_normal (cd, ex_info, insn_value, 0, 0, 16, 16, 32, total_length, pc, & fields->f_uimm16);
785       break;
786     case M32R_OPERAND_UIMM24 :
787       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);
788       break;
789     case M32R_OPERAND_UIMM3 :
790       length = extract_normal (cd, ex_info, insn_value, 0, 0, 5, 3, 32, total_length, pc, & fields->f_uimm3);
791       break;
792     case M32R_OPERAND_UIMM4 :
793       length = extract_normal (cd, ex_info, insn_value, 0, 0, 12, 4, 32, total_length, pc, & fields->f_uimm4);
794       break;
795     case M32R_OPERAND_UIMM5 :
796       length = extract_normal (cd, ex_info, insn_value, 0, 0, 11, 5, 32, total_length, pc, & fields->f_uimm5);
797       break;
798     case M32R_OPERAND_UIMM8 :
799       length = extract_normal (cd, ex_info, insn_value, 0, 0, 8, 8, 32, total_length, pc, & fields->f_uimm8);
800       break;
801     case M32R_OPERAND_ULO16 :
802       length = extract_normal (cd, ex_info, insn_value, 0, 0, 16, 16, 32, total_length, pc, & fields->f_uimm16);
803       break;
804 
805     default :
806       /* xgettext:c-format */
807       opcodes_error_handler
808 	(_("internal error: unrecognized field %d while decoding insn"),
809 	 opindex);
810       abort ();
811     }
812 
813   return length;
814 }
815 
816 cgen_insert_fn * const m32r_cgen_insert_handlers[] =
817 {
818   insert_insn_normal,
819 };
820 
821 cgen_extract_fn * const m32r_cgen_extract_handlers[] =
822 {
823   extract_insn_normal,
824 };
825 
826 int m32r_cgen_get_int_operand     (CGEN_CPU_DESC, int, const CGEN_FIELDS *);
827 bfd_vma m32r_cgen_get_vma_operand (CGEN_CPU_DESC, int, const CGEN_FIELDS *);
828 
829 /* Getting values from cgen_fields is handled by a collection of functions.
830    They are distinguished by the type of the VALUE argument they return.
831    TODO: floating point, inlining support, remove cases where result type
832    not appropriate.  */
833 
834 int
835 m32r_cgen_get_int_operand (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
836 			     int opindex,
837 			     const CGEN_FIELDS * fields)
838 {
839   int value;
840 
841   switch (opindex)
842     {
843     case M32R_OPERAND_ACC :
844       value = fields->f_acc;
845       break;
846     case M32R_OPERAND_ACCD :
847       value = fields->f_accd;
848       break;
849     case M32R_OPERAND_ACCS :
850       value = fields->f_accs;
851       break;
852     case M32R_OPERAND_DCR :
853       value = fields->f_r1;
854       break;
855     case M32R_OPERAND_DISP16 :
856       value = fields->f_disp16;
857       break;
858     case M32R_OPERAND_DISP24 :
859       value = fields->f_disp24;
860       break;
861     case M32R_OPERAND_DISP8 :
862       value = fields->f_disp8;
863       break;
864     case M32R_OPERAND_DR :
865       value = fields->f_r1;
866       break;
867     case M32R_OPERAND_HASH :
868       value = 0;
869       break;
870     case M32R_OPERAND_HI16 :
871       value = fields->f_hi16;
872       break;
873     case M32R_OPERAND_IMM1 :
874       value = fields->f_imm1;
875       break;
876     case M32R_OPERAND_SCR :
877       value = fields->f_r2;
878       break;
879     case M32R_OPERAND_SIMM16 :
880       value = fields->f_simm16;
881       break;
882     case M32R_OPERAND_SIMM8 :
883       value = fields->f_simm8;
884       break;
885     case M32R_OPERAND_SLO16 :
886       value = fields->f_simm16;
887       break;
888     case M32R_OPERAND_SR :
889       value = fields->f_r2;
890       break;
891     case M32R_OPERAND_SRC1 :
892       value = fields->f_r1;
893       break;
894     case M32R_OPERAND_SRC2 :
895       value = fields->f_r2;
896       break;
897     case M32R_OPERAND_UIMM16 :
898       value = fields->f_uimm16;
899       break;
900     case M32R_OPERAND_UIMM24 :
901       value = fields->f_uimm24;
902       break;
903     case M32R_OPERAND_UIMM3 :
904       value = fields->f_uimm3;
905       break;
906     case M32R_OPERAND_UIMM4 :
907       value = fields->f_uimm4;
908       break;
909     case M32R_OPERAND_UIMM5 :
910       value = fields->f_uimm5;
911       break;
912     case M32R_OPERAND_UIMM8 :
913       value = fields->f_uimm8;
914       break;
915     case M32R_OPERAND_ULO16 :
916       value = fields->f_uimm16;
917       break;
918 
919     default :
920       /* xgettext:c-format */
921       opcodes_error_handler
922 	(_("internal error: unrecognized field %d while getting int operand"),
923 	 opindex);
924       abort ();
925   }
926 
927   return value;
928 }
929 
930 bfd_vma
931 m32r_cgen_get_vma_operand (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
932 			     int opindex,
933 			     const CGEN_FIELDS * fields)
934 {
935   bfd_vma value;
936 
937   switch (opindex)
938     {
939     case M32R_OPERAND_ACC :
940       value = fields->f_acc;
941       break;
942     case M32R_OPERAND_ACCD :
943       value = fields->f_accd;
944       break;
945     case M32R_OPERAND_ACCS :
946       value = fields->f_accs;
947       break;
948     case M32R_OPERAND_DCR :
949       value = fields->f_r1;
950       break;
951     case M32R_OPERAND_DISP16 :
952       value = fields->f_disp16;
953       break;
954     case M32R_OPERAND_DISP24 :
955       value = fields->f_disp24;
956       break;
957     case M32R_OPERAND_DISP8 :
958       value = fields->f_disp8;
959       break;
960     case M32R_OPERAND_DR :
961       value = fields->f_r1;
962       break;
963     case M32R_OPERAND_HASH :
964       value = 0;
965       break;
966     case M32R_OPERAND_HI16 :
967       value = fields->f_hi16;
968       break;
969     case M32R_OPERAND_IMM1 :
970       value = fields->f_imm1;
971       break;
972     case M32R_OPERAND_SCR :
973       value = fields->f_r2;
974       break;
975     case M32R_OPERAND_SIMM16 :
976       value = fields->f_simm16;
977       break;
978     case M32R_OPERAND_SIMM8 :
979       value = fields->f_simm8;
980       break;
981     case M32R_OPERAND_SLO16 :
982       value = fields->f_simm16;
983       break;
984     case M32R_OPERAND_SR :
985       value = fields->f_r2;
986       break;
987     case M32R_OPERAND_SRC1 :
988       value = fields->f_r1;
989       break;
990     case M32R_OPERAND_SRC2 :
991       value = fields->f_r2;
992       break;
993     case M32R_OPERAND_UIMM16 :
994       value = fields->f_uimm16;
995       break;
996     case M32R_OPERAND_UIMM24 :
997       value = fields->f_uimm24;
998       break;
999     case M32R_OPERAND_UIMM3 :
1000       value = fields->f_uimm3;
1001       break;
1002     case M32R_OPERAND_UIMM4 :
1003       value = fields->f_uimm4;
1004       break;
1005     case M32R_OPERAND_UIMM5 :
1006       value = fields->f_uimm5;
1007       break;
1008     case M32R_OPERAND_UIMM8 :
1009       value = fields->f_uimm8;
1010       break;
1011     case M32R_OPERAND_ULO16 :
1012       value = fields->f_uimm16;
1013       break;
1014 
1015     default :
1016       /* xgettext:c-format */
1017       opcodes_error_handler
1018 	(_("internal error: unrecognized field %d while getting vma operand"),
1019 	 opindex);
1020       abort ();
1021   }
1022 
1023   return value;
1024 }
1025 
1026 void m32r_cgen_set_int_operand  (CGEN_CPU_DESC, int, CGEN_FIELDS *, int);
1027 void m32r_cgen_set_vma_operand  (CGEN_CPU_DESC, int, CGEN_FIELDS *, bfd_vma);
1028 
1029 /* Stuffing values in cgen_fields is handled by a collection of functions.
1030    They are distinguished by the type of the VALUE argument they accept.
1031    TODO: floating point, inlining support, remove cases where argument type
1032    not appropriate.  */
1033 
1034 void
1035 m32r_cgen_set_int_operand (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
1036 			     int opindex,
1037 			     CGEN_FIELDS * fields,
1038 			     int value)
1039 {
1040   switch (opindex)
1041     {
1042     case M32R_OPERAND_ACC :
1043       fields->f_acc = value;
1044       break;
1045     case M32R_OPERAND_ACCD :
1046       fields->f_accd = value;
1047       break;
1048     case M32R_OPERAND_ACCS :
1049       fields->f_accs = value;
1050       break;
1051     case M32R_OPERAND_DCR :
1052       fields->f_r1 = value;
1053       break;
1054     case M32R_OPERAND_DISP16 :
1055       fields->f_disp16 = value;
1056       break;
1057     case M32R_OPERAND_DISP24 :
1058       fields->f_disp24 = value;
1059       break;
1060     case M32R_OPERAND_DISP8 :
1061       fields->f_disp8 = value;
1062       break;
1063     case M32R_OPERAND_DR :
1064       fields->f_r1 = value;
1065       break;
1066     case M32R_OPERAND_HASH :
1067       break;
1068     case M32R_OPERAND_HI16 :
1069       fields->f_hi16 = value;
1070       break;
1071     case M32R_OPERAND_IMM1 :
1072       fields->f_imm1 = value;
1073       break;
1074     case M32R_OPERAND_SCR :
1075       fields->f_r2 = value;
1076       break;
1077     case M32R_OPERAND_SIMM16 :
1078       fields->f_simm16 = value;
1079       break;
1080     case M32R_OPERAND_SIMM8 :
1081       fields->f_simm8 = value;
1082       break;
1083     case M32R_OPERAND_SLO16 :
1084       fields->f_simm16 = value;
1085       break;
1086     case M32R_OPERAND_SR :
1087       fields->f_r2 = value;
1088       break;
1089     case M32R_OPERAND_SRC1 :
1090       fields->f_r1 = value;
1091       break;
1092     case M32R_OPERAND_SRC2 :
1093       fields->f_r2 = value;
1094       break;
1095     case M32R_OPERAND_UIMM16 :
1096       fields->f_uimm16 = value;
1097       break;
1098     case M32R_OPERAND_UIMM24 :
1099       fields->f_uimm24 = value;
1100       break;
1101     case M32R_OPERAND_UIMM3 :
1102       fields->f_uimm3 = value;
1103       break;
1104     case M32R_OPERAND_UIMM4 :
1105       fields->f_uimm4 = value;
1106       break;
1107     case M32R_OPERAND_UIMM5 :
1108       fields->f_uimm5 = value;
1109       break;
1110     case M32R_OPERAND_UIMM8 :
1111       fields->f_uimm8 = value;
1112       break;
1113     case M32R_OPERAND_ULO16 :
1114       fields->f_uimm16 = value;
1115       break;
1116 
1117     default :
1118       /* xgettext:c-format */
1119       opcodes_error_handler
1120 	(_("internal error: unrecognized field %d while setting int operand"),
1121 	 opindex);
1122       abort ();
1123   }
1124 }
1125 
1126 void
1127 m32r_cgen_set_vma_operand (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
1128 			     int opindex,
1129 			     CGEN_FIELDS * fields,
1130 			     bfd_vma value)
1131 {
1132   switch (opindex)
1133     {
1134     case M32R_OPERAND_ACC :
1135       fields->f_acc = value;
1136       break;
1137     case M32R_OPERAND_ACCD :
1138       fields->f_accd = value;
1139       break;
1140     case M32R_OPERAND_ACCS :
1141       fields->f_accs = value;
1142       break;
1143     case M32R_OPERAND_DCR :
1144       fields->f_r1 = value;
1145       break;
1146     case M32R_OPERAND_DISP16 :
1147       fields->f_disp16 = value;
1148       break;
1149     case M32R_OPERAND_DISP24 :
1150       fields->f_disp24 = value;
1151       break;
1152     case M32R_OPERAND_DISP8 :
1153       fields->f_disp8 = value;
1154       break;
1155     case M32R_OPERAND_DR :
1156       fields->f_r1 = value;
1157       break;
1158     case M32R_OPERAND_HASH :
1159       break;
1160     case M32R_OPERAND_HI16 :
1161       fields->f_hi16 = value;
1162       break;
1163     case M32R_OPERAND_IMM1 :
1164       fields->f_imm1 = value;
1165       break;
1166     case M32R_OPERAND_SCR :
1167       fields->f_r2 = value;
1168       break;
1169     case M32R_OPERAND_SIMM16 :
1170       fields->f_simm16 = value;
1171       break;
1172     case M32R_OPERAND_SIMM8 :
1173       fields->f_simm8 = value;
1174       break;
1175     case M32R_OPERAND_SLO16 :
1176       fields->f_simm16 = value;
1177       break;
1178     case M32R_OPERAND_SR :
1179       fields->f_r2 = value;
1180       break;
1181     case M32R_OPERAND_SRC1 :
1182       fields->f_r1 = value;
1183       break;
1184     case M32R_OPERAND_SRC2 :
1185       fields->f_r2 = value;
1186       break;
1187     case M32R_OPERAND_UIMM16 :
1188       fields->f_uimm16 = value;
1189       break;
1190     case M32R_OPERAND_UIMM24 :
1191       fields->f_uimm24 = value;
1192       break;
1193     case M32R_OPERAND_UIMM3 :
1194       fields->f_uimm3 = value;
1195       break;
1196     case M32R_OPERAND_UIMM4 :
1197       fields->f_uimm4 = value;
1198       break;
1199     case M32R_OPERAND_UIMM5 :
1200       fields->f_uimm5 = value;
1201       break;
1202     case M32R_OPERAND_UIMM8 :
1203       fields->f_uimm8 = value;
1204       break;
1205     case M32R_OPERAND_ULO16 :
1206       fields->f_uimm16 = value;
1207       break;
1208 
1209     default :
1210       /* xgettext:c-format */
1211       opcodes_error_handler
1212 	(_("internal error: unrecognized field %d while setting vma operand"),
1213 	 opindex);
1214       abort ();
1215   }
1216 }
1217 
1218 /* Function to call before using the instruction builder tables.  */
1219 
1220 void
1221 m32r_cgen_init_ibld_table (CGEN_CPU_DESC cd)
1222 {
1223   cd->insert_handlers = & m32r_cgen_insert_handlers[0];
1224   cd->extract_handlers = & m32r_cgen_extract_handlers[0];
1225 
1226   cd->insert_operand = m32r_cgen_insert_operand;
1227   cd->extract_operand = m32r_cgen_extract_operand;
1228 
1229   cd->get_int_operand = m32r_cgen_get_int_operand;
1230   cd->set_int_operand = m32r_cgen_set_int_operand;
1231   cd->get_vma_operand = m32r_cgen_get_vma_operand;
1232   cd->set_vma_operand = m32r_cgen_set_vma_operand;
1233 }
1234