Fix an overflow checking bug uncovered when a 32 bit target is compiled
[binutils.git] / opcodes / m32r-ibld.c
blobfa15d7e45140679c2ee7729530f5b26a44fa6833
1 /* Instruction building/extraction support for m32r. -*- C -*-
3 THIS FILE IS MACHINE GENERATED WITH CGEN: Cpu tools GENerator.
4 - the resultant file is machine generated, cgen-ibld.in isn't
6 Copyright (C) 1996, 1997, 1998, 1999 Free Software Foundation, Inc.
8 This file is part of the GNU Binutils and GDB, the GNU debugger.
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2, or (at your option)
13 any later version.
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software Foundation, Inc.,
22 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
24 /* ??? Eventually more and more of this stuff can go to cpu-independent files.
25 Keep that in mind. */
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 "m32r-desc.h"
35 #include "m32r-opc.h"
36 #include "opintl.h"
38 #undef min
39 #define min(a,b) ((a) < (b) ? (a) : (b))
40 #undef max
41 #define max(a,b) ((a) > (b) ? (a) : (b))
43 /* Used by the ifield rtx function. */
44 #define FLD(f) (fields->f)
46 static 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));
49 static const char * insert_insn_normal
50 PARAMS ((CGEN_CPU_DESC, const CGEN_INSN *,
51 CGEN_FIELDS *, CGEN_INSN_BYTES_PTR, bfd_vma));
53 static 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 *));
57 static int extract_insn_normal
58 PARAMS ((CGEN_CPU_DESC, const CGEN_INSN *, CGEN_EXTRACT_INFO *,
59 CGEN_INSN_INT, CGEN_FIELDS *, bfd_vma));
61 /* Operand insertion. */
63 #if ! CGEN_INT_INSN_P
65 /* Subroutine of insert_normal. */
67 static CGEN_INLINE void
68 insert_1 (cd, value, start, length, word_length, bufp)
69 CGEN_CPU_DESC cd;
70 unsigned long value;
71 int start,length,word_length;
72 unsigned char *bufp;
74 unsigned long x,mask;
75 int shift;
76 int big_p = CGEN_CPU_INSN_ENDIAN (cd) == CGEN_ENDIAN_BIG;
78 switch (word_length)
80 case 8:
81 x = *bufp;
82 break;
83 case 16:
84 if (big_p)
85 x = bfd_getb16 (bufp);
86 else
87 x = bfd_getl16 (bufp);
88 break;
89 case 24:
90 /* ??? This may need reworking as these cases don't necessarily
91 want the first byte and the last two bytes handled like this. */
92 if (big_p)
93 x = (bufp[0] << 16) | bfd_getb16 (bufp + 1);
94 else
95 x = bfd_getl16 (bufp) | (bufp[2] << 16);
96 break;
97 case 32:
98 if (big_p)
99 x = bfd_getb32 (bufp);
100 else
101 x = bfd_getl32 (bufp);
102 break;
103 default :
104 abort ();
107 /* Written this way to avoid undefined behaviour. */
108 mask = (((1L << (length - 1)) - 1) << 1) | 1;
109 if (CGEN_INSN_LSB0_P)
110 shift = (start + 1) - length;
111 else
112 shift = (word_length - (start + length));
113 x = (x & ~(mask << shift)) | ((value & mask) << shift);
115 switch (word_length)
117 case 8:
118 *bufp = x;
119 break;
120 case 16:
121 if (big_p)
122 bfd_putb16 (x, bufp);
123 else
124 bfd_putl16 (x, bufp);
125 break;
126 case 24:
127 /* ??? This may need reworking as these cases don't necessarily
128 want the first byte and the last two bytes handled like this. */
129 if (big_p)
131 bufp[0] = x >> 16;
132 bfd_putb16 (x, bufp + 1);
134 else
136 bfd_putl16 (x, bufp);
137 bufp[2] = x >> 16;
139 break;
140 case 32:
141 if (big_p)
142 bfd_putb32 (x, bufp);
143 else
144 bfd_putl32 (x, bufp);
145 break;
146 default :
147 abort ();
151 #endif /* ! CGEN_INT_INSN_P */
153 /* Default insertion routine.
155 ATTRS is a mask of the boolean attributes.
156 WORD_OFFSET is the offset in bits from the start of the insn of the value.
157 WORD_LENGTH is the length of the word in bits in which the value resides.
158 START is the starting bit number in the word, architecture origin.
159 LENGTH is the length of VALUE in bits.
160 TOTAL_LENGTH is the total length of the insn in bits.
162 The result is an error message or NULL if success. */
164 /* ??? This duplicates functionality with bfd's howto table and
165 bfd_install_relocation. */
166 /* ??? This doesn't handle bfd_vma's. Create another function when
167 necessary. */
169 static const char *
170 insert_normal (cd, value, attrs, word_offset, start, length, word_length,
171 total_length, buffer)
172 CGEN_CPU_DESC cd;
173 long value;
174 unsigned int attrs;
175 unsigned int word_offset, start, length, word_length, total_length;
176 CGEN_INSN_BYTES_PTR buffer;
178 static char errbuf[100];
179 /* Written this way to avoid undefined behaviour. */
180 unsigned long mask = (((1L << (length - 1)) - 1) << 1) | 1;
182 /* If LENGTH is zero, this operand doesn't contribute to the value. */
183 if (length == 0)
184 return NULL;
186 if (CGEN_INT_INSN_P
187 && word_offset != 0)
188 abort ();
190 if (word_length > 32)
191 abort ();
193 /* For architectures with insns smaller than the base-insn-bitsize,
194 word_length may be too big. */
195 if (cd->min_insn_bitsize < cd->base_insn_bitsize)
197 if (word_offset == 0
198 && word_length > total_length)
199 word_length = total_length;
202 /* Ensure VALUE will fit. */
203 if (! CGEN_BOOL_ATTR (attrs, CGEN_IFLD_SIGNED))
205 unsigned long maxval = mask;
206 if ((unsigned long) value > maxval)
208 /* xgettext:c-format */
209 sprintf (errbuf,
210 _("operand out of range (%lu not between 0 and %lu)"),
211 value, maxval);
212 return errbuf;
215 else
217 long minval = - (1L << (length - 1));
218 long maxval = (1L << (length - 1)) - 1;
219 if (value < minval || value > maxval)
221 sprintf
222 /* xgettext:c-format */
223 (errbuf, _("operand out of range (%ld not between %ld and %ld)"),
224 value, minval, maxval);
225 return errbuf;
229 #if CGEN_INT_INSN_P
232 int shift;
234 if (CGEN_INSN_LSB0_P)
235 shift = (start + 1) - length;
236 else
237 shift = word_length - (start + length);
238 *buffer = (*buffer & ~(mask << shift)) | ((value & mask) << shift);
241 #else /* ! CGEN_INT_INSN_P */
244 unsigned char *bufp = (unsigned char *) buffer + word_offset / 8;
246 insert_1 (cd, value, start, length, word_length, bufp);
249 #endif /* ! CGEN_INT_INSN_P */
251 return NULL;
254 /* Default insn builder (insert handler).
255 The instruction is recorded in CGEN_INT_INSN_P byte order
256 (meaning that if CGEN_INT_INSN_P BUFFER is an int * and thus the value is
257 recorded in host byte order, otherwise BUFFER is an array of bytes and the
258 value is recorded in target byte order).
259 The result is an error message or NULL if success. */
261 static const char *
262 insert_insn_normal (cd, insn, fields, buffer, pc)
263 CGEN_CPU_DESC cd;
264 const CGEN_INSN * insn;
265 CGEN_FIELDS * fields;
266 CGEN_INSN_BYTES_PTR buffer;
267 bfd_vma pc;
269 const CGEN_SYNTAX *syntax = CGEN_INSN_SYNTAX (insn);
270 unsigned long value;
271 const unsigned char * syn;
273 CGEN_INIT_INSERT (cd);
274 value = CGEN_INSN_BASE_VALUE (insn);
276 /* If we're recording insns as numbers (rather than a string of bytes),
277 target byte order handling is deferred until later. */
279 #if CGEN_INT_INSN_P
281 *buffer = value;
283 #else
285 cgen_put_insn_value (cd, buffer, min (cd->base_insn_bitsize,
286 CGEN_FIELDS_BITSIZE (fields)),
287 value);
289 #endif /* ! CGEN_INT_INSN_P */
291 /* ??? It would be better to scan the format's fields.
292 Still need to be able to insert a value based on the operand though;
293 e.g. storing a branch displacement that got resolved later.
294 Needs more thought first. */
296 for (syn = CGEN_SYNTAX_STRING (syntax); * syn != '\0'; ++ syn)
298 const char *errmsg;
300 if (CGEN_SYNTAX_CHAR_P (* syn))
301 continue;
303 errmsg = (* cd->insert_operand) (cd, CGEN_SYNTAX_FIELD (*syn),
304 fields, buffer, pc);
305 if (errmsg)
306 return errmsg;
309 return NULL;
312 /* Operand extraction. */
314 #if ! CGEN_INT_INSN_P
316 /* Subroutine of extract_normal.
317 Ensure sufficient bytes are cached in EX_INFO.
318 OFFSET is the offset in bytes from the start of the insn of the value.
319 BYTES is the length of the needed value.
320 Returns 1 for success, 0 for failure. */
322 static CGEN_INLINE int
323 fill_cache (cd, ex_info, offset, bytes, pc)
324 CGEN_CPU_DESC cd;
325 CGEN_EXTRACT_INFO *ex_info;
326 int offset, bytes;
327 bfd_vma pc;
329 /* It's doubtful that the middle part has already been fetched so
330 we don't optimize that case. kiss. */
331 int mask;
332 disassemble_info *info = (disassemble_info *) ex_info->dis_info;
334 /* First do a quick check. */
335 mask = (1 << bytes) - 1;
336 if (((ex_info->valid >> offset) & mask) == mask)
337 return 1;
339 /* Search for the first byte we need to read. */
340 for (mask = 1 << offset; bytes > 0; --bytes, ++offset, mask <<= 1)
341 if (! (mask & ex_info->valid))
342 break;
344 if (bytes)
346 int status;
348 pc += offset;
349 status = (*info->read_memory_func)
350 (pc, ex_info->insn_bytes + offset, bytes, info);
352 if (status != 0)
354 (*info->memory_error_func) (status, pc, info);
355 return 0;
358 ex_info->valid |= ((1 << bytes) - 1) << offset;
361 return 1;
364 /* Subroutine of extract_normal. */
366 static CGEN_INLINE long
367 extract_1 (cd, ex_info, start, length, word_length, bufp, pc)
368 CGEN_CPU_DESC cd;
369 CGEN_EXTRACT_INFO *ex_info;
370 int start,length,word_length;
371 unsigned char *bufp;
372 bfd_vma pc;
374 unsigned long x,mask;
375 int shift;
376 int big_p = CGEN_CPU_INSN_ENDIAN (cd) == CGEN_ENDIAN_BIG;
378 switch (word_length)
380 case 8:
381 x = *bufp;
382 break;
383 case 16:
384 if (big_p)
385 x = bfd_getb16 (bufp);
386 else
387 x = bfd_getl16 (bufp);
388 break;
389 case 24:
390 /* ??? This may need reworking as these cases don't necessarily
391 want the first byte and the last two bytes handled like this. */
392 if (big_p)
393 x = (bufp[0] << 16) | bfd_getb16 (bufp + 1);
394 else
395 x = bfd_getl16 (bufp) | (bufp[2] << 16);
396 break;
397 case 32:
398 if (big_p)
399 x = bfd_getb32 (bufp);
400 else
401 x = bfd_getl32 (bufp);
402 break;
403 default :
404 abort ();
407 /* Written this way to avoid undefined behaviour. */
408 mask = (((1L << (length - 1)) - 1) << 1) | 1;
409 if (CGEN_INSN_LSB0_P)
410 shift = (start + 1) - length;
411 else
412 shift = (word_length - (start + length));
413 return (x >> shift) & mask;
416 #endif /* ! CGEN_INT_INSN_P */
418 /* Default extraction routine.
420 INSN_VALUE is the first base_insn_bitsize bits of the insn in host order,
421 or sometimes less for cases like the m32r where the base insn size is 32
422 but some insns are 16 bits.
423 ATTRS is a mask of the boolean attributes. We only need `SIGNED',
424 but for generality we take a bitmask of all of them.
425 WORD_OFFSET is the offset in bits from the start of the insn of the value.
426 WORD_LENGTH is the length of the word in bits in which the value resides.
427 START is the starting bit number in the word, architecture origin.
428 LENGTH is the length of VALUE in bits.
429 TOTAL_LENGTH is the total length of the insn in bits.
431 Returns 1 for success, 0 for failure. */
433 /* ??? The return code isn't properly used. wip. */
435 /* ??? This doesn't handle bfd_vma's. Create another function when
436 necessary. */
438 static int
439 extract_normal (cd, ex_info, insn_value, attrs, word_offset, start, length,
440 word_length, total_length, pc, valuep)
441 CGEN_CPU_DESC cd;
442 CGEN_EXTRACT_INFO *ex_info;
443 CGEN_INSN_INT insn_value;
444 unsigned int attrs;
445 unsigned int word_offset, start, length, word_length, total_length;
446 bfd_vma pc;
447 long *valuep;
449 CGEN_INSN_INT value;
451 /* If LENGTH is zero, this operand doesn't contribute to the value
452 so give it a standard value of zero. */
453 if (length == 0)
455 *valuep = 0;
456 return 1;
459 if (CGEN_INT_INSN_P
460 && word_offset != 0)
461 abort ();
463 if (word_length > 32)
464 abort ();
466 /* For architectures with insns smaller than the insn-base-bitsize,
467 word_length may be too big. */
468 if (cd->min_insn_bitsize < cd->base_insn_bitsize)
470 if (word_offset == 0
471 && word_length > total_length)
472 word_length = total_length;
475 /* Does the value reside in INSN_VALUE? */
477 if (word_offset == 0)
479 /* Written this way to avoid undefined behaviour. */
480 CGEN_INSN_INT mask = (((1L << (length - 1)) - 1) << 1) | 1;
482 if (CGEN_INSN_LSB0_P)
483 value = insn_value >> ((start + 1) - length);
484 else
485 value = insn_value >> (word_length - (start + length));
486 value &= mask;
487 /* sign extend? */
488 if (CGEN_BOOL_ATTR (attrs, CGEN_IFLD_SIGNED)
489 && (value & (1L << (length - 1))))
490 value |= ~mask;
493 #if ! CGEN_INT_INSN_P
495 else
497 unsigned char *bufp = ex_info->insn_bytes + word_offset / 8;
499 if (word_length > 32)
500 abort ();
502 if (fill_cache (cd, ex_info, word_offset / 8, word_length / 8, pc) == 0)
503 return 0;
505 value = extract_1 (cd, ex_info, start, length, word_length, bufp, pc);
508 #endif /* ! CGEN_INT_INSN_P */
510 *valuep = value;
512 return 1;
515 /* Default insn extractor.
517 INSN_VALUE is the first base_insn_bitsize bits, translated to host order.
518 The extracted fields are stored in FIELDS.
519 EX_INFO is used to handle reading variable length insns.
520 Return the length of the insn in bits, or 0 if no match,
521 or -1 if an error occurs fetching data (memory_error_func will have
522 been called). */
524 static int
525 extract_insn_normal (cd, insn, ex_info, insn_value, fields, pc)
526 CGEN_CPU_DESC cd;
527 const CGEN_INSN *insn;
528 CGEN_EXTRACT_INFO *ex_info;
529 CGEN_INSN_INT insn_value;
530 CGEN_FIELDS *fields;
531 bfd_vma pc;
533 const CGEN_SYNTAX *syntax = CGEN_INSN_SYNTAX (insn);
534 const unsigned char *syn;
536 CGEN_FIELDS_BITSIZE (fields) = CGEN_INSN_BITSIZE (insn);
538 CGEN_INIT_EXTRACT (cd);
540 for (syn = CGEN_SYNTAX_STRING (syntax); *syn; ++syn)
542 int length;
544 if (CGEN_SYNTAX_CHAR_P (*syn))
545 continue;
547 length = (* cd->extract_operand) (cd, CGEN_SYNTAX_FIELD (*syn),
548 ex_info, insn_value, fields, pc);
549 if (length <= 0)
550 return length;
553 /* We recognized and successfully extracted this insn. */
554 return CGEN_INSN_BITSIZE (insn);
557 /* machine generated code added here */
559 /* Main entry point for operand insertion.
561 This function is basically just a big switch statement. Earlier versions
562 used tables to look up the function to use, but
563 - if the table contains both assembler and disassembler functions then
564 the disassembler contains much of the assembler and vice-versa,
565 - there's a lot of inlining possibilities as things grow,
566 - using a switch statement avoids the function call overhead.
568 This function could be moved into `parse_insn_normal', but keeping it
569 separate makes clear the interface between `parse_insn_normal' and each of
570 the handlers. It's also needed by GAS to insert operands that couldn't be
571 resolved during parsing.
574 const char *
575 m32r_cgen_insert_operand (cd, opindex, fields, buffer, pc)
576 CGEN_CPU_DESC cd;
577 int opindex;
578 CGEN_FIELDS * fields;
579 CGEN_INSN_BYTES_PTR buffer;
580 bfd_vma pc;
582 const char * errmsg;
583 unsigned int total_length = CGEN_FIELDS_BITSIZE (fields);
585 switch (opindex)
587 case M32R_OPERAND_DCR :
588 errmsg = insert_normal (cd, fields->f_r1, 0, 0, 4, 4, 32, total_length, buffer);
589 break;
590 case M32R_OPERAND_DISP16 :
592 long value = fields->f_disp16;
593 value = ((int) (((value) - (pc))) >> (2));
594 errmsg = insert_normal (cd, value, 0|(1<<CGEN_IFLD_SIGNED)|(1<<CGEN_IFLD_RELOC)|(1<<CGEN_IFLD_PCREL_ADDR), 0, 16, 16, 32, total_length, buffer);
596 break;
597 case M32R_OPERAND_DISP24 :
599 long value = fields->f_disp24;
600 value = ((int) (((value) - (pc))) >> (2));
601 errmsg = insert_normal (cd, value, 0|(1<<CGEN_IFLD_SIGNED)|(1<<CGEN_IFLD_RELOC)|(1<<CGEN_IFLD_PCREL_ADDR), 0, 8, 24, 32, total_length, buffer);
603 break;
604 case M32R_OPERAND_DISP8 :
606 long value = fields->f_disp8;
607 value = ((int) (((value) - (((pc) & (-4))))) >> (2));
608 errmsg = insert_normal (cd, value, 0|(1<<CGEN_IFLD_SIGNED)|(1<<CGEN_IFLD_RELOC)|(1<<CGEN_IFLD_PCREL_ADDR), 0, 8, 8, 32, total_length, buffer);
610 break;
611 case M32R_OPERAND_DR :
612 errmsg = insert_normal (cd, fields->f_r1, 0, 0, 4, 4, 32, total_length, buffer);
613 break;
614 case M32R_OPERAND_HASH :
615 errmsg = insert_normal (cd, fields->f_nil, 0, 0, 0, 0, 0, total_length, buffer);
616 break;
617 case M32R_OPERAND_HI16 :
618 errmsg = insert_normal (cd, fields->f_hi16, 0|(1<<CGEN_IFLD_SIGN_OPT), 0, 16, 16, 32, total_length, buffer);
619 break;
620 case M32R_OPERAND_SCR :
621 errmsg = insert_normal (cd, fields->f_r2, 0, 0, 12, 4, 32, total_length, buffer);
622 break;
623 case M32R_OPERAND_SIMM16 :
624 errmsg = insert_normal (cd, fields->f_simm16, 0|(1<<CGEN_IFLD_SIGNED), 0, 16, 16, 32, total_length, buffer);
625 break;
626 case M32R_OPERAND_SIMM8 :
627 errmsg = insert_normal (cd, fields->f_simm8, 0|(1<<CGEN_IFLD_SIGNED), 0, 8, 8, 32, total_length, buffer);
628 break;
629 case M32R_OPERAND_SLO16 :
630 errmsg = insert_normal (cd, fields->f_simm16, 0|(1<<CGEN_IFLD_SIGNED), 0, 16, 16, 32, total_length, buffer);
631 break;
632 case M32R_OPERAND_SR :
633 errmsg = insert_normal (cd, fields->f_r2, 0, 0, 12, 4, 32, total_length, buffer);
634 break;
635 case M32R_OPERAND_SRC1 :
636 errmsg = insert_normal (cd, fields->f_r1, 0, 0, 4, 4, 32, total_length, buffer);
637 break;
638 case M32R_OPERAND_SRC2 :
639 errmsg = insert_normal (cd, fields->f_r2, 0, 0, 12, 4, 32, total_length, buffer);
640 break;
641 case M32R_OPERAND_UIMM16 :
642 errmsg = insert_normal (cd, fields->f_uimm16, 0, 0, 16, 16, 32, total_length, buffer);
643 break;
644 case M32R_OPERAND_UIMM24 :
645 errmsg = insert_normal (cd, fields->f_uimm24, 0|(1<<CGEN_IFLD_RELOC)|(1<<CGEN_IFLD_ABS_ADDR), 0, 8, 24, 32, total_length, buffer);
646 break;
647 case M32R_OPERAND_UIMM4 :
648 errmsg = insert_normal (cd, fields->f_uimm4, 0, 0, 12, 4, 32, total_length, buffer);
649 break;
650 case M32R_OPERAND_UIMM5 :
651 errmsg = insert_normal (cd, fields->f_uimm5, 0, 0, 11, 5, 32, total_length, buffer);
652 break;
653 case M32R_OPERAND_ULO16 :
654 errmsg = insert_normal (cd, fields->f_uimm16, 0, 0, 16, 16, 32, total_length, buffer);
655 break;
657 default :
658 /* xgettext:c-format */
659 fprintf (stderr, _("Unrecognized field %d while building insn.\n"),
660 opindex);
661 abort ();
664 return errmsg;
667 /* Main entry point for operand extraction.
669 This function is basically just a big switch statement. Earlier versions
670 used tables to look up the function to use, but
671 - if the table contains both assembler and disassembler functions then
672 the disassembler contains much of the assembler and vice-versa,
673 - there's a lot of inlining possibilities as things grow,
674 - using a switch statement avoids the function call overhead.
676 This function could be moved into `print_insn_normal', but keeping it
677 separate makes clear the interface between `print_insn_normal' and each of
678 the handlers.
682 m32r_cgen_extract_operand (cd, opindex, ex_info, insn_value, fields, pc)
683 CGEN_CPU_DESC cd;
684 int opindex;
685 CGEN_EXTRACT_INFO *ex_info;
686 CGEN_INSN_INT insn_value;
687 CGEN_FIELDS * fields;
688 bfd_vma pc;
690 int length;
691 unsigned int total_length = CGEN_FIELDS_BITSIZE (fields);
693 switch (opindex)
695 case M32R_OPERAND_DCR :
696 length = extract_normal (cd, ex_info, insn_value, 0, 0, 4, 4, 32, total_length, pc, & fields->f_r1);
697 break;
698 case M32R_OPERAND_DISP16 :
700 long value;
701 length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_SIGNED)|(1<<CGEN_IFLD_RELOC)|(1<<CGEN_IFLD_PCREL_ADDR), 0, 16, 16, 32, total_length, pc, & value);
702 value = ((((value) << (2))) + (pc));
703 fields->f_disp16 = value;
705 break;
706 case M32R_OPERAND_DISP24 :
708 long value;
709 length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_SIGNED)|(1<<CGEN_IFLD_RELOC)|(1<<CGEN_IFLD_PCREL_ADDR), 0, 8, 24, 32, total_length, pc, & value);
710 value = ((((value) << (2))) + (pc));
711 fields->f_disp24 = value;
713 break;
714 case M32R_OPERAND_DISP8 :
716 long value;
717 length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_SIGNED)|(1<<CGEN_IFLD_RELOC)|(1<<CGEN_IFLD_PCREL_ADDR), 0, 8, 8, 32, total_length, pc, & value);
718 value = ((((value) << (2))) + (((pc) & (-4))));
719 fields->f_disp8 = value;
721 break;
722 case M32R_OPERAND_DR :
723 length = extract_normal (cd, ex_info, insn_value, 0, 0, 4, 4, 32, total_length, pc, & fields->f_r1);
724 break;
725 case M32R_OPERAND_HASH :
726 length = extract_normal (cd, ex_info, insn_value, 0, 0, 0, 0, 0, total_length, pc, & fields->f_nil);
727 break;
728 case M32R_OPERAND_HI16 :
729 length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_SIGN_OPT), 0, 16, 16, 32, total_length, pc, & fields->f_hi16);
730 break;
731 case M32R_OPERAND_SCR :
732 length = extract_normal (cd, ex_info, insn_value, 0, 0, 12, 4, 32, total_length, pc, & fields->f_r2);
733 break;
734 case M32R_OPERAND_SIMM16 :
735 length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_SIGNED), 0, 16, 16, 32, total_length, pc, & fields->f_simm16);
736 break;
737 case M32R_OPERAND_SIMM8 :
738 length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_SIGNED), 0, 8, 8, 32, total_length, pc, & fields->f_simm8);
739 break;
740 case M32R_OPERAND_SLO16 :
741 length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_SIGNED), 0, 16, 16, 32, total_length, pc, & fields->f_simm16);
742 break;
743 case M32R_OPERAND_SR :
744 length = extract_normal (cd, ex_info, insn_value, 0, 0, 12, 4, 32, total_length, pc, & fields->f_r2);
745 break;
746 case M32R_OPERAND_SRC1 :
747 length = extract_normal (cd, ex_info, insn_value, 0, 0, 4, 4, 32, total_length, pc, & fields->f_r1);
748 break;
749 case M32R_OPERAND_SRC2 :
750 length = extract_normal (cd, ex_info, insn_value, 0, 0, 12, 4, 32, total_length, pc, & fields->f_r2);
751 break;
752 case M32R_OPERAND_UIMM16 :
753 length = extract_normal (cd, ex_info, insn_value, 0, 0, 16, 16, 32, total_length, pc, & fields->f_uimm16);
754 break;
755 case M32R_OPERAND_UIMM24 :
756 length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_RELOC)|(1<<CGEN_IFLD_ABS_ADDR), 0, 8, 24, 32, total_length, pc, & fields->f_uimm24);
757 break;
758 case M32R_OPERAND_UIMM4 :
759 length = extract_normal (cd, ex_info, insn_value, 0, 0, 12, 4, 32, total_length, pc, & fields->f_uimm4);
760 break;
761 case M32R_OPERAND_UIMM5 :
762 length = extract_normal (cd, ex_info, insn_value, 0, 0, 11, 5, 32, total_length, pc, & fields->f_uimm5);
763 break;
764 case M32R_OPERAND_ULO16 :
765 length = extract_normal (cd, ex_info, insn_value, 0, 0, 16, 16, 32, total_length, pc, & fields->f_uimm16);
766 break;
768 default :
769 /* xgettext:c-format */
770 fprintf (stderr, _("Unrecognized field %d while decoding insn.\n"),
771 opindex);
772 abort ();
775 return length;
778 cgen_insert_fn * const m32r_cgen_insert_handlers[] =
780 insert_insn_normal,
783 cgen_extract_fn * const m32r_cgen_extract_handlers[] =
785 extract_insn_normal,
788 /* Getting values from cgen_fields is handled by a collection of functions.
789 They are distinguished by the type of the VALUE argument they return.
790 TODO: floating point, inlining support, remove cases where result type
791 not appropriate. */
794 m32r_cgen_get_int_operand (cd, opindex, fields)
795 CGEN_CPU_DESC cd;
796 int opindex;
797 const CGEN_FIELDS * fields;
799 int value;
801 switch (opindex)
803 case M32R_OPERAND_DCR :
804 value = fields->f_r1;
805 break;
806 case M32R_OPERAND_DISP16 :
807 value = fields->f_disp16;
808 break;
809 case M32R_OPERAND_DISP24 :
810 value = fields->f_disp24;
811 break;
812 case M32R_OPERAND_DISP8 :
813 value = fields->f_disp8;
814 break;
815 case M32R_OPERAND_DR :
816 value = fields->f_r1;
817 break;
818 case M32R_OPERAND_HASH :
819 value = fields->f_nil;
820 break;
821 case M32R_OPERAND_HI16 :
822 value = fields->f_hi16;
823 break;
824 case M32R_OPERAND_SCR :
825 value = fields->f_r2;
826 break;
827 case M32R_OPERAND_SIMM16 :
828 value = fields->f_simm16;
829 break;
830 case M32R_OPERAND_SIMM8 :
831 value = fields->f_simm8;
832 break;
833 case M32R_OPERAND_SLO16 :
834 value = fields->f_simm16;
835 break;
836 case M32R_OPERAND_SR :
837 value = fields->f_r2;
838 break;
839 case M32R_OPERAND_SRC1 :
840 value = fields->f_r1;
841 break;
842 case M32R_OPERAND_SRC2 :
843 value = fields->f_r2;
844 break;
845 case M32R_OPERAND_UIMM16 :
846 value = fields->f_uimm16;
847 break;
848 case M32R_OPERAND_UIMM24 :
849 value = fields->f_uimm24;
850 break;
851 case M32R_OPERAND_UIMM4 :
852 value = fields->f_uimm4;
853 break;
854 case M32R_OPERAND_UIMM5 :
855 value = fields->f_uimm5;
856 break;
857 case M32R_OPERAND_ULO16 :
858 value = fields->f_uimm16;
859 break;
861 default :
862 /* xgettext:c-format */
863 fprintf (stderr, _("Unrecognized field %d while getting int operand.\n"),
864 opindex);
865 abort ();
868 return value;
871 bfd_vma
872 m32r_cgen_get_vma_operand (cd, opindex, fields)
873 CGEN_CPU_DESC cd;
874 int opindex;
875 const CGEN_FIELDS * fields;
877 bfd_vma value;
879 switch (opindex)
881 case M32R_OPERAND_DCR :
882 value = fields->f_r1;
883 break;
884 case M32R_OPERAND_DISP16 :
885 value = fields->f_disp16;
886 break;
887 case M32R_OPERAND_DISP24 :
888 value = fields->f_disp24;
889 break;
890 case M32R_OPERAND_DISP8 :
891 value = fields->f_disp8;
892 break;
893 case M32R_OPERAND_DR :
894 value = fields->f_r1;
895 break;
896 case M32R_OPERAND_HASH :
897 value = fields->f_nil;
898 break;
899 case M32R_OPERAND_HI16 :
900 value = fields->f_hi16;
901 break;
902 case M32R_OPERAND_SCR :
903 value = fields->f_r2;
904 break;
905 case M32R_OPERAND_SIMM16 :
906 value = fields->f_simm16;
907 break;
908 case M32R_OPERAND_SIMM8 :
909 value = fields->f_simm8;
910 break;
911 case M32R_OPERAND_SLO16 :
912 value = fields->f_simm16;
913 break;
914 case M32R_OPERAND_SR :
915 value = fields->f_r2;
916 break;
917 case M32R_OPERAND_SRC1 :
918 value = fields->f_r1;
919 break;
920 case M32R_OPERAND_SRC2 :
921 value = fields->f_r2;
922 break;
923 case M32R_OPERAND_UIMM16 :
924 value = fields->f_uimm16;
925 break;
926 case M32R_OPERAND_UIMM24 :
927 value = fields->f_uimm24;
928 break;
929 case M32R_OPERAND_UIMM4 :
930 value = fields->f_uimm4;
931 break;
932 case M32R_OPERAND_UIMM5 :
933 value = fields->f_uimm5;
934 break;
935 case M32R_OPERAND_ULO16 :
936 value = fields->f_uimm16;
937 break;
939 default :
940 /* xgettext:c-format */
941 fprintf (stderr, _("Unrecognized field %d while getting vma operand.\n"),
942 opindex);
943 abort ();
946 return value;
949 /* Stuffing values in cgen_fields is handled by a collection of functions.
950 They are distinguished by the type of the VALUE argument they accept.
951 TODO: floating point, inlining support, remove cases where argument type
952 not appropriate. */
954 void
955 m32r_cgen_set_int_operand (cd, opindex, fields, value)
956 CGEN_CPU_DESC cd;
957 int opindex;
958 CGEN_FIELDS * fields;
959 int value;
961 switch (opindex)
963 case M32R_OPERAND_DCR :
964 fields->f_r1 = value;
965 break;
966 case M32R_OPERAND_DISP16 :
967 fields->f_disp16 = value;
968 break;
969 case M32R_OPERAND_DISP24 :
970 fields->f_disp24 = value;
971 break;
972 case M32R_OPERAND_DISP8 :
973 fields->f_disp8 = value;
974 break;
975 case M32R_OPERAND_DR :
976 fields->f_r1 = value;
977 break;
978 case M32R_OPERAND_HASH :
979 fields->f_nil = value;
980 break;
981 case M32R_OPERAND_HI16 :
982 fields->f_hi16 = value;
983 break;
984 case M32R_OPERAND_SCR :
985 fields->f_r2 = value;
986 break;
987 case M32R_OPERAND_SIMM16 :
988 fields->f_simm16 = value;
989 break;
990 case M32R_OPERAND_SIMM8 :
991 fields->f_simm8 = value;
992 break;
993 case M32R_OPERAND_SLO16 :
994 fields->f_simm16 = value;
995 break;
996 case M32R_OPERAND_SR :
997 fields->f_r2 = value;
998 break;
999 case M32R_OPERAND_SRC1 :
1000 fields->f_r1 = value;
1001 break;
1002 case M32R_OPERAND_SRC2 :
1003 fields->f_r2 = value;
1004 break;
1005 case M32R_OPERAND_UIMM16 :
1006 fields->f_uimm16 = value;
1007 break;
1008 case M32R_OPERAND_UIMM24 :
1009 fields->f_uimm24 = value;
1010 break;
1011 case M32R_OPERAND_UIMM4 :
1012 fields->f_uimm4 = value;
1013 break;
1014 case M32R_OPERAND_UIMM5 :
1015 fields->f_uimm5 = value;
1016 break;
1017 case M32R_OPERAND_ULO16 :
1018 fields->f_uimm16 = value;
1019 break;
1021 default :
1022 /* xgettext:c-format */
1023 fprintf (stderr, _("Unrecognized field %d while setting int operand.\n"),
1024 opindex);
1025 abort ();
1029 void
1030 m32r_cgen_set_vma_operand (cd, opindex, fields, value)
1031 CGEN_CPU_DESC cd;
1032 int opindex;
1033 CGEN_FIELDS * fields;
1034 bfd_vma value;
1036 switch (opindex)
1038 case M32R_OPERAND_DCR :
1039 fields->f_r1 = value;
1040 break;
1041 case M32R_OPERAND_DISP16 :
1042 fields->f_disp16 = value;
1043 break;
1044 case M32R_OPERAND_DISP24 :
1045 fields->f_disp24 = value;
1046 break;
1047 case M32R_OPERAND_DISP8 :
1048 fields->f_disp8 = value;
1049 break;
1050 case M32R_OPERAND_DR :
1051 fields->f_r1 = value;
1052 break;
1053 case M32R_OPERAND_HASH :
1054 fields->f_nil = value;
1055 break;
1056 case M32R_OPERAND_HI16 :
1057 fields->f_hi16 = value;
1058 break;
1059 case M32R_OPERAND_SCR :
1060 fields->f_r2 = value;
1061 break;
1062 case M32R_OPERAND_SIMM16 :
1063 fields->f_simm16 = value;
1064 break;
1065 case M32R_OPERAND_SIMM8 :
1066 fields->f_simm8 = value;
1067 break;
1068 case M32R_OPERAND_SLO16 :
1069 fields->f_simm16 = value;
1070 break;
1071 case M32R_OPERAND_SR :
1072 fields->f_r2 = value;
1073 break;
1074 case M32R_OPERAND_SRC1 :
1075 fields->f_r1 = value;
1076 break;
1077 case M32R_OPERAND_SRC2 :
1078 fields->f_r2 = value;
1079 break;
1080 case M32R_OPERAND_UIMM16 :
1081 fields->f_uimm16 = value;
1082 break;
1083 case M32R_OPERAND_UIMM24 :
1084 fields->f_uimm24 = value;
1085 break;
1086 case M32R_OPERAND_UIMM4 :
1087 fields->f_uimm4 = value;
1088 break;
1089 case M32R_OPERAND_UIMM5 :
1090 fields->f_uimm5 = value;
1091 break;
1092 case M32R_OPERAND_ULO16 :
1093 fields->f_uimm16 = value;
1094 break;
1096 default :
1097 /* xgettext:c-format */
1098 fprintf (stderr, _("Unrecognized field %d while setting vma operand.\n"),
1099 opindex);
1100 abort ();
1104 /* Function to call before using the instruction builder tables. */
1106 void
1107 m32r_cgen_init_ibld_table (cd)
1108 CGEN_CPU_DESC cd;
1110 cd->insert_handlers = & m32r_cgen_insert_handlers[0];
1111 cd->extract_handlers = & m32r_cgen_extract_handlers[0];
1113 cd->insert_operand = m32r_cgen_insert_operand;
1114 cd->extract_operand = m32r_cgen_extract_operand;
1116 cd->get_int_operand = m32r_cgen_get_int_operand;
1117 cd->set_int_operand = m32r_cgen_set_int_operand;
1118 cd->get_vma_operand = m32r_cgen_get_vma_operand;
1119 cd->set_vma_operand = m32r_cgen_set_vma_operand;