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