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