]> Git Repo - binutils.git/blob - opcodes/epiphany-ibld.c
NS32K arg_bufs uninitialised
[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-2020 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         {
484           *valuep = 0;
485           return 0;
486         }
487
488       value = extract_1 (cd, ex_info, start, length, word_length, bufp, pc);
489     }
490
491 #endif /* ! CGEN_INT_INSN_P */
492
493   /* Written this way to avoid undefined behaviour.  */
494   mask = (((1L << (length - 1)) - 1) << 1) | 1;
495
496   value &= mask;
497   /* sign extend? */
498   if (CGEN_BOOL_ATTR (attrs, CGEN_IFLD_SIGNED)
499       && (value & (1L << (length - 1))))
500     value |= ~mask;
501
502   *valuep = value;
503
504   return 1;
505 }
506
507 /* Default insn extractor.
508
509    INSN_VALUE is the first base_insn_bitsize bits, translated to host order.
510    The extracted fields are stored in FIELDS.
511    EX_INFO is used to handle reading variable length insns.
512    Return the length of the insn in bits, or 0 if no match,
513    or -1 if an error occurs fetching data (memory_error_func will have
514    been called).  */
515
516 static int
517 extract_insn_normal (CGEN_CPU_DESC cd,
518                      const CGEN_INSN *insn,
519                      CGEN_EXTRACT_INFO *ex_info,
520                      CGEN_INSN_INT insn_value,
521                      CGEN_FIELDS *fields,
522                      bfd_vma pc)
523 {
524   const CGEN_SYNTAX *syntax = CGEN_INSN_SYNTAX (insn);
525   const CGEN_SYNTAX_CHAR_TYPE *syn;
526
527   CGEN_FIELDS_BITSIZE (fields) = CGEN_INSN_BITSIZE (insn);
528
529   CGEN_INIT_EXTRACT (cd);
530
531   for (syn = CGEN_SYNTAX_STRING (syntax); *syn; ++syn)
532     {
533       int length;
534
535       if (CGEN_SYNTAX_CHAR_P (*syn))
536         continue;
537
538       length = (* cd->extract_operand) (cd, CGEN_SYNTAX_FIELD (*syn),
539                                         ex_info, insn_value, fields, pc);
540       if (length <= 0)
541         return length;
542     }
543
544   /* We recognized and successfully extracted this insn.  */
545   return CGEN_INSN_BITSIZE (insn);
546 }
547 \f
548 /* Machine generated code added here.  */
549
550 const char * epiphany_cgen_insert_operand
551   (CGEN_CPU_DESC, int, CGEN_FIELDS *, CGEN_INSN_BYTES_PTR, bfd_vma);
552
553 /* Main entry point for operand insertion.
554
555    This function is basically just a big switch statement.  Earlier versions
556    used tables to look up the function to use, but
557    - if the table contains both assembler and disassembler functions then
558      the disassembler contains much of the assembler and vice-versa,
559    - there's a lot of inlining possibilities as things grow,
560    - using a switch statement avoids the function call overhead.
561
562    This function could be moved into `parse_insn_normal', but keeping it
563    separate makes clear the interface between `parse_insn_normal' and each of
564    the handlers.  It's also needed by GAS to insert operands that couldn't be
565    resolved during parsing.  */
566
567 const char *
568 epiphany_cgen_insert_operand (CGEN_CPU_DESC cd,
569                              int opindex,
570                              CGEN_FIELDS * fields,
571                              CGEN_INSN_BYTES_PTR buffer,
572                              bfd_vma pc ATTRIBUTE_UNUSED)
573 {
574   const char * errmsg = NULL;
575   unsigned int total_length = CGEN_FIELDS_BITSIZE (fields);
576
577   switch (opindex)
578     {
579     case EPIPHANY_OPERAND_DIRECTION :
580       errmsg = insert_normal (cd, fields->f_addsubx, 0, 0, 20, 1, 32, total_length, buffer);
581       break;
582     case EPIPHANY_OPERAND_DISP11 :
583       {
584 {
585   FLD (f_disp8) = ((((UINT) (FLD (f_disp11)) >> (3))) & (255));
586   FLD (f_disp3) = ((FLD (f_disp11)) & (7));
587 }
588         errmsg = insert_normal (cd, fields->f_disp3, 0, 0, 9, 3, 32, total_length, buffer);
589         if (errmsg)
590           break;
591         errmsg = insert_normal (cd, fields->f_disp8, 0, 0, 23, 8, 32, total_length, buffer);
592         if (errmsg)
593           break;
594       }
595       break;
596     case EPIPHANY_OPERAND_DISP3 :
597       errmsg = insert_normal (cd, fields->f_disp3, 0, 0, 9, 3, 32, total_length, buffer);
598       break;
599     case EPIPHANY_OPERAND_DPMI :
600       errmsg = insert_normal (cd, fields->f_subd, 0, 0, 24, 1, 32, total_length, buffer);
601       break;
602     case EPIPHANY_OPERAND_FRD :
603       errmsg = insert_normal (cd, fields->f_rd, 0, 0, 15, 3, 32, total_length, buffer);
604       break;
605     case EPIPHANY_OPERAND_FRD6 :
606       {
607 {
608   FLD (f_rd) = ((FLD (f_rd6)) & (7));
609   FLD (f_rd_x) = ((UINT) (FLD (f_rd6)) >> (3));
610 }
611         errmsg = insert_normal (cd, fields->f_rd_x, 0, 0, 31, 3, 32, total_length, buffer);
612         if (errmsg)
613           break;
614         errmsg = insert_normal (cd, fields->f_rd, 0, 0, 15, 3, 32, total_length, buffer);
615         if (errmsg)
616           break;
617       }
618       break;
619     case EPIPHANY_OPERAND_FRM :
620       errmsg = insert_normal (cd, fields->f_rm, 0, 0, 9, 3, 32, total_length, buffer);
621       break;
622     case EPIPHANY_OPERAND_FRM6 :
623       {
624 {
625   FLD (f_rm) = ((FLD (f_rm6)) & (7));
626   FLD (f_rm_x) = ((UINT) (FLD (f_rm6)) >> (3));
627 }
628         errmsg = insert_normal (cd, fields->f_rm_x, 0, 0, 25, 3, 32, total_length, buffer);
629         if (errmsg)
630           break;
631         errmsg = insert_normal (cd, fields->f_rm, 0, 0, 9, 3, 32, total_length, buffer);
632         if (errmsg)
633           break;
634       }
635       break;
636     case EPIPHANY_OPERAND_FRN :
637       errmsg = insert_normal (cd, fields->f_rn, 0, 0, 12, 3, 32, total_length, buffer);
638       break;
639     case EPIPHANY_OPERAND_FRN6 :
640       {
641 {
642   FLD (f_rn) = ((FLD (f_rn6)) & (7));
643   FLD (f_rn_x) = ((UINT) (FLD (f_rn6)) >> (3));
644 }
645         errmsg = insert_normal (cd, fields->f_rn_x, 0, 0, 28, 3, 32, total_length, buffer);
646         if (errmsg)
647           break;
648         errmsg = insert_normal (cd, fields->f_rn, 0, 0, 12, 3, 32, total_length, buffer);
649         if (errmsg)
650           break;
651       }
652       break;
653     case EPIPHANY_OPERAND_IMM16 :
654       {
655 {
656   FLD (f_imm8) = ((FLD (f_imm16)) & (255));
657   FLD (f_imm_27_8) = ((UINT) (FLD (f_imm16)) >> (8));
658 }
659         errmsg = insert_normal (cd, fields->f_imm8, 0, 0, 12, 8, 32, total_length, buffer);
660         if (errmsg)
661           break;
662         errmsg = insert_normal (cd, fields->f_imm_27_8, 0, 0, 27, 8, 32, total_length, buffer);
663         if (errmsg)
664           break;
665       }
666       break;
667     case EPIPHANY_OPERAND_IMM8 :
668       errmsg = insert_normal (cd, fields->f_imm8, 0, 0, 12, 8, 32, total_length, buffer);
669       break;
670     case EPIPHANY_OPERAND_RD :
671       errmsg = insert_normal (cd, fields->f_rd, 0, 0, 15, 3, 32, total_length, buffer);
672       break;
673     case EPIPHANY_OPERAND_RD6 :
674       {
675 {
676   FLD (f_rd) = ((FLD (f_rd6)) & (7));
677   FLD (f_rd_x) = ((UINT) (FLD (f_rd6)) >> (3));
678 }
679         errmsg = insert_normal (cd, fields->f_rd_x, 0, 0, 31, 3, 32, total_length, buffer);
680         if (errmsg)
681           break;
682         errmsg = insert_normal (cd, fields->f_rd, 0, 0, 15, 3, 32, total_length, buffer);
683         if (errmsg)
684           break;
685       }
686       break;
687     case EPIPHANY_OPERAND_RM :
688       errmsg = insert_normal (cd, fields->f_rm, 0, 0, 9, 3, 32, total_length, buffer);
689       break;
690     case EPIPHANY_OPERAND_RM6 :
691       {
692 {
693   FLD (f_rm) = ((FLD (f_rm6)) & (7));
694   FLD (f_rm_x) = ((UINT) (FLD (f_rm6)) >> (3));
695 }
696         errmsg = insert_normal (cd, fields->f_rm_x, 0, 0, 25, 3, 32, total_length, buffer);
697         if (errmsg)
698           break;
699         errmsg = insert_normal (cd, fields->f_rm, 0, 0, 9, 3, 32, total_length, buffer);
700         if (errmsg)
701           break;
702       }
703       break;
704     case EPIPHANY_OPERAND_RN :
705       errmsg = insert_normal (cd, fields->f_rn, 0, 0, 12, 3, 32, total_length, buffer);
706       break;
707     case EPIPHANY_OPERAND_RN6 :
708       {
709 {
710   FLD (f_rn) = ((FLD (f_rn6)) & (7));
711   FLD (f_rn_x) = ((UINT) (FLD (f_rn6)) >> (3));
712 }
713         errmsg = insert_normal (cd, fields->f_rn_x, 0, 0, 28, 3, 32, total_length, buffer);
714         if (errmsg)
715           break;
716         errmsg = insert_normal (cd, fields->f_rn, 0, 0, 12, 3, 32, total_length, buffer);
717         if (errmsg)
718           break;
719       }
720       break;
721     case EPIPHANY_OPERAND_SD :
722       errmsg = insert_normal (cd, fields->f_sd, 0, 0, 15, 3, 32, total_length, buffer);
723       break;
724     case EPIPHANY_OPERAND_SD6 :
725       {
726 {
727   FLD (f_sd) = ((FLD (f_sd6)) & (7));
728   FLD (f_sd_x) = ((UINT) (FLD (f_sd6)) >> (3));
729 }
730         errmsg = insert_normal (cd, fields->f_sd_x, 0, 0, 31, 3, 32, total_length, buffer);
731         if (errmsg)
732           break;
733         errmsg = insert_normal (cd, fields->f_sd, 0, 0, 15, 3, 32, total_length, buffer);
734         if (errmsg)
735           break;
736       }
737       break;
738     case EPIPHANY_OPERAND_SDDMA :
739       {
740 {
741   FLD (f_sd) = ((FLD (f_sd6)) & (7));
742   FLD (f_sd_x) = ((UINT) (FLD (f_sd6)) >> (3));
743 }
744         errmsg = insert_normal (cd, fields->f_sd_x, 0, 0, 31, 3, 32, total_length, buffer);
745         if (errmsg)
746           break;
747         errmsg = insert_normal (cd, fields->f_sd, 0, 0, 15, 3, 32, total_length, buffer);
748         if (errmsg)
749           break;
750       }
751       break;
752     case EPIPHANY_OPERAND_SDMEM :
753       {
754 {
755   FLD (f_sd) = ((FLD (f_sd6)) & (7));
756   FLD (f_sd_x) = ((UINT) (FLD (f_sd6)) >> (3));
757 }
758         errmsg = insert_normal (cd, fields->f_sd_x, 0, 0, 31, 3, 32, total_length, buffer);
759         if (errmsg)
760           break;
761         errmsg = insert_normal (cd, fields->f_sd, 0, 0, 15, 3, 32, total_length, buffer);
762         if (errmsg)
763           break;
764       }
765       break;
766     case EPIPHANY_OPERAND_SDMESH :
767       {
768 {
769   FLD (f_sd) = ((FLD (f_sd6)) & (7));
770   FLD (f_sd_x) = ((UINT) (FLD (f_sd6)) >> (3));
771 }
772         errmsg = insert_normal (cd, fields->f_sd_x, 0, 0, 31, 3, 32, total_length, buffer);
773         if (errmsg)
774           break;
775         errmsg = insert_normal (cd, fields->f_sd, 0, 0, 15, 3, 32, total_length, buffer);
776         if (errmsg)
777           break;
778       }
779       break;
780     case EPIPHANY_OPERAND_SHIFT :
781       errmsg = insert_normal (cd, fields->f_shift, 0, 0, 9, 5, 32, total_length, buffer);
782       break;
783     case EPIPHANY_OPERAND_SIMM11 :
784       {
785 {
786   FLD (f_disp8) = ((255) & (((USI) (FLD (f_sdisp11)) >> (3))));
787   FLD (f_disp3) = ((FLD (f_sdisp11)) & (7));
788 }
789         errmsg = insert_normal (cd, fields->f_disp3, 0, 0, 9, 3, 32, total_length, buffer);
790         if (errmsg)
791           break;
792         errmsg = insert_normal (cd, fields->f_disp8, 0, 0, 23, 8, 32, total_length, buffer);
793         if (errmsg)
794           break;
795       }
796       break;
797     case EPIPHANY_OPERAND_SIMM24 :
798       {
799         long value = fields->f_simm24;
800         value = ((SI) (((value) - (pc))) >> (1));
801         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);
802       }
803       break;
804     case EPIPHANY_OPERAND_SIMM3 :
805       errmsg = insert_normal (cd, fields->f_sdisp3, 0|(1<<CGEN_IFLD_SIGNED), 0, 9, 3, 32, total_length, buffer);
806       break;
807     case EPIPHANY_OPERAND_SIMM8 :
808       {
809         long value = fields->f_simm8;
810         value = ((SI) (((value) - (pc))) >> (1));
811         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);
812       }
813       break;
814     case EPIPHANY_OPERAND_SN :
815       errmsg = insert_normal (cd, fields->f_sn, 0, 0, 12, 3, 32, total_length, buffer);
816       break;
817     case EPIPHANY_OPERAND_SN6 :
818       {
819 {
820   FLD (f_sn) = ((FLD (f_sn6)) & (7));
821   FLD (f_sn_x) = ((UINT) (FLD (f_sn6)) >> (3));
822 }
823         errmsg = insert_normal (cd, fields->f_sn_x, 0, 0, 28, 3, 32, total_length, buffer);
824         if (errmsg)
825           break;
826         errmsg = insert_normal (cd, fields->f_sn, 0, 0, 12, 3, 32, total_length, buffer);
827         if (errmsg)
828           break;
829       }
830       break;
831     case EPIPHANY_OPERAND_SNDMA :
832       {
833 {
834   FLD (f_sn) = ((FLD (f_sn6)) & (7));
835   FLD (f_sn_x) = ((UINT) (FLD (f_sn6)) >> (3));
836 }
837         errmsg = insert_normal (cd, fields->f_sn_x, 0, 0, 28, 3, 32, total_length, buffer);
838         if (errmsg)
839           break;
840         errmsg = insert_normal (cd, fields->f_sn, 0, 0, 12, 3, 32, total_length, buffer);
841         if (errmsg)
842           break;
843       }
844       break;
845     case EPIPHANY_OPERAND_SNMEM :
846       {
847 {
848   FLD (f_sn) = ((FLD (f_sn6)) & (7));
849   FLD (f_sn_x) = ((UINT) (FLD (f_sn6)) >> (3));
850 }
851         errmsg = insert_normal (cd, fields->f_sn_x, 0, 0, 28, 3, 32, total_length, buffer);
852         if (errmsg)
853           break;
854         errmsg = insert_normal (cd, fields->f_sn, 0, 0, 12, 3, 32, total_length, buffer);
855         if (errmsg)
856           break;
857       }
858       break;
859     case EPIPHANY_OPERAND_SNMESH :
860       {
861 {
862   FLD (f_sn) = ((FLD (f_sn6)) & (7));
863   FLD (f_sn_x) = ((UINT) (FLD (f_sn6)) >> (3));
864 }
865         errmsg = insert_normal (cd, fields->f_sn_x, 0, 0, 28, 3, 32, total_length, buffer);
866         if (errmsg)
867           break;
868         errmsg = insert_normal (cd, fields->f_sn, 0, 0, 12, 3, 32, total_length, buffer);
869         if (errmsg)
870           break;
871       }
872       break;
873     case EPIPHANY_OPERAND_SWI_NUM :
874       errmsg = insert_normal (cd, fields->f_trap_num, 0, 0, 15, 6, 32, total_length, buffer);
875       break;
876     case EPIPHANY_OPERAND_TRAPNUM6 :
877       errmsg = insert_normal (cd, fields->f_trap_num, 0, 0, 15, 6, 32, total_length, buffer);
878       break;
879
880     default :
881       /* xgettext:c-format */
882       opcodes_error_handler
883         (_("internal error: unrecognized field %d while building insn"),
884          opindex);
885       abort ();
886   }
887
888   return errmsg;
889 }
890
891 int epiphany_cgen_extract_operand
892   (CGEN_CPU_DESC, int, CGEN_EXTRACT_INFO *, CGEN_INSN_INT, CGEN_FIELDS *, bfd_vma);
893
894 /* Main entry point for operand extraction.
895    The result is <= 0 for error, >0 for success.
896    ??? Actual values aren't well defined right now.
897
898    This function is basically just a big switch statement.  Earlier versions
899    used tables to look up the function to use, but
900    - if the table contains both assembler and disassembler functions then
901      the disassembler contains much of the assembler and vice-versa,
902    - there's a lot of inlining possibilities as things grow,
903    - using a switch statement avoids the function call overhead.
904
905    This function could be moved into `print_insn_normal', but keeping it
906    separate makes clear the interface between `print_insn_normal' and each of
907    the handlers.  */
908
909 int
910 epiphany_cgen_extract_operand (CGEN_CPU_DESC cd,
911                              int opindex,
912                              CGEN_EXTRACT_INFO *ex_info,
913                              CGEN_INSN_INT insn_value,
914                              CGEN_FIELDS * fields,
915                              bfd_vma pc)
916 {
917   /* Assume success (for those operands that are nops).  */
918   int length = 1;
919   unsigned int total_length = CGEN_FIELDS_BITSIZE (fields);
920
921   switch (opindex)
922     {
923     case EPIPHANY_OPERAND_DIRECTION :
924       length = extract_normal (cd, ex_info, insn_value, 0, 0, 20, 1, 32, total_length, pc, & fields->f_addsubx);
925       break;
926     case EPIPHANY_OPERAND_DISP11 :
927       {
928         length = extract_normal (cd, ex_info, insn_value, 0, 0, 9, 3, 32, total_length, pc, & fields->f_disp3);
929         if (length <= 0) break;
930         length = extract_normal (cd, ex_info, insn_value, 0, 0, 23, 8, 32, total_length, pc, & fields->f_disp8);
931         if (length <= 0) break;
932 {
933   FLD (f_disp11) = ((((FLD (f_disp8)) << (3))) | (FLD (f_disp3)));
934 }
935       }
936       break;
937     case EPIPHANY_OPERAND_DISP3 :
938       length = extract_normal (cd, ex_info, insn_value, 0, 0, 9, 3, 32, total_length, pc, & fields->f_disp3);
939       break;
940     case EPIPHANY_OPERAND_DPMI :
941       length = extract_normal (cd, ex_info, insn_value, 0, 0, 24, 1, 32, total_length, pc, & fields->f_subd);
942       break;
943     case EPIPHANY_OPERAND_FRD :
944       length = extract_normal (cd, ex_info, insn_value, 0, 0, 15, 3, 32, total_length, pc, & fields->f_rd);
945       break;
946     case EPIPHANY_OPERAND_FRD6 :
947       {
948         length = extract_normal (cd, ex_info, insn_value, 0, 0, 31, 3, 32, total_length, pc, & fields->f_rd_x);
949         if (length <= 0) break;
950         length = extract_normal (cd, ex_info, insn_value, 0, 0, 15, 3, 32, total_length, pc, & fields->f_rd);
951         if (length <= 0) break;
952 {
953   FLD (f_rd6) = ((((FLD (f_rd_x)) << (3))) | (FLD (f_rd)));
954 }
955       }
956       break;
957     case EPIPHANY_OPERAND_FRM :
958       length = extract_normal (cd, ex_info, insn_value, 0, 0, 9, 3, 32, total_length, pc, & fields->f_rm);
959       break;
960     case EPIPHANY_OPERAND_FRM6 :
961       {
962         length = extract_normal (cd, ex_info, insn_value, 0, 0, 25, 3, 32, total_length, pc, & fields->f_rm_x);
963         if (length <= 0) break;
964         length = extract_normal (cd, ex_info, insn_value, 0, 0, 9, 3, 32, total_length, pc, & fields->f_rm);
965         if (length <= 0) break;
966 {
967   FLD (f_rm6) = ((((FLD (f_rm_x)) << (3))) | (FLD (f_rm)));
968 }
969       }
970       break;
971     case EPIPHANY_OPERAND_FRN :
972       length = extract_normal (cd, ex_info, insn_value, 0, 0, 12, 3, 32, total_length, pc, & fields->f_rn);
973       break;
974     case EPIPHANY_OPERAND_FRN6 :
975       {
976         length = extract_normal (cd, ex_info, insn_value, 0, 0, 28, 3, 32, total_length, pc, & fields->f_rn_x);
977         if (length <= 0) break;
978         length = extract_normal (cd, ex_info, insn_value, 0, 0, 12, 3, 32, total_length, pc, & fields->f_rn);
979         if (length <= 0) break;
980 {
981   FLD (f_rn6) = ((((FLD (f_rn_x)) << (3))) | (FLD (f_rn)));
982 }
983       }
984       break;
985     case EPIPHANY_OPERAND_IMM16 :
986       {
987         length = extract_normal (cd, ex_info, insn_value, 0, 0, 12, 8, 32, total_length, pc, & fields->f_imm8);
988         if (length <= 0) break;
989         length = extract_normal (cd, ex_info, insn_value, 0, 0, 27, 8, 32, total_length, pc, & fields->f_imm_27_8);
990         if (length <= 0) break;
991 {
992   FLD (f_imm16) = ((((FLD (f_imm_27_8)) << (8))) | (FLD (f_imm8)));
993 }
994       }
995       break;
996     case EPIPHANY_OPERAND_IMM8 :
997       length = extract_normal (cd, ex_info, insn_value, 0, 0, 12, 8, 32, total_length, pc, & fields->f_imm8);
998       break;
999     case EPIPHANY_OPERAND_RD :
1000       length = extract_normal (cd, ex_info, insn_value, 0, 0, 15, 3, 32, total_length, pc, & fields->f_rd);
1001       break;
1002     case EPIPHANY_OPERAND_RD6 :
1003       {
1004         length = extract_normal (cd, ex_info, insn_value, 0, 0, 31, 3, 32, total_length, pc, & fields->f_rd_x);
1005         if (length <= 0) break;
1006         length = extract_normal (cd, ex_info, insn_value, 0, 0, 15, 3, 32, total_length, pc, & fields->f_rd);
1007         if (length <= 0) break;
1008 {
1009   FLD (f_rd6) = ((((FLD (f_rd_x)) << (3))) | (FLD (f_rd)));
1010 }
1011       }
1012       break;
1013     case EPIPHANY_OPERAND_RM :
1014       length = extract_normal (cd, ex_info, insn_value, 0, 0, 9, 3, 32, total_length, pc, & fields->f_rm);
1015       break;
1016     case EPIPHANY_OPERAND_RM6 :
1017       {
1018         length = extract_normal (cd, ex_info, insn_value, 0, 0, 25, 3, 32, total_length, pc, & fields->f_rm_x);
1019         if (length <= 0) break;
1020         length = extract_normal (cd, ex_info, insn_value, 0, 0, 9, 3, 32, total_length, pc, & fields->f_rm);
1021         if (length <= 0) break;
1022 {
1023   FLD (f_rm6) = ((((FLD (f_rm_x)) << (3))) | (FLD (f_rm)));
1024 }
1025       }
1026       break;
1027     case EPIPHANY_OPERAND_RN :
1028       length = extract_normal (cd, ex_info, insn_value, 0, 0, 12, 3, 32, total_length, pc, & fields->f_rn);
1029       break;
1030     case EPIPHANY_OPERAND_RN6 :
1031       {
1032         length = extract_normal (cd, ex_info, insn_value, 0, 0, 28, 3, 32, total_length, pc, & fields->f_rn_x);
1033         if (length <= 0) break;
1034         length = extract_normal (cd, ex_info, insn_value, 0, 0, 12, 3, 32, total_length, pc, & fields->f_rn);
1035         if (length <= 0) break;
1036 {
1037   FLD (f_rn6) = ((((FLD (f_rn_x)) << (3))) | (FLD (f_rn)));
1038 }
1039       }
1040       break;
1041     case EPIPHANY_OPERAND_SD :
1042       length = extract_normal (cd, ex_info, insn_value, 0, 0, 15, 3, 32, total_length, pc, & fields->f_sd);
1043       break;
1044     case EPIPHANY_OPERAND_SD6 :
1045       {
1046         length = extract_normal (cd, ex_info, insn_value, 0, 0, 31, 3, 32, total_length, pc, & fields->f_sd_x);
1047         if (length <= 0) break;
1048         length = extract_normal (cd, ex_info, insn_value, 0, 0, 15, 3, 32, total_length, pc, & fields->f_sd);
1049         if (length <= 0) break;
1050 {
1051   FLD (f_sd6) = ((((FLD (f_sd_x)) << (3))) | (FLD (f_sd)));
1052 }
1053       }
1054       break;
1055     case EPIPHANY_OPERAND_SDDMA :
1056       {
1057         length = extract_normal (cd, ex_info, insn_value, 0, 0, 31, 3, 32, total_length, pc, & fields->f_sd_x);
1058         if (length <= 0) break;
1059         length = extract_normal (cd, ex_info, insn_value, 0, 0, 15, 3, 32, total_length, pc, & fields->f_sd);
1060         if (length <= 0) break;
1061 {
1062   FLD (f_sd6) = ((((FLD (f_sd_x)) << (3))) | (FLD (f_sd)));
1063 }
1064       }
1065       break;
1066     case EPIPHANY_OPERAND_SDMEM :
1067       {
1068         length = extract_normal (cd, ex_info, insn_value, 0, 0, 31, 3, 32, total_length, pc, & fields->f_sd_x);
1069         if (length <= 0) break;
1070         length = extract_normal (cd, ex_info, insn_value, 0, 0, 15, 3, 32, total_length, pc, & fields->f_sd);
1071         if (length <= 0) break;
1072 {
1073   FLD (f_sd6) = ((((FLD (f_sd_x)) << (3))) | (FLD (f_sd)));
1074 }
1075       }
1076       break;
1077     case EPIPHANY_OPERAND_SDMESH :
1078       {
1079         length = extract_normal (cd, ex_info, insn_value, 0, 0, 31, 3, 32, total_length, pc, & fields->f_sd_x);
1080         if (length <= 0) break;
1081         length = extract_normal (cd, ex_info, insn_value, 0, 0, 15, 3, 32, total_length, pc, & fields->f_sd);
1082         if (length <= 0) break;
1083 {
1084   FLD (f_sd6) = ((((FLD (f_sd_x)) << (3))) | (FLD (f_sd)));
1085 }
1086       }
1087       break;
1088     case EPIPHANY_OPERAND_SHIFT :
1089       length = extract_normal (cd, ex_info, insn_value, 0, 0, 9, 5, 32, total_length, pc, & fields->f_shift);
1090       break;
1091     case EPIPHANY_OPERAND_SIMM11 :
1092       {
1093         length = extract_normal (cd, ex_info, insn_value, 0, 0, 9, 3, 32, total_length, pc, & fields->f_disp3);
1094         if (length <= 0) break;
1095         length = extract_normal (cd, ex_info, insn_value, 0, 0, 23, 8, 32, total_length, pc, & fields->f_disp8);
1096         if (length <= 0) break;
1097 {
1098   FLD (f_sdisp11) = ((((((((((FLD (f_disp8)) << (3))) | (FLD (f_disp3)))) & (2047))) ^ (1024))) - (1024));
1099 }
1100       }
1101       break;
1102     case EPIPHANY_OPERAND_SIMM24 :
1103       {
1104         long value;
1105         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);
1106         value = ((((value) * (2))) + (pc));
1107         fields->f_simm24 = value;
1108       }
1109       break;
1110     case EPIPHANY_OPERAND_SIMM3 :
1111       length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_SIGNED), 0, 9, 3, 32, total_length, pc, & fields->f_sdisp3);
1112       break;
1113     case EPIPHANY_OPERAND_SIMM8 :
1114       {
1115         long value;
1116         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);
1117         value = ((((value) * (2))) + (pc));
1118         fields->f_simm8 = value;
1119       }
1120       break;
1121     case EPIPHANY_OPERAND_SN :
1122       length = extract_normal (cd, ex_info, insn_value, 0, 0, 12, 3, 32, total_length, pc, & fields->f_sn);
1123       break;
1124     case EPIPHANY_OPERAND_SN6 :
1125       {
1126         length = extract_normal (cd, ex_info, insn_value, 0, 0, 28, 3, 32, total_length, pc, & fields->f_sn_x);
1127         if (length <= 0) break;
1128         length = extract_normal (cd, ex_info, insn_value, 0, 0, 12, 3, 32, total_length, pc, & fields->f_sn);
1129         if (length <= 0) break;
1130 {
1131   FLD (f_sn6) = ((((FLD (f_sn_x)) << (3))) | (FLD (f_sn)));
1132 }
1133       }
1134       break;
1135     case EPIPHANY_OPERAND_SNDMA :
1136       {
1137         length = extract_normal (cd, ex_info, insn_value, 0, 0, 28, 3, 32, total_length, pc, & fields->f_sn_x);
1138         if (length <= 0) break;
1139         length = extract_normal (cd, ex_info, insn_value, 0, 0, 12, 3, 32, total_length, pc, & fields->f_sn);
1140         if (length <= 0) break;
1141 {
1142   FLD (f_sn6) = ((((FLD (f_sn_x)) << (3))) | (FLD (f_sn)));
1143 }
1144       }
1145       break;
1146     case EPIPHANY_OPERAND_SNMEM :
1147       {
1148         length = extract_normal (cd, ex_info, insn_value, 0, 0, 28, 3, 32, total_length, pc, & fields->f_sn_x);
1149         if (length <= 0) break;
1150         length = extract_normal (cd, ex_info, insn_value, 0, 0, 12, 3, 32, total_length, pc, & fields->f_sn);
1151         if (length <= 0) break;
1152 {
1153   FLD (f_sn6) = ((((FLD (f_sn_x)) << (3))) | (FLD (f_sn)));
1154 }
1155       }
1156       break;
1157     case EPIPHANY_OPERAND_SNMESH :
1158       {
1159         length = extract_normal (cd, ex_info, insn_value, 0, 0, 28, 3, 32, total_length, pc, & fields->f_sn_x);
1160         if (length <= 0) break;
1161         length = extract_normal (cd, ex_info, insn_value, 0, 0, 12, 3, 32, total_length, pc, & fields->f_sn);
1162         if (length <= 0) break;
1163 {
1164   FLD (f_sn6) = ((((FLD (f_sn_x)) << (3))) | (FLD (f_sn)));
1165 }
1166       }
1167       break;
1168     case EPIPHANY_OPERAND_SWI_NUM :
1169       length = extract_normal (cd, ex_info, insn_value, 0, 0, 15, 6, 32, total_length, pc, & fields->f_trap_num);
1170       break;
1171     case EPIPHANY_OPERAND_TRAPNUM6 :
1172       length = extract_normal (cd, ex_info, insn_value, 0, 0, 15, 6, 32, total_length, pc, & fields->f_trap_num);
1173       break;
1174
1175     default :
1176       /* xgettext:c-format */
1177       opcodes_error_handler
1178         (_("internal error: unrecognized field %d while decoding insn"),
1179          opindex);
1180       abort ();
1181     }
1182
1183   return length;
1184 }
1185
1186 cgen_insert_fn * const epiphany_cgen_insert_handlers[] =
1187 {
1188   insert_insn_normal,
1189 };
1190
1191 cgen_extract_fn * const epiphany_cgen_extract_handlers[] =
1192 {
1193   extract_insn_normal,
1194 };
1195
1196 int epiphany_cgen_get_int_operand     (CGEN_CPU_DESC, int, const CGEN_FIELDS *);
1197 bfd_vma epiphany_cgen_get_vma_operand (CGEN_CPU_DESC, int, const CGEN_FIELDS *);
1198
1199 /* Getting values from cgen_fields is handled by a collection of functions.
1200    They are distinguished by the type of the VALUE argument they return.
1201    TODO: floating point, inlining support, remove cases where result type
1202    not appropriate.  */
1203
1204 int
1205 epiphany_cgen_get_int_operand (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
1206                              int opindex,
1207                              const CGEN_FIELDS * fields)
1208 {
1209   int value;
1210
1211   switch (opindex)
1212     {
1213     case EPIPHANY_OPERAND_DIRECTION :
1214       value = fields->f_addsubx;
1215       break;
1216     case EPIPHANY_OPERAND_DISP11 :
1217       value = fields->f_disp11;
1218       break;
1219     case EPIPHANY_OPERAND_DISP3 :
1220       value = fields->f_disp3;
1221       break;
1222     case EPIPHANY_OPERAND_DPMI :
1223       value = fields->f_subd;
1224       break;
1225     case EPIPHANY_OPERAND_FRD :
1226       value = fields->f_rd;
1227       break;
1228     case EPIPHANY_OPERAND_FRD6 :
1229       value = fields->f_rd6;
1230       break;
1231     case EPIPHANY_OPERAND_FRM :
1232       value = fields->f_rm;
1233       break;
1234     case EPIPHANY_OPERAND_FRM6 :
1235       value = fields->f_rm6;
1236       break;
1237     case EPIPHANY_OPERAND_FRN :
1238       value = fields->f_rn;
1239       break;
1240     case EPIPHANY_OPERAND_FRN6 :
1241       value = fields->f_rn6;
1242       break;
1243     case EPIPHANY_OPERAND_IMM16 :
1244       value = fields->f_imm16;
1245       break;
1246     case EPIPHANY_OPERAND_IMM8 :
1247       value = fields->f_imm8;
1248       break;
1249     case EPIPHANY_OPERAND_RD :
1250       value = fields->f_rd;
1251       break;
1252     case EPIPHANY_OPERAND_RD6 :
1253       value = fields->f_rd6;
1254       break;
1255     case EPIPHANY_OPERAND_RM :
1256       value = fields->f_rm;
1257       break;
1258     case EPIPHANY_OPERAND_RM6 :
1259       value = fields->f_rm6;
1260       break;
1261     case EPIPHANY_OPERAND_RN :
1262       value = fields->f_rn;
1263       break;
1264     case EPIPHANY_OPERAND_RN6 :
1265       value = fields->f_rn6;
1266       break;
1267     case EPIPHANY_OPERAND_SD :
1268       value = fields->f_sd;
1269       break;
1270     case EPIPHANY_OPERAND_SD6 :
1271       value = fields->f_sd6;
1272       break;
1273     case EPIPHANY_OPERAND_SDDMA :
1274       value = fields->f_sd6;
1275       break;
1276     case EPIPHANY_OPERAND_SDMEM :
1277       value = fields->f_sd6;
1278       break;
1279     case EPIPHANY_OPERAND_SDMESH :
1280       value = fields->f_sd6;
1281       break;
1282     case EPIPHANY_OPERAND_SHIFT :
1283       value = fields->f_shift;
1284       break;
1285     case EPIPHANY_OPERAND_SIMM11 :
1286       value = fields->f_sdisp11;
1287       break;
1288     case EPIPHANY_OPERAND_SIMM24 :
1289       value = fields->f_simm24;
1290       break;
1291     case EPIPHANY_OPERAND_SIMM3 :
1292       value = fields->f_sdisp3;
1293       break;
1294     case EPIPHANY_OPERAND_SIMM8 :
1295       value = fields->f_simm8;
1296       break;
1297     case EPIPHANY_OPERAND_SN :
1298       value = fields->f_sn;
1299       break;
1300     case EPIPHANY_OPERAND_SN6 :
1301       value = fields->f_sn6;
1302       break;
1303     case EPIPHANY_OPERAND_SNDMA :
1304       value = fields->f_sn6;
1305       break;
1306     case EPIPHANY_OPERAND_SNMEM :
1307       value = fields->f_sn6;
1308       break;
1309     case EPIPHANY_OPERAND_SNMESH :
1310       value = fields->f_sn6;
1311       break;
1312     case EPIPHANY_OPERAND_SWI_NUM :
1313       value = fields->f_trap_num;
1314       break;
1315     case EPIPHANY_OPERAND_TRAPNUM6 :
1316       value = fields->f_trap_num;
1317       break;
1318
1319     default :
1320       /* xgettext:c-format */
1321       opcodes_error_handler
1322         (_("internal error: unrecognized field %d while getting int operand"),
1323          opindex);
1324       abort ();
1325   }
1326
1327   return value;
1328 }
1329
1330 bfd_vma
1331 epiphany_cgen_get_vma_operand (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
1332                              int opindex,
1333                              const CGEN_FIELDS * fields)
1334 {
1335   bfd_vma value;
1336
1337   switch (opindex)
1338     {
1339     case EPIPHANY_OPERAND_DIRECTION :
1340       value = fields->f_addsubx;
1341       break;
1342     case EPIPHANY_OPERAND_DISP11 :
1343       value = fields->f_disp11;
1344       break;
1345     case EPIPHANY_OPERAND_DISP3 :
1346       value = fields->f_disp3;
1347       break;
1348     case EPIPHANY_OPERAND_DPMI :
1349       value = fields->f_subd;
1350       break;
1351     case EPIPHANY_OPERAND_FRD :
1352       value = fields->f_rd;
1353       break;
1354     case EPIPHANY_OPERAND_FRD6 :
1355       value = fields->f_rd6;
1356       break;
1357     case EPIPHANY_OPERAND_FRM :
1358       value = fields->f_rm;
1359       break;
1360     case EPIPHANY_OPERAND_FRM6 :
1361       value = fields->f_rm6;
1362       break;
1363     case EPIPHANY_OPERAND_FRN :
1364       value = fields->f_rn;
1365       break;
1366     case EPIPHANY_OPERAND_FRN6 :
1367       value = fields->f_rn6;
1368       break;
1369     case EPIPHANY_OPERAND_IMM16 :
1370       value = fields->f_imm16;
1371       break;
1372     case EPIPHANY_OPERAND_IMM8 :
1373       value = fields->f_imm8;
1374       break;
1375     case EPIPHANY_OPERAND_RD :
1376       value = fields->f_rd;
1377       break;
1378     case EPIPHANY_OPERAND_RD6 :
1379       value = fields->f_rd6;
1380       break;
1381     case EPIPHANY_OPERAND_RM :
1382       value = fields->f_rm;
1383       break;
1384     case EPIPHANY_OPERAND_RM6 :
1385       value = fields->f_rm6;
1386       break;
1387     case EPIPHANY_OPERAND_RN :
1388       value = fields->f_rn;
1389       break;
1390     case EPIPHANY_OPERAND_RN6 :
1391       value = fields->f_rn6;
1392       break;
1393     case EPIPHANY_OPERAND_SD :
1394       value = fields->f_sd;
1395       break;
1396     case EPIPHANY_OPERAND_SD6 :
1397       value = fields->f_sd6;
1398       break;
1399     case EPIPHANY_OPERAND_SDDMA :
1400       value = fields->f_sd6;
1401       break;
1402     case EPIPHANY_OPERAND_SDMEM :
1403       value = fields->f_sd6;
1404       break;
1405     case EPIPHANY_OPERAND_SDMESH :
1406       value = fields->f_sd6;
1407       break;
1408     case EPIPHANY_OPERAND_SHIFT :
1409       value = fields->f_shift;
1410       break;
1411     case EPIPHANY_OPERAND_SIMM11 :
1412       value = fields->f_sdisp11;
1413       break;
1414     case EPIPHANY_OPERAND_SIMM24 :
1415       value = fields->f_simm24;
1416       break;
1417     case EPIPHANY_OPERAND_SIMM3 :
1418       value = fields->f_sdisp3;
1419       break;
1420     case EPIPHANY_OPERAND_SIMM8 :
1421       value = fields->f_simm8;
1422       break;
1423     case EPIPHANY_OPERAND_SN :
1424       value = fields->f_sn;
1425       break;
1426     case EPIPHANY_OPERAND_SN6 :
1427       value = fields->f_sn6;
1428       break;
1429     case EPIPHANY_OPERAND_SNDMA :
1430       value = fields->f_sn6;
1431       break;
1432     case EPIPHANY_OPERAND_SNMEM :
1433       value = fields->f_sn6;
1434       break;
1435     case EPIPHANY_OPERAND_SNMESH :
1436       value = fields->f_sn6;
1437       break;
1438     case EPIPHANY_OPERAND_SWI_NUM :
1439       value = fields->f_trap_num;
1440       break;
1441     case EPIPHANY_OPERAND_TRAPNUM6 :
1442       value = fields->f_trap_num;
1443       break;
1444
1445     default :
1446       /* xgettext:c-format */
1447       opcodes_error_handler
1448         (_("internal error: unrecognized field %d while getting vma operand"),
1449          opindex);
1450       abort ();
1451   }
1452
1453   return value;
1454 }
1455
1456 void epiphany_cgen_set_int_operand  (CGEN_CPU_DESC, int, CGEN_FIELDS *, int);
1457 void epiphany_cgen_set_vma_operand  (CGEN_CPU_DESC, int, CGEN_FIELDS *, bfd_vma);
1458
1459 /* Stuffing values in cgen_fields is handled by a collection of functions.
1460    They are distinguished by the type of the VALUE argument they accept.
1461    TODO: floating point, inlining support, remove cases where argument type
1462    not appropriate.  */
1463
1464 void
1465 epiphany_cgen_set_int_operand (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
1466                              int opindex,
1467                              CGEN_FIELDS * fields,
1468                              int value)
1469 {
1470   switch (opindex)
1471     {
1472     case EPIPHANY_OPERAND_DIRECTION :
1473       fields->f_addsubx = value;
1474       break;
1475     case EPIPHANY_OPERAND_DISP11 :
1476       fields->f_disp11 = value;
1477       break;
1478     case EPIPHANY_OPERAND_DISP3 :
1479       fields->f_disp3 = value;
1480       break;
1481     case EPIPHANY_OPERAND_DPMI :
1482       fields->f_subd = value;
1483       break;
1484     case EPIPHANY_OPERAND_FRD :
1485       fields->f_rd = value;
1486       break;
1487     case EPIPHANY_OPERAND_FRD6 :
1488       fields->f_rd6 = value;
1489       break;
1490     case EPIPHANY_OPERAND_FRM :
1491       fields->f_rm = value;
1492       break;
1493     case EPIPHANY_OPERAND_FRM6 :
1494       fields->f_rm6 = value;
1495       break;
1496     case EPIPHANY_OPERAND_FRN :
1497       fields->f_rn = value;
1498       break;
1499     case EPIPHANY_OPERAND_FRN6 :
1500       fields->f_rn6 = value;
1501       break;
1502     case EPIPHANY_OPERAND_IMM16 :
1503       fields->f_imm16 = value;
1504       break;
1505     case EPIPHANY_OPERAND_IMM8 :
1506       fields->f_imm8 = value;
1507       break;
1508     case EPIPHANY_OPERAND_RD :
1509       fields->f_rd = value;
1510       break;
1511     case EPIPHANY_OPERAND_RD6 :
1512       fields->f_rd6 = value;
1513       break;
1514     case EPIPHANY_OPERAND_RM :
1515       fields->f_rm = value;
1516       break;
1517     case EPIPHANY_OPERAND_RM6 :
1518       fields->f_rm6 = value;
1519       break;
1520     case EPIPHANY_OPERAND_RN :
1521       fields->f_rn = value;
1522       break;
1523     case EPIPHANY_OPERAND_RN6 :
1524       fields->f_rn6 = value;
1525       break;
1526     case EPIPHANY_OPERAND_SD :
1527       fields->f_sd = value;
1528       break;
1529     case EPIPHANY_OPERAND_SD6 :
1530       fields->f_sd6 = value;
1531       break;
1532     case EPIPHANY_OPERAND_SDDMA :
1533       fields->f_sd6 = value;
1534       break;
1535     case EPIPHANY_OPERAND_SDMEM :
1536       fields->f_sd6 = value;
1537       break;
1538     case EPIPHANY_OPERAND_SDMESH :
1539       fields->f_sd6 = value;
1540       break;
1541     case EPIPHANY_OPERAND_SHIFT :
1542       fields->f_shift = value;
1543       break;
1544     case EPIPHANY_OPERAND_SIMM11 :
1545       fields->f_sdisp11 = value;
1546       break;
1547     case EPIPHANY_OPERAND_SIMM24 :
1548       fields->f_simm24 = value;
1549       break;
1550     case EPIPHANY_OPERAND_SIMM3 :
1551       fields->f_sdisp3 = value;
1552       break;
1553     case EPIPHANY_OPERAND_SIMM8 :
1554       fields->f_simm8 = value;
1555       break;
1556     case EPIPHANY_OPERAND_SN :
1557       fields->f_sn = value;
1558       break;
1559     case EPIPHANY_OPERAND_SN6 :
1560       fields->f_sn6 = value;
1561       break;
1562     case EPIPHANY_OPERAND_SNDMA :
1563       fields->f_sn6 = value;
1564       break;
1565     case EPIPHANY_OPERAND_SNMEM :
1566       fields->f_sn6 = value;
1567       break;
1568     case EPIPHANY_OPERAND_SNMESH :
1569       fields->f_sn6 = value;
1570       break;
1571     case EPIPHANY_OPERAND_SWI_NUM :
1572       fields->f_trap_num = value;
1573       break;
1574     case EPIPHANY_OPERAND_TRAPNUM6 :
1575       fields->f_trap_num = value;
1576       break;
1577
1578     default :
1579       /* xgettext:c-format */
1580       opcodes_error_handler
1581         (_("internal error: unrecognized field %d while setting int operand"),
1582          opindex);
1583       abort ();
1584   }
1585 }
1586
1587 void
1588 epiphany_cgen_set_vma_operand (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
1589                              int opindex,
1590                              CGEN_FIELDS * fields,
1591                              bfd_vma value)
1592 {
1593   switch (opindex)
1594     {
1595     case EPIPHANY_OPERAND_DIRECTION :
1596       fields->f_addsubx = value;
1597       break;
1598     case EPIPHANY_OPERAND_DISP11 :
1599       fields->f_disp11 = value;
1600       break;
1601     case EPIPHANY_OPERAND_DISP3 :
1602       fields->f_disp3 = value;
1603       break;
1604     case EPIPHANY_OPERAND_DPMI :
1605       fields->f_subd = value;
1606       break;
1607     case EPIPHANY_OPERAND_FRD :
1608       fields->f_rd = value;
1609       break;
1610     case EPIPHANY_OPERAND_FRD6 :
1611       fields->f_rd6 = value;
1612       break;
1613     case EPIPHANY_OPERAND_FRM :
1614       fields->f_rm = value;
1615       break;
1616     case EPIPHANY_OPERAND_FRM6 :
1617       fields->f_rm6 = value;
1618       break;
1619     case EPIPHANY_OPERAND_FRN :
1620       fields->f_rn = value;
1621       break;
1622     case EPIPHANY_OPERAND_FRN6 :
1623       fields->f_rn6 = value;
1624       break;
1625     case EPIPHANY_OPERAND_IMM16 :
1626       fields->f_imm16 = value;
1627       break;
1628     case EPIPHANY_OPERAND_IMM8 :
1629       fields->f_imm8 = value;
1630       break;
1631     case EPIPHANY_OPERAND_RD :
1632       fields->f_rd = value;
1633       break;
1634     case EPIPHANY_OPERAND_RD6 :
1635       fields->f_rd6 = value;
1636       break;
1637     case EPIPHANY_OPERAND_RM :
1638       fields->f_rm = value;
1639       break;
1640     case EPIPHANY_OPERAND_RM6 :
1641       fields->f_rm6 = value;
1642       break;
1643     case EPIPHANY_OPERAND_RN :
1644       fields->f_rn = value;
1645       break;
1646     case EPIPHANY_OPERAND_RN6 :
1647       fields->f_rn6 = value;
1648       break;
1649     case EPIPHANY_OPERAND_SD :
1650       fields->f_sd = value;
1651       break;
1652     case EPIPHANY_OPERAND_SD6 :
1653       fields->f_sd6 = value;
1654       break;
1655     case EPIPHANY_OPERAND_SDDMA :
1656       fields->f_sd6 = value;
1657       break;
1658     case EPIPHANY_OPERAND_SDMEM :
1659       fields->f_sd6 = value;
1660       break;
1661     case EPIPHANY_OPERAND_SDMESH :
1662       fields->f_sd6 = value;
1663       break;
1664     case EPIPHANY_OPERAND_SHIFT :
1665       fields->f_shift = value;
1666       break;
1667     case EPIPHANY_OPERAND_SIMM11 :
1668       fields->f_sdisp11 = value;
1669       break;
1670     case EPIPHANY_OPERAND_SIMM24 :
1671       fields->f_simm24 = value;
1672       break;
1673     case EPIPHANY_OPERAND_SIMM3 :
1674       fields->f_sdisp3 = value;
1675       break;
1676     case EPIPHANY_OPERAND_SIMM8 :
1677       fields->f_simm8 = value;
1678       break;
1679     case EPIPHANY_OPERAND_SN :
1680       fields->f_sn = value;
1681       break;
1682     case EPIPHANY_OPERAND_SN6 :
1683       fields->f_sn6 = value;
1684       break;
1685     case EPIPHANY_OPERAND_SNDMA :
1686       fields->f_sn6 = value;
1687       break;
1688     case EPIPHANY_OPERAND_SNMEM :
1689       fields->f_sn6 = value;
1690       break;
1691     case EPIPHANY_OPERAND_SNMESH :
1692       fields->f_sn6 = value;
1693       break;
1694     case EPIPHANY_OPERAND_SWI_NUM :
1695       fields->f_trap_num = value;
1696       break;
1697     case EPIPHANY_OPERAND_TRAPNUM6 :
1698       fields->f_trap_num = value;
1699       break;
1700
1701     default :
1702       /* xgettext:c-format */
1703       opcodes_error_handler
1704         (_("internal error: unrecognized field %d while setting vma operand"),
1705          opindex);
1706       abort ();
1707   }
1708 }
1709
1710 /* Function to call before using the instruction builder tables.  */
1711
1712 void
1713 epiphany_cgen_init_ibld_table (CGEN_CPU_DESC cd)
1714 {
1715   cd->insert_handlers = & epiphany_cgen_insert_handlers[0];
1716   cd->extract_handlers = & epiphany_cgen_extract_handlers[0];
1717
1718   cd->insert_operand = epiphany_cgen_insert_operand;
1719   cd->extract_operand = epiphany_cgen_extract_operand;
1720
1721   cd->get_int_operand = epiphany_cgen_get_int_operand;
1722   cd->set_int_operand = epiphany_cgen_set_int_operand;
1723   cd->get_vma_operand = epiphany_cgen_get_vma_operand;
1724   cd->set_vma_operand = epiphany_cgen_set_vma_operand;
1725 }
This page took 0.119329 seconds and 4 git commands to generate.