qemu

FORK: QEMU emulator
git clone https://git.neptards.moe/neptards/qemu.git
Log | Files | Refs | Submodules | LICENSE

xtensa-isa.c (49274B)


      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 }