1/* Instruction building/extraction support for m32r. -*- C -*-
2
3THIS FILE IS MACHINE GENERATED WITH CGEN: Cpu tools GENerator.
4- the resultant file is machine generated, cgen-ibld.in isn't
5
6Copyright 1996, 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
7
8This file is part of the GNU Binutils and GDB, the GNU debugger.
9
10This program is free software; you can redistribute it and/or modify
11it under the terms of the GNU General Public License as published by
12the Free Software Foundation; either version 2, or (at your option)
13any later version.
14
15This program is distributed in the hope that it will be useful,
16but WITHOUT ANY WARRANTY; without even the implied warranty of
17MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18GNU General Public License for more details.
19
20You should have received a copy of the GNU General Public License
21along with this program; if not, write to the Free Software Foundation, Inc.,
2259 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
46static 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);
49static const char * insert_insn_normal
50  (CGEN_CPU_DESC, const CGEN_INSN *,
51   CGEN_FIELDS *, CGEN_INSN_BYTES_PTR, bfd_vma);
52static 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 *);
56static 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
60static 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
64static CGEN_INLINE void insert_1
65  (CGEN_CPU_DESC, unsigned long, int, int, int, unsigned char *);
66static CGEN_INLINE int fill_cache
67  (CGEN_CPU_DESC, CGEN_EXTRACT_INFO *,  int, int, bfd_vma);
68static 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
78static CGEN_INLINE void
79insert_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
120static const char *
121insert_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
236static const char *
237insert_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
291static void
292put_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
322static CGEN_INLINE int
323fill_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
366static CGEN_INLINE long
367extract_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
411static int
412extract_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
510static int
511extract_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
544const 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
561const char *
562m32r_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
675int 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
694int
695m32r_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
814cgen_insert_fn * const m32r_cgen_insert_handlers[] =
815{
816  insert_insn_normal,
817};
818
819cgen_extract_fn * const m32r_cgen_extract_handlers[] =
820{
821  extract_insn_normal,
822};
823
824int m32r_cgen_get_int_operand
825  PARAMS ((CGEN_CPU_DESC, int, const CGEN_FIELDS *));
826bfd_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
834int
835m32r_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
930bfd_vma
931m32r_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
1026void m32r_cgen_set_int_operand
1027  PARAMS ((CGEN_CPU_DESC, int, CGEN_FIELDS *, int));
1028void 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
1036void
1037m32r_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
1128void
1129m32r_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
1222void
1223m32r_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