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