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