1 /* CGEN generic opcode support. 2 3 Copyright (C) 1996-2014 Free Software Foundation, Inc. 4 5 This file is part of libopcodes. 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 along 18 with this program; if not, write to the Free Software Foundation, Inc., 19 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ 20 21 #include "sysdep.h" 22 #include "alloca-conf.h" 23 #include <stdio.h> 24 #include "ansidecl.h" 25 #include "libiberty.h" 26 #include "safe-ctype.h" 27 #include "bfd.h" 28 #include "symcat.h" 29 #include "opcode/cgen.h" 30 31 static unsigned int hash_keyword_name 32 (const CGEN_KEYWORD *, const char *, int); 33 static unsigned int hash_keyword_value 34 (const CGEN_KEYWORD *, unsigned int); 35 static void build_keyword_hash_tables 36 (CGEN_KEYWORD *); 37 38 /* Return number of hash table entries to use for N elements. */ 39 #define KEYWORD_HASH_SIZE(n) ((n) <= 31 ? 17 : 31) 40 41 /* Look up *NAMEP in the keyword table KT. 42 The result is the keyword entry or NULL if not found. */ 43 44 const CGEN_KEYWORD_ENTRY * 45 cgen_keyword_lookup_name (CGEN_KEYWORD *kt, const char *name) 46 { 47 const CGEN_KEYWORD_ENTRY *ke; 48 const char *p,*n; 49 50 if (kt->name_hash_table == NULL) 51 build_keyword_hash_tables (kt); 52 53 ke = kt->name_hash_table[hash_keyword_name (kt, name, 0)]; 54 55 /* We do case insensitive comparisons. 56 If that ever becomes a problem, add an attribute that denotes 57 "do case sensitive comparisons". */ 58 59 while (ke != NULL) 60 { 61 n = name; 62 p = ke->name; 63 64 while (*p 65 && (*p == *n 66 || (ISALPHA (*p) && (TOLOWER (*p) == TOLOWER (*n))))) 67 ++n, ++p; 68 69 if (!*p && !*n) 70 return ke; 71 72 ke = ke->next_name; 73 } 74 75 if (kt->null_entry) 76 return kt->null_entry; 77 return NULL; 78 } 79 80 /* Look up VALUE in the keyword table KT. 81 The result is the keyword entry or NULL if not found. */ 82 83 const CGEN_KEYWORD_ENTRY * 84 cgen_keyword_lookup_value (CGEN_KEYWORD *kt, int value) 85 { 86 const CGEN_KEYWORD_ENTRY *ke; 87 88 if (kt->name_hash_table == NULL) 89 build_keyword_hash_tables (kt); 90 91 ke = kt->value_hash_table[hash_keyword_value (kt, value)]; 92 93 while (ke != NULL) 94 { 95 if (value == ke->value) 96 return ke; 97 ke = ke->next_value; 98 } 99 100 return NULL; 101 } 102 103 /* Add an entry to a keyword table. */ 104 105 void 106 cgen_keyword_add (CGEN_KEYWORD *kt, CGEN_KEYWORD_ENTRY *ke) 107 { 108 unsigned int hash; 109 size_t i; 110 111 if (kt->name_hash_table == NULL) 112 build_keyword_hash_tables (kt); 113 114 hash = hash_keyword_name (kt, ke->name, 0); 115 ke->next_name = kt->name_hash_table[hash]; 116 kt->name_hash_table[hash] = ke; 117 118 hash = hash_keyword_value (kt, ke->value); 119 ke->next_value = kt->value_hash_table[hash]; 120 kt->value_hash_table[hash] = ke; 121 122 if (ke->name[0] == 0) 123 kt->null_entry = ke; 124 125 for (i = 1; i < strlen (ke->name); i++) 126 if (! ISALNUM (ke->name[i]) 127 && ! strchr (kt->nonalpha_chars, ke->name[i])) 128 { 129 size_t idx = strlen (kt->nonalpha_chars); 130 131 /* If you hit this limit, please don't just 132 increase the size of the field, instead 133 look for a better algorithm. */ 134 if (idx >= sizeof (kt->nonalpha_chars) - 1) 135 abort (); 136 kt->nonalpha_chars[idx] = ke->name[i]; 137 kt->nonalpha_chars[idx+1] = 0; 138 } 139 } 140 141 /* FIXME: Need function to return count of keywords. */ 142 143 /* Initialize a keyword table search. 144 SPEC is a specification of what to search for. 145 A value of NULL means to find every keyword. 146 Currently NULL is the only acceptable value [further specification 147 deferred]. 148 The result is an opaque data item used to record the search status. 149 It is passed to each call to cgen_keyword_search_next. */ 150 151 CGEN_KEYWORD_SEARCH 152 cgen_keyword_search_init (CGEN_KEYWORD *kt, const char *spec) 153 { 154 CGEN_KEYWORD_SEARCH search; 155 156 /* FIXME: Need to specify format of params. */ 157 if (spec != NULL) 158 abort (); 159 160 if (kt->name_hash_table == NULL) 161 build_keyword_hash_tables (kt); 162 163 search.table = kt; 164 search.spec = spec; 165 search.current_hash = 0; 166 search.current_entry = NULL; 167 return search; 168 } 169 170 /* Return the next keyword specified by SEARCH. 171 The result is the next entry or NULL if there are no more. */ 172 173 const CGEN_KEYWORD_ENTRY * 174 cgen_keyword_search_next (CGEN_KEYWORD_SEARCH *search) 175 { 176 /* Has search finished? */ 177 if (search->current_hash == search->table->hash_table_size) 178 return NULL; 179 180 /* Search in progress? */ 181 if (search->current_entry != NULL 182 /* Anything left on this hash chain? */ 183 && search->current_entry->next_name != NULL) 184 { 185 search->current_entry = search->current_entry->next_name; 186 return search->current_entry; 187 } 188 189 /* Move to next hash chain [unless we haven't started yet]. */ 190 if (search->current_entry != NULL) 191 ++search->current_hash; 192 193 while (search->current_hash < search->table->hash_table_size) 194 { 195 search->current_entry = search->table->name_hash_table[search->current_hash]; 196 if (search->current_entry != NULL) 197 return search->current_entry; 198 ++search->current_hash; 199 } 200 201 return NULL; 202 } 203 204 /* Return first entry in hash chain for NAME. 205 If CASE_SENSITIVE_P is non-zero, return a case sensitive hash. */ 206 207 static unsigned int 208 hash_keyword_name (const CGEN_KEYWORD *kt, 209 const char *name, 210 int case_sensitive_p) 211 { 212 unsigned int hash; 213 214 if (case_sensitive_p) 215 for (hash = 0; *name; ++name) 216 hash = (hash * 97) + (unsigned char) *name; 217 else 218 for (hash = 0; *name; ++name) 219 hash = (hash * 97) + (unsigned char) TOLOWER (*name); 220 return hash % kt->hash_table_size; 221 } 222 223 /* Return first entry in hash chain for VALUE. */ 224 225 static unsigned int 226 hash_keyword_value (const CGEN_KEYWORD *kt, unsigned int value) 227 { 228 return value % kt->hash_table_size; 229 } 230 231 /* Build a keyword table's hash tables. 232 We probably needn't build the value hash table for the assembler when 233 we're using the disassembler, but we keep things simple. */ 234 235 static void 236 build_keyword_hash_tables (CGEN_KEYWORD *kt) 237 { 238 int i; 239 /* Use the number of compiled in entries as an estimate for the 240 typical sized table [not too many added at runtime]. */ 241 unsigned int size = KEYWORD_HASH_SIZE (kt->num_init_entries); 242 243 kt->hash_table_size = size; 244 kt->name_hash_table = (CGEN_KEYWORD_ENTRY **) 245 xmalloc (size * sizeof (CGEN_KEYWORD_ENTRY *)); 246 memset (kt->name_hash_table, 0, size * sizeof (CGEN_KEYWORD_ENTRY *)); 247 kt->value_hash_table = (CGEN_KEYWORD_ENTRY **) 248 xmalloc (size * sizeof (CGEN_KEYWORD_ENTRY *)); 249 memset (kt->value_hash_table, 0, size * sizeof (CGEN_KEYWORD_ENTRY *)); 250 251 /* The table is scanned backwards as we want keywords appearing earlier to 252 be prefered over later ones. */ 253 for (i = kt->num_init_entries - 1; i >= 0; --i) 254 cgen_keyword_add (kt, &kt->init_entries[i]); 255 } 256 257 /* Hardware support. */ 259 260 /* Lookup a hardware element by its name. 261 Returns NULL if NAME is not supported by the currently selected 262 mach/isa. */ 263 264 const CGEN_HW_ENTRY * 265 cgen_hw_lookup_by_name (CGEN_CPU_DESC cd, const char *name) 266 { 267 unsigned int i; 268 const CGEN_HW_ENTRY **hw = cd->hw_table.entries; 269 270 for (i = 0; i < cd->hw_table.num_entries; ++i) 271 if (hw[i] && strcmp (name, hw[i]->name) == 0) 272 return hw[i]; 273 274 return NULL; 275 } 276 277 /* Lookup a hardware element by its number. 278 Hardware elements are enumerated, however it may be possible to add some 279 at runtime, thus HWNUM is not an enum type but rather an int. 280 Returns NULL if HWNUM is not supported by the currently selected mach. */ 281 282 const CGEN_HW_ENTRY * 283 cgen_hw_lookup_by_num (CGEN_CPU_DESC cd, unsigned int hwnum) 284 { 285 unsigned int i; 286 const CGEN_HW_ENTRY **hw = cd->hw_table.entries; 287 288 /* ??? This can be speeded up. */ 289 for (i = 0; i < cd->hw_table.num_entries; ++i) 290 if (hw[i] && hwnum == hw[i]->type) 291 return hw[i]; 292 293 return NULL; 294 } 295 296 /* Operand support. */ 298 299 /* Lookup an operand by its name. 300 Returns NULL if NAME is not supported by the currently selected 301 mach/isa. */ 302 303 const CGEN_OPERAND * 304 cgen_operand_lookup_by_name (CGEN_CPU_DESC cd, const char *name) 305 { 306 unsigned int i; 307 const CGEN_OPERAND **op = cd->operand_table.entries; 308 309 for (i = 0; i < cd->operand_table.num_entries; ++i) 310 if (op[i] && strcmp (name, op[i]->name) == 0) 311 return op[i]; 312 313 return NULL; 314 } 315 316 /* Lookup an operand by its number. 317 Operands are enumerated, however it may be possible to add some 318 at runtime, thus OPNUM is not an enum type but rather an int. 319 Returns NULL if OPNUM is not supported by the currently selected 320 mach/isa. */ 321 322 const CGEN_OPERAND * 323 cgen_operand_lookup_by_num (CGEN_CPU_DESC cd, int opnum) 324 { 325 return cd->operand_table.entries[opnum]; 326 } 327 328 /* Instruction support. */ 330 331 /* Return number of instructions. This includes any added at runtime. */ 332 333 int 334 cgen_insn_count (CGEN_CPU_DESC cd) 335 { 336 int count = cd->insn_table.num_init_entries; 337 CGEN_INSN_LIST *rt_insns = cd->insn_table.new_entries; 338 339 for ( ; rt_insns != NULL; rt_insns = rt_insns->next) 340 ++count; 341 342 return count; 343 } 344 345 /* Return number of macro-instructions. 346 This includes any added at runtime. */ 347 348 int 349 cgen_macro_insn_count (CGEN_CPU_DESC cd) 350 { 351 int count = cd->macro_insn_table.num_init_entries; 352 CGEN_INSN_LIST *rt_insns = cd->macro_insn_table.new_entries; 353 354 for ( ; rt_insns != NULL; rt_insns = rt_insns->next) 355 ++count; 356 357 return count; 358 } 359 360 /* Cover function to read and properly byteswap an insn value. */ 361 362 CGEN_INSN_INT 363 cgen_get_insn_value (CGEN_CPU_DESC cd, unsigned char *buf, int length) 364 { 365 int big_p = (cd->insn_endian == CGEN_ENDIAN_BIG); 366 int insn_chunk_bitsize = cd->insn_chunk_bitsize; 367 CGEN_INSN_INT value = 0; 368 369 if (insn_chunk_bitsize != 0 && insn_chunk_bitsize < length) 370 { 371 /* We need to divide up the incoming value into insn_chunk_bitsize-length 372 segments, and endian-convert them, one at a time. */ 373 int i; 374 375 /* Enforce divisibility. */ 376 if ((length % insn_chunk_bitsize) != 0) 377 abort (); 378 379 for (i = 0; i < length; i += insn_chunk_bitsize) /* NB: i == bits */ 380 { 381 int bit_index; 382 bfd_vma this_value; 383 384 bit_index = i; /* NB: not dependent on endianness; opposite of cgen_put_insn_value! */ 385 this_value = bfd_get_bits (& buf[bit_index / 8], insn_chunk_bitsize, big_p); 386 value = (value << insn_chunk_bitsize) | this_value; 387 } 388 } 389 else 390 { 391 value = bfd_get_bits (buf, length, cd->insn_endian == CGEN_ENDIAN_BIG); 392 } 393 394 return value; 395 } 396 397 /* Cover function to store an insn value properly byteswapped. */ 398 399 void 400 cgen_put_insn_value (CGEN_CPU_DESC cd, 401 unsigned char *buf, 402 int length, 403 CGEN_INSN_INT value) 404 { 405 int big_p = (cd->insn_endian == CGEN_ENDIAN_BIG); 406 int insn_chunk_bitsize = cd->insn_chunk_bitsize; 407 408 if (insn_chunk_bitsize != 0 && insn_chunk_bitsize < length) 409 { 410 /* We need to divide up the incoming value into insn_chunk_bitsize-length 411 segments, and endian-convert them, one at a time. */ 412 int i; 413 414 /* Enforce divisibility. */ 415 if ((length % insn_chunk_bitsize) != 0) 416 abort (); 417 418 for (i = 0; i < length; i += insn_chunk_bitsize) /* NB: i == bits */ 419 { 420 int bit_index; 421 422 bit_index = (length - insn_chunk_bitsize - i); /* NB: not dependent on endianness! */ 423 bfd_put_bits ((bfd_vma) value, & buf[bit_index / 8], insn_chunk_bitsize, big_p); 424 value >>= insn_chunk_bitsize; 425 } 426 } 427 else 428 { 429 bfd_put_bits ((bfd_vma) value, buf, length, big_p); 430 } 431 } 432 433 /* Look up instruction INSN_*_VALUE and extract its fields. 435 INSN_INT_VALUE is used if CGEN_INT_INSN_P. 436 Otherwise INSN_BYTES_VALUE is used. 437 INSN, if non-null, is the insn table entry. 438 Otherwise INSN_*_VALUE is examined to compute it. 439 LENGTH is the bit length of INSN_*_VALUE if known, otherwise 0. 440 0 is only valid if `insn == NULL && ! CGEN_INT_INSN_P'. 441 If INSN != NULL, LENGTH must be valid. 442 ALIAS_P is non-zero if alias insns are to be included in the search. 443 444 The result is a pointer to the insn table entry, or NULL if the instruction 445 wasn't recognized. */ 446 447 /* ??? Will need to be revisited for VLIW architectures. */ 448 449 const CGEN_INSN * 450 cgen_lookup_insn (CGEN_CPU_DESC cd, 451 const CGEN_INSN *insn, 452 CGEN_INSN_INT insn_int_value, 453 /* ??? CGEN_INSN_BYTES would be a nice type name to use here. */ 454 unsigned char *insn_bytes_value, 455 int length, 456 CGEN_FIELDS *fields, 457 int alias_p) 458 { 459 unsigned char *buf; 460 CGEN_INSN_INT base_insn; 461 CGEN_EXTRACT_INFO ex_info; 462 CGEN_EXTRACT_INFO *info; 463 464 if (cd->int_insn_p) 465 { 466 info = NULL; 467 buf = (unsigned char *) alloca (cd->max_insn_bitsize / 8); 468 cgen_put_insn_value (cd, buf, length, insn_int_value); 469 base_insn = insn_int_value; 470 } 471 else 472 { 473 info = &ex_info; 474 ex_info.dis_info = NULL; 475 ex_info.insn_bytes = insn_bytes_value; 476 ex_info.valid = -1; 477 buf = insn_bytes_value; 478 base_insn = cgen_get_insn_value (cd, buf, length); 479 } 480 481 if (!insn) 482 { 483 const CGEN_INSN_LIST *insn_list; 484 485 /* The instructions are stored in hash lists. 486 Pick the first one and keep trying until we find the right one. */ 487 488 insn_list = cgen_dis_lookup_insn (cd, (char *) buf, base_insn); 489 while (insn_list != NULL) 490 { 491 insn = insn_list->insn; 492 493 if (alias_p 494 /* FIXME: Ensure ALIAS attribute always has same index. */ 495 || ! CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_ALIAS)) 496 { 497 /* Basic bit mask must be correct. */ 498 /* ??? May wish to allow target to defer this check until the 499 extract handler. */ 500 if ((base_insn & CGEN_INSN_BASE_MASK (insn)) 501 == CGEN_INSN_BASE_VALUE (insn)) 502 { 503 /* ??? 0 is passed for `pc' */ 504 int elength = CGEN_EXTRACT_FN (cd, insn) 505 (cd, insn, info, base_insn, fields, (bfd_vma) 0); 506 if (elength > 0) 507 { 508 /* sanity check */ 509 if (length != 0 && length != elength) 510 abort (); 511 return insn; 512 } 513 } 514 } 515 516 insn_list = insn_list->next; 517 } 518 } 519 else 520 { 521 /* Sanity check: can't pass an alias insn if ! alias_p. */ 522 if (! alias_p 523 && CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_ALIAS)) 524 abort (); 525 /* Sanity check: length must be correct. */ 526 if (length != CGEN_INSN_BITSIZE (insn)) 527 abort (); 528 529 /* ??? 0 is passed for `pc' */ 530 length = CGEN_EXTRACT_FN (cd, insn) 531 (cd, insn, info, base_insn, fields, (bfd_vma) 0); 532 /* Sanity check: must succeed. 533 Could relax this later if it ever proves useful. */ 534 if (length == 0) 535 abort (); 536 return insn; 537 } 538 539 return NULL; 540 } 541 542 /* Fill in the operand instances used by INSN whose operands are FIELDS. 543 INDICES is a pointer to a buffer of MAX_OPERAND_INSTANCES ints to be filled 544 in. */ 545 546 void 547 cgen_get_insn_operands (CGEN_CPU_DESC cd, 548 const CGEN_INSN *insn, 549 const CGEN_FIELDS *fields, 550 int *indices) 551 { 552 const CGEN_OPINST *opinst; 553 int i; 554 555 if (insn->opinst == NULL) 556 abort (); 557 for (i = 0, opinst = insn->opinst; opinst->type != CGEN_OPINST_END; ++i, ++opinst) 558 { 559 enum cgen_operand_type op_type = opinst->op_type; 560 if (op_type == CGEN_OPERAND_NIL) 561 indices[i] = opinst->index; 562 else 563 indices[i] = (*cd->get_int_operand) (cd, op_type, fields); 564 } 565 } 566 567 /* Cover function to cgen_get_insn_operands when either INSN or FIELDS 568 isn't known. 569 The INSN, INSN_*_VALUE, and LENGTH arguments are passed to 570 cgen_lookup_insn unchanged. 571 INSN_INT_VALUE is used if CGEN_INT_INSN_P. 572 Otherwise INSN_BYTES_VALUE is used. 573 574 The result is the insn table entry or NULL if the instruction wasn't 575 recognized. */ 576 577 const CGEN_INSN * 578 cgen_lookup_get_insn_operands (CGEN_CPU_DESC cd, 579 const CGEN_INSN *insn, 580 CGEN_INSN_INT insn_int_value, 581 /* ??? CGEN_INSN_BYTES would be a nice type name to use here. */ 582 unsigned char *insn_bytes_value, 583 int length, 584 int *indices, 585 CGEN_FIELDS *fields) 586 { 587 /* Pass non-zero for ALIAS_P only if INSN != NULL. 588 If INSN == NULL, we want a real insn. */ 589 insn = cgen_lookup_insn (cd, insn, insn_int_value, insn_bytes_value, 590 length, fields, insn != NULL); 591 if (! insn) 592 return NULL; 593 594 cgen_get_insn_operands (cd, insn, fields, indices); 595 return insn; 596 } 597 598 /* Allow signed overflow of instruction fields. */ 599 void 600 cgen_set_signed_overflow_ok (CGEN_CPU_DESC cd) 601 { 602 cd->signed_overflow_ok_p = 1; 603 } 604 605 /* Generate an error message if a signed field in an instruction overflows. */ 606 void 607 cgen_clear_signed_overflow_ok (CGEN_CPU_DESC cd) 608 { 609 cd->signed_overflow_ok_p = 0; 610 } 611 612 /* Will an error message be generated if a signed field in an instruction overflows ? */ 613 unsigned int 614 cgen_signed_overflow_ok_p (CGEN_CPU_DESC cd) 615 { 616 return cd->signed_overflow_ok_p; 617 } 618