1 /* ia64-opc.c -- Functions to access the compacted opcode table 2 Copyright (C) 1999-2016 Free Software Foundation, Inc. 3 Written by Bob Manson of Cygnus Solutions, <manson (at) cygnus.com> 4 5 This file is part of the GNU opcodes library. 6 7 This library is free software; you can redistribute it and/or modify 8 it under the terms of the GNU General Public License as published by 9 the Free Software Foundation; either version 3, or (at your option) 10 any later version. 11 12 It is distributed in the hope that it will be useful, but WITHOUT 13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 14 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public 15 License for more details. 16 17 You should have received a copy of the GNU General Public License 18 along with this file; see the file COPYING. If not, write to the 19 Free Software Foundation, 51 Franklin Street - Fifth Floor, Boston, 20 MA 02110-1301, USA. */ 21 22 #include "sysdep.h" 23 #include "libiberty.h" 24 #include "ia64-asmtab.h" 25 #include "ia64-asmtab.c" 26 27 static void get_opc_prefix (const char **, char *); 28 static short int find_string_ent (const char *); 29 static short int find_main_ent (short int); 30 static short int find_completer (short int, short int, const char *); 31 static ia64_insn apply_completer (ia64_insn, int); 32 static int extract_op_bits (int, int, int); 33 static int extract_op (int, int *, unsigned int *); 34 static int opcode_verify (ia64_insn, int, enum ia64_insn_type); 35 static int locate_opcode_ent (ia64_insn, enum ia64_insn_type); 36 static struct ia64_opcode *make_ia64_opcode 37 (ia64_insn, const char *, int, int); 38 static struct ia64_opcode *ia64_find_matching_opcode 39 (const char *, short int); 40 41 const struct ia64_templ_desc ia64_templ_desc[16] = 42 { 43 { 0, { IA64_UNIT_M, IA64_UNIT_I, IA64_UNIT_I }, "MII" }, /* 0 */ 44 { 2, { IA64_UNIT_M, IA64_UNIT_I, IA64_UNIT_I }, "MII" }, 45 { 0, { IA64_UNIT_M, IA64_UNIT_L, IA64_UNIT_X }, "MLX" }, 46 { 0, { 0, }, "-3-" }, 47 { 0, { IA64_UNIT_M, IA64_UNIT_M, IA64_UNIT_I }, "MMI" }, /* 4 */ 48 { 1, { IA64_UNIT_M, IA64_UNIT_M, IA64_UNIT_I }, "MMI" }, 49 { 0, { IA64_UNIT_M, IA64_UNIT_F, IA64_UNIT_I }, "MFI" }, 50 { 0, { IA64_UNIT_M, IA64_UNIT_M, IA64_UNIT_F }, "MMF" }, 51 { 0, { IA64_UNIT_M, IA64_UNIT_I, IA64_UNIT_B }, "MIB" }, /* 8 */ 52 { 0, { IA64_UNIT_M, IA64_UNIT_B, IA64_UNIT_B }, "MBB" }, 53 { 0, { 0, }, "-a-" }, 54 { 0, { IA64_UNIT_B, IA64_UNIT_B, IA64_UNIT_B }, "BBB" }, 55 { 0, { IA64_UNIT_M, IA64_UNIT_M, IA64_UNIT_B }, "MMB" }, /* c */ 56 { 0, { 0, }, "-d-" }, 57 { 0, { IA64_UNIT_M, IA64_UNIT_F, IA64_UNIT_B }, "MFB" }, 58 { 0, { 0, }, "-f-" }, 59 }; 60 61 62 /* Copy the prefix contained in *PTR (up to a '.' or a NUL) to DEST. 63 PTR will be adjusted to point to the start of the next portion 64 of the opcode, or at the NUL character. */ 65 66 static void 67 get_opc_prefix (const char **ptr, char *dest) 68 { 69 char *c = strchr (*ptr, '.'); 70 if (c != NULL) 71 { 72 memcpy (dest, *ptr, c - *ptr); 73 dest[c - *ptr] = '\0'; 74 *ptr = c + 1; 75 } 76 else 77 { 78 int l = strlen (*ptr); 79 memcpy (dest, *ptr, l); 80 dest[l] = '\0'; 81 *ptr += l; 82 } 83 } 84 85 /* Find the index of the entry in the string table corresponding to 87 STR; return -1 if one does not exist. */ 88 89 static short 90 find_string_ent (const char *str) 91 { 92 short start = 0; 93 short end = sizeof (ia64_strings) / sizeof (const char *); 94 short i = (start + end) / 2; 95 96 if (strcmp (str, ia64_strings[end - 1]) > 0) 97 { 98 return -1; 99 } 100 while (start <= end) 101 { 102 int c = strcmp (str, ia64_strings[i]); 103 if (c < 0) 104 { 105 end = i - 1; 106 } 107 else if (c == 0) 108 { 109 return i; 110 } 111 else 112 { 113 start = i + 1; 114 } 115 i = (start + end) / 2; 116 } 117 return -1; 118 } 119 120 /* Find the opcode in the main opcode table whose name is STRINGINDEX, or 122 return -1 if one does not exist. */ 123 124 static short 125 find_main_ent (short nameindex) 126 { 127 short start = 0; 128 short end = sizeof (main_table) / sizeof (struct ia64_main_table); 129 short i = (start + end) / 2; 130 131 if (nameindex < main_table[0].name_index 132 || nameindex > main_table[end - 1].name_index) 133 { 134 return -1; 135 } 136 while (start <= end) 137 { 138 if (nameindex < main_table[i].name_index) 139 { 140 end = i - 1; 141 } 142 else if (nameindex == main_table[i].name_index) 143 { 144 while (i > 0 && main_table[i - 1].name_index == nameindex) 145 { 146 i--; 147 } 148 return i; 149 } 150 else 151 { 152 start = i + 1; 153 } 154 i = (start + end) / 2; 155 } 156 return -1; 157 } 158 159 /* Find the index of the entry in the completer table that is part of 161 MAIN_ENT (starting from PREV_COMPLETER) that matches NAME, or 162 return -1 if one does not exist. */ 163 164 static short 165 find_completer (short main_ent, short prev_completer, const char *name) 166 { 167 short name_index = find_string_ent (name); 168 169 if (name_index < 0) 170 { 171 return -1; 172 } 173 174 if (prev_completer == -1) 175 { 176 prev_completer = main_table[main_ent].completers; 177 } 178 else 179 { 180 prev_completer = completer_table[prev_completer].subentries; 181 } 182 183 while (prev_completer != -1) 184 { 185 if (completer_table[prev_completer].name_index == name_index) 186 { 187 return prev_completer; 188 } 189 prev_completer = completer_table[prev_completer].alternative; 190 } 191 return -1; 192 } 193 194 /* Apply the completer referred to by COMPLETER_INDEX to OPCODE, and 196 return the result. */ 197 198 static ia64_insn 199 apply_completer (ia64_insn opcode, int completer_index) 200 { 201 ia64_insn mask = completer_table[completer_index].mask; 202 ia64_insn bits = completer_table[completer_index].bits; 203 int shiftamt = (completer_table[completer_index].offset & 63); 204 205 mask = mask << shiftamt; 206 bits = bits << shiftamt; 207 opcode = (opcode & ~mask) | bits; 208 return opcode; 209 } 210 211 /* Extract BITS number of bits starting from OP_POINTER + BITOFFSET in 213 the dis_table array, and return its value. (BITOFFSET is numbered 214 starting from MSB to LSB, so a BITOFFSET of 0 indicates the MSB of the 215 first byte in OP_POINTER.) */ 216 217 static int 218 extract_op_bits (int op_pointer, int bitoffset, int bits) 219 { 220 int res = 0; 221 222 op_pointer += (bitoffset / 8); 223 224 if (bitoffset % 8) 225 { 226 unsigned int op = dis_table[op_pointer++]; 227 int numb = 8 - (bitoffset % 8); 228 int mask = (1 << numb) - 1; 229 int bata = (bits < numb) ? bits : numb; 230 int delta = numb - bata; 231 232 res = (res << bata) | ((op & mask) >> delta); 233 bitoffset += bata; 234 bits -= bata; 235 } 236 while (bits >= 8) 237 { 238 res = (res << 8) | (dis_table[op_pointer++] & 255); 239 bits -= 8; 240 } 241 if (bits > 0) 242 { 243 unsigned int op = (dis_table[op_pointer++] & 255); 244 res = (res << bits) | (op >> (8 - bits)); 245 } 246 return res; 247 } 248 249 /* Examine the state machine entry at OP_POINTER in the dis_table 251 array, and extract its values into OPVAL and OP. The length of the 252 state entry in bits is returned. */ 253 254 static int 255 extract_op (int op_pointer, int *opval, unsigned int *op) 256 { 257 int oplen = 5; 258 259 *op = dis_table[op_pointer]; 260 261 if ((*op) & 0x40) 262 { 263 opval[0] = extract_op_bits (op_pointer, oplen, 5); 264 oplen += 5; 265 } 266 switch ((*op) & 0x30) 267 { 268 case 0x10: 269 { 270 opval[1] = extract_op_bits (op_pointer, oplen, 8); 271 oplen += 8; 272 opval[1] += op_pointer; 273 break; 274 } 275 case 0x20: 276 { 277 opval[1] = extract_op_bits (op_pointer, oplen, 16); 278 if (! (opval[1] & 32768)) 279 { 280 opval[1] += op_pointer; 281 } 282 oplen += 16; 283 break; 284 } 285 case 0x30: 286 { 287 oplen--; 288 opval[2] = extract_op_bits (op_pointer, oplen, 12); 289 oplen += 12; 290 opval[2] |= 32768; 291 break; 292 } 293 } 294 if (((*op) & 0x08) && (((*op) & 0x30) != 0x30)) 295 { 296 opval[2] = extract_op_bits (op_pointer, oplen, 16); 297 oplen += 16; 298 if (! (opval[2] & 32768)) 299 { 300 opval[2] += op_pointer; 301 } 302 } 303 return oplen; 304 } 305 306 /* Returns a non-zero value if the opcode in the main_table list at 308 PLACE matches OPCODE and is of type TYPE. */ 309 310 static int 311 opcode_verify (ia64_insn opcode, int place, enum ia64_insn_type type) 312 { 313 if (main_table[place].opcode_type != type) 314 { 315 return 0; 316 } 317 if (main_table[place].flags 318 & (IA64_OPCODE_F2_EQ_F3 | IA64_OPCODE_LEN_EQ_64MCNT)) 319 { 320 const struct ia64_operand *o1, *o2; 321 ia64_insn f2, f3; 322 323 if (main_table[place].flags & IA64_OPCODE_F2_EQ_F3) 324 { 325 o1 = elf64_ia64_operands + IA64_OPND_F2; 326 o2 = elf64_ia64_operands + IA64_OPND_F3; 327 (*o1->extract) (o1, opcode, &f2); 328 (*o2->extract) (o2, opcode, &f3); 329 if (f2 != f3) 330 return 0; 331 } 332 else 333 { 334 ia64_insn len, count; 335 336 /* length must equal 64-count: */ 337 o1 = elf64_ia64_operands + IA64_OPND_LEN6; 338 o2 = elf64_ia64_operands + main_table[place].operands[2]; 339 (*o1->extract) (o1, opcode, &len); 340 (*o2->extract) (o2, opcode, &count); 341 if (len != 64 - count) 342 return 0; 343 } 344 } 345 return 1; 346 } 347 348 /* Find an instruction entry in the ia64_dis_names array that matches 350 opcode OPCODE and is of type TYPE. Returns either a positive index 351 into the array, or a negative value if an entry for OPCODE could 352 not be found. Checks all matches and returns the one with the highest 353 priority. */ 354 355 static int 356 locate_opcode_ent (ia64_insn opcode, enum ia64_insn_type type) 357 { 358 int currtest[41]; 359 int bitpos[41]; 360 int op_ptr[41]; 361 int currstatenum = 0; 362 short found_disent = -1; 363 short found_priority = -1; 364 365 currtest[currstatenum] = 0; 366 op_ptr[currstatenum] = 0; 367 bitpos[currstatenum] = 40; 368 369 while (1) 370 { 371 int op_pointer = op_ptr[currstatenum]; 372 unsigned int op; 373 int currbitnum = bitpos[currstatenum]; 374 int oplen; 375 int opval[3] = {0}; 376 int next_op; 377 int currbit; 378 379 oplen = extract_op (op_pointer, opval, &op); 380 381 bitpos[currstatenum] = currbitnum; 382 383 /* Skip opval[0] bits in the instruction. */ 384 if (op & 0x40) 385 { 386 currbitnum -= opval[0]; 387 } 388 389 /* The value of the current bit being tested. */ 390 currbit = opcode & (((ia64_insn) 1) << currbitnum) ? 1 : 0; 391 next_op = -1; 392 393 /* We always perform the tests specified in the current state in 394 a particular order, falling through to the next test if the 395 previous one failed. */ 396 switch (currtest[currstatenum]) 397 { 398 case 0: 399 currtest[currstatenum]++; 400 if (currbit == 0 && (op & 0x80)) 401 { 402 /* Check for a zero bit. If this test solely checks for 403 a zero bit, we can check for up to 8 consecutive zero 404 bits (the number to check is specified by the lower 3 405 bits in the state code.) 406 407 If the state instruction matches, we go to the very 408 next state instruction; otherwise, try the next test. */ 409 410 if ((op & 0xf8) == 0x80) 411 { 412 int count = op & 0x7; 413 int x; 414 415 for (x = 0; x <= count; x++) 416 { 417 int i = 418 opcode & (((ia64_insn) 1) << (currbitnum - x)) ? 1 : 0; 419 if (i) 420 { 421 break; 422 } 423 } 424 if (x > count) 425 { 426 next_op = op_pointer + ((oplen + 7) / 8); 427 currbitnum -= count; 428 break; 429 } 430 } 431 else if (! currbit) 432 { 433 next_op = op_pointer + ((oplen + 7) / 8); 434 break; 435 } 436 } 437 /* FALLTHROUGH */ 438 case 1: 439 /* If the bit in the instruction is one, go to the state 440 instruction specified by opval[1]. */ 441 currtest[currstatenum]++; 442 if (currbit && (op & 0x30) != 0 && ((op & 0x30) != 0x30)) 443 { 444 next_op = opval[1]; 445 break; 446 } 447 /* FALLTHROUGH */ 448 case 2: 449 /* Don't care. Skip the current bit and go to the state 450 instruction specified by opval[2]. 451 452 An encoding of 0x30 is special; this means that a 12-bit 453 offset into the ia64_dis_names[] array is specified. */ 454 currtest[currstatenum]++; 455 if ((op & 0x08) || ((op & 0x30) == 0x30)) 456 { 457 next_op = opval[2]; 458 break; 459 } 460 } 461 462 /* If bit 15 is set in the address of the next state, an offset 463 in the ia64_dis_names array was specified instead. We then 464 check to see if an entry in the list of opcodes matches the 465 opcode we were given; if so, we have succeeded. */ 466 467 if ((next_op >= 0) && (next_op & 32768)) 468 { 469 short disent = next_op & 32767; 470 short priority = -1; 471 472 if (next_op > 65535) 473 { 474 abort (); 475 } 476 477 /* Run through the list of opcodes to check, trying to find 478 one that matches. */ 479 while (disent >= 0) 480 { 481 int place = ia64_dis_names[disent].insn_index; 482 483 priority = ia64_dis_names[disent].priority; 484 485 if (opcode_verify (opcode, place, type) 486 && priority > found_priority) 487 { 488 break; 489 } 490 if (ia64_dis_names[disent].next_flag) 491 { 492 disent++; 493 } 494 else 495 { 496 disent = -1; 497 } 498 } 499 500 if (disent >= 0) 501 { 502 found_disent = disent; 503 found_priority = priority; 504 } 505 /* Try the next test in this state, regardless of whether a match 506 was found. */ 507 next_op = -2; 508 } 509 510 /* next_op == -1 is "back up to the previous state". 511 next_op == -2 is "stay in this state and try the next test". 512 Otherwise, transition to the state indicated by next_op. */ 513 514 if (next_op == -1) 515 { 516 currstatenum--; 517 if (currstatenum < 0) 518 { 519 return found_disent; 520 } 521 } 522 else if (next_op >= 0) 523 { 524 currstatenum++; 525 bitpos[currstatenum] = currbitnum - 1; 526 op_ptr[currstatenum] = next_op; 527 currtest[currstatenum] = 0; 528 } 529 } 530 } 531 532 /* Construct an ia64_opcode entry based on OPCODE, NAME and PLACE. */ 534 535 static struct ia64_opcode * 536 make_ia64_opcode (ia64_insn opcode, const char *name, int place, int depind) 537 { 538 struct ia64_opcode *res = 539 (struct ia64_opcode *) xmalloc (sizeof (struct ia64_opcode)); 540 res->name = xstrdup (name); 541 res->type = main_table[place].opcode_type; 542 res->num_outputs = main_table[place].num_outputs; 543 res->opcode = opcode; 544 res->mask = main_table[place].mask; 545 res->operands[0] = main_table[place].operands[0]; 546 res->operands[1] = main_table[place].operands[1]; 547 res->operands[2] = main_table[place].operands[2]; 548 res->operands[3] = main_table[place].operands[3]; 549 res->operands[4] = main_table[place].operands[4]; 550 res->flags = main_table[place].flags; 551 res->ent_index = place; 552 res->dependencies = &op_dependencies[depind]; 553 return res; 554 } 555 556 /* Determine the ia64_opcode entry for the opcode specified by INSN 558 and TYPE. If a valid entry is not found, return NULL. */ 559 struct ia64_opcode * 560 ia64_dis_opcode (ia64_insn insn, enum ia64_insn_type type) 561 { 562 int disent = locate_opcode_ent (insn, type); 563 564 if (disent < 0) 565 { 566 return NULL; 567 } 568 else 569 { 570 unsigned int cb = ia64_dis_names[disent].completer_index; 571 static char name[128]; 572 int place = ia64_dis_names[disent].insn_index; 573 int ci = main_table[place].completers; 574 ia64_insn tinsn = main_table[place].opcode; 575 576 strcpy (name, ia64_strings [main_table[place].name_index]); 577 578 while (cb) 579 { 580 if (cb & 1) 581 { 582 int cname = completer_table[ci].name_index; 583 584 tinsn = apply_completer (tinsn, ci); 585 586 if (ia64_strings[cname][0] != '\0') 587 { 588 strcat (name, "."); 589 strcat (name, ia64_strings[cname]); 590 } 591 if (cb != 1) 592 { 593 ci = completer_table[ci].subentries; 594 } 595 } 596 else 597 { 598 ci = completer_table[ci].alternative; 599 } 600 if (ci < 0) 601 { 602 abort (); 603 } 604 cb = cb >> 1; 605 } 606 if (tinsn != (insn & main_table[place].mask)) 607 { 608 abort (); 609 } 610 return make_ia64_opcode (insn, name, place, 611 completer_table[ci].dependencies); 612 } 613 } 614 615 /* Search the main_opcode table starting from PLACE for an opcode that 617 matches NAME. Return NULL if one is not found. */ 618 619 static struct ia64_opcode * 620 ia64_find_matching_opcode (const char *name, short place) 621 { 622 char op[129]; 623 const char *suffix; 624 short name_index; 625 626 if (strlen (name) > 128) 627 { 628 return NULL; 629 } 630 suffix = name; 631 get_opc_prefix (&suffix, op); 632 name_index = find_string_ent (op); 633 if (name_index < 0) 634 { 635 return NULL; 636 } 637 638 while (main_table[place].name_index == name_index) 639 { 640 const char *curr_suffix = suffix; 641 ia64_insn curr_insn = main_table[place].opcode; 642 short completer = -1; 643 644 do { 645 if (suffix[0] == '\0') 646 { 647 completer = find_completer (place, completer, suffix); 648 } 649 else 650 { 651 get_opc_prefix (&curr_suffix, op); 652 completer = find_completer (place, completer, op); 653 } 654 if (completer != -1) 655 { 656 curr_insn = apply_completer (curr_insn, completer); 657 } 658 } while (completer != -1 && curr_suffix[0] != '\0'); 659 660 if (completer != -1 && curr_suffix[0] == '\0' 661 && completer_table[completer].terminal_completer) 662 { 663 int depind = completer_table[completer].dependencies; 664 return make_ia64_opcode (curr_insn, name, place, depind); 665 } 666 else 667 { 668 place++; 669 } 670 } 671 return NULL; 672 } 673 674 /* Find the next opcode after PREV_ENT that matches PREV_ENT, or return NULL 676 if one does not exist. 677 678 It is the caller's responsibility to invoke ia64_free_opcode () to 679 release any resources used by the returned entry. */ 680 681 struct ia64_opcode * 682 ia64_find_next_opcode (struct ia64_opcode *prev_ent) 683 { 684 return ia64_find_matching_opcode (prev_ent->name, 685 prev_ent->ent_index + 1); 686 } 687 688 /* Find the first opcode that matches NAME, or return NULL if it does 689 not exist. 690 691 It is the caller's responsibility to invoke ia64_free_opcode () to 692 release any resources used by the returned entry. */ 693 694 struct ia64_opcode * 695 ia64_find_opcode (const char *name) 696 { 697 char op[129]; 698 const char *suffix; 699 short place; 700 short name_index; 701 702 if (strlen (name) > 128) 703 { 704 return NULL; 705 } 706 suffix = name; 707 get_opc_prefix (&suffix, op); 708 name_index = find_string_ent (op); 709 if (name_index < 0) 710 { 711 return NULL; 712 } 713 714 place = find_main_ent (name_index); 715 716 if (place < 0) 717 { 718 return NULL; 719 } 720 return ia64_find_matching_opcode (name, place); 721 } 722 723 /* Free any resources used by ENT. */ 724 void 725 ia64_free_opcode (struct ia64_opcode *ent) 726 { 727 free ((void *)ent->name); 728 free (ent); 729 } 730 731 const struct ia64_dependency * 732 ia64_find_dependency (int dep_index) 733 { 734 dep_index = DEP(dep_index); 735 736 if (dep_index < 0 737 || dep_index >= (int) ARRAY_SIZE (dependencies)) 738 return NULL; 739 740 return &dependencies[dep_index]; 741 } 742