1 /* Instruction printing code for the ARC. 2 Copyright (C) 1994-2017 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 /* Macros section. */ 121 122 #ifdef DEBUG 123 # define pr_debug(fmt, args...) fprintf (stderr, fmt, ##args) 124 #else 125 # define pr_debug(fmt, args...) 126 #endif 127 128 #define ARRANGE_ENDIAN(info, buf) \ 129 (info->endian == BFD_ENDIAN_LITTLE ? bfd_getm32 (bfd_getl32 (buf)) \ 130 : bfd_getb32 (buf)) 131 132 #define BITS(word,s,e) (((word) << (sizeof (word) * 8 - 1 - e)) >> \ 133 (s + (sizeof (word) * 8 - 1 - e))) 134 #define OPCODE_32BIT_INSN(word) (BITS ((word), 27, 31)) 135 136 /* Functions implementation. */ 137 138 /* Initialize private data. */ 139 static bfd_boolean 140 init_arc_disasm_info (struct disassemble_info *info) 141 { 142 struct arc_disassemble_info *arc_infop 143 = calloc (sizeof (*arc_infop), 1); 144 145 if (arc_infop == NULL) 146 return FALSE; 147 148 info->private_data = arc_infop; 149 return TRUE; 150 } 151 152 /* Add a new element to the decode list. */ 153 154 static void 155 add_to_decodelist (insn_class_t insn_class, 156 insn_subclass_t subclass) 157 { 158 linkclass t = (linkclass) xmalloc (sizeof (skipclass_t)); 159 160 t->insn_class = insn_class; 161 t->subclass = subclass; 162 t->nxt = decodelist; 163 decodelist = t; 164 } 165 166 /* Return TRUE if we need to skip the opcode from being 167 disassembled. */ 168 169 static bfd_boolean 170 skip_this_opcode (const struct arc_opcode *opcode) 171 { 172 linkclass t = decodelist; 173 174 /* Check opcode for major 0x06, return if it is not in. */ 175 if (arc_opcode_len (opcode) == 4 176 && OPCODE_32BIT_INSN (opcode->opcode) != 0x06) 177 return FALSE; 178 179 /* or not a known truble class. */ 180 switch (opcode->insn_class) 181 { 182 case FLOAT: 183 case DSP: 184 break; 185 default: 186 return FALSE; 187 } 188 189 while (t != NULL) 190 { 191 if ((t->insn_class == opcode->insn_class) 192 && (t->subclass == opcode->subclass)) 193 return FALSE; 194 t = t->nxt; 195 } 196 197 return TRUE; 198 } 199 200 static bfd_vma 201 bfd_getm32 (unsigned int data) 202 { 203 bfd_vma value = 0; 204 205 value = ((data & 0xff00) | (data & 0xff)) << 16; 206 value |= ((data & 0xff0000) | (data & 0xff000000)) >> 16; 207 return value; 208 } 209 210 static bfd_boolean 211 special_flag_p (const char *opname, 212 const char *flgname) 213 { 214 const struct arc_flag_special *flg_spec; 215 unsigned i, j, flgidx; 216 217 for (i = 0; i < arc_num_flag_special; i++) 218 { 219 flg_spec = &arc_flag_special_cases[i]; 220 221 if (strcmp (opname, flg_spec->name)) 222 continue; 223 224 /* Found potential special case instruction. */ 225 for (j=0;; ++j) 226 { 227 flgidx = flg_spec->flags[j]; 228 if (flgidx == 0) 229 break; /* End of the array. */ 230 231 if (strcmp (flgname, arc_flag_operands[flgidx].name) == 0) 232 return TRUE; 233 } 234 } 235 return FALSE; 236 } 237 238 /* Find opcode from ARC_TABLE given the instruction described by INSN and 239 INSNLEN. The ISA_MASK restricts the possible matches in ARC_TABLE. */ 240 241 static const struct arc_opcode * 242 find_format_from_table (struct disassemble_info *info, 243 const struct arc_opcode *arc_table, 244 unsigned long long insn, 245 unsigned int insn_len, 246 unsigned isa_mask, 247 bfd_boolean *has_limm, 248 bfd_boolean overlaps) 249 { 250 unsigned int i = 0; 251 const struct arc_opcode *opcode = NULL; 252 const struct arc_opcode *t_op = NULL; 253 const unsigned char *opidx; 254 const unsigned char *flgidx; 255 bfd_boolean warn_p = FALSE; 256 257 do 258 { 259 bfd_boolean invalid = FALSE; 260 261 opcode = &arc_table[i++]; 262 263 if (!(opcode->cpu & isa_mask)) 264 continue; 265 266 if (arc_opcode_len (opcode) != (int) insn_len) 267 continue; 268 269 if ((insn & opcode->mask) != opcode->opcode) 270 continue; 271 272 *has_limm = FALSE; 273 274 /* Possible candidate, check the operands. */ 275 for (opidx = opcode->operands; *opidx; opidx++) 276 { 277 int value, limmind; 278 const struct arc_operand *operand = &arc_operands[*opidx]; 279 280 if (operand->flags & ARC_OPERAND_FAKE) 281 continue; 282 283 if (operand->extract) 284 value = (*operand->extract) (insn, &invalid); 285 else 286 value = (insn >> operand->shift) & ((1 << operand->bits) - 1); 287 288 /* Check for LIMM indicator. If it is there, then make sure 289 we pick the right format. */ 290 limmind = (isa_mask & ARC_OPCODE_ARCV2) ? 0x1E : 0x3E; 291 if (operand->flags & ARC_OPERAND_IR 292 && !(operand->flags & ARC_OPERAND_LIMM)) 293 { 294 if ((value == 0x3E && insn_len == 4) 295 || (value == limmind && insn_len == 2)) 296 { 297 invalid = TRUE; 298 break; 299 } 300 } 301 302 if (operand->flags & ARC_OPERAND_LIMM 303 && !(operand->flags & ARC_OPERAND_DUPLICATE)) 304 *has_limm = TRUE; 305 } 306 307 /* Check the flags. */ 308 for (flgidx = opcode->flags; *flgidx; flgidx++) 309 { 310 /* Get a valid flag class. */ 311 const struct arc_flag_class *cl_flags = &arc_flag_classes[*flgidx]; 312 const unsigned *flgopridx; 313 int foundA = 0, foundB = 0; 314 unsigned int value; 315 316 /* Check first the extensions. */ 317 if (cl_flags->flag_class & F_CLASS_EXTEND) 318 { 319 value = (insn & 0x1F); 320 if (arcExtMap_condCodeName (value)) 321 continue; 322 } 323 324 /* Check for the implicit flags. */ 325 if (cl_flags->flag_class & F_CLASS_IMPLICIT) 326 continue; 327 328 for (flgopridx = cl_flags->flags; *flgopridx; ++flgopridx) 329 { 330 const struct arc_flag_operand *flg_operand = 331 &arc_flag_operands[*flgopridx]; 332 333 value = (insn >> flg_operand->shift) 334 & ((1 << flg_operand->bits) - 1); 335 if (value == flg_operand->code) 336 foundA = 1; 337 if (value) 338 foundB = 1; 339 } 340 341 if (!foundA && foundB) 342 { 343 invalid = TRUE; 344 break; 345 } 346 } 347 348 if (invalid) 349 continue; 350 351 if (insn_len == 4 352 && overlaps) 353 { 354 warn_p = TRUE; 355 t_op = opcode; 356 if (skip_this_opcode (opcode)) 357 continue; 358 } 359 360 /* The instruction is valid. */ 361 return opcode; 362 } 363 while (opcode->mask); 364 365 if (warn_p) 366 { 367 info->fprintf_func (info->stream, 368 _("\nWarning: disassembly may be wrong due to " 369 "guessed opcode class choice.\n" 370 "Use -M<class[,class]> to select the correct " 371 "opcode class(es).\n\t\t\t\t")); 372 return t_op; 373 } 374 375 return NULL; 376 } 377 378 /* Find opcode for INSN, trying various different sources. The instruction 379 length in INSN_LEN will be updated if the instruction requires a LIMM 380 extension. 381 382 A pointer to the opcode is placed into OPCODE_RESULT, and ITER is 383 initialised, ready to iterate over the operands of the found opcode. If 384 the found opcode requires a LIMM then the LIMM value will be loaded into a 385 field of ITER. 386 387 This function returns TRUE in almost all cases, FALSE is reserved to 388 indicate an error (failing to find an opcode is not an error) a returned 389 result of FALSE would indicate that the disassembler can't continue. 390 391 If no matching opcode is found then the returned result will be TRUE, the 392 value placed into OPCODE_RESULT will be NULL, ITER will be undefined, and 393 INSN_LEN will be unchanged. 394 395 If a matching opcode is found, then the returned result will be TRUE, the 396 opcode pointer is placed into OPCODE_RESULT, INSN_LEN will be increased by 397 4 if the instruction requires a LIMM, and the LIMM value will have been 398 loaded into a field of ITER. Finally, ITER will have been initialised so 399 that calls to OPERAND_ITERATOR_NEXT will iterate over the opcode's 400 operands. */ 401 402 static bfd_boolean 403 find_format (bfd_vma memaddr, 404 unsigned long long insn, 405 unsigned int * insn_len, 406 unsigned isa_mask, 407 struct disassemble_info * info, 408 const struct arc_opcode ** opcode_result, 409 struct arc_operand_iterator * iter) 410 { 411 const struct arc_opcode *opcode = NULL; 412 bfd_boolean needs_limm; 413 const extInstruction_t *einsn, *i; 414 unsigned limm = 0; 415 struct arc_disassemble_info *arc_infop = info->private_data; 416 417 /* First, try the extension instructions. */ 418 if (*insn_len == 4) 419 { 420 einsn = arcExtMap_insn (OPCODE_32BIT_INSN (insn), insn); 421 for (i = einsn; (i != NULL) && (opcode == NULL); i = i->next) 422 { 423 const char *errmsg = NULL; 424 425 opcode = arcExtMap_genOpcode (i, isa_mask, &errmsg); 426 if (opcode == NULL) 427 { 428 (*info->fprintf_func) (info->stream, "\ 429 An error occured while generating the extension instruction operations"); 430 *opcode_result = NULL; 431 return FALSE; 432 } 433 434 opcode = find_format_from_table (info, opcode, insn, *insn_len, 435 isa_mask, &needs_limm, FALSE); 436 } 437 } 438 439 /* Then, try finding the first match in the opcode table. */ 440 if (opcode == NULL) 441 opcode = find_format_from_table (info, arc_opcodes, insn, *insn_len, 442 isa_mask, &needs_limm, TRUE); 443 444 if (needs_limm && opcode != NULL) 445 { 446 bfd_byte buffer[4]; 447 int status; 448 449 status = (*info->read_memory_func) (memaddr + *insn_len, buffer, 450 4, info); 451 if (status != 0) 452 { 453 opcode = NULL; 454 } 455 else 456 { 457 limm = ARRANGE_ENDIAN (info, buffer); 458 *insn_len += 4; 459 } 460 } 461 462 if (opcode != NULL) 463 { 464 iter->insn = insn; 465 iter->limm = limm; 466 iter->opcode = opcode; 467 iter->opidx = opcode->operands; 468 } 469 470 *opcode_result = opcode; 471 472 /* Update private data. */ 473 arc_infop->opcode = opcode; 474 arc_infop->limm = (needs_limm) ? limm : 0; 475 arc_infop->limm_p = needs_limm; 476 477 return TRUE; 478 } 479 480 static void 481 print_flags (const struct arc_opcode *opcode, 482 unsigned long long *insn, 483 struct disassemble_info *info) 484 { 485 const unsigned char *flgidx; 486 unsigned int value; 487 struct arc_disassemble_info *arc_infop = info->private_data; 488 489 /* Now extract and print the flags. */ 490 for (flgidx = opcode->flags; *flgidx; flgidx++) 491 { 492 /* Get a valid flag class. */ 493 const struct arc_flag_class *cl_flags = &arc_flag_classes[*flgidx]; 494 const unsigned *flgopridx; 495 496 /* Check first the extensions. */ 497 if (cl_flags->flag_class & F_CLASS_EXTEND) 498 { 499 const char *name; 500 value = (insn[0] & 0x1F); 501 502 name = arcExtMap_condCodeName (value); 503 if (name) 504 { 505 (*info->fprintf_func) (info->stream, ".%s", name); 506 continue; 507 } 508 } 509 510 for (flgopridx = cl_flags->flags; *flgopridx; ++flgopridx) 511 { 512 const struct arc_flag_operand *flg_operand = 513 &arc_flag_operands[*flgopridx]; 514 515 /* Implicit flags are only used for the insn decoder. */ 516 if (cl_flags->flag_class & F_CLASS_IMPLICIT) 517 { 518 if (cl_flags->flag_class & F_CLASS_COND) 519 arc_infop->condition_code = flg_operand->code; 520 else if (cl_flags->flag_class & F_CLASS_WB) 521 arc_infop->writeback_mode = flg_operand->code; 522 else if (cl_flags->flag_class & F_CLASS_ZZ) 523 info->data_size = flg_operand->code; 524 continue; 525 } 526 527 if (!flg_operand->favail) 528 continue; 529 530 value = (insn[0] >> flg_operand->shift) 531 & ((1 << flg_operand->bits) - 1); 532 if (value == flg_operand->code) 533 { 534 /* FIXME!: print correctly nt/t flag. */ 535 if (!special_flag_p (opcode->name, flg_operand->name)) 536 (*info->fprintf_func) (info->stream, "."); 537 else if (info->insn_type == dis_dref) 538 { 539 switch (flg_operand->name[0]) 540 { 541 case 'b': 542 info->data_size = 1; 543 break; 544 case 'h': 545 case 'w': 546 info->data_size = 2; 547 break; 548 default: 549 info->data_size = 4; 550 break; 551 } 552 } 553 if (flg_operand->name[0] == 'd' 554 && flg_operand->name[1] == 0) 555 info->branch_delay_insns = 1; 556 557 /* Check if it is a conditional flag. */ 558 if (cl_flags->flag_class & F_CLASS_COND) 559 { 560 if (info->insn_type == dis_jsr) 561 info->insn_type = dis_condjsr; 562 else if (info->insn_type == dis_branch) 563 info->insn_type = dis_condbranch; 564 arc_infop->condition_code = flg_operand->code; 565 } 566 567 /* Check for the write back modes. */ 568 if (cl_flags->flag_class & F_CLASS_WB) 569 arc_infop->writeback_mode = flg_operand->code; 570 571 (*info->fprintf_func) (info->stream, "%s", flg_operand->name); 572 } 573 } 574 } 575 } 576 577 static const char * 578 get_auxreg (const struct arc_opcode *opcode, 579 int value, 580 unsigned isa_mask) 581 { 582 const char *name; 583 unsigned int i; 584 const struct arc_aux_reg *auxr = &arc_aux_regs[0]; 585 586 if (opcode->insn_class != AUXREG) 587 return NULL; 588 589 name = arcExtMap_auxRegName (value); 590 if (name) 591 return name; 592 593 for (i = 0; i < arc_num_aux_regs; i++, auxr++) 594 { 595 if (!(auxr->cpu & isa_mask)) 596 continue; 597 598 if (auxr->subclass != NONE) 599 return NULL; 600 601 if (auxr->address == value) 602 return auxr->name; 603 } 604 return NULL; 605 } 606 607 /* Convert a value representing an address type to a string used to refer to 608 the address type in assembly code. */ 609 610 static const char * 611 get_addrtype (int value) 612 { 613 if (value < 0 || value > addrtypenames_max) 614 return addrtypeunknown; 615 616 return addrtypenames[value]; 617 } 618 619 /* Calculate the instruction length for an instruction starting with MSB 620 and LSB, the most and least significant byte. The ISA_MASK is used to 621 filter the instructions considered to only those that are part of the 622 current architecture. 623 624 The instruction lengths are calculated from the ARC_OPCODE table, and 625 cached for later use. */ 626 627 static unsigned int 628 arc_insn_length (bfd_byte msb, bfd_byte lsb, struct disassemble_info *info) 629 { 630 bfd_byte major_opcode = msb >> 3; 631 632 switch (info->mach) 633 { 634 case bfd_mach_arc_arc700: 635 /* The nps400 extension set requires this special casing of the 636 instruction length calculation. Right now this is not causing any 637 problems as none of the known extensions overlap in opcode space, 638 but, if they ever do then we might need to start carrying 639 information around in the elf about which extensions are in use. */ 640 if (major_opcode == 0xb) 641 { 642 bfd_byte minor_opcode = lsb & 0x1f; 643 644 if (minor_opcode < 4) 645 return 6; 646 else if (minor_opcode == 0x10 || minor_opcode == 0x11) 647 return 8; 648 } 649 if (major_opcode == 0xa) 650 { 651 return 8; 652 } 653 /* Fall through. */ 654 case bfd_mach_arc_arc600: 655 return (major_opcode > 0xb) ? 2 : 4; 656 break; 657 658 case bfd_mach_arc_arcv2: 659 return (major_opcode > 0x7) ? 2 : 4; 660 break; 661 662 default: 663 abort (); 664 } 665 } 666 667 /* Extract and return the value of OPERAND from the instruction whose value 668 is held in the array INSN. */ 669 670 static int 671 extract_operand_value (const struct arc_operand *operand, 672 unsigned long long insn, 673 unsigned limm) 674 { 675 int value; 676 677 /* Read the limm operand, if required. */ 678 if (operand->flags & ARC_OPERAND_LIMM) 679 /* The second part of the instruction value will have been loaded as 680 part of the find_format call made earlier. */ 681 value = limm; 682 else 683 { 684 if (operand->extract) 685 value = (*operand->extract) (insn, (int *) NULL); 686 else 687 { 688 if (operand->flags & ARC_OPERAND_ALIGNED32) 689 { 690 value = (insn >> operand->shift) 691 & ((1 << (operand->bits - 2)) - 1); 692 value = value << 2; 693 } 694 else 695 { 696 value = (insn >> operand->shift) & ((1 << operand->bits) - 1); 697 } 698 if (operand->flags & ARC_OPERAND_SIGNED) 699 { 700 int signbit = 1 << (operand->bits - 1); 701 value = (value ^ signbit) - signbit; 702 } 703 } 704 } 705 706 return value; 707 } 708 709 /* Find the next operand, and the operands value from ITER. Return TRUE if 710 there is another operand, otherwise return FALSE. If there is an 711 operand returned then the operand is placed into OPERAND, and the value 712 into VALUE. If there is no operand returned then OPERAND and VALUE are 713 unchanged. */ 714 715 static bfd_boolean 716 operand_iterator_next (struct arc_operand_iterator *iter, 717 const struct arc_operand **operand, 718 int *value) 719 { 720 if (*iter->opidx == 0) 721 { 722 *operand = NULL; 723 return FALSE; 724 } 725 726 *operand = &arc_operands[*iter->opidx]; 727 *value = extract_operand_value (*operand, iter->insn, iter->limm); 728 iter->opidx++; 729 730 return TRUE; 731 } 732 733 /* Helper for parsing the options. */ 734 735 static void 736 parse_option (const char *option) 737 { 738 if (CONST_STRNEQ (option, "dsp")) 739 add_to_decodelist (DSP, NONE); 740 741 else if (CONST_STRNEQ (option, "spfp")) 742 add_to_decodelist (FLOAT, SPX); 743 744 else if (CONST_STRNEQ (option, "dpfp")) 745 add_to_decodelist (FLOAT, DPX); 746 747 else if (CONST_STRNEQ (option, "quarkse_em")) 748 { 749 add_to_decodelist (FLOAT, DPX); 750 add_to_decodelist (FLOAT, SPX); 751 add_to_decodelist (FLOAT, QUARKSE); 752 } 753 754 else if (CONST_STRNEQ (option, "fpuda")) 755 add_to_decodelist (FLOAT, DPA); 756 757 else if (CONST_STRNEQ (option, "fpus")) 758 { 759 add_to_decodelist (FLOAT, SP); 760 add_to_decodelist (FLOAT, CVT); 761 } 762 763 else if (CONST_STRNEQ (option, "fpud")) 764 { 765 add_to_decodelist (FLOAT, DP); 766 add_to_decodelist (FLOAT, CVT); 767 } 768 else 769 fprintf (stderr, _("Unrecognised disassembler option: %s\n"), option); 770 } 771 772 /* Go over the options list and parse it. */ 773 774 static void 775 parse_disassembler_options (const char *options) 776 { 777 if (options == NULL) 778 return; 779 780 while (*options) 781 { 782 /* Skip empty options. */ 783 if (*options == ',') 784 { 785 ++ options; 786 continue; 787 } 788 789 parse_option (options); 790 791 while (*options != ',' && *options != '\0') 792 ++ options; 793 } 794 } 795 796 /* Return the instruction type for an instruction described by OPCODE. */ 797 798 static enum dis_insn_type 799 arc_opcode_to_insn_type (const struct arc_opcode *opcode) 800 { 801 enum dis_insn_type insn_type; 802 803 switch (opcode->insn_class) 804 { 805 case BRANCH: 806 case BBIT0: 807 case BBIT1: 808 case BI: 809 case BIH: 810 case BRCC: 811 case EI: 812 case JLI: 813 case JUMP: 814 case LOOP: 815 if (!strncmp (opcode->name, "bl", 2) 816 || !strncmp (opcode->name, "jl", 2)) 817 { 818 if (opcode->subclass == COND) 819 insn_type = dis_condjsr; 820 else 821 insn_type = dis_jsr; 822 } 823 else 824 { 825 if (opcode->subclass == COND) 826 insn_type = dis_condbranch; 827 else 828 insn_type = dis_branch; 829 } 830 break; 831 case LOAD: 832 case STORE: 833 case MEMORY: 834 case ENTER: 835 case PUSH: 836 case POP: 837 insn_type = dis_dref; 838 break; 839 case LEAVE: 840 insn_type = dis_branch; 841 break; 842 default: 843 insn_type = dis_nonbranch; 844 break; 845 } 846 847 return insn_type; 848 } 849 850 /* Disassemble ARC instructions. */ 851 852 static int 853 print_insn_arc (bfd_vma memaddr, 854 struct disassemble_info *info) 855 { 856 bfd_byte buffer[8]; 857 unsigned int highbyte, lowbyte; 858 int status; 859 unsigned int insn_len; 860 unsigned long long insn = 0; 861 unsigned isa_mask; 862 const struct arc_opcode *opcode; 863 bfd_boolean need_comma; 864 bfd_boolean open_braket; 865 int size; 866 const struct arc_operand *operand; 867 int value; 868 struct arc_operand_iterator iter; 869 Elf_Internal_Ehdr *header = NULL; 870 struct arc_disassemble_info *arc_infop; 871 872 if (info->disassembler_options) 873 { 874 parse_disassembler_options (info->disassembler_options); 875 876 /* Avoid repeated parsing of the options. */ 877 info->disassembler_options = NULL; 878 } 879 880 if (info->private_data == NULL && !init_arc_disasm_info (info)) 881 return -1; 882 883 memset (&iter, 0, sizeof (iter)); 884 highbyte = ((info->endian == BFD_ENDIAN_LITTLE) ? 1 : 0); 885 lowbyte = ((info->endian == BFD_ENDIAN_LITTLE) ? 0 : 1); 886 887 if (info->section && info->section->owner) 888 header = elf_elfheader (info->section->owner); 889 890 switch (info->mach) 891 { 892 case bfd_mach_arc_arc700: 893 isa_mask = ARC_OPCODE_ARC700; 894 break; 895 896 case bfd_mach_arc_arc600: 897 isa_mask = ARC_OPCODE_ARC600; 898 break; 899 900 case bfd_mach_arc_arcv2: 901 default: 902 isa_mask = ARC_OPCODE_ARCv2EM; 903 /* TODO: Perhaps remove defitinion of header since it is only used at 904 this location. */ 905 if (header != NULL 906 && (header->e_flags & EF_ARC_MACH_MSK) == EF_ARC_CPU_ARCV2HS) 907 { 908 isa_mask = ARC_OPCODE_ARCv2HS; 909 /* FPU instructions are not extensions for HS. */ 910 add_to_decodelist (FLOAT, SP); 911 add_to_decodelist (FLOAT, DP); 912 add_to_decodelist (FLOAT, CVT); 913 } 914 break; 915 } 916 917 /* This variable may be set by the instruction decoder. It suggests 918 the number of bytes objdump should display on a single line. If 919 the instruction decoder sets this, it should always set it to 920 the same value in order to get reasonable looking output. */ 921 922 info->bytes_per_line = 8; 923 924 /* In the next lines, we set two info variables control the way 925 objdump displays the raw data. For example, if bytes_per_line is 926 8 and bytes_per_chunk is 4, the output will look like this: 927 00: 00000000 00000000 928 with the chunks displayed according to "display_endian". */ 929 930 if (info->section 931 && !(info->section->flags & SEC_CODE)) 932 { 933 /* This is not a CODE section. */ 934 switch (info->section->size) 935 { 936 case 1: 937 case 2: 938 case 4: 939 size = info->section->size; 940 break; 941 default: 942 size = (info->section->size & 0x01) ? 1 : 4; 943 break; 944 } 945 info->bytes_per_chunk = 1; 946 info->display_endian = info->endian; 947 } 948 else 949 { 950 size = 2; 951 info->bytes_per_chunk = 2; 952 info->display_endian = info->endian; 953 } 954 955 /* Read the insn into a host word. */ 956 status = (*info->read_memory_func) (memaddr, buffer, size, info); 957 if (status != 0) 958 { 959 (*info->memory_error_func) (status, memaddr, info); 960 return -1; 961 } 962 963 if (info->section 964 && !(info->section->flags & SEC_CODE)) 965 { 966 /* Data section. */ 967 unsigned long data; 968 969 data = bfd_get_bits (buffer, size * 8, 970 info->display_endian == BFD_ENDIAN_BIG); 971 switch (size) 972 { 973 case 1: 974 (*info->fprintf_func) (info->stream, ".byte\t0x%02lx", data); 975 break; 976 case 2: 977 (*info->fprintf_func) (info->stream, ".short\t0x%04lx", data); 978 break; 979 case 4: 980 (*info->fprintf_func) (info->stream, ".word\t0x%08lx", data); 981 break; 982 default: 983 abort (); 984 } 985 return size; 986 } 987 988 insn_len = arc_insn_length (buffer[highbyte], buffer[lowbyte], info); 989 pr_debug ("instruction length = %d bytes\n", insn_len); 990 arc_infop = info->private_data; 991 arc_infop->insn_len = insn_len; 992 993 switch (insn_len) 994 { 995 case 2: 996 insn = (buffer[highbyte] << 8) | buffer[lowbyte]; 997 break; 998 999 case 4: 1000 { 1001 /* This is a long instruction: Read the remaning 2 bytes. */ 1002 status = (*info->read_memory_func) (memaddr + 2, &buffer[2], 2, info); 1003 if (status != 0) 1004 { 1005 (*info->memory_error_func) (status, memaddr + 2, info); 1006 return -1; 1007 } 1008 insn = (unsigned long long) ARRANGE_ENDIAN (info, buffer); 1009 } 1010 break; 1011 1012 case 6: 1013 { 1014 status = (*info->read_memory_func) (memaddr + 2, &buffer[2], 4, info); 1015 if (status != 0) 1016 { 1017 (*info->memory_error_func) (status, memaddr + 2, info); 1018 return -1; 1019 } 1020 insn = (unsigned long long) ARRANGE_ENDIAN (info, &buffer[2]); 1021 insn |= ((unsigned long long) buffer[highbyte] << 40) 1022 | ((unsigned long long) buffer[lowbyte] << 32); 1023 } 1024 break; 1025 1026 case 8: 1027 { 1028 status = (*info->read_memory_func) (memaddr + 2, &buffer[2], 6, info); 1029 if (status != 0) 1030 { 1031 (*info->memory_error_func) (status, memaddr + 2, info); 1032 return -1; 1033 } 1034 insn = 1035 ((((unsigned long long) ARRANGE_ENDIAN (info, buffer)) << 32) 1036 | ((unsigned long long) ARRANGE_ENDIAN (info, &buffer[4]))); 1037 } 1038 break; 1039 1040 default: 1041 /* There is no instruction whose length is not 2, 4, 6, or 8. */ 1042 abort (); 1043 } 1044 1045 pr_debug ("instruction value = %llx\n", insn); 1046 1047 /* Set some defaults for the insn info. */ 1048 info->insn_info_valid = 1; 1049 info->branch_delay_insns = 0; 1050 info->data_size = 4; 1051 info->insn_type = dis_nonbranch; 1052 info->target = 0; 1053 info->target2 = 0; 1054 1055 /* FIXME to be moved in dissasemble_init_for_target. */ 1056 info->disassembler_needs_relocs = TRUE; 1057 1058 /* Find the first match in the opcode table. */ 1059 if (!find_format (memaddr, insn, &insn_len, isa_mask, info, &opcode, &iter)) 1060 return -1; 1061 1062 if (!opcode) 1063 { 1064 switch (insn_len) 1065 { 1066 case 2: 1067 (*info->fprintf_func) (info->stream, ".long %#04llx", 1068 insn & 0xffff); 1069 break; 1070 case 4: 1071 (*info->fprintf_func) (info->stream, ".long %#08llx", 1072 insn & 0xffffffff); 1073 break; 1074 case 6: 1075 (*info->fprintf_func) (info->stream, ".long %#08llx", 1076 insn & 0xffffffff); 1077 (*info->fprintf_func) (info->stream, ".long %#04llx", 1078 (insn >> 32) & 0xffff); 1079 break; 1080 case 8: 1081 (*info->fprintf_func) (info->stream, ".long %#08llx", 1082 insn & 0xffffffff); 1083 (*info->fprintf_func) (info->stream, ".long %#08llx", 1084 insn >> 32); 1085 break; 1086 default: 1087 abort (); 1088 } 1089 1090 info->insn_type = dis_noninsn; 1091 return insn_len; 1092 } 1093 1094 /* Print the mnemonic. */ 1095 (*info->fprintf_func) (info->stream, "%s", opcode->name); 1096 1097 /* Preselect the insn class. */ 1098 info->insn_type = arc_opcode_to_insn_type (opcode); 1099 1100 pr_debug ("%s: 0x%08llx\n", opcode->name, opcode->opcode); 1101 1102 print_flags (opcode, &insn, info); 1103 1104 if (opcode->operands[0] != 0) 1105 (*info->fprintf_func) (info->stream, "\t"); 1106 1107 need_comma = FALSE; 1108 open_braket = FALSE; 1109 arc_infop->operands_count = 0; 1110 1111 /* Now extract and print the operands. */ 1112 operand = NULL; 1113 while (operand_iterator_next (&iter, &operand, &value)) 1114 { 1115 if (open_braket && (operand->flags & ARC_OPERAND_BRAKET)) 1116 { 1117 (*info->fprintf_func) (info->stream, "]"); 1118 open_braket = FALSE; 1119 continue; 1120 } 1121 1122 /* Only take input from real operands. */ 1123 if (ARC_OPERAND_IS_FAKE (operand)) 1124 continue; 1125 1126 if ((operand->flags & ARC_OPERAND_IGNORE) 1127 && (operand->flags & ARC_OPERAND_IR) 1128 && value == -1) 1129 continue; 1130 1131 if (operand->flags & ARC_OPERAND_COLON) 1132 { 1133 (*info->fprintf_func) (info->stream, ":"); 1134 continue; 1135 } 1136 1137 if (need_comma) 1138 (*info->fprintf_func) (info->stream, ","); 1139 1140 if (!open_braket && (operand->flags & ARC_OPERAND_BRAKET)) 1141 { 1142 (*info->fprintf_func) (info->stream, "["); 1143 open_braket = TRUE; 1144 need_comma = FALSE; 1145 continue; 1146 } 1147 1148 need_comma = TRUE; 1149 1150 /* Print the operand as directed by the flags. */ 1151 if (operand->flags & ARC_OPERAND_IR) 1152 { 1153 const char *rname; 1154 1155 assert (value >=0 && value < 64); 1156 rname = arcExtMap_coreRegName (value); 1157 if (!rname) 1158 rname = regnames[value]; 1159 (*info->fprintf_func) (info->stream, "%s", rname); 1160 if (operand->flags & ARC_OPERAND_TRUNCATE) 1161 { 1162 rname = arcExtMap_coreRegName (value + 1); 1163 if (!rname) 1164 rname = regnames[value + 1]; 1165 (*info->fprintf_func) (info->stream, "%s", rname); 1166 } 1167 } 1168 else if (operand->flags & ARC_OPERAND_LIMM) 1169 { 1170 const char *rname = get_auxreg (opcode, value, isa_mask); 1171 1172 if (rname && open_braket) 1173 (*info->fprintf_func) (info->stream, "%s", rname); 1174 else 1175 { 1176 (*info->fprintf_func) (info->stream, "%#x", value); 1177 if (info->insn_type == dis_branch 1178 || info->insn_type == dis_jsr) 1179 info->target = (bfd_vma) value; 1180 } 1181 } 1182 else if (operand->flags & ARC_OPERAND_PCREL) 1183 { 1184 /* PCL relative. */ 1185 if (info->flags & INSN_HAS_RELOC) 1186 memaddr = 0; 1187 (*info->print_address_func) ((memaddr & ~3) + value, info); 1188 1189 info->target = (bfd_vma) (memaddr & ~3) + value; 1190 } 1191 else if (operand->flags & ARC_OPERAND_SIGNED) 1192 { 1193 const char *rname = get_auxreg (opcode, value, isa_mask); 1194 if (rname && open_braket) 1195 (*info->fprintf_func) (info->stream, "%s", rname); 1196 else 1197 (*info->fprintf_func) (info->stream, "%d", value); 1198 } 1199 else if (operand->flags & ARC_OPERAND_ADDRTYPE) 1200 { 1201 const char *addrtype = get_addrtype (value); 1202 (*info->fprintf_func) (info->stream, "%s", addrtype); 1203 /* A colon follow an address type. */ 1204 need_comma = FALSE; 1205 } 1206 else 1207 { 1208 if (operand->flags & ARC_OPERAND_TRUNCATE 1209 && !(operand->flags & ARC_OPERAND_ALIGNED32) 1210 && !(operand->flags & ARC_OPERAND_ALIGNED16) 1211 && value > 0 && value <= 14) 1212 (*info->fprintf_func) (info->stream, "r13-%s", 1213 regnames[13 + value - 1]); 1214 else 1215 { 1216 const char *rname = get_auxreg (opcode, value, isa_mask); 1217 if (rname && open_braket) 1218 (*info->fprintf_func) (info->stream, "%s", rname); 1219 else 1220 (*info->fprintf_func) (info->stream, "%#x", value); 1221 } 1222 } 1223 1224 if (operand->flags & ARC_OPERAND_LIMM) 1225 { 1226 arc_infop->operands[arc_infop->operands_count].kind 1227 = ARC_OPERAND_KIND_LIMM; 1228 /* It is not important to have exactly the LIMM indicator 1229 here. */ 1230 arc_infop->operands[arc_infop->operands_count].value = 63; 1231 } 1232 else 1233 { 1234 arc_infop->operands[arc_infop->operands_count].value = value; 1235 arc_infop->operands[arc_infop->operands_count].kind 1236 = (operand->flags & ARC_OPERAND_IR 1237 ? ARC_OPERAND_KIND_REG 1238 : ARC_OPERAND_KIND_SHIMM); 1239 } 1240 arc_infop->operands_count ++; 1241 } 1242 1243 return insn_len; 1244 } 1245 1246 1247 disassembler_ftype 1248 arc_get_disassembler (bfd *abfd) 1249 { 1250 /* BFD my be absent, if opcodes is invoked from the debugger that 1251 has connected to remote target and doesn't have an ELF file. */ 1252 if (abfd != NULL) 1253 { 1254 /* Read the extension insns and registers, if any. */ 1255 build_ARC_extmap (abfd); 1256 #ifdef DEBUG 1257 dump_ARC_extmap (); 1258 #endif 1259 } 1260 1261 return print_insn_arc; 1262 } 1263 1264 void 1265 print_arc_disassembler_options (FILE *stream) 1266 { 1267 fprintf (stream, _("\n\ 1268 The following ARC specific disassembler options are supported for use \n\ 1269 with -M switch (multiple options should be separated by commas):\n")); 1270 1271 fprintf (stream, _("\ 1272 dsp Recognize DSP instructions.\n")); 1273 fprintf (stream, _("\ 1274 spfp Recognize FPX SP instructions.\n")); 1275 fprintf (stream, _("\ 1276 dpfp Recognize FPX DP instructions.\n")); 1277 fprintf (stream, _("\ 1278 quarkse_em Recognize FPU QuarkSE-EM instructions.\n")); 1279 fprintf (stream, _("\ 1280 fpuda Recognize double assist FPU instructions.\n")); 1281 fprintf (stream, _("\ 1282 fpus Recognize single precision FPU instructions.\n")); 1283 fprintf (stream, _("\ 1284 fpud Recognize double precision FPU instructions.\n")); 1285 } 1286 1287 void arc_insn_decode (bfd_vma addr, 1288 struct disassemble_info *info, 1289 disassembler_ftype disasm_func, 1290 struct arc_instruction *insn) 1291 { 1292 const struct arc_opcode *opcode; 1293 struct arc_disassemble_info *arc_infop; 1294 1295 /* Ensure that insn would be in the reset state. */ 1296 memset (insn, 0, sizeof (struct arc_instruction)); 1297 1298 /* There was an error when disassembling, for example memory read error. */ 1299 if (disasm_func (addr, info) < 0) 1300 { 1301 insn->valid = FALSE; 1302 return; 1303 } 1304 1305 assert (info->private_data != NULL); 1306 arc_infop = info->private_data; 1307 1308 insn->length = arc_infop->insn_len;; 1309 insn->address = addr; 1310 1311 /* Quick exit if memory at this address is not an instruction. */ 1312 if (info->insn_type == dis_noninsn) 1313 { 1314 insn->valid = FALSE; 1315 return; 1316 } 1317 1318 insn->valid = TRUE; 1319 1320 opcode = (const struct arc_opcode *) arc_infop->opcode; 1321 insn->insn_class = opcode->insn_class; 1322 insn->limm_value = arc_infop->limm; 1323 insn->limm_p = arc_infop->limm_p; 1324 1325 insn->is_control_flow = (info->insn_type == dis_branch 1326 || info->insn_type == dis_condbranch 1327 || info->insn_type == dis_jsr 1328 || info->insn_type == dis_condjsr); 1329 1330 insn->has_delay_slot = info->branch_delay_insns; 1331 insn->writeback_mode 1332 = (enum arc_ldst_writeback_mode) arc_infop->writeback_mode; 1333 insn->data_size_mode = info->data_size; 1334 insn->condition_code = arc_infop->condition_code; 1335 memcpy (insn->operands, arc_infop->operands, 1336 sizeof (struct arc_insn_operand) * MAX_INSN_ARGS); 1337 insn->operands_count = arc_infop->operands_count; 1338 } 1339 1340 /* Local variables: 1341 eval: (c-set-style "gnu") 1342 indent-tabs-mode: t 1343 End: */ 1344