cachepc-qemu

Fork of AMDESE/qemu with changes for cachepc side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-qemu
Log | Files | Refs | Submodules | LICENSE | sfeed.txt

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
     29xtensa_isa_status xtisa_errno;
     30char xtisa_error_msg[1024];
     31
     32
     33xtensa_isa_status xtensa_isa_errno(xtensa_isa isa __attribute__ ((unused)))
     34{
     35    return xtisa_errno;
     36}
     37
     38
     39char *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
     72int xtensa_insnbuf_size(xtensa_isa isa)
     73{
     74    xtensa_isa_internal *intisa = (xtensa_isa_internal *)isa;
     75    return intisa->insnbuf_size;
     76}
     77
     78
     79xtensa_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
     89void 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
    102static inline int byte_to_word_index(int byte_index)
    103{
    104    return byte_index / sizeof(xtensa_insnbuf_word);
    105}
    106
    107
    108static 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
    125int 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
    186void 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
    232xtensa_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
    323void 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
    368int 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
    377int xtensa_isa_maxlength(xtensa_isa isa)
    378{
    379    xtensa_isa_internal *intisa = (xtensa_isa_internal *)isa;
    380    return intisa->insn_size;
    381}
    382
    383
    384int 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
    391int 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
    423int 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
    430int 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
    437int 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
    444int 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
    451int 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
    458int 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
    465int 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
    495const 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
    504xtensa_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
    527xtensa_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
    543int 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
    554int 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
    563int 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
    572xtensa_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
    586int 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
    601int 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
    629xtensa_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
    657xtensa_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
    680int 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
    705const 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
    714int 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
    726int 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
    738int 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
    750int 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
    762int 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
    773int 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
    784int 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
    795int 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
    804xtensa_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
    836static 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
    851const 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
    864int 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
    891char 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
    915int 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
    951int 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
    987int 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
   1061int 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
   1086int 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
   1103xtensa_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
   1118int 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
   1132int 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
   1149int 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
   1166int 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
   1198int 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
   1246xtensa_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
   1261char 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
   1292xtensa_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
   1321xtensa_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
   1345xtensa_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
   1378const 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
   1387const 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
   1396xtensa_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
   1405int 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
   1414int 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
   1436xtensa_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
   1464const 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
   1473int 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
   1482int 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
   1494int 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
   1519xtensa_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
   1538xtensa_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
   1566const 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
   1575int 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
   1584int 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
   1609xtensa_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
   1637const 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
   1646int 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
   1655char 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
   1664int 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
   1677int 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
   1699xtensa_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
   1728const 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
   1737int 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}