source: trunk/src/binutils/opcodes/iq2000-ibld.c@ 2013

Last change on this file since 2013 was 607, checked in by bird, 22 years ago

Initial revision

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