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