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