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