2000-05-02 H.J. Lu <hjl@gnu.org>
[binutils.git] / opcodes / m32r-ibld.c
blob30c3c6a8ce9c635f0bcdf6a60cde7b3dd0bee178
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, 2000 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;
207 if ((unsigned long) value > maxval)
209 /* xgettext:c-format */
210 sprintf (errbuf,
211 _("operand out of range (%lu not between 0 and %lu)"),
212 value, maxval);
213 return errbuf;
216 else
218 if (! cgen_signed_overflow_ok_p (cd))
220 long minval = - (1L << (length - 1));
221 long maxval = (1L << (length - 1)) - 1;
223 if (value < minval || value > maxval)
225 sprintf
226 /* xgettext:c-format */
227 (errbuf, _("operand out of range (%ld not between %ld and %ld)"),
228 value, minval, maxval);
229 return errbuf;
234 #if CGEN_INT_INSN_P
237 int shift;
239 if (CGEN_INSN_LSB0_P)
240 shift = (start + 1) - length;
241 else
242 shift = word_length - (start + length);
243 *buffer = (*buffer & ~(mask << shift)) | ((value & mask) << shift);
246 #else /* ! CGEN_INT_INSN_P */
249 unsigned char *bufp = (unsigned char *) buffer + word_offset / 8;
251 insert_1 (cd, value, start, length, word_length, bufp);
254 #endif /* ! CGEN_INT_INSN_P */
256 return NULL;
259 /* Default insn builder (insert handler).
260 The instruction is recorded in CGEN_INT_INSN_P byte order
261 (meaning that if CGEN_INT_INSN_P BUFFER is an int * and thus the value is
262 recorded in host byte order, otherwise BUFFER is an array of bytes and the
263 value is recorded in target byte order).
264 The result is an error message or NULL if success. */
266 static const char *
267 insert_insn_normal (cd, insn, fields, buffer, pc)
268 CGEN_CPU_DESC cd;
269 const CGEN_INSN * insn;
270 CGEN_FIELDS * fields;
271 CGEN_INSN_BYTES_PTR buffer;
272 bfd_vma pc;
274 const CGEN_SYNTAX *syntax = CGEN_INSN_SYNTAX (insn);
275 unsigned long value;
276 const unsigned char * syn;
278 CGEN_INIT_INSERT (cd);
279 value = CGEN_INSN_BASE_VALUE (insn);
281 /* If we're recording insns as numbers (rather than a string of bytes),
282 target byte order handling is deferred until later. */
284 #if CGEN_INT_INSN_P
286 *buffer = value;
288 #else
290 cgen_put_insn_value (cd, buffer, min (cd->base_insn_bitsize,
291 CGEN_FIELDS_BITSIZE (fields)),
292 value);
294 #endif /* ! CGEN_INT_INSN_P */
296 /* ??? It would be better to scan the format's fields.
297 Still need to be able to insert a value based on the operand though;
298 e.g. storing a branch displacement that got resolved later.
299 Needs more thought first. */
301 for (syn = CGEN_SYNTAX_STRING (syntax); * syn != '\0'; ++ syn)
303 const char *errmsg;
305 if (CGEN_SYNTAX_CHAR_P (* syn))
306 continue;
308 errmsg = (* cd->insert_operand) (cd, CGEN_SYNTAX_FIELD (*syn),
309 fields, buffer, pc);
310 if (errmsg)
311 return errmsg;
314 return NULL;
317 /* Operand extraction. */
319 #if ! CGEN_INT_INSN_P
321 /* Subroutine of extract_normal.
322 Ensure sufficient bytes are cached in EX_INFO.
323 OFFSET is the offset in bytes from the start of the insn of the value.
324 BYTES is the length of the needed value.
325 Returns 1 for success, 0 for failure. */
327 static CGEN_INLINE int
328 fill_cache (cd, ex_info, offset, bytes, pc)
329 CGEN_CPU_DESC cd;
330 CGEN_EXTRACT_INFO *ex_info;
331 int offset, bytes;
332 bfd_vma pc;
334 /* It's doubtful that the middle part has already been fetched so
335 we don't optimize that case. kiss. */
336 int mask;
337 disassemble_info *info = (disassemble_info *) ex_info->dis_info;
339 /* First do a quick check. */
340 mask = (1 << bytes) - 1;
341 if (((ex_info->valid >> offset) & mask) == mask)
342 return 1;
344 /* Search for the first byte we need to read. */
345 for (mask = 1 << offset; bytes > 0; --bytes, ++offset, mask <<= 1)
346 if (! (mask & ex_info->valid))
347 break;
349 if (bytes)
351 int status;
353 pc += offset;
354 status = (*info->read_memory_func)
355 (pc, ex_info->insn_bytes + offset, bytes, info);
357 if (status != 0)
359 (*info->memory_error_func) (status, pc, info);
360 return 0;
363 ex_info->valid |= ((1 << bytes) - 1) << offset;
366 return 1;
369 /* Subroutine of extract_normal. */
371 static CGEN_INLINE long
372 extract_1 (cd, ex_info, start, length, word_length, bufp, pc)
373 CGEN_CPU_DESC cd;
374 CGEN_EXTRACT_INFO *ex_info;
375 int start,length,word_length;
376 unsigned char *bufp;
377 bfd_vma pc;
379 unsigned long x,mask;
380 int shift;
381 int big_p = CGEN_CPU_INSN_ENDIAN (cd) == CGEN_ENDIAN_BIG;
383 switch (word_length)
385 case 8:
386 x = *bufp;
387 break;
388 case 16:
389 if (big_p)
390 x = bfd_getb16 (bufp);
391 else
392 x = bfd_getl16 (bufp);
393 break;
394 case 24:
395 /* ??? This may need reworking as these cases don't necessarily
396 want the first byte and the last two bytes handled like this. */
397 if (big_p)
398 x = (bufp[0] << 16) | bfd_getb16 (bufp + 1);
399 else
400 x = bfd_getl16 (bufp) | (bufp[2] << 16);
401 break;
402 case 32:
403 if (big_p)
404 x = bfd_getb32 (bufp);
405 else
406 x = bfd_getl32 (bufp);
407 break;
408 default :
409 abort ();
412 /* Written this way to avoid undefined behaviour. */
413 mask = (((1L << (length - 1)) - 1) << 1) | 1;
414 if (CGEN_INSN_LSB0_P)
415 shift = (start + 1) - length;
416 else
417 shift = (word_length - (start + length));
418 return (x >> shift) & mask;
421 #endif /* ! CGEN_INT_INSN_P */
423 /* Default extraction routine.
425 INSN_VALUE is the first base_insn_bitsize bits of the insn in host order,
426 or sometimes less for cases like the m32r where the base insn size is 32
427 but some insns are 16 bits.
428 ATTRS is a mask of the boolean attributes. We only need `SIGNED',
429 but for generality we take a bitmask of all of them.
430 WORD_OFFSET is the offset in bits from the start of the insn of the value.
431 WORD_LENGTH is the length of the word in bits in which the value resides.
432 START is the starting bit number in the word, architecture origin.
433 LENGTH is the length of VALUE in bits.
434 TOTAL_LENGTH is the total length of the insn in bits.
436 Returns 1 for success, 0 for failure. */
438 /* ??? The return code isn't properly used. wip. */
440 /* ??? This doesn't handle bfd_vma's. Create another function when
441 necessary. */
443 static int
444 extract_normal (cd, ex_info, insn_value, attrs, word_offset, start, length,
445 word_length, total_length, pc, valuep)
446 CGEN_CPU_DESC cd;
447 CGEN_EXTRACT_INFO *ex_info;
448 CGEN_INSN_INT insn_value;
449 unsigned int attrs;
450 unsigned int word_offset, start, length, word_length, total_length;
451 bfd_vma pc;
452 long *valuep;
454 CGEN_INSN_INT value;
456 /* If LENGTH is zero, this operand doesn't contribute to the value
457 so give it a standard value of zero. */
458 if (length == 0)
460 *valuep = 0;
461 return 1;
464 if (CGEN_INT_INSN_P
465 && word_offset != 0)
466 abort ();
468 if (word_length > 32)
469 abort ();
471 /* For architectures with insns smaller than the insn-base-bitsize,
472 word_length may be too big. */
473 if (cd->min_insn_bitsize < cd->base_insn_bitsize)
475 if (word_offset == 0
476 && word_length > total_length)
477 word_length = total_length;
480 /* Does the value reside in INSN_VALUE? */
482 if (word_offset == 0)
484 /* Written this way to avoid undefined behaviour. */
485 CGEN_INSN_INT mask = (((1L << (length - 1)) - 1) << 1) | 1;
487 if (CGEN_INSN_LSB0_P)
488 value = insn_value >> ((start + 1) - length);
489 else
490 value = insn_value >> (word_length - (start + length));
491 value &= mask;
492 /* sign extend? */
493 if (CGEN_BOOL_ATTR (attrs, CGEN_IFLD_SIGNED)
494 && (value & (1L << (length - 1))))
495 value |= ~mask;
498 #if ! CGEN_INT_INSN_P
500 else
502 unsigned char *bufp = ex_info->insn_bytes + word_offset / 8;
504 if (word_length > 32)
505 abort ();
507 if (fill_cache (cd, ex_info, word_offset / 8, word_length / 8, pc) == 0)
508 return 0;
510 value = extract_1 (cd, ex_info, start, length, word_length, bufp, pc);
513 #endif /* ! CGEN_INT_INSN_P */
515 *valuep = value;
517 return 1;
520 /* Default insn extractor.
522 INSN_VALUE is the first base_insn_bitsize bits, translated to host order.
523 The extracted fields are stored in FIELDS.
524 EX_INFO is used to handle reading variable length insns.
525 Return the length of the insn in bits, or 0 if no match,
526 or -1 if an error occurs fetching data (memory_error_func will have
527 been called). */
529 static int
530 extract_insn_normal (cd, insn, ex_info, insn_value, fields, pc)
531 CGEN_CPU_DESC cd;
532 const CGEN_INSN *insn;
533 CGEN_EXTRACT_INFO *ex_info;
534 CGEN_INSN_INT insn_value;
535 CGEN_FIELDS *fields;
536 bfd_vma pc;
538 const CGEN_SYNTAX *syntax = CGEN_INSN_SYNTAX (insn);
539 const unsigned char *syn;
541 CGEN_FIELDS_BITSIZE (fields) = CGEN_INSN_BITSIZE (insn);
543 CGEN_INIT_EXTRACT (cd);
545 for (syn = CGEN_SYNTAX_STRING (syntax); *syn; ++syn)
547 int length;
549 if (CGEN_SYNTAX_CHAR_P (*syn))
550 continue;
552 length = (* cd->extract_operand) (cd, CGEN_SYNTAX_FIELD (*syn),
553 ex_info, insn_value, fields, pc);
554 if (length <= 0)
555 return length;
558 /* We recognized and successfully extracted this insn. */
559 return CGEN_INSN_BITSIZE (insn);
562 /* machine generated code added here */
564 /* Main entry point for operand insertion.
566 This function is basically just a big switch statement. Earlier versions
567 used tables to look up the function to use, but
568 - if the table contains both assembler and disassembler functions then
569 the disassembler contains much of the assembler and vice-versa,
570 - there's a lot of inlining possibilities as things grow,
571 - using a switch statement avoids the function call overhead.
573 This function could be moved into `parse_insn_normal', but keeping it
574 separate makes clear the interface between `parse_insn_normal' and each of
575 the handlers. It's also needed by GAS to insert operands that couldn't be
576 resolved during parsing.
579 const char *
580 m32r_cgen_insert_operand (cd, opindex, fields, buffer, pc)
581 CGEN_CPU_DESC cd;
582 int opindex;
583 CGEN_FIELDS * fields;
584 CGEN_INSN_BYTES_PTR buffer;
585 bfd_vma pc;
587 const char * errmsg = NULL;
588 unsigned int total_length = CGEN_FIELDS_BITSIZE (fields);
590 switch (opindex)
592 case M32R_OPERAND_ACC :
593 errmsg = insert_normal (cd, fields->f_acc, 0, 0, 8, 1, 32, total_length, buffer);
594 break;
595 case M32R_OPERAND_ACCD :
596 errmsg = insert_normal (cd, fields->f_accd, 0, 0, 4, 2, 32, total_length, buffer);
597 break;
598 case M32R_OPERAND_ACCS :
599 errmsg = insert_normal (cd, fields->f_accs, 0, 0, 12, 2, 32, total_length, buffer);
600 break;
601 case M32R_OPERAND_DCR :
602 errmsg = insert_normal (cd, fields->f_r1, 0, 0, 4, 4, 32, total_length, buffer);
603 break;
604 case M32R_OPERAND_DISP16 :
606 long value = fields->f_disp16;
607 value = ((int) (((value) - (pc))) >> (2));
608 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);
610 break;
611 case M32R_OPERAND_DISP24 :
613 long value = fields->f_disp24;
614 value = ((int) (((value) - (pc))) >> (2));
615 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);
617 break;
618 case M32R_OPERAND_DISP8 :
620 long value = fields->f_disp8;
621 value = ((int) (((value) - (((pc) & (-4))))) >> (2));
622 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);
624 break;
625 case M32R_OPERAND_DR :
626 errmsg = insert_normal (cd, fields->f_r1, 0, 0, 4, 4, 32, total_length, buffer);
627 break;
628 case M32R_OPERAND_HASH :
629 break;
630 case M32R_OPERAND_HI16 :
631 errmsg = insert_normal (cd, fields->f_hi16, 0|(1<<CGEN_IFLD_SIGN_OPT), 0, 16, 16, 32, total_length, buffer);
632 break;
633 case M32R_OPERAND_IMM1 :
635 long value = fields->f_imm1;
636 value = ((value) - (1));
637 errmsg = insert_normal (cd, value, 0, 0, 15, 1, 32, total_length, buffer);
639 break;
640 case M32R_OPERAND_SCR :
641 errmsg = insert_normal (cd, fields->f_r2, 0, 0, 12, 4, 32, total_length, buffer);
642 break;
643 case M32R_OPERAND_SIMM16 :
644 errmsg = insert_normal (cd, fields->f_simm16, 0|(1<<CGEN_IFLD_SIGNED), 0, 16, 16, 32, total_length, buffer);
645 break;
646 case M32R_OPERAND_SIMM8 :
647 errmsg = insert_normal (cd, fields->f_simm8, 0|(1<<CGEN_IFLD_SIGNED), 0, 8, 8, 32, total_length, buffer);
648 break;
649 case M32R_OPERAND_SLO16 :
650 errmsg = insert_normal (cd, fields->f_simm16, 0|(1<<CGEN_IFLD_SIGNED), 0, 16, 16, 32, total_length, buffer);
651 break;
652 case M32R_OPERAND_SR :
653 errmsg = insert_normal (cd, fields->f_r2, 0, 0, 12, 4, 32, total_length, buffer);
654 break;
655 case M32R_OPERAND_SRC1 :
656 errmsg = insert_normal (cd, fields->f_r1, 0, 0, 4, 4, 32, total_length, buffer);
657 break;
658 case M32R_OPERAND_SRC2 :
659 errmsg = insert_normal (cd, fields->f_r2, 0, 0, 12, 4, 32, total_length, buffer);
660 break;
661 case M32R_OPERAND_UIMM16 :
662 errmsg = insert_normal (cd, fields->f_uimm16, 0, 0, 16, 16, 32, total_length, buffer);
663 break;
664 case M32R_OPERAND_UIMM24 :
665 errmsg = insert_normal (cd, fields->f_uimm24, 0|(1<<CGEN_IFLD_RELOC)|(1<<CGEN_IFLD_ABS_ADDR), 0, 8, 24, 32, total_length, buffer);
666 break;
667 case M32R_OPERAND_UIMM4 :
668 errmsg = insert_normal (cd, fields->f_uimm4, 0, 0, 12, 4, 32, total_length, buffer);
669 break;
670 case M32R_OPERAND_UIMM5 :
671 errmsg = insert_normal (cd, fields->f_uimm5, 0, 0, 11, 5, 32, total_length, buffer);
672 break;
673 case M32R_OPERAND_ULO16 :
674 errmsg = insert_normal (cd, fields->f_uimm16, 0, 0, 16, 16, 32, total_length, buffer);
675 break;
677 default :
678 /* xgettext:c-format */
679 fprintf (stderr, _("Unrecognized field %d while building insn.\n"),
680 opindex);
681 abort ();
684 return errmsg;
687 /* Main entry point for operand extraction.
688 The result is <= 0 for error, >0 for success.
689 ??? Actual values aren't well defined right now.
691 This function is basically just a big switch statement. Earlier versions
692 used tables to look up the function to use, but
693 - if the table contains both assembler and disassembler functions then
694 the disassembler contains much of the assembler and vice-versa,
695 - there's a lot of inlining possibilities as things grow,
696 - using a switch statement avoids the function call overhead.
698 This function could be moved into `print_insn_normal', but keeping it
699 separate makes clear the interface between `print_insn_normal' and each of
700 the handlers.
704 m32r_cgen_extract_operand (cd, opindex, ex_info, insn_value, fields, pc)
705 CGEN_CPU_DESC cd;
706 int opindex;
707 CGEN_EXTRACT_INFO *ex_info;
708 CGEN_INSN_INT insn_value;
709 CGEN_FIELDS * fields;
710 bfd_vma pc;
712 /* Assume success (for those operands that are nops). */
713 int length = 1;
714 unsigned int total_length = CGEN_FIELDS_BITSIZE (fields);
716 switch (opindex)
718 case M32R_OPERAND_ACC :
719 length = extract_normal (cd, ex_info, insn_value, 0, 0, 8, 1, 32, total_length, pc, & fields->f_acc);
720 break;
721 case M32R_OPERAND_ACCD :
722 length = extract_normal (cd, ex_info, insn_value, 0, 0, 4, 2, 32, total_length, pc, & fields->f_accd);
723 break;
724 case M32R_OPERAND_ACCS :
725 length = extract_normal (cd, ex_info, insn_value, 0, 0, 12, 2, 32, total_length, pc, & fields->f_accs);
726 break;
727 case M32R_OPERAND_DCR :
728 length = extract_normal (cd, ex_info, insn_value, 0, 0, 4, 4, 32, total_length, pc, & fields->f_r1);
729 break;
730 case M32R_OPERAND_DISP16 :
732 long value;
733 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);
734 value = ((((value) << (2))) + (pc));
735 fields->f_disp16 = value;
737 break;
738 case M32R_OPERAND_DISP24 :
740 long value;
741 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);
742 value = ((((value) << (2))) + (pc));
743 fields->f_disp24 = value;
745 break;
746 case M32R_OPERAND_DISP8 :
748 long value;
749 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);
750 value = ((((value) << (2))) + (((pc) & (-4))));
751 fields->f_disp8 = value;
753 break;
754 case M32R_OPERAND_DR :
755 length = extract_normal (cd, ex_info, insn_value, 0, 0, 4, 4, 32, total_length, pc, & fields->f_r1);
756 break;
757 case M32R_OPERAND_HASH :
758 break;
759 case M32R_OPERAND_HI16 :
760 length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_SIGN_OPT), 0, 16, 16, 32, total_length, pc, & fields->f_hi16);
761 break;
762 case M32R_OPERAND_IMM1 :
764 long value;
765 length = extract_normal (cd, ex_info, insn_value, 0, 0, 15, 1, 32, total_length, pc, & value);
766 value = ((value) + (1));
767 fields->f_imm1 = value;
769 break;
770 case M32R_OPERAND_SCR :
771 length = extract_normal (cd, ex_info, insn_value, 0, 0, 12, 4, 32, total_length, pc, & fields->f_r2);
772 break;
773 case M32R_OPERAND_SIMM16 :
774 length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_SIGNED), 0, 16, 16, 32, total_length, pc, & fields->f_simm16);
775 break;
776 case M32R_OPERAND_SIMM8 :
777 length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_SIGNED), 0, 8, 8, 32, total_length, pc, & fields->f_simm8);
778 break;
779 case M32R_OPERAND_SLO16 :
780 length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_SIGNED), 0, 16, 16, 32, total_length, pc, & fields->f_simm16);
781 break;
782 case M32R_OPERAND_SR :
783 length = extract_normal (cd, ex_info, insn_value, 0, 0, 12, 4, 32, total_length, pc, & fields->f_r2);
784 break;
785 case M32R_OPERAND_SRC1 :
786 length = extract_normal (cd, ex_info, insn_value, 0, 0, 4, 4, 32, total_length, pc, & fields->f_r1);
787 break;
788 case M32R_OPERAND_SRC2 :
789 length = extract_normal (cd, ex_info, insn_value, 0, 0, 12, 4, 32, total_length, pc, & fields->f_r2);
790 break;
791 case M32R_OPERAND_UIMM16 :
792 length = extract_normal (cd, ex_info, insn_value, 0, 0, 16, 16, 32, total_length, pc, & fields->f_uimm16);
793 break;
794 case M32R_OPERAND_UIMM24 :
795 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);
796 break;
797 case M32R_OPERAND_UIMM4 :
798 length = extract_normal (cd, ex_info, insn_value, 0, 0, 12, 4, 32, total_length, pc, & fields->f_uimm4);
799 break;
800 case M32R_OPERAND_UIMM5 :
801 length = extract_normal (cd, ex_info, insn_value, 0, 0, 11, 5, 32, total_length, pc, & fields->f_uimm5);
802 break;
803 case M32R_OPERAND_ULO16 :
804 length = extract_normal (cd, ex_info, insn_value, 0, 0, 16, 16, 32, total_length, pc, & fields->f_uimm16);
805 break;
807 default :
808 /* xgettext:c-format */
809 fprintf (stderr, _("Unrecognized field %d while decoding insn.\n"),
810 opindex);
811 abort ();
814 return length;
817 cgen_insert_fn * const m32r_cgen_insert_handlers[] =
819 insert_insn_normal,
822 cgen_extract_fn * const m32r_cgen_extract_handlers[] =
824 extract_insn_normal,
827 /* Getting values from cgen_fields is handled by a collection of functions.
828 They are distinguished by the type of the VALUE argument they return.
829 TODO: floating point, inlining support, remove cases where result type
830 not appropriate. */
833 m32r_cgen_get_int_operand (cd, opindex, fields)
834 CGEN_CPU_DESC cd;
835 int opindex;
836 const CGEN_FIELDS * fields;
838 int value;
840 switch (opindex)
842 case M32R_OPERAND_ACC :
843 value = fields->f_acc;
844 break;
845 case M32R_OPERAND_ACCD :
846 value = fields->f_accd;
847 break;
848 case M32R_OPERAND_ACCS :
849 value = fields->f_accs;
850 break;
851 case M32R_OPERAND_DCR :
852 value = fields->f_r1;
853 break;
854 case M32R_OPERAND_DISP16 :
855 value = fields->f_disp16;
856 break;
857 case M32R_OPERAND_DISP24 :
858 value = fields->f_disp24;
859 break;
860 case M32R_OPERAND_DISP8 :
861 value = fields->f_disp8;
862 break;
863 case M32R_OPERAND_DR :
864 value = fields->f_r1;
865 break;
866 case M32R_OPERAND_HASH :
867 value = 0;
868 break;
869 case M32R_OPERAND_HI16 :
870 value = fields->f_hi16;
871 break;
872 case M32R_OPERAND_IMM1 :
873 value = fields->f_imm1;
874 break;
875 case M32R_OPERAND_SCR :
876 value = fields->f_r2;
877 break;
878 case M32R_OPERAND_SIMM16 :
879 value = fields->f_simm16;
880 break;
881 case M32R_OPERAND_SIMM8 :
882 value = fields->f_simm8;
883 break;
884 case M32R_OPERAND_SLO16 :
885 value = fields->f_simm16;
886 break;
887 case M32R_OPERAND_SR :
888 value = fields->f_r2;
889 break;
890 case M32R_OPERAND_SRC1 :
891 value = fields->f_r1;
892 break;
893 case M32R_OPERAND_SRC2 :
894 value = fields->f_r2;
895 break;
896 case M32R_OPERAND_UIMM16 :
897 value = fields->f_uimm16;
898 break;
899 case M32R_OPERAND_UIMM24 :
900 value = fields->f_uimm24;
901 break;
902 case M32R_OPERAND_UIMM4 :
903 value = fields->f_uimm4;
904 break;
905 case M32R_OPERAND_UIMM5 :
906 value = fields->f_uimm5;
907 break;
908 case M32R_OPERAND_ULO16 :
909 value = fields->f_uimm16;
910 break;
912 default :
913 /* xgettext:c-format */
914 fprintf (stderr, _("Unrecognized field %d while getting int operand.\n"),
915 opindex);
916 abort ();
919 return value;
922 bfd_vma
923 m32r_cgen_get_vma_operand (cd, opindex, fields)
924 CGEN_CPU_DESC cd;
925 int opindex;
926 const CGEN_FIELDS * fields;
928 bfd_vma value;
930 switch (opindex)
932 case M32R_OPERAND_ACC :
933 value = fields->f_acc;
934 break;
935 case M32R_OPERAND_ACCD :
936 value = fields->f_accd;
937 break;
938 case M32R_OPERAND_ACCS :
939 value = fields->f_accs;
940 break;
941 case M32R_OPERAND_DCR :
942 value = fields->f_r1;
943 break;
944 case M32R_OPERAND_DISP16 :
945 value = fields->f_disp16;
946 break;
947 case M32R_OPERAND_DISP24 :
948 value = fields->f_disp24;
949 break;
950 case M32R_OPERAND_DISP8 :
951 value = fields->f_disp8;
952 break;
953 case M32R_OPERAND_DR :
954 value = fields->f_r1;
955 break;
956 case M32R_OPERAND_HASH :
957 value = 0;
958 break;
959 case M32R_OPERAND_HI16 :
960 value = fields->f_hi16;
961 break;
962 case M32R_OPERAND_IMM1 :
963 value = fields->f_imm1;
964 break;
965 case M32R_OPERAND_SCR :
966 value = fields->f_r2;
967 break;
968 case M32R_OPERAND_SIMM16 :
969 value = fields->f_simm16;
970 break;
971 case M32R_OPERAND_SIMM8 :
972 value = fields->f_simm8;
973 break;
974 case M32R_OPERAND_SLO16 :
975 value = fields->f_simm16;
976 break;
977 case M32R_OPERAND_SR :
978 value = fields->f_r2;
979 break;
980 case M32R_OPERAND_SRC1 :
981 value = fields->f_r1;
982 break;
983 case M32R_OPERAND_SRC2 :
984 value = fields->f_r2;
985 break;
986 case M32R_OPERAND_UIMM16 :
987 value = fields->f_uimm16;
988 break;
989 case M32R_OPERAND_UIMM24 :
990 value = fields->f_uimm24;
991 break;
992 case M32R_OPERAND_UIMM4 :
993 value = fields->f_uimm4;
994 break;
995 case M32R_OPERAND_UIMM5 :
996 value = fields->f_uimm5;
997 break;
998 case M32R_OPERAND_ULO16 :
999 value = fields->f_uimm16;
1000 break;
1002 default :
1003 /* xgettext:c-format */
1004 fprintf (stderr, _("Unrecognized field %d while getting vma operand.\n"),
1005 opindex);
1006 abort ();
1009 return value;
1012 /* Stuffing values in cgen_fields is handled by a collection of functions.
1013 They are distinguished by the type of the VALUE argument they accept.
1014 TODO: floating point, inlining support, remove cases where argument type
1015 not appropriate. */
1017 void
1018 m32r_cgen_set_int_operand (cd, opindex, fields, value)
1019 CGEN_CPU_DESC cd;
1020 int opindex;
1021 CGEN_FIELDS * fields;
1022 int value;
1024 switch (opindex)
1026 case M32R_OPERAND_ACC :
1027 fields->f_acc = value;
1028 break;
1029 case M32R_OPERAND_ACCD :
1030 fields->f_accd = value;
1031 break;
1032 case M32R_OPERAND_ACCS :
1033 fields->f_accs = value;
1034 break;
1035 case M32R_OPERAND_DCR :
1036 fields->f_r1 = value;
1037 break;
1038 case M32R_OPERAND_DISP16 :
1039 fields->f_disp16 = value;
1040 break;
1041 case M32R_OPERAND_DISP24 :
1042 fields->f_disp24 = value;
1043 break;
1044 case M32R_OPERAND_DISP8 :
1045 fields->f_disp8 = value;
1046 break;
1047 case M32R_OPERAND_DR :
1048 fields->f_r1 = value;
1049 break;
1050 case M32R_OPERAND_HASH :
1051 break;
1052 case M32R_OPERAND_HI16 :
1053 fields->f_hi16 = value;
1054 break;
1055 case M32R_OPERAND_IMM1 :
1056 fields->f_imm1 = value;
1057 break;
1058 case M32R_OPERAND_SCR :
1059 fields->f_r2 = value;
1060 break;
1061 case M32R_OPERAND_SIMM16 :
1062 fields->f_simm16 = value;
1063 break;
1064 case M32R_OPERAND_SIMM8 :
1065 fields->f_simm8 = value;
1066 break;
1067 case M32R_OPERAND_SLO16 :
1068 fields->f_simm16 = value;
1069 break;
1070 case M32R_OPERAND_SR :
1071 fields->f_r2 = value;
1072 break;
1073 case M32R_OPERAND_SRC1 :
1074 fields->f_r1 = value;
1075 break;
1076 case M32R_OPERAND_SRC2 :
1077 fields->f_r2 = value;
1078 break;
1079 case M32R_OPERAND_UIMM16 :
1080 fields->f_uimm16 = value;
1081 break;
1082 case M32R_OPERAND_UIMM24 :
1083 fields->f_uimm24 = value;
1084 break;
1085 case M32R_OPERAND_UIMM4 :
1086 fields->f_uimm4 = value;
1087 break;
1088 case M32R_OPERAND_UIMM5 :
1089 fields->f_uimm5 = value;
1090 break;
1091 case M32R_OPERAND_ULO16 :
1092 fields->f_uimm16 = value;
1093 break;
1095 default :
1096 /* xgettext:c-format */
1097 fprintf (stderr, _("Unrecognized field %d while setting int operand.\n"),
1098 opindex);
1099 abort ();
1103 void
1104 m32r_cgen_set_vma_operand (cd, opindex, fields, value)
1105 CGEN_CPU_DESC cd;
1106 int opindex;
1107 CGEN_FIELDS * fields;
1108 bfd_vma value;
1110 switch (opindex)
1112 case M32R_OPERAND_ACC :
1113 fields->f_acc = value;
1114 break;
1115 case M32R_OPERAND_ACCD :
1116 fields->f_accd = value;
1117 break;
1118 case M32R_OPERAND_ACCS :
1119 fields->f_accs = value;
1120 break;
1121 case M32R_OPERAND_DCR :
1122 fields->f_r1 = value;
1123 break;
1124 case M32R_OPERAND_DISP16 :
1125 fields->f_disp16 = value;
1126 break;
1127 case M32R_OPERAND_DISP24 :
1128 fields->f_disp24 = value;
1129 break;
1130 case M32R_OPERAND_DISP8 :
1131 fields->f_disp8 = value;
1132 break;
1133 case M32R_OPERAND_DR :
1134 fields->f_r1 = value;
1135 break;
1136 case M32R_OPERAND_HASH :
1137 break;
1138 case M32R_OPERAND_HI16 :
1139 fields->f_hi16 = value;
1140 break;
1141 case M32R_OPERAND_IMM1 :
1142 fields->f_imm1 = value;
1143 break;
1144 case M32R_OPERAND_SCR :
1145 fields->f_r2 = value;
1146 break;
1147 case M32R_OPERAND_SIMM16 :
1148 fields->f_simm16 = value;
1149 break;
1150 case M32R_OPERAND_SIMM8 :
1151 fields->f_simm8 = value;
1152 break;
1153 case M32R_OPERAND_SLO16 :
1154 fields->f_simm16 = value;
1155 break;
1156 case M32R_OPERAND_SR :
1157 fields->f_r2 = value;
1158 break;
1159 case M32R_OPERAND_SRC1 :
1160 fields->f_r1 = value;
1161 break;
1162 case M32R_OPERAND_SRC2 :
1163 fields->f_r2 = value;
1164 break;
1165 case M32R_OPERAND_UIMM16 :
1166 fields->f_uimm16 = value;
1167 break;
1168 case M32R_OPERAND_UIMM24 :
1169 fields->f_uimm24 = value;
1170 break;
1171 case M32R_OPERAND_UIMM4 :
1172 fields->f_uimm4 = value;
1173 break;
1174 case M32R_OPERAND_UIMM5 :
1175 fields->f_uimm5 = value;
1176 break;
1177 case M32R_OPERAND_ULO16 :
1178 fields->f_uimm16 = value;
1179 break;
1181 default :
1182 /* xgettext:c-format */
1183 fprintf (stderr, _("Unrecognized field %d while setting vma operand.\n"),
1184 opindex);
1185 abort ();
1189 /* Function to call before using the instruction builder tables. */
1191 void
1192 m32r_cgen_init_ibld_table (cd)
1193 CGEN_CPU_DESC cd;
1195 cd->insert_handlers = & m32r_cgen_insert_handlers[0];
1196 cd->extract_handlers = & m32r_cgen_extract_handlers[0];
1198 cd->insert_operand = m32r_cgen_insert_operand;
1199 cd->extract_operand = m32r_cgen_extract_operand;
1201 cd->get_int_operand = m32r_cgen_get_int_operand;
1202 cd->set_int_operand = m32r_cgen_set_int_operand;
1203 cd->get_vma_operand = m32r_cgen_get_vma_operand;
1204 cd->set_vma_operand = m32r_cgen_set_vma_operand;