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