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