Update year range in copyright notice of all files.
[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 /* 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 LOAD:
754 case STORE:
755 case MEMORY:
756 insn_type = dis_dref;
757 break;
758 default:
759 insn_type = dis_nonbranch;
760 break;
761 }
762
763 return insn_type;
764 }
765
766 /* Disassemble ARC instructions. */
767
768 static int
769 print_insn_arc (bfd_vma memaddr,
770 struct disassemble_info *info)
771 {
772 bfd_byte buffer[8];
773 unsigned int highbyte, lowbyte;
774 int status;
775 unsigned int insn_len;
776 unsigned long long insn = 0;
777 unsigned isa_mask;
778 const struct arc_opcode *opcode;
779 bfd_boolean need_comma;
780 bfd_boolean open_braket;
781 int size;
782 const struct arc_operand *operand;
783 int value;
784 struct arc_operand_iterator iter;
785 Elf_Internal_Ehdr *header = NULL;
786
787 if (info->disassembler_options)
788 {
789 parse_disassembler_options (info->disassembler_options);
790
791 /* Avoid repeated parsing of the options. */
792 info->disassembler_options = NULL;
793 }
794
795 memset (&iter, 0, sizeof (iter));
796 highbyte = ((info->endian == BFD_ENDIAN_LITTLE) ? 1 : 0);
797 lowbyte = ((info->endian == BFD_ENDIAN_LITTLE) ? 0 : 1);
798
799 if (info->section && info->section->owner)
800 header = elf_elfheader (info->section->owner);
801
802 switch (info->mach)
803 {
804 case bfd_mach_arc_arc700:
805 isa_mask = ARC_OPCODE_ARC700;
806 break;
807
808 case bfd_mach_arc_arc600:
809 isa_mask = ARC_OPCODE_ARC600;
810 break;
811
812 case bfd_mach_arc_arcv2:
813 default:
814 isa_mask = ARC_OPCODE_ARCv2EM;
815 /* TODO: Perhaps remove defitinion of header since it is only used at
816 this location. */
817 if (header != NULL
818 && (header->e_flags & EF_ARC_MACH_MSK) == EF_ARC_CPU_ARCV2HS)
819 {
820 isa_mask = ARC_OPCODE_ARCv2HS;
821 /* FPU instructions are not extensions for HS. */
822 add_to_decodelist (FLOAT, SP);
823 add_to_decodelist (FLOAT, DP);
824 add_to_decodelist (FLOAT, CVT);
825 }
826 break;
827 }
828
829 /* This variable may be set by the instruction decoder. It suggests
830 the number of bytes objdump should display on a single line. If
831 the instruction decoder sets this, it should always set it to
832 the same value in order to get reasonable looking output. */
833
834 info->bytes_per_line = 8;
835
836 /* In the next lines, we set two info variables control the way
837 objdump displays the raw data. For example, if bytes_per_line is
838 8 and bytes_per_chunk is 4, the output will look like this:
839 00: 00000000 00000000
840 with the chunks displayed according to "display_endian". */
841
842 if (info->section
843 && !(info->section->flags & SEC_CODE))
844 {
845 /* This is not a CODE section. */
846 switch (info->section->size)
847 {
848 case 1:
849 case 2:
850 case 4:
851 size = info->section->size;
852 break;
853 default:
854 size = (info->section->size & 0x01) ? 1 : 4;
855 break;
856 }
857 info->bytes_per_chunk = 1;
858 info->display_endian = info->endian;
859 }
860 else
861 {
862 size = 2;
863 info->bytes_per_chunk = 2;
864 info->display_endian = info->endian;
865 }
866
867 /* Read the insn into a host word. */
868 status = (*info->read_memory_func) (memaddr, buffer, size, info);
869 if (status != 0)
870 {
871 (*info->memory_error_func) (status, memaddr, info);
872 return -1;
873 }
874
875 if (info->section
876 && !(info->section->flags & SEC_CODE))
877 {
878 /* Data section. */
879 unsigned long data;
880
881 data = bfd_get_bits (buffer, size * 8,
882 info->display_endian == BFD_ENDIAN_BIG);
883 switch (size)
884 {
885 case 1:
886 (*info->fprintf_func) (info->stream, ".byte\t0x%02lx", data);
887 break;
888 case 2:
889 (*info->fprintf_func) (info->stream, ".short\t0x%04lx", data);
890 break;
891 case 4:
892 (*info->fprintf_func) (info->stream, ".word\t0x%08lx", data);
893 break;
894 default:
895 abort ();
896 }
897 return size;
898 }
899
900 insn_len = arc_insn_length (buffer[highbyte], buffer[lowbyte], info);
901 pr_debug ("instruction length = %d bytes\n", insn_len);
902
903 switch (insn_len)
904 {
905 case 2:
906 insn = (buffer[highbyte] << 8) | buffer[lowbyte];
907 break;
908
909 case 4:
910 {
911 /* This is a long instruction: Read the remaning 2 bytes. */
912 status = (*info->read_memory_func) (memaddr + 2, &buffer[2], 2, info);
913 if (status != 0)
914 {
915 (*info->memory_error_func) (status, memaddr + 2, info);
916 return -1;
917 }
918 insn = (unsigned long long) ARRANGE_ENDIAN (info, buffer);
919 }
920 break;
921
922 case 6:
923 {
924 status = (*info->read_memory_func) (memaddr + 2, &buffer[2], 4, info);
925 if (status != 0)
926 {
927 (*info->memory_error_func) (status, memaddr + 2, info);
928 return -1;
929 }
930 insn = (unsigned long long) ARRANGE_ENDIAN (info, &buffer[2]);
931 insn |= ((unsigned long long) buffer[highbyte] << 40)
932 | ((unsigned long long) buffer[lowbyte] << 32);
933 }
934 break;
935
936 case 8:
937 {
938 status = (*info->read_memory_func) (memaddr + 2, &buffer[2], 6, info);
939 if (status != 0)
940 {
941 (*info->memory_error_func) (status, memaddr + 2, info);
942 return -1;
943 }
944 insn =
945 ((((unsigned long long) ARRANGE_ENDIAN (info, buffer)) << 32)
946 | ((unsigned long long) ARRANGE_ENDIAN (info, &buffer[4])));
947 }
948 break;
949
950 default:
951 /* There is no instruction whose length is not 2, 4, 6, or 8. */
952 abort ();
953 }
954
955 pr_debug ("instruction value = %llx\n", insn);
956
957 /* Set some defaults for the insn info. */
958 info->insn_info_valid = 1;
959 info->branch_delay_insns = 0;
960 info->data_size = 0;
961 info->insn_type = dis_nonbranch;
962 info->target = 0;
963 info->target2 = 0;
964
965 /* FIXME to be moved in dissasemble_init_for_target. */
966 info->disassembler_needs_relocs = TRUE;
967
968 /* Find the first match in the opcode table. */
969 if (!find_format (memaddr, insn, &insn_len, isa_mask, info, &opcode, &iter))
970 return -1;
971
972 if (!opcode)
973 {
974 switch (insn_len)
975 {
976 case 2:
977 (*info->fprintf_func) (info->stream, ".long %#04llx",
978 insn & 0xffff);
979 break;
980 case 4:
981 (*info->fprintf_func) (info->stream, ".long %#08llx",
982 insn & 0xffffffff);
983 break;
984 case 6:
985 (*info->fprintf_func) (info->stream, ".long %#08llx",
986 insn & 0xffffffff);
987 (*info->fprintf_func) (info->stream, ".long %#04llx",
988 (insn >> 32) & 0xffff);
989 break;
990 case 8:
991 (*info->fprintf_func) (info->stream, ".long %#08llx",
992 insn & 0xffffffff);
993 (*info->fprintf_func) (info->stream, ".long %#08llx",
994 insn >> 32);
995 break;
996 default:
997 abort ();
998 }
999
1000 info->insn_type = dis_noninsn;
1001 return insn_len;
1002 }
1003
1004 /* Print the mnemonic. */
1005 (*info->fprintf_func) (info->stream, "%s", opcode->name);
1006
1007 /* Preselect the insn class. */
1008 info->insn_type = arc_opcode_to_insn_type (opcode);
1009
1010 pr_debug ("%s: 0x%08llx\n", opcode->name, opcode->opcode);
1011
1012 print_flags (opcode, &insn, info);
1013
1014 if (opcode->operands[0] != 0)
1015 (*info->fprintf_func) (info->stream, "\t");
1016
1017 need_comma = FALSE;
1018 open_braket = FALSE;
1019
1020 /* Now extract and print the operands. */
1021 operand = NULL;
1022 while (operand_iterator_next (&iter, &operand, &value))
1023 {
1024 if (open_braket && (operand->flags & ARC_OPERAND_BRAKET))
1025 {
1026 (*info->fprintf_func) (info->stream, "]");
1027 open_braket = FALSE;
1028 continue;
1029 }
1030
1031 /* Only take input from real operands. */
1032 if (ARC_OPERAND_IS_FAKE (operand))
1033 continue;
1034
1035 if ((operand->flags & ARC_OPERAND_IGNORE)
1036 && (operand->flags & ARC_OPERAND_IR)
1037 && value == -1)
1038 continue;
1039
1040 if (operand->flags & ARC_OPERAND_COLON)
1041 {
1042 (*info->fprintf_func) (info->stream, ":");
1043 continue;
1044 }
1045
1046 if (need_comma)
1047 (*info->fprintf_func) (info->stream, ",");
1048
1049 if (!open_braket && (operand->flags & ARC_OPERAND_BRAKET))
1050 {
1051 (*info->fprintf_func) (info->stream, "[");
1052 open_braket = TRUE;
1053 need_comma = FALSE;
1054 continue;
1055 }
1056
1057 need_comma = TRUE;
1058
1059 /* Print the operand as directed by the flags. */
1060 if (operand->flags & ARC_OPERAND_IR)
1061 {
1062 const char *rname;
1063
1064 assert (value >=0 && value < 64);
1065 rname = arcExtMap_coreRegName (value);
1066 if (!rname)
1067 rname = regnames[value];
1068 (*info->fprintf_func) (info->stream, "%s", rname);
1069 if (operand->flags & ARC_OPERAND_TRUNCATE)
1070 {
1071 rname = arcExtMap_coreRegName (value + 1);
1072 if (!rname)
1073 rname = regnames[value + 1];
1074 (*info->fprintf_func) (info->stream, "%s", rname);
1075 }
1076 }
1077 else if (operand->flags & ARC_OPERAND_LIMM)
1078 {
1079 const char *rname = get_auxreg (opcode, value, isa_mask);
1080
1081 if (rname && open_braket)
1082 (*info->fprintf_func) (info->stream, "%s", rname);
1083 else
1084 {
1085 (*info->fprintf_func) (info->stream, "%#x", value);
1086 if (info->insn_type == dis_branch
1087 || info->insn_type == dis_jsr)
1088 info->target = (bfd_vma) value;
1089 }
1090 }
1091 else if (operand->flags & ARC_OPERAND_PCREL)
1092 {
1093 /* PCL relative. */
1094 if (info->flags & INSN_HAS_RELOC)
1095 memaddr = 0;
1096 (*info->print_address_func) ((memaddr & ~3) + value, info);
1097
1098 info->target = (bfd_vma) (memaddr & ~3) + value;
1099 }
1100 else if (operand->flags & ARC_OPERAND_SIGNED)
1101 {
1102 const char *rname = get_auxreg (opcode, value, isa_mask);
1103 if (rname && open_braket)
1104 (*info->fprintf_func) (info->stream, "%s", rname);
1105 else
1106 (*info->fprintf_func) (info->stream, "%d", value);
1107 }
1108 else if (operand->flags & ARC_OPERAND_ADDRTYPE)
1109 {
1110 const char *addrtype = get_addrtype (value);
1111 (*info->fprintf_func) (info->stream, "%s", addrtype);
1112 /* A colon follow an address type. */
1113 need_comma = FALSE;
1114 }
1115 else
1116 {
1117 if (operand->flags & ARC_OPERAND_TRUNCATE
1118 && !(operand->flags & ARC_OPERAND_ALIGNED32)
1119 && !(operand->flags & ARC_OPERAND_ALIGNED16)
1120 && value > 0 && value <= 14)
1121 (*info->fprintf_func) (info->stream, "r13-%s",
1122 regnames[13 + value - 1]);
1123 else
1124 {
1125 const char *rname = get_auxreg (opcode, value, isa_mask);
1126 if (rname && open_braket)
1127 (*info->fprintf_func) (info->stream, "%s", rname);
1128 else
1129 (*info->fprintf_func) (info->stream, "%#x", value);
1130 }
1131 }
1132 }
1133
1134 return insn_len;
1135 }
1136
1137
1138 disassembler_ftype
1139 arc_get_disassembler (bfd *abfd)
1140 {
1141 /* BFD my be absent, if opcodes is invoked from the debugger that
1142 has connected to remote target and doesn't have an ELF file. */
1143 if (abfd != NULL)
1144 {
1145 /* Read the extension insns and registers, if any. */
1146 build_ARC_extmap (abfd);
1147 #ifdef DEBUG
1148 dump_ARC_extmap ();
1149 #endif
1150 }
1151
1152 return print_insn_arc;
1153 }
1154
1155 /* Disassemble ARC instructions. Used by debugger. */
1156
1157 struct arcDisState
1158 arcAnalyzeInstr (bfd_vma memaddr,
1159 struct disassemble_info *info)
1160 {
1161 struct arcDisState ret;
1162 memset (&ret, 0, sizeof (struct arcDisState));
1163
1164 ret.instructionLen = print_insn_arc (memaddr, info);
1165
1166 #if 0
1167 ret.words[0] = insn[0];
1168 ret.words[1] = insn[1];
1169 ret._this = &ret;
1170 ret.coreRegName = _coreRegName;
1171 ret.auxRegName = _auxRegName;
1172 ret.condCodeName = _condCodeName;
1173 ret.instName = _instName;
1174 #endif
1175
1176 return ret;
1177 }
1178
1179 void
1180 print_arc_disassembler_options (FILE *stream)
1181 {
1182 fprintf (stream, _("\n\
1183 The following ARC specific disassembler options are supported for use \n\
1184 with -M switch (multiple options should be separated by commas):\n"));
1185
1186 fprintf (stream, _("\
1187 dsp Recognize DSP instructions.\n"));
1188 fprintf (stream, _("\
1189 spfp Recognize FPX SP instructions.\n"));
1190 fprintf (stream, _("\
1191 dpfp Recognize FPX DP instructions.\n"));
1192 fprintf (stream, _("\
1193 quarkse_em Recognize FPU QuarkSE-EM instructions.\n"));
1194 fprintf (stream, _("\
1195 fpuda Recognize double assist FPU instructions.\n"));
1196 fprintf (stream, _("\
1197 fpus Recognize single precision FPU instructions.\n"));
1198 fprintf (stream, _("\
1199 fpud Recognize double precision FPU instructions.\n"));
1200 }
1201
1202
1203 /* Local variables:
1204 eval: (c-set-style "gnu")
1205 indent-tabs-mode: t
1206 End: */
This page took 0.077917 seconds and 5 git commands to generate.