gas/
[deliverable/binutils-gdb.git] / opcodes / ms1-ibld.c
CommitLineData
ac188222
DB
1/* Instruction building/extraction support for ms1. -*- 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.,
2251 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */
23
24/* ??? Eventually more and more of this stuff can go to cpu-independent files.
25 Keep that in mind. */
26
27#include "sysdep.h"
28#include <stdio.h>
29#include "ansidecl.h"
30#include "dis-asm.h"
31#include "bfd.h"
32#include "symcat.h"
33#include "ms1-desc.h"
34#include "ms1-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 (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 (CGEN_CPU_DESC, const CGEN_INSN *,
51 CGEN_FIELDS *, CGEN_INSN_BYTES_PTR, bfd_vma);
52static int extract_normal
53 (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 (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 (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 (CGEN_CPU_DESC, unsigned long, int, int, int, unsigned char *);
66static CGEN_INLINE int fill_cache
67 (CGEN_CPU_DESC, CGEN_EXTRACT_INFO *, int, int, bfd_vma);
68static CGEN_INLINE long extract_1
69 (CGEN_CPU_DESC, CGEN_EXTRACT_INFO *, int, int, int, unsigned char *, bfd_vma);
70#endif
71\f
72/* Operand insertion. */
73
74#if ! CGEN_INT_INSN_P
75
76/* Subroutine of insert_normal. */
77
78static CGEN_INLINE void
79insert_1 (CGEN_CPU_DESC cd,
80 unsigned long value,
81 int start,
82 int length,
83 int word_length,
84 unsigned char *bufp)
85{
86 unsigned long x,mask;
87 int shift;
88
89 x = cgen_get_insn_value (cd, bufp, word_length);
90
91 /* Written this way to avoid undefined behaviour. */
92 mask = (((1L << (length - 1)) - 1) << 1) | 1;
93 if (CGEN_INSN_LSB0_P)
94 shift = (start + 1) - length;
95 else
96 shift = (word_length - (start + length));
97 x = (x & ~(mask << shift)) | ((value & mask) << shift);
98
99 cgen_put_insn_value (cd, bufp, word_length, (bfd_vma) x);
100}
101
102#endif /* ! CGEN_INT_INSN_P */
103
104/* Default insertion routine.
105
106 ATTRS is a mask of the boolean attributes.
107 WORD_OFFSET is the offset in bits from the start of the insn of the value.
108 WORD_LENGTH is the length of the word in bits in which the value resides.
109 START is the starting bit number in the word, architecture origin.
110 LENGTH is the length of VALUE in bits.
111 TOTAL_LENGTH is the total length of the insn in bits.
112
113 The result is an error message or NULL if success. */
114
115/* ??? This duplicates functionality with bfd's howto table and
116 bfd_install_relocation. */
117/* ??? This doesn't handle bfd_vma's. Create another function when
118 necessary. */
119
120static const char *
121insert_normal (CGEN_CPU_DESC cd,
122 long value,
123 unsigned int attrs,
124 unsigned int word_offset,
125 unsigned int start,
126 unsigned int length,
127 unsigned int word_length,
128 unsigned int total_length,
129 CGEN_INSN_BYTES_PTR buffer)
130{
131 static char errbuf[100];
132 /* Written this way to avoid undefined behaviour. */
133 unsigned long mask = (((1L << (length - 1)) - 1) << 1) | 1;
134
135 /* If LENGTH is zero, this operand doesn't contribute to the value. */
136 if (length == 0)
137 return NULL;
138
139#if 0
140 if (CGEN_INT_INSN_P
141 && word_offset != 0)
142 abort ();
143#endif
144
145 if (word_length > 32)
146 abort ();
147
148 /* For architectures with insns smaller than the base-insn-bitsize,
149 word_length may be too big. */
150 if (cd->min_insn_bitsize < cd->base_insn_bitsize)
151 {
152 if (word_offset == 0
153 && word_length > total_length)
154 word_length = total_length;
155 }
156
157 /* Ensure VALUE will fit. */
158 if (CGEN_BOOL_ATTR (attrs, CGEN_IFLD_SIGN_OPT))
159 {
160 long minval = - (1L << (length - 1));
161 unsigned long maxval = mask;
162
163 if ((value > 0 && (unsigned long) value > maxval)
164 || value < minval)
165 {
166 /* xgettext:c-format */
167 sprintf (errbuf,
168 _("operand out of range (%ld not between %ld and %lu)"),
169 value, minval, maxval);
170 return errbuf;
171 }
172 }
173 else if (! CGEN_BOOL_ATTR (attrs, CGEN_IFLD_SIGNED))
174 {
175 unsigned long maxval = mask;
176
177 if ((unsigned long) value > maxval)
178 {
179 /* xgettext:c-format */
180 sprintf (errbuf,
181 _("operand out of range (%lu not between 0 and %lu)"),
182 value, maxval);
183 return errbuf;
184 }
185 }
186 else
187 {
188 if (! cgen_signed_overflow_ok_p (cd))
189 {
190 long minval = - (1L << (length - 1));
191 long maxval = (1L << (length - 1)) - 1;
192
193 if (value < minval || value > maxval)
194 {
195 sprintf
196 /* xgettext:c-format */
197 (errbuf, _("operand out of range (%ld not between %ld and %ld)"),
198 value, minval, maxval);
199 return errbuf;
200 }
201 }
202 }
203
204#if CGEN_INT_INSN_P
205
206 {
207 int shift;
208
209 if (CGEN_INSN_LSB0_P)
210 shift = (word_offset + start + 1) - length;
211 else
212 shift = total_length - (word_offset + start + length);
213 *buffer = (*buffer & ~(mask << shift)) | ((value & mask) << shift);
214 }
215
216#else /* ! CGEN_INT_INSN_P */
217
218 {
219 unsigned char *bufp = (unsigned char *) buffer + word_offset / 8;
220
221 insert_1 (cd, value, start, length, word_length, bufp);
222 }
223
224#endif /* ! CGEN_INT_INSN_P */
225
226 return NULL;
227}
228
229/* Default insn builder (insert handler).
230 The instruction is recorded in CGEN_INT_INSN_P byte order (meaning
231 that if CGEN_INSN_BYTES_PTR is an int * and thus, the value is
232 recorded in host byte order, otherwise BUFFER is an array of bytes
233 and the value is recorded in target byte order).
234 The result is an error message or NULL if success. */
235
236static const char *
237insert_insn_normal (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 (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
293 CGEN_INSN_BYTES_PTR buf,
294 int length,
295 int insn_length,
296 CGEN_INSN_INT value)
297{
298 /* For architectures with insns smaller than the base-insn-bitsize,
299 length may be too big. */
300 if (length > insn_length)
301 *buf = value;
302 else
303 {
304 int shift = insn_length - length;
305 /* Written this way to avoid undefined behaviour. */
306 CGEN_INSN_INT mask = (((1L << (length - 1)) - 1) << 1) | 1;
307 *buf = (*buf & ~(mask << shift)) | ((value & mask) << shift);
308 }
309}
310#endif
311\f
312/* Operand extraction. */
313
314#if ! CGEN_INT_INSN_P
315
316/* Subroutine of extract_normal.
317 Ensure sufficient bytes are cached in EX_INFO.
318 OFFSET is the offset in bytes from the start of the insn of the value.
319 BYTES is the length of the needed value.
320 Returns 1 for success, 0 for failure. */
321
322static CGEN_INLINE int
323fill_cache (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
324 CGEN_EXTRACT_INFO *ex_info,
325 int offset,
326 int bytes,
327 bfd_vma pc)
328{
329 /* It's doubtful that the middle part has already been fetched so
330 we don't optimize that case. kiss. */
331 unsigned int mask;
332 disassemble_info *info = (disassemble_info *) ex_info->dis_info;
333
334 /* First do a quick check. */
335 mask = (1 << bytes) - 1;
336 if (((ex_info->valid >> offset) & mask) == mask)
337 return 1;
338
339 /* Search for the first byte we need to read. */
340 for (mask = 1 << offset; bytes > 0; --bytes, ++offset, mask <<= 1)
341 if (! (mask & ex_info->valid))
342 break;
343
344 if (bytes)
345 {
346 int status;
347
348 pc += offset;
349 status = (*info->read_memory_func)
350 (pc, ex_info->insn_bytes + offset, bytes, info);
351
352 if (status != 0)
353 {
354 (*info->memory_error_func) (status, pc, info);
355 return 0;
356 }
357
358 ex_info->valid |= ((1 << bytes) - 1) << offset;
359 }
360
361 return 1;
362}
363
364/* Subroutine of extract_normal. */
365
366static CGEN_INLINE long
367extract_1 (CGEN_CPU_DESC cd,
368 CGEN_EXTRACT_INFO *ex_info ATTRIBUTE_UNUSED,
369 int start,
370 int length,
371 int word_length,
372 unsigned char *bufp,
373 bfd_vma pc ATTRIBUTE_UNUSED)
374{
375 unsigned long x;
376 int shift;
377#if 0
378 int big_p = CGEN_CPU_INSN_ENDIAN (cd) == CGEN_ENDIAN_BIG;
379#endif
380 x = cgen_get_insn_value (cd, bufp, word_length);
381
382 if (CGEN_INSN_LSB0_P)
383 shift = (start + 1) - length;
384 else
385 shift = (word_length - (start + length));
386 return x >> shift;
387}
388
389#endif /* ! CGEN_INT_INSN_P */
390
391/* Default extraction routine.
392
393 INSN_VALUE is the first base_insn_bitsize bits of the insn in host order,
394 or sometimes less for cases like the m32r where the base insn size is 32
395 but some insns are 16 bits.
396 ATTRS is a mask of the boolean attributes. We only need `SIGNED',
397 but for generality we take a bitmask of all of them.
398 WORD_OFFSET is the offset in bits from the start of the insn of the value.
399 WORD_LENGTH is the length of the word in bits in which the value resides.
400 START is the starting bit number in the word, architecture origin.
401 LENGTH is the length of VALUE in bits.
402 TOTAL_LENGTH is the total length of the insn in bits.
403
404 Returns 1 for success, 0 for failure. */
405
406/* ??? The return code isn't properly used. wip. */
407
408/* ??? This doesn't handle bfd_vma's. Create another function when
409 necessary. */
410
411static int
412extract_normal (CGEN_CPU_DESC cd,
413#if ! CGEN_INT_INSN_P
414 CGEN_EXTRACT_INFO *ex_info,
415#else
416 CGEN_EXTRACT_INFO *ex_info ATTRIBUTE_UNUSED,
417#endif
418 CGEN_INSN_INT insn_value,
419 unsigned int attrs,
420 unsigned int word_offset,
421 unsigned int start,
422 unsigned int length,
423 unsigned int word_length,
424 unsigned int total_length,
425#if ! CGEN_INT_INSN_P
426 bfd_vma pc,
427#else
428 bfd_vma pc ATTRIBUTE_UNUSED,
429#endif
430 long *valuep)
431{
432 long value, mask;
433
434 /* If LENGTH is zero, this operand doesn't contribute to the value
435 so give it a standard value of zero. */
436 if (length == 0)
437 {
438 *valuep = 0;
439 return 1;
440 }
441
442#if 0
443 if (CGEN_INT_INSN_P
444 && word_offset != 0)
445 abort ();
446#endif
447
448 if (word_length > 32)
449 abort ();
450
451 /* For architectures with insns smaller than the insn-base-bitsize,
452 word_length may be too big. */
453 if (cd->min_insn_bitsize < cd->base_insn_bitsize)
454 {
455 if (word_offset == 0
456 && word_length > total_length)
457 word_length = total_length;
458 }
459
460 /* Does the value reside in INSN_VALUE, and at the right alignment? */
461
462 if (CGEN_INT_INSN_P || (word_offset == 0 && word_length == total_length))
463 {
464 if (CGEN_INSN_LSB0_P)
465 value = insn_value >> ((word_offset + start + 1) - length);
466 else
467 value = insn_value >> (total_length - ( word_offset + start + length));
468 }
469
470#if ! CGEN_INT_INSN_P
471
472 else
473 {
474 unsigned char *bufp = ex_info->insn_bytes + word_offset / 8;
475
476 if (word_length > 32)
477 abort ();
478
479 if (fill_cache (cd, ex_info, word_offset / 8, word_length / 8, pc) == 0)
480 return 0;
481
482 value = extract_1 (cd, ex_info, start, length, word_length, bufp, pc);
483 }
484
485#endif /* ! CGEN_INT_INSN_P */
486
487 /* Written this way to avoid undefined behaviour. */
488 mask = (((1L << (length - 1)) - 1) << 1) | 1;
489
490 value &= mask;
491 /* sign extend? */
492 if (CGEN_BOOL_ATTR (attrs, CGEN_IFLD_SIGNED)
493 && (value & (1L << (length - 1))))
494 value |= ~mask;
495
496 *valuep = value;
497
498 return 1;
499}
500
501/* Default insn extractor.
502
503 INSN_VALUE is the first base_insn_bitsize bits, translated to host order.
504 The extracted fields are stored in FIELDS.
505 EX_INFO is used to handle reading variable length insns.
506 Return the length of the insn in bits, or 0 if no match,
507 or -1 if an error occurs fetching data (memory_error_func will have
508 been called). */
509
510static int
511extract_insn_normal (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\f
542/* machine generated code added here */
543
544const char * ms1_cgen_insert_operand
545 PARAMS ((CGEN_CPU_DESC, int, CGEN_FIELDS *, CGEN_INSN_BYTES_PTR, bfd_vma));
546
547/* Main entry point for operand insertion.
548
549 This function is basically just a big switch statement. Earlier versions
550 used tables to look up the function to use, but
551 - if the table contains both assembler and disassembler functions then
552 the disassembler contains much of the assembler and vice-versa,
553 - there's a lot of inlining possibilities as things grow,
554 - using a switch statement avoids the function call overhead.
555
556 This function could be moved into `parse_insn_normal', but keeping it
557 separate makes clear the interface between `parse_insn_normal' and each of
558 the handlers. It's also needed by GAS to insert operands that couldn't be
559 resolved during parsing. */
560
561const char *
562ms1_cgen_insert_operand (cd, opindex, fields, buffer, pc)
563 CGEN_CPU_DESC cd;
564 int opindex;
565 CGEN_FIELDS * fields;
566 CGEN_INSN_BYTES_PTR buffer;
567 bfd_vma pc ATTRIBUTE_UNUSED;
568{
569 const char * errmsg = NULL;
570 unsigned int total_length = CGEN_FIELDS_BITSIZE (fields);
571
572 switch (opindex)
573 {
574 case MS1_OPERAND_A23 :
575 errmsg = insert_normal (cd, fields->f_a23, 0, 0, 23, 1, 32, total_length, buffer);
576 break;
577 case MS1_OPERAND_BALL :
578 errmsg = insert_normal (cd, fields->f_ball, 0, 0, 19, 1, 32, total_length, buffer);
579 break;
580 case MS1_OPERAND_BALL2 :
581 errmsg = insert_normal (cd, fields->f_ball2, 0, 0, 15, 1, 32, total_length, buffer);
582 break;
583 case MS1_OPERAND_BANKADDR :
584 errmsg = insert_normal (cd, fields->f_bankaddr, 0, 0, 25, 13, 32, total_length, buffer);
585 break;
586 case MS1_OPERAND_BRC :
587 errmsg = insert_normal (cd, fields->f_brc, 0, 0, 18, 3, 32, total_length, buffer);
588 break;
589 case MS1_OPERAND_BRC2 :
590 errmsg = insert_normal (cd, fields->f_brc2, 0, 0, 14, 3, 32, total_length, buffer);
591 break;
592 case MS1_OPERAND_CBRB :
593 errmsg = insert_normal (cd, fields->f_cbrb, 0, 0, 10, 1, 32, total_length, buffer);
594 break;
595 case MS1_OPERAND_CBS :
596 errmsg = insert_normal (cd, fields->f_cbs, 0, 0, 19, 2, 32, total_length, buffer);
597 break;
598 case MS1_OPERAND_CBX :
599 errmsg = insert_normal (cd, fields->f_cbx, 0, 0, 14, 3, 32, total_length, buffer);
600 break;
601 case MS1_OPERAND_CCB :
602 errmsg = insert_normal (cd, fields->f_ccb, 0, 0, 11, 1, 32, total_length, buffer);
603 break;
604 case MS1_OPERAND_CDB :
605 errmsg = insert_normal (cd, fields->f_cdb, 0, 0, 10, 1, 32, total_length, buffer);
606 break;
607 case MS1_OPERAND_CELL :
608 errmsg = insert_normal (cd, fields->f_cell, 0, 0, 9, 3, 32, total_length, buffer);
609 break;
610 case MS1_OPERAND_COLNUM :
611 errmsg = insert_normal (cd, fields->f_colnum, 0, 0, 18, 3, 32, total_length, buffer);
612 break;
613 case MS1_OPERAND_CONTNUM :
614 errmsg = insert_normal (cd, fields->f_contnum, 0, 0, 8, 9, 32, total_length, buffer);
615 break;
616 case MS1_OPERAND_CR :
617 errmsg = insert_normal (cd, fields->f_cr, 0, 0, 22, 3, 32, total_length, buffer);
618 break;
619 case MS1_OPERAND_CTXDISP :
620 errmsg = insert_normal (cd, fields->f_ctxdisp, 0, 0, 5, 6, 32, total_length, buffer);
621 break;
622 case MS1_OPERAND_DUP :
623 errmsg = insert_normal (cd, fields->f_dup, 0, 0, 6, 1, 32, total_length, buffer);
624 break;
625 case MS1_OPERAND_FBDISP :
626 errmsg = insert_normal (cd, fields->f_fbdisp, 0, 0, 15, 6, 32, total_length, buffer);
627 break;
628 case MS1_OPERAND_FBINCR :
629 errmsg = insert_normal (cd, fields->f_fbincr, 0, 0, 23, 4, 32, total_length, buffer);
630 break;
631 case MS1_OPERAND_FRDR :
632 errmsg = insert_normal (cd, fields->f_dr, 0|(1<<CGEN_IFLD_ABS_ADDR), 0, 19, 4, 32, total_length, buffer);
633 break;
634 case MS1_OPERAND_FRDRRR :
635 errmsg = insert_normal (cd, fields->f_drrr, 0|(1<<CGEN_IFLD_ABS_ADDR), 0, 15, 4, 32, total_length, buffer);
636 break;
637 case MS1_OPERAND_FRSR1 :
638 errmsg = insert_normal (cd, fields->f_sr1, 0|(1<<CGEN_IFLD_ABS_ADDR), 0, 23, 4, 32, total_length, buffer);
639 break;
640 case MS1_OPERAND_FRSR2 :
641 errmsg = insert_normal (cd, fields->f_sr2, 0|(1<<CGEN_IFLD_ABS_ADDR), 0, 19, 4, 32, total_length, buffer);
642 break;
643 case MS1_OPERAND_ID :
644 errmsg = insert_normal (cd, fields->f_id, 0, 0, 14, 1, 32, total_length, buffer);
645 break;
646 case MS1_OPERAND_IMM16 :
647 {
648 long value = fields->f_imm16s;
649 value = ((value) + (0));
650 errmsg = insert_normal (cd, value, 0|(1<<CGEN_IFLD_SIGNED), 0, 15, 16, 32, total_length, buffer);
651 }
652 break;
653 case MS1_OPERAND_IMM16O :
654 {
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);
658 }
659 break;
660 case MS1_OPERAND_IMM16Z :
661 errmsg = insert_normal (cd, fields->f_imm16u, 0, 0, 15, 16, 32, total_length, buffer);
662 break;
663 case MS1_OPERAND_INCAMT :
664 errmsg = insert_normal (cd, fields->f_incamt, 0, 0, 19, 8, 32, total_length, buffer);
665 break;
666 case MS1_OPERAND_INCR :
667 errmsg = insert_normal (cd, fields->f_incr, 0, 0, 17, 6, 32, total_length, buffer);
668 break;
669 case MS1_OPERAND_LENGTH :
670 errmsg = insert_normal (cd, fields->f_length, 0, 0, 15, 3, 32, total_length, buffer);
671 break;
672 case MS1_OPERAND_MASK :
673 errmsg = insert_normal (cd, fields->f_mask, 0, 0, 25, 16, 32, total_length, buffer);
674 break;
675 case MS1_OPERAND_MASK1 :
676 errmsg = insert_normal (cd, fields->f_mask1, 0, 0, 22, 3, 32, total_length, buffer);
677 break;
678 case MS1_OPERAND_MODE :
679 errmsg = insert_normal (cd, fields->f_mode, 0, 0, 25, 2, 32, total_length, buffer);
680 break;
681 case MS1_OPERAND_PERM :
682 errmsg = insert_normal (cd, fields->f_perm, 0, 0, 25, 2, 32, total_length, buffer);
683 break;
684 case MS1_OPERAND_RBBC :
685 errmsg = insert_normal (cd, fields->f_rbbc, 0, 0, 25, 2, 32, total_length, buffer);
686 break;
687 case MS1_OPERAND_RC :
688 errmsg = insert_normal (cd, fields->f_rc, 0, 0, 15, 1, 32, total_length, buffer);
689 break;
690 case MS1_OPERAND_RC1 :
691 errmsg = insert_normal (cd, fields->f_rc1, 0, 0, 11, 1, 32, total_length, buffer);
692 break;
693 case MS1_OPERAND_RC2 :
694 errmsg = insert_normal (cd, fields->f_rc2, 0, 0, 6, 1, 32, total_length, buffer);
695 break;
696 case MS1_OPERAND_RCNUM :
697 errmsg = insert_normal (cd, fields->f_rcnum, 0, 0, 14, 3, 32, total_length, buffer);
698 break;
699 case MS1_OPERAND_RDA :
700 errmsg = insert_normal (cd, fields->f_rda, 0, 0, 25, 1, 32, total_length, buffer);
701 break;
702 case MS1_OPERAND_ROWNUM :
703 errmsg = insert_normal (cd, fields->f_rownum, 0, 0, 14, 3, 32, total_length, buffer);
704 break;
705 case MS1_OPERAND_ROWNUM1 :
706 errmsg = insert_normal (cd, fields->f_rownum1, 0, 0, 12, 3, 32, total_length, buffer);
707 break;
708 case MS1_OPERAND_ROWNUM2 :
709 errmsg = insert_normal (cd, fields->f_rownum2, 0, 0, 9, 3, 32, total_length, buffer);
710 break;
711 case MS1_OPERAND_SIZE :
712 errmsg = insert_normal (cd, fields->f_size, 0, 0, 13, 14, 32, total_length, buffer);
713 break;
714 case MS1_OPERAND_TYPE :
715 errmsg = insert_normal (cd, fields->f_type, 0, 0, 21, 2, 32, total_length, buffer);
716 break;
717 case MS1_OPERAND_WR :
718 errmsg = insert_normal (cd, fields->f_wr, 0, 0, 24, 1, 32, total_length, buffer);
719 break;
720 case MS1_OPERAND_XMODE :
721 errmsg = insert_normal (cd, fields->f_xmode, 0, 0, 23, 1, 32, total_length, buffer);
722 break;
723
724 default :
725 /* xgettext:c-format */
726 fprintf (stderr, _("Unrecognized field %d while building insn.\n"),
727 opindex);
728 abort ();
729 }
730
731 return errmsg;
732}
733
734int ms1_cgen_extract_operand
735 PARAMS ((CGEN_CPU_DESC, int, CGEN_EXTRACT_INFO *, CGEN_INSN_INT,
736 CGEN_FIELDS *, bfd_vma));
737
738/* Main entry point for operand extraction.
739 The result is <= 0 for error, >0 for success.
740 ??? Actual values aren't well defined right now.
741
742 This function is basically just a big switch statement. Earlier versions
743 used tables to look up the function to use, but
744 - if the table contains both assembler and disassembler functions then
745 the disassembler contains much of the assembler and vice-versa,
746 - there's a lot of inlining possibilities as things grow,
747 - using a switch statement avoids the function call overhead.
748
749 This function could be moved into `print_insn_normal', but keeping it
750 separate makes clear the interface between `print_insn_normal' and each of
751 the handlers. */
752
753int
754ms1_cgen_extract_operand (cd, opindex, ex_info, insn_value, fields, pc)
755 CGEN_CPU_DESC cd;
756 int opindex;
757 CGEN_EXTRACT_INFO *ex_info;
758 CGEN_INSN_INT insn_value;
759 CGEN_FIELDS * fields;
760 bfd_vma pc;
761{
762 /* Assume success (for those operands that are nops). */
763 int length = 1;
764 unsigned int total_length = CGEN_FIELDS_BITSIZE (fields);
765
766 switch (opindex)
767 {
768 case MS1_OPERAND_A23 :
769 length = extract_normal (cd, ex_info, insn_value, 0, 0, 23, 1, 32, total_length, pc, & fields->f_a23);
770 break;
771 case MS1_OPERAND_BALL :
772 length = extract_normal (cd, ex_info, insn_value, 0, 0, 19, 1, 32, total_length, pc, & fields->f_ball);
773 break;
774 case MS1_OPERAND_BALL2 :
775 length = extract_normal (cd, ex_info, insn_value, 0, 0, 15, 1, 32, total_length, pc, & fields->f_ball2);
776 break;
777 case MS1_OPERAND_BANKADDR :
778 length = extract_normal (cd, ex_info, insn_value, 0, 0, 25, 13, 32, total_length, pc, & fields->f_bankaddr);
779 break;
780 case MS1_OPERAND_BRC :
781 length = extract_normal (cd, ex_info, insn_value, 0, 0, 18, 3, 32, total_length, pc, & fields->f_brc);
782 break;
783 case MS1_OPERAND_BRC2 :
784 length = extract_normal (cd, ex_info, insn_value, 0, 0, 14, 3, 32, total_length, pc, & fields->f_brc2);
785 break;
786 case MS1_OPERAND_CBRB :
787 length = extract_normal (cd, ex_info, insn_value, 0, 0, 10, 1, 32, total_length, pc, & fields->f_cbrb);
788 break;
789 case MS1_OPERAND_CBS :
790 length = extract_normal (cd, ex_info, insn_value, 0, 0, 19, 2, 32, total_length, pc, & fields->f_cbs);
791 break;
792 case MS1_OPERAND_CBX :
793 length = extract_normal (cd, ex_info, insn_value, 0, 0, 14, 3, 32, total_length, pc, & fields->f_cbx);
794 break;
795 case MS1_OPERAND_CCB :
796 length = extract_normal (cd, ex_info, insn_value, 0, 0, 11, 1, 32, total_length, pc, & fields->f_ccb);
797 break;
798 case MS1_OPERAND_CDB :
799 length = extract_normal (cd, ex_info, insn_value, 0, 0, 10, 1, 32, total_length, pc, & fields->f_cdb);
800 break;
801 case MS1_OPERAND_CELL :
802 length = extract_normal (cd, ex_info, insn_value, 0, 0, 9, 3, 32, total_length, pc, & fields->f_cell);
803 break;
804 case MS1_OPERAND_COLNUM :
805 length = extract_normal (cd, ex_info, insn_value, 0, 0, 18, 3, 32, total_length, pc, & fields->f_colnum);
806 break;
807 case MS1_OPERAND_CONTNUM :
808 length = extract_normal (cd, ex_info, insn_value, 0, 0, 8, 9, 32, total_length, pc, & fields->f_contnum);
809 break;
810 case MS1_OPERAND_CR :
811 length = extract_normal (cd, ex_info, insn_value, 0, 0, 22, 3, 32, total_length, pc, & fields->f_cr);
812 break;
813 case MS1_OPERAND_CTXDISP :
814 length = extract_normal (cd, ex_info, insn_value, 0, 0, 5, 6, 32, total_length, pc, & fields->f_ctxdisp);
815 break;
816 case MS1_OPERAND_DUP :
817 length = extract_normal (cd, ex_info, insn_value, 0, 0, 6, 1, 32, total_length, pc, & fields->f_dup);
818 break;
819 case MS1_OPERAND_FBDISP :
820 length = extract_normal (cd, ex_info, insn_value, 0, 0, 15, 6, 32, total_length, pc, & fields->f_fbdisp);
821 break;
822 case MS1_OPERAND_FBINCR :
823 length = extract_normal (cd, ex_info, insn_value, 0, 0, 23, 4, 32, total_length, pc, & fields->f_fbincr);
824 break;
825 case MS1_OPERAND_FRDR :
826 length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_ABS_ADDR), 0, 19, 4, 32, total_length, pc, & fields->f_dr);
827 break;
828 case MS1_OPERAND_FRDRRR :
829 length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_ABS_ADDR), 0, 15, 4, 32, total_length, pc, & fields->f_drrr);
830 break;
831 case MS1_OPERAND_FRSR1 :
832 length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_ABS_ADDR), 0, 23, 4, 32, total_length, pc, & fields->f_sr1);
833 break;
834 case MS1_OPERAND_FRSR2 :
835 length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_ABS_ADDR), 0, 19, 4, 32, total_length, pc, & fields->f_sr2);
836 break;
837 case MS1_OPERAND_ID :
838 length = extract_normal (cd, ex_info, insn_value, 0, 0, 14, 1, 32, total_length, pc, & fields->f_id);
839 break;
840 case MS1_OPERAND_IMM16 :
841 {
842 long value;
843 length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_SIGNED), 0, 15, 16, 32, total_length, pc, & value);
844 value = ((value) + (0));
845 fields->f_imm16s = value;
846 }
847 break;
848 case MS1_OPERAND_IMM16O :
849 {
850 long value;
851 length = extract_normal (cd, ex_info, insn_value, 0|(1<<CGEN_IFLD_SIGNED), 0, 15, 16, 32, total_length, pc, & value);
852 value = ((value) + (0));
853 fields->f_imm16s = value;
854 }
855 break;
856 case MS1_OPERAND_IMM16Z :
857 length = extract_normal (cd, ex_info, insn_value, 0, 0, 15, 16, 32, total_length, pc, & fields->f_imm16u);
858 break;
859 case MS1_OPERAND_INCAMT :
860 length = extract_normal (cd, ex_info, insn_value, 0, 0, 19, 8, 32, total_length, pc, & fields->f_incamt);
861 break;
862 case MS1_OPERAND_INCR :
863 length = extract_normal (cd, ex_info, insn_value, 0, 0, 17, 6, 32, total_length, pc, & fields->f_incr);
864 break;
865 case MS1_OPERAND_LENGTH :
866 length = extract_normal (cd, ex_info, insn_value, 0, 0, 15, 3, 32, total_length, pc, & fields->f_length);
867 break;
868 case MS1_OPERAND_MASK :
869 length = extract_normal (cd, ex_info, insn_value, 0, 0, 25, 16, 32, total_length, pc, & fields->f_mask);
870 break;
871 case MS1_OPERAND_MASK1 :
872 length = extract_normal (cd, ex_info, insn_value, 0, 0, 22, 3, 32, total_length, pc, & fields->f_mask1);
873 break;
874 case MS1_OPERAND_MODE :
875 length = extract_normal (cd, ex_info, insn_value, 0, 0, 25, 2, 32, total_length, pc, & fields->f_mode);
876 break;
877 case MS1_OPERAND_PERM :
878 length = extract_normal (cd, ex_info, insn_value, 0, 0, 25, 2, 32, total_length, pc, & fields->f_perm);
879 break;
880 case MS1_OPERAND_RBBC :
881 length = extract_normal (cd, ex_info, insn_value, 0, 0, 25, 2, 32, total_length, pc, & fields->f_rbbc);
882 break;
883 case MS1_OPERAND_RC :
884 length = extract_normal (cd, ex_info, insn_value, 0, 0, 15, 1, 32, total_length, pc, & fields->f_rc);
885 break;
886 case MS1_OPERAND_RC1 :
887 length = extract_normal (cd, ex_info, insn_value, 0, 0, 11, 1, 32, total_length, pc, & fields->f_rc1);
888 break;
889 case MS1_OPERAND_RC2 :
890 length = extract_normal (cd, ex_info, insn_value, 0, 0, 6, 1, 32, total_length, pc, & fields->f_rc2);
891 break;
892 case MS1_OPERAND_RCNUM :
893 length = extract_normal (cd, ex_info, insn_value, 0, 0, 14, 3, 32, total_length, pc, & fields->f_rcnum);
894 break;
895 case MS1_OPERAND_RDA :
896 length = extract_normal (cd, ex_info, insn_value, 0, 0, 25, 1, 32, total_length, pc, & fields->f_rda);
897 break;
898 case MS1_OPERAND_ROWNUM :
899 length = extract_normal (cd, ex_info, insn_value, 0, 0, 14, 3, 32, total_length, pc, & fields->f_rownum);
900 break;
901 case MS1_OPERAND_ROWNUM1 :
902 length = extract_normal (cd, ex_info, insn_value, 0, 0, 12, 3, 32, total_length, pc, & fields->f_rownum1);
903 break;
904 case MS1_OPERAND_ROWNUM2 :
905 length = extract_normal (cd, ex_info, insn_value, 0, 0, 9, 3, 32, total_length, pc, & fields->f_rownum2);
906 break;
907 case MS1_OPERAND_SIZE :
908 length = extract_normal (cd, ex_info, insn_value, 0, 0, 13, 14, 32, total_length, pc, & fields->f_size);
909 break;
910 case MS1_OPERAND_TYPE :
911 length = extract_normal (cd, ex_info, insn_value, 0, 0, 21, 2, 32, total_length, pc, & fields->f_type);
912 break;
913 case MS1_OPERAND_WR :
914 length = extract_normal (cd, ex_info, insn_value, 0, 0, 24, 1, 32, total_length, pc, & fields->f_wr);
915 break;
916 case MS1_OPERAND_XMODE :
917 length = extract_normal (cd, ex_info, insn_value, 0, 0, 23, 1, 32, total_length, pc, & fields->f_xmode);
918 break;
919
920 default :
921 /* xgettext:c-format */
922 fprintf (stderr, _("Unrecognized field %d while decoding insn.\n"),
923 opindex);
924 abort ();
925 }
926
927 return length;
928}
929
930cgen_insert_fn * const ms1_cgen_insert_handlers[] =
931{
932 insert_insn_normal,
933};
934
935cgen_extract_fn * const ms1_cgen_extract_handlers[] =
936{
937 extract_insn_normal,
938};
939
940int ms1_cgen_get_int_operand
941 PARAMS ((CGEN_CPU_DESC, int, const CGEN_FIELDS *));
942bfd_vma ms1_cgen_get_vma_operand
943 PARAMS ((CGEN_CPU_DESC, int, const CGEN_FIELDS *));
944
945/* Getting values from cgen_fields is handled by a collection of functions.
946 They are distinguished by the type of the VALUE argument they return.
947 TODO: floating point, inlining support, remove cases where result type
948 not appropriate. */
949
950int
951ms1_cgen_get_int_operand (cd, opindex, fields)
952 CGEN_CPU_DESC cd ATTRIBUTE_UNUSED;
953 int opindex;
954 const CGEN_FIELDS * fields;
955{
956 int value;
957
958 switch (opindex)
959 {
960 case MS1_OPERAND_A23 :
961 value = fields->f_a23;
962 break;
963 case MS1_OPERAND_BALL :
964 value = fields->f_ball;
965 break;
966 case MS1_OPERAND_BALL2 :
967 value = fields->f_ball2;
968 break;
969 case MS1_OPERAND_BANKADDR :
970 value = fields->f_bankaddr;
971 break;
972 case MS1_OPERAND_BRC :
973 value = fields->f_brc;
974 break;
975 case MS1_OPERAND_BRC2 :
976 value = fields->f_brc2;
977 break;
978 case MS1_OPERAND_CBRB :
979 value = fields->f_cbrb;
980 break;
981 case MS1_OPERAND_CBS :
982 value = fields->f_cbs;
983 break;
984 case MS1_OPERAND_CBX :
985 value = fields->f_cbx;
986 break;
987 case MS1_OPERAND_CCB :
988 value = fields->f_ccb;
989 break;
990 case MS1_OPERAND_CDB :
991 value = fields->f_cdb;
992 break;
993 case MS1_OPERAND_CELL :
994 value = fields->f_cell;
995 break;
996 case MS1_OPERAND_COLNUM :
997 value = fields->f_colnum;
998 break;
999 case MS1_OPERAND_CONTNUM :
1000 value = fields->f_contnum;
1001 break;
1002 case MS1_OPERAND_CR :
1003 value = fields->f_cr;
1004 break;
1005 case MS1_OPERAND_CTXDISP :
1006 value = fields->f_ctxdisp;
1007 break;
1008 case MS1_OPERAND_DUP :
1009 value = fields->f_dup;
1010 break;
1011 case MS1_OPERAND_FBDISP :
1012 value = fields->f_fbdisp;
1013 break;
1014 case MS1_OPERAND_FBINCR :
1015 value = fields->f_fbincr;
1016 break;
1017 case MS1_OPERAND_FRDR :
1018 value = fields->f_dr;
1019 break;
1020 case MS1_OPERAND_FRDRRR :
1021 value = fields->f_drrr;
1022 break;
1023 case MS1_OPERAND_FRSR1 :
1024 value = fields->f_sr1;
1025 break;
1026 case MS1_OPERAND_FRSR2 :
1027 value = fields->f_sr2;
1028 break;
1029 case MS1_OPERAND_ID :
1030 value = fields->f_id;
1031 break;
1032 case MS1_OPERAND_IMM16 :
1033 value = fields->f_imm16s;
1034 break;
1035 case MS1_OPERAND_IMM16O :
1036 value = fields->f_imm16s;
1037 break;
1038 case MS1_OPERAND_IMM16Z :
1039 value = fields->f_imm16u;
1040 break;
1041 case MS1_OPERAND_INCAMT :
1042 value = fields->f_incamt;
1043 break;
1044 case MS1_OPERAND_INCR :
1045 value = fields->f_incr;
1046 break;
1047 case MS1_OPERAND_LENGTH :
1048 value = fields->f_length;
1049 break;
1050 case MS1_OPERAND_MASK :
1051 value = fields->f_mask;
1052 break;
1053 case MS1_OPERAND_MASK1 :
1054 value = fields->f_mask1;
1055 break;
1056 case MS1_OPERAND_MODE :
1057 value = fields->f_mode;
1058 break;
1059 case MS1_OPERAND_PERM :
1060 value = fields->f_perm;
1061 break;
1062 case MS1_OPERAND_RBBC :
1063 value = fields->f_rbbc;
1064 break;
1065 case MS1_OPERAND_RC :
1066 value = fields->f_rc;
1067 break;
1068 case MS1_OPERAND_RC1 :
1069 value = fields->f_rc1;
1070 break;
1071 case MS1_OPERAND_RC2 :
1072 value = fields->f_rc2;
1073 break;
1074 case MS1_OPERAND_RCNUM :
1075 value = fields->f_rcnum;
1076 break;
1077 case MS1_OPERAND_RDA :
1078 value = fields->f_rda;
1079 break;
1080 case MS1_OPERAND_ROWNUM :
1081 value = fields->f_rownum;
1082 break;
1083 case MS1_OPERAND_ROWNUM1 :
1084 value = fields->f_rownum1;
1085 break;
1086 case MS1_OPERAND_ROWNUM2 :
1087 value = fields->f_rownum2;
1088 break;
1089 case MS1_OPERAND_SIZE :
1090 value = fields->f_size;
1091 break;
1092 case MS1_OPERAND_TYPE :
1093 value = fields->f_type;
1094 break;
1095 case MS1_OPERAND_WR :
1096 value = fields->f_wr;
1097 break;
1098 case MS1_OPERAND_XMODE :
1099 value = fields->f_xmode;
1100 break;
1101
1102 default :
1103 /* xgettext:c-format */
1104 fprintf (stderr, _("Unrecognized field %d while getting int operand.\n"),
1105 opindex);
1106 abort ();
1107 }
1108
1109 return value;
1110}
1111
1112bfd_vma
1113ms1_cgen_get_vma_operand (cd, opindex, fields)
1114 CGEN_CPU_DESC cd ATTRIBUTE_UNUSED;
1115 int opindex;
1116 const CGEN_FIELDS * fields;
1117{
1118 bfd_vma value;
1119
1120 switch (opindex)
1121 {
1122 case MS1_OPERAND_A23 :
1123 value = fields->f_a23;
1124 break;
1125 case MS1_OPERAND_BALL :
1126 value = fields->f_ball;
1127 break;
1128 case MS1_OPERAND_BALL2 :
1129 value = fields->f_ball2;
1130 break;
1131 case MS1_OPERAND_BANKADDR :
1132 value = fields->f_bankaddr;
1133 break;
1134 case MS1_OPERAND_BRC :
1135 value = fields->f_brc;
1136 break;
1137 case MS1_OPERAND_BRC2 :
1138 value = fields->f_brc2;
1139 break;
1140 case MS1_OPERAND_CBRB :
1141 value = fields->f_cbrb;
1142 break;
1143 case MS1_OPERAND_CBS :
1144 value = fields->f_cbs;
1145 break;
1146 case MS1_OPERAND_CBX :
1147 value = fields->f_cbx;
1148 break;
1149 case MS1_OPERAND_CCB :
1150 value = fields->f_ccb;
1151 break;
1152 case MS1_OPERAND_CDB :
1153 value = fields->f_cdb;
1154 break;
1155 case MS1_OPERAND_CELL :
1156 value = fields->f_cell;
1157 break;
1158 case MS1_OPERAND_COLNUM :
1159 value = fields->f_colnum;
1160 break;
1161 case MS1_OPERAND_CONTNUM :
1162 value = fields->f_contnum;
1163 break;
1164 case MS1_OPERAND_CR :
1165 value = fields->f_cr;
1166 break;
1167 case MS1_OPERAND_CTXDISP :
1168 value = fields->f_ctxdisp;
1169 break;
1170 case MS1_OPERAND_DUP :
1171 value = fields->f_dup;
1172 break;
1173 case MS1_OPERAND_FBDISP :
1174 value = fields->f_fbdisp;
1175 break;
1176 case MS1_OPERAND_FBINCR :
1177 value = fields->f_fbincr;
1178 break;
1179 case MS1_OPERAND_FRDR :
1180 value = fields->f_dr;
1181 break;
1182 case MS1_OPERAND_FRDRRR :
1183 value = fields->f_drrr;
1184 break;
1185 case MS1_OPERAND_FRSR1 :
1186 value = fields->f_sr1;
1187 break;
1188 case MS1_OPERAND_FRSR2 :
1189 value = fields->f_sr2;
1190 break;
1191 case MS1_OPERAND_ID :
1192 value = fields->f_id;
1193 break;
1194 case MS1_OPERAND_IMM16 :
1195 value = fields->f_imm16s;
1196 break;
1197 case MS1_OPERAND_IMM16O :
1198 value = fields->f_imm16s;
1199 break;
1200 case MS1_OPERAND_IMM16Z :
1201 value = fields->f_imm16u;
1202 break;
1203 case MS1_OPERAND_INCAMT :
1204 value = fields->f_incamt;
1205 break;
1206 case MS1_OPERAND_INCR :
1207 value = fields->f_incr;
1208 break;
1209 case MS1_OPERAND_LENGTH :
1210 value = fields->f_length;
1211 break;
1212 case MS1_OPERAND_MASK :
1213 value = fields->f_mask;
1214 break;
1215 case MS1_OPERAND_MASK1 :
1216 value = fields->f_mask1;
1217 break;
1218 case MS1_OPERAND_MODE :
1219 value = fields->f_mode;
1220 break;
1221 case MS1_OPERAND_PERM :
1222 value = fields->f_perm;
1223 break;
1224 case MS1_OPERAND_RBBC :
1225 value = fields->f_rbbc;
1226 break;
1227 case MS1_OPERAND_RC :
1228 value = fields->f_rc;
1229 break;
1230 case MS1_OPERAND_RC1 :
1231 value = fields->f_rc1;
1232 break;
1233 case MS1_OPERAND_RC2 :
1234 value = fields->f_rc2;
1235 break;
1236 case MS1_OPERAND_RCNUM :
1237 value = fields->f_rcnum;
1238 break;
1239 case MS1_OPERAND_RDA :
1240 value = fields->f_rda;
1241 break;
1242 case MS1_OPERAND_ROWNUM :
1243 value = fields->f_rownum;
1244 break;
1245 case MS1_OPERAND_ROWNUM1 :
1246 value = fields->f_rownum1;
1247 break;
1248 case MS1_OPERAND_ROWNUM2 :
1249 value = fields->f_rownum2;
1250 break;
1251 case MS1_OPERAND_SIZE :
1252 value = fields->f_size;
1253 break;
1254 case MS1_OPERAND_TYPE :
1255 value = fields->f_type;
1256 break;
1257 case MS1_OPERAND_WR :
1258 value = fields->f_wr;
1259 break;
1260 case MS1_OPERAND_XMODE :
1261 value = fields->f_xmode;
1262 break;
1263
1264 default :
1265 /* xgettext:c-format */
1266 fprintf (stderr, _("Unrecognized field %d while getting vma operand.\n"),
1267 opindex);
1268 abort ();
1269 }
1270
1271 return value;
1272}
1273
1274void ms1_cgen_set_int_operand
1275 PARAMS ((CGEN_CPU_DESC, int, CGEN_FIELDS *, int));
1276void ms1_cgen_set_vma_operand
1277 PARAMS ((CGEN_CPU_DESC, int, CGEN_FIELDS *, bfd_vma));
1278
1279/* Stuffing values in cgen_fields is handled by a collection of functions.
1280 They are distinguished by the type of the VALUE argument they accept.
1281 TODO: floating point, inlining support, remove cases where argument type
1282 not appropriate. */
1283
1284void
1285ms1_cgen_set_int_operand (cd, opindex, fields, value)
1286 CGEN_CPU_DESC cd ATTRIBUTE_UNUSED;
1287 int opindex;
1288 CGEN_FIELDS * fields;
1289 int value;
1290{
1291 switch (opindex)
1292 {
1293 case MS1_OPERAND_A23 :
1294 fields->f_a23 = value;
1295 break;
1296 case MS1_OPERAND_BALL :
1297 fields->f_ball = value;
1298 break;
1299 case MS1_OPERAND_BALL2 :
1300 fields->f_ball2 = value;
1301 break;
1302 case MS1_OPERAND_BANKADDR :
1303 fields->f_bankaddr = value;
1304 break;
1305 case MS1_OPERAND_BRC :
1306 fields->f_brc = value;
1307 break;
1308 case MS1_OPERAND_BRC2 :
1309 fields->f_brc2 = value;
1310 break;
1311 case MS1_OPERAND_CBRB :
1312 fields->f_cbrb = value;
1313 break;
1314 case MS1_OPERAND_CBS :
1315 fields->f_cbs = value;
1316 break;
1317 case MS1_OPERAND_CBX :
1318 fields->f_cbx = value;
1319 break;
1320 case MS1_OPERAND_CCB :
1321 fields->f_ccb = value;
1322 break;
1323 case MS1_OPERAND_CDB :
1324 fields->f_cdb = value;
1325 break;
1326 case MS1_OPERAND_CELL :
1327 fields->f_cell = value;
1328 break;
1329 case MS1_OPERAND_COLNUM :
1330 fields->f_colnum = value;
1331 break;
1332 case MS1_OPERAND_CONTNUM :
1333 fields->f_contnum = value;
1334 break;
1335 case MS1_OPERAND_CR :
1336 fields->f_cr = value;
1337 break;
1338 case MS1_OPERAND_CTXDISP :
1339 fields->f_ctxdisp = value;
1340 break;
1341 case MS1_OPERAND_DUP :
1342 fields->f_dup = value;
1343 break;
1344 case MS1_OPERAND_FBDISP :
1345 fields->f_fbdisp = value;
1346 break;
1347 case MS1_OPERAND_FBINCR :
1348 fields->f_fbincr = value;
1349 break;
1350 case MS1_OPERAND_FRDR :
1351 fields->f_dr = value;
1352 break;
1353 case MS1_OPERAND_FRDRRR :
1354 fields->f_drrr = value;
1355 break;
1356 case MS1_OPERAND_FRSR1 :
1357 fields->f_sr1 = value;
1358 break;
1359 case MS1_OPERAND_FRSR2 :
1360 fields->f_sr2 = value;
1361 break;
1362 case MS1_OPERAND_ID :
1363 fields->f_id = value;
1364 break;
1365 case MS1_OPERAND_IMM16 :
1366 fields->f_imm16s = value;
1367 break;
1368 case MS1_OPERAND_IMM16O :
1369 fields->f_imm16s = value;
1370 break;
1371 case MS1_OPERAND_IMM16Z :
1372 fields->f_imm16u = value;
1373 break;
1374 case MS1_OPERAND_INCAMT :
1375 fields->f_incamt = value;
1376 break;
1377 case MS1_OPERAND_INCR :
1378 fields->f_incr = value;
1379 break;
1380 case MS1_OPERAND_LENGTH :
1381 fields->f_length = value;
1382 break;
1383 case MS1_OPERAND_MASK :
1384 fields->f_mask = value;
1385 break;
1386 case MS1_OPERAND_MASK1 :
1387 fields->f_mask1 = value;
1388 break;
1389 case MS1_OPERAND_MODE :
1390 fields->f_mode = value;
1391 break;
1392 case MS1_OPERAND_PERM :
1393 fields->f_perm = value;
1394 break;
1395 case MS1_OPERAND_RBBC :
1396 fields->f_rbbc = value;
1397 break;
1398 case MS1_OPERAND_RC :
1399 fields->f_rc = value;
1400 break;
1401 case MS1_OPERAND_RC1 :
1402 fields->f_rc1 = value;
1403 break;
1404 case MS1_OPERAND_RC2 :
1405 fields->f_rc2 = value;
1406 break;
1407 case MS1_OPERAND_RCNUM :
1408 fields->f_rcnum = value;
1409 break;
1410 case MS1_OPERAND_RDA :
1411 fields->f_rda = value;
1412 break;
1413 case MS1_OPERAND_ROWNUM :
1414 fields->f_rownum = value;
1415 break;
1416 case MS1_OPERAND_ROWNUM1 :
1417 fields->f_rownum1 = value;
1418 break;
1419 case MS1_OPERAND_ROWNUM2 :
1420 fields->f_rownum2 = value;
1421 break;
1422 case MS1_OPERAND_SIZE :
1423 fields->f_size = value;
1424 break;
1425 case MS1_OPERAND_TYPE :
1426 fields->f_type = value;
1427 break;
1428 case MS1_OPERAND_WR :
1429 fields->f_wr = value;
1430 break;
1431 case MS1_OPERAND_XMODE :
1432 fields->f_xmode = value;
1433 break;
1434
1435 default :
1436 /* xgettext:c-format */
1437 fprintf (stderr, _("Unrecognized field %d while setting int operand.\n"),
1438 opindex);
1439 abort ();
1440 }
1441}
1442
1443void
1444ms1_cgen_set_vma_operand (cd, opindex, fields, value)
1445 CGEN_CPU_DESC cd ATTRIBUTE_UNUSED;
1446 int opindex;
1447 CGEN_FIELDS * fields;
1448 bfd_vma value;
1449{
1450 switch (opindex)
1451 {
1452 case MS1_OPERAND_A23 :
1453 fields->f_a23 = value;
1454 break;
1455 case MS1_OPERAND_BALL :
1456 fields->f_ball = value;
1457 break;
1458 case MS1_OPERAND_BALL2 :
1459 fields->f_ball2 = value;
1460 break;
1461 case MS1_OPERAND_BANKADDR :
1462 fields->f_bankaddr = value;
1463 break;
1464 case MS1_OPERAND_BRC :
1465 fields->f_brc = value;
1466 break;
1467 case MS1_OPERAND_BRC2 :
1468 fields->f_brc2 = value;
1469 break;
1470 case MS1_OPERAND_CBRB :
1471 fields->f_cbrb = value;
1472 break;
1473 case MS1_OPERAND_CBS :
1474 fields->f_cbs = value;
1475 break;
1476 case MS1_OPERAND_CBX :
1477 fields->f_cbx = value;
1478 break;
1479 case MS1_OPERAND_CCB :
1480 fields->f_ccb = value;
1481 break;
1482 case MS1_OPERAND_CDB :
1483 fields->f_cdb = value;
1484 break;
1485 case MS1_OPERAND_CELL :
1486 fields->f_cell = value;
1487 break;
1488 case MS1_OPERAND_COLNUM :
1489 fields->f_colnum = value;
1490 break;
1491 case MS1_OPERAND_CONTNUM :
1492 fields->f_contnum = value;
1493 break;
1494 case MS1_OPERAND_CR :
1495 fields->f_cr = value;
1496 break;
1497 case MS1_OPERAND_CTXDISP :
1498 fields->f_ctxdisp = value;
1499 break;
1500 case MS1_OPERAND_DUP :
1501 fields->f_dup = value;
1502 break;
1503 case MS1_OPERAND_FBDISP :
1504 fields->f_fbdisp = value;
1505 break;
1506 case MS1_OPERAND_FBINCR :
1507 fields->f_fbincr = value;
1508 break;
1509 case MS1_OPERAND_FRDR :
1510 fields->f_dr = value;
1511 break;
1512 case MS1_OPERAND_FRDRRR :
1513 fields->f_drrr = value;
1514 break;
1515 case MS1_OPERAND_FRSR1 :
1516 fields->f_sr1 = value;
1517 break;
1518 case MS1_OPERAND_FRSR2 :
1519 fields->f_sr2 = value;
1520 break;
1521 case MS1_OPERAND_ID :
1522 fields->f_id = value;
1523 break;
1524 case MS1_OPERAND_IMM16 :
1525 fields->f_imm16s = value;
1526 break;
1527 case MS1_OPERAND_IMM16O :
1528 fields->f_imm16s = value;
1529 break;
1530 case MS1_OPERAND_IMM16Z :
1531 fields->f_imm16u = value;
1532 break;
1533 case MS1_OPERAND_INCAMT :
1534 fields->f_incamt = value;
1535 break;
1536 case MS1_OPERAND_INCR :
1537 fields->f_incr = value;
1538 break;
1539 case MS1_OPERAND_LENGTH :
1540 fields->f_length = value;
1541 break;
1542 case MS1_OPERAND_MASK :
1543 fields->f_mask = value;
1544 break;
1545 case MS1_OPERAND_MASK1 :
1546 fields->f_mask1 = value;
1547 break;
1548 case MS1_OPERAND_MODE :
1549 fields->f_mode = value;
1550 break;
1551 case MS1_OPERAND_PERM :
1552 fields->f_perm = value;
1553 break;
1554 case MS1_OPERAND_RBBC :
1555 fields->f_rbbc = value;
1556 break;
1557 case MS1_OPERAND_RC :
1558 fields->f_rc = value;
1559 break;
1560 case MS1_OPERAND_RC1 :
1561 fields->f_rc1 = value;
1562 break;
1563 case MS1_OPERAND_RC2 :
1564 fields->f_rc2 = value;
1565 break;
1566 case MS1_OPERAND_RCNUM :
1567 fields->f_rcnum = value;
1568 break;
1569 case MS1_OPERAND_RDA :
1570 fields->f_rda = value;
1571 break;
1572 case MS1_OPERAND_ROWNUM :
1573 fields->f_rownum = value;
1574 break;
1575 case MS1_OPERAND_ROWNUM1 :
1576 fields->f_rownum1 = value;
1577 break;
1578 case MS1_OPERAND_ROWNUM2 :
1579 fields->f_rownum2 = value;
1580 break;
1581 case MS1_OPERAND_SIZE :
1582 fields->f_size = value;
1583 break;
1584 case MS1_OPERAND_TYPE :
1585 fields->f_type = value;
1586 break;
1587 case MS1_OPERAND_WR :
1588 fields->f_wr = value;
1589 break;
1590 case MS1_OPERAND_XMODE :
1591 fields->f_xmode = value;
1592 break;
1593
1594 default :
1595 /* xgettext:c-format */
1596 fprintf (stderr, _("Unrecognized field %d while setting vma operand.\n"),
1597 opindex);
1598 abort ();
1599 }
1600}
1601
1602/* Function to call before using the instruction builder tables. */
1603
1604void
1605ms1_cgen_init_ibld_table (cd)
1606 CGEN_CPU_DESC cd;
1607{
1608 cd->insert_handlers = & ms1_cgen_insert_handlers[0];
1609 cd->extract_handlers = & ms1_cgen_extract_handlers[0];
1610
1611 cd->insert_operand = ms1_cgen_insert_operand;
1612 cd->extract_operand = ms1_cgen_extract_operand;
1613
1614 cd->get_int_operand = ms1_cgen_get_int_operand;
1615 cd->set_int_operand = ms1_cgen_set_int_operand;
1616 cd->get_vma_operand = ms1_cgen_get_vma_operand;
1617 cd->set_vma_operand = ms1_cgen_set_vma_operand;
1618}
This page took 0.098295 seconds and 4 git commands to generate.