*** empty log message ***
[deliverable/binutils-gdb.git] / opcodes / fr30-ibld.c
CommitLineData
252b5132
RH
1/* Instruction building/extraction support for fr30. -*- C -*-
2
47b0e7ad
NC
3 THIS FILE IS MACHINE GENERATED WITH CGEN: Cpu tools GENerator.
4 - the resultant file is machine generated, cgen-ibld.in isn't
252b5132 5
47b0e7ad
NC
6 Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2005
7 Free Software Foundation, Inc.
252b5132 8
47b0e7ad 9 This file is part of the GNU Binutils and GDB, the GNU debugger.
252b5132 10
47b0e7ad
NC
11 This program is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation; either version 2, or (at your option)
14 any later version.
252b5132 15
47b0e7ad
NC
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details.
252b5132 20
47b0e7ad
NC
21 You should have received a copy of the GNU General Public License
22 along with this program; if not, write to the Free Software Foundation, Inc.,
23 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */
252b5132
RH
24
25/* ??? Eventually more and more of this stuff can go to cpu-independent files.
26 Keep that in mind. */
27
28#include "sysdep.h"
252b5132
RH
29#include <stdio.h>
30#include "ansidecl.h"
31#include "dis-asm.h"
32#include "bfd.h"
33#include "symcat.h"
34#include "fr30-desc.h"
35#include "fr30-opc.h"
36#include "opintl.h"
37111cc7 37#include "safe-ctype.h"
252b5132 38
47b0e7ad 39#undef min
252b5132 40#define min(a,b) ((a) < (b) ? (a) : (b))
47b0e7ad 41#undef max
252b5132
RH
42#define max(a,b) ((a) > (b) ? (a) : (b))
43
44/* Used by the ifield rtx function. */
45#define FLD(f) (fields->f)
46
47static const char * insert_normal
ffead7ae
MM
48 (CGEN_CPU_DESC, long, unsigned int, unsigned int, unsigned int,
49 unsigned int, unsigned int, unsigned int, CGEN_INSN_BYTES_PTR);
252b5132 50static const char * insert_insn_normal
ffead7ae
MM
51 (CGEN_CPU_DESC, const CGEN_INSN *,
52 CGEN_FIELDS *, CGEN_INSN_BYTES_PTR, bfd_vma);
252b5132 53static int extract_normal
ffead7ae
MM
54 (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 *);
252b5132 57static int extract_insn_normal
ffead7ae
MM
58 (CGEN_CPU_DESC, const CGEN_INSN *, CGEN_EXTRACT_INFO *,
59 CGEN_INSN_INT, CGEN_FIELDS *, bfd_vma);
d5b2f4d6 60#if CGEN_INT_INSN_P
6bb95a0f 61static void put_insn_int_value
ffead7ae 62 (CGEN_CPU_DESC, CGEN_INSN_BYTES_PTR, int, int, CGEN_INSN_INT);
d5b2f4d6 63#endif
0e2ee3ca 64#if ! CGEN_INT_INSN_P
d5b2f4d6 65static CGEN_INLINE void insert_1
ffead7ae 66 (CGEN_CPU_DESC, unsigned long, int, int, int, unsigned char *);
0e2ee3ca 67static CGEN_INLINE int fill_cache
ffead7ae 68 (CGEN_CPU_DESC, CGEN_EXTRACT_INFO *, int, int, bfd_vma);
0e2ee3ca 69static CGEN_INLINE long extract_1
ffead7ae 70 (CGEN_CPU_DESC, CGEN_EXTRACT_INFO *, int, int, int, unsigned char *, bfd_vma);
0e2ee3ca 71#endif
252b5132
RH
72\f
73/* Operand insertion. */
74
75#if ! CGEN_INT_INSN_P
76
77/* Subroutine of insert_normal. */
78
79static CGEN_INLINE void
ffead7ae
MM
80insert_1 (CGEN_CPU_DESC cd,
81 unsigned long value,
82 int start,
83 int length,
84 int word_length,
85 unsigned char *bufp)
252b5132
RH
86{
87 unsigned long x,mask;
88 int shift;
252b5132 89
0e2ee3ca 90 x = cgen_get_insn_value (cd, bufp, word_length);
252b5132
RH
91
92 /* Written this way to avoid undefined behaviour. */
93 mask = (((1L << (length - 1)) - 1) << 1) | 1;
94 if (CGEN_INSN_LSB0_P)
95 shift = (start + 1) - length;
96 else
97 shift = (word_length - (start + length));
98 x = (x & ~(mask << shift)) | ((value & mask) << shift);
99
0e2ee3ca 100 cgen_put_insn_value (cd, bufp, word_length, (bfd_vma) x);
252b5132
RH
101}
102
103#endif /* ! CGEN_INT_INSN_P */
104
105/* Default insertion routine.
106
107 ATTRS is a mask of the boolean attributes.
108 WORD_OFFSET is the offset in bits from the start of the insn of the value.
109 WORD_LENGTH is the length of the word in bits in which the value resides.
110 START is the starting bit number in the word, architecture origin.
111 LENGTH is the length of VALUE in bits.
112 TOTAL_LENGTH is the total length of the insn in bits.
113
114 The result is an error message or NULL if success. */
115
116/* ??? This duplicates functionality with bfd's howto table and
117 bfd_install_relocation. */
118/* ??? This doesn't handle bfd_vma's. Create another function when
119 necessary. */
120
121static const char *
ffead7ae
MM
122insert_normal (CGEN_CPU_DESC cd,
123 long value,
124 unsigned int attrs,
125 unsigned int word_offset,
126 unsigned int start,
127 unsigned int length,
128 unsigned int word_length,
129 unsigned int total_length,
130 CGEN_INSN_BYTES_PTR buffer)
252b5132
RH
131{
132 static char errbuf[100];
133 /* Written this way to avoid undefined behaviour. */
134 unsigned long mask = (((1L << (length - 1)) - 1) << 1) | 1;
135
136 /* If LENGTH is zero, this operand doesn't contribute to the value. */
137 if (length == 0)
138 return NULL;
139
252b5132
RH
140 if (word_length > 32)
141 abort ();
142
143 /* For architectures with insns smaller than the base-insn-bitsize,
144 word_length may be too big. */
145 if (cd->min_insn_bitsize < cd->base_insn_bitsize)
146 {
147 if (word_offset == 0
148 && word_length > total_length)
149 word_length = total_length;
150 }
151
152 /* Ensure VALUE will fit. */
fc7bc883
RH
153 if (CGEN_BOOL_ATTR (attrs, CGEN_IFLD_SIGN_OPT))
154 {
155 long minval = - (1L << (length - 1));
156 unsigned long maxval = mask;
157
158 if ((value > 0 && (unsigned long) value > maxval)
159 || value < minval)
160 {
161 /* xgettext:c-format */
162 sprintf (errbuf,
163 _("operand out of range (%ld not between %ld and %lu)"),
164 value, minval, maxval);
165 return errbuf;
166 }
167 }
168 else if (! CGEN_BOOL_ATTR (attrs, CGEN_IFLD_SIGNED))
252b5132
RH
169 {
170 unsigned long maxval = mask;
6bb95a0f 171
252b5132
RH
172 if ((unsigned long) value > maxval)
173 {
174 /* xgettext:c-format */
175 sprintf (errbuf,
176 _("operand out of range (%lu not between 0 and %lu)"),
177 value, maxval);
178 return errbuf;
179 }
180 }
181 else
182 {
6bb95a0f 183 if (! cgen_signed_overflow_ok_p (cd))
252b5132 184 {
6bb95a0f
DB
185 long minval = - (1L << (length - 1));
186 long maxval = (1L << (length - 1)) - 1;
187
188 if (value < minval || value > maxval)
189 {
190 sprintf
191 /* xgettext:c-format */
192 (errbuf, _("operand out of range (%ld not between %ld and %ld)"),
193 value, minval, maxval);
194 return errbuf;
195 }
252b5132
RH
196 }
197 }
198
199#if CGEN_INT_INSN_P
200
201 {
202 int shift;
203
204 if (CGEN_INSN_LSB0_P)
6bb95a0f 205 shift = (word_offset + start + 1) - length;
252b5132 206 else
6bb95a0f 207 shift = total_length - (word_offset + start + length);
252b5132
RH
208 *buffer = (*buffer & ~(mask << shift)) | ((value & mask) << shift);
209 }
210
211#else /* ! CGEN_INT_INSN_P */
212
213 {
214 unsigned char *bufp = (unsigned char *) buffer + word_offset / 8;
215
216 insert_1 (cd, value, start, length, word_length, bufp);
217 }
218
219#endif /* ! CGEN_INT_INSN_P */
220
221 return NULL;
222}
223
224/* Default insn builder (insert handler).
fc7bc883
RH
225 The instruction is recorded in CGEN_INT_INSN_P byte order (meaning
226 that if CGEN_INSN_BYTES_PTR is an int * and thus, the value is
227 recorded in host byte order, otherwise BUFFER is an array of bytes
228 and the value is recorded in target byte order).
252b5132
RH
229 The result is an error message or NULL if success. */
230
231static const char *
ffead7ae
MM
232insert_insn_normal (CGEN_CPU_DESC cd,
233 const CGEN_INSN * insn,
234 CGEN_FIELDS * fields,
235 CGEN_INSN_BYTES_PTR buffer,
236 bfd_vma pc)
252b5132
RH
237{
238 const CGEN_SYNTAX *syntax = CGEN_INSN_SYNTAX (insn);
239 unsigned long value;
b3466c39 240 const CGEN_SYNTAX_CHAR_TYPE * syn;
252b5132
RH
241
242 CGEN_INIT_INSERT (cd);
243 value = CGEN_INSN_BASE_VALUE (insn);
244
245 /* If we're recording insns as numbers (rather than a string of bytes),
246 target byte order handling is deferred until later. */
247
248#if CGEN_INT_INSN_P
249
6bb95a0f
DB
250 put_insn_int_value (cd, buffer, cd->base_insn_bitsize,
251 CGEN_FIELDS_BITSIZE (fields), value);
252b5132
RH
252
253#else
254
0e2ee3ca 255 cgen_put_insn_value (cd, buffer, min ((unsigned) cd->base_insn_bitsize,
d5b2f4d6 256 (unsigned) CGEN_FIELDS_BITSIZE (fields)),
252b5132
RH
257 value);
258
259#endif /* ! CGEN_INT_INSN_P */
260
261 /* ??? It would be better to scan the format's fields.
262 Still need to be able to insert a value based on the operand though;
263 e.g. storing a branch displacement that got resolved later.
264 Needs more thought first. */
265
b3466c39 266 for (syn = CGEN_SYNTAX_STRING (syntax); * syn; ++ syn)
252b5132
RH
267 {
268 const char *errmsg;
269
270 if (CGEN_SYNTAX_CHAR_P (* syn))
271 continue;
272
273 errmsg = (* cd->insert_operand) (cd, CGEN_SYNTAX_FIELD (*syn),
274 fields, buffer, pc);
275 if (errmsg)
276 return errmsg;
277 }
278
279 return NULL;
280}
6bb95a0f 281
d5b2f4d6 282#if CGEN_INT_INSN_P
6bb95a0f 283/* Cover function to store an insn value into an integral insn. Must go here
47b0e7ad 284 because it needs <prefix>-desc.h for CGEN_INT_INSN_P. */
6bb95a0f
DB
285
286static void
ffead7ae
MM
287put_insn_int_value (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
288 CGEN_INSN_BYTES_PTR buf,
289 int length,
290 int insn_length,
291 CGEN_INSN_INT value)
6bb95a0f
DB
292{
293 /* For architectures with insns smaller than the base-insn-bitsize,
294 length may be too big. */
295 if (length > insn_length)
296 *buf = value;
297 else
298 {
299 int shift = insn_length - length;
300 /* Written this way to avoid undefined behaviour. */
301 CGEN_INSN_INT mask = (((1L << (length - 1)) - 1) << 1) | 1;
47b0e7ad 302
6bb95a0f
DB
303 *buf = (*buf & ~(mask << shift)) | ((value & mask) << shift);
304 }
305}
d5b2f4d6 306#endif
252b5132
RH
307\f
308/* Operand extraction. */
309
310#if ! CGEN_INT_INSN_P
311
312/* Subroutine of extract_normal.
313 Ensure sufficient bytes are cached in EX_INFO.
314 OFFSET is the offset in bytes from the start of the insn of the value.
315 BYTES is the length of the needed value.
316 Returns 1 for success, 0 for failure. */
317
318static CGEN_INLINE int
ffead7ae
MM
319fill_cache (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
320 CGEN_EXTRACT_INFO *ex_info,
321 int offset,
322 int bytes,
323 bfd_vma pc)
252b5132
RH
324{
325 /* It's doubtful that the middle part has already been fetched so
326 we don't optimize that case. kiss. */
d5b2f4d6 327 unsigned int mask;
252b5132
RH
328 disassemble_info *info = (disassemble_info *) ex_info->dis_info;
329
330 /* First do a quick check. */
331 mask = (1 << bytes) - 1;
332 if (((ex_info->valid >> offset) & mask) == mask)
333 return 1;
334
335 /* Search for the first byte we need to read. */
336 for (mask = 1 << offset; bytes > 0; --bytes, ++offset, mask <<= 1)
337 if (! (mask & ex_info->valid))
338 break;
339
340 if (bytes)
341 {
342 int status;
343
344 pc += offset;
345 status = (*info->read_memory_func)
346 (pc, ex_info->insn_bytes + offset, bytes, info);
347
348 if (status != 0)
349 {
350 (*info->memory_error_func) (status, pc, info);
351 return 0;
352 }
353
354 ex_info->valid |= ((1 << bytes) - 1) << offset;
355 }
356
357 return 1;
358}
359
360/* Subroutine of extract_normal. */
361
362static CGEN_INLINE long
ffead7ae
MM
363extract_1 (CGEN_CPU_DESC cd,
364 CGEN_EXTRACT_INFO *ex_info ATTRIBUTE_UNUSED,
365 int start,
366 int length,
367 int word_length,
368 unsigned char *bufp,
369 bfd_vma pc ATTRIBUTE_UNUSED)
252b5132 370{
b3466c39 371 unsigned long x;
252b5132 372 int shift;
47b0e7ad 373
e333d2c4
NC
374 x = cgen_get_insn_value (cd, bufp, word_length);
375
252b5132
RH
376 if (CGEN_INSN_LSB0_P)
377 shift = (start + 1) - length;
378 else
379 shift = (word_length - (start + length));
b3466c39 380 return x >> shift;
252b5132
RH
381}
382
383#endif /* ! CGEN_INT_INSN_P */
384
385/* Default extraction routine.
386
387 INSN_VALUE is the first base_insn_bitsize bits of the insn in host order,
388 or sometimes less for cases like the m32r where the base insn size is 32
389 but some insns are 16 bits.
390 ATTRS is a mask of the boolean attributes. We only need `SIGNED',
391 but for generality we take a bitmask of all of them.
392 WORD_OFFSET is the offset in bits from the start of the insn of the value.
393 WORD_LENGTH is the length of the word in bits in which the value resides.
394 START is the starting bit number in the word, architecture origin.
395 LENGTH is the length of VALUE in bits.
396 TOTAL_LENGTH is the total length of the insn in bits.
397
398 Returns 1 for success, 0 for failure. */
399
400/* ??? The return code isn't properly used. wip. */
401
402/* ??? This doesn't handle bfd_vma's. Create another function when
403 necessary. */
404
405static int
ffead7ae 406extract_normal (CGEN_CPU_DESC cd,
6bb95a0f 407#if ! CGEN_INT_INSN_P
ffead7ae 408 CGEN_EXTRACT_INFO *ex_info,
6bb95a0f 409#else
ffead7ae 410 CGEN_EXTRACT_INFO *ex_info ATTRIBUTE_UNUSED,
6bb95a0f 411#endif
ffead7ae
MM
412 CGEN_INSN_INT insn_value,
413 unsigned int attrs,
414 unsigned int word_offset,
415 unsigned int start,
416 unsigned int length,
417 unsigned int word_length,
418 unsigned int total_length,
6bb95a0f 419#if ! CGEN_INT_INSN_P
ffead7ae 420 bfd_vma pc,
6bb95a0f 421#else
ffead7ae 422 bfd_vma pc ATTRIBUTE_UNUSED,
6bb95a0f 423#endif
ffead7ae 424 long *valuep)
252b5132 425{
fc7bc883 426 long value, mask;
252b5132
RH
427
428 /* If LENGTH is zero, this operand doesn't contribute to the value
429 so give it a standard value of zero. */
430 if (length == 0)
431 {
432 *valuep = 0;
433 return 1;
434 }
435
252b5132
RH
436 if (word_length > 32)
437 abort ();
438
439 /* For architectures with insns smaller than the insn-base-bitsize,
440 word_length may be too big. */
441 if (cd->min_insn_bitsize < cd->base_insn_bitsize)
442 {
443 if (word_offset == 0
444 && word_length > total_length)
445 word_length = total_length;
446 }
447
fc7bc883 448 /* Does the value reside in INSN_VALUE, and at the right alignment? */
252b5132 449
fc7bc883 450 if (CGEN_INT_INSN_P || (word_offset == 0 && word_length == total_length))
252b5132 451 {
252b5132 452 if (CGEN_INSN_LSB0_P)
6bb95a0f 453 value = insn_value >> ((word_offset + start + 1) - length);
252b5132 454 else
6bb95a0f 455 value = insn_value >> (total_length - ( word_offset + start + length));
252b5132
RH
456 }
457
458#if ! CGEN_INT_INSN_P
459
460 else
461 {
462 unsigned char *bufp = ex_info->insn_bytes + word_offset / 8;
463
464 if (word_length > 32)
465 abort ();
466
467 if (fill_cache (cd, ex_info, word_offset / 8, word_length / 8, pc) == 0)
468 return 0;
469
470 value = extract_1 (cd, ex_info, start, length, word_length, bufp, pc);
471 }
472
473#endif /* ! CGEN_INT_INSN_P */
474
b3466c39
DB
475 /* Written this way to avoid undefined behaviour. */
476 mask = (((1L << (length - 1)) - 1) << 1) | 1;
477
478 value &= mask;
479 /* sign extend? */
480 if (CGEN_BOOL_ATTR (attrs, CGEN_IFLD_SIGNED)
481 && (value & (1L << (length - 1))))
482 value |= ~mask;
483
252b5132
RH
484 *valuep = value;
485
486 return 1;
487}
488
489/* Default insn extractor.
490
491 INSN_VALUE is the first base_insn_bitsize bits, translated to host order.
492 The extracted fields are stored in FIELDS.
493 EX_INFO is used to handle reading variable length insns.
494 Return the length of the insn in bits, or 0 if no match,
495 or -1 if an error occurs fetching data (memory_error_func will have
496 been called). */
497
498static int
ffead7ae
MM
499extract_insn_normal (CGEN_CPU_DESC cd,
500 const CGEN_INSN *insn,
501 CGEN_EXTRACT_INFO *ex_info,
502 CGEN_INSN_INT insn_value,
503 CGEN_FIELDS *fields,
504 bfd_vma pc)
252b5132
RH
505{
506 const CGEN_SYNTAX *syntax = CGEN_INSN_SYNTAX (insn);
b3466c39 507 const CGEN_SYNTAX_CHAR_TYPE *syn;
252b5132
RH
508
509 CGEN_FIELDS_BITSIZE (fields) = CGEN_INSN_BITSIZE (insn);
510
511 CGEN_INIT_EXTRACT (cd);
512
513 for (syn = CGEN_SYNTAX_STRING (syntax); *syn; ++syn)
514 {
515 int length;
516
517 if (CGEN_SYNTAX_CHAR_P (*syn))
518 continue;
519
520 length = (* cd->extract_operand) (cd, CGEN_SYNTAX_FIELD (*syn),
521 ex_info, insn_value, fields, pc);
522 if (length <= 0)
523 return length;
524 }
525
526 /* We recognized and successfully extracted this insn. */
527 return CGEN_INSN_BITSIZE (insn);
528}
529\f
47b0e7ad 530/* Machine generated code added here. */
252b5132 531
0e2ee3ca 532const char * fr30_cgen_insert_operand
47b0e7ad 533 (CGEN_CPU_DESC, int, CGEN_FIELDS *, CGEN_INSN_BYTES_PTR, bfd_vma);
0e2ee3ca 534
252b5132
RH
535/* Main entry point for operand insertion.
536
537 This function is basically just a big switch statement. Earlier versions
538 used tables to look up the function to use, but
539 - if the table contains both assembler and disassembler functions then
540 the disassembler contains much of the assembler and vice-versa,
541 - there's a lot of inlining possibilities as things grow,
542 - using a switch statement avoids the function call overhead.
543
544 This function could be moved into `parse_insn_normal', but keeping it
545 separate makes clear the interface between `parse_insn_normal' and each of
546 the handlers. It's also needed by GAS to insert operands that couldn't be
9a2e995d 547 resolved during parsing. */
252b5132
RH
548
549const char *
47b0e7ad
NC
550fr30_cgen_insert_operand (CGEN_CPU_DESC cd,
551 int opindex,
552 CGEN_FIELDS * fields,
553 CGEN_INSN_BYTES_PTR buffer,
554 bfd_vma pc ATTRIBUTE_UNUSED)
252b5132 555{
eb1b03df 556 const char * errmsg = NULL;
252b5132
RH
557 unsigned int total_length = CGEN_FIELDS_BITSIZE (fields);
558
559 switch (opindex)
560 {
561 case FR30_OPERAND_CRI :
562 errmsg = insert_normal (cd, fields->f_CRi, 0, 16, 12, 4, 16, total_length, buffer);
563 break;
564 case FR30_OPERAND_CRJ :
565 errmsg = insert_normal (cd, fields->f_CRj, 0, 16, 8, 4, 16, total_length, buffer);
566 break;
567 case FR30_OPERAND_R13 :
252b5132
RH
568 break;
569 case FR30_OPERAND_R14 :
252b5132
RH
570 break;
571 case FR30_OPERAND_R15 :
252b5132
RH
572 break;
573 case FR30_OPERAND_RI :
574 errmsg = insert_normal (cd, fields->f_Ri, 0, 0, 12, 4, 16, total_length, buffer);
575 break;
576 case FR30_OPERAND_RIC :
577 errmsg = insert_normal (cd, fields->f_Ric, 0, 16, 12, 4, 16, total_length, buffer);
578 break;
579 case FR30_OPERAND_RJ :
580 errmsg = insert_normal (cd, fields->f_Rj, 0, 0, 8, 4, 16, total_length, buffer);
581 break;
582 case FR30_OPERAND_RJC :
583 errmsg = insert_normal (cd, fields->f_Rjc, 0, 16, 8, 4, 16, total_length, buffer);
584 break;
585 case FR30_OPERAND_RS1 :
586 errmsg = insert_normal (cd, fields->f_Rs1, 0, 0, 8, 4, 16, total_length, buffer);
587 break;
588 case FR30_OPERAND_RS2 :
589 errmsg = insert_normal (cd, fields->f_Rs2, 0, 0, 12, 4, 16, total_length, buffer);
590 break;
591 case FR30_OPERAND_CC :
592 errmsg = insert_normal (cd, fields->f_cc, 0, 0, 4, 4, 16, total_length, buffer);
593 break;
594 case FR30_OPERAND_CCC :
595 errmsg = insert_normal (cd, fields->f_ccc, 0, 16, 0, 8, 16, total_length, buffer);
596 break;
597 case FR30_OPERAND_DIR10 :
598 {
599 long value = fields->f_dir10;
600 value = ((unsigned int) (value) >> (2));
601 errmsg = insert_normal (cd, value, 0, 0, 8, 8, 16, total_length, buffer);
602 }
603 break;
604 case FR30_OPERAND_DIR8 :
605 errmsg = insert_normal (cd, fields->f_dir8, 0, 0, 8, 8, 16, total_length, buffer);
606 break;
607 case FR30_OPERAND_DIR9 :
608 {
609 long value = fields->f_dir9;
610 value = ((unsigned int) (value) >> (1));
611 errmsg = insert_normal (cd, value, 0, 0, 8, 8, 16, total_length, buffer);
612 }
613 break;
614 case FR30_OPERAND_DISP10 :
615 {
616 long value = fields->f_disp10;
617 value = ((int) (value) >> (2));
618 errmsg = insert_normal (cd, value, 0|(1<<CGEN_IFLD_SIGNED), 0, 4, 8, 16, total_length, buffer);
619 }
620 break;
621 case FR30_OPERAND_DISP8 :
622 errmsg = insert_normal (cd, fields->f_disp8, 0|(1<<CGEN_IFLD_SIGNED), 0, 4, 8, 16, total_length, buffer);
623 break;
624 case FR30_OPERAND_DISP9 :
625 {
626 long value = fields->f_disp9;
627 value = ((int) (value) >> (1));
628 errmsg = insert_normal (cd, value, 0|(1<<CGEN_IFLD_SIGNED), 0, 4, 8, 16, total_length, buffer);
629 }
630 break;
631 case FR30_OPERAND_I20 :
632 {
633{
634 FLD (f_i20_4) = ((unsigned int) (FLD (f_i20)) >> (16));
635 FLD (f_i20_16) = ((FLD (f_i20)) & (65535));
636}
637 errmsg = insert_normal (cd, fields->f_i20_4, 0, 0, 8, 4, 16, total_length, buffer);
638 if (errmsg)
639 break;
640 errmsg = insert_normal (cd, fields->f_i20_16, 0, 16, 0, 16, 16, total_length, buffer);
641 if (errmsg)
642 break;
643 }
644 break;
645 case FR30_OPERAND_I32 :
646 errmsg = insert_normal (cd, fields->f_i32, 0|(1<<CGEN_IFLD_SIGN_OPT), 16, 0, 32, 32, total_length, buffer);
647 break;
648 case FR30_OPERAND_I8 :
649 errmsg = insert_normal (cd, fields->f_i8, 0, 0, 4, 8, 16, total_length, buffer);
650 break;
651 case FR30_OPERAND_LABEL12 :
652 {
653 long value = fields->f_rel12;
654 value = ((int) (((value) - (((pc) + (2))))) >> (1));
655 errmsg = insert_normal (cd, value, 0|(1<<CGEN_IFLD_SIGNED)|(1<<CGEN_IFLD_PCREL_ADDR), 0, 5, 11, 16, total_length, buffer);
656 }
657 break;
658 case FR30_OPERAND_LABEL9 :
659 {
660 long value = fields->f_rel9;
661 value = ((int) (((value) - (((pc) + (2))))) >> (1));
662 errmsg = insert_normal (cd, value, 0|(1<<CGEN_IFLD_SIGNED)|(1<<CGEN_IFLD_PCREL_ADDR), 0, 8, 8, 16, total_length, buffer);
663 }
664 break;
665 case FR30_OPERAND_M4 :
666 {
667 long value = fields->f_m4;
668 value = ((value) & (15));
669 errmsg = insert_normal (cd, value, 0, 0, 8, 4, 16, total_length, buffer);
670 }
671 break;
672 case FR30_OPERAND_PS :
252b5132
RH
673 break;
674 case FR30_OPERAND_REGLIST_HI_LD :
675 errmsg = insert_normal (cd, fields->f_reglist_hi_ld, 0, 0, 8, 8, 16, total_length, buffer);
676 break;
677 case FR30_OPERAND_REGLIST_HI_ST :
678 errmsg = insert_normal (cd, fields->f_reglist_hi_st, 0, 0, 8, 8, 16, total_length, buffer);
679 break;
680 case FR30_OPERAND_REGLIST_LOW_LD :
681 errmsg = insert_normal (cd, fields->f_reglist_low_ld, 0, 0, 8, 8, 16, total_length, buffer);
682 break;
683 case FR30_OPERAND_REGLIST_LOW_ST :
684 errmsg = insert_normal (cd, fields->f_reglist_low_st, 0, 0, 8, 8, 16, total_length, buffer);
685 break;
686 case FR30_OPERAND_S10 :
687 {
688 long value = fields->f_s10;
689 value = ((int) (value) >> (2));
690 errmsg = insert_normal (cd, value, 0|(1<<CGEN_IFLD_SIGNED), 0, 8, 8, 16, total_length, buffer);
691 }
692 break;
693 case FR30_OPERAND_U10 :
694 {
695 long value = fields->f_u10;
696 value = ((unsigned int) (value) >> (2));
697 errmsg = insert_normal (cd, value, 0, 0, 8, 8, 16, total_length, buffer);
698 }
699 break;
700 case FR30_OPERAND_U4 :
701 errmsg = insert_normal (cd, fields->f_u4, 0, 0, 8, 4, 16, total_length, buffer);
702 break;
703 case FR30_OPERAND_U4C :
704 errmsg = insert_normal (cd, fields->f_u4c, 0, 0, 12, 4, 16, total_length, buffer);
705 break;
706 case FR30_OPERAND_U8 :
707 errmsg = insert_normal (cd, fields->f_u8, 0, 0, 8, 8, 16, total_length, buffer);
708 break;
709 case FR30_OPERAND_UDISP6 :
710 {
711 long value = fields->f_udisp6;
712 value = ((unsigned int) (value) >> (2));
713 errmsg = insert_normal (cd, value, 0, 0, 8, 4, 16, total_length, buffer);
714 }
715 break;
716
717 default :
718 /* xgettext:c-format */
719 fprintf (stderr, _("Unrecognized field %d while building insn.\n"),
720 opindex);
721 abort ();
722 }
723
724 return errmsg;
725}
726
0e2ee3ca 727int fr30_cgen_extract_operand
47b0e7ad 728 (CGEN_CPU_DESC, int, CGEN_EXTRACT_INFO *, CGEN_INSN_INT, CGEN_FIELDS *, bfd_vma);
0e2ee3ca 729
252b5132 730/* Main entry point for operand extraction.
eb1b03df
DE
731 The result is <= 0 for error, >0 for success.
732 ??? Actual values aren't well defined right now.
252b5132
RH
733
734 This function is basically just a big switch statement. Earlier versions
735 used tables to look up the function to use, but
736 - if the table contains both assembler and disassembler functions then
737 the disassembler contains much of the assembler and vice-versa,
738 - there's a lot of inlining possibilities as things grow,
739 - using a switch statement avoids the function call overhead.
740
741 This function could be moved into `print_insn_normal', but keeping it
742 separate makes clear the interface between `print_insn_normal' and each of
9a2e995d 743 the handlers. */
252b5132
RH
744
745int
47b0e7ad
NC
746fr30_cgen_extract_operand (CGEN_CPU_DESC cd,
747 int opindex,
748 CGEN_EXTRACT_INFO *ex_info,
749 CGEN_INSN_INT insn_value,
750 CGEN_FIELDS * fields,
751 bfd_vma pc)
252b5132 752{
eb1b03df
DE
753 /* Assume success (for those operands that are nops). */
754 int length = 1;
252b5132
RH
755 unsigned int total_length = CGEN_FIELDS_BITSIZE (fields);
756
757 switch (opindex)
758 {
759 case FR30_OPERAND_CRI :
760 length = extract_normal (cd, ex_info, insn_value, 0, 16, 12, 4, 16, total_length, pc, & fields->f_CRi);
761 break;
762 case FR30_OPERAND_CRJ :
763 length = extract_normal (cd, ex_info, insn_value, 0, 16, 8, 4, 16, total_length, pc, & fields->f_CRj);
764 break;
765 case FR30_OPERAND_R13 :
252b5132
RH
766 break;
767 case FR30_OPERAND_R14 :
252b5132
RH
768 break;
769 case FR30_OPERAND_R15 :
252b5132
RH
770 break;
771 case FR30_OPERAND_RI :
772 length = extract_normal (cd, ex_info, insn_value, 0, 0, 12, 4, 16, total_length, pc, & fields->f_Ri);
773 break;
774 case FR30_OPERAND_RIC :
775 length = extract_normal (cd, ex_info, insn_value, 0, 16, 12, 4, 16, total_length, pc, & fields->f_Ric);
776 break;
777 case FR30_OPERAND_RJ :
778 length = extract_normal (cd, ex_info, insn_value, 0, 0, 8, 4, 16, total_length, pc, & fields->f_Rj);
779 break;
780 case FR30_OPERAND_RJC :
781 length = extract_normal (cd, ex_info, insn_value, 0, 16, 8, 4, 16, total_length, pc, & fields->f_Rjc);
782 break;
783 case FR30_OPERAND_RS1 :
784 length = extract_normal (cd, ex_info, insn_value, 0, 0, 8, 4, 16, total_length, pc, & fields->f_Rs1);
785 break;
786 case FR30_OPERAND_RS2 :
787 length = extract_normal (cd, ex_info, insn_value, 0, 0, 12, 4, 16, total_length, pc, & fields->f_Rs2);
788 break;
789 case FR30_OPERAND_CC :
790 length = extract_normal (cd, ex_info, insn_value, 0, 0, 4, 4, 16, total_length, pc, & fields->f_cc);
791 break;
792 case FR30_OPERAND_CCC :
793 length = extract_normal (cd, ex_info, insn_value, 0, 16, 0, 8, 16, total_length, pc, & fields->f_ccc);
794 break;
795 case FR30_OPERAND_DIR10 :
796 {
797 long value;
798 length = extract_normal (cd, ex_info, insn_value, 0, 0, 8, 8, 16, total_length, pc, & value);
799 value = ((value) << (2));
800 fields->f_dir10 = value;
801 }
802 break;
803 case FR30_OPERAND_DIR8 :
804 length = extract_normal (cd, ex_info, insn_value, 0, 0, 8, 8, 16, total_length, pc, & fields->f_dir8);
805 break;
806 case FR30_OPERAND_DIR9 :
807 {
808 long value;
809 length = extract_normal (cd, ex_info, insn_value, 0, 0, 8, 8, 16, total_length, pc, & value);
810 value = ((value) << (1));
811 fields->f_dir9 = value;
812 }
813 break;
814 case FR30_OPERAND_DISP10 :
815 {
816 long value;
817 length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_SIGNED), 0, 4, 8, 16, total_length, pc, & value);
818 value = ((value) << (2));
819 fields->f_disp10 = value;
820 }
821 break;
822 case FR30_OPERAND_DISP8 :
823 length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_SIGNED), 0, 4, 8, 16, total_length, pc, & fields->f_disp8);
824 break;
825 case FR30_OPERAND_DISP9 :
826 {
827 long value;
828 length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_SIGNED), 0, 4, 8, 16, total_length, pc, & value);
829 value = ((value) << (1));
830 fields->f_disp9 = value;
831 }
832 break;
833 case FR30_OPERAND_I20 :
834 {
835 length = extract_normal (cd, ex_info, insn_value, 0, 0, 8, 4, 16, total_length, pc, & fields->f_i20_4);
6bb95a0f 836 if (length <= 0) break;
252b5132 837 length = extract_normal (cd, ex_info, insn_value, 0, 16, 0, 16, 16, total_length, pc, & fields->f_i20_16);
6bb95a0f 838 if (length <= 0) break;
252b5132
RH
839{
840 FLD (f_i20) = ((((FLD (f_i20_4)) << (16))) | (FLD (f_i20_16)));
841}
842 }
843 break;
844 case FR30_OPERAND_I32 :
845 length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_SIGN_OPT), 16, 0, 32, 32, total_length, pc, & fields->f_i32);
846 break;
847 case FR30_OPERAND_I8 :
848 length = extract_normal (cd, ex_info, insn_value, 0, 0, 4, 8, 16, total_length, pc, & fields->f_i8);
849 break;
850 case FR30_OPERAND_LABEL12 :
851 {
852 long value;
853 length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_SIGNED)|(1<<CGEN_IFLD_PCREL_ADDR), 0, 5, 11, 16, total_length, pc, & value);
854 value = ((((value) << (1))) + (((pc) + (2))));
855 fields->f_rel12 = value;
856 }
857 break;
858 case FR30_OPERAND_LABEL9 :
859 {
860 long value;
861 length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_SIGNED)|(1<<CGEN_IFLD_PCREL_ADDR), 0, 8, 8, 16, total_length, pc, & value);
862 value = ((((value) << (1))) + (((pc) + (2))));
863 fields->f_rel9 = value;
864 }
865 break;
866 case FR30_OPERAND_M4 :
867 {
868 long value;
869 length = extract_normal (cd, ex_info, insn_value, 0, 0, 8, 4, 16, total_length, pc, & value);
870 value = ((value) | (((-1) << (4))));
871 fields->f_m4 = value;
872 }
873 break;
874 case FR30_OPERAND_PS :
252b5132
RH
875 break;
876 case FR30_OPERAND_REGLIST_HI_LD :
877 length = extract_normal (cd, ex_info, insn_value, 0, 0, 8, 8, 16, total_length, pc, & fields->f_reglist_hi_ld);
878 break;
879 case FR30_OPERAND_REGLIST_HI_ST :
880 length = extract_normal (cd, ex_info, insn_value, 0, 0, 8, 8, 16, total_length, pc, & fields->f_reglist_hi_st);
881 break;
882 case FR30_OPERAND_REGLIST_LOW_LD :
883 length = extract_normal (cd, ex_info, insn_value, 0, 0, 8, 8, 16, total_length, pc, & fields->f_reglist_low_ld);
884 break;
885 case FR30_OPERAND_REGLIST_LOW_ST :
886 length = extract_normal (cd, ex_info, insn_value, 0, 0, 8, 8, 16, total_length, pc, & fields->f_reglist_low_st);
887 break;
888 case FR30_OPERAND_S10 :
889 {
890 long value;
891 length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_SIGNED), 0, 8, 8, 16, total_length, pc, & value);
892 value = ((value) << (2));
893 fields->f_s10 = value;
894 }
895 break;
896 case FR30_OPERAND_U10 :
897 {
898 long value;
899 length = extract_normal (cd, ex_info, insn_value, 0, 0, 8, 8, 16, total_length, pc, & value);
900 value = ((value) << (2));
901 fields->f_u10 = value;
902 }
903 break;
904 case FR30_OPERAND_U4 :
905 length = extract_normal (cd, ex_info, insn_value, 0, 0, 8, 4, 16, total_length, pc, & fields->f_u4);
906 break;
907 case FR30_OPERAND_U4C :
908 length = extract_normal (cd, ex_info, insn_value, 0, 0, 12, 4, 16, total_length, pc, & fields->f_u4c);
909 break;
910 case FR30_OPERAND_U8 :
911 length = extract_normal (cd, ex_info, insn_value, 0, 0, 8, 8, 16, total_length, pc, & fields->f_u8);
912 break;
913 case FR30_OPERAND_UDISP6 :
914 {
915 long value;
916 length = extract_normal (cd, ex_info, insn_value, 0, 0, 8, 4, 16, total_length, pc, & value);
917 value = ((value) << (2));
918 fields->f_udisp6 = value;
919 }
920 break;
921
922 default :
923 /* xgettext:c-format */
924 fprintf (stderr, _("Unrecognized field %d while decoding insn.\n"),
925 opindex);
926 abort ();
927 }
928
929 return length;
930}
931
932cgen_insert_fn * const fr30_cgen_insert_handlers[] =
933{
934 insert_insn_normal,
935};
936
937cgen_extract_fn * const fr30_cgen_extract_handlers[] =
938{
939 extract_insn_normal,
940};
941
47b0e7ad
NC
942int fr30_cgen_get_int_operand (CGEN_CPU_DESC, int, const CGEN_FIELDS *);
943bfd_vma fr30_cgen_get_vma_operand (CGEN_CPU_DESC, int, const CGEN_FIELDS *);
0e2ee3ca 944
252b5132
RH
945/* Getting values from cgen_fields is handled by a collection of functions.
946 They are distinguished by the type of the VALUE argument they return.
947 TODO: floating point, inlining support, remove cases where result type
948 not appropriate. */
949
950int
47b0e7ad
NC
951fr30_cgen_get_int_operand (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
952 int opindex,
953 const CGEN_FIELDS * fields)
252b5132
RH
954{
955 int value;
956
957 switch (opindex)
958 {
959 case FR30_OPERAND_CRI :
960 value = fields->f_CRi;
961 break;
962 case FR30_OPERAND_CRJ :
963 value = fields->f_CRj;
964 break;
965 case FR30_OPERAND_R13 :
eb1b03df 966 value = 0;
252b5132
RH
967 break;
968 case FR30_OPERAND_R14 :
eb1b03df 969 value = 0;
252b5132
RH
970 break;
971 case FR30_OPERAND_R15 :
eb1b03df 972 value = 0;
252b5132
RH
973 break;
974 case FR30_OPERAND_RI :
975 value = fields->f_Ri;
976 break;
977 case FR30_OPERAND_RIC :
978 value = fields->f_Ric;
979 break;
980 case FR30_OPERAND_RJ :
981 value = fields->f_Rj;
982 break;
983 case FR30_OPERAND_RJC :
984 value = fields->f_Rjc;
985 break;
986 case FR30_OPERAND_RS1 :
987 value = fields->f_Rs1;
988 break;
989 case FR30_OPERAND_RS2 :
990 value = fields->f_Rs2;
991 break;
992 case FR30_OPERAND_CC :
993 value = fields->f_cc;
994 break;
995 case FR30_OPERAND_CCC :
996 value = fields->f_ccc;
997 break;
998 case FR30_OPERAND_DIR10 :
999 value = fields->f_dir10;
1000 break;
1001 case FR30_OPERAND_DIR8 :
1002 value = fields->f_dir8;
1003 break;
1004 case FR30_OPERAND_DIR9 :
1005 value = fields->f_dir9;
1006 break;
1007 case FR30_OPERAND_DISP10 :
1008 value = fields->f_disp10;
1009 break;
1010 case FR30_OPERAND_DISP8 :
1011 value = fields->f_disp8;
1012 break;
1013 case FR30_OPERAND_DISP9 :
1014 value = fields->f_disp9;
1015 break;
1016 case FR30_OPERAND_I20 :
1017 value = fields->f_i20;
1018 break;
1019 case FR30_OPERAND_I32 :
1020 value = fields->f_i32;
1021 break;
1022 case FR30_OPERAND_I8 :
1023 value = fields->f_i8;
1024 break;
1025 case FR30_OPERAND_LABEL12 :
1026 value = fields->f_rel12;
1027 break;
1028 case FR30_OPERAND_LABEL9 :
1029 value = fields->f_rel9;
1030 break;
1031 case FR30_OPERAND_M4 :
1032 value = fields->f_m4;
1033 break;
1034 case FR30_OPERAND_PS :
eb1b03df 1035 value = 0;
252b5132
RH
1036 break;
1037 case FR30_OPERAND_REGLIST_HI_LD :
1038 value = fields->f_reglist_hi_ld;
1039 break;
1040 case FR30_OPERAND_REGLIST_HI_ST :
1041 value = fields->f_reglist_hi_st;
1042 break;
1043 case FR30_OPERAND_REGLIST_LOW_LD :
1044 value = fields->f_reglist_low_ld;
1045 break;
1046 case FR30_OPERAND_REGLIST_LOW_ST :
1047 value = fields->f_reglist_low_st;
1048 break;
1049 case FR30_OPERAND_S10 :
1050 value = fields->f_s10;
1051 break;
1052 case FR30_OPERAND_U10 :
1053 value = fields->f_u10;
1054 break;
1055 case FR30_OPERAND_U4 :
1056 value = fields->f_u4;
1057 break;
1058 case FR30_OPERAND_U4C :
1059 value = fields->f_u4c;
1060 break;
1061 case FR30_OPERAND_U8 :
1062 value = fields->f_u8;
1063 break;
1064 case FR30_OPERAND_UDISP6 :
1065 value = fields->f_udisp6;
1066 break;
1067
1068 default :
1069 /* xgettext:c-format */
1070 fprintf (stderr, _("Unrecognized field %d while getting int operand.\n"),
1071 opindex);
1072 abort ();
1073 }
1074
1075 return value;
1076}
1077
1078bfd_vma
47b0e7ad
NC
1079fr30_cgen_get_vma_operand (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
1080 int opindex,
1081 const CGEN_FIELDS * fields)
252b5132
RH
1082{
1083 bfd_vma value;
1084
1085 switch (opindex)
1086 {
1087 case FR30_OPERAND_CRI :
1088 value = fields->f_CRi;
1089 break;
1090 case FR30_OPERAND_CRJ :
1091 value = fields->f_CRj;
1092 break;
1093 case FR30_OPERAND_R13 :
eb1b03df 1094 value = 0;
252b5132
RH
1095 break;
1096 case FR30_OPERAND_R14 :
eb1b03df 1097 value = 0;
252b5132
RH
1098 break;
1099 case FR30_OPERAND_R15 :
eb1b03df 1100 value = 0;
252b5132
RH
1101 break;
1102 case FR30_OPERAND_RI :
1103 value = fields->f_Ri;
1104 break;
1105 case FR30_OPERAND_RIC :
1106 value = fields->f_Ric;
1107 break;
1108 case FR30_OPERAND_RJ :
1109 value = fields->f_Rj;
1110 break;
1111 case FR30_OPERAND_RJC :
1112 value = fields->f_Rjc;
1113 break;
1114 case FR30_OPERAND_RS1 :
1115 value = fields->f_Rs1;
1116 break;
1117 case FR30_OPERAND_RS2 :
1118 value = fields->f_Rs2;
1119 break;
1120 case FR30_OPERAND_CC :
1121 value = fields->f_cc;
1122 break;
1123 case FR30_OPERAND_CCC :
1124 value = fields->f_ccc;
1125 break;
1126 case FR30_OPERAND_DIR10 :
1127 value = fields->f_dir10;
1128 break;
1129 case FR30_OPERAND_DIR8 :
1130 value = fields->f_dir8;
1131 break;
1132 case FR30_OPERAND_DIR9 :
1133 value = fields->f_dir9;
1134 break;
1135 case FR30_OPERAND_DISP10 :
1136 value = fields->f_disp10;
1137 break;
1138 case FR30_OPERAND_DISP8 :
1139 value = fields->f_disp8;
1140 break;
1141 case FR30_OPERAND_DISP9 :
1142 value = fields->f_disp9;
1143 break;
1144 case FR30_OPERAND_I20 :
1145 value = fields->f_i20;
1146 break;
1147 case FR30_OPERAND_I32 :
1148 value = fields->f_i32;
1149 break;
1150 case FR30_OPERAND_I8 :
1151 value = fields->f_i8;
1152 break;
1153 case FR30_OPERAND_LABEL12 :
1154 value = fields->f_rel12;
1155 break;
1156 case FR30_OPERAND_LABEL9 :
1157 value = fields->f_rel9;
1158 break;
1159 case FR30_OPERAND_M4 :
1160 value = fields->f_m4;
1161 break;
1162 case FR30_OPERAND_PS :
eb1b03df 1163 value = 0;
252b5132
RH
1164 break;
1165 case FR30_OPERAND_REGLIST_HI_LD :
1166 value = fields->f_reglist_hi_ld;
1167 break;
1168 case FR30_OPERAND_REGLIST_HI_ST :
1169 value = fields->f_reglist_hi_st;
1170 break;
1171 case FR30_OPERAND_REGLIST_LOW_LD :
1172 value = fields->f_reglist_low_ld;
1173 break;
1174 case FR30_OPERAND_REGLIST_LOW_ST :
1175 value = fields->f_reglist_low_st;
1176 break;
1177 case FR30_OPERAND_S10 :
1178 value = fields->f_s10;
1179 break;
1180 case FR30_OPERAND_U10 :
1181 value = fields->f_u10;
1182 break;
1183 case FR30_OPERAND_U4 :
1184 value = fields->f_u4;
1185 break;
1186 case FR30_OPERAND_U4C :
1187 value = fields->f_u4c;
1188 break;
1189 case FR30_OPERAND_U8 :
1190 value = fields->f_u8;
1191 break;
1192 case FR30_OPERAND_UDISP6 :
1193 value = fields->f_udisp6;
1194 break;
1195
1196 default :
1197 /* xgettext:c-format */
1198 fprintf (stderr, _("Unrecognized field %d while getting vma operand.\n"),
1199 opindex);
1200 abort ();
1201 }
1202
1203 return value;
1204}
1205
47b0e7ad
NC
1206void fr30_cgen_set_int_operand (CGEN_CPU_DESC, int, CGEN_FIELDS *, int);
1207void fr30_cgen_set_vma_operand (CGEN_CPU_DESC, int, CGEN_FIELDS *, bfd_vma);
0e2ee3ca 1208
252b5132
RH
1209/* Stuffing values in cgen_fields is handled by a collection of functions.
1210 They are distinguished by the type of the VALUE argument they accept.
1211 TODO: floating point, inlining support, remove cases where argument type
1212 not appropriate. */
1213
1214void
47b0e7ad
NC
1215fr30_cgen_set_int_operand (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
1216 int opindex,
1217 CGEN_FIELDS * fields,
1218 int value)
252b5132
RH
1219{
1220 switch (opindex)
1221 {
1222 case FR30_OPERAND_CRI :
1223 fields->f_CRi = value;
1224 break;
1225 case FR30_OPERAND_CRJ :
1226 fields->f_CRj = value;
1227 break;
1228 case FR30_OPERAND_R13 :
252b5132
RH
1229 break;
1230 case FR30_OPERAND_R14 :
252b5132
RH
1231 break;
1232 case FR30_OPERAND_R15 :
252b5132
RH
1233 break;
1234 case FR30_OPERAND_RI :
1235 fields->f_Ri = value;
1236 break;
1237 case FR30_OPERAND_RIC :
1238 fields->f_Ric = value;
1239 break;
1240 case FR30_OPERAND_RJ :
1241 fields->f_Rj = value;
1242 break;
1243 case FR30_OPERAND_RJC :
1244 fields->f_Rjc = value;
1245 break;
1246 case FR30_OPERAND_RS1 :
1247 fields->f_Rs1 = value;
1248 break;
1249 case FR30_OPERAND_RS2 :
1250 fields->f_Rs2 = value;
1251 break;
1252 case FR30_OPERAND_CC :
1253 fields->f_cc = value;
1254 break;
1255 case FR30_OPERAND_CCC :
1256 fields->f_ccc = value;
1257 break;
1258 case FR30_OPERAND_DIR10 :
1259 fields->f_dir10 = value;
1260 break;
1261 case FR30_OPERAND_DIR8 :
1262 fields->f_dir8 = value;
1263 break;
1264 case FR30_OPERAND_DIR9 :
1265 fields->f_dir9 = value;
1266 break;
1267 case FR30_OPERAND_DISP10 :
1268 fields->f_disp10 = value;
1269 break;
1270 case FR30_OPERAND_DISP8 :
1271 fields->f_disp8 = value;
1272 break;
1273 case FR30_OPERAND_DISP9 :
1274 fields->f_disp9 = value;
1275 break;
1276 case FR30_OPERAND_I20 :
1277 fields->f_i20 = value;
1278 break;
1279 case FR30_OPERAND_I32 :
1280 fields->f_i32 = value;
1281 break;
1282 case FR30_OPERAND_I8 :
1283 fields->f_i8 = value;
1284 break;
1285 case FR30_OPERAND_LABEL12 :
1286 fields->f_rel12 = value;
1287 break;
1288 case FR30_OPERAND_LABEL9 :
1289 fields->f_rel9 = value;
1290 break;
1291 case FR30_OPERAND_M4 :
1292 fields->f_m4 = value;
1293 break;
1294 case FR30_OPERAND_PS :
252b5132
RH
1295 break;
1296 case FR30_OPERAND_REGLIST_HI_LD :
1297 fields->f_reglist_hi_ld = value;
1298 break;
1299 case FR30_OPERAND_REGLIST_HI_ST :
1300 fields->f_reglist_hi_st = value;
1301 break;
1302 case FR30_OPERAND_REGLIST_LOW_LD :
1303 fields->f_reglist_low_ld = value;
1304 break;
1305 case FR30_OPERAND_REGLIST_LOW_ST :
1306 fields->f_reglist_low_st = value;
1307 break;
1308 case FR30_OPERAND_S10 :
1309 fields->f_s10 = value;
1310 break;
1311 case FR30_OPERAND_U10 :
1312 fields->f_u10 = value;
1313 break;
1314 case FR30_OPERAND_U4 :
1315 fields->f_u4 = value;
1316 break;
1317 case FR30_OPERAND_U4C :
1318 fields->f_u4c = value;
1319 break;
1320 case FR30_OPERAND_U8 :
1321 fields->f_u8 = value;
1322 break;
1323 case FR30_OPERAND_UDISP6 :
1324 fields->f_udisp6 = value;
1325 break;
1326
1327 default :
1328 /* xgettext:c-format */
1329 fprintf (stderr, _("Unrecognized field %d while setting int operand.\n"),
1330 opindex);
1331 abort ();
1332 }
1333}
1334
1335void
47b0e7ad
NC
1336fr30_cgen_set_vma_operand (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
1337 int opindex,
1338 CGEN_FIELDS * fields,
1339 bfd_vma value)
252b5132
RH
1340{
1341 switch (opindex)
1342 {
1343 case FR30_OPERAND_CRI :
1344 fields->f_CRi = value;
1345 break;
1346 case FR30_OPERAND_CRJ :
1347 fields->f_CRj = value;
1348 break;
1349 case FR30_OPERAND_R13 :
252b5132
RH
1350 break;
1351 case FR30_OPERAND_R14 :
252b5132
RH
1352 break;
1353 case FR30_OPERAND_R15 :
252b5132
RH
1354 break;
1355 case FR30_OPERAND_RI :
1356 fields->f_Ri = value;
1357 break;
1358 case FR30_OPERAND_RIC :
1359 fields->f_Ric = value;
1360 break;
1361 case FR30_OPERAND_RJ :
1362 fields->f_Rj = value;
1363 break;
1364 case FR30_OPERAND_RJC :
1365 fields->f_Rjc = value;
1366 break;
1367 case FR30_OPERAND_RS1 :
1368 fields->f_Rs1 = value;
1369 break;
1370 case FR30_OPERAND_RS2 :
1371 fields->f_Rs2 = value;
1372 break;
1373 case FR30_OPERAND_CC :
1374 fields->f_cc = value;
1375 break;
1376 case FR30_OPERAND_CCC :
1377 fields->f_ccc = value;
1378 break;
1379 case FR30_OPERAND_DIR10 :
1380 fields->f_dir10 = value;
1381 break;
1382 case FR30_OPERAND_DIR8 :
1383 fields->f_dir8 = value;
1384 break;
1385 case FR30_OPERAND_DIR9 :
1386 fields->f_dir9 = value;
1387 break;
1388 case FR30_OPERAND_DISP10 :
1389 fields->f_disp10 = value;
1390 break;
1391 case FR30_OPERAND_DISP8 :
1392 fields->f_disp8 = value;
1393 break;
1394 case FR30_OPERAND_DISP9 :
1395 fields->f_disp9 = value;
1396 break;
1397 case FR30_OPERAND_I20 :
1398 fields->f_i20 = value;
1399 break;
1400 case FR30_OPERAND_I32 :
1401 fields->f_i32 = value;
1402 break;
1403 case FR30_OPERAND_I8 :
1404 fields->f_i8 = value;
1405 break;
1406 case FR30_OPERAND_LABEL12 :
1407 fields->f_rel12 = value;
1408 break;
1409 case FR30_OPERAND_LABEL9 :
1410 fields->f_rel9 = value;
1411 break;
1412 case FR30_OPERAND_M4 :
1413 fields->f_m4 = value;
1414 break;
1415 case FR30_OPERAND_PS :
252b5132
RH
1416 break;
1417 case FR30_OPERAND_REGLIST_HI_LD :
1418 fields->f_reglist_hi_ld = value;
1419 break;
1420 case FR30_OPERAND_REGLIST_HI_ST :
1421 fields->f_reglist_hi_st = value;
1422 break;
1423 case FR30_OPERAND_REGLIST_LOW_LD :
1424 fields->f_reglist_low_ld = value;
1425 break;
1426 case FR30_OPERAND_REGLIST_LOW_ST :
1427 fields->f_reglist_low_st = value;
1428 break;
1429 case FR30_OPERAND_S10 :
1430 fields->f_s10 = value;
1431 break;
1432 case FR30_OPERAND_U10 :
1433 fields->f_u10 = value;
1434 break;
1435 case FR30_OPERAND_U4 :
1436 fields->f_u4 = value;
1437 break;
1438 case FR30_OPERAND_U4C :
1439 fields->f_u4c = value;
1440 break;
1441 case FR30_OPERAND_U8 :
1442 fields->f_u8 = value;
1443 break;
1444 case FR30_OPERAND_UDISP6 :
1445 fields->f_udisp6 = value;
1446 break;
1447
1448 default :
1449 /* xgettext:c-format */
1450 fprintf (stderr, _("Unrecognized field %d while setting vma operand.\n"),
1451 opindex);
1452 abort ();
1453 }
1454}
1455
1456/* Function to call before using the instruction builder tables. */
1457
1458void
47b0e7ad 1459fr30_cgen_init_ibld_table (CGEN_CPU_DESC cd)
252b5132
RH
1460{
1461 cd->insert_handlers = & fr30_cgen_insert_handlers[0];
1462 cd->extract_handlers = & fr30_cgen_extract_handlers[0];
1463
1464 cd->insert_operand = fr30_cgen_insert_operand;
1465 cd->extract_operand = fr30_cgen_extract_operand;
1466
1467 cd->get_int_operand = fr30_cgen_get_int_operand;
1468 cd->set_int_operand = fr30_cgen_set_int_operand;
1469 cd->get_vma_operand = fr30_cgen_get_vma_operand;
1470 cd->set_vma_operand = fr30_cgen_set_vma_operand;
1471}
This page took 0.455846 seconds and 4 git commands to generate.