btrace: remove leftover comment
[deliverable/binutils-gdb.git] / opcodes / arc-dis.c
CommitLineData
252b5132 1/* Instruction printing code for the ARC.
6f2750fe 2 Copyright (C) 1994-2016 Free Software Foundation, Inc.
886a2506
NC
3
4 Contributed by Claudiu Zissulescu (claziss@synopsys.com)
252b5132 5
9b201bb5
NC
6 This file is part of libopcodes.
7
8 This library is free software; you can redistribute it and/or modify
0d2bcfaf 9 it under the terms of the GNU General Public License as published by
9b201bb5
NC
10 the Free Software Foundation; either version 3, or (at your option)
11 any later version.
252b5132 12
9b201bb5
NC
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.
252b5132 17
0d2bcfaf
NC
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
47b0e7ad
NC
20 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
21 MA 02110-1301, USA. */
252b5132 22
5eb3690e 23#include "sysdep.h"
886a2506
NC
24#include <stdio.h>
25#include <assert.h>
252b5132
RH
26#include "dis-asm.h"
27#include "opcode/arc.h"
37fd5ef3 28#include "elf/arc.h"
0d2bcfaf
NC
29#include "arc-dis.h"
30#include "arc-ext.h"
37fd5ef3
CZ
31#include "elf-bfd.h"
32#include "libiberty.h"
33#include "opintl.h"
252b5132 34
4eb6f892
AB
35/* Structure used to iterate over, and extract the values for, operands of
36 an opcode. */
37
38struct 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};
252b5132 72
886a2506 73/* Globals variables. */
82b829a7 74
886a2506 75static const char * const regnames[64] =
47b0e7ad 76{
886a2506
NC
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
db18dbab
GM
88static 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
94static int addrtypenames_max = ARC_NUM_ADDRTYPES - 1;
95
96static const char * const addrtypeunknown = "unknown";
97
37fd5ef3
CZ
98/* This structure keeps track which instruction class(es)
99 should be ignored durring disassembling. */
100
101typedef 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. */
110static linkclass decodelist = NULL;
111
886a2506
NC
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)))
279a96ca 126#define OPCODE(word) (BITS ((word), 27, 31))
252b5132 127
886a2506 128#define OPCODE_AC(word) (BITS ((word), 11, 15))
252b5132 129
886a2506 130/* Functions implementation. */
252b5132 131
37fd5ef3
CZ
132/* Return TRUE when two classes are not opcode conflicting. */
133
134static bfd_boolean
135is_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
149static void
150add_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
164static bfd_boolean
165skip_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;
db18dbab 188
37fd5ef3
CZ
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\
204Warning: 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
886a2506
NC
214static bfd_vma
215bfd_getm32 (unsigned int data)
0d2bcfaf 216{
886a2506 217 bfd_vma value = 0;
0d2bcfaf 218
886a2506
NC
219 value = ((data & 0xff00) | (data & 0xff)) << 16;
220 value |= ((data & 0xff0000) | (data & 0xff000000)) >> 16;
221 return value;
0d2bcfaf
NC
222}
223
37fd5ef3 224static bfd_boolean
886a2506
NC
225special_flag_p (const char *opname,
226 const char *flgname)
0d2bcfaf 227{
886a2506 228 const struct arc_flag_special *flg_spec;
886a2506 229 unsigned i, j, flgidx;
0d2bcfaf 230
886a2506 231 for (i = 0; i < arc_num_flag_special; i++)
252b5132 232 {
886a2506 233 flg_spec = &arc_flag_special_cases[i];
279a96ca 234
24b368f8 235 if (strcmp (opname, flg_spec->name))
886a2506 236 continue;
279a96ca 237
886a2506
NC
238 /* Found potential special case instruction. */
239 for (j=0;; ++j)
0d2bcfaf 240 {
886a2506
NC
241 flgidx = flg_spec->flags[j];
242 if (flgidx == 0)
243 break; /* End of the array. */
0d2bcfaf 244
886a2506 245 if (strcmp (flgname, arc_flag_operands[flgidx].name) == 0)
37fd5ef3 246 return TRUE;
252b5132 247 }
0d2bcfaf 248 }
37fd5ef3 249 return FALSE;
0d2bcfaf 250}
252b5132 251
4eb6f892
AB
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
b99747ae 255static const struct arc_opcode *
37fd5ef3
CZ
256find_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)
b99747ae
CZ
263{
264 unsigned int i = 0;
265 const struct arc_opcode *opcode = NULL;
266 const unsigned char *opidx;
267 const unsigned char *flgidx;
268
37fd5ef3
CZ
269 do
270 {
271 bfd_boolean invalid = FALSE;
b99747ae 272
37fd5ef3 273 opcode = &arc_table[i++];
b99747ae 274
37fd5ef3
CZ
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;
b99747ae 287
37fd5ef3
CZ
288 if ((insn[0] ^ opcode->opcode) & opcode->mask)
289 continue;
b99747ae 290
37fd5ef3
CZ
291 if (!(opcode->cpu & isa_mask))
292 continue;
b99747ae 293
37fd5ef3 294 *has_limm = FALSE;
4eb6f892 295
37fd5ef3
CZ
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];
b99747ae 301
37fd5ef3
CZ
302 if (operand->flags & ARC_OPERAND_FAKE)
303 continue;
b99747ae 304
37fd5ef3
CZ
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);
b99747ae
CZ
377
378 return NULL;
379}
380
4eb6f892
AB
381/* Find long instructions matching values in INSN array. */
382
383static const struct arc_long_opcode *
384find_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
469static bfd_boolean
37fd5ef3
CZ
470find_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)
4eb6f892 477{
37fd5ef3 478 const struct arc_opcode *opcode = NULL;
4eb6f892 479 bfd_boolean needs_limm;
f807f43d 480 const extInstruction_t *einsn, *i;
4eb6f892 481
37fd5ef3
CZ
482 /* First, try the extension instructions. */
483 einsn = arcExtMap_insn (OPCODE (insn[0]), insn[0]);
f807f43d 484 for (i = einsn; (i != NULL) && (opcode == NULL); i = i->next)
4eb6f892 485 {
37fd5ef3 486 const char *errmsg = NULL;
4eb6f892 487
f807f43d 488 opcode = arcExtMap_genOpcode (i, isa_mask, &errmsg);
37fd5ef3 489 if (opcode == NULL)
4eb6f892 490 {
37fd5ef3
CZ
491 (*info->fprintf_func) (info->stream, "\
492An error occured while generating the extension instruction operations");
493 *opcode_result = NULL;
494 return FALSE;
4eb6f892 495 }
37fd5ef3
CZ
496
497 opcode = find_format_from_table (info, opcode, insn, *insn_len,
498 isa_mask, &needs_limm, FALSE);
4eb6f892
AB
499 }
500
37fd5ef3
CZ
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
4eb6f892
AB
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
f36e33da
CZ
557static void
558print_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. */
c810e0b8 573 if (cl_flags->flag_class & F_CLASS_EXTEND)
f36e33da
CZ
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 }
d9eca1df
CZ
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
f36e33da
CZ
630 (*info->fprintf_func) (info->stream, "%s", flg_operand->name);
631 }
f36e33da
CZ
632 }
633 }
634}
635
636static const char *
637get_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
c810e0b8 645 if (opcode->insn_class != AUXREG)
f36e33da
CZ
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}
cb040366 665
db18dbab
GM
666/* Convert a value representing an address type to a string used to refer to
667 the address type in assembly code. */
668
669static const char *
670get_addrtype (int value)
671{
672 if (value < 0 || value > addrtypenames_max)
673 return addrtypeunknown;
674
675 return addrtypenames[value];
676}
677
cb040366
AB
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
686static unsigned int
4eb6f892 687arc_insn_length (bfd_byte msb, bfd_byte lsb, struct disassemble_info *info)
cb040366
AB
688{
689 bfd_byte major_opcode = msb >> 3;
690
691 switch (info->mach)
692 {
bdd582db
GM
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. */
4eb6f892
AB
699 if (major_opcode == 0xb)
700 {
701 bfd_byte minor_opcode = lsb & 0x1f;
702
703 if (minor_opcode < 4)
704 return 2;
705 }
1a0670f3 706 /* Fall through. */
cb040366
AB
707 case bfd_mach_arc_arc600:
708 return (major_opcode > 0xb) ? 2 : 4;
709 break;
710
711 case bfd_mach_arc_arcv2:
712 return (major_opcode > 0x7) ? 2 : 4;
713 break;
714
715 default:
716 abort ();
717 }
718}
719
4eb6f892
AB
720/* Extract and return the value of OPERAND from the instruction whose value
721 is held in the array INSN. */
722
723static int
724extract_operand_value (const struct arc_operand *operand, unsigned *insn)
725{
726 int value;
727
728 /* Read the limm operand, if required. */
729 if (operand->flags & ARC_OPERAND_LIMM)
730 /* The second part of the instruction value will have been loaded as
731 part of the find_format call made earlier. */
732 value = insn[1];
733 else
734 {
735 if (operand->extract)
736 value = (*operand->extract) (insn[0], (int *) NULL);
737 else
738 {
739 if (operand->flags & ARC_OPERAND_ALIGNED32)
740 {
741 value = (insn[0] >> operand->shift)
742 & ((1 << (operand->bits - 2)) - 1);
743 value = value << 2;
744 }
745 else
746 {
747 value = (insn[0] >> operand->shift) & ((1 << operand->bits) - 1);
748 }
749 if (operand->flags & ARC_OPERAND_SIGNED)
750 {
751 int signbit = 1 << (operand->bits - 1);
752 value = (value ^ signbit) - signbit;
753 }
754 }
755 }
756
757 return value;
758}
759
760/* Find the next operand, and the operands value from ITER. Return TRUE if
761 there is another operand, otherwise return FALSE. If there is an
762 operand returned then the operand is placed into OPERAND, and the value
763 into VALUE. If there is no operand returned then OPERAND and VALUE are
764 unchanged. */
765
766static bfd_boolean
767operand_iterator_next (struct arc_operand_iterator *iter,
768 const struct arc_operand **operand,
769 int *value)
770{
771 if (iter->mode == OPERAND_ITERATOR_STANDARD)
772 {
773 if (*iter->state.standard.opidx == 0)
774 {
775 *operand = NULL;
776 return FALSE;
777 }
778
779 *operand = &arc_operands[*iter->state.standard.opidx];
780 *value = extract_operand_value (*operand, iter->insn);
781 iter->state.standard.opidx++;
782 }
783 else
784 {
785 const struct arc_operand *operand_base, *operand_limm;
786 int value_base, value_limm;
787
788 if (*iter->state.long_insn.opidx_limm == 0)
789 {
790 *operand = NULL;
791 return FALSE;
792 }
793
794 operand_base = &arc_operands[*iter->state.long_insn.opidx_base];
795 operand_limm = &arc_operands[*iter->state.long_insn.opidx_limm];
796
797 if (operand_base->flags & ARC_OPERAND_LIMM)
798 {
799 /* We've reached the end of the operand list. */
800 *operand = NULL;
801 return FALSE;
802 }
803
804 value_base = value_limm = 0;
805 if (!(operand_limm->flags & ARC_OPERAND_IGNORE))
806 {
807 /* This should never happen. If it does then the use of
808 extract_operand_value below will access memory beyond
809 the insn array. */
810 assert ((operand_limm->flags & ARC_OPERAND_LIMM) == 0);
811
812 *operand = operand_limm;
813 value_limm = extract_operand_value (*operand, &iter->insn[1]);
814 }
815
816 if (!(operand_base->flags & ARC_OPERAND_IGNORE))
817 {
818 *operand = operand_base;
819 value_base = extract_operand_value (*operand, iter->insn);
820 }
821
822 /* This is a bit of a fudge. There's no reason why simply ORing
823 together the two values is the right thing to do, however, for all
824 the cases we currently have, it is the right thing, so, for now,
825 I've put off solving the more complex problem. */
826 *value = value_base | value_limm;
827
828 iter->state.long_insn.opidx_base++;
829 iter->state.long_insn.opidx_limm++;
830 }
831 return TRUE;
832}
833
37fd5ef3
CZ
834/* Helper for parsing the options. */
835
836static void
837parse_option (char *option)
838{
839 if (CONST_STRNEQ (option, "dsp"))
840 add_to_decodelist (DSP, NONE);
841
842 else if (CONST_STRNEQ (option, "spfp"))
843 add_to_decodelist (FLOAT, SPX);
844
845 else if (CONST_STRNEQ (option, "dpfp"))
846 add_to_decodelist (FLOAT, DPX);
847
848 else if (CONST_STRNEQ (option, "quarkse_em"))
849 add_to_decodelist (FLOAT, QUARKSE);
850
851 else if (CONST_STRNEQ (option, "fpuda"))
852 add_to_decodelist (FLOAT, DPA);
853
854 else if (CONST_STRNEQ (option, "fpud"))
855 {
856 add_to_decodelist (FLOAT, SP);
857 add_to_decodelist (FLOAT, CVT);
858 }
859
860 else if (CONST_STRNEQ (option, "fpus"))
861 {
862 add_to_decodelist (FLOAT, DP);
863 add_to_decodelist (FLOAT, CVT);
864 }
865 else
866 fprintf (stderr, _("Unrecognised disassembler option: %s\n"), option);
867}
868
869/* Go over the options list and parse it. */
870
871static void
872parse_disassembler_options (char *options)
873{
874 if (options == NULL)
875 return;
876
877 while (*options)
878 {
879 /* Skip empty options. */
880 if (*options == ',')
881 {
882 ++ options;
883 continue;
884 }
885
886 parse_option (options);
887
888 while (*options != ',' && *options != '\0')
889 ++ options;
890 }
891}
892
886a2506 893/* Disassemble ARC instructions. */
0d2bcfaf 894
886a2506
NC
895static int
896print_insn_arc (bfd_vma memaddr,
897 struct disassemble_info *info)
0d2bcfaf 898{
886a2506
NC
899 bfd_byte buffer[4];
900 unsigned int lowbyte, highbyte;
901 int status;
4eb6f892 902 unsigned int insn_len;
3f94e60d
NC
903 unsigned insn[2] = { 0, 0 };
904 unsigned isa_mask;
886a2506 905 const struct arc_opcode *opcode;
886a2506
NC
906 bfd_boolean need_comma;
907 bfd_boolean open_braket;
24b368f8 908 int size;
4eb6f892
AB
909 const struct arc_operand *operand;
910 int value;
911 struct arc_operand_iterator iter;
37fd5ef3
CZ
912 Elf_Internal_Ehdr *header = NULL;
913
914 if (info->disassembler_options)
915 {
916 parse_disassembler_options (info->disassembler_options);
917
918 /* Avoid repeated parsing of the options. */
919 info->disassembler_options = NULL;
920 }
0d2bcfaf 921
4eb6f892 922 memset (&iter, 0, sizeof (iter));
886a2506
NC
923 lowbyte = ((info->endian == BFD_ENDIAN_LITTLE) ? 1 : 0);
924 highbyte = ((info->endian == BFD_ENDIAN_LITTLE) ? 0 : 1);
0d2bcfaf 925
37fd5ef3
CZ
926 if (info->section && info->section->owner)
927 header = elf_elfheader (info->section->owner);
928
886a2506
NC
929 switch (info->mach)
930 {
931 case bfd_mach_arc_arc700:
932 isa_mask = ARC_OPCODE_ARC700;
933 break;
0d2bcfaf 934
886a2506
NC
935 case bfd_mach_arc_arc600:
936 isa_mask = ARC_OPCODE_ARC600;
937 break;
0d2bcfaf 938
886a2506
NC
939 case bfd_mach_arc_arcv2:
940 default:
37fd5ef3 941 isa_mask = ARC_OPCODE_ARCv2EM;
7763838e
CM
942 /* TODO: Perhaps remove defitinion of header since it is only used at
943 this location. */
944 if (header != NULL
945 && (header->e_flags & EF_ARC_MACH_MSK) == EF_ARC_CPU_ARCV2HS)
37fd5ef3
CZ
946 {
947 isa_mask = ARC_OPCODE_ARCv2HS;
948 /* FPU instructions are not extensions for HS. */
949 add_to_decodelist (FLOAT, SP);
950 add_to_decodelist (FLOAT, DP);
951 add_to_decodelist (FLOAT, CVT);
952 }
886a2506 953 break;
0d2bcfaf
NC
954 }
955
24b368f8
CZ
956 /* This variable may be set by the instruction decoder. It suggests
957 the number of bytes objdump should display on a single line. If
958 the instruction decoder sets this, it should always set it to
959 the same value in order to get reasonable looking output. */
960
961 info->bytes_per_line = 8;
962
963 /* In the next lines, we set two info variables control the way
964 objdump displays the raw data. For example, if bytes_per_line is
965 8 and bytes_per_chunk is 4, the output will look like this:
966 00: 00000000 00000000
967 with the chunks displayed according to "display_endian". */
968
969 if (info->section
970 && !(info->section->flags & SEC_CODE))
971 {
972 /* This is not a CODE section. */
973 switch (info->section->size)
974 {
975 case 1:
976 case 2:
977 case 4:
978 size = info->section->size;
979 break;
980 default:
981 size = (info->section->size & 0x01) ? 1 : 4;
982 break;
983 }
984 info->bytes_per_chunk = 1;
985 info->display_endian = info->endian;
986 }
987 else
988 {
989 size = 2;
990 info->bytes_per_chunk = 2;
991 info->display_endian = info->endian;
992 }
993
886a2506 994 /* Read the insn into a host word. */
24b368f8 995 status = (*info->read_memory_func) (memaddr, buffer, size, info);
886a2506 996 if (status != 0)
0d2bcfaf 997 {
886a2506
NC
998 (*info->memory_error_func) (status, memaddr, info);
999 return -1;
0d2bcfaf
NC
1000 }
1001
886a2506
NC
1002 if (info->section
1003 && !(info->section->flags & SEC_CODE))
0d2bcfaf 1004 {
24b368f8
CZ
1005 /* Data section. */
1006 unsigned long data;
1007
1008 data = bfd_get_bits (buffer, size * 8,
1009 info->display_endian == BFD_ENDIAN_BIG);
1010 switch (size)
0d2bcfaf 1011 {
24b368f8
CZ
1012 case 1:
1013 (*info->fprintf_func) (info->stream, ".byte\t0x%02lx", data);
1014 break;
1015 case 2:
1016 (*info->fprintf_func) (info->stream, ".short\t0x%04lx", data);
1017 break;
1018 case 4:
1019 (*info->fprintf_func) (info->stream, ".word\t0x%08lx", data);
1020 break;
1021 default:
1022 abort ();
0d2bcfaf 1023 }
24b368f8 1024 return size;
886a2506 1025 }
279a96ca 1026
4eb6f892
AB
1027 insn_len = arc_insn_length (buffer[lowbyte], buffer[highbyte], info);
1028 pr_debug ("instruction length = %d bytes\n", insn_len);
37fd5ef3 1029
4eb6f892 1030 switch (insn_len)
886a2506 1031 {
cb040366 1032 case 2:
886a2506 1033 insn[0] = (buffer[lowbyte] << 8) | buffer[highbyte];
cb040366 1034 break;
886a2506 1035
cb040366
AB
1036 default:
1037 /* An unknown instruction is treated as being length 4. This is
1038 possibly not the best solution, but matches the behaviour that was
1039 in place before the table based instruction length look-up was
1040 introduced. */
1041 case 4:
886a2506
NC
1042 /* This is a long instruction: Read the remaning 2 bytes. */
1043 status = (*info->read_memory_func) (memaddr + 2, &buffer[2], 2, info);
1044 if (status != 0)
0d2bcfaf 1045 {
886a2506
NC
1046 (*info->memory_error_func) (status, memaddr + 2, info);
1047 return -1;
0d2bcfaf 1048 }
886a2506 1049 insn[0] = ARRANGE_ENDIAN (info, buffer);
cb040366 1050 break;
886a2506
NC
1051 }
1052
886a2506
NC
1053 /* Set some defaults for the insn info. */
1054 info->insn_info_valid = 1;
1055 info->branch_delay_insns = 0;
1056 info->data_size = 0;
1057 info->insn_type = dis_nonbranch;
1058 info->target = 0;
1059 info->target2 = 0;
1060
1061 /* FIXME to be moved in dissasemble_init_for_target. */
1062 info->disassembler_needs_relocs = TRUE;
1063
1064 /* Find the first match in the opcode table. */
4eb6f892
AB
1065 if (!find_format (memaddr, insn, &insn_len, isa_mask, info, &opcode, &iter))
1066 return -1;
886a2506 1067
b99747ae
CZ
1068 if (!opcode)
1069 {
4eb6f892
AB
1070 if (insn_len == 2)
1071 (*info->fprintf_func) (info->stream, ".long %#04x", insn[0]);
b99747ae 1072 else
4eb6f892 1073 (*info->fprintf_func) (info->stream, ".long %#08x", insn[0]);
886a2506 1074
4eb6f892
AB
1075 info->insn_type = dis_noninsn;
1076 return insn_len;
886a2506 1077 }
279a96ca 1078
886a2506
NC
1079 /* Print the mnemonic. */
1080 (*info->fprintf_func) (info->stream, "%s", opcode->name);
1081
1082 /* Preselect the insn class. */
c810e0b8 1083 switch (opcode->insn_class)
886a2506
NC
1084 {
1085 case BRANCH:
1086 case JUMP:
1087 if (!strncmp (opcode->name, "bl", 2)
1088 || !strncmp (opcode->name, "jl", 2))
d9eca1df
CZ
1089 {
1090 if (opcode->subclass == COND)
1091 info->insn_type = dis_condjsr;
1092 else
1093 info->insn_type = dis_jsr;
1094 }
279a96ca 1095 else
d9eca1df
CZ
1096 {
1097 if (opcode->subclass == COND)
1098 info->insn_type = dis_condbranch;
1099 else
1100 info->insn_type = dis_branch;
1101 }
886a2506
NC
1102 break;
1103 case MEMORY:
1104 info->insn_type = dis_dref; /* FIXME! DB indicates mov as memory! */
0d2bcfaf 1105 break;
0d2bcfaf 1106 default:
886a2506 1107 info->insn_type = dis_nonbranch;
0d2bcfaf
NC
1108 break;
1109 }
279a96ca 1110
886a2506 1111 pr_debug ("%s: 0x%08x\n", opcode->name, opcode->opcode);
279a96ca 1112
f36e33da 1113 print_flags (opcode, insn, info);
279a96ca 1114
886a2506
NC
1115 if (opcode->operands[0] != 0)
1116 (*info->fprintf_func) (info->stream, "\t");
279a96ca 1117
886a2506
NC
1118 need_comma = FALSE;
1119 open_braket = FALSE;
279a96ca 1120
886a2506 1121 /* Now extract and print the operands. */
4eb6f892
AB
1122 operand = NULL;
1123 while (operand_iterator_next (&iter, &operand, &value))
886a2506 1124 {
886a2506 1125 if (open_braket && (operand->flags & ARC_OPERAND_BRAKET))
0d2bcfaf 1126 {
886a2506
NC
1127 (*info->fprintf_func) (info->stream, "]");
1128 open_braket = FALSE;
1129 continue;
0d2bcfaf 1130 }
279a96ca 1131
886a2506 1132 /* Only take input from real operands. */
db18dbab 1133 if (ARC_OPERAND_IS_FAKE (operand))
886a2506 1134 continue;
279a96ca 1135
4eb6f892
AB
1136 if ((operand->flags & ARC_OPERAND_IGNORE)
1137 && (operand->flags & ARC_OPERAND_IR)
1138 && value == -1)
886a2506 1139 continue;
279a96ca 1140
db18dbab
GM
1141 if (operand->flags & ARC_OPERAND_COLON)
1142 {
1143 (*info->fprintf_func) (info->stream, ":");
1144 continue;
1145 }
1146
886a2506
NC
1147 if (need_comma)
1148 (*info->fprintf_func) (info->stream, ",");
279a96ca 1149
886a2506 1150 if (!open_braket && (operand->flags & ARC_OPERAND_BRAKET))
0d2bcfaf 1151 {
886a2506
NC
1152 (*info->fprintf_func) (info->stream, "[");
1153 open_braket = TRUE;
1154 need_comma = FALSE;
1155 continue;
0d2bcfaf 1156 }
886a2506 1157
db18dbab
GM
1158 need_comma = TRUE;
1159
886a2506
NC
1160 /* Print the operand as directed by the flags. */
1161 if (operand->flags & ARC_OPERAND_IR)
1162 {
f36e33da
CZ
1163 const char *rname;
1164
886a2506 1165 assert (value >=0 && value < 64);
f36e33da
CZ
1166 rname = arcExtMap_coreRegName (value);
1167 if (!rname)
1168 rname = regnames[value];
1169 (*info->fprintf_func) (info->stream, "%s", rname);
886a2506 1170 if (operand->flags & ARC_OPERAND_TRUNCATE)
f36e33da
CZ
1171 {
1172 rname = arcExtMap_coreRegName (value + 1);
1173 if (!rname)
1174 rname = regnames[value + 1];
1175 (*info->fprintf_func) (info->stream, "%s", rname);
1176 }
886a2506
NC
1177 }
1178 else if (operand->flags & ARC_OPERAND_LIMM)
1179 {
4eb6f892 1180 const char *rname = get_auxreg (opcode, value, isa_mask);
db18dbab 1181
f36e33da
CZ
1182 if (rname && open_braket)
1183 (*info->fprintf_func) (info->stream, "%s", rname);
1184 else
1185 {
4eb6f892 1186 (*info->fprintf_func) (info->stream, "%#x", value);
f36e33da
CZ
1187 if (info->insn_type == dis_branch
1188 || info->insn_type == dis_jsr)
4eb6f892 1189 info->target = (bfd_vma) value;
f36e33da 1190 }
886a2506
NC
1191 }
1192 else if (operand->flags & ARC_OPERAND_PCREL)
1193 {
1194 /* PCL relative. */
1195 if (info->flags & INSN_HAS_RELOC)
1196 memaddr = 0;
1197 (*info->print_address_func) ((memaddr & ~3) + value, info);
279a96ca 1198
886a2506
NC
1199 info->target = (bfd_vma) (memaddr & ~3) + value;
1200 }
1201 else if (operand->flags & ARC_OPERAND_SIGNED)
f36e33da
CZ
1202 {
1203 const char *rname = get_auxreg (opcode, value, isa_mask);
1204 if (rname && open_braket)
1205 (*info->fprintf_func) (info->stream, "%s", rname);
1206 else
1207 (*info->fprintf_func) (info->stream, "%d", value);
1208 }
db18dbab
GM
1209 else if (operand->flags & ARC_OPERAND_ADDRTYPE)
1210 {
1211 const char *addrtype = get_addrtype (value);
1212 (*info->fprintf_func) (info->stream, "%s", addrtype);
1213 /* A colon follow an address type. */
1214 need_comma = FALSE;
1215 }
886a2506 1216 else
f36e33da
CZ
1217 {
1218 if (operand->flags & ARC_OPERAND_TRUNCATE
1219 && !(operand->flags & ARC_OPERAND_ALIGNED32)
1220 && !(operand->flags & ARC_OPERAND_ALIGNED16)
1221 && value > 0 && value <= 14)
1222 (*info->fprintf_func) (info->stream, "r13-%s",
1223 regnames[13 + value - 1]);
1224 else
1225 {
1226 const char *rname = get_auxreg (opcode, value, isa_mask);
1227 if (rname && open_braket)
1228 (*info->fprintf_func) (info->stream, "%s", rname);
1229 else
1230 (*info->fprintf_func) (info->stream, "%#x", value);
1231 }
1232 }
252b5132 1233 }
279a96ca 1234
4eb6f892 1235 return insn_len;
252b5132
RH
1236}
1237
47b0e7ad 1238
886a2506
NC
1239disassembler_ftype
1240arc_get_disassembler (bfd *abfd)
252b5132 1241{
dce08442
AK
1242 /* BFD my be absent, if opcodes is invoked from the debugger that
1243 has connected to remote target and doesn't have an ELF file. */
1244 if (abfd != NULL)
1245 {
1246 /* Read the extension insns and registers, if any. */
1247 build_ARC_extmap (abfd);
b99747ae 1248#ifdef DEBUG
dce08442 1249 dump_ARC_extmap ();
b99747ae 1250#endif
dce08442 1251 }
252b5132 1252
886a2506 1253 return print_insn_arc;
252b5132
RH
1254}
1255
886a2506 1256/* Disassemble ARC instructions. Used by debugger. */
47b0e7ad 1257
886a2506
NC
1258struct arcDisState
1259arcAnalyzeInstr (bfd_vma memaddr,
1260 struct disassemble_info *info)
0d2bcfaf 1261{
886a2506
NC
1262 struct arcDisState ret;
1263 memset (&ret, 0, sizeof (struct arcDisState));
1264
1265 ret.instructionLen = print_insn_arc (memaddr, info);
1266
1267#if 0
1268 ret.words[0] = insn[0];
1269 ret.words[1] = insn[1];
1270 ret._this = &ret;
1271 ret.coreRegName = _coreRegName;
1272 ret.auxRegName = _auxRegName;
1273 ret.condCodeName = _condCodeName;
1274 ret.instName = _instName;
1275#endif
47b0e7ad 1276
886a2506 1277 return ret;
0d2bcfaf
NC
1278}
1279
37fd5ef3
CZ
1280void
1281print_arc_disassembler_options (FILE *stream)
1282{
1283 fprintf (stream, _("\n\
1284The following ARC specific disassembler options are supported for use \n\
1285with -M switch (multiple options should be separated by commas):\n"));
1286
1287 fprintf (stream, _("\
1288 dsp Recognize DSP instructions.\n"));
1289 fprintf (stream, _("\
1290 spfp Recognize FPX SP instructions.\n"));
1291 fprintf (stream, _("\
1292 dpfp Recognize FPX DP instructions.\n"));
1293 fprintf (stream, _("\
1294 quarkse_em Recognize FPU QuarkSE-EM instructions.\n"));
1295 fprintf (stream, _("\
1296 fpuda Recognize double assist FPU instructions.\n"));
1297 fprintf (stream, _("\
1298 fpus Recognize single precision FPU instructions.\n"));
1299 fprintf (stream, _("\
1300 fpud Recognize double precision FPU instructions.\n"));
1301}
1302
1303
886a2506
NC
1304/* Local variables:
1305 eval: (c-set-style "gnu")
1306 indent-tabs-mode: t
1307 End: */
This page took 0.790995 seconds and 4 git commands to generate.