Added --identify option to dlltool.
[deliverable/binutils-gdb.git] / opcodes / cr16-dis.c
CommitLineData
3d3d428f 1/* Disassembler code for CR16.
3ce6fddb 2 Copyright 2007, 2008 Free Software Foundation, Inc.
3d3d428f
NC
3 Contributed by M R Swami Reddy (MR.Swami.Reddy@nsc.com).
4
5 This file is part of GAS, GDB and the GNU binutils.
6
9b201bb5
NC
7 This program is free software; you can redistribute it and/or modify it
8 under the terms of the GNU General Public License as published by the
9 Free Software Foundation; either version 3, or (at your option)
3d3d428f
NC
10 any later version.
11
12 This program is distributed in the hope that it will be useful, but WITHOUT
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
15 more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software Foundation,
19 Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */
20
21#include "dis-asm.h"
22#include "sysdep.h"
23#include "opcode/cr16.h"
24#include "libiberty.h"
25
26/* String to print when opcode was not matched. */
27#define ILLEGAL "illegal"
28 /* Escape to 16-bit immediate. */
29#define ESCAPE_16_BIT 0xB
30
31/* Extract 'n_bits' from 'a' starting from offset 'offs'. */
32#define EXTRACT(a, offs, n_bits) \
33 (n_bits == 32 ? (((a) >> (offs)) & 0xffffffffL) \
34 : (((a) >> (offs)) & ((1 << (n_bits)) -1)))
35
36/* Set Bit Mask - a mask to set all bits starting from offset 'offs'. */
37#define SBM(offs) ((((1 << (32 - offs)) -1) << (offs)))
38
39typedef unsigned long dwordU;
40typedef unsigned short wordU;
41
42typedef struct
43{
44 dwordU val;
45 int nbits;
46} parameter;
47
48/* Structure to map valid 'cinv' instruction options. */
49
50typedef struct
51 {
52 /* Cinv printed string. */
53 char *istr;
54 /* Value corresponding to the string. */
55 char *ostr;
56 }
57cinv_entry;
58
59/* CR16 'cinv' options mapping. */
60const cinv_entry cr16_cinvs[] =
61{
62 {"cinv[i]", "cinv [i]"},
63 {"cinv[i,u]", "cinv [i,u]"},
64 {"cinv[d]", "cinv [d]"},
65 {"cinv[d,u]", "cinv [d,u]"},
66 {"cinv[d,i]", "cinv [d,i]"},
67 {"cinv[d,i,u]", "cinv [d,i,u]"}
68};
69
70/* Number of valid 'cinv' instruction options. */
71static int NUMCINVS = ARRAY_SIZE (cr16_cinvs);
72
73/* Enum to distinguish different registers argument types. */
74typedef enum REG_ARG_TYPE
75 {
76 /* General purpose register (r<N>). */
77 REG_ARG = 0,
78 /*Processor register */
79 P_ARG,
80 }
81REG_ARG_TYPE;
82
83/* Current opcode table entry we're disassembling. */
84const inst *instruction;
85/* Current instruction we're disassembling. */
86ins currInsn;
87/* The current instruction is read into 3 consecutive words. */
88wordU words[3];
89/* Contains all words in appropriate order. */
90ULONGLONG allWords;
91/* Holds the current processed argument number. */
92int processing_argument_number;
93/* Nonzero means a IMM4 instruction. */
94int imm4flag;
95/* Nonzero means the instruction's original size is
96 incremented (escape sequence is used). */
97int size_changed;
98
99
100/* Print the constant expression length. */
101
102static char *
103print_exp_len (int size)
104{
105 switch (size)
106 {
107 case 4:
108 case 5:
109 case 6:
110 case 8:
111 case 14:
112 case 16:
113 return ":s";
114 case 20:
115 case 24:
116 case 32:
117 return ":m";
118 case 48:
119 return ":l";
120 default:
121 return "";
122 }
123}
124
125
126/* Retrieve the number of operands for the current assembled instruction. */
127
128static int
129get_number_of_operands (void)
130{
131 int i;
132
133 for (i = 0; instruction->operands[i].op_type && i < MAX_OPERANDS; i++)
134 ;
135
136 return i;
137}
138
139/* Return the bit size for a given operand. */
140
141static int
142getbits (operand_type op)
143{
144 if (op < MAX_OPRD)
145 return cr16_optab[op].bit_size;
146
147 return 0;
148}
149
150/* Return the argument type of a given operand. */
151
152static argtype
153getargtype (operand_type op)
154{
155 if (op < MAX_OPRD)
156 return cr16_optab[op].arg_type;
157
158 return nullargs;
159}
160
161/* Given a 'CC' instruction constant operand, return its corresponding
162 string. This routine is used when disassembling the 'CC' instruction. */
163
164static char *
165getccstring (unsigned cc)
166{
167 return (char *) cr16_b_cond_tab[cc];
168}
169
170
171/* Given a 'cinv' instruction constant operand, return its corresponding
172 string. This routine is used when disassembling the 'cinv' instruction. */
173
174static char *
ddb341a7 175getcinvstring (const char *str)
3d3d428f
NC
176{
177 const cinv_entry *cinv;
178
179 for (cinv = cr16_cinvs; cinv < (cr16_cinvs + NUMCINVS); cinv++)
180 if (strcmp (cinv->istr, str) == 0)
181 return cinv->ostr;
182
183 return ILLEGAL;
184}
185
186/* Given the trap index in dispatch table, return its name.
187 This routine is used when disassembling the 'excp' instruction. */
188
189static char *
190gettrapstring (unsigned int index)
191{
192 const trap_entry *trap;
193
194 for (trap = cr16_traps; trap < cr16_traps + NUMTRAPS; trap++)
195 if (trap->entry == index)
196 return trap->name;
197
198 return ILLEGAL;
199}
200
201/* Given a register enum value, retrieve its name. */
202
203static char *
204getregname (reg r)
205{
206 const reg_entry *reg = cr16_regtab + r;
207
208 if (reg->type != CR16_R_REGTYPE)
209 return ILLEGAL;
210
211 return reg->name;
212}
213
214/* Given a register pair enum value, retrieve its name. */
215
216static char *
217getregpname (reg r)
218{
219 const reg_entry *reg = cr16_regptab + r;
220
221 if (reg->type != CR16_RP_REGTYPE)
222 return ILLEGAL;
223
224 return reg->name;
225}
226
227/* Given a index register pair enum value, retrieve its name. */
228
229static char *
230getidxregpname (reg r)
231{
232 const reg_entry *reg;
233
234 switch (r)
235 {
236 case 0: r = 0; break;
237 case 1: r = 2; break;
238 case 2: r = 4; break;
239 case 3: r = 6; break;
240 case 4: r = 8; break;
241 case 5: r = 10; break;
242 case 6: r = 3; break;
243 case 7: r = 5; break;
244 default:
245 break;
246 }
247
248 reg = cr16_regptab + r;
249
250 if (reg->type != CR16_RP_REGTYPE)
251 return ILLEGAL;
252
253 return reg->name;
254}
255
256/* Getting a processor register name. */
257
258static char *
259getprocregname (int index)
260{
261 const reg_entry *r;
262
263 for (r = cr16_pregtab; r < cr16_pregtab + NUMPREGS; r++)
264 if (r->image == index)
265 return r->name;
266
267 return "ILLEGAL REGISTER";
268}
269
270/* Getting a processor register name - 32 bit size. */
271
272static char *
273getprocpregname (int index)
274{
275 const reg_entry *r;
276
277 for (r = cr16_pregptab; r < cr16_pregptab + NUMPREGPS; r++)
278 if (r->image == index)
279 return r->name;
280
281 return "ILLEGAL REGISTER";
282}
283
284/* START and END are relating 'allWords' struct, which is 48 bits size.
285
286 START|--------|END
287 +---------+---------+---------+---------+
288 | | V | A | L |
289 +---------+---------+---------+---------+
290 0 16 32 48
291 words [0] [1] [2] */
292
293static parameter
294makelongparameter (ULONGLONG val, int start, int end)
295{
296 parameter p;
297
298 p.val = (dwordU) EXTRACT (val, 48 - end, end - start);
299 p.nbits = end - start;
300 return p;
301}
302
303/* Build a mask of the instruction's 'constant' opcode,
304 based on the instruction's printing flags. */
305
306static unsigned long
307build_mask (void)
308{
309 unsigned long mask = SBM (instruction->match_bits);
3ce6fddb
NC
310
311 /* Adjust mask for bcond with 32-bit size instruction. */
312 if ((IS_INSN_MNEMONIC("b") && instruction->size == 2))
313 mask = 0xff0f0000;
314
3d3d428f
NC
315 return mask;
316}
317
318/* Search for a matching opcode. Return 1 for success, 0 for failure. */
319
320static int
321match_opcode (void)
322{
323 unsigned long mask;
324 /* The instruction 'constant' opcode doewsn't exceed 32 bits. */
325 unsigned long doubleWord = words[1] + (words[0] << 16);
326
327 /* Start searching from end of instruction table. */
328 instruction = &cr16_instruction[NUMOPCODES - 2];
329
330 /* Loop over instruction table until a full match is found. */
331 while (instruction >= cr16_instruction)
332 {
333 mask = build_mask ();
334 if ((doubleWord & mask) == BIN (instruction->match,
335 instruction->match_bits))
336 return 1;
337 else
338 instruction--;
339 }
340 return 0;
341}
342
343/* Set the proper parameter value for different type of arguments. */
344
345static void
346make_argument (argument * a, int start_bits)
347{
348 int inst_bit_size;
349 parameter p;
350
351 if ((instruction->size == 3) && a->size >= 16)
352 inst_bit_size = 48;
353 else
354 inst_bit_size = 32;
355
356 switch (a->type)
357 {
358 case arg_r:
359 p = makelongparameter (allWords, inst_bit_size - (start_bits + a->size),
360 inst_bit_size - start_bits);
361 a->r = p.val;
362 break;
363
364 case arg_rp:
365 p = makelongparameter (allWords, inst_bit_size - (start_bits + a->size),
366 inst_bit_size - start_bits);
367 a->rp = p.val;
368 break;
369
370 case arg_pr:
371 p = makelongparameter (allWords, inst_bit_size - (start_bits + a->size),
372 inst_bit_size - start_bits);
373 a->pr = p.val;
374 break;
375
376 case arg_prp:
377 p = makelongparameter (allWords, inst_bit_size - (start_bits + a->size),
378 inst_bit_size - start_bits);
379 a->prp = p.val;
380 break;
381
382 case arg_ic:
383 p = makelongparameter (allWords, inst_bit_size - (start_bits + a->size),
384 inst_bit_size - start_bits);
385 a->constant = p.val;
386 break;
387
388 case arg_cc:
389 p = makelongparameter (allWords, inst_bit_size - (start_bits + a->size),
390 inst_bit_size - start_bits);
391
392 a->cc = p.val;
393 break;
394
395 case arg_idxr:
396 if ((IS_INSN_MNEMONIC ("cbitb"))
397 || (IS_INSN_MNEMONIC ("sbitb"))
398 || (IS_INSN_MNEMONIC ("tbitb")))
399 p = makelongparameter (allWords, 8, 9);
400 else
401 p = makelongparameter (allWords, 9, 10);
402 a->i_r = p.val;
403 p = makelongparameter (allWords, inst_bit_size - a->size, inst_bit_size);
404 a->constant = p.val;
405 break;
406
407 case arg_idxrp:
408 p = makelongparameter (allWords, start_bits + 12, start_bits + 13);
409 a->i_r = p.val;
410 p = makelongparameter (allWords, start_bits + 13, start_bits + 16);
411 a->rp = p.val;
412 if (inst_bit_size > 32)
413 {
414 p = makelongparameter (allWords, inst_bit_size - start_bits - 12,
415 inst_bit_size);
416 a->constant = ((p.val & 0xffff) | (p.val >> 8 & 0xf0000));
417 }
418 else if (instruction->size == 2)
419 {
420 p = makelongparameter (allWords, inst_bit_size - 22, inst_bit_size);
421 a->constant = (p.val & 0xf) | (((p.val >>20) & 0x3) << 4)
422 | ((p.val >>14 & 0x3) << 6) | (((p.val >>7) & 0x1f) <<7);
423 }
424 else if (instruction->size == 1 && a->size == 0)
425 a->constant = 0;
426
427 break;
428
429 case arg_rbase:
430 p = makelongparameter (allWords, inst_bit_size, inst_bit_size);
431 a->constant = p.val;
432 p = makelongparameter (allWords, inst_bit_size - (start_bits + 4),
433 inst_bit_size - start_bits);
434 a->r = p.val;
435 break;
436
437 case arg_cr:
438 p = makelongparameter (allWords, start_bits + 12, start_bits + 16);
439 a->r = p.val;
440 p = makelongparameter (allWords, inst_bit_size - 16, inst_bit_size);
441 a->constant = p.val;
442 break;
443
444 case arg_crp:
445 if (instruction->size == 1)
446 p = makelongparameter (allWords, 12, 16);
447 else
448 p = makelongparameter (allWords, start_bits + 12, start_bits + 16);
449 a->rp = p.val;
450
451 if (inst_bit_size > 32)
452 {
453 p = makelongparameter (allWords, inst_bit_size - start_bits - 12,
454 inst_bit_size);
455 a->constant = ((p.val & 0xffff) | (p.val >> 8 & 0xf0000));
456 }
457 else if (instruction->size == 2)
458 {
459 p = makelongparameter (allWords, inst_bit_size - 16, inst_bit_size);
460 a->constant = p.val;
461 }
462 else if (instruction->size == 1 && a->size != 0)
463 {
464 p = makelongparameter (allWords, 4, 8);
465 if (IS_INSN_MNEMONIC ("loadw")
466 || IS_INSN_MNEMONIC ("loadd")
467 || IS_INSN_MNEMONIC ("storw")
468 || IS_INSN_MNEMONIC ("stord"))
469 a->constant = (p.val * 2);
470 else
471 a->constant = p.val;
472 }
473 else /* below case for 0x0(reg pair) */
474 a->constant = 0;
475
476 break;
477
478 case arg_c:
479
480 if ((IS_INSN_TYPE (BRANCH_INS))
481 || (IS_INSN_MNEMONIC ("bal"))
482 || (IS_INSN_TYPE (CSTBIT_INS))
483 || (IS_INSN_TYPE (LD_STOR_INS)))
484 {
485 switch (a->size)
486 {
487 case 8 :
488 p = makelongparameter (allWords, 0, start_bits);
489 a->constant = ((((p.val&0xf00)>>4)) | (p.val&0xf));
490 break;
491
492 case 24:
493 if (instruction->size == 3)
494 {
495 p = makelongparameter (allWords, 16, inst_bit_size);
496 a->constant = ((((p.val>>16)&0xf) << 20)
497 | (((p.val>>24)&0xf) << 16)
498 | (p.val & 0xffff));
499 }
500 else if (instruction->size == 2)
501 {
502 p = makelongparameter (allWords, 8, inst_bit_size);
503 a->constant = p.val;
504 }
505 break;
506
507 default:
508 p = makelongparameter (allWords, inst_bit_size - (start_bits +
509 a->size), inst_bit_size - start_bits);
510 a->constant = p.val;
511 break;
512 }
513 }
514 else
515 {
516 p = makelongparameter (allWords, inst_bit_size -
517 (start_bits + a->size),
518 inst_bit_size - start_bits);
519 a->constant = p.val;
520 }
521 break;
522
523 default:
524 break;
525 }
526}
527
528/* Print a single argument. */
529
530static void
531print_arg (argument *a, bfd_vma memaddr, struct disassemble_info *info)
532{
533 LONGLONG longdisp, mask;
534 int sign_flag = 0;
535 int relative = 0;
536 bfd_vma number;
537 PTR stream = info->stream;
538 fprintf_ftype func = info->fprintf_func;
539
540 switch (a->type)
541 {
542 case arg_r:
543 func (stream, "%s", getregname (a->r));
544 break;
545
546 case arg_rp:
547 func (stream, "%s", getregpname (a->rp));
548 break;
549
550 case arg_pr:
551 func (stream, "%s", getprocregname (a->pr));
552 break;
553
554 case arg_prp:
555 func (stream, "%s", getprocpregname (a->prp));
556 break;
557
558 case arg_cc:
559 func (stream, "%s", getccstring (a->cc));
560 func (stream, "%s", "\t");
561 break;
562
563 case arg_ic:
564 if (IS_INSN_MNEMONIC ("excp"))
565 {
566 func (stream, "%s", gettrapstring (a->constant));
567 break;
568 }
569 else if ((IS_INSN_TYPE (ARITH_INS) || IS_INSN_TYPE (ARITH_BYTE_INS))
570 && ((instruction->size == 1) && (a->constant == 9)))
571 func (stream, "$%d", -1);
572 else if (INST_HAS_REG_LIST)
573 func (stream, "$0x%lx", a->constant +1);
574 else if (IS_INSN_TYPE (SHIFT_INS))
575 {
576 longdisp = a->constant;
577 mask = ((LONGLONG)1 << a->size) - 1;
578 if (longdisp & ((LONGLONG)1 << (a->size -1)))
579 {
580 sign_flag = 1;
581 longdisp = ~(longdisp) + 1;
582 }
583 a->constant = (unsigned long int) (longdisp & mask);
584 func (stream, "$%d", ((int)(sign_flag ? -a->constant :
585 a->constant)));
586 }
587 else
588 func (stream, "$0x%lx", a->constant);
589 switch (a->size)
590 {
591 case 4 : case 5 : case 6 : case 8 :
592 func (stream, "%s", ":s"); break;
593 case 16 : case 20 : func (stream, "%s", ":m"); break;
594 case 24 : case 32 : func (stream, "%s", ":l"); break;
595 default: break;
596 }
597 break;
598
599 case arg_idxr:
600 if (a->i_r == 0) func (stream, "[r12]");
601 if (a->i_r == 1) func (stream, "[r13]");
602 func (stream, "0x%lx", a->constant);
603 func (stream, "%s", print_exp_len (instruction->size * 16));
604 break;
605
606 case arg_idxrp:
607 if (a->i_r == 0) func (stream, "[r12]");
608 if (a->i_r == 1) func (stream, "[r13]");
609 func (stream, "0x%lx", a->constant);
610 func (stream, "%s", print_exp_len (instruction->size * 16));
611 func (stream, "%s", getidxregpname (a->rp));
612 break;
613
614 case arg_rbase:
615 func (stream, "(%s)", getregname (a->r));
616 break;
617
618 case arg_cr:
619 func (stream, "0x%lx", a->constant);
620 func (stream, "%s", print_exp_len (instruction->size * 16));
621 func (stream, "(%s)", getregname (a->r));
622 break;
623
624 case arg_crp:
625 func (stream, "0x%lx", a->constant);
626 func (stream, "%s", print_exp_len (instruction->size * 16));
627 func (stream, "%s", getregpname (a->rp));
628 break;
629
630 case arg_c:
631 /*Removed the *2 part as because implicit zeros are no more required.
632 Have to fix this as this needs a bit of extension in terms of branch
633 instructions. */
634 if (IS_INSN_TYPE (BRANCH_INS) || IS_INSN_MNEMONIC ("bal"))
635 {
636 relative = 1;
637 longdisp = a->constant;
638 /* REVISIT: To sync with WinIDEA and CR16 4.1tools, the below
639 line commented */
640 /* longdisp <<= 1; */
641 mask = ((LONGLONG)1 << a->size) - 1;
642 switch (a->size)
643 {
644 case 8 :
645 {
646 longdisp <<= 1;
647 if (longdisp & ((LONGLONG)1 << a->size))
648 {
649 sign_flag = 1;
650 longdisp = ~(longdisp) + 1;
651 }
652 break;
653 }
654 case 16 :
655 case 24 :
656 {
657 if (longdisp & 1)
658 {
659 sign_flag = 1;
660 longdisp = ~(longdisp) + 1;
661 }
662 break;
663 }
664 default:
665 func (stream, "Wrong offset used in branch/bal instruction");
666 break;
667 }
668 a->constant = (unsigned long int) (longdisp & mask);
669 }
670 /* For branch Neq instruction it is 2*offset + 2. */
671 else if (IS_INSN_TYPE (BRANCH_NEQ_INS))
672 a->constant = 2 * a->constant + 2;
673
674 if ((!IS_INSN_TYPE (CSTBIT_INS)) && (!IS_INSN_TYPE (LD_STOR_INS)))
675 (sign_flag) ? func (stream, "%s", "*-"): func (stream, "%s","*+");
676
677 func (stream, "%s", "0x");
678 number = ((relative ? memaddr : 0) +
679 (sign_flag ? ((- a->constant) & 0xffffffe) : a->constant));
680
681 (*info->print_address_func) ((number & ((1 << 24) - 1)), info);
682
683 func (stream, "%s", print_exp_len (instruction->size * 16));
684 break;
685
686 default:
687 break;
688 }
689}
690
691/* Print all the arguments of CURRINSN instruction. */
692
693static void
694print_arguments (ins *currInsn, bfd_vma memaddr, struct disassemble_info *info)
695{
696 int i;
697
698 /* For "pop/push/popret RA instruction only. */
699 if ((IS_INSN_MNEMONIC ("pop")
700 || (IS_INSN_MNEMONIC ("popret")
701 || (IS_INSN_MNEMONIC ("push"))))
702 && currInsn->nargs == 1)
703 {
704 info->fprintf_func (info->stream, "RA");
705 return;
706 }
707
708 for (i = 0; i < currInsn->nargs; i++)
709 {
710 processing_argument_number = i;
711
712 /* For "bal (ra), disp17" instruction only. */
713 if ((IS_INSN_MNEMONIC ("bal")) && (i == 0) && instruction->size == 2)
714 {
715 info->fprintf_func (info->stream, "(ra),");
716 continue;
717 }
718
719 if ((INST_HAS_REG_LIST) && (i == 2))
720 info->fprintf_func (info->stream, "RA");
721 else
722 print_arg (&currInsn->arg[i], memaddr, info);
723
724 if ((i != currInsn->nargs - 1) && (!IS_INSN_MNEMONIC ("b")))
725 info->fprintf_func (info->stream, ",");
726 }
727}
728
729/* Build the instruction's arguments. */
730
731static void
732make_instruction (void)
733{
734 int i;
735 unsigned int shift;
736
737 for (i = 0; i < currInsn.nargs; i++)
738 {
739 argument a;
740
741 memset (&a, 0, sizeof (a));
742 a.type = getargtype (instruction->operands[i].op_type);
743 a.size = getbits (instruction->operands[i].op_type);
744 shift = instruction->operands[i].shift;
745
746 make_argument (&a, shift);
747 currInsn.arg[i] = a;
748 }
749
750 /* Calculate instruction size (in bytes). */
751 currInsn.size = instruction->size + (size_changed ? 1 : 0);
752 /* Now in bits. */
753 currInsn.size *= 2;
754}
755
756/* Retrieve a single word from a given memory address. */
757
758static wordU
759get_word_at_PC (bfd_vma memaddr, struct disassemble_info *info)
760{
761 bfd_byte buffer[4];
762 int status;
763 wordU insn = 0;
764
765 status = info->read_memory_func (memaddr, buffer, 2, info);
766
767 if (status == 0)
768 insn = (wordU) bfd_getl16 (buffer);
769
770 return insn;
771}
772
773/* Retrieve multiple words (3) from a given memory address. */
774
775static void
776get_words_at_PC (bfd_vma memaddr, struct disassemble_info *info)
777{
778 int i;
779 bfd_vma mem;
780
781 for (i = 0, mem = memaddr; i < 3; i++, mem += 2)
782 words[i] = get_word_at_PC (mem, info);
783
784 allWords =
785 ((ULONGLONG) words[0] << 32) + ((unsigned long) words[1] << 16) + words[2];
786}
787
788/* Prints the instruction by calling print_arguments after proper matching. */
789
790int
791print_insn_cr16 (bfd_vma memaddr, struct disassemble_info *info)
792{
793 int is_decoded; /* Nonzero means instruction has a match. */
794
795 /* Initialize global variables. */
796 imm4flag = 0;
797 size_changed = 0;
798
799 /* Retrieve the encoding from current memory location. */
800 get_words_at_PC (memaddr, info);
801 /* Find a matching opcode in table. */
802 is_decoded = match_opcode ();
803 /* If found, print the instruction's mnemonic and arguments. */
804 if (is_decoded > 0 && (words[0] << 16 || words[1]) != 0)
805 {
806 if (strneq (instruction->mnemonic, "cinv", 4))
ddb341a7 807 info->fprintf_func (info->stream,"%s", getcinvstring (instruction->mnemonic));
3d3d428f
NC
808 else
809 info->fprintf_func (info->stream, "%s", instruction->mnemonic);
810
811 if (((currInsn.nargs = get_number_of_operands ()) != 0)
812 && ! (IS_INSN_MNEMONIC ("b")))
813 info->fprintf_func (info->stream, "\t");
814 make_instruction ();
815 /* For push/pop/pushrtn with RA instructions. */
816 if ((INST_HAS_REG_LIST) && ((words[0] >> 7) & 0x1))
817 currInsn.nargs +=1;
818 print_arguments (&currInsn, memaddr, info);
819 return currInsn.size;
820 }
821
822 /* No match found. */
823 info->fprintf_func (info->stream,"%s ",ILLEGAL);
824 return 2;
825}
This page took 0.101519 seconds and 4 git commands to generate.