1 /* Instruction printing code for the ARC. 2 Copyright (C) 1994-2018 Free Software Foundation, Inc. 3 4 Contributed by Claudiu Zissulescu (claziss@synopsys.com) 5 6 This file is part of libopcodes. 7 8 This library is free software; you can redistribute it and/or modify 9 it under the terms of the GNU General Public License as published by 10 the Free Software Foundation; either version 3, or (at your option) 11 any later version. 12 13 It is distributed in the hope that it will be useful, but WITHOUT 14 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 15 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public 16 License for more details. 17 18 You should have received a copy of the GNU General Public License 19 along with this program; if not, write to the Free Software 20 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, 21 MA 02110-1301, USA. */ 22 23 #include "sysdep.h" 24 #include <stdio.h> 25 #include <assert.h> 26 #include "dis-asm.h" 27 #include "opcode/arc.h" 28 #include "elf/arc.h" 29 #include "arc-dis.h" 30 #include "arc-ext.h" 31 #include "elf-bfd.h" 32 #include "libiberty.h" 33 #include "opintl.h" 34 35 /* Structure used to iterate over, and extract the values for, operands of 36 an opcode. */ 37 38 struct arc_operand_iterator 39 { 40 /* The complete instruction value to extract operands from. */ 41 unsigned long long insn; 42 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; 46 47 /* The opcode this iterator is operating on. */ 48 const struct arc_opcode *opcode; 49 50 /* The index into the opcodes operand index list. */ 51 const unsigned char *opidx; 52 }; 53 54 /* A private data used by ARC decoder. */ 55 struct arc_disassemble_info 56 { 57 /* The current disassembled arc opcode. */ 58 const struct arc_opcode *opcode; 59 60 /* Instruction length w/o limm field. */ 61 unsigned insn_len; 62 63 /* TRUE if we have limm. */ 64 bfd_boolean limm_p; 65 66 /* LIMM value, if exists. */ 67 unsigned limm; 68 69 /* Condition code, if exists. */ 70 unsigned condition_code; 71 72 /* Writeback mode. */ 73 unsigned writeback_mode; 74 75 /* Number of operands. */ 76 unsigned operands_count; 77 78 struct arc_insn_operand operands[MAX_INSN_ARGS]; 79 }; 80 81 /* Globals variables. */ 82 83 static const char * const regnames[64] = 84 { 85 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", 86 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", 87 "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23", 88 "r24", "r25", "gp", "fp", "sp", "ilink", "r30", "blink", 89 90 "r32", "r33", "r34", "r35", "r36", "r37", "r38", "r39", 91 "r40", "r41", "r42", "r43", "r44", "r45", "r46", "r47", 92 "r48", "r49", "r50", "r51", "r52", "r53", "r54", "r55", 93 "r56", "r57", "ACCL", "ACCH", "lp_count", "rezerved", "LIMM", "pcl" 94 }; 95 96 static const char * const addrtypenames[ARC_NUM_ADDRTYPES] = 97 { 98 "bd", "jid", "lbd", "mbd", "sd", "sm", "xa", "xd", 99 "cd", "cbd", "cjid", "clbd", "cm", "csd", "cxa", "cxd" 100 }; 101 102 static int addrtypenames_max = ARC_NUM_ADDRTYPES - 1; 103 104 static const char * const addrtypeunknown = "unknown"; 105 106 /* This structure keeps track which instruction class(es) 107 should be ignored durring disassembling. */ 108 109 typedef struct skipclass 110 { 111 insn_class_t insn_class; 112 insn_subclass_t subclass; 113 struct skipclass *nxt; 114 } skipclass_t, *linkclass; 115 116 /* Intial classes of instructions to be consider first when 117 disassembling. */ 118 static linkclass decodelist = NULL; 119 120 /* ISA mask value enforced via disassembler info options. ARC_OPCODE_NONE 121 value means that no CPU is enforced. */ 122 123 static unsigned enforced_isa_mask = ARC_OPCODE_NONE; 124 125 /* True if we want to print using only hex numbers. */ 126 static bfd_boolean print_hex = FALSE; 127 128 /* Macros section. */ 129 130 #ifdef DEBUG 131 # define pr_debug(fmt, args...) fprintf (stderr, fmt, ##args) 132 #else 133 # define pr_debug(fmt, args...) 134 #endif 135 136 #define ARRANGE_ENDIAN(info, buf) \ 137 (info->endian == BFD_ENDIAN_LITTLE ? bfd_getm32 (bfd_getl32 (buf)) \ 138 : bfd_getb32 (buf)) 139 140 #define BITS(word,s,e) (((word) << (sizeof (word) * 8 - 1 - e)) >> \ 141 (s + (sizeof (word) * 8 - 1 - e))) 142 #define OPCODE_32BIT_INSN(word) (BITS ((word), 27, 31)) 143 144 /* Functions implementation. */ 145 146 /* Initialize private data. */ 147 static bfd_boolean 148 init_arc_disasm_info (struct disassemble_info *info) 149 { 150 struct arc_disassemble_info *arc_infop 151 = calloc (sizeof (*arc_infop), 1); 152 153 if (arc_infop == NULL) 154 return FALSE; 155 156 info->private_data = arc_infop; 157 return TRUE; 158 } 159 160 /* Add a new element to the decode list. */ 161 162 static void 163 add_to_decodelist (insn_class_t insn_class, 164 insn_subclass_t subclass) 165 { 166 linkclass t = (linkclass) xmalloc (sizeof (skipclass_t)); 167 168 t->insn_class = insn_class; 169 t->subclass = subclass; 170 t->nxt = decodelist; 171 decodelist = t; 172 } 173 174 /* Return TRUE if we need to skip the opcode from being 175 disassembled. */ 176 177 static bfd_boolean 178 skip_this_opcode (const struct arc_opcode *opcode) 179 { 180 linkclass t = decodelist; 181 182 /* Check opcode for major 0x06, return if it is not in. */ 183 if (arc_opcode_len (opcode) == 4 184 && OPCODE_32BIT_INSN (opcode->opcode) != 0x06) 185 return FALSE; 186 187 /* or not a known truble class. */ 188 switch (opcode->insn_class) 189 { 190 case FLOAT: 191 case DSP: 192 case ARITH: 193 break; 194 default: 195 return FALSE; 196 } 197 198 while (t != NULL) 199 { 200 if ((t->insn_class == opcode->insn_class) 201 && (t->subclass == opcode->subclass)) 202 return FALSE; 203 t = t->nxt; 204 } 205 206 return TRUE; 207 } 208 209 static bfd_vma 210 bfd_getm32 (unsigned int data) 211 { 212 bfd_vma value = 0; 213 214 value = ((data & 0xff00) | (data & 0xff)) << 16; 215 value |= ((data & 0xff0000) | (data & 0xff000000)) >> 16; 216 return value; 217 } 218 219 static bfd_boolean 220 special_flag_p (const char *opname, 221 const char *flgname) 222 { 223 const struct arc_flag_special *flg_spec; 224 unsigned i, j, flgidx; 225 226 for (i = 0; i < arc_num_flag_special; i++) 227 { 228 flg_spec = &arc_flag_special_cases[i]; 229 230 if (strcmp (opname, flg_spec->name)) 231 continue; 232 233 /* Found potential special case instruction. */ 234 for (j=0;; ++j) 235 { 236 flgidx = flg_spec->flags[j]; 237 if (flgidx == 0) 238 break; /* End of the array. */ 239 240 if (strcmp (flgname, arc_flag_operands[flgidx].name) == 0) 241 return TRUE; 242 } 243 } 244 return FALSE; 245 } 246 247 /* Find opcode from ARC_TABLE given the instruction described by INSN and 248 INSNLEN. The ISA_MASK restricts the possible matches in ARC_TABLE. */ 249 250 static const struct arc_opcode * 251 find_format_from_table (struct disassemble_info *info, 252 const struct arc_opcode *arc_table, 253 unsigned long long insn, 254 unsigned int insn_len, 255 unsigned isa_mask, 256 bfd_boolean *has_limm, 257 bfd_boolean overlaps) 258 { 259 unsigned int i = 0; 260 const struct arc_opcode *opcode = NULL; 261 const struct arc_opcode *t_op = NULL; 262 const unsigned char *opidx; 263 const unsigned char *flgidx; 264 bfd_boolean warn_p = FALSE; 265 266 do 267 { 268 bfd_boolean invalid = FALSE; 269 270 opcode = &arc_table[i++]; 271 272 if (!(opcode->cpu & isa_mask)) 273 continue; 274 275 if (arc_opcode_len (opcode) != (int) insn_len) 276 continue; 277 278 if ((insn & opcode->mask) != opcode->opcode) 279 continue; 280 281 *has_limm = FALSE; 282 283 /* Possible candidate, check the operands. */ 284 for (opidx = opcode->operands; *opidx; opidx++) 285 { 286 int value, limmind; 287 const struct arc_operand *operand = &arc_operands[*opidx]; 288 289 if (operand->flags & ARC_OPERAND_FAKE) 290 continue; 291 292 if (operand->extract) 293 value = (*operand->extract) (insn, &invalid); 294 else 295 value = (insn >> operand->shift) & ((1 << operand->bits) - 1); 296 297 /* Check for LIMM indicator. If it is there, then make sure 298 we pick the right format. */ 299 limmind = (isa_mask & ARC_OPCODE_ARCV2) ? 0x1E : 0x3E; 300 if (operand->flags & ARC_OPERAND_IR 301 && !(operand->flags & ARC_OPERAND_LIMM)) 302 { 303 if ((value == 0x3E && insn_len == 4) 304 || (value == limmind && insn_len == 2)) 305 { 306 invalid = TRUE; 307 break; 308 } 309 } 310 311 if (operand->flags & ARC_OPERAND_LIMM 312 && !(operand->flags & ARC_OPERAND_DUPLICATE)) 313 *has_limm = TRUE; 314 } 315 316 /* Check the flags. */ 317 for (flgidx = opcode->flags; *flgidx; flgidx++) 318 { 319 /* Get a valid flag class. */ 320 const struct arc_flag_class *cl_flags = &arc_flag_classes[*flgidx]; 321 const unsigned *flgopridx; 322 int foundA = 0, foundB = 0; 323 unsigned int value; 324 325 /* Check first the extensions. */ 326 if (cl_flags->flag_class & F_CLASS_EXTEND) 327 { 328 value = (insn & 0x1F); 329 if (arcExtMap_condCodeName (value)) 330 continue; 331 } 332 333 /* Check for the implicit flags. */ 334 if (cl_flags->flag_class & F_CLASS_IMPLICIT) 335 continue; 336 337 for (flgopridx = cl_flags->flags; *flgopridx; ++flgopridx) 338 { 339 const struct arc_flag_operand *flg_operand = 340 &arc_flag_operands[*flgopridx]; 341 342 value = (insn >> flg_operand->shift) 343 & ((1 << flg_operand->bits) - 1); 344 if (value == flg_operand->code) 345 foundA = 1; 346 if (value) 347 foundB = 1; 348 } 349 350 if (!foundA && foundB) 351 { 352 invalid = TRUE; 353 break; 354 } 355 } 356 357 if (invalid) 358 continue; 359 360 if (insn_len == 4 361 && overlaps) 362 { 363 warn_p = TRUE; 364 t_op = opcode; 365 if (skip_this_opcode (opcode)) 366 continue; 367 } 368 369 /* The instruction is valid. */ 370 return opcode; 371 } 372 while (opcode->mask); 373 374 if (warn_p) 375 { 376 info->fprintf_func (info->stream, 377 _("\nWarning: disassembly may be wrong due to " 378 "guessed opcode class choice.\n" 379 "Use -M<class[,class]> to select the correct " 380 "opcode class(es).\n\t\t\t\t")); 381 return t_op; 382 } 383 384 return NULL; 385 } 386 387 /* Find opcode for INSN, trying various different sources. The instruction 388 length in INSN_LEN will be updated if the instruction requires a LIMM 389 extension. 390 391 A pointer to the opcode is placed into OPCODE_RESULT, and ITER is 392 initialised, ready to iterate over the operands of the found opcode. If 393 the found opcode requires a LIMM then the LIMM value will be loaded into a 394 field of ITER. 395 396 This function returns TRUE in almost all cases, FALSE is reserved to 397 indicate an error (failing to find an opcode is not an error) a returned 398 result of FALSE would indicate that the disassembler can't continue. 399 400 If no matching opcode is found then the returned result will be TRUE, the 401 value placed into OPCODE_RESULT will be NULL, ITER will be undefined, and 402 INSN_LEN will be unchanged. 403 404 If a matching opcode is found, then the returned result will be TRUE, the 405 opcode pointer is placed into OPCODE_RESULT, INSN_LEN will be increased by 406 4 if the instruction requires a LIMM, and the LIMM value will have been 407 loaded into a field of ITER. Finally, ITER will have been initialised so 408 that calls to OPERAND_ITERATOR_NEXT will iterate over the opcode's 409 operands. */ 410 411 static bfd_boolean 412 find_format (bfd_vma memaddr, 413 unsigned long long insn, 414 unsigned int * insn_len, 415 unsigned isa_mask, 416 struct disassemble_info * info, 417 const struct arc_opcode ** opcode_result, 418 struct arc_operand_iterator * iter) 419 { 420 const struct arc_opcode *opcode = NULL; 421 bfd_boolean needs_limm; 422 const extInstruction_t *einsn, *i; 423 unsigned limm = 0; 424 struct arc_disassemble_info *arc_infop = info->private_data; 425 426 /* First, try the extension instructions. */ 427 if (*insn_len == 4) 428 { 429 einsn = arcExtMap_insn (OPCODE_32BIT_INSN (insn), insn); 430 for (i = einsn; (i != NULL) && (opcode == NULL); i = i->next) 431 { 432 const char *errmsg = NULL; 433 434 opcode = arcExtMap_genOpcode (i, isa_mask, &errmsg); 435 if (opcode == NULL) 436 { 437 (*info->fprintf_func) (info->stream, "\ 438 An error occured while generating the extension instruction operations"); 439 *opcode_result = NULL; 440 return FALSE; 441 } 442 443 opcode = find_format_from_table (info, opcode, insn, *insn_len, 444 isa_mask, &needs_limm, FALSE); 445 } 446 } 447 448 /* Then, try finding the first match in the opcode table. */ 449 if (opcode == NULL) 450 opcode = find_format_from_table (info, arc_opcodes, insn, *insn_len, 451 isa_mask, &needs_limm, TRUE); 452 453 if (needs_limm && opcode != NULL) 454 { 455 bfd_byte buffer[4]; 456 int status; 457 458 status = (*info->read_memory_func) (memaddr + *insn_len, buffer, 459 4, info); 460 if (status != 0) 461 { 462 opcode = NULL; 463 } 464 else 465 { 466 limm = ARRANGE_ENDIAN (info, buffer); 467 *insn_len += 4; 468 } 469 } 470 471 if (opcode != NULL) 472 { 473 iter->insn = insn; 474 iter->limm = limm; 475 iter->opcode = opcode; 476 iter->opidx = opcode->operands; 477 } 478 479 *opcode_result = opcode; 480 481 /* Update private data. */ 482 arc_infop->opcode = opcode; 483 arc_infop->limm = (needs_limm) ? limm : 0; 484 arc_infop->limm_p = needs_limm; 485 486 return TRUE; 487 } 488 489 static void 490 print_flags (const struct arc_opcode *opcode, 491 unsigned long long *insn, 492 struct disassemble_info *info) 493 { 494 const unsigned char *flgidx; 495 unsigned int value; 496 struct arc_disassemble_info *arc_infop = info->private_data; 497 498 /* Now extract and print the flags. */ 499 for (flgidx = opcode->flags; *flgidx; flgidx++) 500 { 501 /* Get a valid flag class. */ 502 const struct arc_flag_class *cl_flags = &arc_flag_classes[*flgidx]; 503 const unsigned *flgopridx; 504 505 /* Check first the extensions. */ 506 if (cl_flags->flag_class & F_CLASS_EXTEND) 507 { 508 const char *name; 509 value = (insn[0] & 0x1F); 510 511 name = arcExtMap_condCodeName (value); 512 if (name) 513 { 514 (*info->fprintf_func) (info->stream, ".%s", name); 515 continue; 516 } 517 } 518 519 for (flgopridx = cl_flags->flags; *flgopridx; ++flgopridx) 520 { 521 const struct arc_flag_operand *flg_operand = 522 &arc_flag_operands[*flgopridx]; 523 524 /* Implicit flags are only used for the insn decoder. */ 525 if (cl_flags->flag_class & F_CLASS_IMPLICIT) 526 { 527 if (cl_flags->flag_class & F_CLASS_COND) 528 arc_infop->condition_code = flg_operand->code; 529 else if (cl_flags->flag_class & F_CLASS_WB) 530 arc_infop->writeback_mode = flg_operand->code; 531 else if (cl_flags->flag_class & F_CLASS_ZZ) 532 info->data_size = flg_operand->code; 533 continue; 534 } 535 536 if (!flg_operand->favail) 537 continue; 538 539 value = (insn[0] >> flg_operand->shift) 540 & ((1 << flg_operand->bits) - 1); 541 if (value == flg_operand->code) 542 { 543 /* FIXME!: print correctly nt/t flag. */ 544 if (!special_flag_p (opcode->name, flg_operand->name)) 545 (*info->fprintf_func) (info->stream, "."); 546 else if (info->insn_type == dis_dref) 547 { 548 switch (flg_operand->name[0]) 549 { 550 case 'b': 551 info->data_size = 1; 552 break; 553 case 'h': 554 case 'w': 555 info->data_size = 2; 556 break; 557 default: 558 info->data_size = 4; 559 break; 560 } 561 } 562 if (flg_operand->name[0] == 'd' 563 && flg_operand->name[1] == 0) 564 info->branch_delay_insns = 1; 565 566 /* Check if it is a conditional flag. */ 567 if (cl_flags->flag_class & F_CLASS_COND) 568 { 569 if (info->insn_type == dis_jsr) 570 info->insn_type = dis_condjsr; 571 else if (info->insn_type == dis_branch) 572 info->insn_type = dis_condbranch; 573 arc_infop->condition_code = flg_operand->code; 574 } 575 576 /* Check for the write back modes. */ 577 if (cl_flags->flag_class & F_CLASS_WB) 578 arc_infop->writeback_mode = flg_operand->code; 579 580 (*info->fprintf_func) (info->stream, "%s", flg_operand->name); 581 } 582 } 583 } 584 } 585 586 static const char * 587 get_auxreg (const struct arc_opcode *opcode, 588 int value, 589 unsigned isa_mask) 590 { 591 const char *name; 592 unsigned int i; 593 const struct arc_aux_reg *auxr = &arc_aux_regs[0]; 594 595 if (opcode->insn_class != AUXREG) 596 return NULL; 597 598 name = arcExtMap_auxRegName (value); 599 if (name) 600 return name; 601 602 for (i = 0; i < arc_num_aux_regs; i++, auxr++) 603 { 604 if (!(auxr->cpu & isa_mask)) 605 continue; 606 607 if (auxr->subclass != NONE) 608 return NULL; 609 610 if (auxr->address == value) 611 return auxr->name; 612 } 613 return NULL; 614 } 615 616 /* Convert a value representing an address type to a string used to refer to 617 the address type in assembly code. */ 618 619 static const char * 620 get_addrtype (int value) 621 { 622 if (value < 0 || value > addrtypenames_max) 623 return addrtypeunknown; 624 625 return addrtypenames[value]; 626 } 627 628 /* Calculate the instruction length for an instruction starting with MSB 629 and LSB, the most and least significant byte. The ISA_MASK is used to 630 filter the instructions considered to only those that are part of the 631 current architecture. 632 633 The instruction lengths are calculated from the ARC_OPCODE table, and 634 cached for later use. */ 635 636 static unsigned int 637 arc_insn_length (bfd_byte msb, bfd_byte lsb, struct disassemble_info *info) 638 { 639 bfd_byte major_opcode = msb >> 3; 640 641 switch (info->mach) 642 { 643 case bfd_mach_arc_arc700: 644 /* The nps400 extension set requires this special casing of the 645 instruction length calculation. Right now this is not causing any 646 problems as none of the known extensions overlap in opcode space, 647 but, if they ever do then we might need to start carrying 648 information around in the elf about which extensions are in use. */ 649 if (major_opcode == 0xb) 650 { 651 bfd_byte minor_opcode = lsb & 0x1f; 652 653 if (minor_opcode < 4) 654 return 6; 655 else if (minor_opcode == 0x10 || minor_opcode == 0x11) 656 return 8; 657 } 658 if (major_opcode == 0xa) 659 { 660 return 8; 661 } 662 /* Fall through. */ 663 case bfd_mach_arc_arc600: 664 return (major_opcode > 0xb) ? 2 : 4; 665 break; 666 667 case bfd_mach_arc_arcv2: 668 return (major_opcode > 0x7) ? 2 : 4; 669 break; 670 671 default: 672 abort (); 673 } 674 } 675 676 /* Extract and return the value of OPERAND from the instruction whose value 677 is held in the array INSN. */ 678 679 static int 680 extract_operand_value (const struct arc_operand *operand, 681 unsigned long long insn, 682 unsigned limm) 683 { 684 int value; 685 686 /* Read the limm operand, if required. */ 687 if (operand->flags & ARC_OPERAND_LIMM) 688 /* The second part of the instruction value will have been loaded as 689 part of the find_format call made earlier. */ 690 value = limm; 691 else 692 { 693 if (operand->extract) 694 value = (*operand->extract) (insn, (int *) NULL); 695 else 696 { 697 if (operand->flags & ARC_OPERAND_ALIGNED32) 698 { 699 value = (insn >> operand->shift) 700 & ((1 << (operand->bits - 2)) - 1); 701 value = value << 2; 702 } 703 else 704 { 705 value = (insn >> operand->shift) & ((1 << operand->bits) - 1); 706 } 707 if (operand->flags & ARC_OPERAND_SIGNED) 708 { 709 int signbit = 1 << (operand->bits - 1); 710 value = (value ^ signbit) - signbit; 711 } 712 } 713 } 714 715 return value; 716 } 717 718 /* Find the next operand, and the operands value from ITER. Return TRUE if 719 there is another operand, otherwise return FALSE. If there is an 720 operand returned then the operand is placed into OPERAND, and the value 721 into VALUE. If there is no operand returned then OPERAND and VALUE are 722 unchanged. */ 723 724 static bfd_boolean 725 operand_iterator_next (struct arc_operand_iterator *iter, 726 const struct arc_operand **operand, 727 int *value) 728 { 729 if (*iter->opidx == 0) 730 { 731 *operand = NULL; 732 return FALSE; 733 } 734 735 *operand = &arc_operands[*iter->opidx]; 736 *value = extract_operand_value (*operand, iter->insn, iter->limm); 737 iter->opidx++; 738 739 return TRUE; 740 } 741 742 /* Helper for parsing the options. */ 743 744 static void 745 parse_option (const char *option) 746 { 747 if (disassembler_options_cmp (option, "dsp") == 0) 748 add_to_decodelist (DSP, NONE); 749 750 else if (disassembler_options_cmp (option, "spfp") == 0) 751 add_to_decodelist (FLOAT, SPX); 752 753 else if (disassembler_options_cmp (option, "dpfp") == 0) 754 add_to_decodelist (FLOAT, DPX); 755 756 else if (disassembler_options_cmp (option, "quarkse_em") == 0) 757 { 758 add_to_decodelist (FLOAT, DPX); 759 add_to_decodelist (FLOAT, SPX); 760 add_to_decodelist (FLOAT, QUARKSE1); 761 add_to_decodelist (FLOAT, QUARKSE2); 762 } 763 764 else if (disassembler_options_cmp (option, "fpuda") == 0) 765 add_to_decodelist (FLOAT, DPA); 766 767 else if (disassembler_options_cmp (option, "fpus") == 0) 768 { 769 add_to_decodelist (FLOAT, SP); 770 add_to_decodelist (FLOAT, CVT); 771 } 772 773 else if (disassembler_options_cmp (option, "fpud") == 0) 774 { 775 add_to_decodelist (FLOAT, DP); 776 add_to_decodelist (FLOAT, CVT); 777 } 778 else if (CONST_STRNEQ (option, "hex")) 779 print_hex = TRUE; 780 else 781 fprintf (stderr, _("Unrecognised disassembler option: %s\n"), option); 782 } 783 784 #define ARC_CPU_TYPE_A6xx(NAME,EXTRA) \ 785 { #NAME, ARC_OPCODE_ARC600, "ARC600" } 786 #define ARC_CPU_TYPE_A7xx(NAME,EXTRA) \ 787 { #NAME, ARC_OPCODE_ARC700, "ARC700" } 788 #define ARC_CPU_TYPE_AV2EM(NAME,EXTRA) \ 789 { #NAME, ARC_OPCODE_ARCv2EM, "ARC EM" } 790 #define ARC_CPU_TYPE_AV2HS(NAME,EXTRA) \ 791 { #NAME, ARC_OPCODE_ARCv2HS, "ARC HS" } 792 #define ARC_CPU_TYPE_NONE \ 793 { 0, 0, 0 } 794 795 /* A table of CPU names and opcode sets. */ 796 static const struct cpu_type 797 { 798 const char *name; 799 unsigned flags; 800 const char *isa; 801 } 802 cpu_types[] = 803 { 804 #include "elf/arc-cpu.def" 805 }; 806 807 /* Helper for parsing the CPU options. Accept any of the ARC architectures 808 values. OPTION should be a value passed to cpu=. */ 809 810 static unsigned 811 parse_cpu_option (const char *option) 812 { 813 int i; 814 815 for (i = 0; cpu_types[i].name; ++i) 816 { 817 if (!disassembler_options_cmp (cpu_types[i].name, option)) 818 { 819 return cpu_types[i].flags; 820 } 821 } 822 823 fprintf (stderr, _("Unrecognised disassembler CPU option: %s\n"), option); 824 return ARC_OPCODE_NONE; 825 } 826 827 /* Go over the options list and parse it. */ 828 829 static void 830 parse_disassembler_options (const char *options) 831 { 832 const char *option; 833 834 if (options == NULL) 835 return; 836 837 /* Disassembler might be reused for difference CPU's, and cpu option set for 838 the first one shouldn't be applied to second (which might not have 839 explicit cpu in its options. Therefore it is required to reset enforced 840 CPU when new options are being parsed. */ 841 enforced_isa_mask = ARC_OPCODE_NONE; 842 843 FOR_EACH_DISASSEMBLER_OPTION (option, options) 844 { 845 /* A CPU option? Cannot use STRING_COMMA_LEN because strncmp is also a 846 preprocessor macro. */ 847 if (strncmp (option, "cpu=", 4) == 0) 848 /* Strip leading `cpu=`. */ 849 enforced_isa_mask = parse_cpu_option (option + 4); 850 else 851 parse_option (option); 852 } 853 } 854 855 /* Return the instruction type for an instruction described by OPCODE. */ 856 857 static enum dis_insn_type 858 arc_opcode_to_insn_type (const struct arc_opcode *opcode) 859 { 860 enum dis_insn_type insn_type; 861 862 switch (opcode->insn_class) 863 { 864 case BRANCH: 865 case BBIT0: 866 case BBIT1: 867 case BI: 868 case BIH: 869 case BRCC: 870 case EI: 871 case JLI: 872 case JUMP: 873 case LOOP: 874 if (!strncmp (opcode->name, "bl", 2) 875 || !strncmp (opcode->name, "jl", 2)) 876 { 877 if (opcode->subclass == COND) 878 insn_type = dis_condjsr; 879 else 880 insn_type = dis_jsr; 881 } 882 else 883 { 884 if (opcode->subclass == COND) 885 insn_type = dis_condbranch; 886 else 887 insn_type = dis_branch; 888 } 889 break; 890 case LOAD: 891 case STORE: 892 case MEMORY: 893 case ENTER: 894 case PUSH: 895 case POP: 896 insn_type = dis_dref; 897 break; 898 case LEAVE: 899 insn_type = dis_branch; 900 break; 901 default: 902 insn_type = dis_nonbranch; 903 break; 904 } 905 906 return insn_type; 907 } 908 909 /* Disassemble ARC instructions. */ 910 911 static int 912 print_insn_arc (bfd_vma memaddr, 913 struct disassemble_info *info) 914 { 915 bfd_byte buffer[8]; 916 unsigned int highbyte, lowbyte; 917 int status; 918 unsigned int insn_len; 919 unsigned long long insn = 0; 920 unsigned isa_mask = ARC_OPCODE_NONE; 921 const struct arc_opcode *opcode; 922 bfd_boolean need_comma; 923 bfd_boolean open_braket; 924 int size; 925 const struct arc_operand *operand; 926 int value, vpcl; 927 struct arc_operand_iterator iter; 928 struct arc_disassemble_info *arc_infop; 929 bfd_boolean rpcl = FALSE, rset = FALSE; 930 931 if (info->disassembler_options) 932 { 933 parse_disassembler_options (info->disassembler_options); 934 935 /* Avoid repeated parsing of the options. */ 936 info->disassembler_options = NULL; 937 } 938 939 if (info->private_data == NULL && !init_arc_disasm_info (info)) 940 return -1; 941 942 memset (&iter, 0, sizeof (iter)); 943 highbyte = ((info->endian == BFD_ENDIAN_LITTLE) ? 1 : 0); 944 lowbyte = ((info->endian == BFD_ENDIAN_LITTLE) ? 0 : 1); 945 946 /* Figure out CPU type, unless it was enforced via disassembler options. */ 947 if (enforced_isa_mask == ARC_OPCODE_NONE) 948 { 949 Elf_Internal_Ehdr *header = NULL; 950 951 if (info->section && info->section->owner) 952 header = elf_elfheader (info->section->owner); 953 954 switch (info->mach) 955 { 956 case bfd_mach_arc_arc700: 957 isa_mask = ARC_OPCODE_ARC700; 958 break; 959 960 case bfd_mach_arc_arc600: 961 isa_mask = ARC_OPCODE_ARC600; 962 break; 963 964 case bfd_mach_arc_arcv2: 965 default: 966 isa_mask = ARC_OPCODE_ARCv2EM; 967 /* TODO: Perhaps remove definition of header since it is only used at 968 this location. */ 969 if (header != NULL 970 && (header->e_flags & EF_ARC_MACH_MSK) == EF_ARC_CPU_ARCV2HS) 971 isa_mask = ARC_OPCODE_ARCv2HS; 972 break; 973 } 974 } 975 else 976 isa_mask = enforced_isa_mask; 977 978 if (isa_mask == ARC_OPCODE_ARCv2HS) 979 { 980 /* FPU instructions are not extensions for HS. */ 981 add_to_decodelist (FLOAT, SP); 982 add_to_decodelist (FLOAT, DP); 983 add_to_decodelist (FLOAT, CVT); 984 } 985 986 /* This variable may be set by the instruction decoder. It suggests 987 the number of bytes objdump should display on a single line. If 988 the instruction decoder sets this, it should always set it to 989 the same value in order to get reasonable looking output. */ 990 991 info->bytes_per_line = 8; 992 993 /* In the next lines, we set two info variables control the way 994 objdump displays the raw data. For example, if bytes_per_line is 995 8 and bytes_per_chunk is 4, the output will look like this: 996 00: 00000000 00000000 997 with the chunks displayed according to "display_endian". */ 998 999 if (info->section 1000 && !(info->section->flags & SEC_CODE)) 1001 { 1002 /* This is not a CODE section. */ 1003 switch (info->section->size) 1004 { 1005 case 1: 1006 case 2: 1007 case 4: 1008 size = info->section->size; 1009 break; 1010 default: 1011 size = (info->section->size & 0x01) ? 1 : 4; 1012 break; 1013 } 1014 info->bytes_per_chunk = 1; 1015 info->display_endian = info->endian; 1016 } 1017 else 1018 { 1019 size = 2; 1020 info->bytes_per_chunk = 2; 1021 info->display_endian = info->endian; 1022 } 1023 1024 /* Read the insn into a host word. */ 1025 status = (*info->read_memory_func) (memaddr, buffer, size, info); 1026 1027 if (status != 0) 1028 { 1029 (*info->memory_error_func) (status, memaddr, info); 1030 return -1; 1031 } 1032 1033 if (info->section 1034 && !(info->section->flags & SEC_CODE)) 1035 { 1036 /* Data section. */ 1037 unsigned long data; 1038 1039 data = bfd_get_bits (buffer, size * 8, 1040 info->display_endian == BFD_ENDIAN_BIG); 1041 switch (size) 1042 { 1043 case 1: 1044 (*info->fprintf_func) (info->stream, ".byte\t0x%02lx", data); 1045 break; 1046 case 2: 1047 (*info->fprintf_func) (info->stream, ".short\t0x%04lx", data); 1048 break; 1049 case 4: 1050 (*info->fprintf_func) (info->stream, ".word\t0x%08lx", data); 1051 break; 1052 default: 1053 abort (); 1054 } 1055 return size; 1056 } 1057 1058 insn_len = arc_insn_length (buffer[highbyte], buffer[lowbyte], info); 1059 pr_debug ("instruction length = %d bytes\n", insn_len); 1060 arc_infop = info->private_data; 1061 arc_infop->insn_len = insn_len; 1062 1063 switch (insn_len) 1064 { 1065 case 2: 1066 insn = (buffer[highbyte] << 8) | buffer[lowbyte]; 1067 break; 1068 1069 case 4: 1070 { 1071 /* This is a long instruction: Read the remaning 2 bytes. */ 1072 status = (*info->read_memory_func) (memaddr + 2, &buffer[2], 2, info); 1073 if (status != 0) 1074 { 1075 (*info->memory_error_func) (status, memaddr + 2, info); 1076 return -1; 1077 } 1078 insn = (unsigned long long) ARRANGE_ENDIAN (info, buffer); 1079 } 1080 break; 1081 1082 case 6: 1083 { 1084 status = (*info->read_memory_func) (memaddr + 2, &buffer[2], 4, info); 1085 if (status != 0) 1086 { 1087 (*info->memory_error_func) (status, memaddr + 2, info); 1088 return -1; 1089 } 1090 insn = (unsigned long long) ARRANGE_ENDIAN (info, &buffer[2]); 1091 insn |= ((unsigned long long) buffer[highbyte] << 40) 1092 | ((unsigned long long) buffer[lowbyte] << 32); 1093 } 1094 break; 1095 1096 case 8: 1097 { 1098 status = (*info->read_memory_func) (memaddr + 2, &buffer[2], 6, info); 1099 if (status != 0) 1100 { 1101 (*info->memory_error_func) (status, memaddr + 2, info); 1102 return -1; 1103 } 1104 insn = 1105 ((((unsigned long long) ARRANGE_ENDIAN (info, buffer)) << 32) 1106 | ((unsigned long long) ARRANGE_ENDIAN (info, &buffer[4]))); 1107 } 1108 break; 1109 1110 default: 1111 /* There is no instruction whose length is not 2, 4, 6, or 8. */ 1112 abort (); 1113 } 1114 1115 pr_debug ("instruction value = %llx\n", insn); 1116 1117 /* Set some defaults for the insn info. */ 1118 info->insn_info_valid = 1; 1119 info->branch_delay_insns = 0; 1120 info->data_size = 4; 1121 info->insn_type = dis_nonbranch; 1122 info->target = 0; 1123 info->target2 = 0; 1124 1125 /* FIXME to be moved in dissasemble_init_for_target. */ 1126 info->disassembler_needs_relocs = TRUE; 1127 1128 /* Find the first match in the opcode table. */ 1129 if (!find_format (memaddr, insn, &insn_len, isa_mask, info, &opcode, &iter)) 1130 return -1; 1131 1132 if (!opcode) 1133 { 1134 switch (insn_len) 1135 { 1136 case 2: 1137 (*info->fprintf_func) (info->stream, ".shor\t%#04llx", 1138 insn & 0xffff); 1139 break; 1140 case 4: 1141 (*info->fprintf_func) (info->stream, ".word\t%#08llx", 1142 insn & 0xffffffff); 1143 break; 1144 case 6: 1145 (*info->fprintf_func) (info->stream, ".long\t%#08llx", 1146 insn & 0xffffffff); 1147 (*info->fprintf_func) (info->stream, ".long\t%#04llx", 1148 (insn >> 32) & 0xffff); 1149 break; 1150 case 8: 1151 (*info->fprintf_func) (info->stream, ".long\t%#08llx", 1152 insn & 0xffffffff); 1153 (*info->fprintf_func) (info->stream, ".long\t%#08llx", 1154 insn >> 32); 1155 break; 1156 default: 1157 abort (); 1158 } 1159 1160 info->insn_type = dis_noninsn; 1161 return insn_len; 1162 } 1163 1164 /* Print the mnemonic. */ 1165 (*info->fprintf_func) (info->stream, "%s", opcode->name); 1166 1167 /* Preselect the insn class. */ 1168 info->insn_type = arc_opcode_to_insn_type (opcode); 1169 1170 pr_debug ("%s: 0x%08llx\n", opcode->name, opcode->opcode); 1171 1172 print_flags (opcode, &insn, info); 1173 1174 if (opcode->operands[0] != 0) 1175 (*info->fprintf_func) (info->stream, "\t"); 1176 1177 need_comma = FALSE; 1178 open_braket = FALSE; 1179 arc_infop->operands_count = 0; 1180 1181 /* Now extract and print the operands. */ 1182 operand = NULL; 1183 vpcl = 0; 1184 while (operand_iterator_next (&iter, &operand, &value)) 1185 { 1186 if (open_braket && (operand->flags & ARC_OPERAND_BRAKET)) 1187 { 1188 (*info->fprintf_func) (info->stream, "]"); 1189 open_braket = FALSE; 1190 continue; 1191 } 1192 1193 /* Only take input from real operands. */ 1194 if (ARC_OPERAND_IS_FAKE (operand)) 1195 continue; 1196 1197 if ((operand->flags & ARC_OPERAND_IGNORE) 1198 && (operand->flags & ARC_OPERAND_IR) 1199 && value == -1) 1200 continue; 1201 1202 if (operand->flags & ARC_OPERAND_COLON) 1203 { 1204 (*info->fprintf_func) (info->stream, ":"); 1205 continue; 1206 } 1207 1208 if (need_comma) 1209 (*info->fprintf_func) (info->stream, ","); 1210 1211 if (!open_braket && (operand->flags & ARC_OPERAND_BRAKET)) 1212 { 1213 (*info->fprintf_func) (info->stream, "["); 1214 open_braket = TRUE; 1215 need_comma = FALSE; 1216 continue; 1217 } 1218 1219 need_comma = TRUE; 1220 1221 if (operand->flags & ARC_OPERAND_PCREL) 1222 { 1223 rpcl = TRUE; 1224 vpcl = value; 1225 rset = TRUE; 1226 1227 info->target = (bfd_vma) (memaddr & ~3) + value; 1228 } 1229 else if (!(operand->flags & ARC_OPERAND_IR)) 1230 { 1231 vpcl = value; 1232 rset = TRUE; 1233 } 1234 1235 /* Print the operand as directed by the flags. */ 1236 if (operand->flags & ARC_OPERAND_IR) 1237 { 1238 const char *rname; 1239 1240 assert (value >=0 && value < 64); 1241 rname = arcExtMap_coreRegName (value); 1242 if (!rname) 1243 rname = regnames[value]; 1244 (*info->fprintf_func) (info->stream, "%s", rname); 1245 if (operand->flags & ARC_OPERAND_TRUNCATE) 1246 { 1247 rname = arcExtMap_coreRegName (value + 1); 1248 if (!rname) 1249 rname = regnames[value + 1]; 1250 (*info->fprintf_func) (info->stream, "%s", rname); 1251 } 1252 if (value == 63) 1253 rpcl = TRUE; 1254 else 1255 rpcl = FALSE; 1256 } 1257 else if (operand->flags & ARC_OPERAND_LIMM) 1258 { 1259 const char *rname = get_auxreg (opcode, value, isa_mask); 1260 1261 if (rname && open_braket) 1262 (*info->fprintf_func) (info->stream, "%s", rname); 1263 else 1264 { 1265 (*info->fprintf_func) (info->stream, "%#x", value); 1266 if (info->insn_type == dis_branch 1267 || info->insn_type == dis_jsr) 1268 info->target = (bfd_vma) value; 1269 } 1270 } 1271 else if (operand->flags & ARC_OPERAND_SIGNED) 1272 { 1273 const char *rname = get_auxreg (opcode, value, isa_mask); 1274 if (rname && open_braket) 1275 (*info->fprintf_func) (info->stream, "%s", rname); 1276 else 1277 { 1278 if (print_hex) 1279 (*info->fprintf_func) (info->stream, "%#x", value); 1280 else 1281 (*info->fprintf_func) (info->stream, "%d", value); 1282 } 1283 } 1284 else if (operand->flags & ARC_OPERAND_ADDRTYPE) 1285 { 1286 const char *addrtype = get_addrtype (value); 1287 (*info->fprintf_func) (info->stream, "%s", addrtype); 1288 /* A colon follow an address type. */ 1289 need_comma = FALSE; 1290 } 1291 else 1292 { 1293 if (operand->flags & ARC_OPERAND_TRUNCATE 1294 && !(operand->flags & ARC_OPERAND_ALIGNED32) 1295 && !(operand->flags & ARC_OPERAND_ALIGNED16) 1296 && value >= 0 && value <= 14) 1297 { 1298 /* Leave/Enter mnemonics. */ 1299 switch (value) 1300 { 1301 case 0: 1302 need_comma = FALSE; 1303 break; 1304 case 1: 1305 (*info->fprintf_func) (info->stream, "r13"); 1306 break; 1307 default: 1308 (*info->fprintf_func) (info->stream, "r13-%s", 1309 regnames[13 + value - 1]); 1310 break; 1311 } 1312 rpcl = FALSE; 1313 rset = FALSE; 1314 } 1315 else 1316 { 1317 const char *rname = get_auxreg (opcode, value, isa_mask); 1318 if (rname && open_braket) 1319 (*info->fprintf_func) (info->stream, "%s", rname); 1320 else 1321 (*info->fprintf_func) (info->stream, "%#x", value); 1322 } 1323 } 1324 1325 if (operand->flags & ARC_OPERAND_LIMM) 1326 { 1327 arc_infop->operands[arc_infop->operands_count].kind 1328 = ARC_OPERAND_KIND_LIMM; 1329 /* It is not important to have exactly the LIMM indicator 1330 here. */ 1331 arc_infop->operands[arc_infop->operands_count].value = 63; 1332 } 1333 else 1334 { 1335 arc_infop->operands[arc_infop->operands_count].value = value; 1336 arc_infop->operands[arc_infop->operands_count].kind 1337 = (operand->flags & ARC_OPERAND_IR 1338 ? ARC_OPERAND_KIND_REG 1339 : ARC_OPERAND_KIND_SHIMM); 1340 } 1341 arc_infop->operands_count ++; 1342 } 1343 1344 /* Pretty print extra info for pc-relative operands. */ 1345 if (rpcl && rset) 1346 { 1347 if (info->flags & INSN_HAS_RELOC) 1348 /* If the instruction has a reloc associated with it, then the 1349 offset field in the instruction will actually be the addend 1350 for the reloc. (We are using REL type relocs). In such 1351 cases, we can ignore the pc when computing addresses, since 1352 the addend is not currently pc-relative. */ 1353 memaddr = 0; 1354 1355 (*info->fprintf_func) (info->stream, "\t;"); 1356 (*info->print_address_func) ((memaddr & ~3) + vpcl, info); 1357 } 1358 1359 return insn_len; 1360 } 1361 1362 1363 disassembler_ftype 1364 arc_get_disassembler (bfd *abfd) 1365 { 1366 /* BFD my be absent, if opcodes is invoked from the debugger that 1367 has connected to remote target and doesn't have an ELF file. */ 1368 if (abfd != NULL) 1369 { 1370 /* Read the extension insns and registers, if any. */ 1371 build_ARC_extmap (abfd); 1372 #ifdef DEBUG 1373 dump_ARC_extmap (); 1374 #endif 1375 } 1376 1377 return print_insn_arc; 1378 } 1379 1380 void 1381 print_arc_disassembler_options (FILE *stream) 1382 { 1383 int i; 1384 1385 fprintf (stream, _("\n\ 1386 The following ARC specific disassembler options are supported for use \n\ 1387 with -M switch (multiple options should be separated by commas):\n")); 1388 1389 /* cpu=... options. */ 1390 for (i = 0; cpu_types[i].name; ++i) 1391 { 1392 /* As of now all value CPU values are less than 16 characters. */ 1393 fprintf (stream, " cpu=%-16s\tEnforce %s ISA.\n", 1394 cpu_types[i].name, cpu_types[i].isa); 1395 } 1396 1397 fprintf (stream, _("\ 1398 dsp Recognize DSP instructions.\n")); 1399 fprintf (stream, _("\ 1400 spfp Recognize FPX SP instructions.\n")); 1401 fprintf (stream, _("\ 1402 dpfp Recognize FPX DP instructions.\n")); 1403 fprintf (stream, _("\ 1404 quarkse_em Recognize FPU QuarkSE-EM instructions.\n")); 1405 fprintf (stream, _("\ 1406 fpuda Recognize double assist FPU instructions.\n")); 1407 fprintf (stream, _("\ 1408 fpus Recognize single precision FPU instructions.\n")); 1409 fprintf (stream, _("\ 1410 fpud Recognize double precision FPU instructions.\n")); 1411 fprintf (stream, _("\ 1412 hex Use only hexadecimal number to print immediates.\n")); 1413 } 1414 1415 void arc_insn_decode (bfd_vma addr, 1416 struct disassemble_info *info, 1417 disassembler_ftype disasm_func, 1418 struct arc_instruction *insn) 1419 { 1420 const struct arc_opcode *opcode; 1421 struct arc_disassemble_info *arc_infop; 1422 1423 /* Ensure that insn would be in the reset state. */ 1424 memset (insn, 0, sizeof (struct arc_instruction)); 1425 1426 /* There was an error when disassembling, for example memory read error. */ 1427 if (disasm_func (addr, info) < 0) 1428 { 1429 insn->valid = FALSE; 1430 return; 1431 } 1432 1433 assert (info->private_data != NULL); 1434 arc_infop = info->private_data; 1435 1436 insn->length = arc_infop->insn_len;; 1437 insn->address = addr; 1438 1439 /* Quick exit if memory at this address is not an instruction. */ 1440 if (info->insn_type == dis_noninsn) 1441 { 1442 insn->valid = FALSE; 1443 return; 1444 } 1445 1446 insn->valid = TRUE; 1447 1448 opcode = (const struct arc_opcode *) arc_infop->opcode; 1449 insn->insn_class = opcode->insn_class; 1450 insn->limm_value = arc_infop->limm; 1451 insn->limm_p = arc_infop->limm_p; 1452 1453 insn->is_control_flow = (info->insn_type == dis_branch 1454 || info->insn_type == dis_condbranch 1455 || info->insn_type == dis_jsr 1456 || info->insn_type == dis_condjsr); 1457 1458 insn->has_delay_slot = info->branch_delay_insns; 1459 insn->writeback_mode 1460 = (enum arc_ldst_writeback_mode) arc_infop->writeback_mode; 1461 insn->data_size_mode = info->data_size; 1462 insn->condition_code = arc_infop->condition_code; 1463 memcpy (insn->operands, arc_infop->operands, 1464 sizeof (struct arc_insn_operand) * MAX_INSN_ARGS); 1465 insn->operands_count = arc_infop->operands_count; 1466 } 1467 1468 /* Local variables: 1469 eval: (c-set-style "gnu") 1470 indent-tabs-mode: t 1471 End: */ 1472