opcodes/arc: Make some macros 64-bit safe
[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
06fe285f 275 if ((arc_opcode_len (opcode) == 2) && (insn_len == 2))
37fd5ef3
CZ
276 {
277 if (OPCODE_AC (opcode->opcode) != OPCODE_AC (insn[0]))
278 continue;
279 }
06fe285f 280 else if ((arc_opcode_len (opcode) == 4) && (insn_len == 4))
37fd5ef3
CZ
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 {
e5b06ef0 299 int value, limmind;
37fd5ef3 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. */
e5b06ef0 312 limmind = (isa_mask & ARC_OPCODE_ARCV2) ? 0x1E : 0x3E;
37fd5ef3
CZ
313 if (operand->flags & ARC_OPERAND_IR
314 && !(operand->flags & ARC_OPERAND_LIMM))
315 {
316 if ((value == 0x3E && insn_len == 4)
e5b06ef0 317 || (value == limmind && insn_len == 2))
37fd5ef3
CZ
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);
b99747ae
CZ
378
379 return NULL;
380}
381
4eb6f892
AB
382/* Find long instructions matching values in INSN array. */
383
384static const struct arc_long_opcode *
385find_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
06fe285f 403 if ((arc_opcode_len (opcode) == 2) && (*insn_len == 2))
4eb6f892
AB
404 {
405 if (OPCODE_AC (opcode->opcode) != OPCODE_AC (insn[0]))
406 continue;
407 }
06fe285f 408 else if ((arc_opcode_len (opcode) == 4) && (*insn_len == 4))
4eb6f892
AB
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
470static bfd_boolean
37fd5ef3
CZ
471find_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)
4eb6f892 478{
37fd5ef3 479 const struct arc_opcode *opcode = NULL;
4eb6f892 480 bfd_boolean needs_limm;
f807f43d 481 const extInstruction_t *einsn, *i;
4eb6f892 482
37fd5ef3
CZ
483 /* First, try the extension instructions. */
484 einsn = arcExtMap_insn (OPCODE (insn[0]), insn[0]);
f807f43d 485 for (i = einsn; (i != NULL) && (opcode == NULL); i = i->next)
4eb6f892 486 {
37fd5ef3 487 const char *errmsg = NULL;
4eb6f892 488
f807f43d 489 opcode = arcExtMap_genOpcode (i, isa_mask, &errmsg);
37fd5ef3 490 if (opcode == NULL)
4eb6f892 491 {
37fd5ef3
CZ
492 (*info->fprintf_func) (info->stream, "\
493An error occured while generating the extension instruction operations");
494 *opcode_result = NULL;
495 return FALSE;
4eb6f892 496 }
37fd5ef3
CZ
497
498 opcode = find_format_from_table (info, opcode, insn, *insn_len,
499 isa_mask, &needs_limm, FALSE);
4eb6f892
AB
500 }
501
37fd5ef3
CZ
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
4eb6f892
AB
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
f36e33da
CZ
558static void
559print_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. */
c810e0b8 574 if (cl_flags->flag_class & F_CLASS_EXTEND)
f36e33da
CZ
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 }
d9eca1df
CZ
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
f36e33da
CZ
631 (*info->fprintf_func) (info->stream, "%s", flg_operand->name);
632 }
f36e33da
CZ
633 }
634 }
635}
636
637static const char *
638get_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
c810e0b8 646 if (opcode->insn_class != AUXREG)
f36e33da
CZ
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}
cb040366 666
db18dbab
GM
667/* Convert a value representing an address type to a string used to refer to
668 the address type in assembly code. */
669
670static const char *
671get_addrtype (int value)
672{
673 if (value < 0 || value > addrtypenames_max)
674 return addrtypeunknown;
675
676 return addrtypenames[value];
677}
678
cb040366
AB
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
687static unsigned int
4eb6f892 688arc_insn_length (bfd_byte msb, bfd_byte lsb, struct disassemble_info *info)
cb040366
AB
689{
690 bfd_byte major_opcode = msb >> 3;
691
692 switch (info->mach)
693 {
bdd582db
GM
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. */
4eb6f892
AB
700 if (major_opcode == 0xb)
701 {
702 bfd_byte minor_opcode = lsb & 0x1f;
703
704 if (minor_opcode < 4)
705 return 2;
706 }
1a0670f3 707 /* Fall through. */
cb040366
AB
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
4eb6f892
AB
721/* Extract and return the value of OPERAND from the instruction whose value
722 is held in the array INSN. */
723
724static int
725extract_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
767static bfd_boolean
768operand_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
37fd5ef3
CZ
835/* Helper for parsing the options. */
836
837static void
838parse_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
872static void
873parse_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
886a2506 894/* Disassemble ARC instructions. */
0d2bcfaf 895
886a2506
NC
896static int
897print_insn_arc (bfd_vma memaddr,
898 struct disassemble_info *info)
0d2bcfaf 899{
886a2506
NC
900 bfd_byte buffer[4];
901 unsigned int lowbyte, highbyte;
902 int status;
4eb6f892 903 unsigned int insn_len;
3f94e60d
NC
904 unsigned insn[2] = { 0, 0 };
905 unsigned isa_mask;
886a2506 906 const struct arc_opcode *opcode;
886a2506
NC
907 bfd_boolean need_comma;
908 bfd_boolean open_braket;
24b368f8 909 int size;
4eb6f892
AB
910 const struct arc_operand *operand;
911 int value;
912 struct arc_operand_iterator iter;
37fd5ef3
CZ
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 }
0d2bcfaf 922
4eb6f892 923 memset (&iter, 0, sizeof (iter));
886a2506
NC
924 lowbyte = ((info->endian == BFD_ENDIAN_LITTLE) ? 1 : 0);
925 highbyte = ((info->endian == BFD_ENDIAN_LITTLE) ? 0 : 1);
0d2bcfaf 926
37fd5ef3
CZ
927 if (info->section && info->section->owner)
928 header = elf_elfheader (info->section->owner);
929
886a2506
NC
930 switch (info->mach)
931 {
932 case bfd_mach_arc_arc700:
933 isa_mask = ARC_OPCODE_ARC700;
934 break;
0d2bcfaf 935
886a2506
NC
936 case bfd_mach_arc_arc600:
937 isa_mask = ARC_OPCODE_ARC600;
938 break;
0d2bcfaf 939
886a2506
NC
940 case bfd_mach_arc_arcv2:
941 default:
37fd5ef3 942 isa_mask = ARC_OPCODE_ARCv2EM;
7763838e
CM
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)
37fd5ef3
CZ
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 }
886a2506 954 break;
0d2bcfaf
NC
955 }
956
24b368f8
CZ
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
886a2506 995 /* Read the insn into a host word. */
24b368f8 996 status = (*info->read_memory_func) (memaddr, buffer, size, info);
886a2506 997 if (status != 0)
0d2bcfaf 998 {
886a2506
NC
999 (*info->memory_error_func) (status, memaddr, info);
1000 return -1;
0d2bcfaf
NC
1001 }
1002
886a2506
NC
1003 if (info->section
1004 && !(info->section->flags & SEC_CODE))
0d2bcfaf 1005 {
24b368f8
CZ
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)
0d2bcfaf 1012 {
24b368f8
CZ
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 ();
0d2bcfaf 1024 }
24b368f8 1025 return size;
886a2506 1026 }
279a96ca 1027
4eb6f892
AB
1028 insn_len = arc_insn_length (buffer[lowbyte], buffer[highbyte], info);
1029 pr_debug ("instruction length = %d bytes\n", insn_len);
37fd5ef3 1030
4eb6f892 1031 switch (insn_len)
886a2506 1032 {
cb040366 1033 case 2:
886a2506 1034 insn[0] = (buffer[lowbyte] << 8) | buffer[highbyte];
cb040366 1035 break;
886a2506 1036
cb040366
AB
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:
886a2506
NC
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)
0d2bcfaf 1046 {
886a2506
NC
1047 (*info->memory_error_func) (status, memaddr + 2, info);
1048 return -1;
0d2bcfaf 1049 }
886a2506 1050 insn[0] = ARRANGE_ENDIAN (info, buffer);
cb040366 1051 break;
886a2506
NC
1052 }
1053
886a2506
NC
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. */
4eb6f892
AB
1066 if (!find_format (memaddr, insn, &insn_len, isa_mask, info, &opcode, &iter))
1067 return -1;
886a2506 1068
b99747ae
CZ
1069 if (!opcode)
1070 {
4eb6f892
AB
1071 if (insn_len == 2)
1072 (*info->fprintf_func) (info->stream, ".long %#04x", insn[0]);
b99747ae 1073 else
4eb6f892 1074 (*info->fprintf_func) (info->stream, ".long %#08x", insn[0]);
886a2506 1075
4eb6f892
AB
1076 info->insn_type = dis_noninsn;
1077 return insn_len;
886a2506 1078 }
279a96ca 1079
886a2506
NC
1080 /* Print the mnemonic. */
1081 (*info->fprintf_func) (info->stream, "%s", opcode->name);
1082
1083 /* Preselect the insn class. */
c810e0b8 1084 switch (opcode->insn_class)
886a2506
NC
1085 {
1086 case BRANCH:
1087 case JUMP:
1088 if (!strncmp (opcode->name, "bl", 2)
1089 || !strncmp (opcode->name, "jl", 2))
d9eca1df
CZ
1090 {
1091 if (opcode->subclass == COND)
1092 info->insn_type = dis_condjsr;
1093 else
1094 info->insn_type = dis_jsr;
1095 }
279a96ca 1096 else
d9eca1df
CZ
1097 {
1098 if (opcode->subclass == COND)
1099 info->insn_type = dis_condbranch;
1100 else
1101 info->insn_type = dis_branch;
1102 }
886a2506
NC
1103 break;
1104 case MEMORY:
1105 info->insn_type = dis_dref; /* FIXME! DB indicates mov as memory! */
0d2bcfaf 1106 break;
0d2bcfaf 1107 default:
886a2506 1108 info->insn_type = dis_nonbranch;
0d2bcfaf
NC
1109 break;
1110 }
279a96ca 1111
886a2506 1112 pr_debug ("%s: 0x%08x\n", opcode->name, opcode->opcode);
279a96ca 1113
f36e33da 1114 print_flags (opcode, insn, info);
279a96ca 1115
886a2506
NC
1116 if (opcode->operands[0] != 0)
1117 (*info->fprintf_func) (info->stream, "\t");
279a96ca 1118
886a2506
NC
1119 need_comma = FALSE;
1120 open_braket = FALSE;
279a96ca 1121
886a2506 1122 /* Now extract and print the operands. */
4eb6f892
AB
1123 operand = NULL;
1124 while (operand_iterator_next (&iter, &operand, &value))
886a2506 1125 {
886a2506 1126 if (open_braket && (operand->flags & ARC_OPERAND_BRAKET))
0d2bcfaf 1127 {
886a2506
NC
1128 (*info->fprintf_func) (info->stream, "]");
1129 open_braket = FALSE;
1130 continue;
0d2bcfaf 1131 }
279a96ca 1132
886a2506 1133 /* Only take input from real operands. */
db18dbab 1134 if (ARC_OPERAND_IS_FAKE (operand))
886a2506 1135 continue;
279a96ca 1136
4eb6f892
AB
1137 if ((operand->flags & ARC_OPERAND_IGNORE)
1138 && (operand->flags & ARC_OPERAND_IR)
1139 && value == -1)
886a2506 1140 continue;
279a96ca 1141
db18dbab
GM
1142 if (operand->flags & ARC_OPERAND_COLON)
1143 {
1144 (*info->fprintf_func) (info->stream, ":");
1145 continue;
1146 }
1147
886a2506
NC
1148 if (need_comma)
1149 (*info->fprintf_func) (info->stream, ",");
279a96ca 1150
886a2506 1151 if (!open_braket && (operand->flags & ARC_OPERAND_BRAKET))
0d2bcfaf 1152 {
886a2506
NC
1153 (*info->fprintf_func) (info->stream, "[");
1154 open_braket = TRUE;
1155 need_comma = FALSE;
1156 continue;
0d2bcfaf 1157 }
886a2506 1158
db18dbab
GM
1159 need_comma = TRUE;
1160
886a2506
NC
1161 /* Print the operand as directed by the flags. */
1162 if (operand->flags & ARC_OPERAND_IR)
1163 {
f36e33da
CZ
1164 const char *rname;
1165
886a2506 1166 assert (value >=0 && value < 64);
f36e33da
CZ
1167 rname = arcExtMap_coreRegName (value);
1168 if (!rname)
1169 rname = regnames[value];
1170 (*info->fprintf_func) (info->stream, "%s", rname);
886a2506 1171 if (operand->flags & ARC_OPERAND_TRUNCATE)
f36e33da
CZ
1172 {
1173 rname = arcExtMap_coreRegName (value + 1);
1174 if (!rname)
1175 rname = regnames[value + 1];
1176 (*info->fprintf_func) (info->stream, "%s", rname);
1177 }
886a2506
NC
1178 }
1179 else if (operand->flags & ARC_OPERAND_LIMM)
1180 {
4eb6f892 1181 const char *rname = get_auxreg (opcode, value, isa_mask);
db18dbab 1182
f36e33da
CZ
1183 if (rname && open_braket)
1184 (*info->fprintf_func) (info->stream, "%s", rname);
1185 else
1186 {
4eb6f892 1187 (*info->fprintf_func) (info->stream, "%#x", value);
f36e33da
CZ
1188 if (info->insn_type == dis_branch
1189 || info->insn_type == dis_jsr)
4eb6f892 1190 info->target = (bfd_vma) value;
f36e33da 1191 }
886a2506
NC
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);
279a96ca 1199
886a2506
NC
1200 info->target = (bfd_vma) (memaddr & ~3) + value;
1201 }
1202 else if (operand->flags & ARC_OPERAND_SIGNED)
f36e33da
CZ
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 }
db18dbab
GM
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 }
886a2506 1217 else
f36e33da
CZ
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 }
252b5132 1234 }
279a96ca 1235
4eb6f892 1236 return insn_len;
252b5132
RH
1237}
1238
47b0e7ad 1239
886a2506
NC
1240disassembler_ftype
1241arc_get_disassembler (bfd *abfd)
252b5132 1242{
dce08442
AK
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);
b99747ae 1249#ifdef DEBUG
dce08442 1250 dump_ARC_extmap ();
b99747ae 1251#endif
dce08442 1252 }
252b5132 1253
886a2506 1254 return print_insn_arc;
252b5132
RH
1255}
1256
886a2506 1257/* Disassemble ARC instructions. Used by debugger. */
47b0e7ad 1258
886a2506
NC
1259struct arcDisState
1260arcAnalyzeInstr (bfd_vma memaddr,
1261 struct disassemble_info *info)
0d2bcfaf 1262{
886a2506
NC
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
47b0e7ad 1277
886a2506 1278 return ret;
0d2bcfaf
NC
1279}
1280
37fd5ef3
CZ
1281void
1282print_arc_disassembler_options (FILE *stream)
1283{
1284 fprintf (stream, _("\n\
1285The following ARC specific disassembler options are supported for use \n\
1286with -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
886a2506
NC
1305/* Local variables:
1306 eval: (c-set-style "gnu")
1307 indent-tabs-mode: t
1308 End: */
This page took 0.777665 seconds and 4 git commands to generate.