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