Mark generated cgen files read-only
[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-2017 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       fprintf (stderr, _("Unrecognized field %d while building insn.\n"),
880                opindex);
881       abort ();
882   }
883
884   return errmsg;
885 }
886
887 int epiphany_cgen_extract_operand
888   (CGEN_CPU_DESC, int, CGEN_EXTRACT_INFO *, CGEN_INSN_INT, CGEN_FIELDS *, bfd_vma);
889
890 /* Main entry point for operand extraction.
891    The result is <= 0 for error, >0 for success.
892    ??? Actual values aren't well defined right now.
893
894    This function is basically just a big switch statement.  Earlier versions
895    used tables to look up the function to use, but
896    - if the table contains both assembler and disassembler functions then
897      the disassembler contains much of the assembler and vice-versa,
898    - there's a lot of inlining possibilities as things grow,
899    - using a switch statement avoids the function call overhead.
900
901    This function could be moved into `print_insn_normal', but keeping it
902    separate makes clear the interface between `print_insn_normal' and each of
903    the handlers.  */
904
905 int
906 epiphany_cgen_extract_operand (CGEN_CPU_DESC cd,
907                              int opindex,
908                              CGEN_EXTRACT_INFO *ex_info,
909                              CGEN_INSN_INT insn_value,
910                              CGEN_FIELDS * fields,
911                              bfd_vma pc)
912 {
913   /* Assume success (for those operands that are nops).  */
914   int length = 1;
915   unsigned int total_length = CGEN_FIELDS_BITSIZE (fields);
916
917   switch (opindex)
918     {
919     case EPIPHANY_OPERAND_DIRECTION :
920       length = extract_normal (cd, ex_info, insn_value, 0, 0, 20, 1, 32, total_length, pc, & fields->f_addsubx);
921       break;
922     case EPIPHANY_OPERAND_DISP11 :
923       {
924         length = extract_normal (cd, ex_info, insn_value, 0, 0, 9, 3, 32, total_length, pc, & fields->f_disp3);
925         if (length <= 0) break;
926         length = extract_normal (cd, ex_info, insn_value, 0, 0, 23, 8, 32, total_length, pc, & fields->f_disp8);
927         if (length <= 0) break;
928 {
929   FLD (f_disp11) = ((((FLD (f_disp8)) << (3))) | (FLD (f_disp3)));
930 }
931       }
932       break;
933     case EPIPHANY_OPERAND_DISP3 :
934       length = extract_normal (cd, ex_info, insn_value, 0, 0, 9, 3, 32, total_length, pc, & fields->f_disp3);
935       break;
936     case EPIPHANY_OPERAND_DPMI :
937       length = extract_normal (cd, ex_info, insn_value, 0, 0, 24, 1, 32, total_length, pc, & fields->f_subd);
938       break;
939     case EPIPHANY_OPERAND_FRD :
940       length = extract_normal (cd, ex_info, insn_value, 0, 0, 15, 3, 32, total_length, pc, & fields->f_rd);
941       break;
942     case EPIPHANY_OPERAND_FRD6 :
943       {
944         length = extract_normal (cd, ex_info, insn_value, 0, 0, 31, 3, 32, total_length, pc, & fields->f_rd_x);
945         if (length <= 0) break;
946         length = extract_normal (cd, ex_info, insn_value, 0, 0, 15, 3, 32, total_length, pc, & fields->f_rd);
947         if (length <= 0) break;
948 {
949   FLD (f_rd6) = ((((FLD (f_rd_x)) << (3))) | (FLD (f_rd)));
950 }
951       }
952       break;
953     case EPIPHANY_OPERAND_FRM :
954       length = extract_normal (cd, ex_info, insn_value, 0, 0, 9, 3, 32, total_length, pc, & fields->f_rm);
955       break;
956     case EPIPHANY_OPERAND_FRM6 :
957       {
958         length = extract_normal (cd, ex_info, insn_value, 0, 0, 25, 3, 32, total_length, pc, & fields->f_rm_x);
959         if (length <= 0) break;
960         length = extract_normal (cd, ex_info, insn_value, 0, 0, 9, 3, 32, total_length, pc, & fields->f_rm);
961         if (length <= 0) break;
962 {
963   FLD (f_rm6) = ((((FLD (f_rm_x)) << (3))) | (FLD (f_rm)));
964 }
965       }
966       break;
967     case EPIPHANY_OPERAND_FRN :
968       length = extract_normal (cd, ex_info, insn_value, 0, 0, 12, 3, 32, total_length, pc, & fields->f_rn);
969       break;
970     case EPIPHANY_OPERAND_FRN6 :
971       {
972         length = extract_normal (cd, ex_info, insn_value, 0, 0, 28, 3, 32, total_length, pc, & fields->f_rn_x);
973         if (length <= 0) break;
974         length = extract_normal (cd, ex_info, insn_value, 0, 0, 12, 3, 32, total_length, pc, & fields->f_rn);
975         if (length <= 0) break;
976 {
977   FLD (f_rn6) = ((((FLD (f_rn_x)) << (3))) | (FLD (f_rn)));
978 }
979       }
980       break;
981     case EPIPHANY_OPERAND_IMM16 :
982       {
983         length = extract_normal (cd, ex_info, insn_value, 0, 0, 12, 8, 32, total_length, pc, & fields->f_imm8);
984         if (length <= 0) break;
985         length = extract_normal (cd, ex_info, insn_value, 0, 0, 27, 8, 32, total_length, pc, & fields->f_imm_27_8);
986         if (length <= 0) break;
987 {
988   FLD (f_imm16) = ((((FLD (f_imm_27_8)) << (8))) | (FLD (f_imm8)));
989 }
990       }
991       break;
992     case EPIPHANY_OPERAND_IMM8 :
993       length = extract_normal (cd, ex_info, insn_value, 0, 0, 12, 8, 32, total_length, pc, & fields->f_imm8);
994       break;
995     case EPIPHANY_OPERAND_RD :
996       length = extract_normal (cd, ex_info, insn_value, 0, 0, 15, 3, 32, total_length, pc, & fields->f_rd);
997       break;
998     case EPIPHANY_OPERAND_RD6 :
999       {
1000         length = extract_normal (cd, ex_info, insn_value, 0, 0, 31, 3, 32, total_length, pc, & fields->f_rd_x);
1001         if (length <= 0) break;
1002         length = extract_normal (cd, ex_info, insn_value, 0, 0, 15, 3, 32, total_length, pc, & fields->f_rd);
1003         if (length <= 0) break;
1004 {
1005   FLD (f_rd6) = ((((FLD (f_rd_x)) << (3))) | (FLD (f_rd)));
1006 }
1007       }
1008       break;
1009     case EPIPHANY_OPERAND_RM :
1010       length = extract_normal (cd, ex_info, insn_value, 0, 0, 9, 3, 32, total_length, pc, & fields->f_rm);
1011       break;
1012     case EPIPHANY_OPERAND_RM6 :
1013       {
1014         length = extract_normal (cd, ex_info, insn_value, 0, 0, 25, 3, 32, total_length, pc, & fields->f_rm_x);
1015         if (length <= 0) break;
1016         length = extract_normal (cd, ex_info, insn_value, 0, 0, 9, 3, 32, total_length, pc, & fields->f_rm);
1017         if (length <= 0) break;
1018 {
1019   FLD (f_rm6) = ((((FLD (f_rm_x)) << (3))) | (FLD (f_rm)));
1020 }
1021       }
1022       break;
1023     case EPIPHANY_OPERAND_RN :
1024       length = extract_normal (cd, ex_info, insn_value, 0, 0, 12, 3, 32, total_length, pc, & fields->f_rn);
1025       break;
1026     case EPIPHANY_OPERAND_RN6 :
1027       {
1028         length = extract_normal (cd, ex_info, insn_value, 0, 0, 28, 3, 32, total_length, pc, & fields->f_rn_x);
1029         if (length <= 0) break;
1030         length = extract_normal (cd, ex_info, insn_value, 0, 0, 12, 3, 32, total_length, pc, & fields->f_rn);
1031         if (length <= 0) break;
1032 {
1033   FLD (f_rn6) = ((((FLD (f_rn_x)) << (3))) | (FLD (f_rn)));
1034 }
1035       }
1036       break;
1037     case EPIPHANY_OPERAND_SD :
1038       length = extract_normal (cd, ex_info, insn_value, 0, 0, 15, 3, 32, total_length, pc, & fields->f_sd);
1039       break;
1040     case EPIPHANY_OPERAND_SD6 :
1041       {
1042         length = extract_normal (cd, ex_info, insn_value, 0, 0, 31, 3, 32, total_length, pc, & fields->f_sd_x);
1043         if (length <= 0) break;
1044         length = extract_normal (cd, ex_info, insn_value, 0, 0, 15, 3, 32, total_length, pc, & fields->f_sd);
1045         if (length <= 0) break;
1046 {
1047   FLD (f_sd6) = ((((FLD (f_sd_x)) << (3))) | (FLD (f_sd)));
1048 }
1049       }
1050       break;
1051     case EPIPHANY_OPERAND_SDDMA :
1052       {
1053         length = extract_normal (cd, ex_info, insn_value, 0, 0, 31, 3, 32, total_length, pc, & fields->f_sd_x);
1054         if (length <= 0) break;
1055         length = extract_normal (cd, ex_info, insn_value, 0, 0, 15, 3, 32, total_length, pc, & fields->f_sd);
1056         if (length <= 0) break;
1057 {
1058   FLD (f_sd6) = ((((FLD (f_sd_x)) << (3))) | (FLD (f_sd)));
1059 }
1060       }
1061       break;
1062     case EPIPHANY_OPERAND_SDMEM :
1063       {
1064         length = extract_normal (cd, ex_info, insn_value, 0, 0, 31, 3, 32, total_length, pc, & fields->f_sd_x);
1065         if (length <= 0) break;
1066         length = extract_normal (cd, ex_info, insn_value, 0, 0, 15, 3, 32, total_length, pc, & fields->f_sd);
1067         if (length <= 0) break;
1068 {
1069   FLD (f_sd6) = ((((FLD (f_sd_x)) << (3))) | (FLD (f_sd)));
1070 }
1071       }
1072       break;
1073     case EPIPHANY_OPERAND_SDMESH :
1074       {
1075         length = extract_normal (cd, ex_info, insn_value, 0, 0, 31, 3, 32, total_length, pc, & fields->f_sd_x);
1076         if (length <= 0) break;
1077         length = extract_normal (cd, ex_info, insn_value, 0, 0, 15, 3, 32, total_length, pc, & fields->f_sd);
1078         if (length <= 0) break;
1079 {
1080   FLD (f_sd6) = ((((FLD (f_sd_x)) << (3))) | (FLD (f_sd)));
1081 }
1082       }
1083       break;
1084     case EPIPHANY_OPERAND_SHIFT :
1085       length = extract_normal (cd, ex_info, insn_value, 0, 0, 9, 5, 32, total_length, pc, & fields->f_shift);
1086       break;
1087     case EPIPHANY_OPERAND_SIMM11 :
1088       {
1089         length = extract_normal (cd, ex_info, insn_value, 0, 0, 9, 3, 32, total_length, pc, & fields->f_disp3);
1090         if (length <= 0) break;
1091         length = extract_normal (cd, ex_info, insn_value, 0, 0, 23, 8, 32, total_length, pc, & fields->f_disp8);
1092         if (length <= 0) break;
1093 {
1094   FLD (f_sdisp11) = ((SI) (((((((FLD (f_disp8)) << (3))) | (FLD (f_disp3)))) << (21))) >> (21));
1095 }
1096       }
1097       break;
1098     case EPIPHANY_OPERAND_SIMM24 :
1099       {
1100         long value;
1101         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);
1102         value = ((((value) << (1))) + (pc));
1103         fields->f_simm24 = value;
1104       }
1105       break;
1106     case EPIPHANY_OPERAND_SIMM3 :
1107       length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_SIGNED), 0, 9, 3, 32, total_length, pc, & fields->f_sdisp3);
1108       break;
1109     case EPIPHANY_OPERAND_SIMM8 :
1110       {
1111         long value;
1112         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);
1113         value = ((((value) << (1))) + (pc));
1114         fields->f_simm8 = value;
1115       }
1116       break;
1117     case EPIPHANY_OPERAND_SN :
1118       length = extract_normal (cd, ex_info, insn_value, 0, 0, 12, 3, 32, total_length, pc, & fields->f_sn);
1119       break;
1120     case EPIPHANY_OPERAND_SN6 :
1121       {
1122         length = extract_normal (cd, ex_info, insn_value, 0, 0, 28, 3, 32, total_length, pc, & fields->f_sn_x);
1123         if (length <= 0) break;
1124         length = extract_normal (cd, ex_info, insn_value, 0, 0, 12, 3, 32, total_length, pc, & fields->f_sn);
1125         if (length <= 0) break;
1126 {
1127   FLD (f_sn6) = ((((FLD (f_sn_x)) << (3))) | (FLD (f_sn)));
1128 }
1129       }
1130       break;
1131     case EPIPHANY_OPERAND_SNDMA :
1132       {
1133         length = extract_normal (cd, ex_info, insn_value, 0, 0, 28, 3, 32, total_length, pc, & fields->f_sn_x);
1134         if (length <= 0) break;
1135         length = extract_normal (cd, ex_info, insn_value, 0, 0, 12, 3, 32, total_length, pc, & fields->f_sn);
1136         if (length <= 0) break;
1137 {
1138   FLD (f_sn6) = ((((FLD (f_sn_x)) << (3))) | (FLD (f_sn)));
1139 }
1140       }
1141       break;
1142     case EPIPHANY_OPERAND_SNMEM :
1143       {
1144         length = extract_normal (cd, ex_info, insn_value, 0, 0, 28, 3, 32, total_length, pc, & fields->f_sn_x);
1145         if (length <= 0) break;
1146         length = extract_normal (cd, ex_info, insn_value, 0, 0, 12, 3, 32, total_length, pc, & fields->f_sn);
1147         if (length <= 0) break;
1148 {
1149   FLD (f_sn6) = ((((FLD (f_sn_x)) << (3))) | (FLD (f_sn)));
1150 }
1151       }
1152       break;
1153     case EPIPHANY_OPERAND_SNMESH :
1154       {
1155         length = extract_normal (cd, ex_info, insn_value, 0, 0, 28, 3, 32, total_length, pc, & fields->f_sn_x);
1156         if (length <= 0) break;
1157         length = extract_normal (cd, ex_info, insn_value, 0, 0, 12, 3, 32, total_length, pc, & fields->f_sn);
1158         if (length <= 0) break;
1159 {
1160   FLD (f_sn6) = ((((FLD (f_sn_x)) << (3))) | (FLD (f_sn)));
1161 }
1162       }
1163       break;
1164     case EPIPHANY_OPERAND_SWI_NUM :
1165       length = extract_normal (cd, ex_info, insn_value, 0, 0, 15, 6, 32, total_length, pc, & fields->f_trap_num);
1166       break;
1167     case EPIPHANY_OPERAND_TRAPNUM6 :
1168       length = extract_normal (cd, ex_info, insn_value, 0, 0, 15, 6, 32, total_length, pc, & fields->f_trap_num);
1169       break;
1170
1171     default :
1172       /* xgettext:c-format */
1173       fprintf (stderr, _("Unrecognized field %d while decoding insn.\n"),
1174                opindex);
1175       abort ();
1176     }
1177
1178   return length;
1179 }
1180
1181 cgen_insert_fn * const epiphany_cgen_insert_handlers[] =
1182 {
1183   insert_insn_normal,
1184 };
1185
1186 cgen_extract_fn * const epiphany_cgen_extract_handlers[] =
1187 {
1188   extract_insn_normal,
1189 };
1190
1191 int epiphany_cgen_get_int_operand     (CGEN_CPU_DESC, int, const CGEN_FIELDS *);
1192 bfd_vma epiphany_cgen_get_vma_operand (CGEN_CPU_DESC, int, const CGEN_FIELDS *);
1193
1194 /* Getting values from cgen_fields is handled by a collection of functions.
1195    They are distinguished by the type of the VALUE argument they return.
1196    TODO: floating point, inlining support, remove cases where result type
1197    not appropriate.  */
1198
1199 int
1200 epiphany_cgen_get_int_operand (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
1201                              int opindex,
1202                              const CGEN_FIELDS * fields)
1203 {
1204   int value;
1205
1206   switch (opindex)
1207     {
1208     case EPIPHANY_OPERAND_DIRECTION :
1209       value = fields->f_addsubx;
1210       break;
1211     case EPIPHANY_OPERAND_DISP11 :
1212       value = fields->f_disp11;
1213       break;
1214     case EPIPHANY_OPERAND_DISP3 :
1215       value = fields->f_disp3;
1216       break;
1217     case EPIPHANY_OPERAND_DPMI :
1218       value = fields->f_subd;
1219       break;
1220     case EPIPHANY_OPERAND_FRD :
1221       value = fields->f_rd;
1222       break;
1223     case EPIPHANY_OPERAND_FRD6 :
1224       value = fields->f_rd6;
1225       break;
1226     case EPIPHANY_OPERAND_FRM :
1227       value = fields->f_rm;
1228       break;
1229     case EPIPHANY_OPERAND_FRM6 :
1230       value = fields->f_rm6;
1231       break;
1232     case EPIPHANY_OPERAND_FRN :
1233       value = fields->f_rn;
1234       break;
1235     case EPIPHANY_OPERAND_FRN6 :
1236       value = fields->f_rn6;
1237       break;
1238     case EPIPHANY_OPERAND_IMM16 :
1239       value = fields->f_imm16;
1240       break;
1241     case EPIPHANY_OPERAND_IMM8 :
1242       value = fields->f_imm8;
1243       break;
1244     case EPIPHANY_OPERAND_RD :
1245       value = fields->f_rd;
1246       break;
1247     case EPIPHANY_OPERAND_RD6 :
1248       value = fields->f_rd6;
1249       break;
1250     case EPIPHANY_OPERAND_RM :
1251       value = fields->f_rm;
1252       break;
1253     case EPIPHANY_OPERAND_RM6 :
1254       value = fields->f_rm6;
1255       break;
1256     case EPIPHANY_OPERAND_RN :
1257       value = fields->f_rn;
1258       break;
1259     case EPIPHANY_OPERAND_RN6 :
1260       value = fields->f_rn6;
1261       break;
1262     case EPIPHANY_OPERAND_SD :
1263       value = fields->f_sd;
1264       break;
1265     case EPIPHANY_OPERAND_SD6 :
1266       value = fields->f_sd6;
1267       break;
1268     case EPIPHANY_OPERAND_SDDMA :
1269       value = fields->f_sd6;
1270       break;
1271     case EPIPHANY_OPERAND_SDMEM :
1272       value = fields->f_sd6;
1273       break;
1274     case EPIPHANY_OPERAND_SDMESH :
1275       value = fields->f_sd6;
1276       break;
1277     case EPIPHANY_OPERAND_SHIFT :
1278       value = fields->f_shift;
1279       break;
1280     case EPIPHANY_OPERAND_SIMM11 :
1281       value = fields->f_sdisp11;
1282       break;
1283     case EPIPHANY_OPERAND_SIMM24 :
1284       value = fields->f_simm24;
1285       break;
1286     case EPIPHANY_OPERAND_SIMM3 :
1287       value = fields->f_sdisp3;
1288       break;
1289     case EPIPHANY_OPERAND_SIMM8 :
1290       value = fields->f_simm8;
1291       break;
1292     case EPIPHANY_OPERAND_SN :
1293       value = fields->f_sn;
1294       break;
1295     case EPIPHANY_OPERAND_SN6 :
1296       value = fields->f_sn6;
1297       break;
1298     case EPIPHANY_OPERAND_SNDMA :
1299       value = fields->f_sn6;
1300       break;
1301     case EPIPHANY_OPERAND_SNMEM :
1302       value = fields->f_sn6;
1303       break;
1304     case EPIPHANY_OPERAND_SNMESH :
1305       value = fields->f_sn6;
1306       break;
1307     case EPIPHANY_OPERAND_SWI_NUM :
1308       value = fields->f_trap_num;
1309       break;
1310     case EPIPHANY_OPERAND_TRAPNUM6 :
1311       value = fields->f_trap_num;
1312       break;
1313
1314     default :
1315       /* xgettext:c-format */
1316       fprintf (stderr, _("Unrecognized field %d while getting int operand.\n"),
1317                        opindex);
1318       abort ();
1319   }
1320
1321   return value;
1322 }
1323
1324 bfd_vma
1325 epiphany_cgen_get_vma_operand (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
1326                              int opindex,
1327                              const CGEN_FIELDS * fields)
1328 {
1329   bfd_vma value;
1330
1331   switch (opindex)
1332     {
1333     case EPIPHANY_OPERAND_DIRECTION :
1334       value = fields->f_addsubx;
1335       break;
1336     case EPIPHANY_OPERAND_DISP11 :
1337       value = fields->f_disp11;
1338       break;
1339     case EPIPHANY_OPERAND_DISP3 :
1340       value = fields->f_disp3;
1341       break;
1342     case EPIPHANY_OPERAND_DPMI :
1343       value = fields->f_subd;
1344       break;
1345     case EPIPHANY_OPERAND_FRD :
1346       value = fields->f_rd;
1347       break;
1348     case EPIPHANY_OPERAND_FRD6 :
1349       value = fields->f_rd6;
1350       break;
1351     case EPIPHANY_OPERAND_FRM :
1352       value = fields->f_rm;
1353       break;
1354     case EPIPHANY_OPERAND_FRM6 :
1355       value = fields->f_rm6;
1356       break;
1357     case EPIPHANY_OPERAND_FRN :
1358       value = fields->f_rn;
1359       break;
1360     case EPIPHANY_OPERAND_FRN6 :
1361       value = fields->f_rn6;
1362       break;
1363     case EPIPHANY_OPERAND_IMM16 :
1364       value = fields->f_imm16;
1365       break;
1366     case EPIPHANY_OPERAND_IMM8 :
1367       value = fields->f_imm8;
1368       break;
1369     case EPIPHANY_OPERAND_RD :
1370       value = fields->f_rd;
1371       break;
1372     case EPIPHANY_OPERAND_RD6 :
1373       value = fields->f_rd6;
1374       break;
1375     case EPIPHANY_OPERAND_RM :
1376       value = fields->f_rm;
1377       break;
1378     case EPIPHANY_OPERAND_RM6 :
1379       value = fields->f_rm6;
1380       break;
1381     case EPIPHANY_OPERAND_RN :
1382       value = fields->f_rn;
1383       break;
1384     case EPIPHANY_OPERAND_RN6 :
1385       value = fields->f_rn6;
1386       break;
1387     case EPIPHANY_OPERAND_SD :
1388       value = fields->f_sd;
1389       break;
1390     case EPIPHANY_OPERAND_SD6 :
1391       value = fields->f_sd6;
1392       break;
1393     case EPIPHANY_OPERAND_SDDMA :
1394       value = fields->f_sd6;
1395       break;
1396     case EPIPHANY_OPERAND_SDMEM :
1397       value = fields->f_sd6;
1398       break;
1399     case EPIPHANY_OPERAND_SDMESH :
1400       value = fields->f_sd6;
1401       break;
1402     case EPIPHANY_OPERAND_SHIFT :
1403       value = fields->f_shift;
1404       break;
1405     case EPIPHANY_OPERAND_SIMM11 :
1406       value = fields->f_sdisp11;
1407       break;
1408     case EPIPHANY_OPERAND_SIMM24 :
1409       value = fields->f_simm24;
1410       break;
1411     case EPIPHANY_OPERAND_SIMM3 :
1412       value = fields->f_sdisp3;
1413       break;
1414     case EPIPHANY_OPERAND_SIMM8 :
1415       value = fields->f_simm8;
1416       break;
1417     case EPIPHANY_OPERAND_SN :
1418       value = fields->f_sn;
1419       break;
1420     case EPIPHANY_OPERAND_SN6 :
1421       value = fields->f_sn6;
1422       break;
1423     case EPIPHANY_OPERAND_SNDMA :
1424       value = fields->f_sn6;
1425       break;
1426     case EPIPHANY_OPERAND_SNMEM :
1427       value = fields->f_sn6;
1428       break;
1429     case EPIPHANY_OPERAND_SNMESH :
1430       value = fields->f_sn6;
1431       break;
1432     case EPIPHANY_OPERAND_SWI_NUM :
1433       value = fields->f_trap_num;
1434       break;
1435     case EPIPHANY_OPERAND_TRAPNUM6 :
1436       value = fields->f_trap_num;
1437       break;
1438
1439     default :
1440       /* xgettext:c-format */
1441       fprintf (stderr, _("Unrecognized field %d while getting vma operand.\n"),
1442                        opindex);
1443       abort ();
1444   }
1445
1446   return value;
1447 }
1448
1449 void epiphany_cgen_set_int_operand  (CGEN_CPU_DESC, int, CGEN_FIELDS *, int);
1450 void epiphany_cgen_set_vma_operand  (CGEN_CPU_DESC, int, CGEN_FIELDS *, bfd_vma);
1451
1452 /* Stuffing values in cgen_fields is handled by a collection of functions.
1453    They are distinguished by the type of the VALUE argument they accept.
1454    TODO: floating point, inlining support, remove cases where argument type
1455    not appropriate.  */
1456
1457 void
1458 epiphany_cgen_set_int_operand (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
1459                              int opindex,
1460                              CGEN_FIELDS * fields,
1461                              int value)
1462 {
1463   switch (opindex)
1464     {
1465     case EPIPHANY_OPERAND_DIRECTION :
1466       fields->f_addsubx = value;
1467       break;
1468     case EPIPHANY_OPERAND_DISP11 :
1469       fields->f_disp11 = value;
1470       break;
1471     case EPIPHANY_OPERAND_DISP3 :
1472       fields->f_disp3 = value;
1473       break;
1474     case EPIPHANY_OPERAND_DPMI :
1475       fields->f_subd = value;
1476       break;
1477     case EPIPHANY_OPERAND_FRD :
1478       fields->f_rd = value;
1479       break;
1480     case EPIPHANY_OPERAND_FRD6 :
1481       fields->f_rd6 = value;
1482       break;
1483     case EPIPHANY_OPERAND_FRM :
1484       fields->f_rm = value;
1485       break;
1486     case EPIPHANY_OPERAND_FRM6 :
1487       fields->f_rm6 = value;
1488       break;
1489     case EPIPHANY_OPERAND_FRN :
1490       fields->f_rn = value;
1491       break;
1492     case EPIPHANY_OPERAND_FRN6 :
1493       fields->f_rn6 = value;
1494       break;
1495     case EPIPHANY_OPERAND_IMM16 :
1496       fields->f_imm16 = value;
1497       break;
1498     case EPIPHANY_OPERAND_IMM8 :
1499       fields->f_imm8 = value;
1500       break;
1501     case EPIPHANY_OPERAND_RD :
1502       fields->f_rd = value;
1503       break;
1504     case EPIPHANY_OPERAND_RD6 :
1505       fields->f_rd6 = value;
1506       break;
1507     case EPIPHANY_OPERAND_RM :
1508       fields->f_rm = value;
1509       break;
1510     case EPIPHANY_OPERAND_RM6 :
1511       fields->f_rm6 = value;
1512       break;
1513     case EPIPHANY_OPERAND_RN :
1514       fields->f_rn = value;
1515       break;
1516     case EPIPHANY_OPERAND_RN6 :
1517       fields->f_rn6 = value;
1518       break;
1519     case EPIPHANY_OPERAND_SD :
1520       fields->f_sd = value;
1521       break;
1522     case EPIPHANY_OPERAND_SD6 :
1523       fields->f_sd6 = value;
1524       break;
1525     case EPIPHANY_OPERAND_SDDMA :
1526       fields->f_sd6 = value;
1527       break;
1528     case EPIPHANY_OPERAND_SDMEM :
1529       fields->f_sd6 = value;
1530       break;
1531     case EPIPHANY_OPERAND_SDMESH :
1532       fields->f_sd6 = value;
1533       break;
1534     case EPIPHANY_OPERAND_SHIFT :
1535       fields->f_shift = value;
1536       break;
1537     case EPIPHANY_OPERAND_SIMM11 :
1538       fields->f_sdisp11 = value;
1539       break;
1540     case EPIPHANY_OPERAND_SIMM24 :
1541       fields->f_simm24 = value;
1542       break;
1543     case EPIPHANY_OPERAND_SIMM3 :
1544       fields->f_sdisp3 = value;
1545       break;
1546     case EPIPHANY_OPERAND_SIMM8 :
1547       fields->f_simm8 = value;
1548       break;
1549     case EPIPHANY_OPERAND_SN :
1550       fields->f_sn = value;
1551       break;
1552     case EPIPHANY_OPERAND_SN6 :
1553       fields->f_sn6 = value;
1554       break;
1555     case EPIPHANY_OPERAND_SNDMA :
1556       fields->f_sn6 = value;
1557       break;
1558     case EPIPHANY_OPERAND_SNMEM :
1559       fields->f_sn6 = value;
1560       break;
1561     case EPIPHANY_OPERAND_SNMESH :
1562       fields->f_sn6 = value;
1563       break;
1564     case EPIPHANY_OPERAND_SWI_NUM :
1565       fields->f_trap_num = value;
1566       break;
1567     case EPIPHANY_OPERAND_TRAPNUM6 :
1568       fields->f_trap_num = value;
1569       break;
1570
1571     default :
1572       /* xgettext:c-format */
1573       fprintf (stderr, _("Unrecognized field %d while setting int operand.\n"),
1574                        opindex);
1575       abort ();
1576   }
1577 }
1578
1579 void
1580 epiphany_cgen_set_vma_operand (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
1581                              int opindex,
1582                              CGEN_FIELDS * fields,
1583                              bfd_vma value)
1584 {
1585   switch (opindex)
1586     {
1587     case EPIPHANY_OPERAND_DIRECTION :
1588       fields->f_addsubx = value;
1589       break;
1590     case EPIPHANY_OPERAND_DISP11 :
1591       fields->f_disp11 = value;
1592       break;
1593     case EPIPHANY_OPERAND_DISP3 :
1594       fields->f_disp3 = value;
1595       break;
1596     case EPIPHANY_OPERAND_DPMI :
1597       fields->f_subd = value;
1598       break;
1599     case EPIPHANY_OPERAND_FRD :
1600       fields->f_rd = value;
1601       break;
1602     case EPIPHANY_OPERAND_FRD6 :
1603       fields->f_rd6 = value;
1604       break;
1605     case EPIPHANY_OPERAND_FRM :
1606       fields->f_rm = value;
1607       break;
1608     case EPIPHANY_OPERAND_FRM6 :
1609       fields->f_rm6 = value;
1610       break;
1611     case EPIPHANY_OPERAND_FRN :
1612       fields->f_rn = value;
1613       break;
1614     case EPIPHANY_OPERAND_FRN6 :
1615       fields->f_rn6 = value;
1616       break;
1617     case EPIPHANY_OPERAND_IMM16 :
1618       fields->f_imm16 = value;
1619       break;
1620     case EPIPHANY_OPERAND_IMM8 :
1621       fields->f_imm8 = value;
1622       break;
1623     case EPIPHANY_OPERAND_RD :
1624       fields->f_rd = value;
1625       break;
1626     case EPIPHANY_OPERAND_RD6 :
1627       fields->f_rd6 = value;
1628       break;
1629     case EPIPHANY_OPERAND_RM :
1630       fields->f_rm = value;
1631       break;
1632     case EPIPHANY_OPERAND_RM6 :
1633       fields->f_rm6 = value;
1634       break;
1635     case EPIPHANY_OPERAND_RN :
1636       fields->f_rn = value;
1637       break;
1638     case EPIPHANY_OPERAND_RN6 :
1639       fields->f_rn6 = value;
1640       break;
1641     case EPIPHANY_OPERAND_SD :
1642       fields->f_sd = value;
1643       break;
1644     case EPIPHANY_OPERAND_SD6 :
1645       fields->f_sd6 = value;
1646       break;
1647     case EPIPHANY_OPERAND_SDDMA :
1648       fields->f_sd6 = value;
1649       break;
1650     case EPIPHANY_OPERAND_SDMEM :
1651       fields->f_sd6 = value;
1652       break;
1653     case EPIPHANY_OPERAND_SDMESH :
1654       fields->f_sd6 = value;
1655       break;
1656     case EPIPHANY_OPERAND_SHIFT :
1657       fields->f_shift = value;
1658       break;
1659     case EPIPHANY_OPERAND_SIMM11 :
1660       fields->f_sdisp11 = value;
1661       break;
1662     case EPIPHANY_OPERAND_SIMM24 :
1663       fields->f_simm24 = value;
1664       break;
1665     case EPIPHANY_OPERAND_SIMM3 :
1666       fields->f_sdisp3 = value;
1667       break;
1668     case EPIPHANY_OPERAND_SIMM8 :
1669       fields->f_simm8 = value;
1670       break;
1671     case EPIPHANY_OPERAND_SN :
1672       fields->f_sn = value;
1673       break;
1674     case EPIPHANY_OPERAND_SN6 :
1675       fields->f_sn6 = value;
1676       break;
1677     case EPIPHANY_OPERAND_SNDMA :
1678       fields->f_sn6 = value;
1679       break;
1680     case EPIPHANY_OPERAND_SNMEM :
1681       fields->f_sn6 = value;
1682       break;
1683     case EPIPHANY_OPERAND_SNMESH :
1684       fields->f_sn6 = value;
1685       break;
1686     case EPIPHANY_OPERAND_SWI_NUM :
1687       fields->f_trap_num = value;
1688       break;
1689     case EPIPHANY_OPERAND_TRAPNUM6 :
1690       fields->f_trap_num = value;
1691       break;
1692
1693     default :
1694       /* xgettext:c-format */
1695       fprintf (stderr, _("Unrecognized field %d while setting vma operand.\n"),
1696                        opindex);
1697       abort ();
1698   }
1699 }
1700
1701 /* Function to call before using the instruction builder tables.  */
1702
1703 void
1704 epiphany_cgen_init_ibld_table (CGEN_CPU_DESC cd)
1705 {
1706   cd->insert_handlers = & epiphany_cgen_insert_handlers[0];
1707   cd->extract_handlers = & epiphany_cgen_extract_handlers[0];
1708
1709   cd->insert_operand = epiphany_cgen_insert_operand;
1710   cd->extract_operand = epiphany_cgen_extract_operand;
1711
1712   cd->get_int_operand = epiphany_cgen_get_int_operand;
1713   cd->set_int_operand = epiphany_cgen_set_int_operand;
1714   cd->get_vma_operand = epiphany_cgen_get_vma_operand;
1715   cd->set_vma_operand = epiphany_cgen_set_vma_operand;
1716 }