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