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