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