source: trunk/src/binutils/opcodes/fr30-ibld.c@ 201

Last change on this file since 201 was 10, checked in by bird, 22 years ago

Initial revision

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