oops - omitted from previous delta
[binutils.git] / opcodes / m32r-ibld.c
blobef1ee0e01266fff15460c1c0fd37d1ae60b0b343
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 1996, 1997, 1998, 1999, 2000, 2001 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 <stdio.h>
29 #include "ansidecl.h"
30 #include "dis-asm.h"
31 #include "bfd.h"
32 #include "symcat.h"
33 #include "m32r-desc.h"
34 #include "m32r-opc.h"
35 #include "opintl.h"
36 #include "safe-ctype.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));
52 static int extract_normal
53 PARAMS ((CGEN_CPU_DESC, CGEN_EXTRACT_INFO *, CGEN_INSN_INT,
54 unsigned int, unsigned int, unsigned int, unsigned int,
55 unsigned int, unsigned int, bfd_vma, long *));
56 static int extract_insn_normal
57 PARAMS ((CGEN_CPU_DESC, const CGEN_INSN *, CGEN_EXTRACT_INFO *,
58 CGEN_INSN_INT, CGEN_FIELDS *, bfd_vma));
59 #if CGEN_INT_INSN_P
60 static void put_insn_int_value
61 PARAMS ((CGEN_CPU_DESC, CGEN_INSN_BYTES_PTR, int, int, CGEN_INSN_INT));
62 #endif
63 #if ! CGEN_INT_INSN_P
64 static CGEN_INLINE void insert_1
65 PARAMS ((CGEN_CPU_DESC, unsigned long, int, int, int, unsigned char *));
66 static CGEN_INLINE int fill_cache
67 PARAMS ((CGEN_CPU_DESC, CGEN_EXTRACT_INFO *, int, int, bfd_vma));
68 static CGEN_INLINE long extract_1
69 PARAMS ((CGEN_CPU_DESC, CGEN_EXTRACT_INFO *, int, int, int,
70 unsigned char *, bfd_vma));
71 #endif
73 /* Operand insertion. */
75 #if ! CGEN_INT_INSN_P
77 /* Subroutine of insert_normal. */
79 static CGEN_INLINE void
80 insert_1 (cd, value, start, length, word_length, bufp)
81 CGEN_CPU_DESC cd;
82 unsigned long value;
83 int start,length,word_length;
84 unsigned char *bufp;
86 unsigned long x,mask;
87 int shift;
89 x = cgen_get_insn_value (cd, bufp, word_length);
91 /* Written this way to avoid undefined behaviour. */
92 mask = (((1L << (length - 1)) - 1) << 1) | 1;
93 if (CGEN_INSN_LSB0_P)
94 shift = (start + 1) - length;
95 else
96 shift = (word_length - (start + length));
97 x = (x & ~(mask << shift)) | ((value & mask) << shift);
99 cgen_put_insn_value (cd, bufp, word_length, (bfd_vma) x);
102 #endif /* ! CGEN_INT_INSN_P */
104 /* Default insertion routine.
106 ATTRS is a mask of the boolean attributes.
107 WORD_OFFSET is the offset in bits from the start of the insn of the value.
108 WORD_LENGTH is the length of the word in bits in which the value resides.
109 START is the starting bit number in the word, architecture origin.
110 LENGTH is the length of VALUE in bits.
111 TOTAL_LENGTH is the total length of the insn in bits.
113 The result is an error message or NULL if success. */
115 /* ??? This duplicates functionality with bfd's howto table and
116 bfd_install_relocation. */
117 /* ??? This doesn't handle bfd_vma's. Create another function when
118 necessary. */
120 static const char *
121 insert_normal (cd, value, attrs, word_offset, start, length, word_length,
122 total_length, buffer)
123 CGEN_CPU_DESC cd;
124 long value;
125 unsigned int attrs;
126 unsigned int word_offset, start, length, word_length, total_length;
127 CGEN_INSN_BYTES_PTR buffer;
129 static char errbuf[100];
130 /* Written this way to avoid undefined behaviour. */
131 unsigned long mask = (((1L << (length - 1)) - 1) << 1) | 1;
133 /* If LENGTH is zero, this operand doesn't contribute to the value. */
134 if (length == 0)
135 return NULL;
137 #if 0
138 if (CGEN_INT_INSN_P
139 && word_offset != 0)
140 abort ();
141 #endif
143 if (word_length > 32)
144 abort ();
146 /* For architectures with insns smaller than the base-insn-bitsize,
147 word_length may be too big. */
148 if (cd->min_insn_bitsize < cd->base_insn_bitsize)
150 if (word_offset == 0
151 && word_length > total_length)
152 word_length = total_length;
155 /* Ensure VALUE will fit. */
156 if (CGEN_BOOL_ATTR (attrs, CGEN_IFLD_SIGN_OPT))
158 long minval = - (1L << (length - 1));
159 unsigned long maxval = mask;
161 if ((value > 0 && (unsigned long) value > maxval)
162 || value < minval)
164 /* xgettext:c-format */
165 sprintf (errbuf,
166 _("operand out of range (%ld not between %ld and %lu)"),
167 value, minval, maxval);
168 return errbuf;
171 else if (! CGEN_BOOL_ATTR (attrs, CGEN_IFLD_SIGNED))
173 unsigned long maxval = mask;
175 if ((unsigned long) value > maxval)
177 /* xgettext:c-format */
178 sprintf (errbuf,
179 _("operand out of range (%lu not between 0 and %lu)"),
180 value, maxval);
181 return errbuf;
184 else
186 if (! cgen_signed_overflow_ok_p (cd))
188 long minval = - (1L << (length - 1));
189 long maxval = (1L << (length - 1)) - 1;
191 if (value < minval || value > maxval)
193 sprintf
194 /* xgettext:c-format */
195 (errbuf, _("operand out of range (%ld not between %ld and %ld)"),
196 value, minval, maxval);
197 return errbuf;
202 #if CGEN_INT_INSN_P
205 int shift;
207 if (CGEN_INSN_LSB0_P)
208 shift = (word_offset + start + 1) - length;
209 else
210 shift = total_length - (word_offset + start + length);
211 *buffer = (*buffer & ~(mask << shift)) | ((value & mask) << shift);
214 #else /* ! CGEN_INT_INSN_P */
217 unsigned char *bufp = (unsigned char *) buffer + word_offset / 8;
219 insert_1 (cd, value, start, length, word_length, bufp);
222 #endif /* ! CGEN_INT_INSN_P */
224 return NULL;
227 /* Default insn builder (insert handler).
228 The instruction is recorded in CGEN_INT_INSN_P byte order (meaning
229 that if CGEN_INSN_BYTES_PTR is an int * and thus, the value is
230 recorded in host byte order, otherwise BUFFER is an array of bytes
231 and the value is recorded in target byte order).
232 The result is an error message or NULL if success. */
234 static const char *
235 insert_insn_normal (cd, insn, fields, buffer, pc)
236 CGEN_CPU_DESC cd;
237 const CGEN_INSN * insn;
238 CGEN_FIELDS * fields;
239 CGEN_INSN_BYTES_PTR buffer;
240 bfd_vma pc;
242 const CGEN_SYNTAX *syntax = CGEN_INSN_SYNTAX (insn);
243 unsigned long value;
244 const CGEN_SYNTAX_CHAR_TYPE * syn;
246 CGEN_INIT_INSERT (cd);
247 value = CGEN_INSN_BASE_VALUE (insn);
249 /* If we're recording insns as numbers (rather than a string of bytes),
250 target byte order handling is deferred until later. */
252 #if CGEN_INT_INSN_P
254 put_insn_int_value (cd, buffer, cd->base_insn_bitsize,
255 CGEN_FIELDS_BITSIZE (fields), value);
257 #else
259 cgen_put_insn_value (cd, buffer, min ((unsigned) cd->base_insn_bitsize,
260 (unsigned) CGEN_FIELDS_BITSIZE (fields)),
261 value);
263 #endif /* ! CGEN_INT_INSN_P */
265 /* ??? It would be better to scan the format's fields.
266 Still need to be able to insert a value based on the operand though;
267 e.g. storing a branch displacement that got resolved later.
268 Needs more thought first. */
270 for (syn = CGEN_SYNTAX_STRING (syntax); * syn; ++ syn)
272 const char *errmsg;
274 if (CGEN_SYNTAX_CHAR_P (* syn))
275 continue;
277 errmsg = (* cd->insert_operand) (cd, CGEN_SYNTAX_FIELD (*syn),
278 fields, buffer, pc);
279 if (errmsg)
280 return errmsg;
283 return NULL;
286 #if CGEN_INT_INSN_P
287 /* Cover function to store an insn value into an integral insn. Must go here
288 because it needs <prefix>-desc.h for CGEN_INT_INSN_P. */
290 static void
291 put_insn_int_value (cd, buf, length, insn_length, value)
292 CGEN_CPU_DESC cd ATTRIBUTE_UNUSED;
293 CGEN_INSN_BYTES_PTR buf;
294 int length;
295 int insn_length;
296 CGEN_INSN_INT value;
298 /* For architectures with insns smaller than the base-insn-bitsize,
299 length may be too big. */
300 if (length > insn_length)
301 *buf = value;
302 else
304 int shift = insn_length - length;
305 /* Written this way to avoid undefined behaviour. */
306 CGEN_INSN_INT mask = (((1L << (length - 1)) - 1) << 1) | 1;
307 *buf = (*buf & ~(mask << shift)) | ((value & mask) << shift);
310 #endif
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 ATTRIBUTE_UNUSED;
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 unsigned 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 ATTRIBUTE_UNUSED;
370 int start,length,word_length;
371 unsigned char *bufp;
372 bfd_vma pc ATTRIBUTE_UNUSED;
374 unsigned long x;
375 int shift;
376 #if 0
377 int big_p = CGEN_CPU_INSN_ENDIAN (cd) == CGEN_ENDIAN_BIG;
378 #endif
379 x = cgen_get_insn_value (cd, bufp, word_length);
381 if (CGEN_INSN_LSB0_P)
382 shift = (start + 1) - length;
383 else
384 shift = (word_length - (start + length));
385 return x >> shift;
388 #endif /* ! CGEN_INT_INSN_P */
390 /* Default extraction routine.
392 INSN_VALUE is the first base_insn_bitsize bits of the insn in host order,
393 or sometimes less for cases like the m32r where the base insn size is 32
394 but some insns are 16 bits.
395 ATTRS is a mask of the boolean attributes. We only need `SIGNED',
396 but for generality we take a bitmask of all of them.
397 WORD_OFFSET is the offset in bits from the start of the insn of the value.
398 WORD_LENGTH is the length of the word in bits in which the value resides.
399 START is the starting bit number in the word, architecture origin.
400 LENGTH is the length of VALUE in bits.
401 TOTAL_LENGTH is the total length of the insn in bits.
403 Returns 1 for success, 0 for failure. */
405 /* ??? The return code isn't properly used. wip. */
407 /* ??? This doesn't handle bfd_vma's. Create another function when
408 necessary. */
410 static int
411 extract_normal (cd, ex_info, insn_value, attrs, word_offset, start, length,
412 word_length, total_length, pc, valuep)
413 CGEN_CPU_DESC cd;
414 #if ! CGEN_INT_INSN_P
415 CGEN_EXTRACT_INFO *ex_info;
416 #else
417 CGEN_EXTRACT_INFO *ex_info ATTRIBUTE_UNUSED;
418 #endif
419 CGEN_INSN_INT insn_value;
420 unsigned int attrs;
421 unsigned int word_offset, start, length, word_length, total_length;
422 #if ! CGEN_INT_INSN_P
423 bfd_vma pc;
424 #else
425 bfd_vma pc ATTRIBUTE_UNUSED;
426 #endif
427 long *valuep;
429 long value, mask;
431 /* If LENGTH is zero, this operand doesn't contribute to the value
432 so give it a standard value of zero. */
433 if (length == 0)
435 *valuep = 0;
436 return 1;
439 #if 0
440 if (CGEN_INT_INSN_P
441 && word_offset != 0)
442 abort ();
443 #endif
445 if (word_length > 32)
446 abort ();
448 /* For architectures with insns smaller than the insn-base-bitsize,
449 word_length may be too big. */
450 if (cd->min_insn_bitsize < cd->base_insn_bitsize)
452 if (word_offset == 0
453 && word_length > total_length)
454 word_length = total_length;
457 /* Does the value reside in INSN_VALUE, and at the right alignment? */
459 if (CGEN_INT_INSN_P || (word_offset == 0 && word_length == total_length))
461 if (CGEN_INSN_LSB0_P)
462 value = insn_value >> ((word_offset + start + 1) - length);
463 else
464 value = insn_value >> (total_length - ( word_offset + start + length));
467 #if ! CGEN_INT_INSN_P
469 else
471 unsigned char *bufp = ex_info->insn_bytes + word_offset / 8;
473 if (word_length > 32)
474 abort ();
476 if (fill_cache (cd, ex_info, word_offset / 8, word_length / 8, pc) == 0)
477 return 0;
479 value = extract_1 (cd, ex_info, start, length, word_length, bufp, pc);
482 #endif /* ! CGEN_INT_INSN_P */
484 /* Written this way to avoid undefined behaviour. */
485 mask = (((1L << (length - 1)) - 1) << 1) | 1;
487 value &= mask;
488 /* sign extend? */
489 if (CGEN_BOOL_ATTR (attrs, CGEN_IFLD_SIGNED)
490 && (value & (1L << (length - 1))))
491 value |= ~mask;
493 *valuep = value;
495 return 1;
498 /* Default insn extractor.
500 INSN_VALUE is the first base_insn_bitsize bits, translated to host order.
501 The extracted fields are stored in FIELDS.
502 EX_INFO is used to handle reading variable length insns.
503 Return the length of the insn in bits, or 0 if no match,
504 or -1 if an error occurs fetching data (memory_error_func will have
505 been called). */
507 static int
508 extract_insn_normal (cd, insn, ex_info, insn_value, fields, pc)
509 CGEN_CPU_DESC cd;
510 const CGEN_INSN *insn;
511 CGEN_EXTRACT_INFO *ex_info;
512 CGEN_INSN_INT insn_value;
513 CGEN_FIELDS *fields;
514 bfd_vma pc;
516 const CGEN_SYNTAX *syntax = CGEN_INSN_SYNTAX (insn);
517 const CGEN_SYNTAX_CHAR_TYPE *syn;
519 CGEN_FIELDS_BITSIZE (fields) = CGEN_INSN_BITSIZE (insn);
521 CGEN_INIT_EXTRACT (cd);
523 for (syn = CGEN_SYNTAX_STRING (syntax); *syn; ++syn)
525 int length;
527 if (CGEN_SYNTAX_CHAR_P (*syn))
528 continue;
530 length = (* cd->extract_operand) (cd, CGEN_SYNTAX_FIELD (*syn),
531 ex_info, insn_value, fields, pc);
532 if (length <= 0)
533 return length;
536 /* We recognized and successfully extracted this insn. */
537 return CGEN_INSN_BITSIZE (insn);
540 /* machine generated code added here */
542 const char * m32r_cgen_insert_operand
543 PARAMS ((CGEN_CPU_DESC, int, CGEN_FIELDS *, CGEN_INSN_BYTES_PTR, bfd_vma));
545 /* Main entry point for operand insertion.
547 This function is basically just a big switch statement. Earlier versions
548 used tables to look up the function to use, but
549 - if the table contains both assembler and disassembler functions then
550 the disassembler contains much of the assembler and vice-versa,
551 - there's a lot of inlining possibilities as things grow,
552 - using a switch statement avoids the function call overhead.
554 This function could be moved into `parse_insn_normal', but keeping it
555 separate makes clear the interface between `parse_insn_normal' and each of
556 the handlers. It's also needed by GAS to insert operands that couldn't be
557 resolved during parsing. */
559 const char *
560 m32r_cgen_insert_operand (cd, opindex, fields, buffer, pc)
561 CGEN_CPU_DESC cd;
562 int opindex;
563 CGEN_FIELDS * fields;
564 CGEN_INSN_BYTES_PTR buffer;
565 bfd_vma pc ATTRIBUTE_UNUSED;
567 const char * errmsg = NULL;
568 unsigned int total_length = CGEN_FIELDS_BITSIZE (fields);
570 switch (opindex)
572 case M32R_OPERAND_ACC :
573 errmsg = insert_normal (cd, fields->f_acc, 0, 0, 8, 1, 32, total_length, buffer);
574 break;
575 case M32R_OPERAND_ACCD :
576 errmsg = insert_normal (cd, fields->f_accd, 0, 0, 4, 2, 32, total_length, buffer);
577 break;
578 case M32R_OPERAND_ACCS :
579 errmsg = insert_normal (cd, fields->f_accs, 0, 0, 12, 2, 32, total_length, buffer);
580 break;
581 case M32R_OPERAND_DCR :
582 errmsg = insert_normal (cd, fields->f_r1, 0, 0, 4, 4, 32, total_length, buffer);
583 break;
584 case M32R_OPERAND_DISP16 :
586 long value = fields->f_disp16;
587 value = ((int) (((value) - (pc))) >> (2));
588 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);
590 break;
591 case M32R_OPERAND_DISP24 :
593 long value = fields->f_disp24;
594 value = ((int) (((value) - (pc))) >> (2));
595 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);
597 break;
598 case M32R_OPERAND_DISP8 :
600 long value = fields->f_disp8;
601 value = ((int) (((value) - (((pc) & (-4))))) >> (2));
602 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);
604 break;
605 case M32R_OPERAND_DR :
606 errmsg = insert_normal (cd, fields->f_r1, 0, 0, 4, 4, 32, total_length, buffer);
607 break;
608 case M32R_OPERAND_HASH :
609 break;
610 case M32R_OPERAND_HI16 :
611 errmsg = insert_normal (cd, fields->f_hi16, 0|(1<<CGEN_IFLD_SIGN_OPT), 0, 16, 16, 32, total_length, buffer);
612 break;
613 case M32R_OPERAND_IMM1 :
615 long value = fields->f_imm1;
616 value = ((value) - (1));
617 errmsg = insert_normal (cd, value, 0, 0, 15, 1, 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 int m32r_cgen_extract_operand
668 PARAMS ((CGEN_CPU_DESC, int, CGEN_EXTRACT_INFO *, CGEN_INSN_INT,
669 CGEN_FIELDS *, bfd_vma));
671 /* Main entry point for operand extraction.
672 The result is <= 0 for error, >0 for success.
673 ??? Actual values aren't well defined right now.
675 This function is basically just a big switch statement. Earlier versions
676 used tables to look up the function to use, but
677 - if the table contains both assembler and disassembler functions then
678 the disassembler contains much of the assembler and vice-versa,
679 - there's a lot of inlining possibilities as things grow,
680 - using a switch statement avoids the function call overhead.
682 This function could be moved into `print_insn_normal', but keeping it
683 separate makes clear the interface between `print_insn_normal' and each of
684 the handlers. */
687 m32r_cgen_extract_operand (cd, opindex, ex_info, insn_value, fields, pc)
688 CGEN_CPU_DESC cd;
689 int opindex;
690 CGEN_EXTRACT_INFO *ex_info;
691 CGEN_INSN_INT insn_value;
692 CGEN_FIELDS * fields;
693 bfd_vma pc;
695 /* Assume success (for those operands that are nops). */
696 int length = 1;
697 unsigned int total_length = CGEN_FIELDS_BITSIZE (fields);
699 switch (opindex)
701 case M32R_OPERAND_ACC :
702 length = extract_normal (cd, ex_info, insn_value, 0, 0, 8, 1, 32, total_length, pc, & fields->f_acc);
703 break;
704 case M32R_OPERAND_ACCD :
705 length = extract_normal (cd, ex_info, insn_value, 0, 0, 4, 2, 32, total_length, pc, & fields->f_accd);
706 break;
707 case M32R_OPERAND_ACCS :
708 length = extract_normal (cd, ex_info, insn_value, 0, 0, 12, 2, 32, total_length, pc, & fields->f_accs);
709 break;
710 case M32R_OPERAND_DCR :
711 length = extract_normal (cd, ex_info, insn_value, 0, 0, 4, 4, 32, total_length, pc, & fields->f_r1);
712 break;
713 case M32R_OPERAND_DISP16 :
715 long value;
716 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);
717 value = ((((value) << (2))) + (pc));
718 fields->f_disp16 = value;
720 break;
721 case M32R_OPERAND_DISP24 :
723 long value;
724 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);
725 value = ((((value) << (2))) + (pc));
726 fields->f_disp24 = value;
728 break;
729 case M32R_OPERAND_DISP8 :
731 long value;
732 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);
733 value = ((((value) << (2))) + (((pc) & (-4))));
734 fields->f_disp8 = value;
736 break;
737 case M32R_OPERAND_DR :
738 length = extract_normal (cd, ex_info, insn_value, 0, 0, 4, 4, 32, total_length, pc, & fields->f_r1);
739 break;
740 case M32R_OPERAND_HASH :
741 break;
742 case M32R_OPERAND_HI16 :
743 length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_SIGN_OPT), 0, 16, 16, 32, total_length, pc, & fields->f_hi16);
744 break;
745 case M32R_OPERAND_IMM1 :
747 long value;
748 length = extract_normal (cd, ex_info, insn_value, 0, 0, 15, 1, 32, total_length, pc, & value);
749 value = ((value) + (1));
750 fields->f_imm1 = value;
752 break;
753 case M32R_OPERAND_SCR :
754 length = extract_normal (cd, ex_info, insn_value, 0, 0, 12, 4, 32, total_length, pc, & fields->f_r2);
755 break;
756 case M32R_OPERAND_SIMM16 :
757 length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_SIGNED), 0, 16, 16, 32, total_length, pc, & fields->f_simm16);
758 break;
759 case M32R_OPERAND_SIMM8 :
760 length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_SIGNED), 0, 8, 8, 32, total_length, pc, & fields->f_simm8);
761 break;
762 case M32R_OPERAND_SLO16 :
763 length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_SIGNED), 0, 16, 16, 32, total_length, pc, & fields->f_simm16);
764 break;
765 case M32R_OPERAND_SR :
766 length = extract_normal (cd, ex_info, insn_value, 0, 0, 12, 4, 32, total_length, pc, & fields->f_r2);
767 break;
768 case M32R_OPERAND_SRC1 :
769 length = extract_normal (cd, ex_info, insn_value, 0, 0, 4, 4, 32, total_length, pc, & fields->f_r1);
770 break;
771 case M32R_OPERAND_SRC2 :
772 length = extract_normal (cd, ex_info, insn_value, 0, 0, 12, 4, 32, total_length, pc, & fields->f_r2);
773 break;
774 case M32R_OPERAND_UIMM16 :
775 length = extract_normal (cd, ex_info, insn_value, 0, 0, 16, 16, 32, total_length, pc, & fields->f_uimm16);
776 break;
777 case M32R_OPERAND_UIMM24 :
778 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);
779 break;
780 case M32R_OPERAND_UIMM4 :
781 length = extract_normal (cd, ex_info, insn_value, 0, 0, 12, 4, 32, total_length, pc, & fields->f_uimm4);
782 break;
783 case M32R_OPERAND_UIMM5 :
784 length = extract_normal (cd, ex_info, insn_value, 0, 0, 11, 5, 32, total_length, pc, & fields->f_uimm5);
785 break;
786 case M32R_OPERAND_ULO16 :
787 length = extract_normal (cd, ex_info, insn_value, 0, 0, 16, 16, 32, total_length, pc, & fields->f_uimm16);
788 break;
790 default :
791 /* xgettext:c-format */
792 fprintf (stderr, _("Unrecognized field %d while decoding insn.\n"),
793 opindex);
794 abort ();
797 return length;
800 cgen_insert_fn * const m32r_cgen_insert_handlers[] =
802 insert_insn_normal,
805 cgen_extract_fn * const m32r_cgen_extract_handlers[] =
807 extract_insn_normal,
810 int m32r_cgen_get_int_operand
811 PARAMS ((CGEN_CPU_DESC, int, const CGEN_FIELDS *));
812 bfd_vma m32r_cgen_get_vma_operand
813 PARAMS ((CGEN_CPU_DESC, int, const CGEN_FIELDS *));
815 /* Getting values from cgen_fields is handled by a collection of functions.
816 They are distinguished by the type of the VALUE argument they return.
817 TODO: floating point, inlining support, remove cases where result type
818 not appropriate. */
821 m32r_cgen_get_int_operand (cd, opindex, fields)
822 CGEN_CPU_DESC cd ATTRIBUTE_UNUSED;
823 int opindex;
824 const CGEN_FIELDS * fields;
826 int value;
828 switch (opindex)
830 case M32R_OPERAND_ACC :
831 value = fields->f_acc;
832 break;
833 case M32R_OPERAND_ACCD :
834 value = fields->f_accd;
835 break;
836 case M32R_OPERAND_ACCS :
837 value = fields->f_accs;
838 break;
839 case M32R_OPERAND_DCR :
840 value = fields->f_r1;
841 break;
842 case M32R_OPERAND_DISP16 :
843 value = fields->f_disp16;
844 break;
845 case M32R_OPERAND_DISP24 :
846 value = fields->f_disp24;
847 break;
848 case M32R_OPERAND_DISP8 :
849 value = fields->f_disp8;
850 break;
851 case M32R_OPERAND_DR :
852 value = fields->f_r1;
853 break;
854 case M32R_OPERAND_HASH :
855 value = 0;
856 break;
857 case M32R_OPERAND_HI16 :
858 value = fields->f_hi16;
859 break;
860 case M32R_OPERAND_IMM1 :
861 value = fields->f_imm1;
862 break;
863 case M32R_OPERAND_SCR :
864 value = fields->f_r2;
865 break;
866 case M32R_OPERAND_SIMM16 :
867 value = fields->f_simm16;
868 break;
869 case M32R_OPERAND_SIMM8 :
870 value = fields->f_simm8;
871 break;
872 case M32R_OPERAND_SLO16 :
873 value = fields->f_simm16;
874 break;
875 case M32R_OPERAND_SR :
876 value = fields->f_r2;
877 break;
878 case M32R_OPERAND_SRC1 :
879 value = fields->f_r1;
880 break;
881 case M32R_OPERAND_SRC2 :
882 value = fields->f_r2;
883 break;
884 case M32R_OPERAND_UIMM16 :
885 value = fields->f_uimm16;
886 break;
887 case M32R_OPERAND_UIMM24 :
888 value = fields->f_uimm24;
889 break;
890 case M32R_OPERAND_UIMM4 :
891 value = fields->f_uimm4;
892 break;
893 case M32R_OPERAND_UIMM5 :
894 value = fields->f_uimm5;
895 break;
896 case M32R_OPERAND_ULO16 :
897 value = fields->f_uimm16;
898 break;
900 default :
901 /* xgettext:c-format */
902 fprintf (stderr, _("Unrecognized field %d while getting int operand.\n"),
903 opindex);
904 abort ();
907 return value;
910 bfd_vma
911 m32r_cgen_get_vma_operand (cd, opindex, fields)
912 CGEN_CPU_DESC cd ATTRIBUTE_UNUSED;
913 int opindex;
914 const CGEN_FIELDS * fields;
916 bfd_vma value;
918 switch (opindex)
920 case M32R_OPERAND_ACC :
921 value = fields->f_acc;
922 break;
923 case M32R_OPERAND_ACCD :
924 value = fields->f_accd;
925 break;
926 case M32R_OPERAND_ACCS :
927 value = fields->f_accs;
928 break;
929 case M32R_OPERAND_DCR :
930 value = fields->f_r1;
931 break;
932 case M32R_OPERAND_DISP16 :
933 value = fields->f_disp16;
934 break;
935 case M32R_OPERAND_DISP24 :
936 value = fields->f_disp24;
937 break;
938 case M32R_OPERAND_DISP8 :
939 value = fields->f_disp8;
940 break;
941 case M32R_OPERAND_DR :
942 value = fields->f_r1;
943 break;
944 case M32R_OPERAND_HASH :
945 value = 0;
946 break;
947 case M32R_OPERAND_HI16 :
948 value = fields->f_hi16;
949 break;
950 case M32R_OPERAND_IMM1 :
951 value = fields->f_imm1;
952 break;
953 case M32R_OPERAND_SCR :
954 value = fields->f_r2;
955 break;
956 case M32R_OPERAND_SIMM16 :
957 value = fields->f_simm16;
958 break;
959 case M32R_OPERAND_SIMM8 :
960 value = fields->f_simm8;
961 break;
962 case M32R_OPERAND_SLO16 :
963 value = fields->f_simm16;
964 break;
965 case M32R_OPERAND_SR :
966 value = fields->f_r2;
967 break;
968 case M32R_OPERAND_SRC1 :
969 value = fields->f_r1;
970 break;
971 case M32R_OPERAND_SRC2 :
972 value = fields->f_r2;
973 break;
974 case M32R_OPERAND_UIMM16 :
975 value = fields->f_uimm16;
976 break;
977 case M32R_OPERAND_UIMM24 :
978 value = fields->f_uimm24;
979 break;
980 case M32R_OPERAND_UIMM4 :
981 value = fields->f_uimm4;
982 break;
983 case M32R_OPERAND_UIMM5 :
984 value = fields->f_uimm5;
985 break;
986 case M32R_OPERAND_ULO16 :
987 value = fields->f_uimm16;
988 break;
990 default :
991 /* xgettext:c-format */
992 fprintf (stderr, _("Unrecognized field %d while getting vma operand.\n"),
993 opindex);
994 abort ();
997 return value;
1000 void m32r_cgen_set_int_operand
1001 PARAMS ((CGEN_CPU_DESC, int, CGEN_FIELDS *, int));
1002 void m32r_cgen_set_vma_operand
1003 PARAMS ((CGEN_CPU_DESC, int, CGEN_FIELDS *, bfd_vma));
1005 /* Stuffing values in cgen_fields is handled by a collection of functions.
1006 They are distinguished by the type of the VALUE argument they accept.
1007 TODO: floating point, inlining support, remove cases where argument type
1008 not appropriate. */
1010 void
1011 m32r_cgen_set_int_operand (cd, opindex, fields, value)
1012 CGEN_CPU_DESC cd ATTRIBUTE_UNUSED;
1013 int opindex;
1014 CGEN_FIELDS * fields;
1015 int value;
1017 switch (opindex)
1019 case M32R_OPERAND_ACC :
1020 fields->f_acc = value;
1021 break;
1022 case M32R_OPERAND_ACCD :
1023 fields->f_accd = value;
1024 break;
1025 case M32R_OPERAND_ACCS :
1026 fields->f_accs = value;
1027 break;
1028 case M32R_OPERAND_DCR :
1029 fields->f_r1 = value;
1030 break;
1031 case M32R_OPERAND_DISP16 :
1032 fields->f_disp16 = value;
1033 break;
1034 case M32R_OPERAND_DISP24 :
1035 fields->f_disp24 = value;
1036 break;
1037 case M32R_OPERAND_DISP8 :
1038 fields->f_disp8 = value;
1039 break;
1040 case M32R_OPERAND_DR :
1041 fields->f_r1 = value;
1042 break;
1043 case M32R_OPERAND_HASH :
1044 break;
1045 case M32R_OPERAND_HI16 :
1046 fields->f_hi16 = value;
1047 break;
1048 case M32R_OPERAND_IMM1 :
1049 fields->f_imm1 = value;
1050 break;
1051 case M32R_OPERAND_SCR :
1052 fields->f_r2 = value;
1053 break;
1054 case M32R_OPERAND_SIMM16 :
1055 fields->f_simm16 = value;
1056 break;
1057 case M32R_OPERAND_SIMM8 :
1058 fields->f_simm8 = value;
1059 break;
1060 case M32R_OPERAND_SLO16 :
1061 fields->f_simm16 = value;
1062 break;
1063 case M32R_OPERAND_SR :
1064 fields->f_r2 = value;
1065 break;
1066 case M32R_OPERAND_SRC1 :
1067 fields->f_r1 = value;
1068 break;
1069 case M32R_OPERAND_SRC2 :
1070 fields->f_r2 = value;
1071 break;
1072 case M32R_OPERAND_UIMM16 :
1073 fields->f_uimm16 = value;
1074 break;
1075 case M32R_OPERAND_UIMM24 :
1076 fields->f_uimm24 = value;
1077 break;
1078 case M32R_OPERAND_UIMM4 :
1079 fields->f_uimm4 = value;
1080 break;
1081 case M32R_OPERAND_UIMM5 :
1082 fields->f_uimm5 = value;
1083 break;
1084 case M32R_OPERAND_ULO16 :
1085 fields->f_uimm16 = value;
1086 break;
1088 default :
1089 /* xgettext:c-format */
1090 fprintf (stderr, _("Unrecognized field %d while setting int operand.\n"),
1091 opindex);
1092 abort ();
1096 void
1097 m32r_cgen_set_vma_operand (cd, opindex, fields, value)
1098 CGEN_CPU_DESC cd ATTRIBUTE_UNUSED;
1099 int opindex;
1100 CGEN_FIELDS * fields;
1101 bfd_vma value;
1103 switch (opindex)
1105 case M32R_OPERAND_ACC :
1106 fields->f_acc = value;
1107 break;
1108 case M32R_OPERAND_ACCD :
1109 fields->f_accd = value;
1110 break;
1111 case M32R_OPERAND_ACCS :
1112 fields->f_accs = value;
1113 break;
1114 case M32R_OPERAND_DCR :
1115 fields->f_r1 = value;
1116 break;
1117 case M32R_OPERAND_DISP16 :
1118 fields->f_disp16 = value;
1119 break;
1120 case M32R_OPERAND_DISP24 :
1121 fields->f_disp24 = value;
1122 break;
1123 case M32R_OPERAND_DISP8 :
1124 fields->f_disp8 = value;
1125 break;
1126 case M32R_OPERAND_DR :
1127 fields->f_r1 = value;
1128 break;
1129 case M32R_OPERAND_HASH :
1130 break;
1131 case M32R_OPERAND_HI16 :
1132 fields->f_hi16 = value;
1133 break;
1134 case M32R_OPERAND_IMM1 :
1135 fields->f_imm1 = value;
1136 break;
1137 case M32R_OPERAND_SCR :
1138 fields->f_r2 = value;
1139 break;
1140 case M32R_OPERAND_SIMM16 :
1141 fields->f_simm16 = value;
1142 break;
1143 case M32R_OPERAND_SIMM8 :
1144 fields->f_simm8 = value;
1145 break;
1146 case M32R_OPERAND_SLO16 :
1147 fields->f_simm16 = value;
1148 break;
1149 case M32R_OPERAND_SR :
1150 fields->f_r2 = value;
1151 break;
1152 case M32R_OPERAND_SRC1 :
1153 fields->f_r1 = value;
1154 break;
1155 case M32R_OPERAND_SRC2 :
1156 fields->f_r2 = value;
1157 break;
1158 case M32R_OPERAND_UIMM16 :
1159 fields->f_uimm16 = value;
1160 break;
1161 case M32R_OPERAND_UIMM24 :
1162 fields->f_uimm24 = value;
1163 break;
1164 case M32R_OPERAND_UIMM4 :
1165 fields->f_uimm4 = value;
1166 break;
1167 case M32R_OPERAND_UIMM5 :
1168 fields->f_uimm5 = value;
1169 break;
1170 case M32R_OPERAND_ULO16 :
1171 fields->f_uimm16 = value;
1172 break;
1174 default :
1175 /* xgettext:c-format */
1176 fprintf (stderr, _("Unrecognized field %d while setting vma operand.\n"),
1177 opindex);
1178 abort ();
1182 /* Function to call before using the instruction builder tables. */
1184 void
1185 m32r_cgen_init_ibld_table (cd)
1186 CGEN_CPU_DESC cd;
1188 cd->insert_handlers = & m32r_cgen_insert_handlers[0];
1189 cd->extract_handlers = & m32r_cgen_extract_handlers[0];
1191 cd->insert_operand = m32r_cgen_insert_operand;
1192 cd->extract_operand = m32r_cgen_extract_operand;
1194 cd->get_int_operand = m32r_cgen_get_int_operand;
1195 cd->set_int_operand = m32r_cgen_set_int_operand;
1196 cd->get_vma_operand = m32r_cgen_get_vma_operand;
1197 cd->set_vma_operand = m32r_cgen_set_vma_operand;