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