2000-08-28 Kazu Hirata <kazu@hxi.com>
[deliverable/binutils-gdb.git] / opcodes / m32r-ibld.c
CommitLineData
252b5132
RH
1/* Instruction building/extraction support for m32r. -*- C -*-
2
3THIS FILE IS MACHINE GENERATED WITH CGEN: Cpu tools GENerator.
4- the resultant file is machine generated, cgen-ibld.in isn't
5
cfcdbe97 6Copyright (C) 1996, 1997, 1998, 1999, 2000 Free Software Foundation, Inc.
252b5132
RH
7
8This file is part of the GNU Binutils and GDB, the GNU debugger.
9
10This program is free software; you can redistribute it and/or modify
11it under the terms of the GNU General Public License as published by
12the Free Software Foundation; either version 2, or (at your option)
13any later version.
14
15This program is distributed in the hope that it will be useful,
16but WITHOUT ANY WARRANTY; without even the implied warranty of
17MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18GNU General Public License for more details.
19
20You should have received a copy of the GNU General Public License
21along with this program; if not, write to the Free Software Foundation, Inc.,
2259 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
23
24/* ??? Eventually more and more of this stuff can go to cpu-independent files.
25 Keep that in mind. */
26
27#include "sysdep.h"
28#include <ctype.h>
29#include <stdio.h>
30#include "ansidecl.h"
31#include "dis-asm.h"
32#include "bfd.h"
33#include "symcat.h"
34#include "m32r-desc.h"
35#include "m32r-opc.h"
36#include "opintl.h"
37
38#undef min
39#define min(a,b) ((a) < (b) ? (a) : (b))
40#undef max
41#define max(a,b) ((a) > (b) ? (a) : (b))
42
43/* Used by the ifield rtx function. */
44#define FLD(f) (fields->f)
45
46static const char * insert_normal
47 PARAMS ((CGEN_CPU_DESC, long, unsigned int, unsigned int, unsigned int,
48 unsigned int, unsigned int, unsigned int, CGEN_INSN_BYTES_PTR));
49static const char * insert_insn_normal
50 PARAMS ((CGEN_CPU_DESC, const CGEN_INSN *,
51 CGEN_FIELDS *, CGEN_INSN_BYTES_PTR, bfd_vma));
52
53static int extract_normal
54 PARAMS ((CGEN_CPU_DESC, CGEN_EXTRACT_INFO *, CGEN_INSN_INT,
55 unsigned int, unsigned int, unsigned int, unsigned int,
56 unsigned int, unsigned int, bfd_vma, long *));
57static int extract_insn_normal
58 PARAMS ((CGEN_CPU_DESC, const CGEN_INSN *, CGEN_EXTRACT_INFO *,
59 CGEN_INSN_INT, CGEN_FIELDS *, bfd_vma));
60\f
61/* Operand insertion. */
62
63#if ! CGEN_INT_INSN_P
64
65/* Subroutine of insert_normal. */
66
67static CGEN_INLINE void
68insert_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;
73{
74 unsigned long x,mask;
75 int shift;
76 int big_p = CGEN_CPU_INSN_ENDIAN (cd) == CGEN_ENDIAN_BIG;
77
78 switch (word_length)
79 {
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 ();
105 }
106
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);
114
115 switch (word_length)
116 {
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)
130 {
131 bufp[0] = x >> 16;
132 bfd_putb16 (x, bufp + 1);
133 }
134 else
135 {
136 bfd_putl16 (x, bufp);
137 bufp[2] = x >> 16;
138 }
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 ();
148 }
149}
150
151#endif /* ! CGEN_INT_INSN_P */
152
153/* Default insertion routine.
154
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.
161
162 The result is an error message or NULL if success. */
163
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. */
168
169static const char *
170insert_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;
177{
178 static char errbuf[100];
179 /* Written this way to avoid undefined behaviour. */
180 unsigned long mask = (((1L << (length - 1)) - 1) << 1) | 1;
181
182 /* If LENGTH is zero, this operand doesn't contribute to the value. */
183 if (length == 0)
184 return NULL;
185
186 if (CGEN_INT_INSN_P
187 && word_offset != 0)
188 abort ();
189
190 if (word_length > 32)
191 abort ();
192
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)
196 {
197 if (word_offset == 0
198 && word_length > total_length)
199 word_length = total_length;
200 }
201
202 /* Ensure VALUE will fit. */
203 if (! CGEN_BOOL_ATTR (attrs, CGEN_IFLD_SIGNED))
204 {
205 unsigned long maxval = mask;
cfcdbe97 206
252b5132
RH
207 if ((unsigned long) value > maxval)
208 {
209 /* xgettext:c-format */
210 sprintf (errbuf,
211 _("operand out of range (%lu not between 0 and %lu)"),
212 value, maxval);
213 return errbuf;
214 }
215 }
216 else
217 {
cfcdbe97 218 if (! cgen_signed_overflow_ok_p (cd))
252b5132 219 {
cfcdbe97
AH
220 long minval = - (1L << (length - 1));
221 long maxval = (1L << (length - 1)) - 1;
222
223 if (value < minval || value > maxval)
224 {
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;
230 }
252b5132
RH
231 }
232 }
233
234#if CGEN_INT_INSN_P
235
236 {
237 int shift;
238
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);
244 }
245
246#else /* ! CGEN_INT_INSN_P */
247
248 {
249 unsigned char *bufp = (unsigned char *) buffer + word_offset / 8;
250
251 insert_1 (cd, value, start, length, word_length, bufp);
252 }
253
254#endif /* ! CGEN_INT_INSN_P */
255
256 return NULL;
257}
258
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. */
265
266static const char *
267insert_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;
273{
274 const CGEN_SYNTAX *syntax = CGEN_INSN_SYNTAX (insn);
275 unsigned long value;
276 const unsigned char * syn;
277
278 CGEN_INIT_INSERT (cd);
279 value = CGEN_INSN_BASE_VALUE (insn);
280
281 /* If we're recording insns as numbers (rather than a string of bytes),
282 target byte order handling is deferred until later. */
283
284#if CGEN_INT_INSN_P
285
286 *buffer = value;
287
288#else
289
290 cgen_put_insn_value (cd, buffer, min (cd->base_insn_bitsize,
291 CGEN_FIELDS_BITSIZE (fields)),
292 value);
293
294#endif /* ! CGEN_INT_INSN_P */
295
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. */
300
301 for (syn = CGEN_SYNTAX_STRING (syntax); * syn != '\0'; ++ syn)
302 {
303 const char *errmsg;
304
305 if (CGEN_SYNTAX_CHAR_P (* syn))
306 continue;
307
308 errmsg = (* cd->insert_operand) (cd, CGEN_SYNTAX_FIELD (*syn),
309 fields, buffer, pc);
310 if (errmsg)
311 return errmsg;
312 }
313
314 return NULL;
315}
316\f
317/* Operand extraction. */
318
319#if ! CGEN_INT_INSN_P
320
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. */
326
327static CGEN_INLINE int
328fill_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;
333{
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;
338
339 /* First do a quick check. */
340 mask = (1 << bytes) - 1;
341 if (((ex_info->valid >> offset) & mask) == mask)
342 return 1;
343
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;
348
349 if (bytes)
350 {
351 int status;
352
353 pc += offset;
354 status = (*info->read_memory_func)
355 (pc, ex_info->insn_bytes + offset, bytes, info);
356
357 if (status != 0)
358 {
359 (*info->memory_error_func) (status, pc, info);
360 return 0;
361 }
362
363 ex_info->valid |= ((1 << bytes) - 1) << offset;
364 }
365
366 return 1;
367}
368
369/* Subroutine of extract_normal. */
370
371static CGEN_INLINE long
372extract_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;
378{
379 unsigned long x,mask;
380 int shift;
381 int big_p = CGEN_CPU_INSN_ENDIAN (cd) == CGEN_ENDIAN_BIG;
382
383 switch (word_length)
384 {
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 ();
410 }
411
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;
419}
420
421#endif /* ! CGEN_INT_INSN_P */
422
423/* Default extraction routine.
424
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.
435
436 Returns 1 for success, 0 for failure. */
437
438/* ??? The return code isn't properly used. wip. */
439
440/* ??? This doesn't handle bfd_vma's. Create another function when
441 necessary. */
442
443static int
444extract_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;
453{
454 CGEN_INSN_INT value;
455
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)
459 {
460 *valuep = 0;
461 return 1;
462 }
463
464 if (CGEN_INT_INSN_P
465 && word_offset != 0)
466 abort ();
467
468 if (word_length > 32)
469 abort ();
470
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)
474 {
475 if (word_offset == 0
476 && word_length > total_length)
477 word_length = total_length;
478 }
479
480 /* Does the value reside in INSN_VALUE? */
481
482 if (word_offset == 0)
483 {
484 /* Written this way to avoid undefined behaviour. */
485 CGEN_INSN_INT mask = (((1L << (length - 1)) - 1) << 1) | 1;
486
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;
496 }
497
498#if ! CGEN_INT_INSN_P
499
500 else
501 {
502 unsigned char *bufp = ex_info->insn_bytes + word_offset / 8;
503
504 if (word_length > 32)
505 abort ();
506
507 if (fill_cache (cd, ex_info, word_offset / 8, word_length / 8, pc) == 0)
508 return 0;
509
510 value = extract_1 (cd, ex_info, start, length, word_length, bufp, pc);
511 }
512
513#endif /* ! CGEN_INT_INSN_P */
514
515 *valuep = value;
516
517 return 1;
518}
519
520/* Default insn extractor.
521
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). */
528
529static int
530extract_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;
537{
538 const CGEN_SYNTAX *syntax = CGEN_INSN_SYNTAX (insn);
539 const unsigned char *syn;
540
541 CGEN_FIELDS_BITSIZE (fields) = CGEN_INSN_BITSIZE (insn);
542
543 CGEN_INIT_EXTRACT (cd);
544
545 for (syn = CGEN_SYNTAX_STRING (syntax); *syn; ++syn)
546 {
547 int length;
548
549 if (CGEN_SYNTAX_CHAR_P (*syn))
550 continue;
551
552 length = (* cd->extract_operand) (cd, CGEN_SYNTAX_FIELD (*syn),
553 ex_info, insn_value, fields, pc);
554 if (length <= 0)
555 return length;
556 }
557
558 /* We recognized and successfully extracted this insn. */
559 return CGEN_INSN_BITSIZE (insn);
560}
561\f
562/* machine generated code added here */
563
564/* Main entry point for operand insertion.
565
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.
572
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.
577*/
578
579const char *
580m32r_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;
586{
eb1b03df 587 const char * errmsg = NULL;
252b5132
RH
588 unsigned int total_length = CGEN_FIELDS_BITSIZE (fields);
589
590 switch (opindex)
591 {
1fa60b5d
DE
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;
252b5132
RH
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 :
605 {
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);
609 }
610 break;
611 case M32R_OPERAND_DISP24 :
612 {
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);
616 }
617 break;
618 case M32R_OPERAND_DISP8 :
619 {
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);
623 }
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 :
252b5132
RH
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;
1fa60b5d
DE
633 case M32R_OPERAND_IMM1 :
634 {
635 long value = fields->f_imm1;
636 value = ((value) - (1));
637 errmsg = insert_normal (cd, value, 0, 0, 15, 1, 32, total_length, buffer);
638 }
639 break;
252b5132
RH
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;
676
677 default :
678 /* xgettext:c-format */
679 fprintf (stderr, _("Unrecognized field %d while building insn.\n"),
680 opindex);
681 abort ();
682 }
683
684 return errmsg;
685}
686
687/* Main entry point for operand extraction.
eb1b03df
DE
688 The result is <= 0 for error, >0 for success.
689 ??? Actual values aren't well defined right now.
252b5132
RH
690
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.
697
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.
701*/
702
703int
704m32r_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;
711{
eb1b03df
DE
712 /* Assume success (for those operands that are nops). */
713 int length = 1;
252b5132
RH
714 unsigned int total_length = CGEN_FIELDS_BITSIZE (fields);
715
716 switch (opindex)
717 {
1fa60b5d
DE
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;
252b5132
RH
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 :
731 {
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;
736 }
737 break;
738 case M32R_OPERAND_DISP24 :
739 {
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;
744 }
745 break;
746 case M32R_OPERAND_DISP8 :
747 {
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;
752 }
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 :
252b5132
RH
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;
1fa60b5d
DE
762 case M32R_OPERAND_IMM1 :
763 {
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;
768 }
769 break;
252b5132
RH
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;
806
807 default :
808 /* xgettext:c-format */
809 fprintf (stderr, _("Unrecognized field %d while decoding insn.\n"),
810 opindex);
811 abort ();
812 }
813
814 return length;
815}
816
817cgen_insert_fn * const m32r_cgen_insert_handlers[] =
818{
819 insert_insn_normal,
820};
821
822cgen_extract_fn * const m32r_cgen_extract_handlers[] =
823{
824 extract_insn_normal,
825};
826
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. */
831
832int
833m32r_cgen_get_int_operand (cd, opindex, fields)
834 CGEN_CPU_DESC cd;
835 int opindex;
836 const CGEN_FIELDS * fields;
837{
838 int value;
839
840 switch (opindex)
841 {
1fa60b5d
DE
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;
252b5132
RH
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 :
eb1b03df 867 value = 0;
252b5132
RH
868 break;
869 case M32R_OPERAND_HI16 :
870 value = fields->f_hi16;
871 break;
1fa60b5d
DE
872 case M32R_OPERAND_IMM1 :
873 value = fields->f_imm1;
874 break;
252b5132
RH
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;
911
912 default :
913 /* xgettext:c-format */
914 fprintf (stderr, _("Unrecognized field %d while getting int operand.\n"),
915 opindex);
916 abort ();
917 }
918
919 return value;
920}
921
922bfd_vma
923m32r_cgen_get_vma_operand (cd, opindex, fields)
924 CGEN_CPU_DESC cd;
925 int opindex;
926 const CGEN_FIELDS * fields;
927{
928 bfd_vma value;
929
930 switch (opindex)
931 {
1fa60b5d
DE
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;
252b5132
RH
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 :
eb1b03df 957 value = 0;
252b5132
RH
958 break;
959 case M32R_OPERAND_HI16 :
960 value = fields->f_hi16;
961 break;
1fa60b5d
DE
962 case M32R_OPERAND_IMM1 :
963 value = fields->f_imm1;
964 break;
252b5132
RH
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;
1001
1002 default :
1003 /* xgettext:c-format */
1004 fprintf (stderr, _("Unrecognized field %d while getting vma operand.\n"),
1005 opindex);
1006 abort ();
1007 }
1008
1009 return value;
1010}
1011
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. */
1016
1017void
1018m32r_cgen_set_int_operand (cd, opindex, fields, value)
1019 CGEN_CPU_DESC cd;
1020 int opindex;
1021 CGEN_FIELDS * fields;
1022 int value;
1023{
1024 switch (opindex)
1025 {
1fa60b5d
DE
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;
252b5132
RH
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 :
252b5132
RH
1051 break;
1052 case M32R_OPERAND_HI16 :
1053 fields->f_hi16 = value;
1054 break;
1fa60b5d
DE
1055 case M32R_OPERAND_IMM1 :
1056 fields->f_imm1 = value;
1057 break;
252b5132
RH
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;
1094
1095 default :
1096 /* xgettext:c-format */
1097 fprintf (stderr, _("Unrecognized field %d while setting int operand.\n"),
1098 opindex);
1099 abort ();
1100 }
1101}
1102
1103void
1104m32r_cgen_set_vma_operand (cd, opindex, fields, value)
1105 CGEN_CPU_DESC cd;
1106 int opindex;
1107 CGEN_FIELDS * fields;
1108 bfd_vma value;
1109{
1110 switch (opindex)
1111 {
1fa60b5d
DE
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;
252b5132
RH
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 :
252b5132
RH
1137 break;
1138 case M32R_OPERAND_HI16 :
1139 fields->f_hi16 = value;
1140 break;
1fa60b5d
DE
1141 case M32R_OPERAND_IMM1 :
1142 fields->f_imm1 = value;
1143 break;
252b5132
RH
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;
1180
1181 default :
1182 /* xgettext:c-format */
1183 fprintf (stderr, _("Unrecognized field %d while setting vma operand.\n"),
1184 opindex);
1185 abort ();
1186 }
1187}
1188
1189/* Function to call before using the instruction builder tables. */
1190
1191void
1192m32r_cgen_init_ibld_table (cd)
1193 CGEN_CPU_DESC cd;
1194{
1195 cd->insert_handlers = & m32r_cgen_insert_handlers[0];
1196 cd->extract_handlers = & m32r_cgen_extract_handlers[0];
1197
1198 cd->insert_operand = m32r_cgen_insert_operand;
1199 cd->extract_operand = m32r_cgen_extract_operand;
1200
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;
1205}
This page took 0.09633 seconds and 4 git commands to generate.