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