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