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