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