]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - opcodes/m32r-ibld.c
* config/obj-elf.c: (obj_elf_change_section): Add "group" param.
[thirdparty/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
060d22b0 6Copyright 1996, 1997, 1998, 1999, 2000, 2001 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"
252b5132
RH
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
37#undef min
38#define min(a,b) ((a) < (b) ? (a) : (b))
39#undef max
40#define max(a,b) ((a) > (b) ? (a) : (b))
41
42/* Used by the ifield rtx function. */
43#define FLD(f) (fields->f)
44
45static const char * insert_normal
46 PARAMS ((CGEN_CPU_DESC, long, unsigned int, unsigned int, unsigned int,
47 unsigned int, unsigned int, unsigned int, CGEN_INSN_BYTES_PTR));
48static const char * insert_insn_normal
49 PARAMS ((CGEN_CPU_DESC, const CGEN_INSN *,
50 CGEN_FIELDS *, CGEN_INSN_BYTES_PTR, bfd_vma));
51
52static 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 *));
56static int extract_insn_normal
57 PARAMS ((CGEN_CPU_DESC, const CGEN_INSN *, CGEN_EXTRACT_INFO *,
58 CGEN_INSN_INT, CGEN_FIELDS *, bfd_vma));
f40c3ea3 59static void put_insn_int_value
6bb95a0f 60 PARAMS ((CGEN_CPU_DESC, CGEN_INSN_BYTES_PTR, int, int, CGEN_INSN_INT));
fc05c67f
NC
61const char * m32r_cgen_insert_operand
62 PARAMS ((CGEN_CPU_DESC, int, CGEN_FIELDS *, CGEN_INSN_BYTES_PTR, bfd_vma));
63int m32r_cgen_extract_operand
64 PARAMS ((CGEN_CPU_DESC, int, CGEN_EXTRACT_INFO *, CGEN_INSN_INT, CGEN_FIELDS *, bfd_vma));
65int m32r_cgen_get_int_operand
66 PARAMS ((CGEN_CPU_DESC, int, const CGEN_FIELDS *));
67bfd_vma m32r_cgen_get_vma_operand
68 PARAMS ((CGEN_CPU_DESC, int, const CGEN_FIELDS *));
69void m32r_cgen_set_int_operand
70 PARAMS ((CGEN_CPU_DESC, int, CGEN_FIELDS *, int));
71void m32r_cgen_set_vma_operand
72 PARAMS ((CGEN_CPU_DESC, int, CGEN_FIELDS *, bfd_vma));
252b5132
RH
73\f
74/* Operand insertion. */
75
76#if ! CGEN_INT_INSN_P
77
78/* Subroutine of insert_normal. */
79
80static CGEN_INLINE void
81insert_1 (cd, value, start, length, word_length, bufp)
82 CGEN_CPU_DESC cd;
83 unsigned long value;
84 int start,length,word_length;
85 unsigned char *bufp;
86{
87 unsigned long x,mask;
88 int shift;
89 int big_p = CGEN_CPU_INSN_ENDIAN (cd) == CGEN_ENDIAN_BIG;
90
b3466c39 91 x = bfd_get_bits (bufp, word_length, big_p);
252b5132
RH
92
93 /* Written this way to avoid undefined behaviour. */
94 mask = (((1L << (length - 1)) - 1) << 1) | 1;
95 if (CGEN_INSN_LSB0_P)
96 shift = (start + 1) - length;
97 else
98 shift = (word_length - (start + length));
99 x = (x & ~(mask << shift)) | ((value & mask) << shift);
100
b3466c39 101 bfd_put_bits ((bfd_vma) x, bufp, word_length, big_p);
252b5132
RH
102}
103
104#endif /* ! CGEN_INT_INSN_P */
105
106/* Default insertion routine.
107
108 ATTRS is a mask of the boolean attributes.
109 WORD_OFFSET is the offset in bits from the start of the insn of the value.
110 WORD_LENGTH is the length of the word in bits in which the value resides.
111 START is the starting bit number in the word, architecture origin.
112 LENGTH is the length of VALUE in bits.
113 TOTAL_LENGTH is the total length of the insn in bits.
114
115 The result is an error message or NULL if success. */
116
117/* ??? This duplicates functionality with bfd's howto table and
118 bfd_install_relocation. */
119/* ??? This doesn't handle bfd_vma's. Create another function when
120 necessary. */
121
122static const char *
123insert_normal (cd, value, attrs, word_offset, start, length, word_length,
124 total_length, buffer)
125 CGEN_CPU_DESC cd;
126 long value;
127 unsigned int attrs;
128 unsigned int word_offset, start, length, word_length, total_length;
129 CGEN_INSN_BYTES_PTR buffer;
130{
131 static char errbuf[100];
132 /* Written this way to avoid undefined behaviour. */
133 unsigned long mask = (((1L << (length - 1)) - 1) << 1) | 1;
134
135 /* If LENGTH is zero, this operand doesn't contribute to the value. */
136 if (length == 0)
137 return NULL;
138
6bb95a0f 139#if 0
252b5132
RH
140 if (CGEN_INT_INSN_P
141 && word_offset != 0)
142 abort ();
6bb95a0f 143#endif
252b5132
RH
144
145 if (word_length > 32)
146 abort ();
147
148 /* For architectures with insns smaller than the base-insn-bitsize,
149 word_length may be too big. */
150 if (cd->min_insn_bitsize < cd->base_insn_bitsize)
151 {
152 if (word_offset == 0
153 && word_length > total_length)
154 word_length = total_length;
155 }
156
157 /* Ensure VALUE will fit. */
fc7bc883
RH
158 if (CGEN_BOOL_ATTR (attrs, CGEN_IFLD_SIGN_OPT))
159 {
160 long minval = - (1L << (length - 1));
161 unsigned long maxval = mask;
162
163 if ((value > 0 && (unsigned long) value > maxval)
164 || value < minval)
165 {
166 /* xgettext:c-format */
167 sprintf (errbuf,
168 _("operand out of range (%ld not between %ld and %lu)"),
169 value, minval, maxval);
170 return errbuf;
171 }
172 }
173 else if (! CGEN_BOOL_ATTR (attrs, CGEN_IFLD_SIGNED))
252b5132
RH
174 {
175 unsigned long maxval = mask;
cfcdbe97 176
252b5132
RH
177 if ((unsigned long) value > maxval)
178 {
179 /* xgettext:c-format */
180 sprintf (errbuf,
181 _("operand out of range (%lu not between 0 and %lu)"),
182 value, maxval);
183 return errbuf;
184 }
185 }
186 else
187 {
cfcdbe97 188 if (! cgen_signed_overflow_ok_p (cd))
252b5132 189 {
cfcdbe97
AH
190 long minval = - (1L << (length - 1));
191 long maxval = (1L << (length - 1)) - 1;
192
193 if (value < minval || value > maxval)
194 {
195 sprintf
196 /* xgettext:c-format */
197 (errbuf, _("operand out of range (%ld not between %ld and %ld)"),
198 value, minval, maxval);
199 return errbuf;
200 }
252b5132
RH
201 }
202 }
203
204#if CGEN_INT_INSN_P
205
206 {
207 int shift;
208
209 if (CGEN_INSN_LSB0_P)
6bb95a0f 210 shift = (word_offset + start + 1) - length;
252b5132 211 else
6bb95a0f 212 shift = total_length - (word_offset + start + length);
252b5132
RH
213 *buffer = (*buffer & ~(mask << shift)) | ((value & mask) << shift);
214 }
215
216#else /* ! CGEN_INT_INSN_P */
217
218 {
219 unsigned char *bufp = (unsigned char *) buffer + word_offset / 8;
220
221 insert_1 (cd, value, start, length, word_length, bufp);
222 }
223
224#endif /* ! CGEN_INT_INSN_P */
225
226 return NULL;
227}
228
229/* Default insn builder (insert handler).
52646233
FCE
230 The instruction is recorded in CGEN_INT_INSN_P byte order (meaning
231 that if CGEN_INSN_BYTES_PTR is an int * and thus, the value is
232 recorded in host byte order, otherwise BUFFER is an array of bytes
233 and the value is recorded in target byte order).
252b5132
RH
234 The result is an error message or NULL if success. */
235
236static const char *
237insert_insn_normal (cd, insn, fields, buffer, pc)
238 CGEN_CPU_DESC cd;
239 const CGEN_INSN * insn;
240 CGEN_FIELDS * fields;
241 CGEN_INSN_BYTES_PTR buffer;
242 bfd_vma pc;
243{
244 const CGEN_SYNTAX *syntax = CGEN_INSN_SYNTAX (insn);
245 unsigned long value;
b3466c39 246 const CGEN_SYNTAX_CHAR_TYPE * syn;
252b5132
RH
247
248 CGEN_INIT_INSERT (cd);
249 value = CGEN_INSN_BASE_VALUE (insn);
250
251 /* If we're recording insns as numbers (rather than a string of bytes),
252 target byte order handling is deferred until later. */
253
254#if CGEN_INT_INSN_P
255
f40c3ea3
DB
256 put_insn_int_value (cd, buffer, cd->base_insn_bitsize,
257 CGEN_FIELDS_BITSIZE (fields), value);
252b5132
RH
258
259#else
260
261 cgen_put_insn_value (cd, buffer, min (cd->base_insn_bitsize,
262 CGEN_FIELDS_BITSIZE (fields)),
263 value);
264
265#endif /* ! CGEN_INT_INSN_P */
266
267 /* ??? It would be better to scan the format's fields.
268 Still need to be able to insert a value based on the operand though;
269 e.g. storing a branch displacement that got resolved later.
270 Needs more thought first. */
271
b3466c39 272 for (syn = CGEN_SYNTAX_STRING (syntax); * syn; ++ syn)
252b5132
RH
273 {
274 const char *errmsg;
275
276 if (CGEN_SYNTAX_CHAR_P (* syn))
277 continue;
278
279 errmsg = (* cd->insert_operand) (cd, CGEN_SYNTAX_FIELD (*syn),
280 fields, buffer, pc);
281 if (errmsg)
282 return errmsg;
283 }
284
285 return NULL;
286}
6bb95a0f
DB
287
288/* Cover function to store an insn value into an integral insn. Must go here
289 because it needs <prefix>-desc.h for CGEN_INT_INSN_P. */
290
f40c3ea3
DB
291static void
292put_insn_int_value (cd, buf, length, insn_length, value)
52646233 293 CGEN_CPU_DESC cd ATTRIBUTE_UNUSED;
6bb95a0f
DB
294 CGEN_INSN_BYTES_PTR buf;
295 int length;
296 int insn_length;
297 CGEN_INSN_INT value;
298{
299 /* For architectures with insns smaller than the base-insn-bitsize,
300 length may be too big. */
301 if (length > insn_length)
302 *buf = value;
303 else
304 {
305 int shift = insn_length - length;
306 /* Written this way to avoid undefined behaviour. */
307 CGEN_INSN_INT mask = (((1L << (length - 1)) - 1) << 1) | 1;
308 *buf = (*buf & ~(mask << shift)) | ((value & mask) << shift);
309 }
310}
252b5132
RH
311\f
312/* Operand extraction. */
313
314#if ! CGEN_INT_INSN_P
315
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. */
321
322static CGEN_INLINE int
323fill_cache (cd, ex_info, offset, bytes, pc)
324 CGEN_CPU_DESC cd;
325 CGEN_EXTRACT_INFO *ex_info;
326 int offset, bytes;
327 bfd_vma pc;
328{
329 /* It's doubtful that the middle part has already been fetched so
330 we don't optimize that case. kiss. */
331 int mask;
332 disassemble_info *info = (disassemble_info *) ex_info->dis_info;
333
334 /* First do a quick check. */
335 mask = (1 << bytes) - 1;
336 if (((ex_info->valid >> offset) & mask) == mask)
337 return 1;
338
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;
343
344 if (bytes)
345 {
346 int status;
347
348 pc += offset;
349 status = (*info->read_memory_func)
350 (pc, ex_info->insn_bytes + offset, bytes, info);
351
352 if (status != 0)
353 {
354 (*info->memory_error_func) (status, pc, info);
355 return 0;
356 }
357
358 ex_info->valid |= ((1 << bytes) - 1) << offset;
359 }
360
361 return 1;
362}
363
364/* Subroutine of extract_normal. */
365
366static CGEN_INLINE long
367extract_1 (cd, ex_info, start, length, word_length, bufp, pc)
368 CGEN_CPU_DESC cd;
369 CGEN_EXTRACT_INFO *ex_info;
370 int start,length,word_length;
371 unsigned char *bufp;
372 bfd_vma pc;
373{
b3466c39 374 unsigned long x;
252b5132
RH
375 int shift;
376 int big_p = CGEN_CPU_INSN_ENDIAN (cd) == CGEN_ENDIAN_BIG;
377
b3466c39 378 x = bfd_get_bits (bufp, word_length, big_p);
252b5132 379
252b5132
RH
380 if (CGEN_INSN_LSB0_P)
381 shift = (start + 1) - length;
382 else
383 shift = (word_length - (start + length));
b3466c39 384 return x >> shift;
252b5132
RH
385}
386
387#endif /* ! CGEN_INT_INSN_P */
388
389/* Default extraction routine.
390
391 INSN_VALUE is the first base_insn_bitsize bits of the insn in host order,
392 or sometimes less for cases like the m32r where the base insn size is 32
393 but some insns are 16 bits.
394 ATTRS is a mask of the boolean attributes. We only need `SIGNED',
395 but for generality we take a bitmask of all of them.
396 WORD_OFFSET is the offset in bits from the start of the insn of the value.
397 WORD_LENGTH is the length of the word in bits in which the value resides.
398 START is the starting bit number in the word, architecture origin.
399 LENGTH is the length of VALUE in bits.
400 TOTAL_LENGTH is the total length of the insn in bits.
401
402 Returns 1 for success, 0 for failure. */
403
404/* ??? The return code isn't properly used. wip. */
405
406/* ??? This doesn't handle bfd_vma's. Create another function when
407 necessary. */
408
409static int
410extract_normal (cd, ex_info, insn_value, attrs, word_offset, start, length,
411 word_length, total_length, pc, valuep)
412 CGEN_CPU_DESC cd;
6bb95a0f 413#if ! CGEN_INT_INSN_P
252b5132 414 CGEN_EXTRACT_INFO *ex_info;
6bb95a0f
DB
415#else
416 CGEN_EXTRACT_INFO *ex_info ATTRIBUTE_UNUSED;
417#endif
252b5132
RH
418 CGEN_INSN_INT insn_value;
419 unsigned int attrs;
420 unsigned int word_offset, start, length, word_length, total_length;
6bb95a0f 421#if ! CGEN_INT_INSN_P
252b5132 422 bfd_vma pc;
6bb95a0f
DB
423#else
424 bfd_vma pc ATTRIBUTE_UNUSED;
425#endif
252b5132
RH
426 long *valuep;
427{
fc7bc883 428 long value, mask;
252b5132
RH
429
430 /* If LENGTH is zero, this operand doesn't contribute to the value
431 so give it a standard value of zero. */
432 if (length == 0)
433 {
434 *valuep = 0;
435 return 1;
436 }
437
6bb95a0f 438#if 0
252b5132
RH
439 if (CGEN_INT_INSN_P
440 && word_offset != 0)
441 abort ();
6bb95a0f 442#endif
252b5132
RH
443
444 if (word_length > 32)
445 abort ();
446
447 /* For architectures with insns smaller than the insn-base-bitsize,
448 word_length may be too big. */
449 if (cd->min_insn_bitsize < cd->base_insn_bitsize)
450 {
451 if (word_offset == 0
452 && word_length > total_length)
453 word_length = total_length;
454 }
455
fc7bc883 456 /* Does the value reside in INSN_VALUE, and at the right alignment? */
252b5132 457
fc7bc883 458 if (CGEN_INT_INSN_P || (word_offset == 0 && word_length == total_length))
252b5132 459 {
252b5132 460 if (CGEN_INSN_LSB0_P)
6bb95a0f 461 value = insn_value >> ((word_offset + start + 1) - length);
252b5132 462 else
6bb95a0f 463 value = insn_value >> (total_length - ( word_offset + start + length));
252b5132
RH
464 }
465
466#if ! CGEN_INT_INSN_P
467
468 else
469 {
470 unsigned char *bufp = ex_info->insn_bytes + word_offset / 8;
471
472 if (word_length > 32)
473 abort ();
474
475 if (fill_cache (cd, ex_info, word_offset / 8, word_length / 8, pc) == 0)
476 return 0;
477
478 value = extract_1 (cd, ex_info, start, length, word_length, bufp, pc);
479 }
480
481#endif /* ! CGEN_INT_INSN_P */
482
b3466c39
DB
483 /* Written this way to avoid undefined behaviour. */
484 mask = (((1L << (length - 1)) - 1) << 1) | 1;
485
486 value &= mask;
487 /* sign extend? */
488 if (CGEN_BOOL_ATTR (attrs, CGEN_IFLD_SIGNED)
489 && (value & (1L << (length - 1))))
490 value |= ~mask;
491
252b5132
RH
492 *valuep = value;
493
494 return 1;
495}
496
497/* Default insn extractor.
498
499 INSN_VALUE is the first base_insn_bitsize bits, translated to host order.
500 The extracted fields are stored in FIELDS.
501 EX_INFO is used to handle reading variable length insns.
502 Return the length of the insn in bits, or 0 if no match,
503 or -1 if an error occurs fetching data (memory_error_func will have
504 been called). */
505
506static int
507extract_insn_normal (cd, insn, ex_info, insn_value, fields, pc)
508 CGEN_CPU_DESC cd;
509 const CGEN_INSN *insn;
510 CGEN_EXTRACT_INFO *ex_info;
511 CGEN_INSN_INT insn_value;
512 CGEN_FIELDS *fields;
513 bfd_vma pc;
514{
515 const CGEN_SYNTAX *syntax = CGEN_INSN_SYNTAX (insn);
b3466c39 516 const CGEN_SYNTAX_CHAR_TYPE *syn;
252b5132
RH
517
518 CGEN_FIELDS_BITSIZE (fields) = CGEN_INSN_BITSIZE (insn);
519
520 CGEN_INIT_EXTRACT (cd);
521
522 for (syn = CGEN_SYNTAX_STRING (syntax); *syn; ++syn)
523 {
524 int length;
525
526 if (CGEN_SYNTAX_CHAR_P (*syn))
527 continue;
528
529 length = (* cd->extract_operand) (cd, CGEN_SYNTAX_FIELD (*syn),
530 ex_info, insn_value, fields, pc);
531 if (length <= 0)
532 return length;
533 }
534
535 /* We recognized and successfully extracted this insn. */
536 return CGEN_INSN_BITSIZE (insn);
537}
538\f
539/* machine generated code added here */
540
541/* Main entry point for operand insertion.
542
543 This function is basically just a big switch statement. Earlier versions
544 used tables to look up the function to use, but
545 - if the table contains both assembler and disassembler functions then
546 the disassembler contains much of the assembler and vice-versa,
547 - there's a lot of inlining possibilities as things grow,
548 - using a switch statement avoids the function call overhead.
549
550 This function could be moved into `parse_insn_normal', but keeping it
551 separate makes clear the interface between `parse_insn_normal' and each of
552 the handlers. It's also needed by GAS to insert operands that couldn't be
553 resolved during parsing.
554*/
555
556const char *
557m32r_cgen_insert_operand (cd, opindex, fields, buffer, pc)
558 CGEN_CPU_DESC cd;
559 int opindex;
560 CGEN_FIELDS * fields;
561 CGEN_INSN_BYTES_PTR buffer;
562 bfd_vma pc;
563{
eb1b03df 564 const char * errmsg = NULL;
252b5132
RH
565 unsigned int total_length = CGEN_FIELDS_BITSIZE (fields);
566
567 switch (opindex)
568 {
1fa60b5d
DE
569 case M32R_OPERAND_ACC :
570 errmsg = insert_normal (cd, fields->f_acc, 0, 0, 8, 1, 32, total_length, buffer);
571 break;
572 case M32R_OPERAND_ACCD :
573 errmsg = insert_normal (cd, fields->f_accd, 0, 0, 4, 2, 32, total_length, buffer);
574 break;
575 case M32R_OPERAND_ACCS :
576 errmsg = insert_normal (cd, fields->f_accs, 0, 0, 12, 2, 32, total_length, buffer);
577 break;
252b5132
RH
578 case M32R_OPERAND_DCR :
579 errmsg = insert_normal (cd, fields->f_r1, 0, 0, 4, 4, 32, total_length, buffer);
580 break;
581 case M32R_OPERAND_DISP16 :
582 {
583 long value = fields->f_disp16;
584 value = ((int) (((value) - (pc))) >> (2));
585 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);
586 }
587 break;
588 case M32R_OPERAND_DISP24 :
589 {
590 long value = fields->f_disp24;
591 value = ((int) (((value) - (pc))) >> (2));
592 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);
593 }
594 break;
595 case M32R_OPERAND_DISP8 :
596 {
597 long value = fields->f_disp8;
598 value = ((int) (((value) - (((pc) & (-4))))) >> (2));
599 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);
600 }
601 break;
602 case M32R_OPERAND_DR :
603 errmsg = insert_normal (cd, fields->f_r1, 0, 0, 4, 4, 32, total_length, buffer);
604 break;
605 case M32R_OPERAND_HASH :
252b5132
RH
606 break;
607 case M32R_OPERAND_HI16 :
608 errmsg = insert_normal (cd, fields->f_hi16, 0|(1<<CGEN_IFLD_SIGN_OPT), 0, 16, 16, 32, total_length, buffer);
609 break;
1fa60b5d
DE
610 case M32R_OPERAND_IMM1 :
611 {
612 long value = fields->f_imm1;
613 value = ((value) - (1));
614 errmsg = insert_normal (cd, value, 0, 0, 15, 1, 32, total_length, buffer);
615 }
616 break;
252b5132
RH
617 case M32R_OPERAND_SCR :
618 errmsg = insert_normal (cd, fields->f_r2, 0, 0, 12, 4, 32, total_length, buffer);
619 break;
620 case M32R_OPERAND_SIMM16 :
621 errmsg = insert_normal (cd, fields->f_simm16, 0|(1<<CGEN_IFLD_SIGNED), 0, 16, 16, 32, total_length, buffer);
622 break;
623 case M32R_OPERAND_SIMM8 :
624 errmsg = insert_normal (cd, fields->f_simm8, 0|(1<<CGEN_IFLD_SIGNED), 0, 8, 8, 32, total_length, buffer);
625 break;
626 case M32R_OPERAND_SLO16 :
627 errmsg = insert_normal (cd, fields->f_simm16, 0|(1<<CGEN_IFLD_SIGNED), 0, 16, 16, 32, total_length, buffer);
628 break;
629 case M32R_OPERAND_SR :
630 errmsg = insert_normal (cd, fields->f_r2, 0, 0, 12, 4, 32, total_length, buffer);
631 break;
632 case M32R_OPERAND_SRC1 :
633 errmsg = insert_normal (cd, fields->f_r1, 0, 0, 4, 4, 32, total_length, buffer);
634 break;
635 case M32R_OPERAND_SRC2 :
636 errmsg = insert_normal (cd, fields->f_r2, 0, 0, 12, 4, 32, total_length, buffer);
637 break;
638 case M32R_OPERAND_UIMM16 :
639 errmsg = insert_normal (cd, fields->f_uimm16, 0, 0, 16, 16, 32, total_length, buffer);
640 break;
641 case M32R_OPERAND_UIMM24 :
642 errmsg = insert_normal (cd, fields->f_uimm24, 0|(1<<CGEN_IFLD_RELOC)|(1<<CGEN_IFLD_ABS_ADDR), 0, 8, 24, 32, total_length, buffer);
643 break;
644 case M32R_OPERAND_UIMM4 :
645 errmsg = insert_normal (cd, fields->f_uimm4, 0, 0, 12, 4, 32, total_length, buffer);
646 break;
647 case M32R_OPERAND_UIMM5 :
648 errmsg = insert_normal (cd, fields->f_uimm5, 0, 0, 11, 5, 32, total_length, buffer);
649 break;
650 case M32R_OPERAND_ULO16 :
651 errmsg = insert_normal (cd, fields->f_uimm16, 0, 0, 16, 16, 32, total_length, buffer);
652 break;
653
654 default :
655 /* xgettext:c-format */
656 fprintf (stderr, _("Unrecognized field %d while building insn.\n"),
657 opindex);
658 abort ();
659 }
660
661 return errmsg;
662}
663
664/* Main entry point for operand extraction.
eb1b03df
DE
665 The result is <= 0 for error, >0 for success.
666 ??? Actual values aren't well defined right now.
252b5132
RH
667
668 This function is basically just a big switch statement. Earlier versions
669 used tables to look up the function to use, but
670 - if the table contains both assembler and disassembler functions then
671 the disassembler contains much of the assembler and vice-versa,
672 - there's a lot of inlining possibilities as things grow,
673 - using a switch statement avoids the function call overhead.
674
675 This function could be moved into `print_insn_normal', but keeping it
676 separate makes clear the interface between `print_insn_normal' and each of
677 the handlers.
678*/
679
680int
681m32r_cgen_extract_operand (cd, opindex, ex_info, insn_value, fields, pc)
682 CGEN_CPU_DESC cd;
683 int opindex;
684 CGEN_EXTRACT_INFO *ex_info;
685 CGEN_INSN_INT insn_value;
686 CGEN_FIELDS * fields;
687 bfd_vma pc;
688{
eb1b03df
DE
689 /* Assume success (for those operands that are nops). */
690 int length = 1;
252b5132
RH
691 unsigned int total_length = CGEN_FIELDS_BITSIZE (fields);
692
693 switch (opindex)
694 {
1fa60b5d
DE
695 case M32R_OPERAND_ACC :
696 length = extract_normal (cd, ex_info, insn_value, 0, 0, 8, 1, 32, total_length, pc, & fields->f_acc);
697 break;
698 case M32R_OPERAND_ACCD :
699 length = extract_normal (cd, ex_info, insn_value, 0, 0, 4, 2, 32, total_length, pc, & fields->f_accd);
700 break;
701 case M32R_OPERAND_ACCS :
702 length = extract_normal (cd, ex_info, insn_value, 0, 0, 12, 2, 32, total_length, pc, & fields->f_accs);
703 break;
252b5132
RH
704 case M32R_OPERAND_DCR :
705 length = extract_normal (cd, ex_info, insn_value, 0, 0, 4, 4, 32, total_length, pc, & fields->f_r1);
706 break;
707 case M32R_OPERAND_DISP16 :
708 {
709 long value;
710 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);
711 value = ((((value) << (2))) + (pc));
712 fields->f_disp16 = value;
713 }
714 break;
715 case M32R_OPERAND_DISP24 :
716 {
717 long value;
718 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);
719 value = ((((value) << (2))) + (pc));
720 fields->f_disp24 = value;
721 }
722 break;
723 case M32R_OPERAND_DISP8 :
724 {
725 long value;
726 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);
727 value = ((((value) << (2))) + (((pc) & (-4))));
728 fields->f_disp8 = value;
729 }
730 break;
731 case M32R_OPERAND_DR :
732 length = extract_normal (cd, ex_info, insn_value, 0, 0, 4, 4, 32, total_length, pc, & fields->f_r1);
733 break;
734 case M32R_OPERAND_HASH :
252b5132
RH
735 break;
736 case M32R_OPERAND_HI16 :
737 length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_SIGN_OPT), 0, 16, 16, 32, total_length, pc, & fields->f_hi16);
738 break;
1fa60b5d
DE
739 case M32R_OPERAND_IMM1 :
740 {
741 long value;
742 length = extract_normal (cd, ex_info, insn_value, 0, 0, 15, 1, 32, total_length, pc, & value);
743 value = ((value) + (1));
744 fields->f_imm1 = value;
745 }
746 break;
252b5132
RH
747 case M32R_OPERAND_SCR :
748 length = extract_normal (cd, ex_info, insn_value, 0, 0, 12, 4, 32, total_length, pc, & fields->f_r2);
749 break;
750 case M32R_OPERAND_SIMM16 :
751 length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_SIGNED), 0, 16, 16, 32, total_length, pc, & fields->f_simm16);
752 break;
753 case M32R_OPERAND_SIMM8 :
754 length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_SIGNED), 0, 8, 8, 32, total_length, pc, & fields->f_simm8);
755 break;
756 case M32R_OPERAND_SLO16 :
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_SR :
760 length = extract_normal (cd, ex_info, insn_value, 0, 0, 12, 4, 32, total_length, pc, & fields->f_r2);
761 break;
762 case M32R_OPERAND_SRC1 :
763 length = extract_normal (cd, ex_info, insn_value, 0, 0, 4, 4, 32, total_length, pc, & fields->f_r1);
764 break;
765 case M32R_OPERAND_SRC2 :
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_UIMM16 :
769 length = extract_normal (cd, ex_info, insn_value, 0, 0, 16, 16, 32, total_length, pc, & fields->f_uimm16);
770 break;
771 case M32R_OPERAND_UIMM24 :
772 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);
773 break;
774 case M32R_OPERAND_UIMM4 :
775 length = extract_normal (cd, ex_info, insn_value, 0, 0, 12, 4, 32, total_length, pc, & fields->f_uimm4);
776 break;
777 case M32R_OPERAND_UIMM5 :
778 length = extract_normal (cd, ex_info, insn_value, 0, 0, 11, 5, 32, total_length, pc, & fields->f_uimm5);
779 break;
780 case M32R_OPERAND_ULO16 :
781 length = extract_normal (cd, ex_info, insn_value, 0, 0, 16, 16, 32, total_length, pc, & fields->f_uimm16);
782 break;
783
784 default :
785 /* xgettext:c-format */
786 fprintf (stderr, _("Unrecognized field %d while decoding insn.\n"),
787 opindex);
788 abort ();
789 }
790
791 return length;
792}
793
794cgen_insert_fn * const m32r_cgen_insert_handlers[] =
795{
796 insert_insn_normal,
797};
798
799cgen_extract_fn * const m32r_cgen_extract_handlers[] =
800{
801 extract_insn_normal,
802};
803
804/* Getting values from cgen_fields is handled by a collection of functions.
805 They are distinguished by the type of the VALUE argument they return.
806 TODO: floating point, inlining support, remove cases where result type
807 not appropriate. */
808
809int
810m32r_cgen_get_int_operand (cd, opindex, fields)
fc05c67f 811 CGEN_CPU_DESC cd ATTRIBUTE_UNUSED;
252b5132
RH
812 int opindex;
813 const CGEN_FIELDS * fields;
814{
815 int value;
816
817 switch (opindex)
818 {
1fa60b5d
DE
819 case M32R_OPERAND_ACC :
820 value = fields->f_acc;
821 break;
822 case M32R_OPERAND_ACCD :
823 value = fields->f_accd;
824 break;
825 case M32R_OPERAND_ACCS :
826 value = fields->f_accs;
827 break;
252b5132
RH
828 case M32R_OPERAND_DCR :
829 value = fields->f_r1;
830 break;
831 case M32R_OPERAND_DISP16 :
832 value = fields->f_disp16;
833 break;
834 case M32R_OPERAND_DISP24 :
835 value = fields->f_disp24;
836 break;
837 case M32R_OPERAND_DISP8 :
838 value = fields->f_disp8;
839 break;
840 case M32R_OPERAND_DR :
841 value = fields->f_r1;
842 break;
843 case M32R_OPERAND_HASH :
eb1b03df 844 value = 0;
252b5132
RH
845 break;
846 case M32R_OPERAND_HI16 :
847 value = fields->f_hi16;
848 break;
1fa60b5d
DE
849 case M32R_OPERAND_IMM1 :
850 value = fields->f_imm1;
851 break;
252b5132
RH
852 case M32R_OPERAND_SCR :
853 value = fields->f_r2;
854 break;
855 case M32R_OPERAND_SIMM16 :
856 value = fields->f_simm16;
857 break;
858 case M32R_OPERAND_SIMM8 :
859 value = fields->f_simm8;
860 break;
861 case M32R_OPERAND_SLO16 :
862 value = fields->f_simm16;
863 break;
864 case M32R_OPERAND_SR :
865 value = fields->f_r2;
866 break;
867 case M32R_OPERAND_SRC1 :
868 value = fields->f_r1;
869 break;
870 case M32R_OPERAND_SRC2 :
871 value = fields->f_r2;
872 break;
873 case M32R_OPERAND_UIMM16 :
874 value = fields->f_uimm16;
875 break;
876 case M32R_OPERAND_UIMM24 :
877 value = fields->f_uimm24;
878 break;
879 case M32R_OPERAND_UIMM4 :
880 value = fields->f_uimm4;
881 break;
882 case M32R_OPERAND_UIMM5 :
883 value = fields->f_uimm5;
884 break;
885 case M32R_OPERAND_ULO16 :
886 value = fields->f_uimm16;
887 break;
888
889 default :
890 /* xgettext:c-format */
891 fprintf (stderr, _("Unrecognized field %d while getting int operand.\n"),
892 opindex);
893 abort ();
894 }
895
896 return value;
897}
898
899bfd_vma
900m32r_cgen_get_vma_operand (cd, opindex, fields)
fc05c67f 901 CGEN_CPU_DESC cd ATTRIBUTE_UNUSED;
252b5132
RH
902 int opindex;
903 const CGEN_FIELDS * fields;
904{
905 bfd_vma value;
906
907 switch (opindex)
908 {
1fa60b5d
DE
909 case M32R_OPERAND_ACC :
910 value = fields->f_acc;
911 break;
912 case M32R_OPERAND_ACCD :
913 value = fields->f_accd;
914 break;
915 case M32R_OPERAND_ACCS :
916 value = fields->f_accs;
917 break;
252b5132
RH
918 case M32R_OPERAND_DCR :
919 value = fields->f_r1;
920 break;
921 case M32R_OPERAND_DISP16 :
922 value = fields->f_disp16;
923 break;
924 case M32R_OPERAND_DISP24 :
925 value = fields->f_disp24;
926 break;
927 case M32R_OPERAND_DISP8 :
928 value = fields->f_disp8;
929 break;
930 case M32R_OPERAND_DR :
931 value = fields->f_r1;
932 break;
933 case M32R_OPERAND_HASH :
eb1b03df 934 value = 0;
252b5132
RH
935 break;
936 case M32R_OPERAND_HI16 :
937 value = fields->f_hi16;
938 break;
1fa60b5d
DE
939 case M32R_OPERAND_IMM1 :
940 value = fields->f_imm1;
941 break;
252b5132
RH
942 case M32R_OPERAND_SCR :
943 value = fields->f_r2;
944 break;
945 case M32R_OPERAND_SIMM16 :
946 value = fields->f_simm16;
947 break;
948 case M32R_OPERAND_SIMM8 :
949 value = fields->f_simm8;
950 break;
951 case M32R_OPERAND_SLO16 :
952 value = fields->f_simm16;
953 break;
954 case M32R_OPERAND_SR :
955 value = fields->f_r2;
956 break;
957 case M32R_OPERAND_SRC1 :
958 value = fields->f_r1;
959 break;
960 case M32R_OPERAND_SRC2 :
961 value = fields->f_r2;
962 break;
963 case M32R_OPERAND_UIMM16 :
964 value = fields->f_uimm16;
965 break;
966 case M32R_OPERAND_UIMM24 :
967 value = fields->f_uimm24;
968 break;
969 case M32R_OPERAND_UIMM4 :
970 value = fields->f_uimm4;
971 break;
972 case M32R_OPERAND_UIMM5 :
973 value = fields->f_uimm5;
974 break;
975 case M32R_OPERAND_ULO16 :
976 value = fields->f_uimm16;
977 break;
978
979 default :
980 /* xgettext:c-format */
981 fprintf (stderr, _("Unrecognized field %d while getting vma operand.\n"),
982 opindex);
983 abort ();
984 }
985
986 return value;
987}
988
989/* Stuffing values in cgen_fields is handled by a collection of functions.
990 They are distinguished by the type of the VALUE argument they accept.
991 TODO: floating point, inlining support, remove cases where argument type
992 not appropriate. */
993
994void
995m32r_cgen_set_int_operand (cd, opindex, fields, value)
fc05c67f 996 CGEN_CPU_DESC cd ATTRIBUTE_UNUSED;
252b5132
RH
997 int opindex;
998 CGEN_FIELDS * fields;
999 int value;
1000{
1001 switch (opindex)
1002 {
1fa60b5d
DE
1003 case M32R_OPERAND_ACC :
1004 fields->f_acc = value;
1005 break;
1006 case M32R_OPERAND_ACCD :
1007 fields->f_accd = value;
1008 break;
1009 case M32R_OPERAND_ACCS :
1010 fields->f_accs = value;
1011 break;
252b5132
RH
1012 case M32R_OPERAND_DCR :
1013 fields->f_r1 = value;
1014 break;
1015 case M32R_OPERAND_DISP16 :
1016 fields->f_disp16 = value;
1017 break;
1018 case M32R_OPERAND_DISP24 :
1019 fields->f_disp24 = value;
1020 break;
1021 case M32R_OPERAND_DISP8 :
1022 fields->f_disp8 = value;
1023 break;
1024 case M32R_OPERAND_DR :
1025 fields->f_r1 = value;
1026 break;
1027 case M32R_OPERAND_HASH :
252b5132
RH
1028 break;
1029 case M32R_OPERAND_HI16 :
1030 fields->f_hi16 = value;
1031 break;
1fa60b5d
DE
1032 case M32R_OPERAND_IMM1 :
1033 fields->f_imm1 = value;
1034 break;
252b5132
RH
1035 case M32R_OPERAND_SCR :
1036 fields->f_r2 = value;
1037 break;
1038 case M32R_OPERAND_SIMM16 :
1039 fields->f_simm16 = value;
1040 break;
1041 case M32R_OPERAND_SIMM8 :
1042 fields->f_simm8 = value;
1043 break;
1044 case M32R_OPERAND_SLO16 :
1045 fields->f_simm16 = value;
1046 break;
1047 case M32R_OPERAND_SR :
1048 fields->f_r2 = value;
1049 break;
1050 case M32R_OPERAND_SRC1 :
1051 fields->f_r1 = value;
1052 break;
1053 case M32R_OPERAND_SRC2 :
1054 fields->f_r2 = value;
1055 break;
1056 case M32R_OPERAND_UIMM16 :
1057 fields->f_uimm16 = value;
1058 break;
1059 case M32R_OPERAND_UIMM24 :
1060 fields->f_uimm24 = value;
1061 break;
1062 case M32R_OPERAND_UIMM4 :
1063 fields->f_uimm4 = value;
1064 break;
1065 case M32R_OPERAND_UIMM5 :
1066 fields->f_uimm5 = value;
1067 break;
1068 case M32R_OPERAND_ULO16 :
1069 fields->f_uimm16 = value;
1070 break;
1071
1072 default :
1073 /* xgettext:c-format */
1074 fprintf (stderr, _("Unrecognized field %d while setting int operand.\n"),
1075 opindex);
1076 abort ();
1077 }
1078}
1079
1080void
1081m32r_cgen_set_vma_operand (cd, opindex, fields, value)
fc05c67f 1082 CGEN_CPU_DESC cd ATTRIBUTE_UNUSED;
252b5132
RH
1083 int opindex;
1084 CGEN_FIELDS * fields;
1085 bfd_vma value;
1086{
1087 switch (opindex)
1088 {
1fa60b5d
DE
1089 case M32R_OPERAND_ACC :
1090 fields->f_acc = value;
1091 break;
1092 case M32R_OPERAND_ACCD :
1093 fields->f_accd = value;
1094 break;
1095 case M32R_OPERAND_ACCS :
1096 fields->f_accs = value;
1097 break;
252b5132
RH
1098 case M32R_OPERAND_DCR :
1099 fields->f_r1 = value;
1100 break;
1101 case M32R_OPERAND_DISP16 :
1102 fields->f_disp16 = value;
1103 break;
1104 case M32R_OPERAND_DISP24 :
1105 fields->f_disp24 = value;
1106 break;
1107 case M32R_OPERAND_DISP8 :
1108 fields->f_disp8 = value;
1109 break;
1110 case M32R_OPERAND_DR :
1111 fields->f_r1 = value;
1112 break;
1113 case M32R_OPERAND_HASH :
252b5132
RH
1114 break;
1115 case M32R_OPERAND_HI16 :
1116 fields->f_hi16 = value;
1117 break;
1fa60b5d
DE
1118 case M32R_OPERAND_IMM1 :
1119 fields->f_imm1 = value;
1120 break;
252b5132
RH
1121 case M32R_OPERAND_SCR :
1122 fields->f_r2 = value;
1123 break;
1124 case M32R_OPERAND_SIMM16 :
1125 fields->f_simm16 = value;
1126 break;
1127 case M32R_OPERAND_SIMM8 :
1128 fields->f_simm8 = value;
1129 break;
1130 case M32R_OPERAND_SLO16 :
1131 fields->f_simm16 = value;
1132 break;
1133 case M32R_OPERAND_SR :
1134 fields->f_r2 = value;
1135 break;
1136 case M32R_OPERAND_SRC1 :
1137 fields->f_r1 = value;
1138 break;
1139 case M32R_OPERAND_SRC2 :
1140 fields->f_r2 = value;
1141 break;
1142 case M32R_OPERAND_UIMM16 :
1143 fields->f_uimm16 = value;
1144 break;
1145 case M32R_OPERAND_UIMM24 :
1146 fields->f_uimm24 = value;
1147 break;
1148 case M32R_OPERAND_UIMM4 :
1149 fields->f_uimm4 = value;
1150 break;
1151 case M32R_OPERAND_UIMM5 :
1152 fields->f_uimm5 = value;
1153 break;
1154 case M32R_OPERAND_ULO16 :
1155 fields->f_uimm16 = value;
1156 break;
1157
1158 default :
1159 /* xgettext:c-format */
1160 fprintf (stderr, _("Unrecognized field %d while setting vma operand.\n"),
1161 opindex);
1162 abort ();
1163 }
1164}
1165
1166/* Function to call before using the instruction builder tables. */
1167
1168void
1169m32r_cgen_init_ibld_table (cd)
1170 CGEN_CPU_DESC cd;
1171{
1172 cd->insert_handlers = & m32r_cgen_insert_handlers[0];
1173 cd->extract_handlers = & m32r_cgen_extract_handlers[0];
1174
1175 cd->insert_operand = m32r_cgen_insert_operand;
1176 cd->extract_operand = m32r_cgen_extract_operand;
1177
1178 cd->get_int_operand = m32r_cgen_get_int_operand;
1179 cd->set_int_operand = m32r_cgen_set_int_operand;
1180 cd->get_vma_operand = m32r_cgen_get_vma_operand;
1181 cd->set_vma_operand = m32r_cgen_set_vma_operand;
1182}