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