]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - opcodes/crx-dis.c
Automatic date update in version.in
[thirdparty/binutils-gdb.git] / opcodes / crx-dis.c
CommitLineData
1fe1f39c 1/* Disassembler code for CRX.
b3adc24a 2 Copyright (C) 2004-2020 Free Software Foundation, Inc.
1fe1f39c
NC
3 Contributed by Tomer Levi, NSC, Israel.
4 Written by Tomer Levi.
5
9b201bb5 6 This file is part of the GNU opcodes library.
1fe1f39c 7
9b201bb5
NC
8 This library is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3, or (at your option)
1fe1f39c
NC
11 any later version.
12
9b201bb5
NC
13 It is distributed in the hope that it will be useful, but WITHOUT
14 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
15 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
16 License for more details.
1fe1f39c
NC
17
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
9b201bb5
NC
20 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
21 MA 02110-1301, USA. */
1fe1f39c 22
1fe1f39c 23#include "sysdep.h"
88c1242d 24#include "disassemble.h"
1fe1f39c
NC
25#include "opcode/crx.h"
26
27/* String to print when opcode was not matched. */
28#define ILLEGAL "illegal"
29 /* Escape to 16-bit immediate. */
30#define ESCAPE_16_BIT 0xE
31
32/* Extract 'n_bits' from 'a' starting from offset 'offs'. */
33#define EXTRACT(a, offs, n_bits) \
36bd8ea7 34 (((a) >> (offs)) & ((2ull << (n_bits - 1)) - 1))
1fe1f39c
NC
35
36/* Set Bit Mask - a mask to set all bits starting from offset 'offs'. */
36bd8ea7 37#define SBM(offs) ((-1u << (offs)) & 0xffffffff)
1fe1f39c
NC
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 hold valid 'cinv' instruction options. */
49
50typedef struct
51 {
52 /* Cinv printed string. */
53 char *str;
54 /* Value corresponding to the string. */
55 unsigned int value;
56 }
57cinv_entry;
58
59/* CRX 'cinv' options. */
e5d70d6b 60static const cinv_entry crx_cinvs[] =
1fe1f39c 61{
43e65147
L
62 {"[i]", 2}, {"[i,u]", 3}, {"[d]", 4}, {"[d,u]", 5},
63 {"[d,i]", 6}, {"[d,i,u]", 7}, {"[b]", 8},
64 {"[b,i]", 10}, {"[b,i,u]", 11}, {"[b,d]", 12},
48c9f030 65 {"[b,d,u]", 13}, {"[b,d,i]", 14}, {"[b,d,i,u]", 15}
1fe1f39c
NC
66};
67
a58a3762
TL
68/* Enum to distinguish different registers argument types. */
69typedef enum REG_ARG_TYPE
48c9f030 70 {
a58a3762
TL
71 /* General purpose register (r<N>). */
72 REG_ARG = 0,
73 /* User register (u<N>). */
74 USER_REG_ARG,
75 /* CO-Processor register (c<N>). */
48c9f030 76 COP_ARG,
a58a3762 77 /* CO-Processor special register (cs<N>). */
43e65147 78 COPS_ARG
48c9f030 79 }
a58a3762 80REG_ARG_TYPE;
48c9f030 81
1fe1f39c 82/* Number of valid 'cinv' instruction options. */
e5d70d6b 83static int NUMCINVS = ((sizeof crx_cinvs)/(sizeof crx_cinvs[0]));
1fe1f39c 84/* Current opcode table entry we're disassembling. */
e5d70d6b 85static const inst *instruction;
1fe1f39c 86/* Current instruction we're disassembling. */
e5d70d6b 87static ins currInsn;
1fe1f39c 88/* The current instruction is read into 3 consecutive words. */
e5d70d6b 89static wordU words[3];
1fe1f39c 90/* Contains all words in appropriate order. */
e5d70d6b 91static ULONGLONG allWords;
1fe1f39c 92/* Holds the current processed argument number. */
e5d70d6b 93static int processing_argument_number;
1fe1f39c 94/* Nonzero means a CST4 instruction. */
e5d70d6b 95static int cst4flag;
1fe1f39c
NC
96/* Nonzero means the instruction's original size is
97 incremented (escape sequence is used). */
e5d70d6b 98static int size_changed;
1fe1f39c 99
1fe1f39c
NC
100
101/* Retrieve the number of operands for the current assembled instruction. */
102
103static int
104get_number_of_operands (void)
105{
106 int i;
107
100b122f 108 for (i = 0; i < MAX_OPERANDS && instruction->operands[i].op_type; i++)
1fe1f39c
NC
109 ;
110
111 return i;
112}
113
114/* Return the bit size for a given operand. */
115
116static int
117getbits (operand_type op)
118{
119 if (op < MAX_OPRD)
120 return crx_optab[op].bit_size;
121 else
122 return 0;
123}
124
125/* Return the argument type of a given operand. */
126
127static argtype
128getargtype (operand_type op)
129{
130 if (op < MAX_OPRD)
131 return crx_optab[op].arg_type;
132 else
133 return nullargs;
134}
135
136/* Given the trap index in dispatch table, return its name.
137 This routine is used when disassembling the 'excp' instruction. */
138
139static char *
91d6fa6a 140gettrapstring (unsigned int trap_index)
1fe1f39c
NC
141{
142 const trap_entry *trap;
143
144 for (trap = crx_traps; trap < crx_traps + NUMTRAPS; trap++)
91d6fa6a 145 if (trap->entry == trap_index)
1fe1f39c
NC
146 return trap->name;
147
148 return ILLEGAL;
149}
150
151/* Given a 'cinv' instruction constant operand, return its corresponding string.
152 This routine is used when disassembling the 'cinv' instruction. */
153
154static char *
155getcinvstring (unsigned int num)
156{
157 const cinv_entry *cinv;
158
159 for (cinv = crx_cinvs; cinv < (crx_cinvs + NUMCINVS); cinv++)
160 if (cinv->value == num)
161 return cinv->str;
162
163 return ILLEGAL;
164}
165
166/* Given a register enum value, retrieve its name. */
167
36bd8ea7 168static char *
1fe1f39c
NC
169getregname (reg r)
170{
91d6fa6a 171 const reg_entry * regentry = &crx_regtab[r];
1fe1f39c 172
91d6fa6a 173 if (regentry->type != CRX_R_REGTYPE)
1fe1f39c
NC
174 return ILLEGAL;
175 else
91d6fa6a 176 return regentry->name;
1fe1f39c
NC
177}
178
179/* Given a coprocessor register enum value, retrieve its name. */
180
36bd8ea7 181static char *
1fe1f39c
NC
182getcopregname (copreg r, reg_type type)
183{
91d6fa6a 184 const reg_entry * regentry;
1fe1f39c
NC
185
186 if (type == CRX_C_REGTYPE)
91d6fa6a 187 regentry = &crx_copregtab[r];
1fe1f39c 188 else if (type == CRX_CS_REGTYPE)
91d6fa6a 189 regentry = &crx_copregtab[r+(cs0-c0)];
1fe1f39c
NC
190 else
191 return ILLEGAL;
192
91d6fa6a 193 return regentry->name;
1fe1f39c
NC
194}
195
196
197/* Getting a processor register name. */
198
199static char *
91d6fa6a 200getprocregname (int reg_index)
1fe1f39c
NC
201{
202 const reg_entry *r;
203
204 for (r = crx_regtab; r < crx_regtab + NUMREGS; r++)
91d6fa6a 205 if (r->image == reg_index)
1fe1f39c
NC
206 return r->name;
207
208 return "ILLEGAL REGISTER";
209}
210
211/* Get the power of two for a given integer. */
212
213static int
214powerof2 (int x)
215{
216 int product, i;
217
218 for (i = 0, product = 1; i < x; i++)
219 product *= 2;
220
221 return product;
222}
223
224/* Transform a register bit mask to a register list. */
225
36bd8ea7 226static void
a58a3762 227getregliststring (int mask, char *string, enum REG_ARG_TYPE core_cop)
1fe1f39c 228{
e95b887f 229 char temp_string[16];
1fe1f39c
NC
230 int i;
231
232 string[0] = '{';
233 string[1] = '\0';
234
a58a3762
TL
235
236 /* A zero mask means HI/LO registers. */
237 if (mask == 0)
238 {
239 if (core_cop == USER_REG_ARG)
240 strcat (string, "ulo,uhi");
241 else
242 strcat (string, "lo,hi");
243 }
244 else
1fe1f39c 245 {
a58a3762 246 for (i = 0; i < 16; i++)
48c9f030 247 {
a58a3762 248 if (mask & 0x1)
48c9f030 249 {
a58a3762
TL
250 switch (core_cop)
251 {
252 case REG_ARG:
253 sprintf (temp_string, "r%d", i);
254 break;
255 case USER_REG_ARG:
256 sprintf (temp_string, "u%d", i);
257 break;
258 case COP_ARG:
259 sprintf (temp_string, "c%d", i);
260 break;
261 case COPS_ARG:
262 sprintf (temp_string, "cs%d", i);
263 break;
264 default:
265 break;
266 }
267 strcat (string, temp_string);
268 if (mask & 0xfffe)
269 strcat (string, ",");
48c9f030 270 }
a58a3762
TL
271 mask >>= 1;
272 }
1fe1f39c
NC
273 }
274
275 strcat (string, "}");
276}
277
278/* START and END are relating 'allWords' struct, which is 48 bits size.
279
280 START|--------|END
281 +---------+---------+---------+---------+
282 | | V | A | L |
283 +---------+---------+---------+---------+
284 0 16 32 48
285 words [0] [1] [2] */
286
287static parameter
288makelongparameter (ULONGLONG val, int start, int end)
289{
290 parameter p;
291
292 p.val = (dwordU) EXTRACT(val, 48 - end, end - start);
293 p.nbits = end - start;
294 return p;
295}
296
297/* Build a mask of the instruction's 'constant' opcode,
298 based on the instruction's printing flags. */
299
36bd8ea7 300static unsigned int
1fe1f39c
NC
301build_mask (void)
302{
303 unsigned int print_flags;
36bd8ea7 304 unsigned int mask;
1fe1f39c
NC
305
306 print_flags = instruction->flags & FMT_CRX;
307 switch (print_flags)
308 {
309 case FMT_1:
310 mask = 0xF0F00000;
311 break;
312 case FMT_2:
313 mask = 0xFFF0FF00;
314 break;
315 case FMT_3:
316 mask = 0xFFF00F00;
317 break;
318 case FMT_4:
319 mask = 0xFFF0F000;
320 break;
321 case FMT_5:
322 mask = 0xFFF0FFF0;
323 break;
324 default:
325 mask = SBM(instruction->match_bits);
326 break;
327 }
328
329 return mask;
330}
331
332/* Search for a matching opcode. Return 1 for success, 0 for failure. */
333
334static int
335match_opcode (void)
336{
36bd8ea7 337 unsigned int mask;
1fe1f39c
NC
338
339 /* The instruction 'constant' opcode doewsn't exceed 32 bits. */
2c5c1196 340 unsigned int doubleWord = words[1] + ((unsigned) words[0] << 16);
1fe1f39c
NC
341
342 /* Start searching from end of instruction table. */
343 instruction = &crx_instruction[NUMOPCODES - 2];
344
345 /* Loop over instruction table until a full match is found. */
346 while (instruction >= crx_instruction)
347 {
348 mask = build_mask ();
349 if ((doubleWord & mask) == BIN(instruction->match, instruction->match_bits))
350 return 1;
351 else
352 instruction--;
353 }
354 return 0;
355}
356
357/* Set the proper parameter value for different type of arguments. */
358
359static void
360make_argument (argument * a, int start_bits)
361{
362 int inst_bit_size, total_size;
363 parameter p;
364
365 if ((instruction->size == 3) && a->size >= 16)
366 inst_bit_size = 48;
367 else
368 inst_bit_size = 32;
369
370 switch (a->type)
371 {
372 case arg_copr:
373 case arg_copsr:
374 p = makelongparameter (allWords, inst_bit_size - (start_bits + a->size),
375 inst_bit_size - start_bits);
376 a->cr = p.val;
377 break;
378
379 case arg_r:
380 p = makelongparameter (allWords, inst_bit_size - (start_bits + a->size),
381 inst_bit_size - start_bits);
382 a->r = p.val;
383 break;
384
385 case arg_ic:
386 p = makelongparameter (allWords, inst_bit_size - (start_bits + a->size),
387 inst_bit_size - start_bits);
388
389 if ((p.nbits == 4) && cst4flag)
390 {
391 if (IS_INSN_TYPE (CMPBR_INS) && (p.val == ESCAPE_16_BIT))
392 {
393 /* A special case, where the value is actually stored
394 in the last 4 bits. */
395 p = makelongparameter (allWords, 44, 48);
396 /* The size of the instruction should be incremented. */
397 size_changed = 1;
398 }
399
400 if (p.val == 6)
401 p.val = -1;
402 else if (p.val == 13)
403 p.val = 48;
404 else if (p.val == 5)
405 p.val = -4;
406 else if (p.val == 10)
407 p.val = 32;
408 else if (p.val == 11)
409 p.val = 20;
410 else if (p.val == 9)
411 p.val = 16;
412 }
413
414 a->constant = p.val;
415 break;
416
42048ee7 417 case arg_idxr:
1fe1f39c
NC
418 a->scale = 0;
419 total_size = a->size + 10; /* sizeof(rbase + ridx + scl2) = 10. */
420 p = makelongparameter (allWords, inst_bit_size - total_size,
421 inst_bit_size - (total_size - 4));
422 a->r = p.val;
423 p = makelongparameter (allWords, inst_bit_size - (total_size - 4),
424 inst_bit_size - (total_size - 8));
425 a->i_r = p.val;
426 p = makelongparameter (allWords, inst_bit_size - (total_size - 8),
427 inst_bit_size - (total_size - 10));
428 a->scale = p.val;
429 p = makelongparameter (allWords, inst_bit_size - (total_size - 10),
430 inst_bit_size);
431 a->constant = p.val;
432 break;
433
434 case arg_rbase:
435 p = makelongparameter (allWords, inst_bit_size - (start_bits + 4),
436 inst_bit_size - start_bits);
437 a->r = p.val;
438 break;
439
440 case arg_cr:
441 if (a->size <= 8)
442 {
443 p = makelongparameter (allWords, inst_bit_size - (start_bits + 4),
444 inst_bit_size - start_bits);
445 a->r = p.val;
446 /* Case for opc4 r dispu rbase. */
447 p = makelongparameter (allWords, inst_bit_size - (start_bits + 8),
448 inst_bit_size - (start_bits + 4));
449 }
450 else
451 {
452 /* The 'rbase' start_bits is always relative to a 32-bit data type. */
453 p = makelongparameter (allWords, 32 - (start_bits + 4),
454 32 - start_bits);
455 a->r = p.val;
456 p = makelongparameter (allWords, 32 - start_bits,
457 inst_bit_size);
458 }
459 if ((p.nbits == 4) && cst4flag)
460 {
461 if (instruction->flags & DISPUW4)
462 p.val *= 2;
463 else if (instruction->flags & DISPUD4)
464 p.val *= 4;
465 }
466 a->constant = p.val;
467 break;
468
469 case arg_c:
470 p = makelongparameter (allWords, inst_bit_size - (start_bits + a->size),
471 inst_bit_size - start_bits);
472 a->constant = p.val;
473 break;
474 default:
475 break;
476 }
477}
478
479/* Print a single argument. */
480
481static void
12855a36 482print_arg (argument *a, bfd_vma memaddr, struct disassemble_info *info)
1fe1f39c
NC
483{
484 LONGLONG longdisp, mask;
12855a36
TL
485 int sign_flag = 0;
486 int relative = 0;
487 bfd_vma number;
1fe1f39c
NC
488 int op_index = 0;
489 char string[200];
490 PTR stream = info->stream;
491 fprintf_ftype func = info->fprintf_func;
492
493 switch (a->type)
494 {
495 case arg_copr:
496 func (stream, "%s", getcopregname (a->cr, CRX_C_REGTYPE));
497 break;
498
499 case arg_copsr:
500 func (stream, "%s", getcopregname (a->cr, CRX_CS_REGTYPE));
501 break;
502
503 case arg_r:
504 if (IS_INSN_MNEMONIC ("mtpr") || IS_INSN_MNEMONIC ("mfpr"))
505 func (stream, "%s", getprocregname (a->r));
506 else
507 func (stream, "%s", getregname (a->r));
508 break;
509
510 case arg_ic:
511 if (IS_INSN_MNEMONIC ("excp"))
512 func (stream, "%s", gettrapstring (a->constant));
513
514 else if (IS_INSN_MNEMONIC ("cinv"))
515 func (stream, "%s", getcinvstring (a->constant));
516
517 else if (INST_HAS_REG_LIST)
518 {
43e65147
L
519 REG_ARG_TYPE reg_arg_type = IS_INSN_TYPE (COP_REG_INS) ?
520 COP_ARG : IS_INSN_TYPE (COPS_REG_INS) ?
a58a3762
TL
521 COPS_ARG : (instruction->flags & USER_REG) ?
522 USER_REG_ARG : REG_ARG;
48c9f030 523
a58a3762 524 if ((reg_arg_type == COP_ARG) || (reg_arg_type == COPS_ARG))
48c9f030 525 {
a58a3762
TL
526 /* Check for proper argument number. */
527 if (processing_argument_number == 2)
528 {
529 getregliststring (a->constant, string, reg_arg_type);
530 func (stream, "%s", string);
531 }
532 else
1f42f8b3 533 func (stream, "$0x%lx", a->constant & 0xffffffff);
48c9f030
NC
534 }
535 else
1fe1f39c 536 {
a58a3762 537 getregliststring (a->constant, string, reg_arg_type);
1fe1f39c
NC
538 func (stream, "%s", string);
539 }
1fe1f39c
NC
540 }
541 else
1f42f8b3 542 func (stream, "$0x%lx", a->constant & 0xffffffff);
1fe1f39c
NC
543 break;
544
42048ee7 545 case arg_idxr:
1f42f8b3
AM
546 func (stream, "0x%lx(%s,%s,%d)", a->constant & 0xffffffff,
547 getregname (a->r), getregname (a->i_r), powerof2 (a->scale));
1fe1f39c
NC
548 break;
549
550 case arg_rbase:
551 func (stream, "(%s)", getregname (a->r));
552 break;
553
554 case arg_cr:
1f42f8b3 555 func (stream, "0x%lx(%s)", a->constant & 0xffffffff, getregname (a->r));
1fe1f39c
NC
556
557 if (IS_INSN_TYPE (LD_STOR_INS_INC))
558 func (stream, "+");
559 break;
560
561 case arg_c:
562 /* Removed the *2 part as because implicit zeros are no more required.
563 Have to fix this as this needs a bit of extension in terms of branchins.
564 Have to add support for cmp and branch instructions. */
565 if (IS_INSN_TYPE (BRANCH_INS) || IS_INSN_MNEMONIC ("bal")
566 || IS_INSN_TYPE (CMPBR_INS) || IS_INSN_TYPE (DCR_BRANCH_INS)
567 || IS_INSN_TYPE (COP_BRANCH_INS))
568 {
12855a36 569 relative = 1;
1fe1f39c
NC
570 longdisp = a->constant;
571 longdisp <<= 1;
1fe1f39c
NC
572
573 switch (a->size)
574 {
575 case 8:
576 case 16:
577 case 24:
578 case 32:
579 mask = ((LONGLONG)1 << a->size) - 1;
580 if (longdisp & ((LONGLONG)1 << a->size))
581 {
12855a36 582 sign_flag = 1;
1fe1f39c
NC
583 longdisp = ~(longdisp) + 1;
584 }
585 a->constant = (unsigned long int) (longdisp & mask);
586 break;
587 default:
588 func (stream,
589 "Wrong offset used in branch/bal instruction");
590 break;
591 }
592
1fe1f39c
NC
593 }
594 /* For branch Neq instruction it is 2*offset + 2. */
12855a36 595 else if (IS_INSN_TYPE (BRANCH_NEQ_INS))
1fe1f39c 596 a->constant = 2 * a->constant + 2;
12855a36 597 else if (IS_INSN_TYPE (LD_STOR_INS_INC)
1fe1f39c
NC
598 || IS_INSN_TYPE (LD_STOR_INS)
599 || IS_INSN_TYPE (STOR_IMM_INS)
600 || IS_INSN_TYPE (CSTBIT_INS))
601 {
602 op_index = instruction->flags & REVERSE_MATCH ? 0 : 1;
603 if (instruction->operands[op_index].op_type == abs16)
604 a->constant |= 0xFFFF0000;
605 }
12855a36
TL
606 func (stream, "%s", "0x");
607 number = (relative ? memaddr : 0)
608 + (sign_flag ? -a->constant : a->constant);
609 (*info->print_address_func) (number, info);
1fe1f39c
NC
610 break;
611 default:
612 break;
613 }
614}
615
616/* Print all the arguments of CURRINSN instruction. */
617
618static void
91d6fa6a 619print_arguments (ins *currentInsn, bfd_vma memaddr, struct disassemble_info *info)
1fe1f39c
NC
620{
621 int i;
622
91d6fa6a 623 for (i = 0; i < currentInsn->nargs; i++)
1fe1f39c
NC
624 {
625 processing_argument_number = i;
626
91d6fa6a 627 print_arg (&currentInsn->arg[i], memaddr, info);
1fe1f39c 628
91d6fa6a 629 if (i != currentInsn->nargs - 1)
1fe1f39c
NC
630 info->fprintf_func (info->stream, ", ");
631 }
632}
633
634/* Build the instruction's arguments. */
635
636static void
637make_instruction (void)
638{
639 int i;
89a649f7 640 unsigned int shift;
1fe1f39c
NC
641
642 for (i = 0; i < currInsn.nargs; i++)
643 {
47d8304e 644 argument a;
ec36c4a4 645
47d8304e 646 memset (&a, 0, sizeof (a));
1fe1f39c
NC
647 a.type = getargtype (instruction->operands[i].op_type);
648 if (instruction->operands[i].op_type == cst4
89a649f7 649 || instruction->operands[i].op_type == rbase_dispu4)
1fe1f39c
NC
650 cst4flag = 1;
651 a.size = getbits (instruction->operands[i].op_type);
652 shift = instruction->operands[i].shift;
653
654 make_argument (&a, shift);
655 currInsn.arg[i] = a;
656 }
657
658 /* Calculate instruction size (in bytes). */
659 currInsn.size = instruction->size + (size_changed ? 1 : 0);
89a649f7 660 /* Now in bits. */
1fe1f39c 661 currInsn.size *= 2;
1fe1f39c
NC
662}
663
664/* Retrieve a single word from a given memory address. */
665
666static wordU
667get_word_at_PC (bfd_vma memaddr, struct disassemble_info *info)
668{
669 bfd_byte buffer[4];
670 int status;
671 wordU insn = 0;
672
673 status = info->read_memory_func (memaddr, buffer, 2, info);
674
675 if (status == 0)
676 insn = (wordU) bfd_getl16 (buffer);
677
678 return insn;
679}
680
681/* Retrieve multiple words (3) from a given memory address. */
682
683static void
684get_words_at_PC (bfd_vma memaddr, struct disassemble_info *info)
685{
686 int i;
687 bfd_vma mem;
688
689 for (i = 0, mem = memaddr; i < 3; i++, mem += 2)
690 words[i] = get_word_at_PC (mem, info);
691
692 allWords =
693 ((ULONGLONG) words[0] << 32) + ((unsigned long) words[1] << 16) + words[2];
694}
695
696/* Prints the instruction by calling print_arguments after proper matching. */
697
698int
e6c7cdec 699print_insn_crx (bfd_vma memaddr, struct disassemble_info *info)
1fe1f39c
NC
700{
701 int is_decoded; /* Nonzero means instruction has a match. */
702
703 /* Initialize global variables. */
704 cst4flag = 0;
705 size_changed = 0;
706
707 /* Retrieve the encoding from current memory location. */
708 get_words_at_PC (memaddr, info);
709 /* Find a matching opcode in table. */
710 is_decoded = match_opcode ();
711 /* If found, print the instruction's mnemonic and arguments. */
616ec358 712 if (is_decoded > 0 && (words[0] != 0 || words[1] != 0))
1fe1f39c
NC
713 {
714 info->fprintf_func (info->stream, "%s", instruction->mnemonic);
715 if ((currInsn.nargs = get_number_of_operands ()) != 0)
716 info->fprintf_func (info->stream, "\t");
717 make_instruction ();
12855a36 718 print_arguments (&currInsn, memaddr, info);
1fe1f39c
NC
719 return currInsn.size;
720 }
721
722 /* No match found. */
723 info->fprintf_func (info->stream,"%s ",ILLEGAL);
724 return 2;
725}