1/* Instruction building/extraction support for epiphany. -*- 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 (C) 1996-2017 Free Software Foundation, Inc.
7
8   This file is part of libopcodes.
9
10   This library 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 3, or (at your option)
13   any later version.
14
15   It is distributed in the hope that it will be useful, but WITHOUT
16   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
17   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
18   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   51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, 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 "epiphany-desc.h"
34#include "epiphany-opc.h"
35#include "cgen/basic-modes.h"
36#include "opintl.h"
37#include "safe-ctype.h"
38
39#undef  min
40#define min(a,b) ((a) < (b) ? (a) : (b))
41#undef  max
42#define max(a,b) ((a) > (b) ? (a) : (b))
43
44/* Used by the ifield rtx function.  */
45#define FLD(f) (fields->f)
46
47static const char * insert_normal
48  (CGEN_CPU_DESC, long, unsigned int, unsigned int, unsigned int,
49   unsigned int, unsigned int, unsigned int, CGEN_INSN_BYTES_PTR);
50static const char * insert_insn_normal
51  (CGEN_CPU_DESC, const CGEN_INSN *,
52   CGEN_FIELDS *, CGEN_INSN_BYTES_PTR, bfd_vma);
53static int extract_normal
54  (CGEN_CPU_DESC, CGEN_EXTRACT_INFO *, CGEN_INSN_INT,
55   unsigned int, unsigned int, unsigned int, unsigned int,
56   unsigned int, unsigned int, bfd_vma, long *);
57static int extract_insn_normal
58  (CGEN_CPU_DESC, const CGEN_INSN *, CGEN_EXTRACT_INFO *,
59   CGEN_INSN_INT, CGEN_FIELDS *, bfd_vma);
60#if CGEN_INT_INSN_P
61static void put_insn_int_value
62  (CGEN_CPU_DESC, CGEN_INSN_BYTES_PTR, int, int, CGEN_INSN_INT);
63#endif
64#if ! CGEN_INT_INSN_P
65static CGEN_INLINE void insert_1
66  (CGEN_CPU_DESC, unsigned long, int, int, int, unsigned char *);
67static CGEN_INLINE int fill_cache
68  (CGEN_CPU_DESC, CGEN_EXTRACT_INFO *,  int, int, bfd_vma);
69static CGEN_INLINE long extract_1
70  (CGEN_CPU_DESC, CGEN_EXTRACT_INFO *, int, int, int, unsigned char *, bfd_vma);
71#endif
72
73/* Operand insertion.  */
74
75#if ! CGEN_INT_INSN_P
76
77/* Subroutine of insert_normal.  */
78
79static CGEN_INLINE void
80insert_1 (CGEN_CPU_DESC cd,
81	  unsigned long value,
82	  int start,
83	  int length,
84	  int word_length,
85	  unsigned char *bufp)
86{
87  unsigned long x,mask;
88  int shift;
89
90  x = cgen_get_insn_value (cd, bufp, word_length);
91
92  /* Written this way to avoid undefined behaviour.  */
93  mask = (((1L << (length - 1)) - 1) << 1) | 1;
94  if (CGEN_INSN_LSB0_P)
95    shift = (start + 1) - length;
96  else
97    shift = (word_length - (start + length));
98  x = (x & ~(mask << shift)) | ((value & mask) << shift);
99
100  cgen_put_insn_value (cd, bufp, word_length, (bfd_vma) x);
101}
102
103#endif /* ! CGEN_INT_INSN_P */
104
105/* Default insertion routine.
106
107   ATTRS is a mask of the boolean attributes.
108   WORD_OFFSET is the offset in bits from the start of the insn of the value.
109   WORD_LENGTH is the length of the word in bits in which the value resides.
110   START is the starting bit number in the word, architecture origin.
111   LENGTH is the length of VALUE in bits.
112   TOTAL_LENGTH is the total length of the insn in bits.
113
114   The result is an error message or NULL if success.  */
115
116/* ??? This duplicates functionality with bfd's howto table and
117   bfd_install_relocation.  */
118/* ??? This doesn't handle bfd_vma's.  Create another function when
119   necessary.  */
120
121static const char *
122insert_normal (CGEN_CPU_DESC cd,
123	       long value,
124	       unsigned int attrs,
125	       unsigned int word_offset,
126	       unsigned int start,
127	       unsigned int length,
128	       unsigned int word_length,
129	       unsigned int total_length,
130	       CGEN_INSN_BYTES_PTR buffer)
131{
132  static char errbuf[100];
133  /* Written this way to avoid undefined behaviour.  */
134  unsigned long mask = (((1L << (length - 1)) - 1) << 1) | 1;
135
136  /* If LENGTH is zero, this operand doesn't contribute to the value.  */
137  if (length == 0)
138    return NULL;
139
140  if (word_length > 8 * sizeof (CGEN_INSN_INT))
141    abort ();
142
143  /* For architectures with insns smaller than the base-insn-bitsize,
144     word_length may be too big.  */
145  if (cd->min_insn_bitsize < cd->base_insn_bitsize)
146    {
147      if (word_offset == 0
148	  && word_length > total_length)
149	word_length = total_length;
150    }
151
152  /* Ensure VALUE will fit.  */
153  if (CGEN_BOOL_ATTR (attrs, CGEN_IFLD_SIGN_OPT))
154    {
155      long minval = - (1L << (length - 1));
156      unsigned long maxval = mask;
157
158      if ((value > 0 && (unsigned long) value > maxval)
159	  || value < minval)
160	{
161	  /* xgettext:c-format */
162	  sprintf (errbuf,
163		   _("operand out of range (%ld not between %ld and %lu)"),
164		   value, minval, maxval);
165	  return errbuf;
166	}
167    }
168  else if (! CGEN_BOOL_ATTR (attrs, CGEN_IFLD_SIGNED))
169    {
170      unsigned long maxval = mask;
171      unsigned long val = (unsigned long) value;
172
173      /* For hosts with a word size > 32 check to see if value has been sign
174	 extended beyond 32 bits.  If so then ignore these higher sign bits
175	 as the user is attempting to store a 32-bit signed value into an
176	 unsigned 32-bit field which is allowed.  */
177      if (sizeof (unsigned long) > 4 && ((value >> 32) == -1))
178	val &= 0xFFFFFFFF;
179
180      if (val > maxval)
181	{
182	  /* xgettext:c-format */
183	  sprintf (errbuf,
184		   _("operand out of range (0x%lx not between 0 and 0x%lx)"),
185		   val, maxval);
186	  return errbuf;
187	}
188    }
189  else
190    {
191      if (! cgen_signed_overflow_ok_p (cd))
192	{
193	  long minval = - (1L << (length - 1));
194	  long maxval =   (1L << (length - 1)) - 1;
195
196	  if (value < minval || value > maxval)
197	    {
198	      sprintf
199		/* xgettext:c-format */
200		(errbuf, _("operand out of range (%ld not between %ld and %ld)"),
201		 value, minval, maxval);
202	      return errbuf;
203	    }
204	}
205    }
206
207#if CGEN_INT_INSN_P
208
209  {
210    int shift_within_word, shift_to_word, shift;
211
212    /* How to shift the value to BIT0 of the word.  */
213    shift_to_word = total_length - (word_offset + word_length);
214
215    /* How to shift the value to the field within the word.  */
216    if (CGEN_INSN_LSB0_P)
217      shift_within_word = start + 1 - length;
218    else
219      shift_within_word = word_length - start - length;
220
221    /* The total SHIFT, then mask in the value.  */
222    shift = shift_to_word + shift_within_word;
223    *buffer = (*buffer & ~(mask << shift)) | ((value & mask) << shift);
224  }
225
226#else /* ! CGEN_INT_INSN_P */
227
228  {
229    unsigned char *bufp = (unsigned char *) buffer + word_offset / 8;
230
231    insert_1 (cd, value, start, length, word_length, bufp);
232  }
233
234#endif /* ! CGEN_INT_INSN_P */
235
236  return NULL;
237}
238
239/* Default insn builder (insert handler).
240   The instruction is recorded in CGEN_INT_INSN_P byte order (meaning
241   that if CGEN_INSN_BYTES_PTR is an int * and thus, the value is
242   recorded in host byte order, otherwise BUFFER is an array of bytes
243   and the value is recorded in target byte order).
244   The result is an error message or NULL if success.  */
245
246static const char *
247insert_insn_normal (CGEN_CPU_DESC cd,
248		    const CGEN_INSN * insn,
249		    CGEN_FIELDS * fields,
250		    CGEN_INSN_BYTES_PTR buffer,
251		    bfd_vma pc)
252{
253  const CGEN_SYNTAX *syntax = CGEN_INSN_SYNTAX (insn);
254  unsigned long value;
255  const CGEN_SYNTAX_CHAR_TYPE * syn;
256
257  CGEN_INIT_INSERT (cd);
258  value = CGEN_INSN_BASE_VALUE (insn);
259
260  /* If we're recording insns as numbers (rather than a string of bytes),
261     target byte order handling is deferred until later.  */
262
263#if CGEN_INT_INSN_P
264
265  put_insn_int_value (cd, buffer, cd->base_insn_bitsize,
266		      CGEN_FIELDS_BITSIZE (fields), value);
267
268#else
269
270  cgen_put_insn_value (cd, buffer, min ((unsigned) cd->base_insn_bitsize,
271					(unsigned) CGEN_FIELDS_BITSIZE (fields)),
272		       value);
273
274#endif /* ! CGEN_INT_INSN_P */
275
276  /* ??? It would be better to scan the format's fields.
277     Still need to be able to insert a value based on the operand though;
278     e.g. storing a branch displacement that got resolved later.
279     Needs more thought first.  */
280
281  for (syn = CGEN_SYNTAX_STRING (syntax); * syn; ++ syn)
282    {
283      const char *errmsg;
284
285      if (CGEN_SYNTAX_CHAR_P (* syn))
286	continue;
287
288      errmsg = (* cd->insert_operand) (cd, CGEN_SYNTAX_FIELD (*syn),
289				       fields, buffer, pc);
290      if (errmsg)
291	return errmsg;
292    }
293
294  return NULL;
295}
296
297#if CGEN_INT_INSN_P
298/* Cover function to store an insn value into an integral insn.  Must go here
299   because it needs <prefix>-desc.h for CGEN_INT_INSN_P.  */
300
301static void
302put_insn_int_value (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
303		    CGEN_INSN_BYTES_PTR buf,
304		    int length,
305		    int insn_length,
306		    CGEN_INSN_INT value)
307{
308  /* For architectures with insns smaller than the base-insn-bitsize,
309     length may be too big.  */
310  if (length > insn_length)
311    *buf = value;
312  else
313    {
314      int shift = insn_length - length;
315      /* Written this way to avoid undefined behaviour.  */
316      CGEN_INSN_INT mask = (((1L << (length - 1)) - 1) << 1) | 1;
317
318      *buf = (*buf & ~(mask << shift)) | ((value & mask) << shift);
319    }
320}
321#endif
322
323/* Operand extraction.  */
324
325#if ! CGEN_INT_INSN_P
326
327/* Subroutine of extract_normal.
328   Ensure sufficient bytes are cached in EX_INFO.
329   OFFSET is the offset in bytes from the start of the insn of the value.
330   BYTES is the length of the needed value.
331   Returns 1 for success, 0 for failure.  */
332
333static CGEN_INLINE int
334fill_cache (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
335	    CGEN_EXTRACT_INFO *ex_info,
336	    int offset,
337	    int bytes,
338	    bfd_vma pc)
339{
340  /* It's doubtful that the middle part has already been fetched so
341     we don't optimize that case.  kiss.  */
342  unsigned int mask;
343  disassemble_info *info = (disassemble_info *) ex_info->dis_info;
344
345  /* First do a quick check.  */
346  mask = (1 << bytes) - 1;
347  if (((ex_info->valid >> offset) & mask) == mask)
348    return 1;
349
350  /* Search for the first byte we need to read.  */
351  for (mask = 1 << offset; bytes > 0; --bytes, ++offset, mask <<= 1)
352    if (! (mask & ex_info->valid))
353      break;
354
355  if (bytes)
356    {
357      int status;
358
359      pc += offset;
360      status = (*info->read_memory_func)
361	(pc, ex_info->insn_bytes + offset, bytes, info);
362
363      if (status != 0)
364	{
365	  (*info->memory_error_func) (status, pc, info);
366	  return 0;
367	}
368
369      ex_info->valid |= ((1 << bytes) - 1) << offset;
370    }
371
372  return 1;
373}
374
375/* Subroutine of extract_normal.  */
376
377static CGEN_INLINE long
378extract_1 (CGEN_CPU_DESC cd,
379	   CGEN_EXTRACT_INFO *ex_info ATTRIBUTE_UNUSED,
380	   int start,
381	   int length,
382	   int word_length,
383	   unsigned char *bufp,
384	   bfd_vma pc ATTRIBUTE_UNUSED)
385{
386  unsigned long x;
387  int shift;
388
389  x = cgen_get_insn_value (cd, bufp, word_length);
390
391  if (CGEN_INSN_LSB0_P)
392    shift = (start + 1) - length;
393  else
394    shift = (word_length - (start + length));
395  return x >> shift;
396}
397
398#endif /* ! CGEN_INT_INSN_P */
399
400/* Default extraction routine.
401
402   INSN_VALUE is the first base_insn_bitsize bits of the insn in host order,
403   or sometimes less for cases like the m32r where the base insn size is 32
404   but some insns are 16 bits.
405   ATTRS is a mask of the boolean attributes.  We only need `SIGNED',
406   but for generality we take a bitmask of all of them.
407   WORD_OFFSET is the offset in bits from the start of the insn of the value.
408   WORD_LENGTH is the length of the word in bits in which the value resides.
409   START is the starting bit number in the word, architecture origin.
410   LENGTH is the length of VALUE in bits.
411   TOTAL_LENGTH is the total length of the insn in bits.
412
413   Returns 1 for success, 0 for failure.  */
414
415/* ??? The return code isn't properly used.  wip.  */
416
417/* ??? This doesn't handle bfd_vma's.  Create another function when
418   necessary.  */
419
420static int
421extract_normal (CGEN_CPU_DESC cd,
422#if ! CGEN_INT_INSN_P
423		CGEN_EXTRACT_INFO *ex_info,
424#else
425		CGEN_EXTRACT_INFO *ex_info ATTRIBUTE_UNUSED,
426#endif
427		CGEN_INSN_INT insn_value,
428		unsigned int attrs,
429		unsigned int word_offset,
430		unsigned int start,
431		unsigned int length,
432		unsigned int word_length,
433		unsigned int total_length,
434#if ! CGEN_INT_INSN_P
435		bfd_vma pc,
436#else
437		bfd_vma pc ATTRIBUTE_UNUSED,
438#endif
439		long *valuep)
440{
441  long value, mask;
442
443  /* If LENGTH is zero, this operand doesn't contribute to the value
444     so give it a standard value of zero.  */
445  if (length == 0)
446    {
447      *valuep = 0;
448      return 1;
449    }
450
451  if (word_length > 8 * sizeof (CGEN_INSN_INT))
452    abort ();
453
454  /* For architectures with insns smaller than the insn-base-bitsize,
455     word_length may be too big.  */
456  if (cd->min_insn_bitsize < cd->base_insn_bitsize)
457    {
458      if (word_offset + word_length > total_length)
459	word_length = total_length - word_offset;
460    }
461
462  /* Does the value reside in INSN_VALUE, and at the right alignment?  */
463
464  if (CGEN_INT_INSN_P || (word_offset == 0 && word_length == total_length))
465    {
466      if (CGEN_INSN_LSB0_P)
467	value = insn_value >> ((word_offset + start + 1) - length);
468      else
469	value = insn_value >> (total_length - ( word_offset + start + length));
470    }
471
472#if ! CGEN_INT_INSN_P
473
474  else
475    {
476      unsigned char *bufp = ex_info->insn_bytes + word_offset / 8;
477
478      if (word_length > 8 * sizeof (CGEN_INSN_INT))
479	abort ();
480
481      if (fill_cache (cd, ex_info, word_offset / 8, word_length / 8, pc) == 0)
482	return 0;
483
484      value = extract_1 (cd, ex_info, start, length, word_length, bufp, pc);
485    }
486
487#endif /* ! CGEN_INT_INSN_P */
488
489  /* Written this way to avoid undefined behaviour.  */
490  mask = (((1L << (length - 1)) - 1) << 1) | 1;
491
492  value &= mask;
493  /* sign extend? */
494  if (CGEN_BOOL_ATTR (attrs, CGEN_IFLD_SIGNED)
495      && (value & (1L << (length - 1))))
496    value |= ~mask;
497
498  *valuep = value;
499
500  return 1;
501}
502
503/* Default insn extractor.
504
505   INSN_VALUE is the first base_insn_bitsize bits, translated to host order.
506   The extracted fields are stored in FIELDS.
507   EX_INFO is used to handle reading variable length insns.
508   Return the length of the insn in bits, or 0 if no match,
509   or -1 if an error occurs fetching data (memory_error_func will have
510   been called).  */
511
512static int
513extract_insn_normal (CGEN_CPU_DESC cd,
514		     const CGEN_INSN *insn,
515		     CGEN_EXTRACT_INFO *ex_info,
516		     CGEN_INSN_INT insn_value,
517		     CGEN_FIELDS *fields,
518		     bfd_vma pc)
519{
520  const CGEN_SYNTAX *syntax = CGEN_INSN_SYNTAX (insn);
521  const CGEN_SYNTAX_CHAR_TYPE *syn;
522
523  CGEN_FIELDS_BITSIZE (fields) = CGEN_INSN_BITSIZE (insn);
524
525  CGEN_INIT_EXTRACT (cd);
526
527  for (syn = CGEN_SYNTAX_STRING (syntax); *syn; ++syn)
528    {
529      int length;
530
531      if (CGEN_SYNTAX_CHAR_P (*syn))
532	continue;
533
534      length = (* cd->extract_operand) (cd, CGEN_SYNTAX_FIELD (*syn),
535					ex_info, insn_value, fields, pc);
536      if (length <= 0)
537	return length;
538    }
539
540  /* We recognized and successfully extracted this insn.  */
541  return CGEN_INSN_BITSIZE (insn);
542}
543
544/* Machine generated code added here.  */
545
546const char * epiphany_cgen_insert_operand
547  (CGEN_CPU_DESC, int, CGEN_FIELDS *, CGEN_INSN_BYTES_PTR, bfd_vma);
548
549/* Main entry point for operand insertion.
550
551   This function is basically just a big switch statement.  Earlier versions
552   used tables to look up the function to use, but
553   - if the table contains both assembler and disassembler functions then
554     the disassembler contains much of the assembler and vice-versa,
555   - there's a lot of inlining possibilities as things grow,
556   - using a switch statement avoids the function call overhead.
557
558   This function could be moved into `parse_insn_normal', but keeping it
559   separate makes clear the interface between `parse_insn_normal' and each of
560   the handlers.  It's also needed by GAS to insert operands that couldn't be
561   resolved during parsing.  */
562
563const char *
564epiphany_cgen_insert_operand (CGEN_CPU_DESC cd,
565			     int opindex,
566			     CGEN_FIELDS * fields,
567			     CGEN_INSN_BYTES_PTR buffer,
568			     bfd_vma pc ATTRIBUTE_UNUSED)
569{
570  const char * errmsg = NULL;
571  unsigned int total_length = CGEN_FIELDS_BITSIZE (fields);
572
573  switch (opindex)
574    {
575    case EPIPHANY_OPERAND_DIRECTION :
576      errmsg = insert_normal (cd, fields->f_addsubx, 0, 0, 20, 1, 32, total_length, buffer);
577      break;
578    case EPIPHANY_OPERAND_DISP11 :
579      {
580{
581  FLD (f_disp8) = ((((UINT) (FLD (f_disp11)) >> (3))) & (255));
582  FLD (f_disp3) = ((FLD (f_disp11)) & (7));
583}
584        errmsg = insert_normal (cd, fields->f_disp3, 0, 0, 9, 3, 32, total_length, buffer);
585        if (errmsg)
586          break;
587        errmsg = insert_normal (cd, fields->f_disp8, 0, 0, 23, 8, 32, total_length, buffer);
588        if (errmsg)
589          break;
590      }
591      break;
592    case EPIPHANY_OPERAND_DISP3 :
593      errmsg = insert_normal (cd, fields->f_disp3, 0, 0, 9, 3, 32, total_length, buffer);
594      break;
595    case EPIPHANY_OPERAND_DPMI :
596      errmsg = insert_normal (cd, fields->f_subd, 0, 0, 24, 1, 32, total_length, buffer);
597      break;
598    case EPIPHANY_OPERAND_FRD :
599      errmsg = insert_normal (cd, fields->f_rd, 0, 0, 15, 3, 32, total_length, buffer);
600      break;
601    case EPIPHANY_OPERAND_FRD6 :
602      {
603{
604  FLD (f_rd) = ((FLD (f_rd6)) & (7));
605  FLD (f_rd_x) = ((UINT) (FLD (f_rd6)) >> (3));
606}
607        errmsg = insert_normal (cd, fields->f_rd_x, 0, 0, 31, 3, 32, total_length, buffer);
608        if (errmsg)
609          break;
610        errmsg = insert_normal (cd, fields->f_rd, 0, 0, 15, 3, 32, total_length, buffer);
611        if (errmsg)
612          break;
613      }
614      break;
615    case EPIPHANY_OPERAND_FRM :
616      errmsg = insert_normal (cd, fields->f_rm, 0, 0, 9, 3, 32, total_length, buffer);
617      break;
618    case EPIPHANY_OPERAND_FRM6 :
619      {
620{
621  FLD (f_rm) = ((FLD (f_rm6)) & (7));
622  FLD (f_rm_x) = ((UINT) (FLD (f_rm6)) >> (3));
623}
624        errmsg = insert_normal (cd, fields->f_rm_x, 0, 0, 25, 3, 32, total_length, buffer);
625        if (errmsg)
626          break;
627        errmsg = insert_normal (cd, fields->f_rm, 0, 0, 9, 3, 32, total_length, buffer);
628        if (errmsg)
629          break;
630      }
631      break;
632    case EPIPHANY_OPERAND_FRN :
633      errmsg = insert_normal (cd, fields->f_rn, 0, 0, 12, 3, 32, total_length, buffer);
634      break;
635    case EPIPHANY_OPERAND_FRN6 :
636      {
637{
638  FLD (f_rn) = ((FLD (f_rn6)) & (7));
639  FLD (f_rn_x) = ((UINT) (FLD (f_rn6)) >> (3));
640}
641        errmsg = insert_normal (cd, fields->f_rn_x, 0, 0, 28, 3, 32, total_length, buffer);
642        if (errmsg)
643          break;
644        errmsg = insert_normal (cd, fields->f_rn, 0, 0, 12, 3, 32, total_length, buffer);
645        if (errmsg)
646          break;
647      }
648      break;
649    case EPIPHANY_OPERAND_IMM16 :
650      {
651{
652  FLD (f_imm8) = ((FLD (f_imm16)) & (255));
653  FLD (f_imm_27_8) = ((UINT) (FLD (f_imm16)) >> (8));
654}
655        errmsg = insert_normal (cd, fields->f_imm8, 0, 0, 12, 8, 32, total_length, buffer);
656        if (errmsg)
657          break;
658        errmsg = insert_normal (cd, fields->f_imm_27_8, 0, 0, 27, 8, 32, total_length, buffer);
659        if (errmsg)
660          break;
661      }
662      break;
663    case EPIPHANY_OPERAND_IMM8 :
664      errmsg = insert_normal (cd, fields->f_imm8, 0, 0, 12, 8, 32, total_length, buffer);
665      break;
666    case EPIPHANY_OPERAND_RD :
667      errmsg = insert_normal (cd, fields->f_rd, 0, 0, 15, 3, 32, total_length, buffer);
668      break;
669    case EPIPHANY_OPERAND_RD6 :
670      {
671{
672  FLD (f_rd) = ((FLD (f_rd6)) & (7));
673  FLD (f_rd_x) = ((UINT) (FLD (f_rd6)) >> (3));
674}
675        errmsg = insert_normal (cd, fields->f_rd_x, 0, 0, 31, 3, 32, total_length, buffer);
676        if (errmsg)
677          break;
678        errmsg = insert_normal (cd, fields->f_rd, 0, 0, 15, 3, 32, total_length, buffer);
679        if (errmsg)
680          break;
681      }
682      break;
683    case EPIPHANY_OPERAND_RM :
684      errmsg = insert_normal (cd, fields->f_rm, 0, 0, 9, 3, 32, total_length, buffer);
685      break;
686    case EPIPHANY_OPERAND_RM6 :
687      {
688{
689  FLD (f_rm) = ((FLD (f_rm6)) & (7));
690  FLD (f_rm_x) = ((UINT) (FLD (f_rm6)) >> (3));
691}
692        errmsg = insert_normal (cd, fields->f_rm_x, 0, 0, 25, 3, 32, total_length, buffer);
693        if (errmsg)
694          break;
695        errmsg = insert_normal (cd, fields->f_rm, 0, 0, 9, 3, 32, total_length, buffer);
696        if (errmsg)
697          break;
698      }
699      break;
700    case EPIPHANY_OPERAND_RN :
701      errmsg = insert_normal (cd, fields->f_rn, 0, 0, 12, 3, 32, total_length, buffer);
702      break;
703    case EPIPHANY_OPERAND_RN6 :
704      {
705{
706  FLD (f_rn) = ((FLD (f_rn6)) & (7));
707  FLD (f_rn_x) = ((UINT) (FLD (f_rn6)) >> (3));
708}
709        errmsg = insert_normal (cd, fields->f_rn_x, 0, 0, 28, 3, 32, total_length, buffer);
710        if (errmsg)
711          break;
712        errmsg = insert_normal (cd, fields->f_rn, 0, 0, 12, 3, 32, total_length, buffer);
713        if (errmsg)
714          break;
715      }
716      break;
717    case EPIPHANY_OPERAND_SD :
718      errmsg = insert_normal (cd, fields->f_sd, 0, 0, 15, 3, 32, total_length, buffer);
719      break;
720    case EPIPHANY_OPERAND_SD6 :
721      {
722{
723  FLD (f_sd) = ((FLD (f_sd6)) & (7));
724  FLD (f_sd_x) = ((UINT) (FLD (f_sd6)) >> (3));
725}
726        errmsg = insert_normal (cd, fields->f_sd_x, 0, 0, 31, 3, 32, total_length, buffer);
727        if (errmsg)
728          break;
729        errmsg = insert_normal (cd, fields->f_sd, 0, 0, 15, 3, 32, total_length, buffer);
730        if (errmsg)
731          break;
732      }
733      break;
734    case EPIPHANY_OPERAND_SDDMA :
735      {
736{
737  FLD (f_sd) = ((FLD (f_sd6)) & (7));
738  FLD (f_sd_x) = ((UINT) (FLD (f_sd6)) >> (3));
739}
740        errmsg = insert_normal (cd, fields->f_sd_x, 0, 0, 31, 3, 32, total_length, buffer);
741        if (errmsg)
742          break;
743        errmsg = insert_normal (cd, fields->f_sd, 0, 0, 15, 3, 32, total_length, buffer);
744        if (errmsg)
745          break;
746      }
747      break;
748    case EPIPHANY_OPERAND_SDMEM :
749      {
750{
751  FLD (f_sd) = ((FLD (f_sd6)) & (7));
752  FLD (f_sd_x) = ((UINT) (FLD (f_sd6)) >> (3));
753}
754        errmsg = insert_normal (cd, fields->f_sd_x, 0, 0, 31, 3, 32, total_length, buffer);
755        if (errmsg)
756          break;
757        errmsg = insert_normal (cd, fields->f_sd, 0, 0, 15, 3, 32, total_length, buffer);
758        if (errmsg)
759          break;
760      }
761      break;
762    case EPIPHANY_OPERAND_SDMESH :
763      {
764{
765  FLD (f_sd) = ((FLD (f_sd6)) & (7));
766  FLD (f_sd_x) = ((UINT) (FLD (f_sd6)) >> (3));
767}
768        errmsg = insert_normal (cd, fields->f_sd_x, 0, 0, 31, 3, 32, total_length, buffer);
769        if (errmsg)
770          break;
771        errmsg = insert_normal (cd, fields->f_sd, 0, 0, 15, 3, 32, total_length, buffer);
772        if (errmsg)
773          break;
774      }
775      break;
776    case EPIPHANY_OPERAND_SHIFT :
777      errmsg = insert_normal (cd, fields->f_shift, 0, 0, 9, 5, 32, total_length, buffer);
778      break;
779    case EPIPHANY_OPERAND_SIMM11 :
780      {
781{
782  FLD (f_disp8) = ((255) & (((USI) (FLD (f_sdisp11)) >> (3))));
783  FLD (f_disp3) = ((FLD (f_sdisp11)) & (7));
784}
785        errmsg = insert_normal (cd, fields->f_disp3, 0, 0, 9, 3, 32, total_length, buffer);
786        if (errmsg)
787          break;
788        errmsg = insert_normal (cd, fields->f_disp8, 0, 0, 23, 8, 32, total_length, buffer);
789        if (errmsg)
790          break;
791      }
792      break;
793    case EPIPHANY_OPERAND_SIMM24 :
794      {
795        long value = fields->f_simm24;
796        value = ((SI) (((value) - (pc))) >> (1));
797        errmsg = insert_normal (cd, value, 0|(1<<CGEN_IFLD_SIGNED)|(1<<CGEN_IFLD_RELOC)|(1<<CGEN_IFLD_PCREL_ADDR), 0, 31, 24, 32, total_length, buffer);
798      }
799      break;
800    case EPIPHANY_OPERAND_SIMM3 :
801      errmsg = insert_normal (cd, fields->f_sdisp3, 0|(1<<CGEN_IFLD_SIGNED), 0, 9, 3, 32, total_length, buffer);
802      break;
803    case EPIPHANY_OPERAND_SIMM8 :
804      {
805        long value = fields->f_simm8;
806        value = ((SI) (((value) - (pc))) >> (1));
807        errmsg = insert_normal (cd, value, 0|(1<<CGEN_IFLD_SIGNED)|(1<<CGEN_IFLD_RELOC)|(1<<CGEN_IFLD_PCREL_ADDR), 0, 15, 8, 32, total_length, buffer);
808      }
809      break;
810    case EPIPHANY_OPERAND_SN :
811      errmsg = insert_normal (cd, fields->f_sn, 0, 0, 12, 3, 32, total_length, buffer);
812      break;
813    case EPIPHANY_OPERAND_SN6 :
814      {
815{
816  FLD (f_sn) = ((FLD (f_sn6)) & (7));
817  FLD (f_sn_x) = ((UINT) (FLD (f_sn6)) >> (3));
818}
819        errmsg = insert_normal (cd, fields->f_sn_x, 0, 0, 28, 3, 32, total_length, buffer);
820        if (errmsg)
821          break;
822        errmsg = insert_normal (cd, fields->f_sn, 0, 0, 12, 3, 32, total_length, buffer);
823        if (errmsg)
824          break;
825      }
826      break;
827    case EPIPHANY_OPERAND_SNDMA :
828      {
829{
830  FLD (f_sn) = ((FLD (f_sn6)) & (7));
831  FLD (f_sn_x) = ((UINT) (FLD (f_sn6)) >> (3));
832}
833        errmsg = insert_normal (cd, fields->f_sn_x, 0, 0, 28, 3, 32, total_length, buffer);
834        if (errmsg)
835          break;
836        errmsg = insert_normal (cd, fields->f_sn, 0, 0, 12, 3, 32, total_length, buffer);
837        if (errmsg)
838          break;
839      }
840      break;
841    case EPIPHANY_OPERAND_SNMEM :
842      {
843{
844  FLD (f_sn) = ((FLD (f_sn6)) & (7));
845  FLD (f_sn_x) = ((UINT) (FLD (f_sn6)) >> (3));
846}
847        errmsg = insert_normal (cd, fields->f_sn_x, 0, 0, 28, 3, 32, total_length, buffer);
848        if (errmsg)
849          break;
850        errmsg = insert_normal (cd, fields->f_sn, 0, 0, 12, 3, 32, total_length, buffer);
851        if (errmsg)
852          break;
853      }
854      break;
855    case EPIPHANY_OPERAND_SNMESH :
856      {
857{
858  FLD (f_sn) = ((FLD (f_sn6)) & (7));
859  FLD (f_sn_x) = ((UINT) (FLD (f_sn6)) >> (3));
860}
861        errmsg = insert_normal (cd, fields->f_sn_x, 0, 0, 28, 3, 32, total_length, buffer);
862        if (errmsg)
863          break;
864        errmsg = insert_normal (cd, fields->f_sn, 0, 0, 12, 3, 32, total_length, buffer);
865        if (errmsg)
866          break;
867      }
868      break;
869    case EPIPHANY_OPERAND_SWI_NUM :
870      errmsg = insert_normal (cd, fields->f_trap_num, 0, 0, 15, 6, 32, total_length, buffer);
871      break;
872    case EPIPHANY_OPERAND_TRAPNUM6 :
873      errmsg = insert_normal (cd, fields->f_trap_num, 0, 0, 15, 6, 32, total_length, buffer);
874      break;
875
876    default :
877      /* xgettext:c-format */
878      fprintf (stderr, _("Unrecognized field %d while building insn.\n"),
879	       opindex);
880      abort ();
881  }
882
883  return errmsg;
884}
885
886int epiphany_cgen_extract_operand
887  (CGEN_CPU_DESC, int, CGEN_EXTRACT_INFO *, CGEN_INSN_INT, CGEN_FIELDS *, bfd_vma);
888
889/* Main entry point for operand extraction.
890   The result is <= 0 for error, >0 for success.
891   ??? Actual values aren't well defined right now.
892
893   This function is basically just a big switch statement.  Earlier versions
894   used tables to look up the function to use, but
895   - if the table contains both assembler and disassembler functions then
896     the disassembler contains much of the assembler and vice-versa,
897   - there's a lot of inlining possibilities as things grow,
898   - using a switch statement avoids the function call overhead.
899
900   This function could be moved into `print_insn_normal', but keeping it
901   separate makes clear the interface between `print_insn_normal' and each of
902   the handlers.  */
903
904int
905epiphany_cgen_extract_operand (CGEN_CPU_DESC cd,
906			     int opindex,
907			     CGEN_EXTRACT_INFO *ex_info,
908			     CGEN_INSN_INT insn_value,
909			     CGEN_FIELDS * fields,
910			     bfd_vma pc)
911{
912  /* Assume success (for those operands that are nops).  */
913  int length = 1;
914  unsigned int total_length = CGEN_FIELDS_BITSIZE (fields);
915
916  switch (opindex)
917    {
918    case EPIPHANY_OPERAND_DIRECTION :
919      length = extract_normal (cd, ex_info, insn_value, 0, 0, 20, 1, 32, total_length, pc, & fields->f_addsubx);
920      break;
921    case EPIPHANY_OPERAND_DISP11 :
922      {
923        length = extract_normal (cd, ex_info, insn_value, 0, 0, 9, 3, 32, total_length, pc, & fields->f_disp3);
924        if (length <= 0) break;
925        length = extract_normal (cd, ex_info, insn_value, 0, 0, 23, 8, 32, total_length, pc, & fields->f_disp8);
926        if (length <= 0) break;
927{
928  FLD (f_disp11) = ((((FLD (f_disp8)) << (3))) | (FLD (f_disp3)));
929}
930      }
931      break;
932    case EPIPHANY_OPERAND_DISP3 :
933      length = extract_normal (cd, ex_info, insn_value, 0, 0, 9, 3, 32, total_length, pc, & fields->f_disp3);
934      break;
935    case EPIPHANY_OPERAND_DPMI :
936      length = extract_normal (cd, ex_info, insn_value, 0, 0, 24, 1, 32, total_length, pc, & fields->f_subd);
937      break;
938    case EPIPHANY_OPERAND_FRD :
939      length = extract_normal (cd, ex_info, insn_value, 0, 0, 15, 3, 32, total_length, pc, & fields->f_rd);
940      break;
941    case EPIPHANY_OPERAND_FRD6 :
942      {
943        length = extract_normal (cd, ex_info, insn_value, 0, 0, 31, 3, 32, total_length, pc, & fields->f_rd_x);
944        if (length <= 0) break;
945        length = extract_normal (cd, ex_info, insn_value, 0, 0, 15, 3, 32, total_length, pc, & fields->f_rd);
946        if (length <= 0) break;
947{
948  FLD (f_rd6) = ((((FLD (f_rd_x)) << (3))) | (FLD (f_rd)));
949}
950      }
951      break;
952    case EPIPHANY_OPERAND_FRM :
953      length = extract_normal (cd, ex_info, insn_value, 0, 0, 9, 3, 32, total_length, pc, & fields->f_rm);
954      break;
955    case EPIPHANY_OPERAND_FRM6 :
956      {
957        length = extract_normal (cd, ex_info, insn_value, 0, 0, 25, 3, 32, total_length, pc, & fields->f_rm_x);
958        if (length <= 0) break;
959        length = extract_normal (cd, ex_info, insn_value, 0, 0, 9, 3, 32, total_length, pc, & fields->f_rm);
960        if (length <= 0) break;
961{
962  FLD (f_rm6) = ((((FLD (f_rm_x)) << (3))) | (FLD (f_rm)));
963}
964      }
965      break;
966    case EPIPHANY_OPERAND_FRN :
967      length = extract_normal (cd, ex_info, insn_value, 0, 0, 12, 3, 32, total_length, pc, & fields->f_rn);
968      break;
969    case EPIPHANY_OPERAND_FRN6 :
970      {
971        length = extract_normal (cd, ex_info, insn_value, 0, 0, 28, 3, 32, total_length, pc, & fields->f_rn_x);
972        if (length <= 0) break;
973        length = extract_normal (cd, ex_info, insn_value, 0, 0, 12, 3, 32, total_length, pc, & fields->f_rn);
974        if (length <= 0) break;
975{
976  FLD (f_rn6) = ((((FLD (f_rn_x)) << (3))) | (FLD (f_rn)));
977}
978      }
979      break;
980    case EPIPHANY_OPERAND_IMM16 :
981      {
982        length = extract_normal (cd, ex_info, insn_value, 0, 0, 12, 8, 32, total_length, pc, & fields->f_imm8);
983        if (length <= 0) break;
984        length = extract_normal (cd, ex_info, insn_value, 0, 0, 27, 8, 32, total_length, pc, & fields->f_imm_27_8);
985        if (length <= 0) break;
986{
987  FLD (f_imm16) = ((((FLD (f_imm_27_8)) << (8))) | (FLD (f_imm8)));
988}
989      }
990      break;
991    case EPIPHANY_OPERAND_IMM8 :
992      length = extract_normal (cd, ex_info, insn_value, 0, 0, 12, 8, 32, total_length, pc, & fields->f_imm8);
993      break;
994    case EPIPHANY_OPERAND_RD :
995      length = extract_normal (cd, ex_info, insn_value, 0, 0, 15, 3, 32, total_length, pc, & fields->f_rd);
996      break;
997    case EPIPHANY_OPERAND_RD6 :
998      {
999        length = extract_normal (cd, ex_info, insn_value, 0, 0, 31, 3, 32, total_length, pc, & fields->f_rd_x);
1000        if (length <= 0) break;
1001        length = extract_normal (cd, ex_info, insn_value, 0, 0, 15, 3, 32, total_length, pc, & fields->f_rd);
1002        if (length <= 0) break;
1003{
1004  FLD (f_rd6) = ((((FLD (f_rd_x)) << (3))) | (FLD (f_rd)));
1005}
1006      }
1007      break;
1008    case EPIPHANY_OPERAND_RM :
1009      length = extract_normal (cd, ex_info, insn_value, 0, 0, 9, 3, 32, total_length, pc, & fields->f_rm);
1010      break;
1011    case EPIPHANY_OPERAND_RM6 :
1012      {
1013        length = extract_normal (cd, ex_info, insn_value, 0, 0, 25, 3, 32, total_length, pc, & fields->f_rm_x);
1014        if (length <= 0) break;
1015        length = extract_normal (cd, ex_info, insn_value, 0, 0, 9, 3, 32, total_length, pc, & fields->f_rm);
1016        if (length <= 0) break;
1017{
1018  FLD (f_rm6) = ((((FLD (f_rm_x)) << (3))) | (FLD (f_rm)));
1019}
1020      }
1021      break;
1022    case EPIPHANY_OPERAND_RN :
1023      length = extract_normal (cd, ex_info, insn_value, 0, 0, 12, 3, 32, total_length, pc, & fields->f_rn);
1024      break;
1025    case EPIPHANY_OPERAND_RN6 :
1026      {
1027        length = extract_normal (cd, ex_info, insn_value, 0, 0, 28, 3, 32, total_length, pc, & fields->f_rn_x);
1028        if (length <= 0) break;
1029        length = extract_normal (cd, ex_info, insn_value, 0, 0, 12, 3, 32, total_length, pc, & fields->f_rn);
1030        if (length <= 0) break;
1031{
1032  FLD (f_rn6) = ((((FLD (f_rn_x)) << (3))) | (FLD (f_rn)));
1033}
1034      }
1035      break;
1036    case EPIPHANY_OPERAND_SD :
1037      length = extract_normal (cd, ex_info, insn_value, 0, 0, 15, 3, 32, total_length, pc, & fields->f_sd);
1038      break;
1039    case EPIPHANY_OPERAND_SD6 :
1040      {
1041        length = extract_normal (cd, ex_info, insn_value, 0, 0, 31, 3, 32, total_length, pc, & fields->f_sd_x);
1042        if (length <= 0) break;
1043        length = extract_normal (cd, ex_info, insn_value, 0, 0, 15, 3, 32, total_length, pc, & fields->f_sd);
1044        if (length <= 0) break;
1045{
1046  FLD (f_sd6) = ((((FLD (f_sd_x)) << (3))) | (FLD (f_sd)));
1047}
1048      }
1049      break;
1050    case EPIPHANY_OPERAND_SDDMA :
1051      {
1052        length = extract_normal (cd, ex_info, insn_value, 0, 0, 31, 3, 32, total_length, pc, & fields->f_sd_x);
1053        if (length <= 0) break;
1054        length = extract_normal (cd, ex_info, insn_value, 0, 0, 15, 3, 32, total_length, pc, & fields->f_sd);
1055        if (length <= 0) break;
1056{
1057  FLD (f_sd6) = ((((FLD (f_sd_x)) << (3))) | (FLD (f_sd)));
1058}
1059      }
1060      break;
1061    case EPIPHANY_OPERAND_SDMEM :
1062      {
1063        length = extract_normal (cd, ex_info, insn_value, 0, 0, 31, 3, 32, total_length, pc, & fields->f_sd_x);
1064        if (length <= 0) break;
1065        length = extract_normal (cd, ex_info, insn_value, 0, 0, 15, 3, 32, total_length, pc, & fields->f_sd);
1066        if (length <= 0) break;
1067{
1068  FLD (f_sd6) = ((((FLD (f_sd_x)) << (3))) | (FLD (f_sd)));
1069}
1070      }
1071      break;
1072    case EPIPHANY_OPERAND_SDMESH :
1073      {
1074        length = extract_normal (cd, ex_info, insn_value, 0, 0, 31, 3, 32, total_length, pc, & fields->f_sd_x);
1075        if (length <= 0) break;
1076        length = extract_normal (cd, ex_info, insn_value, 0, 0, 15, 3, 32, total_length, pc, & fields->f_sd);
1077        if (length <= 0) break;
1078{
1079  FLD (f_sd6) = ((((FLD (f_sd_x)) << (3))) | (FLD (f_sd)));
1080}
1081      }
1082      break;
1083    case EPIPHANY_OPERAND_SHIFT :
1084      length = extract_normal (cd, ex_info, insn_value, 0, 0, 9, 5, 32, total_length, pc, & fields->f_shift);
1085      break;
1086    case EPIPHANY_OPERAND_SIMM11 :
1087      {
1088        length = extract_normal (cd, ex_info, insn_value, 0, 0, 9, 3, 32, total_length, pc, & fields->f_disp3);
1089        if (length <= 0) break;
1090        length = extract_normal (cd, ex_info, insn_value, 0, 0, 23, 8, 32, total_length, pc, & fields->f_disp8);
1091        if (length <= 0) break;
1092{
1093  FLD (f_sdisp11) = ((SI) (((((((FLD (f_disp8)) << (3))) | (FLD (f_disp3)))) << (21))) >> (21));
1094}
1095      }
1096      break;
1097    case EPIPHANY_OPERAND_SIMM24 :
1098      {
1099        long value;
1100        length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_SIGNED)|(1<<CGEN_IFLD_RELOC)|(1<<CGEN_IFLD_PCREL_ADDR), 0, 31, 24, 32, total_length, pc, & value);
1101        value = ((((value) << (1))) + (pc));
1102        fields->f_simm24 = value;
1103      }
1104      break;
1105    case EPIPHANY_OPERAND_SIMM3 :
1106      length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_SIGNED), 0, 9, 3, 32, total_length, pc, & fields->f_sdisp3);
1107      break;
1108    case EPIPHANY_OPERAND_SIMM8 :
1109      {
1110        long value;
1111        length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_SIGNED)|(1<<CGEN_IFLD_RELOC)|(1<<CGEN_IFLD_PCREL_ADDR), 0, 15, 8, 32, total_length, pc, & value);
1112        value = ((((value) << (1))) + (pc));
1113        fields->f_simm8 = value;
1114      }
1115      break;
1116    case EPIPHANY_OPERAND_SN :
1117      length = extract_normal (cd, ex_info, insn_value, 0, 0, 12, 3, 32, total_length, pc, & fields->f_sn);
1118      break;
1119    case EPIPHANY_OPERAND_SN6 :
1120      {
1121        length = extract_normal (cd, ex_info, insn_value, 0, 0, 28, 3, 32, total_length, pc, & fields->f_sn_x);
1122        if (length <= 0) break;
1123        length = extract_normal (cd, ex_info, insn_value, 0, 0, 12, 3, 32, total_length, pc, & fields->f_sn);
1124        if (length <= 0) break;
1125{
1126  FLD (f_sn6) = ((((FLD (f_sn_x)) << (3))) | (FLD (f_sn)));
1127}
1128      }
1129      break;
1130    case EPIPHANY_OPERAND_SNDMA :
1131      {
1132        length = extract_normal (cd, ex_info, insn_value, 0, 0, 28, 3, 32, total_length, pc, & fields->f_sn_x);
1133        if (length <= 0) break;
1134        length = extract_normal (cd, ex_info, insn_value, 0, 0, 12, 3, 32, total_length, pc, & fields->f_sn);
1135        if (length <= 0) break;
1136{
1137  FLD (f_sn6) = ((((FLD (f_sn_x)) << (3))) | (FLD (f_sn)));
1138}
1139      }
1140      break;
1141    case EPIPHANY_OPERAND_SNMEM :
1142      {
1143        length = extract_normal (cd, ex_info, insn_value, 0, 0, 28, 3, 32, total_length, pc, & fields->f_sn_x);
1144        if (length <= 0) break;
1145        length = extract_normal (cd, ex_info, insn_value, 0, 0, 12, 3, 32, total_length, pc, & fields->f_sn);
1146        if (length <= 0) break;
1147{
1148  FLD (f_sn6) = ((((FLD (f_sn_x)) << (3))) | (FLD (f_sn)));
1149}
1150      }
1151      break;
1152    case EPIPHANY_OPERAND_SNMESH :
1153      {
1154        length = extract_normal (cd, ex_info, insn_value, 0, 0, 28, 3, 32, total_length, pc, & fields->f_sn_x);
1155        if (length <= 0) break;
1156        length = extract_normal (cd, ex_info, insn_value, 0, 0, 12, 3, 32, total_length, pc, & fields->f_sn);
1157        if (length <= 0) break;
1158{
1159  FLD (f_sn6) = ((((FLD (f_sn_x)) << (3))) | (FLD (f_sn)));
1160}
1161      }
1162      break;
1163    case EPIPHANY_OPERAND_SWI_NUM :
1164      length = extract_normal (cd, ex_info, insn_value, 0, 0, 15, 6, 32, total_length, pc, & fields->f_trap_num);
1165      break;
1166    case EPIPHANY_OPERAND_TRAPNUM6 :
1167      length = extract_normal (cd, ex_info, insn_value, 0, 0, 15, 6, 32, total_length, pc, & fields->f_trap_num);
1168      break;
1169
1170    default :
1171      /* xgettext:c-format */
1172      fprintf (stderr, _("Unrecognized field %d while decoding insn.\n"),
1173	       opindex);
1174      abort ();
1175    }
1176
1177  return length;
1178}
1179
1180cgen_insert_fn * const epiphany_cgen_insert_handlers[] =
1181{
1182  insert_insn_normal,
1183};
1184
1185cgen_extract_fn * const epiphany_cgen_extract_handlers[] =
1186{
1187  extract_insn_normal,
1188};
1189
1190int epiphany_cgen_get_int_operand     (CGEN_CPU_DESC, int, const CGEN_FIELDS *);
1191bfd_vma epiphany_cgen_get_vma_operand (CGEN_CPU_DESC, int, const CGEN_FIELDS *);
1192
1193/* Getting values from cgen_fields is handled by a collection of functions.
1194   They are distinguished by the type of the VALUE argument they return.
1195   TODO: floating point, inlining support, remove cases where result type
1196   not appropriate.  */
1197
1198int
1199epiphany_cgen_get_int_operand (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
1200			     int opindex,
1201			     const CGEN_FIELDS * fields)
1202{
1203  int value;
1204
1205  switch (opindex)
1206    {
1207    case EPIPHANY_OPERAND_DIRECTION :
1208      value = fields->f_addsubx;
1209      break;
1210    case EPIPHANY_OPERAND_DISP11 :
1211      value = fields->f_disp11;
1212      break;
1213    case EPIPHANY_OPERAND_DISP3 :
1214      value = fields->f_disp3;
1215      break;
1216    case EPIPHANY_OPERAND_DPMI :
1217      value = fields->f_subd;
1218      break;
1219    case EPIPHANY_OPERAND_FRD :
1220      value = fields->f_rd;
1221      break;
1222    case EPIPHANY_OPERAND_FRD6 :
1223      value = fields->f_rd6;
1224      break;
1225    case EPIPHANY_OPERAND_FRM :
1226      value = fields->f_rm;
1227      break;
1228    case EPIPHANY_OPERAND_FRM6 :
1229      value = fields->f_rm6;
1230      break;
1231    case EPIPHANY_OPERAND_FRN :
1232      value = fields->f_rn;
1233      break;
1234    case EPIPHANY_OPERAND_FRN6 :
1235      value = fields->f_rn6;
1236      break;
1237    case EPIPHANY_OPERAND_IMM16 :
1238      value = fields->f_imm16;
1239      break;
1240    case EPIPHANY_OPERAND_IMM8 :
1241      value = fields->f_imm8;
1242      break;
1243    case EPIPHANY_OPERAND_RD :
1244      value = fields->f_rd;
1245      break;
1246    case EPIPHANY_OPERAND_RD6 :
1247      value = fields->f_rd6;
1248      break;
1249    case EPIPHANY_OPERAND_RM :
1250      value = fields->f_rm;
1251      break;
1252    case EPIPHANY_OPERAND_RM6 :
1253      value = fields->f_rm6;
1254      break;
1255    case EPIPHANY_OPERAND_RN :
1256      value = fields->f_rn;
1257      break;
1258    case EPIPHANY_OPERAND_RN6 :
1259      value = fields->f_rn6;
1260      break;
1261    case EPIPHANY_OPERAND_SD :
1262      value = fields->f_sd;
1263      break;
1264    case EPIPHANY_OPERAND_SD6 :
1265      value = fields->f_sd6;
1266      break;
1267    case EPIPHANY_OPERAND_SDDMA :
1268      value = fields->f_sd6;
1269      break;
1270    case EPIPHANY_OPERAND_SDMEM :
1271      value = fields->f_sd6;
1272      break;
1273    case EPIPHANY_OPERAND_SDMESH :
1274      value = fields->f_sd6;
1275      break;
1276    case EPIPHANY_OPERAND_SHIFT :
1277      value = fields->f_shift;
1278      break;
1279    case EPIPHANY_OPERAND_SIMM11 :
1280      value = fields->f_sdisp11;
1281      break;
1282    case EPIPHANY_OPERAND_SIMM24 :
1283      value = fields->f_simm24;
1284      break;
1285    case EPIPHANY_OPERAND_SIMM3 :
1286      value = fields->f_sdisp3;
1287      break;
1288    case EPIPHANY_OPERAND_SIMM8 :
1289      value = fields->f_simm8;
1290      break;
1291    case EPIPHANY_OPERAND_SN :
1292      value = fields->f_sn;
1293      break;
1294    case EPIPHANY_OPERAND_SN6 :
1295      value = fields->f_sn6;
1296      break;
1297    case EPIPHANY_OPERAND_SNDMA :
1298      value = fields->f_sn6;
1299      break;
1300    case EPIPHANY_OPERAND_SNMEM :
1301      value = fields->f_sn6;
1302      break;
1303    case EPIPHANY_OPERAND_SNMESH :
1304      value = fields->f_sn6;
1305      break;
1306    case EPIPHANY_OPERAND_SWI_NUM :
1307      value = fields->f_trap_num;
1308      break;
1309    case EPIPHANY_OPERAND_TRAPNUM6 :
1310      value = fields->f_trap_num;
1311      break;
1312
1313    default :
1314      /* xgettext:c-format */
1315      fprintf (stderr, _("Unrecognized field %d while getting int operand.\n"),
1316		       opindex);
1317      abort ();
1318  }
1319
1320  return value;
1321}
1322
1323bfd_vma
1324epiphany_cgen_get_vma_operand (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
1325			     int opindex,
1326			     const CGEN_FIELDS * fields)
1327{
1328  bfd_vma value;
1329
1330  switch (opindex)
1331    {
1332    case EPIPHANY_OPERAND_DIRECTION :
1333      value = fields->f_addsubx;
1334      break;
1335    case EPIPHANY_OPERAND_DISP11 :
1336      value = fields->f_disp11;
1337      break;
1338    case EPIPHANY_OPERAND_DISP3 :
1339      value = fields->f_disp3;
1340      break;
1341    case EPIPHANY_OPERAND_DPMI :
1342      value = fields->f_subd;
1343      break;
1344    case EPIPHANY_OPERAND_FRD :
1345      value = fields->f_rd;
1346      break;
1347    case EPIPHANY_OPERAND_FRD6 :
1348      value = fields->f_rd6;
1349      break;
1350    case EPIPHANY_OPERAND_FRM :
1351      value = fields->f_rm;
1352      break;
1353    case EPIPHANY_OPERAND_FRM6 :
1354      value = fields->f_rm6;
1355      break;
1356    case EPIPHANY_OPERAND_FRN :
1357      value = fields->f_rn;
1358      break;
1359    case EPIPHANY_OPERAND_FRN6 :
1360      value = fields->f_rn6;
1361      break;
1362    case EPIPHANY_OPERAND_IMM16 :
1363      value = fields->f_imm16;
1364      break;
1365    case EPIPHANY_OPERAND_IMM8 :
1366      value = fields->f_imm8;
1367      break;
1368    case EPIPHANY_OPERAND_RD :
1369      value = fields->f_rd;
1370      break;
1371    case EPIPHANY_OPERAND_RD6 :
1372      value = fields->f_rd6;
1373      break;
1374    case EPIPHANY_OPERAND_RM :
1375      value = fields->f_rm;
1376      break;
1377    case EPIPHANY_OPERAND_RM6 :
1378      value = fields->f_rm6;
1379      break;
1380    case EPIPHANY_OPERAND_RN :
1381      value = fields->f_rn;
1382      break;
1383    case EPIPHANY_OPERAND_RN6 :
1384      value = fields->f_rn6;
1385      break;
1386    case EPIPHANY_OPERAND_SD :
1387      value = fields->f_sd;
1388      break;
1389    case EPIPHANY_OPERAND_SD6 :
1390      value = fields->f_sd6;
1391      break;
1392    case EPIPHANY_OPERAND_SDDMA :
1393      value = fields->f_sd6;
1394      break;
1395    case EPIPHANY_OPERAND_SDMEM :
1396      value = fields->f_sd6;
1397      break;
1398    case EPIPHANY_OPERAND_SDMESH :
1399      value = fields->f_sd6;
1400      break;
1401    case EPIPHANY_OPERAND_SHIFT :
1402      value = fields->f_shift;
1403      break;
1404    case EPIPHANY_OPERAND_SIMM11 :
1405      value = fields->f_sdisp11;
1406      break;
1407    case EPIPHANY_OPERAND_SIMM24 :
1408      value = fields->f_simm24;
1409      break;
1410    case EPIPHANY_OPERAND_SIMM3 :
1411      value = fields->f_sdisp3;
1412      break;
1413    case EPIPHANY_OPERAND_SIMM8 :
1414      value = fields->f_simm8;
1415      break;
1416    case EPIPHANY_OPERAND_SN :
1417      value = fields->f_sn;
1418      break;
1419    case EPIPHANY_OPERAND_SN6 :
1420      value = fields->f_sn6;
1421      break;
1422    case EPIPHANY_OPERAND_SNDMA :
1423      value = fields->f_sn6;
1424      break;
1425    case EPIPHANY_OPERAND_SNMEM :
1426      value = fields->f_sn6;
1427      break;
1428    case EPIPHANY_OPERAND_SNMESH :
1429      value = fields->f_sn6;
1430      break;
1431    case EPIPHANY_OPERAND_SWI_NUM :
1432      value = fields->f_trap_num;
1433      break;
1434    case EPIPHANY_OPERAND_TRAPNUM6 :
1435      value = fields->f_trap_num;
1436      break;
1437
1438    default :
1439      /* xgettext:c-format */
1440      fprintf (stderr, _("Unrecognized field %d while getting vma operand.\n"),
1441		       opindex);
1442      abort ();
1443  }
1444
1445  return value;
1446}
1447
1448void epiphany_cgen_set_int_operand  (CGEN_CPU_DESC, int, CGEN_FIELDS *, int);
1449void epiphany_cgen_set_vma_operand  (CGEN_CPU_DESC, int, CGEN_FIELDS *, bfd_vma);
1450
1451/* Stuffing values in cgen_fields is handled by a collection of functions.
1452   They are distinguished by the type of the VALUE argument they accept.
1453   TODO: floating point, inlining support, remove cases where argument type
1454   not appropriate.  */
1455
1456void
1457epiphany_cgen_set_int_operand (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
1458			     int opindex,
1459			     CGEN_FIELDS * fields,
1460			     int value)
1461{
1462  switch (opindex)
1463    {
1464    case EPIPHANY_OPERAND_DIRECTION :
1465      fields->f_addsubx = value;
1466      break;
1467    case EPIPHANY_OPERAND_DISP11 :
1468      fields->f_disp11 = value;
1469      break;
1470    case EPIPHANY_OPERAND_DISP3 :
1471      fields->f_disp3 = value;
1472      break;
1473    case EPIPHANY_OPERAND_DPMI :
1474      fields->f_subd = value;
1475      break;
1476    case EPIPHANY_OPERAND_FRD :
1477      fields->f_rd = value;
1478      break;
1479    case EPIPHANY_OPERAND_FRD6 :
1480      fields->f_rd6 = value;
1481      break;
1482    case EPIPHANY_OPERAND_FRM :
1483      fields->f_rm = value;
1484      break;
1485    case EPIPHANY_OPERAND_FRM6 :
1486      fields->f_rm6 = value;
1487      break;
1488    case EPIPHANY_OPERAND_FRN :
1489      fields->f_rn = value;
1490      break;
1491    case EPIPHANY_OPERAND_FRN6 :
1492      fields->f_rn6 = value;
1493      break;
1494    case EPIPHANY_OPERAND_IMM16 :
1495      fields->f_imm16 = value;
1496      break;
1497    case EPIPHANY_OPERAND_IMM8 :
1498      fields->f_imm8 = value;
1499      break;
1500    case EPIPHANY_OPERAND_RD :
1501      fields->f_rd = value;
1502      break;
1503    case EPIPHANY_OPERAND_RD6 :
1504      fields->f_rd6 = value;
1505      break;
1506    case EPIPHANY_OPERAND_RM :
1507      fields->f_rm = value;
1508      break;
1509    case EPIPHANY_OPERAND_RM6 :
1510      fields->f_rm6 = value;
1511      break;
1512    case EPIPHANY_OPERAND_RN :
1513      fields->f_rn = value;
1514      break;
1515    case EPIPHANY_OPERAND_RN6 :
1516      fields->f_rn6 = value;
1517      break;
1518    case EPIPHANY_OPERAND_SD :
1519      fields->f_sd = value;
1520      break;
1521    case EPIPHANY_OPERAND_SD6 :
1522      fields->f_sd6 = value;
1523      break;
1524    case EPIPHANY_OPERAND_SDDMA :
1525      fields->f_sd6 = value;
1526      break;
1527    case EPIPHANY_OPERAND_SDMEM :
1528      fields->f_sd6 = value;
1529      break;
1530    case EPIPHANY_OPERAND_SDMESH :
1531      fields->f_sd6 = value;
1532      break;
1533    case EPIPHANY_OPERAND_SHIFT :
1534      fields->f_shift = value;
1535      break;
1536    case EPIPHANY_OPERAND_SIMM11 :
1537      fields->f_sdisp11 = value;
1538      break;
1539    case EPIPHANY_OPERAND_SIMM24 :
1540      fields->f_simm24 = value;
1541      break;
1542    case EPIPHANY_OPERAND_SIMM3 :
1543      fields->f_sdisp3 = value;
1544      break;
1545    case EPIPHANY_OPERAND_SIMM8 :
1546      fields->f_simm8 = value;
1547      break;
1548    case EPIPHANY_OPERAND_SN :
1549      fields->f_sn = value;
1550      break;
1551    case EPIPHANY_OPERAND_SN6 :
1552      fields->f_sn6 = value;
1553      break;
1554    case EPIPHANY_OPERAND_SNDMA :
1555      fields->f_sn6 = value;
1556      break;
1557    case EPIPHANY_OPERAND_SNMEM :
1558      fields->f_sn6 = value;
1559      break;
1560    case EPIPHANY_OPERAND_SNMESH :
1561      fields->f_sn6 = value;
1562      break;
1563    case EPIPHANY_OPERAND_SWI_NUM :
1564      fields->f_trap_num = value;
1565      break;
1566    case EPIPHANY_OPERAND_TRAPNUM6 :
1567      fields->f_trap_num = value;
1568      break;
1569
1570    default :
1571      /* xgettext:c-format */
1572      fprintf (stderr, _("Unrecognized field %d while setting int operand.\n"),
1573		       opindex);
1574      abort ();
1575  }
1576}
1577
1578void
1579epiphany_cgen_set_vma_operand (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
1580			     int opindex,
1581			     CGEN_FIELDS * fields,
1582			     bfd_vma value)
1583{
1584  switch (opindex)
1585    {
1586    case EPIPHANY_OPERAND_DIRECTION :
1587      fields->f_addsubx = value;
1588      break;
1589    case EPIPHANY_OPERAND_DISP11 :
1590      fields->f_disp11 = value;
1591      break;
1592    case EPIPHANY_OPERAND_DISP3 :
1593      fields->f_disp3 = value;
1594      break;
1595    case EPIPHANY_OPERAND_DPMI :
1596      fields->f_subd = value;
1597      break;
1598    case EPIPHANY_OPERAND_FRD :
1599      fields->f_rd = value;
1600      break;
1601    case EPIPHANY_OPERAND_FRD6 :
1602      fields->f_rd6 = value;
1603      break;
1604    case EPIPHANY_OPERAND_FRM :
1605      fields->f_rm = value;
1606      break;
1607    case EPIPHANY_OPERAND_FRM6 :
1608      fields->f_rm6 = value;
1609      break;
1610    case EPIPHANY_OPERAND_FRN :
1611      fields->f_rn = value;
1612      break;
1613    case EPIPHANY_OPERAND_FRN6 :
1614      fields->f_rn6 = value;
1615      break;
1616    case EPIPHANY_OPERAND_IMM16 :
1617      fields->f_imm16 = value;
1618      break;
1619    case EPIPHANY_OPERAND_IMM8 :
1620      fields->f_imm8 = value;
1621      break;
1622    case EPIPHANY_OPERAND_RD :
1623      fields->f_rd = value;
1624      break;
1625    case EPIPHANY_OPERAND_RD6 :
1626      fields->f_rd6 = value;
1627      break;
1628    case EPIPHANY_OPERAND_RM :
1629      fields->f_rm = value;
1630      break;
1631    case EPIPHANY_OPERAND_RM6 :
1632      fields->f_rm6 = value;
1633      break;
1634    case EPIPHANY_OPERAND_RN :
1635      fields->f_rn = value;
1636      break;
1637    case EPIPHANY_OPERAND_RN6 :
1638      fields->f_rn6 = value;
1639      break;
1640    case EPIPHANY_OPERAND_SD :
1641      fields->f_sd = value;
1642      break;
1643    case EPIPHANY_OPERAND_SD6 :
1644      fields->f_sd6 = value;
1645      break;
1646    case EPIPHANY_OPERAND_SDDMA :
1647      fields->f_sd6 = value;
1648      break;
1649    case EPIPHANY_OPERAND_SDMEM :
1650      fields->f_sd6 = value;
1651      break;
1652    case EPIPHANY_OPERAND_SDMESH :
1653      fields->f_sd6 = value;
1654      break;
1655    case EPIPHANY_OPERAND_SHIFT :
1656      fields->f_shift = value;
1657      break;
1658    case EPIPHANY_OPERAND_SIMM11 :
1659      fields->f_sdisp11 = value;
1660      break;
1661    case EPIPHANY_OPERAND_SIMM24 :
1662      fields->f_simm24 = value;
1663      break;
1664    case EPIPHANY_OPERAND_SIMM3 :
1665      fields->f_sdisp3 = value;
1666      break;
1667    case EPIPHANY_OPERAND_SIMM8 :
1668      fields->f_simm8 = value;
1669      break;
1670    case EPIPHANY_OPERAND_SN :
1671      fields->f_sn = value;
1672      break;
1673    case EPIPHANY_OPERAND_SN6 :
1674      fields->f_sn6 = value;
1675      break;
1676    case EPIPHANY_OPERAND_SNDMA :
1677      fields->f_sn6 = value;
1678      break;
1679    case EPIPHANY_OPERAND_SNMEM :
1680      fields->f_sn6 = value;
1681      break;
1682    case EPIPHANY_OPERAND_SNMESH :
1683      fields->f_sn6 = value;
1684      break;
1685    case EPIPHANY_OPERAND_SWI_NUM :
1686      fields->f_trap_num = value;
1687      break;
1688    case EPIPHANY_OPERAND_TRAPNUM6 :
1689      fields->f_trap_num = value;
1690      break;
1691
1692    default :
1693      /* xgettext:c-format */
1694      fprintf (stderr, _("Unrecognized field %d while setting vma operand.\n"),
1695		       opindex);
1696      abort ();
1697  }
1698}
1699
1700/* Function to call before using the instruction builder tables.  */
1701
1702void
1703epiphany_cgen_init_ibld_table (CGEN_CPU_DESC cd)
1704{
1705  cd->insert_handlers = & epiphany_cgen_insert_handlers[0];
1706  cd->extract_handlers = & epiphany_cgen_extract_handlers[0];
1707
1708  cd->insert_operand = epiphany_cgen_insert_operand;
1709  cd->extract_operand = epiphany_cgen_extract_operand;
1710
1711  cd->get_int_operand = epiphany_cgen_get_int_operand;
1712  cd->set_int_operand = epiphany_cgen_set_int_operand;
1713  cd->get_vma_operand = epiphany_cgen_get_vma_operand;
1714  cd->set_vma_operand = epiphany_cgen_set_vma_operand;
1715}
1716