1/* CGEN generic opcode support. 2 3 Copyright (C) 1996-2017 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 31static unsigned int hash_keyword_name 32 (const CGEN_KEYWORD *, const char *, int); 33static unsigned int hash_keyword_value 34 (const CGEN_KEYWORD *, unsigned int); 35static 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 44const CGEN_KEYWORD_ENTRY * 45cgen_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 83const CGEN_KEYWORD_ENTRY * 84cgen_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 105void 106cgen_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 151CGEN_KEYWORD_SEARCH 152cgen_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 173const CGEN_KEYWORD_ENTRY * 174cgen_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 207static unsigned int 208hash_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 225static unsigned int 226hash_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 235static void 236build_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. */ 258 259/* Lookup a hardware element by its name. 260 Returns NULL if NAME is not supported by the currently selected 261 mach/isa. */ 262 263const CGEN_HW_ENTRY * 264cgen_hw_lookup_by_name (CGEN_CPU_DESC cd, const char *name) 265{ 266 unsigned int i; 267 const CGEN_HW_ENTRY **hw = cd->hw_table.entries; 268 269 for (i = 0; i < cd->hw_table.num_entries; ++i) 270 if (hw[i] && strcmp (name, hw[i]->name) == 0) 271 return hw[i]; 272 273 return NULL; 274} 275 276/* Lookup a hardware element by its number. 277 Hardware elements are enumerated, however it may be possible to add some 278 at runtime, thus HWNUM is not an enum type but rather an int. 279 Returns NULL if HWNUM is not supported by the currently selected mach. */ 280 281const CGEN_HW_ENTRY * 282cgen_hw_lookup_by_num (CGEN_CPU_DESC cd, unsigned int hwnum) 283{ 284 unsigned int i; 285 const CGEN_HW_ENTRY **hw = cd->hw_table.entries; 286 287 /* ??? This can be speeded up. */ 288 for (i = 0; i < cd->hw_table.num_entries; ++i) 289 if (hw[i] && hwnum == hw[i]->type) 290 return hw[i]; 291 292 return NULL; 293} 294 295/* Operand support. */ 296 297/* Lookup an operand by its name. 298 Returns NULL if NAME is not supported by the currently selected 299 mach/isa. */ 300 301const CGEN_OPERAND * 302cgen_operand_lookup_by_name (CGEN_CPU_DESC cd, const char *name) 303{ 304 unsigned int i; 305 const CGEN_OPERAND **op = cd->operand_table.entries; 306 307 for (i = 0; i < cd->operand_table.num_entries; ++i) 308 if (op[i] && strcmp (name, op[i]->name) == 0) 309 return op[i]; 310 311 return NULL; 312} 313 314/* Lookup an operand by its number. 315 Operands are enumerated, however it may be possible to add some 316 at runtime, thus OPNUM is not an enum type but rather an int. 317 Returns NULL if OPNUM is not supported by the currently selected 318 mach/isa. */ 319 320const CGEN_OPERAND * 321cgen_operand_lookup_by_num (CGEN_CPU_DESC cd, int opnum) 322{ 323 return cd->operand_table.entries[opnum]; 324} 325 326/* Instruction support. */ 327 328/* Return number of instructions. This includes any added at runtime. */ 329 330int 331cgen_insn_count (CGEN_CPU_DESC cd) 332{ 333 int count = cd->insn_table.num_init_entries; 334 CGEN_INSN_LIST *rt_insns = cd->insn_table.new_entries; 335 336 for ( ; rt_insns != NULL; rt_insns = rt_insns->next) 337 ++count; 338 339 return count; 340} 341 342/* Return number of macro-instructions. 343 This includes any added at runtime. */ 344 345int 346cgen_macro_insn_count (CGEN_CPU_DESC cd) 347{ 348 int count = cd->macro_insn_table.num_init_entries; 349 CGEN_INSN_LIST *rt_insns = cd->macro_insn_table.new_entries; 350 351 for ( ; rt_insns != NULL; rt_insns = rt_insns->next) 352 ++count; 353 354 return count; 355} 356 357/* Cover function to read and properly byteswap an insn value. */ 358 359CGEN_INSN_INT 360cgen_get_insn_value (CGEN_CPU_DESC cd, unsigned char *buf, int length) 361{ 362 int big_p = (cd->insn_endian == CGEN_ENDIAN_BIG); 363 int insn_chunk_bitsize = cd->insn_chunk_bitsize; 364 CGEN_INSN_INT value = 0; 365 366 if (insn_chunk_bitsize != 0 && insn_chunk_bitsize < length) 367 { 368 /* We need to divide up the incoming value into insn_chunk_bitsize-length 369 segments, and endian-convert them, one at a time. */ 370 int i; 371 372 /* Enforce divisibility. */ 373 if ((length % insn_chunk_bitsize) != 0) 374 abort (); 375 376 for (i = 0; i < length; i += insn_chunk_bitsize) /* NB: i == bits */ 377 { 378 int bit_index; 379 bfd_vma this_value; 380 381 bit_index = i; /* NB: not dependent on endianness; opposite of cgen_put_insn_value! */ 382 this_value = bfd_get_bits (& buf[bit_index / 8], insn_chunk_bitsize, big_p); 383 value = (value << insn_chunk_bitsize) | this_value; 384 } 385 } 386 else 387 { 388 value = bfd_get_bits (buf, length, cd->insn_endian == CGEN_ENDIAN_BIG); 389 } 390 391 return value; 392} 393 394/* Cover function to store an insn value properly byteswapped. */ 395 396void 397cgen_put_insn_value (CGEN_CPU_DESC cd, 398 unsigned char *buf, 399 int length, 400 CGEN_INSN_INT value) 401{ 402 int big_p = (cd->insn_endian == CGEN_ENDIAN_BIG); 403 int insn_chunk_bitsize = cd->insn_chunk_bitsize; 404 405 if (insn_chunk_bitsize != 0 && insn_chunk_bitsize < length) 406 { 407 /* We need to divide up the incoming value into insn_chunk_bitsize-length 408 segments, and endian-convert them, one at a time. */ 409 int i; 410 411 /* Enforce divisibility. */ 412 if ((length % insn_chunk_bitsize) != 0) 413 abort (); 414 415 for (i = 0; i < length; i += insn_chunk_bitsize) /* NB: i == bits */ 416 { 417 int bit_index; 418 419 bit_index = (length - insn_chunk_bitsize - i); /* NB: not dependent on endianness! */ 420 bfd_put_bits ((bfd_vma) value, & buf[bit_index / 8], insn_chunk_bitsize, big_p); 421 value >>= insn_chunk_bitsize; 422 } 423 } 424 else 425 { 426 bfd_put_bits ((bfd_vma) value, buf, length, big_p); 427 } 428} 429 430/* Look up instruction INSN_*_VALUE and extract its fields. 431 INSN_INT_VALUE is used if CGEN_INT_INSN_P. 432 Otherwise INSN_BYTES_VALUE is used. 433 INSN, if non-null, is the insn table entry. 434 Otherwise INSN_*_VALUE is examined to compute it. 435 LENGTH is the bit length of INSN_*_VALUE if known, otherwise 0. 436 0 is only valid if `insn == NULL && ! CGEN_INT_INSN_P'. 437 If INSN != NULL, LENGTH must be valid. 438 ALIAS_P is non-zero if alias insns are to be included in the search. 439 440 The result is a pointer to the insn table entry, or NULL if the instruction 441 wasn't recognized. */ 442 443/* ??? Will need to be revisited for VLIW architectures. */ 444 445const CGEN_INSN * 446cgen_lookup_insn (CGEN_CPU_DESC cd, 447 const CGEN_INSN *insn, 448 CGEN_INSN_INT insn_int_value, 449 /* ??? CGEN_INSN_BYTES would be a nice type name to use here. */ 450 unsigned char *insn_bytes_value, 451 int length, 452 CGEN_FIELDS *fields, 453 int alias_p) 454{ 455 CGEN_EXTRACT_INFO ex_info; 456 CGEN_EXTRACT_INFO *info; 457 458 if (cd->int_insn_p) 459 { 460 info = NULL; 461 insn_bytes_value = (unsigned char *) xmalloc (cd->max_insn_bitsize / 8); 462 cgen_put_insn_value (cd, insn_bytes_value, length, insn_int_value); 463 } 464 else 465 { 466 info = &ex_info; 467 ex_info.dis_info = NULL; 468 ex_info.insn_bytes = insn_bytes_value; 469 ex_info.valid = -1; 470 insn_int_value = cgen_get_insn_value (cd, insn_bytes_value, length); 471 } 472 473 if (!insn) 474 { 475 const CGEN_INSN_LIST *insn_list; 476 477 /* The instructions are stored in hash lists. 478 Pick the first one and keep trying until we find the right one. */ 479 480 insn_list = cgen_dis_lookup_insn (cd, (char *) insn_bytes_value, 481 insn_int_value); 482 while (insn_list != NULL) 483 { 484 insn = insn_list->insn; 485 486 if (alias_p 487 /* FIXME: Ensure ALIAS attribute always has same index. */ 488 || ! CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_ALIAS)) 489 { 490 /* Basic bit mask must be correct. */ 491 /* ??? May wish to allow target to defer this check until the 492 extract handler. */ 493 if ((insn_int_value & CGEN_INSN_BASE_MASK (insn)) 494 == CGEN_INSN_BASE_VALUE (insn)) 495 { 496 /* ??? 0 is passed for `pc' */ 497 int elength = CGEN_EXTRACT_FN (cd, insn) 498 (cd, insn, info, insn_int_value, fields, (bfd_vma) 0); 499 if (elength > 0) 500 { 501 /* sanity check */ 502 if (length != 0 && length != elength) 503 abort (); 504 break; 505 } 506 } 507 } 508 509 insn_list = insn_list->next; 510 } 511 } 512 else 513 { 514 /* Sanity check: can't pass an alias insn if ! alias_p. */ 515 if (! alias_p 516 && CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_ALIAS)) 517 abort (); 518 /* Sanity check: length must be correct. */ 519 if (length != CGEN_INSN_BITSIZE (insn)) 520 abort (); 521 522 /* ??? 0 is passed for `pc' */ 523 length = CGEN_EXTRACT_FN (cd, insn) 524 (cd, insn, info, insn_int_value, fields, (bfd_vma) 0); 525 /* Sanity check: must succeed. 526 Could relax this later if it ever proves useful. */ 527 if (length == 0) 528 abort (); 529 } 530 531 if (cd->int_insn_p) 532 free (insn_bytes_value); 533 534 return insn; 535} 536 537/* Fill in the operand instances used by INSN whose operands are FIELDS. 538 INDICES is a pointer to a buffer of MAX_OPERAND_INSTANCES ints to be filled 539 in. */ 540 541void 542cgen_get_insn_operands (CGEN_CPU_DESC cd, 543 const CGEN_INSN *insn, 544 const CGEN_FIELDS *fields, 545 int *indices) 546{ 547 const CGEN_OPINST *opinst; 548 int i; 549 550 if (insn->opinst == NULL) 551 abort (); 552 for (i = 0, opinst = insn->opinst; opinst->type != CGEN_OPINST_END; ++i, ++opinst) 553 { 554 enum cgen_operand_type op_type = opinst->op_type; 555 if (op_type == CGEN_OPERAND_NIL) 556 indices[i] = opinst->index; 557 else 558 indices[i] = (*cd->get_int_operand) (cd, op_type, fields); 559 } 560} 561 562/* Cover function to cgen_get_insn_operands when either INSN or FIELDS 563 isn't known. 564 The INSN, INSN_*_VALUE, and LENGTH arguments are passed to 565 cgen_lookup_insn unchanged. 566 INSN_INT_VALUE is used if CGEN_INT_INSN_P. 567 Otherwise INSN_BYTES_VALUE is used. 568 569 The result is the insn table entry or NULL if the instruction wasn't 570 recognized. */ 571 572const CGEN_INSN * 573cgen_lookup_get_insn_operands (CGEN_CPU_DESC cd, 574 const CGEN_INSN *insn, 575 CGEN_INSN_INT insn_int_value, 576 /* ??? CGEN_INSN_BYTES would be a nice type name to use here. */ 577 unsigned char *insn_bytes_value, 578 int length, 579 int *indices, 580 CGEN_FIELDS *fields) 581{ 582 /* Pass non-zero for ALIAS_P only if INSN != NULL. 583 If INSN == NULL, we want a real insn. */ 584 insn = cgen_lookup_insn (cd, insn, insn_int_value, insn_bytes_value, 585 length, fields, insn != NULL); 586 if (! insn) 587 return NULL; 588 589 cgen_get_insn_operands (cd, insn, fields, indices); 590 return insn; 591} 592 593/* Allow signed overflow of instruction fields. */ 594void 595cgen_set_signed_overflow_ok (CGEN_CPU_DESC cd) 596{ 597 cd->signed_overflow_ok_p = 1; 598} 599 600/* Generate an error message if a signed field in an instruction overflows. */ 601void 602cgen_clear_signed_overflow_ok (CGEN_CPU_DESC cd) 603{ 604 cd->signed_overflow_ok_p = 0; 605} 606 607/* Will an error message be generated if a signed field in an instruction overflows ? */ 608unsigned int 609cgen_signed_overflow_ok_p (CGEN_CPU_DESC cd) 610{ 611 return cd->signed_overflow_ok_p; 612} 613