2011-03-25 Tristan Gingold <gingold@adacore.com>
[binutils.git] / opcodes / mt-ibld.c
blob00110de7934863901e832eef3567c9c3567f8f15
1 /* Instruction building/extraction support for mt. -*- C -*-
3 THIS FILE IS MACHINE GENERATED WITH CGEN: Cpu tools GENerator.
4 - the resultant file is machine generated, cgen-ibld.in isn't
6 Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2005, 2006, 2007,
7 2008, 2010 Free Software Foundation, Inc.
9 This file is part of libopcodes.
11 This library is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation; either version 3, or (at your option)
14 any later version.
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.
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. */
25 /* ??? Eventually more and more of this stuff can go to cpu-independent files.
26 Keep that in mind. */
28 #include "sysdep.h"
29 #include <stdio.h>
30 #include "ansidecl.h"
31 #include "dis-asm.h"
32 #include "bfd.h"
33 #include "symcat.h"
34 #include "mt-desc.h"
35 #include "mt-opc.h"
36 #include "cgen/basic-modes.h"
37 #include "opintl.h"
38 #include "safe-ctype.h"
40 #undef min
41 #define min(a,b) ((a) < (b) ? (a) : (b))
42 #undef max
43 #define max(a,b) ((a) > (b) ? (a) : (b))
45 /* Used by the ifield rtx function. */
46 #define FLD(f) (fields->f)
48 static const char * insert_normal
49 (CGEN_CPU_DESC, long, unsigned int, unsigned int, unsigned int,
50 unsigned int, unsigned int, unsigned int, CGEN_INSN_BYTES_PTR);
51 static const char * insert_insn_normal
52 (CGEN_CPU_DESC, const CGEN_INSN *,
53 CGEN_FIELDS *, CGEN_INSN_BYTES_PTR, bfd_vma);
54 static int extract_normal
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 *);
58 static int extract_insn_normal
59 (CGEN_CPU_DESC, const CGEN_INSN *, CGEN_EXTRACT_INFO *,
60 CGEN_INSN_INT, CGEN_FIELDS *, bfd_vma);
61 #if CGEN_INT_INSN_P
62 static void put_insn_int_value
63 (CGEN_CPU_DESC, CGEN_INSN_BYTES_PTR, int, int, CGEN_INSN_INT);
64 #endif
65 #if ! CGEN_INT_INSN_P
66 static CGEN_INLINE void insert_1
67 (CGEN_CPU_DESC, unsigned long, int, int, int, unsigned char *);
68 static CGEN_INLINE int fill_cache
69 (CGEN_CPU_DESC, CGEN_EXTRACT_INFO *, int, int, bfd_vma);
70 static CGEN_INLINE long extract_1
71 (CGEN_CPU_DESC, CGEN_EXTRACT_INFO *, int, int, int, unsigned char *, bfd_vma);
72 #endif
74 /* Operand insertion. */
76 #if ! CGEN_INT_INSN_P
78 /* Subroutine of insert_normal. */
80 static CGEN_INLINE void
81 insert_1 (CGEN_CPU_DESC cd,
82 unsigned long value,
83 int start,
84 int length,
85 int word_length,
86 unsigned char *bufp)
88 unsigned long x,mask;
89 int shift;
91 x = cgen_get_insn_value (cd, bufp, word_length);
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);
101 cgen_put_insn_value (cd, bufp, word_length, (bfd_vma) x);
104 #endif /* ! CGEN_INT_INSN_P */
106 /* Default insertion routine.
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.
115 The result is an error message or NULL if success. */
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. */
122 static const char *
123 insert_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)
133 static char errbuf[100];
134 /* Written this way to avoid undefined behaviour. */
135 unsigned long mask = (((1L << (length - 1)) - 1) << 1) | 1;
137 /* If LENGTH is zero, this operand doesn't contribute to the value. */
138 if (length == 0)
139 return NULL;
141 if (word_length > 8 * sizeof (CGEN_INSN_INT))
142 abort ();
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)
148 if (word_offset == 0
149 && word_length > total_length)
150 word_length = total_length;
153 /* Ensure VALUE will fit. */
154 if (CGEN_BOOL_ATTR (attrs, CGEN_IFLD_SIGN_OPT))
156 long minval = - (1L << (length - 1));
157 unsigned long maxval = mask;
159 if ((value > 0 && (unsigned long) value > maxval)
160 || value < minval)
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;
169 else if (! CGEN_BOOL_ATTR (attrs, CGEN_IFLD_SIGNED))
171 unsigned long maxval = mask;
172 unsigned long val = (unsigned long) value;
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;
181 if (val > maxval)
183 /* xgettext:c-format */
184 sprintf (errbuf,
185 _("operand out of range (0x%lx not between 0 and 0x%lx)"),
186 val, maxval);
187 return errbuf;
190 else
192 if (! cgen_signed_overflow_ok_p (cd))
194 long minval = - (1L << (length - 1));
195 long maxval = (1L << (length - 1)) - 1;
197 if (value < minval || value > maxval)
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;
208 #if CGEN_INT_INSN_P
211 int shift;
213 if (CGEN_INSN_LSB0_P)
214 shift = (word_offset + start + 1) - length;
215 else
216 shift = total_length - (word_offset + start + length);
217 *buffer = (*buffer & ~(mask << shift)) | ((value & mask) << shift);
220 #else /* ! CGEN_INT_INSN_P */
223 unsigned char *bufp = (unsigned char *) buffer + word_offset / 8;
225 insert_1 (cd, value, start, length, word_length, bufp);
228 #endif /* ! CGEN_INT_INSN_P */
230 return NULL;
233 /* Default insn builder (insert handler).
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).
238 The result is an error message or NULL if success. */
240 static const char *
241 insert_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)
247 const CGEN_SYNTAX *syntax = CGEN_INSN_SYNTAX (insn);
248 unsigned long value;
249 const CGEN_SYNTAX_CHAR_TYPE * syn;
251 CGEN_INIT_INSERT (cd);
252 value = CGEN_INSN_BASE_VALUE (insn);
254 /* If we're recording insns as numbers (rather than a string of bytes),
255 target byte order handling is deferred until later. */
257 #if CGEN_INT_INSN_P
259 put_insn_int_value (cd, buffer, cd->base_insn_bitsize,
260 CGEN_FIELDS_BITSIZE (fields), value);
262 #else
264 cgen_put_insn_value (cd, buffer, min ((unsigned) cd->base_insn_bitsize,
265 (unsigned) CGEN_FIELDS_BITSIZE (fields)),
266 value);
268 #endif /* ! CGEN_INT_INSN_P */
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. */
275 for (syn = CGEN_SYNTAX_STRING (syntax); * syn; ++ syn)
277 const char *errmsg;
279 if (CGEN_SYNTAX_CHAR_P (* syn))
280 continue;
282 errmsg = (* cd->insert_operand) (cd, CGEN_SYNTAX_FIELD (*syn),
283 fields, buffer, pc);
284 if (errmsg)
285 return errmsg;
288 return NULL;
291 #if CGEN_INT_INSN_P
292 /* Cover function to store an insn value into an integral insn. Must go here
293 because it needs <prefix>-desc.h for CGEN_INT_INSN_P. */
295 static void
296 put_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)
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
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;
312 *buf = (*buf & ~(mask << shift)) | ((value & mask) << shift);
315 #endif
317 /* Operand extraction. */
319 #if ! CGEN_INT_INSN_P
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. */
327 static CGEN_INLINE int
328 fill_cache (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
329 CGEN_EXTRACT_INFO *ex_info,
330 int offset,
331 int bytes,
332 bfd_vma pc)
334 /* It's doubtful that the middle part has already been fetched so
335 we don't optimize that case. kiss. */
336 unsigned int mask;
337 disassemble_info *info = (disassemble_info *) ex_info->dis_info;
339 /* First do a quick check. */
340 mask = (1 << bytes) - 1;
341 if (((ex_info->valid >> offset) & mask) == mask)
342 return 1;
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;
349 if (bytes)
351 int status;
353 pc += offset;
354 status = (*info->read_memory_func)
355 (pc, ex_info->insn_bytes + offset, bytes, info);
357 if (status != 0)
359 (*info->memory_error_func) (status, pc, info);
360 return 0;
363 ex_info->valid |= ((1 << bytes) - 1) << offset;
366 return 1;
369 /* Subroutine of extract_normal. */
371 static CGEN_INLINE long
372 extract_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)
380 unsigned long x;
381 int shift;
383 x = cgen_get_insn_value (cd, bufp, word_length);
385 if (CGEN_INSN_LSB0_P)
386 shift = (start + 1) - length;
387 else
388 shift = (word_length - (start + length));
389 return x >> shift;
392 #endif /* ! CGEN_INT_INSN_P */
394 /* Default extraction routine.
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.
407 Returns 1 for success, 0 for failure. */
409 /* ??? The return code isn't properly used. wip. */
411 /* ??? This doesn't handle bfd_vma's. Create another function when
412 necessary. */
414 static int
415 extract_normal (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,
424 unsigned int start,
425 unsigned int length,
426 unsigned int word_length,
427 unsigned int total_length,
428 #if ! CGEN_INT_INSN_P
429 bfd_vma pc,
430 #else
431 bfd_vma pc ATTRIBUTE_UNUSED,
432 #endif
433 long *valuep)
435 long value, mask;
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)
441 *valuep = 0;
442 return 1;
445 if (word_length > 8 * sizeof (CGEN_INSN_INT))
446 abort ();
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)
452 if (word_offset + word_length > total_length)
453 word_length = total_length - word_offset;
456 /* Does the value reside in INSN_VALUE, and at the right alignment? */
458 if (CGEN_INT_INSN_P || (word_offset == 0 && word_length == total_length))
460 if (CGEN_INSN_LSB0_P)
461 value = insn_value >> ((word_offset + start + 1) - length);
462 else
463 value = insn_value >> (total_length - ( word_offset + start + length));
466 #if ! CGEN_INT_INSN_P
468 else
470 unsigned char *bufp = ex_info->insn_bytes + word_offset / 8;
472 if (word_length > 8 * sizeof (CGEN_INSN_INT))
473 abort ();
475 if (fill_cache (cd, ex_info, word_offset / 8, word_length / 8, pc) == 0)
476 return 0;
478 value = extract_1 (cd, ex_info, start, length, word_length, bufp, pc);
481 #endif /* ! CGEN_INT_INSN_P */
483 /* Written this way to avoid undefined behaviour. */
484 mask = (((1L << (length - 1)) - 1) << 1) | 1;
486 value &= mask;
487 /* sign extend? */
488 if (CGEN_BOOL_ATTR (attrs, CGEN_IFLD_SIGNED)
489 && (value & (1L << (length - 1))))
490 value |= ~mask;
492 *valuep = value;
494 return 1;
497 /* Default insn extractor.
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). */
506 static int
507 extract_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)
514 const CGEN_SYNTAX *syntax = CGEN_INSN_SYNTAX (insn);
515 const CGEN_SYNTAX_CHAR_TYPE *syn;
517 CGEN_FIELDS_BITSIZE (fields) = CGEN_INSN_BITSIZE (insn);
519 CGEN_INIT_EXTRACT (cd);
521 for (syn = CGEN_SYNTAX_STRING (syntax); *syn; ++syn)
523 int length;
525 if (CGEN_SYNTAX_CHAR_P (*syn))
526 continue;
528 length = (* cd->extract_operand) (cd, CGEN_SYNTAX_FIELD (*syn),
529 ex_info, insn_value, fields, pc);
530 if (length <= 0)
531 return length;
534 /* We recognized and successfully extracted this insn. */
535 return CGEN_INSN_BITSIZE (insn);
538 /* Machine generated code added here. */
540 const char * mt_cgen_insert_operand
541 (CGEN_CPU_DESC, int, CGEN_FIELDS *, CGEN_INSN_BYTES_PTR, bfd_vma);
543 /* Main entry point for operand insertion.
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.
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
555 resolved during parsing. */
557 const char *
558 mt_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)
564 const char * errmsg = NULL;
565 unsigned int total_length = CGEN_FIELDS_BITSIZE (fields);
567 switch (opindex)
569 case MT_OPERAND_A23 :
570 errmsg = insert_normal (cd, fields->f_a23, 0, 0, 23, 1, 32, total_length, buffer);
571 break;
572 case MT_OPERAND_BALL :
573 errmsg = insert_normal (cd, fields->f_ball, 0, 0, 19, 1, 32, total_length, buffer);
574 break;
575 case MT_OPERAND_BALL2 :
576 errmsg = insert_normal (cd, fields->f_ball2, 0, 0, 15, 1, 32, total_length, buffer);
577 break;
578 case MT_OPERAND_BANKADDR :
579 errmsg = insert_normal (cd, fields->f_bankaddr, 0, 0, 25, 13, 32, total_length, buffer);
580 break;
581 case MT_OPERAND_BRC :
582 errmsg = insert_normal (cd, fields->f_brc, 0, 0, 18, 3, 32, total_length, buffer);
583 break;
584 case MT_OPERAND_BRC2 :
585 errmsg = insert_normal (cd, fields->f_brc2, 0, 0, 14, 3, 32, total_length, buffer);
586 break;
587 case MT_OPERAND_CB1INCR :
588 errmsg = insert_normal (cd, fields->f_cb1incr, 0|(1<<CGEN_IFLD_SIGNED), 0, 19, 6, 32, total_length, buffer);
589 break;
590 case MT_OPERAND_CB1SEL :
591 errmsg = insert_normal (cd, fields->f_cb1sel, 0, 0, 25, 3, 32, total_length, buffer);
592 break;
593 case MT_OPERAND_CB2INCR :
594 errmsg = insert_normal (cd, fields->f_cb2incr, 0|(1<<CGEN_IFLD_SIGNED), 0, 13, 6, 32, total_length, buffer);
595 break;
596 case MT_OPERAND_CB2SEL :
597 errmsg = insert_normal (cd, fields->f_cb2sel, 0, 0, 22, 3, 32, total_length, buffer);
598 break;
599 case MT_OPERAND_CBRB :
600 errmsg = insert_normal (cd, fields->f_cbrb, 0, 0, 10, 1, 32, total_length, buffer);
601 break;
602 case MT_OPERAND_CBS :
603 errmsg = insert_normal (cd, fields->f_cbs, 0, 0, 19, 2, 32, total_length, buffer);
604 break;
605 case MT_OPERAND_CBX :
606 errmsg = insert_normal (cd, fields->f_cbx, 0, 0, 14, 3, 32, total_length, buffer);
607 break;
608 case MT_OPERAND_CCB :
609 errmsg = insert_normal (cd, fields->f_ccb, 0, 0, 11, 1, 32, total_length, buffer);
610 break;
611 case MT_OPERAND_CDB :
612 errmsg = insert_normal (cd, fields->f_cdb, 0, 0, 10, 1, 32, total_length, buffer);
613 break;
614 case MT_OPERAND_CELL :
615 errmsg = insert_normal (cd, fields->f_cell, 0, 0, 9, 3, 32, total_length, buffer);
616 break;
617 case MT_OPERAND_COLNUM :
618 errmsg = insert_normal (cd, fields->f_colnum, 0, 0, 18, 3, 32, total_length, buffer);
619 break;
620 case MT_OPERAND_CONTNUM :
621 errmsg = insert_normal (cd, fields->f_contnum, 0, 0, 8, 9, 32, total_length, buffer);
622 break;
623 case MT_OPERAND_CR :
624 errmsg = insert_normal (cd, fields->f_cr, 0, 0, 22, 3, 32, total_length, buffer);
625 break;
626 case MT_OPERAND_CTXDISP :
627 errmsg = insert_normal (cd, fields->f_ctxdisp, 0, 0, 5, 6, 32, total_length, buffer);
628 break;
629 case MT_OPERAND_DUP :
630 errmsg = insert_normal (cd, fields->f_dup, 0, 0, 6, 1, 32, total_length, buffer);
631 break;
632 case MT_OPERAND_FBDISP :
633 errmsg = insert_normal (cd, fields->f_fbdisp, 0, 0, 15, 6, 32, total_length, buffer);
634 break;
635 case MT_OPERAND_FBINCR :
636 errmsg = insert_normal (cd, fields->f_fbincr, 0, 0, 23, 4, 32, total_length, buffer);
637 break;
638 case MT_OPERAND_FRDR :
639 errmsg = insert_normal (cd, fields->f_dr, 0|(1<<CGEN_IFLD_ABS_ADDR), 0, 19, 4, 32, total_length, buffer);
640 break;
641 case MT_OPERAND_FRDRRR :
642 errmsg = insert_normal (cd, fields->f_drrr, 0|(1<<CGEN_IFLD_ABS_ADDR), 0, 15, 4, 32, total_length, buffer);
643 break;
644 case MT_OPERAND_FRSR1 :
645 errmsg = insert_normal (cd, fields->f_sr1, 0|(1<<CGEN_IFLD_ABS_ADDR), 0, 23, 4, 32, total_length, buffer);
646 break;
647 case MT_OPERAND_FRSR2 :
648 errmsg = insert_normal (cd, fields->f_sr2, 0|(1<<CGEN_IFLD_ABS_ADDR), 0, 19, 4, 32, total_length, buffer);
649 break;
650 case MT_OPERAND_ID :
651 errmsg = insert_normal (cd, fields->f_id, 0, 0, 14, 1, 32, total_length, buffer);
652 break;
653 case MT_OPERAND_IMM16 :
655 long value = fields->f_imm16s;
656 value = ((value) + (0));
657 errmsg = insert_normal (cd, value, 0|(1<<CGEN_IFLD_SIGNED), 0, 15, 16, 32, total_length, buffer);
659 break;
660 case MT_OPERAND_IMM16L :
661 errmsg = insert_normal (cd, fields->f_imm16l, 0, 0, 23, 16, 32, total_length, buffer);
662 break;
663 case MT_OPERAND_IMM16O :
665 long value = fields->f_imm16s;
666 value = ((value) + (0));
667 errmsg = insert_normal (cd, value, 0|(1<<CGEN_IFLD_SIGNED), 0, 15, 16, 32, total_length, buffer);
669 break;
670 case MT_OPERAND_IMM16Z :
671 errmsg = insert_normal (cd, fields->f_imm16u, 0, 0, 15, 16, 32, total_length, buffer);
672 break;
673 case MT_OPERAND_INCAMT :
674 errmsg = insert_normal (cd, fields->f_incamt, 0, 0, 19, 8, 32, total_length, buffer);
675 break;
676 case MT_OPERAND_INCR :
677 errmsg = insert_normal (cd, fields->f_incr, 0, 0, 17, 6, 32, total_length, buffer);
678 break;
679 case MT_OPERAND_LENGTH :
680 errmsg = insert_normal (cd, fields->f_length, 0, 0, 15, 3, 32, total_length, buffer);
681 break;
682 case MT_OPERAND_LOOPSIZE :
684 long value = fields->f_loopo;
685 value = ((USI) (value) >> (2));
686 errmsg = insert_normal (cd, value, 0, 0, 7, 8, 32, total_length, buffer);
688 break;
689 case MT_OPERAND_MASK :
690 errmsg = insert_normal (cd, fields->f_mask, 0, 0, 25, 16, 32, total_length, buffer);
691 break;
692 case MT_OPERAND_MASK1 :
693 errmsg = insert_normal (cd, fields->f_mask1, 0, 0, 22, 3, 32, total_length, buffer);
694 break;
695 case MT_OPERAND_MODE :
696 errmsg = insert_normal (cd, fields->f_mode, 0, 0, 25, 2, 32, total_length, buffer);
697 break;
698 case MT_OPERAND_PERM :
699 errmsg = insert_normal (cd, fields->f_perm, 0, 0, 25, 2, 32, total_length, buffer);
700 break;
701 case MT_OPERAND_RBBC :
702 errmsg = insert_normal (cd, fields->f_rbbc, 0, 0, 25, 2, 32, total_length, buffer);
703 break;
704 case MT_OPERAND_RC :
705 errmsg = insert_normal (cd, fields->f_rc, 0, 0, 15, 1, 32, total_length, buffer);
706 break;
707 case MT_OPERAND_RC1 :
708 errmsg = insert_normal (cd, fields->f_rc1, 0, 0, 11, 1, 32, total_length, buffer);
709 break;
710 case MT_OPERAND_RC2 :
711 errmsg = insert_normal (cd, fields->f_rc2, 0, 0, 6, 1, 32, total_length, buffer);
712 break;
713 case MT_OPERAND_RC3 :
714 errmsg = insert_normal (cd, fields->f_rc3, 0, 0, 7, 1, 32, total_length, buffer);
715 break;
716 case MT_OPERAND_RCNUM :
717 errmsg = insert_normal (cd, fields->f_rcnum, 0, 0, 14, 3, 32, total_length, buffer);
718 break;
719 case MT_OPERAND_RDA :
720 errmsg = insert_normal (cd, fields->f_rda, 0, 0, 25, 1, 32, total_length, buffer);
721 break;
722 case MT_OPERAND_ROWNUM :
723 errmsg = insert_normal (cd, fields->f_rownum, 0, 0, 14, 3, 32, total_length, buffer);
724 break;
725 case MT_OPERAND_ROWNUM1 :
726 errmsg = insert_normal (cd, fields->f_rownum1, 0, 0, 12, 3, 32, total_length, buffer);
727 break;
728 case MT_OPERAND_ROWNUM2 :
729 errmsg = insert_normal (cd, fields->f_rownum2, 0, 0, 9, 3, 32, total_length, buffer);
730 break;
731 case MT_OPERAND_SIZE :
732 errmsg = insert_normal (cd, fields->f_size, 0, 0, 13, 14, 32, total_length, buffer);
733 break;
734 case MT_OPERAND_TYPE :
735 errmsg = insert_normal (cd, fields->f_type, 0, 0, 21, 2, 32, total_length, buffer);
736 break;
737 case MT_OPERAND_WR :
738 errmsg = insert_normal (cd, fields->f_wr, 0, 0, 24, 1, 32, total_length, buffer);
739 break;
740 case MT_OPERAND_XMODE :
741 errmsg = insert_normal (cd, fields->f_xmode, 0, 0, 23, 1, 32, total_length, buffer);
742 break;
744 default :
745 /* xgettext:c-format */
746 fprintf (stderr, _("Unrecognized field %d while building insn.\n"),
747 opindex);
748 abort ();
751 return errmsg;
754 int mt_cgen_extract_operand
755 (CGEN_CPU_DESC, int, CGEN_EXTRACT_INFO *, CGEN_INSN_INT, CGEN_FIELDS *, bfd_vma);
757 /* Main entry point for operand extraction.
758 The result is <= 0 for error, >0 for success.
759 ??? Actual values aren't well defined right now.
761 This function is basically just a big switch statement. Earlier versions
762 used tables to look up the function to use, but
763 - if the table contains both assembler and disassembler functions then
764 the disassembler contains much of the assembler and vice-versa,
765 - there's a lot of inlining possibilities as things grow,
766 - using a switch statement avoids the function call overhead.
768 This function could be moved into `print_insn_normal', but keeping it
769 separate makes clear the interface between `print_insn_normal' and each of
770 the handlers. */
773 mt_cgen_extract_operand (CGEN_CPU_DESC cd,
774 int opindex,
775 CGEN_EXTRACT_INFO *ex_info,
776 CGEN_INSN_INT insn_value,
777 CGEN_FIELDS * fields,
778 bfd_vma pc)
780 /* Assume success (for those operands that are nops). */
781 int length = 1;
782 unsigned int total_length = CGEN_FIELDS_BITSIZE (fields);
784 switch (opindex)
786 case MT_OPERAND_A23 :
787 length = extract_normal (cd, ex_info, insn_value, 0, 0, 23, 1, 32, total_length, pc, & fields->f_a23);
788 break;
789 case MT_OPERAND_BALL :
790 length = extract_normal (cd, ex_info, insn_value, 0, 0, 19, 1, 32, total_length, pc, & fields->f_ball);
791 break;
792 case MT_OPERAND_BALL2 :
793 length = extract_normal (cd, ex_info, insn_value, 0, 0, 15, 1, 32, total_length, pc, & fields->f_ball2);
794 break;
795 case MT_OPERAND_BANKADDR :
796 length = extract_normal (cd, ex_info, insn_value, 0, 0, 25, 13, 32, total_length, pc, & fields->f_bankaddr);
797 break;
798 case MT_OPERAND_BRC :
799 length = extract_normal (cd, ex_info, insn_value, 0, 0, 18, 3, 32, total_length, pc, & fields->f_brc);
800 break;
801 case MT_OPERAND_BRC2 :
802 length = extract_normal (cd, ex_info, insn_value, 0, 0, 14, 3, 32, total_length, pc, & fields->f_brc2);
803 break;
804 case MT_OPERAND_CB1INCR :
805 length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_SIGNED), 0, 19, 6, 32, total_length, pc, & fields->f_cb1incr);
806 break;
807 case MT_OPERAND_CB1SEL :
808 length = extract_normal (cd, ex_info, insn_value, 0, 0, 25, 3, 32, total_length, pc, & fields->f_cb1sel);
809 break;
810 case MT_OPERAND_CB2INCR :
811 length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_SIGNED), 0, 13, 6, 32, total_length, pc, & fields->f_cb2incr);
812 break;
813 case MT_OPERAND_CB2SEL :
814 length = extract_normal (cd, ex_info, insn_value, 0, 0, 22, 3, 32, total_length, pc, & fields->f_cb2sel);
815 break;
816 case MT_OPERAND_CBRB :
817 length = extract_normal (cd, ex_info, insn_value, 0, 0, 10, 1, 32, total_length, pc, & fields->f_cbrb);
818 break;
819 case MT_OPERAND_CBS :
820 length = extract_normal (cd, ex_info, insn_value, 0, 0, 19, 2, 32, total_length, pc, & fields->f_cbs);
821 break;
822 case MT_OPERAND_CBX :
823 length = extract_normal (cd, ex_info, insn_value, 0, 0, 14, 3, 32, total_length, pc, & fields->f_cbx);
824 break;
825 case MT_OPERAND_CCB :
826 length = extract_normal (cd, ex_info, insn_value, 0, 0, 11, 1, 32, total_length, pc, & fields->f_ccb);
827 break;
828 case MT_OPERAND_CDB :
829 length = extract_normal (cd, ex_info, insn_value, 0, 0, 10, 1, 32, total_length, pc, & fields->f_cdb);
830 break;
831 case MT_OPERAND_CELL :
832 length = extract_normal (cd, ex_info, insn_value, 0, 0, 9, 3, 32, total_length, pc, & fields->f_cell);
833 break;
834 case MT_OPERAND_COLNUM :
835 length = extract_normal (cd, ex_info, insn_value, 0, 0, 18, 3, 32, total_length, pc, & fields->f_colnum);
836 break;
837 case MT_OPERAND_CONTNUM :
838 length = extract_normal (cd, ex_info, insn_value, 0, 0, 8, 9, 32, total_length, pc, & fields->f_contnum);
839 break;
840 case MT_OPERAND_CR :
841 length = extract_normal (cd, ex_info, insn_value, 0, 0, 22, 3, 32, total_length, pc, & fields->f_cr);
842 break;
843 case MT_OPERAND_CTXDISP :
844 length = extract_normal (cd, ex_info, insn_value, 0, 0, 5, 6, 32, total_length, pc, & fields->f_ctxdisp);
845 break;
846 case MT_OPERAND_DUP :
847 length = extract_normal (cd, ex_info, insn_value, 0, 0, 6, 1, 32, total_length, pc, & fields->f_dup);
848 break;
849 case MT_OPERAND_FBDISP :
850 length = extract_normal (cd, ex_info, insn_value, 0, 0, 15, 6, 32, total_length, pc, & fields->f_fbdisp);
851 break;
852 case MT_OPERAND_FBINCR :
853 length = extract_normal (cd, ex_info, insn_value, 0, 0, 23, 4, 32, total_length, pc, & fields->f_fbincr);
854 break;
855 case MT_OPERAND_FRDR :
856 length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_ABS_ADDR), 0, 19, 4, 32, total_length, pc, & fields->f_dr);
857 break;
858 case MT_OPERAND_FRDRRR :
859 length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_ABS_ADDR), 0, 15, 4, 32, total_length, pc, & fields->f_drrr);
860 break;
861 case MT_OPERAND_FRSR1 :
862 length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_ABS_ADDR), 0, 23, 4, 32, total_length, pc, & fields->f_sr1);
863 break;
864 case MT_OPERAND_FRSR2 :
865 length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_ABS_ADDR), 0, 19, 4, 32, total_length, pc, & fields->f_sr2);
866 break;
867 case MT_OPERAND_ID :
868 length = extract_normal (cd, ex_info, insn_value, 0, 0, 14, 1, 32, total_length, pc, & fields->f_id);
869 break;
870 case MT_OPERAND_IMM16 :
872 long value;
873 length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_SIGNED), 0, 15, 16, 32, total_length, pc, & value);
874 value = ((value) + (0));
875 fields->f_imm16s = value;
877 break;
878 case MT_OPERAND_IMM16L :
879 length = extract_normal (cd, ex_info, insn_value, 0, 0, 23, 16, 32, total_length, pc, & fields->f_imm16l);
880 break;
881 case MT_OPERAND_IMM16O :
883 long value;
884 length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_SIGNED), 0, 15, 16, 32, total_length, pc, & value);
885 value = ((value) + (0));
886 fields->f_imm16s = value;
888 break;
889 case MT_OPERAND_IMM16Z :
890 length = extract_normal (cd, ex_info, insn_value, 0, 0, 15, 16, 32, total_length, pc, & fields->f_imm16u);
891 break;
892 case MT_OPERAND_INCAMT :
893 length = extract_normal (cd, ex_info, insn_value, 0, 0, 19, 8, 32, total_length, pc, & fields->f_incamt);
894 break;
895 case MT_OPERAND_INCR :
896 length = extract_normal (cd, ex_info, insn_value, 0, 0, 17, 6, 32, total_length, pc, & fields->f_incr);
897 break;
898 case MT_OPERAND_LENGTH :
899 length = extract_normal (cd, ex_info, insn_value, 0, 0, 15, 3, 32, total_length, pc, & fields->f_length);
900 break;
901 case MT_OPERAND_LOOPSIZE :
903 long value;
904 length = extract_normal (cd, ex_info, insn_value, 0, 0, 7, 8, 32, total_length, pc, & value);
905 value = ((((value) << (2))) + (8));
906 fields->f_loopo = value;
908 break;
909 case MT_OPERAND_MASK :
910 length = extract_normal (cd, ex_info, insn_value, 0, 0, 25, 16, 32, total_length, pc, & fields->f_mask);
911 break;
912 case MT_OPERAND_MASK1 :
913 length = extract_normal (cd, ex_info, insn_value, 0, 0, 22, 3, 32, total_length, pc, & fields->f_mask1);
914 break;
915 case MT_OPERAND_MODE :
916 length = extract_normal (cd, ex_info, insn_value, 0, 0, 25, 2, 32, total_length, pc, & fields->f_mode);
917 break;
918 case MT_OPERAND_PERM :
919 length = extract_normal (cd, ex_info, insn_value, 0, 0, 25, 2, 32, total_length, pc, & fields->f_perm);
920 break;
921 case MT_OPERAND_RBBC :
922 length = extract_normal (cd, ex_info, insn_value, 0, 0, 25, 2, 32, total_length, pc, & fields->f_rbbc);
923 break;
924 case MT_OPERAND_RC :
925 length = extract_normal (cd, ex_info, insn_value, 0, 0, 15, 1, 32, total_length, pc, & fields->f_rc);
926 break;
927 case MT_OPERAND_RC1 :
928 length = extract_normal (cd, ex_info, insn_value, 0, 0, 11, 1, 32, total_length, pc, & fields->f_rc1);
929 break;
930 case MT_OPERAND_RC2 :
931 length = extract_normal (cd, ex_info, insn_value, 0, 0, 6, 1, 32, total_length, pc, & fields->f_rc2);
932 break;
933 case MT_OPERAND_RC3 :
934 length = extract_normal (cd, ex_info, insn_value, 0, 0, 7, 1, 32, total_length, pc, & fields->f_rc3);
935 break;
936 case MT_OPERAND_RCNUM :
937 length = extract_normal (cd, ex_info, insn_value, 0, 0, 14, 3, 32, total_length, pc, & fields->f_rcnum);
938 break;
939 case MT_OPERAND_RDA :
940 length = extract_normal (cd, ex_info, insn_value, 0, 0, 25, 1, 32, total_length, pc, & fields->f_rda);
941 break;
942 case MT_OPERAND_ROWNUM :
943 length = extract_normal (cd, ex_info, insn_value, 0, 0, 14, 3, 32, total_length, pc, & fields->f_rownum);
944 break;
945 case MT_OPERAND_ROWNUM1 :
946 length = extract_normal (cd, ex_info, insn_value, 0, 0, 12, 3, 32, total_length, pc, & fields->f_rownum1);
947 break;
948 case MT_OPERAND_ROWNUM2 :
949 length = extract_normal (cd, ex_info, insn_value, 0, 0, 9, 3, 32, total_length, pc, & fields->f_rownum2);
950 break;
951 case MT_OPERAND_SIZE :
952 length = extract_normal (cd, ex_info, insn_value, 0, 0, 13, 14, 32, total_length, pc, & fields->f_size);
953 break;
954 case MT_OPERAND_TYPE :
955 length = extract_normal (cd, ex_info, insn_value, 0, 0, 21, 2, 32, total_length, pc, & fields->f_type);
956 break;
957 case MT_OPERAND_WR :
958 length = extract_normal (cd, ex_info, insn_value, 0, 0, 24, 1, 32, total_length, pc, & fields->f_wr);
959 break;
960 case MT_OPERAND_XMODE :
961 length = extract_normal (cd, ex_info, insn_value, 0, 0, 23, 1, 32, total_length, pc, & fields->f_xmode);
962 break;
964 default :
965 /* xgettext:c-format */
966 fprintf (stderr, _("Unrecognized field %d while decoding insn.\n"),
967 opindex);
968 abort ();
971 return length;
974 cgen_insert_fn * const mt_cgen_insert_handlers[] =
976 insert_insn_normal,
979 cgen_extract_fn * const mt_cgen_extract_handlers[] =
981 extract_insn_normal,
984 int mt_cgen_get_int_operand (CGEN_CPU_DESC, int, const CGEN_FIELDS *);
985 bfd_vma mt_cgen_get_vma_operand (CGEN_CPU_DESC, int, const CGEN_FIELDS *);
987 /* Getting values from cgen_fields is handled by a collection of functions.
988 They are distinguished by the type of the VALUE argument they return.
989 TODO: floating point, inlining support, remove cases where result type
990 not appropriate. */
993 mt_cgen_get_int_operand (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
994 int opindex,
995 const CGEN_FIELDS * fields)
997 int value;
999 switch (opindex)
1001 case MT_OPERAND_A23 :
1002 value = fields->f_a23;
1003 break;
1004 case MT_OPERAND_BALL :
1005 value = fields->f_ball;
1006 break;
1007 case MT_OPERAND_BALL2 :
1008 value = fields->f_ball2;
1009 break;
1010 case MT_OPERAND_BANKADDR :
1011 value = fields->f_bankaddr;
1012 break;
1013 case MT_OPERAND_BRC :
1014 value = fields->f_brc;
1015 break;
1016 case MT_OPERAND_BRC2 :
1017 value = fields->f_brc2;
1018 break;
1019 case MT_OPERAND_CB1INCR :
1020 value = fields->f_cb1incr;
1021 break;
1022 case MT_OPERAND_CB1SEL :
1023 value = fields->f_cb1sel;
1024 break;
1025 case MT_OPERAND_CB2INCR :
1026 value = fields->f_cb2incr;
1027 break;
1028 case MT_OPERAND_CB2SEL :
1029 value = fields->f_cb2sel;
1030 break;
1031 case MT_OPERAND_CBRB :
1032 value = fields->f_cbrb;
1033 break;
1034 case MT_OPERAND_CBS :
1035 value = fields->f_cbs;
1036 break;
1037 case MT_OPERAND_CBX :
1038 value = fields->f_cbx;
1039 break;
1040 case MT_OPERAND_CCB :
1041 value = fields->f_ccb;
1042 break;
1043 case MT_OPERAND_CDB :
1044 value = fields->f_cdb;
1045 break;
1046 case MT_OPERAND_CELL :
1047 value = fields->f_cell;
1048 break;
1049 case MT_OPERAND_COLNUM :
1050 value = fields->f_colnum;
1051 break;
1052 case MT_OPERAND_CONTNUM :
1053 value = fields->f_contnum;
1054 break;
1055 case MT_OPERAND_CR :
1056 value = fields->f_cr;
1057 break;
1058 case MT_OPERAND_CTXDISP :
1059 value = fields->f_ctxdisp;
1060 break;
1061 case MT_OPERAND_DUP :
1062 value = fields->f_dup;
1063 break;
1064 case MT_OPERAND_FBDISP :
1065 value = fields->f_fbdisp;
1066 break;
1067 case MT_OPERAND_FBINCR :
1068 value = fields->f_fbincr;
1069 break;
1070 case MT_OPERAND_FRDR :
1071 value = fields->f_dr;
1072 break;
1073 case MT_OPERAND_FRDRRR :
1074 value = fields->f_drrr;
1075 break;
1076 case MT_OPERAND_FRSR1 :
1077 value = fields->f_sr1;
1078 break;
1079 case MT_OPERAND_FRSR2 :
1080 value = fields->f_sr2;
1081 break;
1082 case MT_OPERAND_ID :
1083 value = fields->f_id;
1084 break;
1085 case MT_OPERAND_IMM16 :
1086 value = fields->f_imm16s;
1087 break;
1088 case MT_OPERAND_IMM16L :
1089 value = fields->f_imm16l;
1090 break;
1091 case MT_OPERAND_IMM16O :
1092 value = fields->f_imm16s;
1093 break;
1094 case MT_OPERAND_IMM16Z :
1095 value = fields->f_imm16u;
1096 break;
1097 case MT_OPERAND_INCAMT :
1098 value = fields->f_incamt;
1099 break;
1100 case MT_OPERAND_INCR :
1101 value = fields->f_incr;
1102 break;
1103 case MT_OPERAND_LENGTH :
1104 value = fields->f_length;
1105 break;
1106 case MT_OPERAND_LOOPSIZE :
1107 value = fields->f_loopo;
1108 break;
1109 case MT_OPERAND_MASK :
1110 value = fields->f_mask;
1111 break;
1112 case MT_OPERAND_MASK1 :
1113 value = fields->f_mask1;
1114 break;
1115 case MT_OPERAND_MODE :
1116 value = fields->f_mode;
1117 break;
1118 case MT_OPERAND_PERM :
1119 value = fields->f_perm;
1120 break;
1121 case MT_OPERAND_RBBC :
1122 value = fields->f_rbbc;
1123 break;
1124 case MT_OPERAND_RC :
1125 value = fields->f_rc;
1126 break;
1127 case MT_OPERAND_RC1 :
1128 value = fields->f_rc1;
1129 break;
1130 case MT_OPERAND_RC2 :
1131 value = fields->f_rc2;
1132 break;
1133 case MT_OPERAND_RC3 :
1134 value = fields->f_rc3;
1135 break;
1136 case MT_OPERAND_RCNUM :
1137 value = fields->f_rcnum;
1138 break;
1139 case MT_OPERAND_RDA :
1140 value = fields->f_rda;
1141 break;
1142 case MT_OPERAND_ROWNUM :
1143 value = fields->f_rownum;
1144 break;
1145 case MT_OPERAND_ROWNUM1 :
1146 value = fields->f_rownum1;
1147 break;
1148 case MT_OPERAND_ROWNUM2 :
1149 value = fields->f_rownum2;
1150 break;
1151 case MT_OPERAND_SIZE :
1152 value = fields->f_size;
1153 break;
1154 case MT_OPERAND_TYPE :
1155 value = fields->f_type;
1156 break;
1157 case MT_OPERAND_WR :
1158 value = fields->f_wr;
1159 break;
1160 case MT_OPERAND_XMODE :
1161 value = fields->f_xmode;
1162 break;
1164 default :
1165 /* xgettext:c-format */
1166 fprintf (stderr, _("Unrecognized field %d while getting int operand.\n"),
1167 opindex);
1168 abort ();
1171 return value;
1174 bfd_vma
1175 mt_cgen_get_vma_operand (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
1176 int opindex,
1177 const CGEN_FIELDS * fields)
1179 bfd_vma value;
1181 switch (opindex)
1183 case MT_OPERAND_A23 :
1184 value = fields->f_a23;
1185 break;
1186 case MT_OPERAND_BALL :
1187 value = fields->f_ball;
1188 break;
1189 case MT_OPERAND_BALL2 :
1190 value = fields->f_ball2;
1191 break;
1192 case MT_OPERAND_BANKADDR :
1193 value = fields->f_bankaddr;
1194 break;
1195 case MT_OPERAND_BRC :
1196 value = fields->f_brc;
1197 break;
1198 case MT_OPERAND_BRC2 :
1199 value = fields->f_brc2;
1200 break;
1201 case MT_OPERAND_CB1INCR :
1202 value = fields->f_cb1incr;
1203 break;
1204 case MT_OPERAND_CB1SEL :
1205 value = fields->f_cb1sel;
1206 break;
1207 case MT_OPERAND_CB2INCR :
1208 value = fields->f_cb2incr;
1209 break;
1210 case MT_OPERAND_CB2SEL :
1211 value = fields->f_cb2sel;
1212 break;
1213 case MT_OPERAND_CBRB :
1214 value = fields->f_cbrb;
1215 break;
1216 case MT_OPERAND_CBS :
1217 value = fields->f_cbs;
1218 break;
1219 case MT_OPERAND_CBX :
1220 value = fields->f_cbx;
1221 break;
1222 case MT_OPERAND_CCB :
1223 value = fields->f_ccb;
1224 break;
1225 case MT_OPERAND_CDB :
1226 value = fields->f_cdb;
1227 break;
1228 case MT_OPERAND_CELL :
1229 value = fields->f_cell;
1230 break;
1231 case MT_OPERAND_COLNUM :
1232 value = fields->f_colnum;
1233 break;
1234 case MT_OPERAND_CONTNUM :
1235 value = fields->f_contnum;
1236 break;
1237 case MT_OPERAND_CR :
1238 value = fields->f_cr;
1239 break;
1240 case MT_OPERAND_CTXDISP :
1241 value = fields->f_ctxdisp;
1242 break;
1243 case MT_OPERAND_DUP :
1244 value = fields->f_dup;
1245 break;
1246 case MT_OPERAND_FBDISP :
1247 value = fields->f_fbdisp;
1248 break;
1249 case MT_OPERAND_FBINCR :
1250 value = fields->f_fbincr;
1251 break;
1252 case MT_OPERAND_FRDR :
1253 value = fields->f_dr;
1254 break;
1255 case MT_OPERAND_FRDRRR :
1256 value = fields->f_drrr;
1257 break;
1258 case MT_OPERAND_FRSR1 :
1259 value = fields->f_sr1;
1260 break;
1261 case MT_OPERAND_FRSR2 :
1262 value = fields->f_sr2;
1263 break;
1264 case MT_OPERAND_ID :
1265 value = fields->f_id;
1266 break;
1267 case MT_OPERAND_IMM16 :
1268 value = fields->f_imm16s;
1269 break;
1270 case MT_OPERAND_IMM16L :
1271 value = fields->f_imm16l;
1272 break;
1273 case MT_OPERAND_IMM16O :
1274 value = fields->f_imm16s;
1275 break;
1276 case MT_OPERAND_IMM16Z :
1277 value = fields->f_imm16u;
1278 break;
1279 case MT_OPERAND_INCAMT :
1280 value = fields->f_incamt;
1281 break;
1282 case MT_OPERAND_INCR :
1283 value = fields->f_incr;
1284 break;
1285 case MT_OPERAND_LENGTH :
1286 value = fields->f_length;
1287 break;
1288 case MT_OPERAND_LOOPSIZE :
1289 value = fields->f_loopo;
1290 break;
1291 case MT_OPERAND_MASK :
1292 value = fields->f_mask;
1293 break;
1294 case MT_OPERAND_MASK1 :
1295 value = fields->f_mask1;
1296 break;
1297 case MT_OPERAND_MODE :
1298 value = fields->f_mode;
1299 break;
1300 case MT_OPERAND_PERM :
1301 value = fields->f_perm;
1302 break;
1303 case MT_OPERAND_RBBC :
1304 value = fields->f_rbbc;
1305 break;
1306 case MT_OPERAND_RC :
1307 value = fields->f_rc;
1308 break;
1309 case MT_OPERAND_RC1 :
1310 value = fields->f_rc1;
1311 break;
1312 case MT_OPERAND_RC2 :
1313 value = fields->f_rc2;
1314 break;
1315 case MT_OPERAND_RC3 :
1316 value = fields->f_rc3;
1317 break;
1318 case MT_OPERAND_RCNUM :
1319 value = fields->f_rcnum;
1320 break;
1321 case MT_OPERAND_RDA :
1322 value = fields->f_rda;
1323 break;
1324 case MT_OPERAND_ROWNUM :
1325 value = fields->f_rownum;
1326 break;
1327 case MT_OPERAND_ROWNUM1 :
1328 value = fields->f_rownum1;
1329 break;
1330 case MT_OPERAND_ROWNUM2 :
1331 value = fields->f_rownum2;
1332 break;
1333 case MT_OPERAND_SIZE :
1334 value = fields->f_size;
1335 break;
1336 case MT_OPERAND_TYPE :
1337 value = fields->f_type;
1338 break;
1339 case MT_OPERAND_WR :
1340 value = fields->f_wr;
1341 break;
1342 case MT_OPERAND_XMODE :
1343 value = fields->f_xmode;
1344 break;
1346 default :
1347 /* xgettext:c-format */
1348 fprintf (stderr, _("Unrecognized field %d while getting vma operand.\n"),
1349 opindex);
1350 abort ();
1353 return value;
1356 void mt_cgen_set_int_operand (CGEN_CPU_DESC, int, CGEN_FIELDS *, int);
1357 void mt_cgen_set_vma_operand (CGEN_CPU_DESC, int, CGEN_FIELDS *, bfd_vma);
1359 /* Stuffing values in cgen_fields is handled by a collection of functions.
1360 They are distinguished by the type of the VALUE argument they accept.
1361 TODO: floating point, inlining support, remove cases where argument type
1362 not appropriate. */
1364 void
1365 mt_cgen_set_int_operand (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
1366 int opindex,
1367 CGEN_FIELDS * fields,
1368 int value)
1370 switch (opindex)
1372 case MT_OPERAND_A23 :
1373 fields->f_a23 = value;
1374 break;
1375 case MT_OPERAND_BALL :
1376 fields->f_ball = value;
1377 break;
1378 case MT_OPERAND_BALL2 :
1379 fields->f_ball2 = value;
1380 break;
1381 case MT_OPERAND_BANKADDR :
1382 fields->f_bankaddr = value;
1383 break;
1384 case MT_OPERAND_BRC :
1385 fields->f_brc = value;
1386 break;
1387 case MT_OPERAND_BRC2 :
1388 fields->f_brc2 = value;
1389 break;
1390 case MT_OPERAND_CB1INCR :
1391 fields->f_cb1incr = value;
1392 break;
1393 case MT_OPERAND_CB1SEL :
1394 fields->f_cb1sel = value;
1395 break;
1396 case MT_OPERAND_CB2INCR :
1397 fields->f_cb2incr = value;
1398 break;
1399 case MT_OPERAND_CB2SEL :
1400 fields->f_cb2sel = value;
1401 break;
1402 case MT_OPERAND_CBRB :
1403 fields->f_cbrb = value;
1404 break;
1405 case MT_OPERAND_CBS :
1406 fields->f_cbs = value;
1407 break;
1408 case MT_OPERAND_CBX :
1409 fields->f_cbx = value;
1410 break;
1411 case MT_OPERAND_CCB :
1412 fields->f_ccb = value;
1413 break;
1414 case MT_OPERAND_CDB :
1415 fields->f_cdb = value;
1416 break;
1417 case MT_OPERAND_CELL :
1418 fields->f_cell = value;
1419 break;
1420 case MT_OPERAND_COLNUM :
1421 fields->f_colnum = value;
1422 break;
1423 case MT_OPERAND_CONTNUM :
1424 fields->f_contnum = value;
1425 break;
1426 case MT_OPERAND_CR :
1427 fields->f_cr = value;
1428 break;
1429 case MT_OPERAND_CTXDISP :
1430 fields->f_ctxdisp = value;
1431 break;
1432 case MT_OPERAND_DUP :
1433 fields->f_dup = value;
1434 break;
1435 case MT_OPERAND_FBDISP :
1436 fields->f_fbdisp = value;
1437 break;
1438 case MT_OPERAND_FBINCR :
1439 fields->f_fbincr = value;
1440 break;
1441 case MT_OPERAND_FRDR :
1442 fields->f_dr = value;
1443 break;
1444 case MT_OPERAND_FRDRRR :
1445 fields->f_drrr = value;
1446 break;
1447 case MT_OPERAND_FRSR1 :
1448 fields->f_sr1 = value;
1449 break;
1450 case MT_OPERAND_FRSR2 :
1451 fields->f_sr2 = value;
1452 break;
1453 case MT_OPERAND_ID :
1454 fields->f_id = value;
1455 break;
1456 case MT_OPERAND_IMM16 :
1457 fields->f_imm16s = value;
1458 break;
1459 case MT_OPERAND_IMM16L :
1460 fields->f_imm16l = value;
1461 break;
1462 case MT_OPERAND_IMM16O :
1463 fields->f_imm16s = value;
1464 break;
1465 case MT_OPERAND_IMM16Z :
1466 fields->f_imm16u = value;
1467 break;
1468 case MT_OPERAND_INCAMT :
1469 fields->f_incamt = value;
1470 break;
1471 case MT_OPERAND_INCR :
1472 fields->f_incr = value;
1473 break;
1474 case MT_OPERAND_LENGTH :
1475 fields->f_length = value;
1476 break;
1477 case MT_OPERAND_LOOPSIZE :
1478 fields->f_loopo = value;
1479 break;
1480 case MT_OPERAND_MASK :
1481 fields->f_mask = value;
1482 break;
1483 case MT_OPERAND_MASK1 :
1484 fields->f_mask1 = value;
1485 break;
1486 case MT_OPERAND_MODE :
1487 fields->f_mode = value;
1488 break;
1489 case MT_OPERAND_PERM :
1490 fields->f_perm = value;
1491 break;
1492 case MT_OPERAND_RBBC :
1493 fields->f_rbbc = value;
1494 break;
1495 case MT_OPERAND_RC :
1496 fields->f_rc = value;
1497 break;
1498 case MT_OPERAND_RC1 :
1499 fields->f_rc1 = value;
1500 break;
1501 case MT_OPERAND_RC2 :
1502 fields->f_rc2 = value;
1503 break;
1504 case MT_OPERAND_RC3 :
1505 fields->f_rc3 = value;
1506 break;
1507 case MT_OPERAND_RCNUM :
1508 fields->f_rcnum = value;
1509 break;
1510 case MT_OPERAND_RDA :
1511 fields->f_rda = value;
1512 break;
1513 case MT_OPERAND_ROWNUM :
1514 fields->f_rownum = value;
1515 break;
1516 case MT_OPERAND_ROWNUM1 :
1517 fields->f_rownum1 = value;
1518 break;
1519 case MT_OPERAND_ROWNUM2 :
1520 fields->f_rownum2 = value;
1521 break;
1522 case MT_OPERAND_SIZE :
1523 fields->f_size = value;
1524 break;
1525 case MT_OPERAND_TYPE :
1526 fields->f_type = value;
1527 break;
1528 case MT_OPERAND_WR :
1529 fields->f_wr = value;
1530 break;
1531 case MT_OPERAND_XMODE :
1532 fields->f_xmode = value;
1533 break;
1535 default :
1536 /* xgettext:c-format */
1537 fprintf (stderr, _("Unrecognized field %d while setting int operand.\n"),
1538 opindex);
1539 abort ();
1543 void
1544 mt_cgen_set_vma_operand (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
1545 int opindex,
1546 CGEN_FIELDS * fields,
1547 bfd_vma value)
1549 switch (opindex)
1551 case MT_OPERAND_A23 :
1552 fields->f_a23 = value;
1553 break;
1554 case MT_OPERAND_BALL :
1555 fields->f_ball = value;
1556 break;
1557 case MT_OPERAND_BALL2 :
1558 fields->f_ball2 = value;
1559 break;
1560 case MT_OPERAND_BANKADDR :
1561 fields->f_bankaddr = value;
1562 break;
1563 case MT_OPERAND_BRC :
1564 fields->f_brc = value;
1565 break;
1566 case MT_OPERAND_BRC2 :
1567 fields->f_brc2 = value;
1568 break;
1569 case MT_OPERAND_CB1INCR :
1570 fields->f_cb1incr = value;
1571 break;
1572 case MT_OPERAND_CB1SEL :
1573 fields->f_cb1sel = value;
1574 break;
1575 case MT_OPERAND_CB2INCR :
1576 fields->f_cb2incr = value;
1577 break;
1578 case MT_OPERAND_CB2SEL :
1579 fields->f_cb2sel = value;
1580 break;
1581 case MT_OPERAND_CBRB :
1582 fields->f_cbrb = value;
1583 break;
1584 case MT_OPERAND_CBS :
1585 fields->f_cbs = value;
1586 break;
1587 case MT_OPERAND_CBX :
1588 fields->f_cbx = value;
1589 break;
1590 case MT_OPERAND_CCB :
1591 fields->f_ccb = value;
1592 break;
1593 case MT_OPERAND_CDB :
1594 fields->f_cdb = value;
1595 break;
1596 case MT_OPERAND_CELL :
1597 fields->f_cell = value;
1598 break;
1599 case MT_OPERAND_COLNUM :
1600 fields->f_colnum = value;
1601 break;
1602 case MT_OPERAND_CONTNUM :
1603 fields->f_contnum = value;
1604 break;
1605 case MT_OPERAND_CR :
1606 fields->f_cr = value;
1607 break;
1608 case MT_OPERAND_CTXDISP :
1609 fields->f_ctxdisp = value;
1610 break;
1611 case MT_OPERAND_DUP :
1612 fields->f_dup = value;
1613 break;
1614 case MT_OPERAND_FBDISP :
1615 fields->f_fbdisp = value;
1616 break;
1617 case MT_OPERAND_FBINCR :
1618 fields->f_fbincr = value;
1619 break;
1620 case MT_OPERAND_FRDR :
1621 fields->f_dr = value;
1622 break;
1623 case MT_OPERAND_FRDRRR :
1624 fields->f_drrr = value;
1625 break;
1626 case MT_OPERAND_FRSR1 :
1627 fields->f_sr1 = value;
1628 break;
1629 case MT_OPERAND_FRSR2 :
1630 fields->f_sr2 = value;
1631 break;
1632 case MT_OPERAND_ID :
1633 fields->f_id = value;
1634 break;
1635 case MT_OPERAND_IMM16 :
1636 fields->f_imm16s = value;
1637 break;
1638 case MT_OPERAND_IMM16L :
1639 fields->f_imm16l = value;
1640 break;
1641 case MT_OPERAND_IMM16O :
1642 fields->f_imm16s = value;
1643 break;
1644 case MT_OPERAND_IMM16Z :
1645 fields->f_imm16u = value;
1646 break;
1647 case MT_OPERAND_INCAMT :
1648 fields->f_incamt = value;
1649 break;
1650 case MT_OPERAND_INCR :
1651 fields->f_incr = value;
1652 break;
1653 case MT_OPERAND_LENGTH :
1654 fields->f_length = value;
1655 break;
1656 case MT_OPERAND_LOOPSIZE :
1657 fields->f_loopo = value;
1658 break;
1659 case MT_OPERAND_MASK :
1660 fields->f_mask = value;
1661 break;
1662 case MT_OPERAND_MASK1 :
1663 fields->f_mask1 = value;
1664 break;
1665 case MT_OPERAND_MODE :
1666 fields->f_mode = value;
1667 break;
1668 case MT_OPERAND_PERM :
1669 fields->f_perm = value;
1670 break;
1671 case MT_OPERAND_RBBC :
1672 fields->f_rbbc = value;
1673 break;
1674 case MT_OPERAND_RC :
1675 fields->f_rc = value;
1676 break;
1677 case MT_OPERAND_RC1 :
1678 fields->f_rc1 = value;
1679 break;
1680 case MT_OPERAND_RC2 :
1681 fields->f_rc2 = value;
1682 break;
1683 case MT_OPERAND_RC3 :
1684 fields->f_rc3 = value;
1685 break;
1686 case MT_OPERAND_RCNUM :
1687 fields->f_rcnum = value;
1688 break;
1689 case MT_OPERAND_RDA :
1690 fields->f_rda = value;
1691 break;
1692 case MT_OPERAND_ROWNUM :
1693 fields->f_rownum = value;
1694 break;
1695 case MT_OPERAND_ROWNUM1 :
1696 fields->f_rownum1 = value;
1697 break;
1698 case MT_OPERAND_ROWNUM2 :
1699 fields->f_rownum2 = value;
1700 break;
1701 case MT_OPERAND_SIZE :
1702 fields->f_size = value;
1703 break;
1704 case MT_OPERAND_TYPE :
1705 fields->f_type = value;
1706 break;
1707 case MT_OPERAND_WR :
1708 fields->f_wr = value;
1709 break;
1710 case MT_OPERAND_XMODE :
1711 fields->f_xmode = value;
1712 break;
1714 default :
1715 /* xgettext:c-format */
1716 fprintf (stderr, _("Unrecognized field %d while setting vma operand.\n"),
1717 opindex);
1718 abort ();
1722 /* Function to call before using the instruction builder tables. */
1724 void
1725 mt_cgen_init_ibld_table (CGEN_CPU_DESC cd)
1727 cd->insert_handlers = & mt_cgen_insert_handlers[0];
1728 cd->extract_handlers = & mt_cgen_extract_handlers[0];
1730 cd->insert_operand = mt_cgen_insert_operand;
1731 cd->extract_operand = mt_cgen_extract_operand;
1733 cd->get_int_operand = mt_cgen_get_int_operand;
1734 cd->set_int_operand = mt_cgen_set_int_operand;
1735 cd->get_vma_operand = mt_cgen_get_vma_operand;
1736 cd->set_vma_operand = mt_cgen_set_vma_operand;