[ARC] Force the disassam to use the hexadecimal number for printing
[deliverable/binutils-gdb.git] / opcodes / arc-dis.c
1 /* Instruction printing code for the ARC.
2 Copyright (C) 1994-2017 Free Software Foundation, Inc.
3
4 Contributed by Claudiu Zissulescu (claziss@synopsys.com)
5
6 This file is part of libopcodes.
7
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)
11 any later version.
12
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.
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
20 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
21 MA 02110-1301, USA. */
22
23 #include "sysdep.h"
24 #include <stdio.h>
25 #include <assert.h>
26 #include "dis-asm.h"
27 #include "opcode/arc.h"
28 #include "elf/arc.h"
29 #include "arc-dis.h"
30 #include "arc-ext.h"
31 #include "elf-bfd.h"
32 #include "libiberty.h"
33 #include "opintl.h"
34
35 /* Structure used to iterate over, and extract the values for, operands of
36 an opcode. */
37
38 struct arc_operand_iterator
39 {
40 /* The complete instruction value to extract operands from. */
41 unsigned long long insn;
42
43 /* The LIMM if this is being tracked separately. This field is only
44 valid if we find the LIMM operand in the operand list. */
45 unsigned limm;
46
47 /* The opcode this iterator is operating on. */
48 const struct arc_opcode *opcode;
49
50 /* The index into the opcodes operand index list. */
51 const unsigned char *opidx;
52 };
53
54 /* A private data used by ARC decoder. */
55 struct arc_disassemble_info
56 {
57 /* The current disassembled arc opcode. */
58 const struct arc_opcode *opcode;
59
60 /* Instruction length w/o limm field. */
61 unsigned insn_len;
62
63 /* TRUE if we have limm. */
64 bfd_boolean limm_p;
65
66 /* LIMM value, if exists. */
67 unsigned limm;
68
69 /* Condition code, if exists. */
70 unsigned condition_code;
71
72 /* Writeback mode. */
73 unsigned writeback_mode;
74
75 /* Number of operands. */
76 unsigned operands_count;
77
78 struct arc_insn_operand operands[MAX_INSN_ARGS];
79 };
80
81 /* Globals variables. */
82
83 static const char * const regnames[64] =
84 {
85 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
86 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
87 "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
88 "r24", "r25", "gp", "fp", "sp", "ilink", "r30", "blink",
89
90 "r32", "r33", "r34", "r35", "r36", "r37", "r38", "r39",
91 "r40", "r41", "r42", "r43", "r44", "r45", "r46", "r47",
92 "r48", "r49", "r50", "r51", "r52", "r53", "r54", "r55",
93 "r56", "r57", "ACCL", "ACCH", "lp_count", "rezerved", "LIMM", "pcl"
94 };
95
96 static const char * const addrtypenames[ARC_NUM_ADDRTYPES] =
97 {
98 "bd", "jid", "lbd", "mbd", "sd", "sm", "xa", "xd",
99 "cd", "cbd", "cjid", "clbd", "cm", "csd", "cxa", "cxd"
100 };
101
102 static int addrtypenames_max = ARC_NUM_ADDRTYPES - 1;
103
104 static const char * const addrtypeunknown = "unknown";
105
106 /* This structure keeps track which instruction class(es)
107 should be ignored durring disassembling. */
108
109 typedef struct skipclass
110 {
111 insn_class_t insn_class;
112 insn_subclass_t subclass;
113 struct skipclass *nxt;
114 } skipclass_t, *linkclass;
115
116 /* Intial classes of instructions to be consider first when
117 disassembling. */
118 static linkclass decodelist = NULL;
119
120 /* ISA mask value enforced via disassembler info options. ARC_OPCODE_NONE
121 value means that no CPU is enforced. */
122
123 static unsigned enforced_isa_mask = ARC_OPCODE_NONE;
124
125 /* True if we want to print using only hex numbers. */
126 static bfd_boolean print_hex = FALSE;
127
128 /* Macros section. */
129
130 #ifdef DEBUG
131 # define pr_debug(fmt, args...) fprintf (stderr, fmt, ##args)
132 #else
133 # define pr_debug(fmt, args...)
134 #endif
135
136 #define ARRANGE_ENDIAN(info, buf) \
137 (info->endian == BFD_ENDIAN_LITTLE ? bfd_getm32 (bfd_getl32 (buf)) \
138 : bfd_getb32 (buf))
139
140 #define BITS(word,s,e) (((word) << (sizeof (word) * 8 - 1 - e)) >> \
141 (s + (sizeof (word) * 8 - 1 - e)))
142 #define OPCODE_32BIT_INSN(word) (BITS ((word), 27, 31))
143
144 /* Functions implementation. */
145
146 /* Initialize private data. */
147 static bfd_boolean
148 init_arc_disasm_info (struct disassemble_info *info)
149 {
150 struct arc_disassemble_info *arc_infop
151 = calloc (sizeof (*arc_infop), 1);
152
153 if (arc_infop == NULL)
154 return FALSE;
155
156 info->private_data = arc_infop;
157 return TRUE;
158 }
159
160 /* Add a new element to the decode list. */
161
162 static void
163 add_to_decodelist (insn_class_t insn_class,
164 insn_subclass_t subclass)
165 {
166 linkclass t = (linkclass) xmalloc (sizeof (skipclass_t));
167
168 t->insn_class = insn_class;
169 t->subclass = subclass;
170 t->nxt = decodelist;
171 decodelist = t;
172 }
173
174 /* Return TRUE if we need to skip the opcode from being
175 disassembled. */
176
177 static bfd_boolean
178 skip_this_opcode (const struct arc_opcode *opcode)
179 {
180 linkclass t = decodelist;
181
182 /* Check opcode for major 0x06, return if it is not in. */
183 if (arc_opcode_len (opcode) == 4
184 && OPCODE_32BIT_INSN (opcode->opcode) != 0x06)
185 return FALSE;
186
187 /* or not a known truble class. */
188 switch (opcode->insn_class)
189 {
190 case FLOAT:
191 case DSP:
192 case ARITH:
193 break;
194 default:
195 return FALSE;
196 }
197
198 while (t != NULL)
199 {
200 if ((t->insn_class == opcode->insn_class)
201 && (t->subclass == opcode->subclass))
202 return FALSE;
203 t = t->nxt;
204 }
205
206 return TRUE;
207 }
208
209 static bfd_vma
210 bfd_getm32 (unsigned int data)
211 {
212 bfd_vma value = 0;
213
214 value = ((data & 0xff00) | (data & 0xff)) << 16;
215 value |= ((data & 0xff0000) | (data & 0xff000000)) >> 16;
216 return value;
217 }
218
219 static bfd_boolean
220 special_flag_p (const char *opname,
221 const char *flgname)
222 {
223 const struct arc_flag_special *flg_spec;
224 unsigned i, j, flgidx;
225
226 for (i = 0; i < arc_num_flag_special; i++)
227 {
228 flg_spec = &arc_flag_special_cases[i];
229
230 if (strcmp (opname, flg_spec->name))
231 continue;
232
233 /* Found potential special case instruction. */
234 for (j=0;; ++j)
235 {
236 flgidx = flg_spec->flags[j];
237 if (flgidx == 0)
238 break; /* End of the array. */
239
240 if (strcmp (flgname, arc_flag_operands[flgidx].name) == 0)
241 return TRUE;
242 }
243 }
244 return FALSE;
245 }
246
247 /* Find opcode from ARC_TABLE given the instruction described by INSN and
248 INSNLEN. The ISA_MASK restricts the possible matches in ARC_TABLE. */
249
250 static const struct arc_opcode *
251 find_format_from_table (struct disassemble_info *info,
252 const struct arc_opcode *arc_table,
253 unsigned long long insn,
254 unsigned int insn_len,
255 unsigned isa_mask,
256 bfd_boolean *has_limm,
257 bfd_boolean overlaps)
258 {
259 unsigned int i = 0;
260 const struct arc_opcode *opcode = NULL;
261 const struct arc_opcode *t_op = NULL;
262 const unsigned char *opidx;
263 const unsigned char *flgidx;
264 bfd_boolean warn_p = FALSE;
265
266 do
267 {
268 bfd_boolean invalid = FALSE;
269
270 opcode = &arc_table[i++];
271
272 if (!(opcode->cpu & isa_mask))
273 continue;
274
275 if (arc_opcode_len (opcode) != (int) insn_len)
276 continue;
277
278 if ((insn & opcode->mask) != opcode->opcode)
279 continue;
280
281 *has_limm = FALSE;
282
283 /* Possible candidate, check the operands. */
284 for (opidx = opcode->operands; *opidx; opidx++)
285 {
286 int value, limmind;
287 const struct arc_operand *operand = &arc_operands[*opidx];
288
289 if (operand->flags & ARC_OPERAND_FAKE)
290 continue;
291
292 if (operand->extract)
293 value = (*operand->extract) (insn, &invalid);
294 else
295 value = (insn >> operand->shift) & ((1 << operand->bits) - 1);
296
297 /* Check for LIMM indicator. If it is there, then make sure
298 we pick the right format. */
299 limmind = (isa_mask & ARC_OPCODE_ARCV2) ? 0x1E : 0x3E;
300 if (operand->flags & ARC_OPERAND_IR
301 && !(operand->flags & ARC_OPERAND_LIMM))
302 {
303 if ((value == 0x3E && insn_len == 4)
304 || (value == limmind && insn_len == 2))
305 {
306 invalid = TRUE;
307 break;
308 }
309 }
310
311 if (operand->flags & ARC_OPERAND_LIMM
312 && !(operand->flags & ARC_OPERAND_DUPLICATE))
313 *has_limm = TRUE;
314 }
315
316 /* Check the flags. */
317 for (flgidx = opcode->flags; *flgidx; flgidx++)
318 {
319 /* Get a valid flag class. */
320 const struct arc_flag_class *cl_flags = &arc_flag_classes[*flgidx];
321 const unsigned *flgopridx;
322 int foundA = 0, foundB = 0;
323 unsigned int value;
324
325 /* Check first the extensions. */
326 if (cl_flags->flag_class & F_CLASS_EXTEND)
327 {
328 value = (insn & 0x1F);
329 if (arcExtMap_condCodeName (value))
330 continue;
331 }
332
333 /* Check for the implicit flags. */
334 if (cl_flags->flag_class & F_CLASS_IMPLICIT)
335 continue;
336
337 for (flgopridx = cl_flags->flags; *flgopridx; ++flgopridx)
338 {
339 const struct arc_flag_operand *flg_operand =
340 &arc_flag_operands[*flgopridx];
341
342 value = (insn >> flg_operand->shift)
343 & ((1 << flg_operand->bits) - 1);
344 if (value == flg_operand->code)
345 foundA = 1;
346 if (value)
347 foundB = 1;
348 }
349
350 if (!foundA && foundB)
351 {
352 invalid = TRUE;
353 break;
354 }
355 }
356
357 if (invalid)
358 continue;
359
360 if (insn_len == 4
361 && overlaps)
362 {
363 warn_p = TRUE;
364 t_op = opcode;
365 if (skip_this_opcode (opcode))
366 continue;
367 }
368
369 /* The instruction is valid. */
370 return opcode;
371 }
372 while (opcode->mask);
373
374 if (warn_p)
375 {
376 info->fprintf_func (info->stream,
377 _("\nWarning: disassembly may be wrong due to "
378 "guessed opcode class choice.\n"
379 "Use -M<class[,class]> to select the correct "
380 "opcode class(es).\n\t\t\t\t"));
381 return t_op;
382 }
383
384 return NULL;
385 }
386
387 /* Find opcode for INSN, trying various different sources. The instruction
388 length in INSN_LEN will be updated if the instruction requires a LIMM
389 extension.
390
391 A pointer to the opcode is placed into OPCODE_RESULT, and ITER is
392 initialised, ready to iterate over the operands of the found opcode. If
393 the found opcode requires a LIMM then the LIMM value will be loaded into a
394 field of ITER.
395
396 This function returns TRUE in almost all cases, FALSE is reserved to
397 indicate an error (failing to find an opcode is not an error) a returned
398 result of FALSE would indicate that the disassembler can't continue.
399
400 If no matching opcode is found then the returned result will be TRUE, the
401 value placed into OPCODE_RESULT will be NULL, ITER will be undefined, and
402 INSN_LEN will be unchanged.
403
404 If a matching opcode is found, then the returned result will be TRUE, the
405 opcode pointer is placed into OPCODE_RESULT, INSN_LEN will be increased by
406 4 if the instruction requires a LIMM, and the LIMM value will have been
407 loaded into a field of ITER. Finally, ITER will have been initialised so
408 that calls to OPERAND_ITERATOR_NEXT will iterate over the opcode's
409 operands. */
410
411 static bfd_boolean
412 find_format (bfd_vma memaddr,
413 unsigned long long insn,
414 unsigned int * insn_len,
415 unsigned isa_mask,
416 struct disassemble_info * info,
417 const struct arc_opcode ** opcode_result,
418 struct arc_operand_iterator * iter)
419 {
420 const struct arc_opcode *opcode = NULL;
421 bfd_boolean needs_limm;
422 const extInstruction_t *einsn, *i;
423 unsigned limm = 0;
424 struct arc_disassemble_info *arc_infop = info->private_data;
425
426 /* First, try the extension instructions. */
427 if (*insn_len == 4)
428 {
429 einsn = arcExtMap_insn (OPCODE_32BIT_INSN (insn), insn);
430 for (i = einsn; (i != NULL) && (opcode == NULL); i = i->next)
431 {
432 const char *errmsg = NULL;
433
434 opcode = arcExtMap_genOpcode (i, isa_mask, &errmsg);
435 if (opcode == NULL)
436 {
437 (*info->fprintf_func) (info->stream, "\
438 An error occured while generating the extension instruction operations");
439 *opcode_result = NULL;
440 return FALSE;
441 }
442
443 opcode = find_format_from_table (info, opcode, insn, *insn_len,
444 isa_mask, &needs_limm, FALSE);
445 }
446 }
447
448 /* Then, try finding the first match in the opcode table. */
449 if (opcode == NULL)
450 opcode = find_format_from_table (info, arc_opcodes, insn, *insn_len,
451 isa_mask, &needs_limm, TRUE);
452
453 if (needs_limm && opcode != NULL)
454 {
455 bfd_byte buffer[4];
456 int status;
457
458 status = (*info->read_memory_func) (memaddr + *insn_len, buffer,
459 4, info);
460 if (status != 0)
461 {
462 opcode = NULL;
463 }
464 else
465 {
466 limm = ARRANGE_ENDIAN (info, buffer);
467 *insn_len += 4;
468 }
469 }
470
471 if (opcode != NULL)
472 {
473 iter->insn = insn;
474 iter->limm = limm;
475 iter->opcode = opcode;
476 iter->opidx = opcode->operands;
477 }
478
479 *opcode_result = opcode;
480
481 /* Update private data. */
482 arc_infop->opcode = opcode;
483 arc_infop->limm = (needs_limm) ? limm : 0;
484 arc_infop->limm_p = needs_limm;
485
486 return TRUE;
487 }
488
489 static void
490 print_flags (const struct arc_opcode *opcode,
491 unsigned long long *insn,
492 struct disassemble_info *info)
493 {
494 const unsigned char *flgidx;
495 unsigned int value;
496 struct arc_disassemble_info *arc_infop = info->private_data;
497
498 /* Now extract and print the flags. */
499 for (flgidx = opcode->flags; *flgidx; flgidx++)
500 {
501 /* Get a valid flag class. */
502 const struct arc_flag_class *cl_flags = &arc_flag_classes[*flgidx];
503 const unsigned *flgopridx;
504
505 /* Check first the extensions. */
506 if (cl_flags->flag_class & F_CLASS_EXTEND)
507 {
508 const char *name;
509 value = (insn[0] & 0x1F);
510
511 name = arcExtMap_condCodeName (value);
512 if (name)
513 {
514 (*info->fprintf_func) (info->stream, ".%s", name);
515 continue;
516 }
517 }
518
519 for (flgopridx = cl_flags->flags; *flgopridx; ++flgopridx)
520 {
521 const struct arc_flag_operand *flg_operand =
522 &arc_flag_operands[*flgopridx];
523
524 /* Implicit flags are only used for the insn decoder. */
525 if (cl_flags->flag_class & F_CLASS_IMPLICIT)
526 {
527 if (cl_flags->flag_class & F_CLASS_COND)
528 arc_infop->condition_code = flg_operand->code;
529 else if (cl_flags->flag_class & F_CLASS_WB)
530 arc_infop->writeback_mode = flg_operand->code;
531 else if (cl_flags->flag_class & F_CLASS_ZZ)
532 info->data_size = flg_operand->code;
533 continue;
534 }
535
536 if (!flg_operand->favail)
537 continue;
538
539 value = (insn[0] >> flg_operand->shift)
540 & ((1 << flg_operand->bits) - 1);
541 if (value == flg_operand->code)
542 {
543 /* FIXME!: print correctly nt/t flag. */
544 if (!special_flag_p (opcode->name, flg_operand->name))
545 (*info->fprintf_func) (info->stream, ".");
546 else if (info->insn_type == dis_dref)
547 {
548 switch (flg_operand->name[0])
549 {
550 case 'b':
551 info->data_size = 1;
552 break;
553 case 'h':
554 case 'w':
555 info->data_size = 2;
556 break;
557 default:
558 info->data_size = 4;
559 break;
560 }
561 }
562 if (flg_operand->name[0] == 'd'
563 && flg_operand->name[1] == 0)
564 info->branch_delay_insns = 1;
565
566 /* Check if it is a conditional flag. */
567 if (cl_flags->flag_class & F_CLASS_COND)
568 {
569 if (info->insn_type == dis_jsr)
570 info->insn_type = dis_condjsr;
571 else if (info->insn_type == dis_branch)
572 info->insn_type = dis_condbranch;
573 arc_infop->condition_code = flg_operand->code;
574 }
575
576 /* Check for the write back modes. */
577 if (cl_flags->flag_class & F_CLASS_WB)
578 arc_infop->writeback_mode = flg_operand->code;
579
580 (*info->fprintf_func) (info->stream, "%s", flg_operand->name);
581 }
582 }
583 }
584 }
585
586 static const char *
587 get_auxreg (const struct arc_opcode *opcode,
588 int value,
589 unsigned isa_mask)
590 {
591 const char *name;
592 unsigned int i;
593 const struct arc_aux_reg *auxr = &arc_aux_regs[0];
594
595 if (opcode->insn_class != AUXREG)
596 return NULL;
597
598 name = arcExtMap_auxRegName (value);
599 if (name)
600 return name;
601
602 for (i = 0; i < arc_num_aux_regs; i++, auxr++)
603 {
604 if (!(auxr->cpu & isa_mask))
605 continue;
606
607 if (auxr->subclass != NONE)
608 return NULL;
609
610 if (auxr->address == value)
611 return auxr->name;
612 }
613 return NULL;
614 }
615
616 /* Convert a value representing an address type to a string used to refer to
617 the address type in assembly code. */
618
619 static const char *
620 get_addrtype (int value)
621 {
622 if (value < 0 || value > addrtypenames_max)
623 return addrtypeunknown;
624
625 return addrtypenames[value];
626 }
627
628 /* Calculate the instruction length for an instruction starting with MSB
629 and LSB, the most and least significant byte. The ISA_MASK is used to
630 filter the instructions considered to only those that are part of the
631 current architecture.
632
633 The instruction lengths are calculated from the ARC_OPCODE table, and
634 cached for later use. */
635
636 static unsigned int
637 arc_insn_length (bfd_byte msb, bfd_byte lsb, struct disassemble_info *info)
638 {
639 bfd_byte major_opcode = msb >> 3;
640
641 switch (info->mach)
642 {
643 case bfd_mach_arc_arc700:
644 /* The nps400 extension set requires this special casing of the
645 instruction length calculation. Right now this is not causing any
646 problems as none of the known extensions overlap in opcode space,
647 but, if they ever do then we might need to start carrying
648 information around in the elf about which extensions are in use. */
649 if (major_opcode == 0xb)
650 {
651 bfd_byte minor_opcode = lsb & 0x1f;
652
653 if (minor_opcode < 4)
654 return 6;
655 else if (minor_opcode == 0x10 || minor_opcode == 0x11)
656 return 8;
657 }
658 if (major_opcode == 0xa)
659 {
660 return 8;
661 }
662 /* Fall through. */
663 case bfd_mach_arc_arc600:
664 return (major_opcode > 0xb) ? 2 : 4;
665 break;
666
667 case bfd_mach_arc_arcv2:
668 return (major_opcode > 0x7) ? 2 : 4;
669 break;
670
671 default:
672 abort ();
673 }
674 }
675
676 /* Extract and return the value of OPERAND from the instruction whose value
677 is held in the array INSN. */
678
679 static int
680 extract_operand_value (const struct arc_operand *operand,
681 unsigned long long insn,
682 unsigned limm)
683 {
684 int value;
685
686 /* Read the limm operand, if required. */
687 if (operand->flags & ARC_OPERAND_LIMM)
688 /* The second part of the instruction value will have been loaded as
689 part of the find_format call made earlier. */
690 value = limm;
691 else
692 {
693 if (operand->extract)
694 value = (*operand->extract) (insn, (int *) NULL);
695 else
696 {
697 if (operand->flags & ARC_OPERAND_ALIGNED32)
698 {
699 value = (insn >> operand->shift)
700 & ((1 << (operand->bits - 2)) - 1);
701 value = value << 2;
702 }
703 else
704 {
705 value = (insn >> operand->shift) & ((1 << operand->bits) - 1);
706 }
707 if (operand->flags & ARC_OPERAND_SIGNED)
708 {
709 int signbit = 1 << (operand->bits - 1);
710 value = (value ^ signbit) - signbit;
711 }
712 }
713 }
714
715 return value;
716 }
717
718 /* Find the next operand, and the operands value from ITER. Return TRUE if
719 there is another operand, otherwise return FALSE. If there is an
720 operand returned then the operand is placed into OPERAND, and the value
721 into VALUE. If there is no operand returned then OPERAND and VALUE are
722 unchanged. */
723
724 static bfd_boolean
725 operand_iterator_next (struct arc_operand_iterator *iter,
726 const struct arc_operand **operand,
727 int *value)
728 {
729 if (*iter->opidx == 0)
730 {
731 *operand = NULL;
732 return FALSE;
733 }
734
735 *operand = &arc_operands[*iter->opidx];
736 *value = extract_operand_value (*operand, iter->insn, iter->limm);
737 iter->opidx++;
738
739 return TRUE;
740 }
741
742 /* Helper for parsing the options. */
743
744 static void
745 parse_option (const char *option)
746 {
747 if (disassembler_options_cmp (option, "dsp") == 0)
748 add_to_decodelist (DSP, NONE);
749
750 else if (disassembler_options_cmp (option, "spfp") == 0)
751 add_to_decodelist (FLOAT, SPX);
752
753 else if (disassembler_options_cmp (option, "dpfp") == 0)
754 add_to_decodelist (FLOAT, DPX);
755
756 else if (disassembler_options_cmp (option, "quarkse_em") == 0)
757 {
758 add_to_decodelist (FLOAT, DPX);
759 add_to_decodelist (FLOAT, SPX);
760 add_to_decodelist (FLOAT, QUARKSE1);
761 add_to_decodelist (FLOAT, QUARKSE2);
762 }
763
764 else if (disassembler_options_cmp (option, "fpuda") == 0)
765 add_to_decodelist (FLOAT, DPA);
766
767 else if (disassembler_options_cmp (option, "fpus") == 0)
768 {
769 add_to_decodelist (FLOAT, SP);
770 add_to_decodelist (FLOAT, CVT);
771 }
772
773 else if (disassembler_options_cmp (option, "fpud") == 0)
774 {
775 add_to_decodelist (FLOAT, DP);
776 add_to_decodelist (FLOAT, CVT);
777 }
778 else if (CONST_STRNEQ (option, "hex"))
779 print_hex = TRUE;
780 else
781 fprintf (stderr, _("Unrecognised disassembler option: %s\n"), option);
782 }
783
784 #define ARC_CPU_TYPE_A6xx(NAME,EXTRA) \
785 { #NAME, ARC_OPCODE_ARC600, "ARC600" }
786 #define ARC_CPU_TYPE_A7xx(NAME,EXTRA) \
787 { #NAME, ARC_OPCODE_ARC700, "ARC700" }
788 #define ARC_CPU_TYPE_AV2EM(NAME,EXTRA) \
789 { #NAME, ARC_OPCODE_ARCv2EM, "ARC EM" }
790 #define ARC_CPU_TYPE_AV2HS(NAME,EXTRA) \
791 { #NAME, ARC_OPCODE_ARCv2HS, "ARC HS" }
792 #define ARC_CPU_TYPE_NONE \
793 { 0, 0, 0 }
794
795 /* A table of CPU names and opcode sets. */
796 static const struct cpu_type
797 {
798 const char *name;
799 unsigned flags;
800 const char *isa;
801 }
802 cpu_types[] =
803 {
804 #include "elf/arc-cpu.def"
805 };
806
807 /* Helper for parsing the CPU options. Accept any of the ARC architectures
808 values. OPTION should be a value passed to cpu=. */
809
810 static unsigned
811 parse_cpu_option (const char *option)
812 {
813 int i;
814
815 for (i = 0; cpu_types[i].name; ++i)
816 {
817 if (!disassembler_options_cmp (cpu_types[i].name, option))
818 {
819 return cpu_types[i].flags;
820 }
821 }
822
823 fprintf (stderr, _("Unrecognised disassembler CPU option: %s\n"), option);
824 return ARC_OPCODE_NONE;
825 }
826
827 /* Go over the options list and parse it. */
828
829 static void
830 parse_disassembler_options (const char *options)
831 {
832 const char *option;
833
834 if (options == NULL)
835 return;
836
837 /* Disassembler might be reused for difference CPU's, and cpu option set for
838 the first one shouldn't be applied to second (which might not have
839 explicit cpu in its options. Therefore it is required to reset enforced
840 CPU when new options are being parsed. */
841 enforced_isa_mask = ARC_OPCODE_NONE;
842
843 FOR_EACH_DISASSEMBLER_OPTION (option, options)
844 {
845 /* A CPU option? Cannot use STRING_COMMA_LEN because strncmp is also a
846 preprocessor macro. */
847 if (strncmp (option, "cpu=", 4) == 0)
848 /* Strip leading `cpu=`. */
849 enforced_isa_mask = parse_cpu_option (option + 4);
850 else
851 parse_option (option);
852 }
853 }
854
855 /* Return the instruction type for an instruction described by OPCODE. */
856
857 static enum dis_insn_type
858 arc_opcode_to_insn_type (const struct arc_opcode *opcode)
859 {
860 enum dis_insn_type insn_type;
861
862 switch (opcode->insn_class)
863 {
864 case BRANCH:
865 case BBIT0:
866 case BBIT1:
867 case BI:
868 case BIH:
869 case BRCC:
870 case EI:
871 case JLI:
872 case JUMP:
873 case LOOP:
874 if (!strncmp (opcode->name, "bl", 2)
875 || !strncmp (opcode->name, "jl", 2))
876 {
877 if (opcode->subclass == COND)
878 insn_type = dis_condjsr;
879 else
880 insn_type = dis_jsr;
881 }
882 else
883 {
884 if (opcode->subclass == COND)
885 insn_type = dis_condbranch;
886 else
887 insn_type = dis_branch;
888 }
889 break;
890 case LOAD:
891 case STORE:
892 case MEMORY:
893 case ENTER:
894 case PUSH:
895 case POP:
896 insn_type = dis_dref;
897 break;
898 case LEAVE:
899 insn_type = dis_branch;
900 break;
901 default:
902 insn_type = dis_nonbranch;
903 break;
904 }
905
906 return insn_type;
907 }
908
909 /* Disassemble ARC instructions. */
910
911 static int
912 print_insn_arc (bfd_vma memaddr,
913 struct disassemble_info *info)
914 {
915 bfd_byte buffer[8];
916 unsigned int highbyte, lowbyte;
917 int status;
918 unsigned int insn_len;
919 unsigned long long insn = 0;
920 unsigned isa_mask = ARC_OPCODE_NONE;
921 const struct arc_opcode *opcode;
922 bfd_boolean need_comma;
923 bfd_boolean open_braket;
924 int size;
925 const struct arc_operand *operand;
926 int value;
927 struct arc_operand_iterator iter;
928 struct arc_disassemble_info *arc_infop;
929
930 if (info->disassembler_options)
931 {
932 parse_disassembler_options (info->disassembler_options);
933
934 /* Avoid repeated parsing of the options. */
935 info->disassembler_options = NULL;
936 }
937
938 if (info->private_data == NULL && !init_arc_disasm_info (info))
939 return -1;
940
941 memset (&iter, 0, sizeof (iter));
942 highbyte = ((info->endian == BFD_ENDIAN_LITTLE) ? 1 : 0);
943 lowbyte = ((info->endian == BFD_ENDIAN_LITTLE) ? 0 : 1);
944
945 /* Figure out CPU type, unless it was enforced via disassembler options. */
946 if (enforced_isa_mask == ARC_OPCODE_NONE)
947 {
948 Elf_Internal_Ehdr *header = NULL;
949
950 if (info->section && info->section->owner)
951 header = elf_elfheader (info->section->owner);
952
953 switch (info->mach)
954 {
955 case bfd_mach_arc_arc700:
956 isa_mask = ARC_OPCODE_ARC700;
957 break;
958
959 case bfd_mach_arc_arc600:
960 isa_mask = ARC_OPCODE_ARC600;
961 break;
962
963 case bfd_mach_arc_arcv2:
964 default:
965 isa_mask = ARC_OPCODE_ARCv2EM;
966 /* TODO: Perhaps remove definition of header since it is only used at
967 this location. */
968 if (header != NULL
969 && (header->e_flags & EF_ARC_MACH_MSK) == EF_ARC_CPU_ARCV2HS)
970 isa_mask = ARC_OPCODE_ARCv2HS;
971 break;
972 }
973 }
974 else
975 isa_mask = enforced_isa_mask;
976
977 if (isa_mask == ARC_OPCODE_ARCv2HS)
978 {
979 /* FPU instructions are not extensions for HS. */
980 add_to_decodelist (FLOAT, SP);
981 add_to_decodelist (FLOAT, DP);
982 add_to_decodelist (FLOAT, CVT);
983 }
984
985 /* This variable may be set by the instruction decoder. It suggests
986 the number of bytes objdump should display on a single line. If
987 the instruction decoder sets this, it should always set it to
988 the same value in order to get reasonable looking output. */
989
990 info->bytes_per_line = 8;
991
992 /* In the next lines, we set two info variables control the way
993 objdump displays the raw data. For example, if bytes_per_line is
994 8 and bytes_per_chunk is 4, the output will look like this:
995 00: 00000000 00000000
996 with the chunks displayed according to "display_endian". */
997
998 if (info->section
999 && !(info->section->flags & SEC_CODE))
1000 {
1001 /* This is not a CODE section. */
1002 switch (info->section->size)
1003 {
1004 case 1:
1005 case 2:
1006 case 4:
1007 size = info->section->size;
1008 break;
1009 default:
1010 size = (info->section->size & 0x01) ? 1 : 4;
1011 break;
1012 }
1013 info->bytes_per_chunk = 1;
1014 info->display_endian = info->endian;
1015 }
1016 else
1017 {
1018 size = 2;
1019 info->bytes_per_chunk = 2;
1020 info->display_endian = info->endian;
1021 }
1022
1023 /* Read the insn into a host word. */
1024 status = (*info->read_memory_func) (memaddr, buffer, size, info);
1025 if (status != 0)
1026 {
1027 (*info->memory_error_func) (status, memaddr, info);
1028 return -1;
1029 }
1030
1031 if (info->section
1032 && !(info->section->flags & SEC_CODE))
1033 {
1034 /* Data section. */
1035 unsigned long data;
1036
1037 data = bfd_get_bits (buffer, size * 8,
1038 info->display_endian == BFD_ENDIAN_BIG);
1039 switch (size)
1040 {
1041 case 1:
1042 (*info->fprintf_func) (info->stream, ".byte\t0x%02lx", data);
1043 break;
1044 case 2:
1045 (*info->fprintf_func) (info->stream, ".short\t0x%04lx", data);
1046 break;
1047 case 4:
1048 (*info->fprintf_func) (info->stream, ".word\t0x%08lx", data);
1049 break;
1050 default:
1051 abort ();
1052 }
1053 return size;
1054 }
1055
1056 insn_len = arc_insn_length (buffer[highbyte], buffer[lowbyte], info);
1057 pr_debug ("instruction length = %d bytes\n", insn_len);
1058 arc_infop = info->private_data;
1059 arc_infop->insn_len = insn_len;
1060
1061 switch (insn_len)
1062 {
1063 case 2:
1064 insn = (buffer[highbyte] << 8) | buffer[lowbyte];
1065 break;
1066
1067 case 4:
1068 {
1069 /* This is a long instruction: Read the remaning 2 bytes. */
1070 status = (*info->read_memory_func) (memaddr + 2, &buffer[2], 2, info);
1071 if (status != 0)
1072 {
1073 (*info->memory_error_func) (status, memaddr + 2, info);
1074 return -1;
1075 }
1076 insn = (unsigned long long) ARRANGE_ENDIAN (info, buffer);
1077 }
1078 break;
1079
1080 case 6:
1081 {
1082 status = (*info->read_memory_func) (memaddr + 2, &buffer[2], 4, info);
1083 if (status != 0)
1084 {
1085 (*info->memory_error_func) (status, memaddr + 2, info);
1086 return -1;
1087 }
1088 insn = (unsigned long long) ARRANGE_ENDIAN (info, &buffer[2]);
1089 insn |= ((unsigned long long) buffer[highbyte] << 40)
1090 | ((unsigned long long) buffer[lowbyte] << 32);
1091 }
1092 break;
1093
1094 case 8:
1095 {
1096 status = (*info->read_memory_func) (memaddr + 2, &buffer[2], 6, info);
1097 if (status != 0)
1098 {
1099 (*info->memory_error_func) (status, memaddr + 2, info);
1100 return -1;
1101 }
1102 insn =
1103 ((((unsigned long long) ARRANGE_ENDIAN (info, buffer)) << 32)
1104 | ((unsigned long long) ARRANGE_ENDIAN (info, &buffer[4])));
1105 }
1106 break;
1107
1108 default:
1109 /* There is no instruction whose length is not 2, 4, 6, or 8. */
1110 abort ();
1111 }
1112
1113 pr_debug ("instruction value = %llx\n", insn);
1114
1115 /* Set some defaults for the insn info. */
1116 info->insn_info_valid = 1;
1117 info->branch_delay_insns = 0;
1118 info->data_size = 4;
1119 info->insn_type = dis_nonbranch;
1120 info->target = 0;
1121 info->target2 = 0;
1122
1123 /* FIXME to be moved in dissasemble_init_for_target. */
1124 info->disassembler_needs_relocs = TRUE;
1125
1126 /* Find the first match in the opcode table. */
1127 if (!find_format (memaddr, insn, &insn_len, isa_mask, info, &opcode, &iter))
1128 return -1;
1129
1130 if (!opcode)
1131 {
1132 switch (insn_len)
1133 {
1134 case 2:
1135 (*info->fprintf_func) (info->stream, ".long %#04llx",
1136 insn & 0xffff);
1137 break;
1138 case 4:
1139 (*info->fprintf_func) (info->stream, ".long %#08llx",
1140 insn & 0xffffffff);
1141 break;
1142 case 6:
1143 (*info->fprintf_func) (info->stream, ".long %#08llx",
1144 insn & 0xffffffff);
1145 (*info->fprintf_func) (info->stream, ".long %#04llx",
1146 (insn >> 32) & 0xffff);
1147 break;
1148 case 8:
1149 (*info->fprintf_func) (info->stream, ".long %#08llx",
1150 insn & 0xffffffff);
1151 (*info->fprintf_func) (info->stream, ".long %#08llx",
1152 insn >> 32);
1153 break;
1154 default:
1155 abort ();
1156 }
1157
1158 info->insn_type = dis_noninsn;
1159 return insn_len;
1160 }
1161
1162 /* Print the mnemonic. */
1163 (*info->fprintf_func) (info->stream, "%s", opcode->name);
1164
1165 /* Preselect the insn class. */
1166 info->insn_type = arc_opcode_to_insn_type (opcode);
1167
1168 pr_debug ("%s: 0x%08llx\n", opcode->name, opcode->opcode);
1169
1170 print_flags (opcode, &insn, info);
1171
1172 if (opcode->operands[0] != 0)
1173 (*info->fprintf_func) (info->stream, "\t");
1174
1175 need_comma = FALSE;
1176 open_braket = FALSE;
1177 arc_infop->operands_count = 0;
1178
1179 /* Now extract and print the operands. */
1180 operand = NULL;
1181 while (operand_iterator_next (&iter, &operand, &value))
1182 {
1183 if (open_braket && (operand->flags & ARC_OPERAND_BRAKET))
1184 {
1185 (*info->fprintf_func) (info->stream, "]");
1186 open_braket = FALSE;
1187 continue;
1188 }
1189
1190 /* Only take input from real operands. */
1191 if (ARC_OPERAND_IS_FAKE (operand))
1192 continue;
1193
1194 if ((operand->flags & ARC_OPERAND_IGNORE)
1195 && (operand->flags & ARC_OPERAND_IR)
1196 && value == -1)
1197 continue;
1198
1199 if (operand->flags & ARC_OPERAND_COLON)
1200 {
1201 (*info->fprintf_func) (info->stream, ":");
1202 continue;
1203 }
1204
1205 if (need_comma)
1206 (*info->fprintf_func) (info->stream, ",");
1207
1208 if (!open_braket && (operand->flags & ARC_OPERAND_BRAKET))
1209 {
1210 (*info->fprintf_func) (info->stream, "[");
1211 open_braket = TRUE;
1212 need_comma = FALSE;
1213 continue;
1214 }
1215
1216 need_comma = TRUE;
1217
1218 /* Print the operand as directed by the flags. */
1219 if (operand->flags & ARC_OPERAND_IR)
1220 {
1221 const char *rname;
1222
1223 assert (value >=0 && value < 64);
1224 rname = arcExtMap_coreRegName (value);
1225 if (!rname)
1226 rname = regnames[value];
1227 (*info->fprintf_func) (info->stream, "%s", rname);
1228 if (operand->flags & ARC_OPERAND_TRUNCATE)
1229 {
1230 rname = arcExtMap_coreRegName (value + 1);
1231 if (!rname)
1232 rname = regnames[value + 1];
1233 (*info->fprintf_func) (info->stream, "%s", rname);
1234 }
1235 }
1236 else if (operand->flags & ARC_OPERAND_LIMM)
1237 {
1238 const char *rname = get_auxreg (opcode, value, isa_mask);
1239
1240 if (rname && open_braket)
1241 (*info->fprintf_func) (info->stream, "%s", rname);
1242 else
1243 {
1244 (*info->fprintf_func) (info->stream, "%#x", value);
1245 if (info->insn_type == dis_branch
1246 || info->insn_type == dis_jsr)
1247 info->target = (bfd_vma) value;
1248 }
1249 }
1250 else if (operand->flags & ARC_OPERAND_PCREL)
1251 {
1252 /* PCL relative. */
1253 if (info->flags & INSN_HAS_RELOC)
1254 memaddr = 0;
1255 (*info->print_address_func) ((memaddr & ~3) + value, info);
1256
1257 info->target = (bfd_vma) (memaddr & ~3) + value;
1258 }
1259 else if (operand->flags & ARC_OPERAND_SIGNED)
1260 {
1261 const char *rname = get_auxreg (opcode, value, isa_mask);
1262 if (rname && open_braket)
1263 (*info->fprintf_func) (info->stream, "%s", rname);
1264 else
1265 {
1266 if (print_hex)
1267 (*info->fprintf_func) (info->stream, "%#x", value);
1268 else
1269 (*info->fprintf_func) (info->stream, "%d", value);
1270 }
1271 }
1272 else if (operand->flags & ARC_OPERAND_ADDRTYPE)
1273 {
1274 const char *addrtype = get_addrtype (value);
1275 (*info->fprintf_func) (info->stream, "%s", addrtype);
1276 /* A colon follow an address type. */
1277 need_comma = FALSE;
1278 }
1279 else
1280 {
1281 if (operand->flags & ARC_OPERAND_TRUNCATE
1282 && !(operand->flags & ARC_OPERAND_ALIGNED32)
1283 && !(operand->flags & ARC_OPERAND_ALIGNED16)
1284 && value >= 0 && value <= 14)
1285 {
1286 switch (value)
1287 {
1288 case 0:
1289 need_comma = FALSE;
1290 break;
1291 case 1:
1292 (*info->fprintf_func) (info->stream, "r13");
1293 break;
1294 default:
1295 (*info->fprintf_func) (info->stream, "r13-%s",
1296 regnames[13 + value - 1]);
1297 break;
1298 }
1299 }
1300 else
1301 {
1302 const char *rname = get_auxreg (opcode, value, isa_mask);
1303 if (rname && open_braket)
1304 (*info->fprintf_func) (info->stream, "%s", rname);
1305 else
1306 (*info->fprintf_func) (info->stream, "%#x", value);
1307 }
1308 }
1309
1310 if (operand->flags & ARC_OPERAND_LIMM)
1311 {
1312 arc_infop->operands[arc_infop->operands_count].kind
1313 = ARC_OPERAND_KIND_LIMM;
1314 /* It is not important to have exactly the LIMM indicator
1315 here. */
1316 arc_infop->operands[arc_infop->operands_count].value = 63;
1317 }
1318 else
1319 {
1320 arc_infop->operands[arc_infop->operands_count].value = value;
1321 arc_infop->operands[arc_infop->operands_count].kind
1322 = (operand->flags & ARC_OPERAND_IR
1323 ? ARC_OPERAND_KIND_REG
1324 : ARC_OPERAND_KIND_SHIMM);
1325 }
1326 arc_infop->operands_count ++;
1327 }
1328
1329 return insn_len;
1330 }
1331
1332
1333 disassembler_ftype
1334 arc_get_disassembler (bfd *abfd)
1335 {
1336 /* BFD my be absent, if opcodes is invoked from the debugger that
1337 has connected to remote target and doesn't have an ELF file. */
1338 if (abfd != NULL)
1339 {
1340 /* Read the extension insns and registers, if any. */
1341 build_ARC_extmap (abfd);
1342 #ifdef DEBUG
1343 dump_ARC_extmap ();
1344 #endif
1345 }
1346
1347 return print_insn_arc;
1348 }
1349
1350 void
1351 print_arc_disassembler_options (FILE *stream)
1352 {
1353 int i;
1354
1355 fprintf (stream, _("\n\
1356 The following ARC specific disassembler options are supported for use \n\
1357 with -M switch (multiple options should be separated by commas):\n"));
1358
1359 /* cpu=... options. */
1360 for (i = 0; cpu_types[i].name; ++i)
1361 {
1362 /* As of now all value CPU values are less than 16 characters. */
1363 fprintf (stream, " cpu=%-16s\tEnforce %s ISA.\n",
1364 cpu_types[i].name, cpu_types[i].isa);
1365 }
1366
1367 fprintf (stream, _("\
1368 dsp Recognize DSP instructions.\n"));
1369 fprintf (stream, _("\
1370 spfp Recognize FPX SP instructions.\n"));
1371 fprintf (stream, _("\
1372 dpfp Recognize FPX DP instructions.\n"));
1373 fprintf (stream, _("\
1374 quarkse_em Recognize FPU QuarkSE-EM instructions.\n"));
1375 fprintf (stream, _("\
1376 fpuda Recognize double assist FPU instructions.\n"));
1377 fprintf (stream, _("\
1378 fpus Recognize single precision FPU instructions.\n"));
1379 fprintf (stream, _("\
1380 fpud Recognize double precision FPU instructions.\n"));
1381 fprintf (stream, _("\
1382 hex Use only hexadecimal number to print immediates.\n"));
1383 }
1384
1385 void arc_insn_decode (bfd_vma addr,
1386 struct disassemble_info *info,
1387 disassembler_ftype disasm_func,
1388 struct arc_instruction *insn)
1389 {
1390 const struct arc_opcode *opcode;
1391 struct arc_disassemble_info *arc_infop;
1392
1393 /* Ensure that insn would be in the reset state. */
1394 memset (insn, 0, sizeof (struct arc_instruction));
1395
1396 /* There was an error when disassembling, for example memory read error. */
1397 if (disasm_func (addr, info) < 0)
1398 {
1399 insn->valid = FALSE;
1400 return;
1401 }
1402
1403 assert (info->private_data != NULL);
1404 arc_infop = info->private_data;
1405
1406 insn->length = arc_infop->insn_len;;
1407 insn->address = addr;
1408
1409 /* Quick exit if memory at this address is not an instruction. */
1410 if (info->insn_type == dis_noninsn)
1411 {
1412 insn->valid = FALSE;
1413 return;
1414 }
1415
1416 insn->valid = TRUE;
1417
1418 opcode = (const struct arc_opcode *) arc_infop->opcode;
1419 insn->insn_class = opcode->insn_class;
1420 insn->limm_value = arc_infop->limm;
1421 insn->limm_p = arc_infop->limm_p;
1422
1423 insn->is_control_flow = (info->insn_type == dis_branch
1424 || info->insn_type == dis_condbranch
1425 || info->insn_type == dis_jsr
1426 || info->insn_type == dis_condjsr);
1427
1428 insn->has_delay_slot = info->branch_delay_insns;
1429 insn->writeback_mode
1430 = (enum arc_ldst_writeback_mode) arc_infop->writeback_mode;
1431 insn->data_size_mode = info->data_size;
1432 insn->condition_code = arc_infop->condition_code;
1433 memcpy (insn->operands, arc_infop->operands,
1434 sizeof (struct arc_insn_operand) * MAX_INSN_ARGS);
1435 insn->operands_count = arc_infop->operands_count;
1436 }
1437
1438 /* Local variables:
1439 eval: (c-set-style "gnu")
1440 indent-tabs-mode: t
1441 End: */
This page took 0.061122 seconds and 5 git commands to generate.