]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - opcodes/epiphany-ibld.c
gdb.base/watchpoint-running.exp: Run sw watch tests even if no hw watch
[thirdparty/binutils-gdb.git] / opcodes / epiphany-ibld.c
CommitLineData
4162bb66 1/* DO NOT EDIT! -*- buffer-read-only: t -*- vi:set ro: */
cfb8c092
NC
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
fd67aa11 7 Copyright (C) 1996-2024 Free Software Foundation, Inc.
cfb8c092
NC
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
48static 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);
51static const char * insert_insn_normal
52 (CGEN_CPU_DESC, const CGEN_INSN *,
53 CGEN_FIELDS *, CGEN_INSN_BYTES_PTR, bfd_vma);
54static 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 *);
58static 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
62static 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
66static CGEN_INLINE void insert_1
67 (CGEN_CPU_DESC, unsigned long, int, int, int, unsigned char *);
68static CGEN_INLINE int fill_cache
69 (CGEN_CPU_DESC, CGEN_EXTRACT_INFO *, int, int, bfd_vma);
70static CGEN_INLINE long extract_1
71 (CGEN_CPU_DESC, CGEN_EXTRACT_INFO *, int, int, int, unsigned char *, bfd_vma);
72#endif
73\f
74/* Operand insertion. */
75
76#if ! CGEN_INT_INSN_P
77
78/* Subroutine of insert_normal. */
79
80static CGEN_INLINE void
81insert_1 (CGEN_CPU_DESC cd,
82 unsigned long value,
83 int start,
84 int length,
85 int word_length,
86 unsigned char *bufp)
87{
a1e60a1b 88 unsigned long x, mask;
cfb8c092
NC
89 int shift;
90
e9bffec9 91 x = cgen_get_insn_value (cd, bufp, word_length, cd->endian);
cfb8c092
NC
92
93 /* Written this way to avoid undefined behaviour. */
a1e60a1b 94 mask = (1UL << (length - 1) << 1) - 1;
cfb8c092
NC
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
e9bffec9 101 cgen_put_insn_value (cd, bufp, word_length, (bfd_vma) x, cd->endian);
cfb8c092
NC
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
122static const char *
123insert_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];
a1e60a1b 134 unsigned long mask;
cfb8c092
NC
135
136 /* If LENGTH is zero, this operand doesn't contribute to the value. */
137 if (length == 0)
138 return NULL;
139
a1e60a1b
AM
140 /* Written this way to avoid undefined behaviour. */
141 mask = (1UL << (length - 1) << 1) - 1;
142
cfb8c092
NC
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 {
ae3e98b4 158 long minval = - (1UL << (length - 1));
cfb8c092 159 unsigned long maxval = mask;
43e65147 160
cfb8c092
NC
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 {
ae3e98b4
AM
196 long minval = - (1UL << (length - 1));
197 long maxval = (1UL << (length - 1)) - 1;
43e65147 198
cfb8c092
NC
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 {
a143b004 213 int shift_within_word, shift_to_word, shift;
cfb8c092 214
a143b004
AB
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. */
cfb8c092 219 if (CGEN_INSN_LSB0_P)
a143b004 220 shift_within_word = start + 1 - length;
cfb8c092 221 else
a143b004
AB
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;
cfb8c092
NC
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
249static const char *
250insert_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,
e9bffec9
JM
274 (unsigned) CGEN_FIELDS_BITSIZE (fields)),
275 value, cd->insn_endian);
cfb8c092
NC
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
304static void
305put_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. */
a1e60a1b 319 CGEN_INSN_INT mask = length == 0 ? 0 : (1UL << (length - 1) << 1) - 1;
cfb8c092
NC
320
321 *buf = (*buf & ~(mask << shift)) | ((value & mask) << shift);
322 }
323}
324#endif
325\f
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
336static CGEN_INLINE int
337fill_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
380static CGEN_INLINE long
381extract_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
e9bffec9 392 x = cgen_get_insn_value (cd, bufp, word_length, cd->endian);
cfb8c092
NC
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
423static int
424extract_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)
2f5dd314
AM
485 {
486 *valuep = 0;
487 return 0;
488 }
cfb8c092
NC
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. */
a1e60a1b 496 mask = (1UL << (length - 1) << 1) - 1;
cfb8c092
NC
497
498 value &= mask;
499 /* sign extend? */
500 if (CGEN_BOOL_ATTR (attrs, CGEN_IFLD_SIGNED)
ae3e98b4 501 && (value & (1UL << (length - 1))))
cfb8c092
NC
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
518static int
519extract_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\f
550/* Machine generated code added here. */
551
552const 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
569const char *
570epiphany_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 */
a6743a54
AM
884 opcodes_error_handler
885 (_("internal error: unrecognized field %d while building insn"),
886 opindex);
cfb8c092
NC
887 abort ();
888 }
889
890 return errmsg;
891}
892
893int 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
911int
912epiphany_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{
1d61b032 1100 FLD (f_sdisp11) = ((((((((((FLD (f_disp8)) << (3))) | (FLD (f_disp3)))) & (2047))) ^ (1024))) - (1024));
cfb8c092
NC
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);
b8e61daa 1108 value = ((((value) * (2))) + (pc));
cfb8c092
NC
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);
b8e61daa 1119 value = ((((value) * (2))) + (pc));
cfb8c092
NC
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 */
a6743a54
AM
1179 opcodes_error_handler
1180 (_("internal error: unrecognized field %d while decoding insn"),
1181 opindex);
cfb8c092
NC
1182 abort ();
1183 }
1184
1185 return length;
1186}
1187
43e65147 1188cgen_insert_fn * const epiphany_cgen_insert_handlers[] =
cfb8c092
NC
1189{
1190 insert_insn_normal,
1191};
1192
43e65147 1193cgen_extract_fn * const epiphany_cgen_extract_handlers[] =
cfb8c092
NC
1194{
1195 extract_insn_normal,
1196};
1197
1198int epiphany_cgen_get_int_operand (CGEN_CPU_DESC, int, const CGEN_FIELDS *);
1199bfd_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
1206int
1207epiphany_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 */
a6743a54
AM
1323 opcodes_error_handler
1324 (_("internal error: unrecognized field %d while getting int operand"),
1325 opindex);
cfb8c092
NC
1326 abort ();
1327 }
1328
1329 return value;
1330}
1331
1332bfd_vma
1333epiphany_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 */
a6743a54
AM
1449 opcodes_error_handler
1450 (_("internal error: unrecognized field %d while getting vma operand"),
1451 opindex);
cfb8c092
NC
1452 abort ();
1453 }
1454
1455 return value;
1456}
1457
1458void epiphany_cgen_set_int_operand (CGEN_CPU_DESC, int, CGEN_FIELDS *, int);
1459void 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
1466void
1467epiphany_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 */
a6743a54
AM
1582 opcodes_error_handler
1583 (_("internal error: unrecognized field %d while setting int operand"),
1584 opindex);
cfb8c092
NC
1585 abort ();
1586 }
1587}
1588
1589void
1590epiphany_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 */
a6743a54
AM
1705 opcodes_error_handler
1706 (_("internal error: unrecognized field %d while setting vma operand"),
1707 opindex);
cfb8c092
NC
1708 abort ();
1709 }
1710}
1711
1712/* Function to call before using the instruction builder tables. */
1713
1714void
1715epiphany_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}