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