1 /* Configurable Xtensa ISA support. 2 Copyright (C) 2003-2024 Free Software Foundation, Inc. 3 4 This file is part of BFD, the Binary File Descriptor library. 5 6 This program is free software; you can redistribute it and/or modify 7 it under the terms of the GNU General Public License as published by 8 the Free Software Foundation; either version 3 of the License, or 9 (at your option) any later version. 10 11 This program is distributed in the hope that it will be useful, 12 but WITHOUT ANY WARRANTY; without even the implied warranty of 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 GNU General Public License for more details. 15 16 You should have received a copy of the GNU General Public License 17 along with this program; if not, write to the Free Software 18 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, 19 MA 02110-1301, USA. */ 20 21 #include "sysdep.h" 22 #include "bfd.h" 23 #include "libbfd.h" 24 #include "xtensa-isa.h" 25 #include "xtensa-isa-internal.h" 26 #include "xtensa-dynconfig.h" 27 28 static xtensa_isa_status xtisa_errno; 29 static char xtisa_error_msg[1024]; 30 31 32 xtensa_isa_status 33 xtensa_isa_errno (xtensa_isa isa __attribute__ ((unused))) 34 { 35 return xtisa_errno; 36 } 37 38 39 char * 40 xtensa_isa_error_msg (xtensa_isa isa __attribute__ ((unused))) 41 { 42 return xtisa_error_msg; 43 } 44 45 46 #define CHECK_ALLOC(MEM,ERRVAL) \ 47 do { \ 48 if ((MEM) == 0) \ 49 { \ 50 xtisa_errno = xtensa_isa_out_of_memory; \ 51 strcpy (xtisa_error_msg, "out of memory"); \ 52 return (ERRVAL); \ 53 } \ 54 } while (0) 55 56 #define CHECK_ALLOC_FOR_INIT(MEM,ERRVAL,ERRNO_P,ERROR_MSG_P) \ 57 do { \ 58 if ((MEM) == 0) \ 59 { \ 60 xtisa_errno = xtensa_isa_out_of_memory; \ 61 strcpy (xtisa_error_msg, "out of memory"); \ 62 if (ERRNO_P) *(ERRNO_P) = xtisa_errno; \ 63 if (ERROR_MSG_P) *(ERROR_MSG_P) = xtisa_error_msg; \ 64 return (ERRVAL); \ 65 } \ 66 } while (0) 67 68 69 70 /* Instruction buffers. */ 72 73 int 74 xtensa_insnbuf_size (xtensa_isa isa) 75 { 76 xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa; 77 return intisa->insnbuf_size; 78 } 79 80 81 xtensa_insnbuf 82 xtensa_insnbuf_alloc (xtensa_isa isa) 83 { 84 xtensa_insnbuf result = (xtensa_insnbuf) 85 malloc (xtensa_insnbuf_size (isa) * sizeof (xtensa_insnbuf_word)); 86 CHECK_ALLOC (result, 0); 87 return result; 88 } 89 90 91 void 92 xtensa_insnbuf_free (xtensa_isa isa __attribute__ ((unused)), 93 xtensa_insnbuf buf) 94 { 95 free (buf); 96 } 97 98 99 /* Given <byte_index>, the index of a byte in a xtensa_insnbuf, our 100 internal representation of a xtensa instruction word, return the index of 101 its word and the bit index of its low order byte in the xtensa_insnbuf. */ 102 103 static inline int 104 byte_to_word_index (int byte_index) 105 { 106 return byte_index / sizeof (xtensa_insnbuf_word); 107 } 108 109 110 static inline int 111 byte_to_bit_index (int byte_index) 112 { 113 return (byte_index & 0x3) * 8; 114 } 115 116 117 /* Copy an instruction in the 32-bit words pointed at by "insn" to 118 characters pointed at by "cp". This is more complicated than you 119 might think because we want 16-bit instructions in bytes 2 & 3 for 120 big-endian configurations. This function allows us to specify 121 which byte in "insn" to start with and which way to increment, 122 allowing trivial implementation for both big- and little-endian 123 configurations....and it seems to make pretty good code for 124 both. */ 125 126 int 127 xtensa_insnbuf_to_chars (xtensa_isa isa, 128 const xtensa_insnbuf insn, 129 unsigned char *cp, 130 int num_chars) 131 { 132 xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa; 133 int insn_size = xtensa_isa_maxlength (isa); 134 int fence_post, start, increment, i, byte_count; 135 xtensa_format fmt; 136 137 if (num_chars == 0) 138 num_chars = insn_size; 139 140 if (intisa->is_big_endian) 141 { 142 start = insn_size - 1; 143 increment = -1; 144 } 145 else 146 { 147 start = 0; 148 increment = 1; 149 } 150 151 /* Find the instruction format. Do nothing if the buffer does not contain 152 a valid instruction since we need to know how many bytes to copy. */ 153 fmt = xtensa_format_decode (isa, insn); 154 if (fmt == XTENSA_UNDEFINED) 155 return XTENSA_UNDEFINED; 156 157 byte_count = xtensa_format_length (isa, fmt); 158 if (byte_count == XTENSA_UNDEFINED) 159 return XTENSA_UNDEFINED; 160 161 if (byte_count > num_chars) 162 { 163 xtisa_errno = xtensa_isa_buffer_overflow; 164 strcpy (xtisa_error_msg, "output buffer too small for instruction"); 165 return XTENSA_UNDEFINED; 166 } 167 168 fence_post = start + (byte_count * increment); 169 170 for (i = start; i != fence_post; i += increment, ++cp) 171 { 172 int word_inx = byte_to_word_index (i); 173 int bit_inx = byte_to_bit_index (i); 174 175 *cp = (insn[word_inx] >> bit_inx) & 0xff; 176 } 177 178 return byte_count; 179 } 180 181 182 /* Inward conversion from byte stream to xtensa_insnbuf. See 183 xtensa_insnbuf_to_chars for a discussion of why this is complicated 184 by endianness. */ 185 186 void 187 xtensa_insnbuf_from_chars (xtensa_isa isa, 188 xtensa_insnbuf insn, 189 const unsigned char *cp, 190 int num_chars) 191 { 192 xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa; 193 int max_size, insn_size, fence_post, start, increment, i; 194 195 max_size = xtensa_isa_maxlength (isa); 196 197 /* Decode the instruction length so we know how many bytes to read. */ 198 insn_size = (intisa->length_decode_fn) (cp); 199 if (insn_size == XTENSA_UNDEFINED) 200 { 201 /* This should never happen when the byte stream contains a 202 valid instruction. Just read the maximum number of bytes.... */ 203 insn_size = max_size; 204 } 205 206 if (num_chars == 0 || num_chars > insn_size) 207 num_chars = insn_size; 208 209 if (intisa->is_big_endian) 210 { 211 start = max_size - 1; 212 increment = -1; 213 } 214 else 215 { 216 start = 0; 217 increment = 1; 218 } 219 220 fence_post = start + (num_chars * increment); 221 memset (insn, 0, xtensa_insnbuf_size (isa) * sizeof (xtensa_insnbuf_word)); 222 223 for (i = start; i != fence_post; i += increment, ++cp) 224 { 225 int word_inx = byte_to_word_index (i); 226 int bit_inx = byte_to_bit_index (i); 227 228 insn[word_inx] |= (unsigned) (*cp & 0xff) << bit_inx; 229 } 230 } 231 232 233 /* ISA information. */ 235 236 extern xtensa_isa_internal xtensa_modules; 237 238 static xtensa_isa_internal *xtensa_get_modules (void) 239 { 240 static xtensa_isa_internal *modules; 241 242 if (!modules) 243 modules = (xtensa_isa_internal *) xtensa_load_config ("xtensa_modules", 244 &xtensa_modules, 245 NULL); 246 return modules; 247 } 248 249 xtensa_isa 250 xtensa_isa_init (xtensa_isa_status *errno_p, char **error_msg_p) 251 { 252 xtensa_isa_internal *isa = xtensa_get_modules (); 253 int n, is_user; 254 255 /* Set up the opcode name lookup table. */ 256 isa->opname_lookup_table = 257 bfd_malloc (isa->num_opcodes * sizeof (xtensa_lookup_entry)); 258 CHECK_ALLOC_FOR_INIT (isa->opname_lookup_table, NULL, errno_p, error_msg_p); 259 for (n = 0; n < isa->num_opcodes; n++) 260 { 261 isa->opname_lookup_table[n].key = isa->opcodes[n].name; 262 isa->opname_lookup_table[n].u.opcode = n; 263 } 264 qsort (isa->opname_lookup_table, isa->num_opcodes, 265 sizeof (xtensa_lookup_entry), xtensa_isa_name_compare); 266 267 /* Set up the state name lookup table. */ 268 isa->state_lookup_table = 269 bfd_malloc (isa->num_states * sizeof (xtensa_lookup_entry)); 270 CHECK_ALLOC_FOR_INIT (isa->state_lookup_table, NULL, errno_p, error_msg_p); 271 for (n = 0; n < isa->num_states; n++) 272 { 273 isa->state_lookup_table[n].key = isa->states[n].name; 274 isa->state_lookup_table[n].u.state = n; 275 } 276 qsort (isa->state_lookup_table, isa->num_states, 277 sizeof (xtensa_lookup_entry), xtensa_isa_name_compare); 278 279 /* Set up the sysreg name lookup table. */ 280 isa->sysreg_lookup_table = 281 bfd_malloc (isa->num_sysregs * sizeof (xtensa_lookup_entry)); 282 CHECK_ALLOC_FOR_INIT (isa->sysreg_lookup_table, NULL, errno_p, error_msg_p); 283 for (n = 0; n < isa->num_sysregs; n++) 284 { 285 isa->sysreg_lookup_table[n].key = isa->sysregs[n].name; 286 isa->sysreg_lookup_table[n].u.sysreg = n; 287 } 288 qsort (isa->sysreg_lookup_table, isa->num_sysregs, 289 sizeof (xtensa_lookup_entry), xtensa_isa_name_compare); 290 291 /* Set up the user & system sysreg number tables. */ 292 for (is_user = 0; is_user < 2; is_user++) 293 { 294 isa->sysreg_table[is_user] = 295 bfd_malloc ((isa->max_sysreg_num[is_user] + 1) 296 * sizeof (xtensa_sysreg)); 297 CHECK_ALLOC_FOR_INIT (isa->sysreg_table[is_user], NULL, 298 errno_p, error_msg_p); 299 300 for (n = 0; n <= isa->max_sysreg_num[is_user]; n++) 301 isa->sysreg_table[is_user][n] = XTENSA_UNDEFINED; 302 } 303 for (n = 0; n < isa->num_sysregs; n++) 304 { 305 xtensa_sysreg_internal *sreg = &isa->sysregs[n]; 306 is_user = sreg->is_user; 307 308 if (sreg->number >= 0) 309 isa->sysreg_table[is_user][sreg->number] = n; 310 } 311 312 /* Set up the interface lookup table. */ 313 isa->interface_lookup_table = 314 bfd_malloc (isa->num_interfaces * sizeof (xtensa_lookup_entry)); 315 CHECK_ALLOC_FOR_INIT (isa->interface_lookup_table, NULL, errno_p, 316 error_msg_p); 317 for (n = 0; n < isa->num_interfaces; n++) 318 { 319 isa->interface_lookup_table[n].key = isa->interfaces[n].name; 320 isa->interface_lookup_table[n].u.intf = n; 321 } 322 qsort (isa->interface_lookup_table, isa->num_interfaces, 323 sizeof (xtensa_lookup_entry), xtensa_isa_name_compare); 324 325 /* Set up the funcUnit lookup table. */ 326 isa->funcUnit_lookup_table = 327 bfd_malloc (isa->num_funcUnits * sizeof (xtensa_lookup_entry)); 328 CHECK_ALLOC_FOR_INIT (isa->funcUnit_lookup_table, NULL, errno_p, 329 error_msg_p); 330 for (n = 0; n < isa->num_funcUnits; n++) 331 { 332 isa->funcUnit_lookup_table[n].key = isa->funcUnits[n].name; 333 isa->funcUnit_lookup_table[n].u.fun = n; 334 } 335 qsort (isa->funcUnit_lookup_table, isa->num_funcUnits, 336 sizeof (xtensa_lookup_entry), xtensa_isa_name_compare); 337 338 isa->insnbuf_size = ((isa->insn_size + sizeof (xtensa_insnbuf_word) - 1) / 339 sizeof (xtensa_insnbuf_word)); 340 341 return (xtensa_isa) isa; 342 } 343 344 345 void 346 xtensa_isa_free (xtensa_isa isa) 347 { 348 xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa; 349 int n; 350 351 /* With this version of the code, the xtensa_isa structure is not 352 dynamically allocated, so this function is not essential. Free 353 the memory allocated by xtensa_isa_init and restore the xtensa_isa 354 structure to its initial state. */ 355 356 free (intisa->opname_lookup_table); 357 intisa->opname_lookup_table = 0; 358 359 free (intisa->state_lookup_table); 360 intisa->state_lookup_table = 0; 361 362 free (intisa->sysreg_lookup_table); 363 intisa->sysreg_lookup_table = 0; 364 365 for (n = 0; n < 2; n++) 366 { 367 free (intisa->sysreg_table[n]); 368 intisa->sysreg_table[n] = 0; 369 } 370 371 free (intisa->interface_lookup_table); 372 intisa->interface_lookup_table = 0; 373 374 free (intisa->funcUnit_lookup_table); 375 intisa->funcUnit_lookup_table = 0; 376 } 377 378 379 int 380 xtensa_isa_name_compare (const void *v1, const void *v2) 381 { 382 xtensa_lookup_entry *e1 = (xtensa_lookup_entry *) v1; 383 xtensa_lookup_entry *e2 = (xtensa_lookup_entry *) v2; 384 385 return strcasecmp (e1->key, e2->key); 386 } 387 388 389 int 390 xtensa_isa_maxlength (xtensa_isa isa) 391 { 392 xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa; 393 return intisa->insn_size; 394 } 395 396 397 int 398 xtensa_isa_length_from_chars (xtensa_isa isa, const unsigned char *cp) 399 { 400 xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa; 401 return (intisa->length_decode_fn) (cp); 402 } 403 404 405 int 406 xtensa_isa_num_pipe_stages (xtensa_isa isa) 407 { 408 xtensa_opcode opcode; 409 xtensa_funcUnit_use *use; 410 int num_opcodes, num_uses; 411 int i, stage; 412 static int max_stage = XTENSA_UNDEFINED; 413 414 /* Only compute the value once. */ 415 if (max_stage != XTENSA_UNDEFINED) 416 return max_stage + 1; 417 418 num_opcodes = xtensa_isa_num_opcodes (isa); 419 for (opcode = 0; opcode < num_opcodes; opcode++) 420 { 421 num_uses = xtensa_opcode_num_funcUnit_uses (isa, opcode); 422 for (i = 0; i < num_uses; i++) 423 { 424 use = xtensa_opcode_funcUnit_use (isa, opcode, i); 425 stage = use->stage; 426 if (stage > max_stage) 427 max_stage = stage; 428 } 429 } 430 431 return max_stage + 1; 432 } 433 434 435 int 436 xtensa_isa_num_formats (xtensa_isa isa) 437 { 438 xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa; 439 return intisa->num_formats; 440 } 441 442 443 int 444 xtensa_isa_num_opcodes (xtensa_isa isa) 445 { 446 xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa; 447 return intisa->num_opcodes; 448 } 449 450 451 int 452 xtensa_isa_num_regfiles (xtensa_isa isa) 453 { 454 xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa; 455 return intisa->num_regfiles; 456 } 457 458 459 int 460 xtensa_isa_num_states (xtensa_isa isa) 461 { 462 xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa; 463 return intisa->num_states; 464 } 465 466 467 int 468 xtensa_isa_num_sysregs (xtensa_isa isa) 469 { 470 xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa; 471 return intisa->num_sysregs; 472 } 473 474 475 int 476 xtensa_isa_num_interfaces (xtensa_isa isa) 477 { 478 xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa; 479 return intisa->num_interfaces; 480 } 481 482 483 int 484 xtensa_isa_num_funcUnits (xtensa_isa isa) 485 { 486 xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa; 487 return intisa->num_funcUnits; 488 } 489 490 491 492 /* Instruction formats. */ 494 495 496 #define CHECK_FORMAT(INTISA,FMT,ERRVAL) \ 497 do { \ 498 if ((FMT) < 0 || (FMT) >= (INTISA)->num_formats) \ 499 { \ 500 xtisa_errno = xtensa_isa_bad_format; \ 501 strcpy (xtisa_error_msg, "invalid format specifier"); \ 502 return (ERRVAL); \ 503 } \ 504 } while (0) 505 506 507 #define CHECK_SLOT(INTISA,FMT,SLOT,ERRVAL) \ 508 do { \ 509 if ((SLOT) < 0 || (SLOT) >= (INTISA)->formats[FMT].num_slots) \ 510 { \ 511 xtisa_errno = xtensa_isa_bad_slot; \ 512 strcpy (xtisa_error_msg, "invalid slot specifier"); \ 513 return (ERRVAL); \ 514 } \ 515 } while (0) 516 517 518 const char * 519 xtensa_format_name (xtensa_isa isa, xtensa_format fmt) 520 { 521 xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa; 522 CHECK_FORMAT (intisa, fmt, NULL); 523 return intisa->formats[fmt].name; 524 } 525 526 527 xtensa_format 528 xtensa_format_lookup (xtensa_isa isa, const char *fmtname) 529 { 530 xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa; 531 int fmt; 532 533 if (!fmtname || !*fmtname) 534 { 535 xtisa_errno = xtensa_isa_bad_format; 536 strcpy (xtisa_error_msg, "invalid format name"); 537 return XTENSA_UNDEFINED; 538 } 539 540 for (fmt = 0; fmt < intisa->num_formats; fmt++) 541 { 542 if (strcasecmp (fmtname, intisa->formats[fmt].name) == 0) 543 return fmt; 544 } 545 546 xtisa_errno = xtensa_isa_bad_format; 547 sprintf (xtisa_error_msg, "format \"%s\" not recognized", fmtname); 548 return XTENSA_UNDEFINED; 549 } 550 551 552 xtensa_format 553 xtensa_format_decode (xtensa_isa isa, const xtensa_insnbuf insn) 554 { 555 xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa; 556 xtensa_format fmt; 557 558 fmt = (intisa->format_decode_fn) (insn); 559 if (fmt != XTENSA_UNDEFINED) 560 return fmt; 561 562 xtisa_errno = xtensa_isa_bad_format; 563 strcpy (xtisa_error_msg, "cannot decode instruction format"); 564 return XTENSA_UNDEFINED; 565 } 566 567 568 int 569 xtensa_format_encode (xtensa_isa isa, xtensa_format fmt, xtensa_insnbuf insn) 570 { 571 xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa; 572 CHECK_FORMAT (intisa, fmt, -1); 573 (*intisa->formats[fmt].encode_fn) (insn); 574 return 0; 575 } 576 577 578 int 579 xtensa_format_length (xtensa_isa isa, xtensa_format fmt) 580 { 581 xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa; 582 CHECK_FORMAT (intisa, fmt, XTENSA_UNDEFINED); 583 return intisa->formats[fmt].length; 584 } 585 586 587 int 588 xtensa_format_num_slots (xtensa_isa isa, xtensa_format fmt) 589 { 590 xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa; 591 CHECK_FORMAT (intisa, fmt, XTENSA_UNDEFINED); 592 return intisa->formats[fmt].num_slots; 593 } 594 595 596 xtensa_opcode 597 xtensa_format_slot_nop_opcode (xtensa_isa isa, xtensa_format fmt, int slot) 598 { 599 xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa; 600 int slot_id; 601 602 CHECK_FORMAT (intisa, fmt, XTENSA_UNDEFINED); 603 CHECK_SLOT (intisa, fmt, slot, XTENSA_UNDEFINED); 604 605 slot_id = intisa->formats[fmt].slot_id[slot]; 606 return xtensa_opcode_lookup (isa, intisa->slots[slot_id].nop_name); 607 } 608 609 610 int 611 xtensa_format_get_slot (xtensa_isa isa, xtensa_format fmt, int slot, 612 const xtensa_insnbuf insn, xtensa_insnbuf slotbuf) 613 { 614 xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa; 615 int slot_id; 616 617 CHECK_FORMAT (intisa, fmt, -1); 618 CHECK_SLOT (intisa, fmt, slot, -1); 619 620 slot_id = intisa->formats[fmt].slot_id[slot]; 621 (*intisa->slots[slot_id].get_fn) (insn, slotbuf); 622 return 0; 623 } 624 625 626 int 627 xtensa_format_set_slot (xtensa_isa isa, xtensa_format fmt, int slot, 628 xtensa_insnbuf insn, const xtensa_insnbuf slotbuf) 629 { 630 xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa; 631 int slot_id; 632 633 CHECK_FORMAT (intisa, fmt, -1); 634 CHECK_SLOT (intisa, fmt, slot, -1); 635 636 slot_id = intisa->formats[fmt].slot_id[slot]; 637 (*intisa->slots[slot_id].set_fn) (insn, slotbuf); 638 return 0; 639 } 640 641 642 643 /* Opcode information. */ 645 646 647 #define CHECK_OPCODE(INTISA,OPC,ERRVAL) \ 648 do { \ 649 if ((OPC) < 0 || (OPC) >= (INTISA)->num_opcodes) \ 650 { \ 651 xtisa_errno = xtensa_isa_bad_opcode; \ 652 strcpy (xtisa_error_msg, "invalid opcode specifier"); \ 653 return (ERRVAL); \ 654 } \ 655 } while (0) 656 657 658 xtensa_opcode 659 xtensa_opcode_lookup (xtensa_isa isa, const char *opname) 660 { 661 xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa; 662 xtensa_lookup_entry entry, *result = 0; 663 664 if (!opname || !*opname) 665 { 666 xtisa_errno = xtensa_isa_bad_opcode; 667 strcpy (xtisa_error_msg, "invalid opcode name"); 668 return XTENSA_UNDEFINED; 669 } 670 671 if (intisa->num_opcodes != 0) 672 { 673 entry.key = opname; 674 result = bsearch (&entry, intisa->opname_lookup_table, 675 intisa->num_opcodes, sizeof (xtensa_lookup_entry), 676 xtensa_isa_name_compare); 677 } 678 679 if (!result) 680 { 681 xtisa_errno = xtensa_isa_bad_opcode; 682 sprintf (xtisa_error_msg, "opcode \"%s\" not recognized", opname); 683 return XTENSA_UNDEFINED; 684 } 685 686 return result->u.opcode; 687 } 688 689 690 xtensa_opcode 691 xtensa_opcode_decode (xtensa_isa isa, xtensa_format fmt, int slot, 692 const xtensa_insnbuf slotbuf) 693 { 694 xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa; 695 int slot_id; 696 xtensa_opcode opc; 697 698 CHECK_FORMAT (intisa, fmt, XTENSA_UNDEFINED); 699 CHECK_SLOT (intisa, fmt, slot, XTENSA_UNDEFINED); 700 701 slot_id = intisa->formats[fmt].slot_id[slot]; 702 703 opc = (intisa->slots[slot_id].opcode_decode_fn) (slotbuf); 704 if (opc != XTENSA_UNDEFINED) 705 return opc; 706 707 xtisa_errno = xtensa_isa_bad_opcode; 708 strcpy (xtisa_error_msg, "cannot decode opcode"); 709 return XTENSA_UNDEFINED; 710 } 711 712 713 int 714 xtensa_opcode_encode (xtensa_isa isa, xtensa_format fmt, int slot, 715 xtensa_insnbuf slotbuf, xtensa_opcode opc) 716 { 717 xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa; 718 int slot_id; 719 xtensa_opcode_encode_fn encode_fn; 720 721 CHECK_FORMAT (intisa, fmt, -1); 722 CHECK_SLOT (intisa, fmt, slot, -1); 723 CHECK_OPCODE (intisa, opc, -1); 724 725 slot_id = intisa->formats[fmt].slot_id[slot]; 726 encode_fn = intisa->opcodes[opc].encode_fns[slot_id]; 727 if (!encode_fn) 728 { 729 xtisa_errno = xtensa_isa_wrong_slot; 730 sprintf (xtisa_error_msg, 731 "opcode \"%s\" is not allowed in slot %d of format \"%s\"", 732 intisa->opcodes[opc].name, slot, intisa->formats[fmt].name); 733 return -1; 734 } 735 (*encode_fn) (slotbuf); 736 return 0; 737 } 738 739 740 const char * 741 xtensa_opcode_name (xtensa_isa isa, xtensa_opcode opc) 742 { 743 xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa; 744 CHECK_OPCODE (intisa, opc, NULL); 745 return intisa->opcodes[opc].name; 746 } 747 748 749 int 750 xtensa_opcode_is_branch (xtensa_isa isa, xtensa_opcode opc) 751 { 752 xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa; 753 CHECK_OPCODE (intisa, opc, XTENSA_UNDEFINED); 754 if ((intisa->opcodes[opc].flags & XTENSA_OPCODE_IS_BRANCH) != 0) 755 return 1; 756 return 0; 757 } 758 759 760 int 761 xtensa_opcode_is_jump (xtensa_isa isa, xtensa_opcode opc) 762 { 763 xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa; 764 CHECK_OPCODE (intisa, opc, XTENSA_UNDEFINED); 765 if ((intisa->opcodes[opc].flags & XTENSA_OPCODE_IS_JUMP) != 0) 766 return 1; 767 return 0; 768 } 769 770 771 int 772 xtensa_opcode_is_loop (xtensa_isa isa, xtensa_opcode opc) 773 { 774 xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa; 775 CHECK_OPCODE (intisa, opc, XTENSA_UNDEFINED); 776 if ((intisa->opcodes[opc].flags & XTENSA_OPCODE_IS_LOOP) != 0) 777 return 1; 778 return 0; 779 } 780 781 782 int 783 xtensa_opcode_is_call (xtensa_isa isa, xtensa_opcode opc) 784 { 785 xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa; 786 CHECK_OPCODE (intisa, opc, XTENSA_UNDEFINED); 787 if ((intisa->opcodes[opc].flags & XTENSA_OPCODE_IS_CALL) != 0) 788 return 1; 789 return 0; 790 } 791 792 793 int 794 xtensa_opcode_num_operands (xtensa_isa isa, xtensa_opcode opc) 795 { 796 xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa; 797 int iclass_id; 798 799 CHECK_OPCODE (intisa, opc, XTENSA_UNDEFINED); 800 iclass_id = intisa->opcodes[opc].iclass_id; 801 return intisa->iclasses[iclass_id].num_operands; 802 } 803 804 805 int 806 xtensa_opcode_num_stateOperands (xtensa_isa isa, xtensa_opcode opc) 807 { 808 xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa; 809 int iclass_id; 810 811 CHECK_OPCODE (intisa, opc, XTENSA_UNDEFINED); 812 iclass_id = intisa->opcodes[opc].iclass_id; 813 return intisa->iclasses[iclass_id].num_stateOperands; 814 } 815 816 817 int 818 xtensa_opcode_num_interfaceOperands (xtensa_isa isa, xtensa_opcode opc) 819 { 820 xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa; 821 int iclass_id; 822 823 CHECK_OPCODE (intisa, opc, XTENSA_UNDEFINED); 824 iclass_id = intisa->opcodes[opc].iclass_id; 825 return intisa->iclasses[iclass_id].num_interfaceOperands; 826 } 827 828 829 int 830 xtensa_opcode_num_funcUnit_uses (xtensa_isa isa, xtensa_opcode opc) 831 { 832 xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa; 833 CHECK_OPCODE (intisa, opc, XTENSA_UNDEFINED); 834 return intisa->opcodes[opc].num_funcUnit_uses; 835 } 836 837 838 xtensa_funcUnit_use * 839 xtensa_opcode_funcUnit_use (xtensa_isa isa, xtensa_opcode opc, int u) 840 { 841 xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa; 842 CHECK_OPCODE (intisa, opc, NULL); 843 if (u < 0 || u >= intisa->opcodes[opc].num_funcUnit_uses) 844 { 845 xtisa_errno = xtensa_isa_bad_funcUnit; 846 sprintf (xtisa_error_msg, "invalid functional unit use number (%d); " 847 "opcode \"%s\" has %d", u, intisa->opcodes[opc].name, 848 intisa->opcodes[opc].num_funcUnit_uses); 849 return NULL; 850 } 851 return &intisa->opcodes[opc].funcUnit_uses[u]; 852 } 853 854 855 856 /* Operand information. */ 858 859 860 #define CHECK_OPERAND(INTISA,OPC,ICLASS,OPND,ERRVAL) \ 861 do { \ 862 if ((OPND) < 0 || (OPND) >= (ICLASS)->num_operands) \ 863 { \ 864 xtisa_errno = xtensa_isa_bad_operand; \ 865 sprintf (xtisa_error_msg, "invalid operand number (%d); " \ 866 "opcode \"%s\" has %d operands", (OPND), \ 867 (INTISA)->opcodes[(OPC)].name, (ICLASS)->num_operands); \ 868 return (ERRVAL); \ 869 } \ 870 } while (0) 871 872 873 static xtensa_operand_internal * 874 get_operand (xtensa_isa_internal *intisa, xtensa_opcode opc, int opnd) 875 { 876 xtensa_iclass_internal *iclass; 877 int iclass_id, operand_id; 878 879 CHECK_OPCODE (intisa, opc, NULL); 880 iclass_id = intisa->opcodes[opc].iclass_id; 881 iclass = &intisa->iclasses[iclass_id]; 882 CHECK_OPERAND (intisa, opc, iclass, opnd, NULL); 883 operand_id = iclass->operands[opnd].u.operand_id; 884 return &intisa->operands[operand_id]; 885 } 886 887 888 const char * 889 xtensa_operand_name (xtensa_isa isa, xtensa_opcode opc, int opnd) 890 { 891 xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa; 892 xtensa_operand_internal *intop; 893 894 intop = get_operand (intisa, opc, opnd); 895 if (!intop) return NULL; 896 return intop->name; 897 } 898 899 900 int 901 xtensa_operand_is_visible (xtensa_isa isa, xtensa_opcode opc, int opnd) 902 { 903 xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa; 904 xtensa_iclass_internal *iclass; 905 int iclass_id, operand_id; 906 xtensa_operand_internal *intop; 907 908 CHECK_OPCODE (intisa, opc, XTENSA_UNDEFINED); 909 iclass_id = intisa->opcodes[opc].iclass_id; 910 iclass = &intisa->iclasses[iclass_id]; 911 CHECK_OPERAND (intisa, opc, iclass, opnd, XTENSA_UNDEFINED); 912 913 /* Special case for "sout" operands. */ 914 if (iclass->operands[opnd].inout == 's') 915 return 0; 916 917 operand_id = iclass->operands[opnd].u.operand_id; 918 intop = &intisa->operands[operand_id]; 919 920 if ((intop->flags & XTENSA_OPERAND_IS_INVISIBLE) == 0) 921 return 1; 922 return 0; 923 } 924 925 926 char 927 xtensa_operand_inout (xtensa_isa isa, xtensa_opcode opc, int opnd) 928 { 929 xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa; 930 xtensa_iclass_internal *iclass; 931 int iclass_id; 932 char inout; 933 934 CHECK_OPCODE (intisa, opc, 0); 935 iclass_id = intisa->opcodes[opc].iclass_id; 936 iclass = &intisa->iclasses[iclass_id]; 937 CHECK_OPERAND (intisa, opc, iclass, opnd, 0); 938 inout = iclass->operands[opnd].inout; 939 940 /* Special case for "sout" operands. */ 941 if (inout == 's') 942 return 'o'; 943 944 return inout; 945 } 946 947 948 int 949 xtensa_operand_get_field (xtensa_isa isa, xtensa_opcode opc, int opnd, 950 xtensa_format fmt, int slot, 951 const xtensa_insnbuf slotbuf, uint32 *valp) 952 { 953 xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa; 954 xtensa_operand_internal *intop; 955 int slot_id; 956 xtensa_get_field_fn get_fn; 957 958 intop = get_operand (intisa, opc, opnd); 959 if (!intop) return -1; 960 961 CHECK_FORMAT (intisa, fmt, -1); 962 CHECK_SLOT (intisa, fmt, slot, -1); 963 964 slot_id = intisa->formats[fmt].slot_id[slot]; 965 if (intop->field_id == XTENSA_UNDEFINED) 966 { 967 xtisa_errno = xtensa_isa_no_field; 968 strcpy (xtisa_error_msg, "implicit operand has no field"); 969 return -1; 970 } 971 get_fn = intisa->slots[slot_id].get_field_fns[intop->field_id]; 972 if (!get_fn) 973 { 974 xtisa_errno = xtensa_isa_wrong_slot; 975 sprintf (xtisa_error_msg, 976 "operand \"%s\" does not exist in slot %d of format \"%s\"", 977 intop->name, slot, intisa->formats[fmt].name); 978 return -1; 979 } 980 *valp = (*get_fn) (slotbuf); 981 return 0; 982 } 983 984 985 int 986 xtensa_operand_set_field (xtensa_isa isa, xtensa_opcode opc, int opnd, 987 xtensa_format fmt, int slot, 988 xtensa_insnbuf slotbuf, uint32 val) 989 { 990 xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa; 991 xtensa_operand_internal *intop; 992 int slot_id; 993 xtensa_set_field_fn set_fn; 994 995 intop = get_operand (intisa, opc, opnd); 996 if (!intop) return -1; 997 998 CHECK_FORMAT (intisa, fmt, -1); 999 CHECK_SLOT (intisa, fmt, slot, -1); 1000 1001 slot_id = intisa->formats[fmt].slot_id[slot]; 1002 if (intop->field_id == XTENSA_UNDEFINED) 1003 { 1004 xtisa_errno = xtensa_isa_no_field; 1005 strcpy (xtisa_error_msg, "implicit operand has no field"); 1006 return -1; 1007 } 1008 set_fn = intisa->slots[slot_id].set_field_fns[intop->field_id]; 1009 if (!set_fn) 1010 { 1011 xtisa_errno = xtensa_isa_wrong_slot; 1012 sprintf (xtisa_error_msg, 1013 "operand \"%s\" does not exist in slot %d of format \"%s\"", 1014 intop->name, slot, intisa->formats[fmt].name); 1015 return -1; 1016 } 1017 (*set_fn) (slotbuf, val); 1018 return 0; 1019 } 1020 1021 1022 int 1023 xtensa_operand_encode (xtensa_isa isa, xtensa_opcode opc, int opnd, 1024 uint32 *valp) 1025 { 1026 xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa; 1027 xtensa_operand_internal *intop; 1028 uint32 test_val, orig_val; 1029 1030 intop = get_operand (intisa, opc, opnd); 1031 if (!intop) 1032 return -1; 1033 1034 if (!intop->encode) 1035 { 1036 /* This is a default operand for a field. How can we tell if the 1037 value fits in the field? Write the value into the field, 1038 read it back, and then make sure we get the same value. */ 1039 static xtensa_insnbuf tmpbuf = 0; 1040 int slot_id; 1041 1042 if (!tmpbuf) 1043 { 1044 tmpbuf = xtensa_insnbuf_alloc (isa); 1045 CHECK_ALLOC (tmpbuf, -1); 1046 } 1047 1048 /* A default operand is always associated with a field, 1049 but check just to be sure.... */ 1050 if (intop->field_id == XTENSA_UNDEFINED) 1051 { 1052 xtisa_errno = xtensa_isa_internal_error; 1053 strcpy (xtisa_error_msg, "operand has no field"); 1054 return -1; 1055 } 1056 1057 /* Find some slot that includes the field. */ 1058 for (slot_id = 0; slot_id < intisa->num_slots; slot_id++) 1059 { 1060 xtensa_get_field_fn get_fn = 1061 intisa->slots[slot_id].get_field_fns[intop->field_id]; 1062 xtensa_set_field_fn set_fn = 1063 intisa->slots[slot_id].set_field_fns[intop->field_id]; 1064 1065 if (get_fn && set_fn) 1066 { 1067 (*set_fn) (tmpbuf, *valp); 1068 return ((*get_fn) (tmpbuf) != *valp); 1069 } 1070 } 1071 1072 /* Couldn't find any slot containing the field.... */ 1073 xtisa_errno = xtensa_isa_no_field; 1074 strcpy (xtisa_error_msg, "field does not exist in any slot"); 1075 return -1; 1076 } 1077 1078 /* Encode the value. In some cases, the encoding function may detect 1079 errors, but most of the time the only way to determine if the value 1080 was successfully encoded is to decode it and check if it matches 1081 the original value. */ 1082 orig_val = *valp; 1083 if ((*intop->encode) (valp) 1084 || (test_val = *valp, (*intop->decode) (&test_val)) 1085 || test_val != orig_val) 1086 { 1087 xtisa_errno = xtensa_isa_bad_value; 1088 sprintf (xtisa_error_msg, "cannot encode operand value 0x%08x", *valp); 1089 return -1; 1090 } 1091 1092 return 0; 1093 } 1094 1095 1096 int 1097 xtensa_operand_decode (xtensa_isa isa, xtensa_opcode opc, int opnd, 1098 uint32 *valp) 1099 { 1100 xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa; 1101 xtensa_operand_internal *intop; 1102 1103 intop = get_operand (intisa, opc, opnd); 1104 if (!intop) return -1; 1105 1106 /* Use identity function for "default" operands. */ 1107 if (!intop->decode) 1108 return 0; 1109 1110 if ((*intop->decode) (valp)) 1111 { 1112 xtisa_errno = xtensa_isa_bad_value; 1113 sprintf (xtisa_error_msg, "cannot decode operand value 0x%08x", *valp); 1114 return -1; 1115 } 1116 return 0; 1117 } 1118 1119 1120 int 1121 xtensa_operand_is_register (xtensa_isa isa, xtensa_opcode opc, int opnd) 1122 { 1123 xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa; 1124 xtensa_operand_internal *intop; 1125 1126 intop = get_operand (intisa, opc, opnd); 1127 if (!intop) return XTENSA_UNDEFINED; 1128 1129 if ((intop->flags & XTENSA_OPERAND_IS_REGISTER) != 0) 1130 return 1; 1131 return 0; 1132 } 1133 1134 1135 xtensa_regfile 1136 xtensa_operand_regfile (xtensa_isa isa, xtensa_opcode opc, int opnd) 1137 { 1138 xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa; 1139 xtensa_operand_internal *intop; 1140 1141 intop = get_operand (intisa, opc, opnd); 1142 if (!intop) return XTENSA_UNDEFINED; 1143 1144 return intop->regfile; 1145 } 1146 1147 1148 int 1149 xtensa_operand_num_regs (xtensa_isa isa, xtensa_opcode opc, int opnd) 1150 { 1151 xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa; 1152 xtensa_operand_internal *intop; 1153 1154 intop = get_operand (intisa, opc, opnd); 1155 if (!intop) return XTENSA_UNDEFINED; 1156 1157 return intop->num_regs; 1158 } 1159 1160 1161 int 1162 xtensa_operand_is_known_reg (xtensa_isa isa, xtensa_opcode opc, int opnd) 1163 { 1164 xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa; 1165 xtensa_operand_internal *intop; 1166 1167 intop = get_operand (intisa, opc, opnd); 1168 if (!intop) return XTENSA_UNDEFINED; 1169 1170 if ((intop->flags & XTENSA_OPERAND_IS_UNKNOWN) == 0) 1171 return 1; 1172 return 0; 1173 } 1174 1175 1176 int 1177 xtensa_operand_is_PCrelative (xtensa_isa isa, xtensa_opcode opc, int opnd) 1178 { 1179 xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa; 1180 xtensa_operand_internal *intop; 1181 1182 intop = get_operand (intisa, opc, opnd); 1183 if (!intop) return XTENSA_UNDEFINED; 1184 1185 if ((intop->flags & XTENSA_OPERAND_IS_PCRELATIVE) != 0) 1186 return 1; 1187 return 0; 1188 } 1189 1190 1191 int 1192 xtensa_operand_do_reloc (xtensa_isa isa, xtensa_opcode opc, int opnd, 1193 uint32 *valp, uint32 pc) 1194 { 1195 xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa; 1196 xtensa_operand_internal *intop; 1197 1198 intop = get_operand (intisa, opc, opnd); 1199 if (!intop) return -1; 1200 1201 if ((intop->flags & XTENSA_OPERAND_IS_PCRELATIVE) == 0) 1202 return 0; 1203 1204 if (!intop->do_reloc) 1205 { 1206 xtisa_errno = xtensa_isa_internal_error; 1207 strcpy (xtisa_error_msg, "operand missing do_reloc function"); 1208 return -1; 1209 } 1210 1211 if ((*intop->do_reloc) (valp, pc)) 1212 { 1213 xtisa_errno = xtensa_isa_bad_value; 1214 sprintf (xtisa_error_msg, 1215 "do_reloc failed for value 0x%08x at PC 0x%08x", *valp, pc); 1216 return -1; 1217 } 1218 1219 return 0; 1220 } 1221 1222 1223 int 1224 xtensa_operand_undo_reloc (xtensa_isa isa, xtensa_opcode opc, int opnd, 1225 uint32 *valp, uint32 pc) 1226 { 1227 xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa; 1228 xtensa_operand_internal *intop; 1229 1230 intop = get_operand (intisa, opc, opnd); 1231 if (!intop) return -1; 1232 1233 if ((intop->flags & XTENSA_OPERAND_IS_PCRELATIVE) == 0) 1234 return 0; 1235 1236 if (!intop->undo_reloc) 1237 { 1238 xtisa_errno = xtensa_isa_internal_error; 1239 strcpy (xtisa_error_msg, "operand missing undo_reloc function"); 1240 return -1; 1241 } 1242 1243 if ((*intop->undo_reloc) (valp, pc)) 1244 { 1245 xtisa_errno = xtensa_isa_bad_value; 1246 sprintf (xtisa_error_msg, 1247 "undo_reloc failed for value 0x%08x at PC 0x%08x", *valp, pc); 1248 return -1; 1249 } 1250 1251 return 0; 1252 } 1253 1254 1255 1256 /* State Operands. */ 1258 1259 1260 #define CHECK_STATE_OPERAND(INTISA,OPC,ICLASS,STOP,ERRVAL) \ 1261 do { \ 1262 if ((STOP) < 0 || (STOP) >= (ICLASS)->num_stateOperands) \ 1263 { \ 1264 xtisa_errno = xtensa_isa_bad_operand; \ 1265 sprintf (xtisa_error_msg, "invalid state operand number (%d); " \ 1266 "opcode \"%s\" has %d state operands", (STOP), \ 1267 (INTISA)->opcodes[(OPC)].name, (ICLASS)->num_stateOperands); \ 1268 return (ERRVAL); \ 1269 } \ 1270 } while (0) 1271 1272 1273 xtensa_state 1274 xtensa_stateOperand_state (xtensa_isa isa, xtensa_opcode opc, int stOp) 1275 { 1276 xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa; 1277 xtensa_iclass_internal *iclass; 1278 int iclass_id; 1279 1280 CHECK_OPCODE (intisa, opc, XTENSA_UNDEFINED); 1281 iclass_id = intisa->opcodes[opc].iclass_id; 1282 iclass = &intisa->iclasses[iclass_id]; 1283 CHECK_STATE_OPERAND (intisa, opc, iclass, stOp, XTENSA_UNDEFINED); 1284 return iclass->stateOperands[stOp].u.state; 1285 } 1286 1287 1288 char 1289 xtensa_stateOperand_inout (xtensa_isa isa, xtensa_opcode opc, int stOp) 1290 { 1291 xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa; 1292 xtensa_iclass_internal *iclass; 1293 int iclass_id; 1294 1295 CHECK_OPCODE (intisa, opc, 0); 1296 iclass_id = intisa->opcodes[opc].iclass_id; 1297 iclass = &intisa->iclasses[iclass_id]; 1298 CHECK_STATE_OPERAND (intisa, opc, iclass, stOp, 0); 1299 return iclass->stateOperands[stOp].inout; 1300 } 1301 1302 1303 1304 /* Interface Operands. */ 1306 1307 1308 #define CHECK_INTERFACE_OPERAND(INTISA,OPC,ICLASS,IFOP,ERRVAL) \ 1309 do { \ 1310 if ((IFOP) < 0 || (IFOP) >= (ICLASS)->num_interfaceOperands) \ 1311 { \ 1312 xtisa_errno = xtensa_isa_bad_operand; \ 1313 sprintf (xtisa_error_msg, "invalid interface operand number (%d); " \ 1314 "opcode \"%s\" has %d interface operands", (IFOP), \ 1315 (INTISA)->opcodes[(OPC)].name, \ 1316 (ICLASS)->num_interfaceOperands); \ 1317 return (ERRVAL); \ 1318 } \ 1319 } while (0) 1320 1321 1322 xtensa_interface 1323 xtensa_interfaceOperand_interface (xtensa_isa isa, xtensa_opcode opc, 1324 int ifOp) 1325 { 1326 xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa; 1327 xtensa_iclass_internal *iclass; 1328 int iclass_id; 1329 1330 CHECK_OPCODE (intisa, opc, XTENSA_UNDEFINED); 1331 iclass_id = intisa->opcodes[opc].iclass_id; 1332 iclass = &intisa->iclasses[iclass_id]; 1333 CHECK_INTERFACE_OPERAND (intisa, opc, iclass, ifOp, XTENSA_UNDEFINED); 1334 return iclass->interfaceOperands[ifOp]; 1335 } 1336 1337 1338 1339 /* Register Files. */ 1341 1342 1343 #define CHECK_REGFILE(INTISA,RF,ERRVAL) \ 1344 do { \ 1345 if ((RF) < 0 || (RF) >= (INTISA)->num_regfiles) \ 1346 { \ 1347 xtisa_errno = xtensa_isa_bad_regfile; \ 1348 strcpy (xtisa_error_msg, "invalid regfile specifier"); \ 1349 return (ERRVAL); \ 1350 } \ 1351 } while (0) 1352 1353 1354 xtensa_regfile 1355 xtensa_regfile_lookup (xtensa_isa isa, const char *name) 1356 { 1357 xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa; 1358 int n; 1359 1360 if (!name || !*name) 1361 { 1362 xtisa_errno = xtensa_isa_bad_regfile; 1363 strcpy (xtisa_error_msg, "invalid regfile name"); 1364 return XTENSA_UNDEFINED; 1365 } 1366 1367 /* The expected number of regfiles is small; use a linear search. */ 1368 for (n = 0; n < intisa->num_regfiles; n++) 1369 { 1370 if (!filename_cmp (intisa->regfiles[n].name, name)) 1371 return n; 1372 } 1373 1374 xtisa_errno = xtensa_isa_bad_regfile; 1375 sprintf (xtisa_error_msg, "regfile \"%s\" not recognized", name); 1376 return XTENSA_UNDEFINED; 1377 } 1378 1379 1380 xtensa_regfile 1381 xtensa_regfile_lookup_shortname (xtensa_isa isa, const char *shortname) 1382 { 1383 xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa; 1384 int n; 1385 1386 if (!shortname || !*shortname) 1387 { 1388 xtisa_errno = xtensa_isa_bad_regfile; 1389 strcpy (xtisa_error_msg, "invalid regfile shortname"); 1390 return XTENSA_UNDEFINED; 1391 } 1392 1393 /* The expected number of regfiles is small; use a linear search. */ 1394 for (n = 0; n < intisa->num_regfiles; n++) 1395 { 1396 /* Ignore regfile views since they always have the same shortnames 1397 as their parents. */ 1398 if (intisa->regfiles[n].parent != n) 1399 continue; 1400 if (!filename_cmp (intisa->regfiles[n].shortname, shortname)) 1401 return n; 1402 } 1403 1404 xtisa_errno = xtensa_isa_bad_regfile; 1405 sprintf (xtisa_error_msg, "regfile shortname \"%s\" not recognized", 1406 shortname); 1407 return XTENSA_UNDEFINED; 1408 } 1409 1410 1411 const char * 1412 xtensa_regfile_name (xtensa_isa isa, xtensa_regfile rf) 1413 { 1414 xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa; 1415 CHECK_REGFILE (intisa, rf, NULL); 1416 return intisa->regfiles[rf].name; 1417 } 1418 1419 1420 const char * 1421 xtensa_regfile_shortname (xtensa_isa isa, xtensa_regfile rf) 1422 { 1423 xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa; 1424 CHECK_REGFILE (intisa, rf, NULL); 1425 return intisa->regfiles[rf].shortname; 1426 } 1427 1428 1429 xtensa_regfile 1430 xtensa_regfile_view_parent (xtensa_isa isa, xtensa_regfile rf) 1431 { 1432 xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa; 1433 CHECK_REGFILE (intisa, rf, XTENSA_UNDEFINED); 1434 return intisa->regfiles[rf].parent; 1435 } 1436 1437 1438 int 1439 xtensa_regfile_num_bits (xtensa_isa isa, xtensa_regfile rf) 1440 { 1441 xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa; 1442 CHECK_REGFILE (intisa, rf, XTENSA_UNDEFINED); 1443 return intisa->regfiles[rf].num_bits; 1444 } 1445 1446 1447 int 1448 xtensa_regfile_num_entries (xtensa_isa isa, xtensa_regfile rf) 1449 { 1450 xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa; 1451 CHECK_REGFILE (intisa, rf, XTENSA_UNDEFINED); 1452 return intisa->regfiles[rf].num_entries; 1453 } 1454 1455 1456 1457 /* Processor States. */ 1459 1460 1461 #define CHECK_STATE(INTISA,ST,ERRVAL) \ 1462 do { \ 1463 if ((ST) < 0 || (ST) >= (INTISA)->num_states) \ 1464 { \ 1465 xtisa_errno = xtensa_isa_bad_state; \ 1466 strcpy (xtisa_error_msg, "invalid state specifier"); \ 1467 return (ERRVAL); \ 1468 } \ 1469 } while (0) 1470 1471 1472 xtensa_state 1473 xtensa_state_lookup (xtensa_isa isa, const char *name) 1474 { 1475 xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa; 1476 xtensa_lookup_entry entry, *result = 0; 1477 1478 if (!name || !*name) 1479 { 1480 xtisa_errno = xtensa_isa_bad_state; 1481 strcpy (xtisa_error_msg, "invalid state name"); 1482 return XTENSA_UNDEFINED; 1483 } 1484 1485 if (intisa->num_states != 0) 1486 { 1487 entry.key = name; 1488 result = bsearch (&entry, intisa->state_lookup_table, intisa->num_states, 1489 sizeof (xtensa_lookup_entry), xtensa_isa_name_compare); 1490 } 1491 1492 if (!result) 1493 { 1494 xtisa_errno = xtensa_isa_bad_state; 1495 sprintf (xtisa_error_msg, "state \"%s\" not recognized", name); 1496 return XTENSA_UNDEFINED; 1497 } 1498 1499 return result->u.state; 1500 } 1501 1502 1503 const char * 1504 xtensa_state_name (xtensa_isa isa, xtensa_state st) 1505 { 1506 xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa; 1507 CHECK_STATE (intisa, st, NULL); 1508 return intisa->states[st].name; 1509 } 1510 1511 1512 int 1513 xtensa_state_num_bits (xtensa_isa isa, xtensa_state st) 1514 { 1515 xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa; 1516 CHECK_STATE (intisa, st, XTENSA_UNDEFINED); 1517 return intisa->states[st].num_bits; 1518 } 1519 1520 1521 int 1522 xtensa_state_is_exported (xtensa_isa isa, xtensa_state st) 1523 { 1524 xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa; 1525 CHECK_STATE (intisa, st, XTENSA_UNDEFINED); 1526 if ((intisa->states[st].flags & XTENSA_STATE_IS_EXPORTED) != 0) 1527 return 1; 1528 return 0; 1529 } 1530 1531 1532 int 1533 xtensa_state_is_shared_or (xtensa_isa isa, xtensa_state st) 1534 { 1535 xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa; 1536 CHECK_STATE (intisa, st, XTENSA_UNDEFINED); 1537 if ((intisa->states[st].flags & XTENSA_STATE_IS_SHARED_OR) != 0) 1538 return 1; 1539 return 0; 1540 } 1541 1542 1543 1544 /* Sysregs. */ 1546 1547 1548 #define CHECK_SYSREG(INTISA,SYSREG,ERRVAL) \ 1549 do { \ 1550 if ((SYSREG) < 0 || (SYSREG) >= (INTISA)->num_sysregs) \ 1551 { \ 1552 xtisa_errno = xtensa_isa_bad_sysreg; \ 1553 strcpy (xtisa_error_msg, "invalid sysreg specifier"); \ 1554 return (ERRVAL); \ 1555 } \ 1556 } while (0) 1557 1558 1559 xtensa_sysreg 1560 xtensa_sysreg_lookup (xtensa_isa isa, int num, int is_user) 1561 { 1562 xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa; 1563 1564 if (is_user != 0) 1565 is_user = 1; 1566 1567 if (num < 0 || num > intisa->max_sysreg_num[is_user] 1568 || intisa->sysreg_table[is_user][num] == XTENSA_UNDEFINED) 1569 { 1570 xtisa_errno = xtensa_isa_bad_sysreg; 1571 strcpy (xtisa_error_msg, "sysreg not recognized"); 1572 return XTENSA_UNDEFINED; 1573 } 1574 1575 return intisa->sysreg_table[is_user][num]; 1576 } 1577 1578 1579 xtensa_sysreg 1580 xtensa_sysreg_lookup_name (xtensa_isa isa, const char *name) 1581 { 1582 xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa; 1583 xtensa_lookup_entry entry, *result = 0; 1584 1585 if (!name || !*name) 1586 { 1587 xtisa_errno = xtensa_isa_bad_sysreg; 1588 strcpy (xtisa_error_msg, "invalid sysreg name"); 1589 return XTENSA_UNDEFINED; 1590 } 1591 1592 if (intisa->num_sysregs != 0) 1593 { 1594 entry.key = name; 1595 result = bsearch (&entry, intisa->sysreg_lookup_table, 1596 intisa->num_sysregs, sizeof (xtensa_lookup_entry), 1597 xtensa_isa_name_compare); 1598 } 1599 1600 if (!result) 1601 { 1602 xtisa_errno = xtensa_isa_bad_sysreg; 1603 sprintf (xtisa_error_msg, "sysreg \"%s\" not recognized", name); 1604 return XTENSA_UNDEFINED; 1605 } 1606 1607 return result->u.sysreg; 1608 } 1609 1610 1611 const char * 1612 xtensa_sysreg_name (xtensa_isa isa, xtensa_sysreg sysreg) 1613 { 1614 xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa; 1615 CHECK_SYSREG (intisa, sysreg, NULL); 1616 return intisa->sysregs[sysreg].name; 1617 } 1618 1619 1620 int 1621 xtensa_sysreg_number (xtensa_isa isa, xtensa_sysreg sysreg) 1622 { 1623 xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa; 1624 CHECK_SYSREG (intisa, sysreg, XTENSA_UNDEFINED); 1625 return intisa->sysregs[sysreg].number; 1626 } 1627 1628 1629 int 1630 xtensa_sysreg_is_user (xtensa_isa isa, xtensa_sysreg sysreg) 1631 { 1632 xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa; 1633 CHECK_SYSREG (intisa, sysreg, XTENSA_UNDEFINED); 1634 if (intisa->sysregs[sysreg].is_user) 1635 return 1; 1636 return 0; 1637 } 1638 1639 1640 1641 /* Interfaces. */ 1643 1644 1645 #define CHECK_INTERFACE(INTISA,INTF,ERRVAL) \ 1646 do { \ 1647 if ((INTF) < 0 || (INTF) >= (INTISA)->num_interfaces) \ 1648 { \ 1649 xtisa_errno = xtensa_isa_bad_interface; \ 1650 strcpy (xtisa_error_msg, "invalid interface specifier"); \ 1651 return (ERRVAL); \ 1652 } \ 1653 } while (0) 1654 1655 1656 xtensa_interface 1657 xtensa_interface_lookup (xtensa_isa isa, const char *ifname) 1658 { 1659 xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa; 1660 xtensa_lookup_entry entry, *result = 0; 1661 1662 if (!ifname || !*ifname) 1663 { 1664 xtisa_errno = xtensa_isa_bad_interface; 1665 strcpy (xtisa_error_msg, "invalid interface name"); 1666 return XTENSA_UNDEFINED; 1667 } 1668 1669 if (intisa->num_interfaces != 0) 1670 { 1671 entry.key = ifname; 1672 result = bsearch (&entry, intisa->interface_lookup_table, 1673 intisa->num_interfaces, sizeof (xtensa_lookup_entry), 1674 xtensa_isa_name_compare); 1675 } 1676 1677 if (!result) 1678 { 1679 xtisa_errno = xtensa_isa_bad_interface; 1680 sprintf (xtisa_error_msg, "interface \"%s\" not recognized", ifname); 1681 return XTENSA_UNDEFINED; 1682 } 1683 1684 return result->u.intf; 1685 } 1686 1687 1688 const char * 1689 xtensa_interface_name (xtensa_isa isa, xtensa_interface intf) 1690 { 1691 xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa; 1692 CHECK_INTERFACE (intisa, intf, NULL); 1693 return intisa->interfaces[intf].name; 1694 } 1695 1696 1697 int 1698 xtensa_interface_num_bits (xtensa_isa isa, xtensa_interface intf) 1699 { 1700 xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa; 1701 CHECK_INTERFACE (intisa, intf, XTENSA_UNDEFINED); 1702 return intisa->interfaces[intf].num_bits; 1703 } 1704 1705 1706 char 1707 xtensa_interface_inout (xtensa_isa isa, xtensa_interface intf) 1708 { 1709 xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa; 1710 CHECK_INTERFACE (intisa, intf, 0); 1711 return intisa->interfaces[intf].inout; 1712 } 1713 1714 1715 int 1716 xtensa_interface_has_side_effect (xtensa_isa isa, xtensa_interface intf) 1717 { 1718 xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa; 1719 CHECK_INTERFACE (intisa, intf, XTENSA_UNDEFINED); 1720 if ((intisa->interfaces[intf].flags & XTENSA_INTERFACE_HAS_SIDE_EFFECT) != 0) 1721 return 1; 1722 return 0; 1723 } 1724 1725 1726 int 1727 xtensa_interface_class_id (xtensa_isa isa, xtensa_interface intf) 1728 { 1729 xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa; 1730 CHECK_INTERFACE (intisa, intf, XTENSA_UNDEFINED); 1731 return intisa->interfaces[intf].class_id; 1732 } 1733 1734 1735 1736 /* Functional Units. */ 1738 1739 1740 #define CHECK_FUNCUNIT(INTISA,FUN,ERRVAL) \ 1741 do { \ 1742 if ((FUN) < 0 || (FUN) >= (INTISA)->num_funcUnits) \ 1743 { \ 1744 xtisa_errno = xtensa_isa_bad_funcUnit; \ 1745 strcpy (xtisa_error_msg, "invalid functional unit specifier"); \ 1746 return (ERRVAL); \ 1747 } \ 1748 } while (0) 1749 1750 1751 xtensa_funcUnit 1752 xtensa_funcUnit_lookup (xtensa_isa isa, const char *fname) 1753 { 1754 xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa; 1755 xtensa_lookup_entry entry, *result = 0; 1756 1757 if (!fname || !*fname) 1758 { 1759 xtisa_errno = xtensa_isa_bad_funcUnit; 1760 strcpy (xtisa_error_msg, "invalid functional unit name"); 1761 return XTENSA_UNDEFINED; 1762 } 1763 1764 if (intisa->num_funcUnits != 0) 1765 { 1766 entry.key = fname; 1767 result = bsearch (&entry, intisa->funcUnit_lookup_table, 1768 intisa->num_funcUnits, sizeof (xtensa_lookup_entry), 1769 xtensa_isa_name_compare); 1770 } 1771 1772 if (!result) 1773 { 1774 xtisa_errno = xtensa_isa_bad_funcUnit; 1775 sprintf (xtisa_error_msg, 1776 "functional unit \"%s\" not recognized", fname); 1777 return XTENSA_UNDEFINED; 1778 } 1779 1780 return result->u.fun; 1781 } 1782 1783 1784 const char * 1785 xtensa_funcUnit_name (xtensa_isa isa, xtensa_funcUnit fun) 1786 { 1787 xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa; 1788 CHECK_FUNCUNIT (intisa, fun, NULL); 1789 return intisa->funcUnits[fun].name; 1790 } 1791 1792 1793 int 1794 xtensa_funcUnit_num_copies (xtensa_isa isa, xtensa_funcUnit fun) 1795 { 1796 xtensa_isa_internal *intisa = (xtensa_isa_internal *) isa; 1797 CHECK_FUNCUNIT (intisa, fun, XTENSA_UNDEFINED); 1798 return intisa->funcUnits[fun].num_copies; 1799 } 1800 1801