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