/* Configurable Xtensa ISA support.
 *
 * Copyright (c) 2001-2011 Tensilica Inc.
 *
 * Permission is hereby granted, free of charge, to any person obtaining
 * a copy of this software and associated documentation files (the
 * "Software"), to deal in the Software without restriction, including
 * without limitation the rights to use, copy, modify, merge, publish,
 * distribute, sublicense, and/or sell copies of the Software, and to
 * permit persons to whom the Software is furnished to do so, subject to
 * the following conditions:
 *
 * The above copyright notice and this permission notice shall be included
 * in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */

#include "qemu/osdep.h"
#include "xtensa-isa.h"
#include "xtensa-isa-internal.h"

xtensa_isa_status xtisa_errno;
char xtisa_error_msg[1024];


xtensa_isa_status xtensa_isa_errno(xtensa_isa isa __attribute__ ((unused)))
{
    return xtisa_errno;
}


char *xtensa_isa_error_msg(xtensa_isa isa __attribute__ ((unused)))
{
    return xtisa_error_msg;
}


#define CHECK_ALLOC(MEM, ERRVAL) \
    do { \
        if ((MEM) == 0) { \
            xtisa_errno = xtensa_isa_out_of_memory; \
            strcpy(xtisa_error_msg, "out of memory"); \
            return ERRVAL; \
        } \
    } while (0)

#define CHECK_ALLOC_FOR_INIT(MEM, ERRVAL, ERRNO_P, ERROR_MSG_P) \
    do { \
        if ((MEM) == 0) { \
            xtisa_errno = xtensa_isa_out_of_memory; \
            strcpy(xtisa_error_msg, "out of memory"); \
            if (ERRNO_P) { \
                *(ERRNO_P) = xtisa_errno; \
            } \
            if (ERROR_MSG_P) { \
                *(ERROR_MSG_P) = xtisa_error_msg; \
            } \
            return ERRVAL; \
        } \
    } while (0)


/* Instruction buffers. */

int xtensa_insnbuf_size(xtensa_isa isa)
{
    xtensa_isa_internal *intisa = (xtensa_isa_internal *)isa;
    return intisa->insnbuf_size;
}


xtensa_insnbuf xtensa_insnbuf_alloc(xtensa_isa isa)
{
    xtensa_insnbuf result = (xtensa_insnbuf)
        malloc(xtensa_insnbuf_size(isa) * sizeof(xtensa_insnbuf_word));

    CHECK_ALLOC(result, 0);
    return result;
}


void xtensa_insnbuf_free(xtensa_isa isa __attribute__ ((unused)),
                         xtensa_insnbuf buf)
{
    free(buf);
}


/*
 * Given <byte_index>, the index of a byte in a xtensa_insnbuf, our
 * internal representation of a xtensa instruction word, return the index of
 * its word and the bit index of its low order byte in the xtensa_insnbuf.
 */

static inline int byte_to_word_index(int byte_index)
{
    return byte_index / sizeof(xtensa_insnbuf_word);
}


static inline int byte_to_bit_index(int byte_index)
{
    return (byte_index & 0x3) * 8;
}


/*
 * Copy an instruction in the 32-bit words pointed at by "insn" to
 * characters pointed at by "cp". This is more complicated than you
 * might think because we want 16-bit instructions in bytes 2 & 3 for
 * big-endian configurations. This function allows us to specify
 * which byte in "insn" to start with and which way to increment,
 * allowing trivial implementation for both big- and little-endian
 * configurations....and it seems to make pretty good code for
 * both.
 */

int xtensa_insnbuf_to_chars(xtensa_isa isa,
                            const xtensa_insnbuf insn,
                            unsigned char *cp,
                            int num_chars)
{
    xtensa_isa_internal *intisa = (xtensa_isa_internal *)isa;
    int insn_size = xtensa_isa_maxlength(isa);
    int fence_post, start, increment, i, byte_count;
    xtensa_format fmt;

    if (num_chars == 0) {
        num_chars = insn_size;
    }

    if (intisa->is_big_endian) {
        start = insn_size - 1;
        increment = -1;
    } else {
        start = 0;
        increment = 1;
    }

    /*
     * Find the instruction format. Do nothing if the buffer does not contain
     * a valid instruction since we need to know how many bytes to copy.
     */
    fmt = xtensa_format_decode(isa, insn);
    if (fmt == XTENSA_UNDEFINED) {
        return XTENSA_UNDEFINED;
    }

    byte_count = xtensa_format_length(isa, fmt);
    if (byte_count == XTENSA_UNDEFINED) {
        return XTENSA_UNDEFINED;
    }

    if (byte_count > num_chars) {
        xtisa_errno = xtensa_isa_buffer_overflow;
        strcpy(xtisa_error_msg, "output buffer too small for instruction");
        return XTENSA_UNDEFINED;
    }

    fence_post = start + (byte_count * increment);

    for (i = start; i != fence_post; i += increment, ++cp) {
        int word_inx = byte_to_word_index(i);
        int bit_inx = byte_to_bit_index(i);

        *cp = (insn[word_inx] >> bit_inx) & 0xff;
    }

    return byte_count;
}


/*
 * Inward conversion from byte stream to xtensa_insnbuf. See
 * xtensa_insnbuf_to_chars for a discussion of why this is complicated
 * by endianness.
 */

void xtensa_insnbuf_from_chars(xtensa_isa isa,
                               xtensa_insnbuf insn,
                               const unsigned char *cp,
                               int num_chars)
{
    xtensa_isa_internal *intisa = (xtensa_isa_internal *)isa;
    int max_size, insn_size, fence_post, start, increment, i;

    max_size = xtensa_isa_maxlength(isa);

    /* Decode the instruction length so we know how many bytes to read. */
    insn_size = (intisa->length_decode_fn)(cp);
    if (insn_size == XTENSA_UNDEFINED) {
        /*
         * This should never happen when the byte stream contains a
         * valid instruction. Just read the maximum number of bytes....
         */
        insn_size = max_size;
    }

    if (num_chars == 0 || num_chars > insn_size) {
        num_chars = insn_size;
    }

    if (intisa->is_big_endian) {
        start = max_size - 1;
        increment = -1;
    } else {
        start = 0;
        increment = 1;
    }

    fence_post = start + (num_chars * increment);
    memset(insn, 0, xtensa_insnbuf_size(isa) * sizeof(xtensa_insnbuf_word));

    for (i = start; i != fence_post; i += increment, ++cp) {
        int word_inx = byte_to_word_index(i);
        int bit_inx = byte_to_bit_index(i);

        insn[word_inx] |= (*cp & 0xff) << bit_inx;
    }
}


/* ISA information. */

xtensa_isa xtensa_isa_init(void *xtensa_modules, xtensa_isa_status *errno_p,
                           char **error_msg_p)
{
    xtensa_isa_internal *isa = xtensa_modules;
    int n, is_user;

    /* Set up the opcode name lookup table. */
    isa->opname_lookup_table =
        malloc(isa->num_opcodes * sizeof(xtensa_lookup_entry));
    CHECK_ALLOC_FOR_INIT(isa->opname_lookup_table, NULL, errno_p, error_msg_p);
    for (n = 0; n < isa->num_opcodes; n++) {
        isa->opname_lookup_table[n].key = isa->opcodes[n].name;
        isa->opname_lookup_table[n].u.opcode = n;
    }
    qsort(isa->opname_lookup_table, isa->num_opcodes,
          sizeof(xtensa_lookup_entry), xtensa_isa_name_compare);

    /* Set up the state name lookup table. */
    isa->state_lookup_table =
        malloc(isa->num_states * sizeof(xtensa_lookup_entry));
    CHECK_ALLOC_FOR_INIT(isa->state_lookup_table, NULL, errno_p, error_msg_p);
    for (n = 0; n < isa->num_states; n++) {
        isa->state_lookup_table[n].key = isa->states[n].name;
        isa->state_lookup_table[n].u.state = n;
    }
    qsort(isa->state_lookup_table, isa->num_states,
          sizeof(xtensa_lookup_entry), xtensa_isa_name_compare);

    /* Set up the sysreg name lookup table. */
    isa->sysreg_lookup_table =
        malloc(isa->num_sysregs * sizeof(xtensa_lookup_entry));
    CHECK_ALLOC_FOR_INIT(isa->sysreg_lookup_table, NULL, errno_p, error_msg_p);
    for (n = 0; n < isa->num_sysregs; n++) {
        isa->sysreg_lookup_table[n].key = isa->sysregs[n].name;
        isa->sysreg_lookup_table[n].u.sysreg = n;
    }
    qsort(isa->sysreg_lookup_table, isa->num_sysregs,
          sizeof(xtensa_lookup_entry), xtensa_isa_name_compare);

    /* Set up the user & system sysreg number tables. */
    for (is_user = 0; is_user < 2; is_user++) {
        isa->sysreg_table[is_user] =
            malloc((isa->max_sysreg_num[is_user] + 1) * sizeof(xtensa_sysreg));
        CHECK_ALLOC_FOR_INIT(isa->sysreg_table[is_user], NULL,
                             errno_p, error_msg_p);

        for (n = 0; n <= isa->max_sysreg_num[is_user]; n++) {
            isa->sysreg_table[is_user][n] = XTENSA_UNDEFINED;
        }
    }
    for (n = 0; n < isa->num_sysregs; n++) {
        xtensa_sysreg_internal *sreg = &isa->sysregs[n];
        is_user = sreg->is_user;

        if (sreg->number >= 0) {
            isa->sysreg_table[is_user][sreg->number] = n;
        }
    }

    /* Set up the interface lookup table. */
    isa->interface_lookup_table =
        malloc(isa->num_interfaces * sizeof(xtensa_lookup_entry));
    CHECK_ALLOC_FOR_INIT(isa->interface_lookup_table, NULL, errno_p,
                         error_msg_p);
    for (n = 0; n < isa->num_interfaces; n++) {
        isa->interface_lookup_table[n].key = isa->interfaces[n].name;
        isa->interface_lookup_table[n].u.intf = n;
    }
    qsort(isa->interface_lookup_table, isa->num_interfaces,
          sizeof(xtensa_lookup_entry), xtensa_isa_name_compare);

    /* Set up the funcUnit lookup table. */
    isa->funcUnit_lookup_table =
        malloc(isa->num_funcUnits * sizeof(xtensa_lookup_entry));
    CHECK_ALLOC_FOR_INIT(isa->funcUnit_lookup_table, NULL, errno_p,
                         error_msg_p);
    for (n = 0; n < isa->num_funcUnits; n++) {
        isa->funcUnit_lookup_table[n].key = isa->funcUnits[n].name;
        isa->funcUnit_lookup_table[n].u.fun = n;
    }
    qsort(isa->funcUnit_lookup_table, isa->num_funcUnits,
          sizeof(xtensa_lookup_entry), xtensa_isa_name_compare);

    isa->insnbuf_size = ((isa->insn_size + sizeof(xtensa_insnbuf_word) - 1) /
                         sizeof(xtensa_insnbuf_word));
    isa->num_stages = XTENSA_UNDEFINED;

    return (xtensa_isa)isa;
}


void xtensa_isa_free(xtensa_isa isa)
{
    xtensa_isa_internal *intisa = (xtensa_isa_internal *)isa;
    int n;

    /*
     * With this version of the code, the xtensa_isa structure is not
     * dynamically allocated, so this function is not essential. Free
     * the memory allocated by xtensa_isa_init and restore the xtensa_isa
     * structure to its initial state.
     */

    if (intisa->opname_lookup_table) {
        free(intisa->opname_lookup_table);
        intisa->opname_lookup_table = 0;
    }

    if (intisa->state_lookup_table) {
        free(intisa->state_lookup_table);
        intisa->state_lookup_table = 0;
    }

    if (intisa->sysreg_lookup_table) {
        free(intisa->sysreg_lookup_table);
        intisa->sysreg_lookup_table = 0;
    }
    for (n = 0; n < 2; n++) {
        if (intisa->sysreg_table[n]) {
            free(intisa->sysreg_table[n]);
            intisa->sysreg_table[n] = 0;
        }
    }

    if (intisa->interface_lookup_table) {
        free(intisa->interface_lookup_table);
        intisa->interface_lookup_table = 0;
    }

    if (intisa->funcUnit_lookup_table) {
        free(intisa->funcUnit_lookup_table);
        intisa->funcUnit_lookup_table = 0;
    }
}


int xtensa_isa_name_compare(const void *v1, const void *v2)
{
    xtensa_lookup_entry *e1 = (xtensa_lookup_entry *)v1;
    xtensa_lookup_entry *e2 = (xtensa_lookup_entry *)v2;

    return strcasecmp(e1->key, e2->key);
}


int xtensa_isa_maxlength(xtensa_isa isa)
{
    xtensa_isa_internal *intisa = (xtensa_isa_internal *)isa;
    return intisa->insn_size;
}


int xtensa_isa_length_from_chars(xtensa_isa isa, const unsigned char *cp)
{
    xtensa_isa_internal *intisa = (xtensa_isa_internal *)isa;
    return (intisa->length_decode_fn)(cp);
}


int xtensa_isa_num_pipe_stages(xtensa_isa isa)
{
    xtensa_opcode opcode;
    xtensa_funcUnit_use *use;
    int num_opcodes, num_uses;
    int i, stage, max_stage;
    xtensa_isa_internal *intisa = (xtensa_isa_internal *)isa;

    /* Only compute the value once. */
    if (intisa->num_stages != XTENSA_UNDEFINED) {
        return intisa->num_stages;
    }

    max_stage = -1;

    num_opcodes = xtensa_isa_num_opcodes(isa);
    for (opcode = 0; opcode < num_opcodes; opcode++) {
        num_uses = xtensa_opcode_num_funcUnit_uses(isa, opcode);
        for (i = 0; i < num_uses; i++) {
            use = xtensa_opcode_funcUnit_use(isa, opcode, i);
            stage = use->stage;
            if (stage > max_stage) {
                max_stage = stage;
            }
        }
    }

    intisa->num_stages = max_stage + 1;
    return intisa->num_states;
}


int xtensa_isa_num_formats(xtensa_isa isa)
{
    xtensa_isa_internal *intisa = (xtensa_isa_internal *)isa;
    return intisa->num_formats;
}


int xtensa_isa_num_opcodes(xtensa_isa isa)
{
    xtensa_isa_internal *intisa = (xtensa_isa_internal *)isa;
    return intisa->num_opcodes;
}


int xtensa_isa_num_regfiles(xtensa_isa isa)
{
    xtensa_isa_internal *intisa = (xtensa_isa_internal *)isa;
    return intisa->num_regfiles;
}


int xtensa_isa_num_states(xtensa_isa isa)
{
    xtensa_isa_internal *intisa = (xtensa_isa_internal *)isa;
    return intisa->num_states;
}


int xtensa_isa_num_sysregs(xtensa_isa isa)
{
    xtensa_isa_internal *intisa = (xtensa_isa_internal *)isa;
    return intisa->num_sysregs;
}


int xtensa_isa_num_interfaces(xtensa_isa isa)
{
    xtensa_isa_internal *intisa = (xtensa_isa_internal *)isa;
    return intisa->num_interfaces;
}


int xtensa_isa_num_funcUnits(xtensa_isa isa)
{
    xtensa_isa_internal *intisa = (xtensa_isa_internal *)isa;
    return intisa->num_funcUnits;
}


/* Instruction formats. */


#define CHECK_FORMAT(INTISA, FMT, ERRVAL) \
    do { \
        if ((FMT) < 0 || (FMT) >= (INTISA)->num_formats) { \
            xtisa_errno = xtensa_isa_bad_format; \
            strcpy(xtisa_error_msg, "invalid format specifier"); \
            return ERRVAL; \
        } \
    } while (0)


#define CHECK_SLOT(INTISA, FMT, SLOT, ERRVAL) \
    do { \
        if ((SLOT) < 0 || (SLOT) >= (INTISA)->formats[FMT].num_slots) { \
            xtisa_errno = xtensa_isa_bad_slot; \
            strcpy(xtisa_error_msg, "invalid slot specifier"); \
            return ERRVAL; \
        } \
    } while (0)


const char *xtensa_format_name(xtensa_isa isa, xtensa_format fmt)
{
    xtensa_isa_internal *intisa = (xtensa_isa_internal *)isa;

    CHECK_FORMAT(intisa, fmt, NULL);
    return intisa->formats[fmt].name;
}


xtensa_format xtensa_format_lookup(xtensa_isa isa, const char *fmtname)
{
    xtensa_isa_internal *intisa = (xtensa_isa_internal *)isa;
    int fmt;

    if (!fmtname || !*fmtname) {
        xtisa_errno = xtensa_isa_bad_format;
        strcpy(xtisa_error_msg, "invalid format name");
        return XTENSA_UNDEFINED;
    }

    for (fmt = 0; fmt < intisa->num_formats; fmt++) {
        if (strcasecmp(fmtname, intisa->formats[fmt].name) == 0) {
            return fmt;
        }
    }

    xtisa_errno = xtensa_isa_bad_format;
    sprintf(xtisa_error_msg, "format \"%s\" not recognized", fmtname);
    return XTENSA_UNDEFINED;
}


xtensa_format xtensa_format_decode(xtensa_isa isa, const xtensa_insnbuf insn)
{
    xtensa_isa_internal *intisa = (xtensa_isa_internal *)isa;
    xtensa_format fmt;

    fmt = (intisa->format_decode_fn)(insn);
    if (fmt != XTENSA_UNDEFINED) {
        return fmt;
    }

    xtisa_errno = xtensa_isa_bad_format;
    strcpy(xtisa_error_msg, "cannot decode instruction format");
    return XTENSA_UNDEFINED;
}


int xtensa_format_encode(xtensa_isa isa, xtensa_format fmt,
                         xtensa_insnbuf insn)
{
    xtensa_isa_internal *intisa = (xtensa_isa_internal *)isa;

    CHECK_FORMAT(intisa, fmt, -1);
    (*intisa->formats[fmt].encode_fn)(insn);
    return 0;
}


int xtensa_format_length(xtensa_isa isa, xtensa_format fmt)
{
    xtensa_isa_internal *intisa = (xtensa_isa_internal *)isa;

    CHECK_FORMAT(intisa, fmt, XTENSA_UNDEFINED);
    return intisa->formats[fmt].length;
}


int xtensa_format_num_slots(xtensa_isa isa, xtensa_format fmt)
{
    xtensa_isa_internal *intisa = (xtensa_isa_internal *)isa;

    CHECK_FORMAT(intisa, fmt, XTENSA_UNDEFINED);
    return intisa->formats[fmt].num_slots;
}


xtensa_opcode xtensa_format_slot_nop_opcode(xtensa_isa isa, xtensa_format fmt,
                                            int slot)
{
    xtensa_isa_internal *intisa = (xtensa_isa_internal *)isa;
    int slot_id;

    CHECK_FORMAT(intisa, fmt, XTENSA_UNDEFINED);
    CHECK_SLOT(intisa, fmt, slot, XTENSA_UNDEFINED);

    slot_id = intisa->formats[fmt].slot_id[slot];
    return xtensa_opcode_lookup(isa, intisa->slots[slot_id].nop_name);
}


int xtensa_format_get_slot(xtensa_isa isa, xtensa_format fmt, int slot,
                           const xtensa_insnbuf insn, xtensa_insnbuf slotbuf)
{
    xtensa_isa_internal *intisa = (xtensa_isa_internal *)isa;
    int slot_id;

    CHECK_FORMAT(intisa, fmt, -1);
    CHECK_SLOT(intisa, fmt, slot, -1);

    slot_id = intisa->formats[fmt].slot_id[slot];
    (*intisa->slots[slot_id].get_fn)(insn, slotbuf);
    return 0;
}


int xtensa_format_set_slot(xtensa_isa isa, xtensa_format fmt, int slot,
                           xtensa_insnbuf insn, const xtensa_insnbuf slotbuf)
{
    xtensa_isa_internal *intisa = (xtensa_isa_internal *)isa;
    int slot_id;

    CHECK_FORMAT(intisa, fmt, -1);
    CHECK_SLOT(intisa, fmt, slot, -1);

    slot_id = intisa->formats[fmt].slot_id[slot];
    (*intisa->slots[slot_id].set_fn)(insn, slotbuf);
    return 0;
}


/* Opcode information. */


#define CHECK_OPCODE(INTISA, OPC, ERRVAL) \
    do { \
        if ((OPC) < 0 || (OPC) >= (INTISA)->num_opcodes) { \
            xtisa_errno = xtensa_isa_bad_opcode; \
            strcpy(xtisa_error_msg, "invalid opcode specifier"); \
            return ERRVAL; \
        } \
    } while (0)


xtensa_opcode xtensa_opcode_lookup(xtensa_isa isa, const char *opname)
{
    xtensa_isa_internal *intisa = (xtensa_isa_internal *)isa;
    xtensa_lookup_entry entry, *result = 0;

    if (!opname || !*opname) {
        xtisa_errno = xtensa_isa_bad_opcode;
        strcpy(xtisa_error_msg, "invalid opcode name");
        return XTENSA_UNDEFINED;
    }

    if (intisa->num_opcodes != 0) {
        entry.key = opname;
        result = bsearch(&entry, intisa->opname_lookup_table,
                         intisa->num_opcodes, sizeof(xtensa_lookup_entry),
                         xtensa_isa_name_compare);
    }

    if (!result) {
        xtisa_errno = xtensa_isa_bad_opcode;
        sprintf(xtisa_error_msg, "opcode \"%s\" not recognized", opname);
        return XTENSA_UNDEFINED;
    }

    return result->u.opcode;
}


xtensa_opcode xtensa_opcode_decode(xtensa_isa isa, xtensa_format fmt, int slot,
                                   const xtensa_insnbuf slotbuf)
{
    xtensa_isa_internal *intisa = (xtensa_isa_internal *)isa;
    int slot_id;
    xtensa_opcode opc;

    CHECK_FORMAT(intisa, fmt, XTENSA_UNDEFINED);
    CHECK_SLOT(intisa, fmt, slot, XTENSA_UNDEFINED);

    slot_id = intisa->formats[fmt].slot_id[slot];

    opc = (intisa->slots[slot_id].opcode_decode_fn) (slotbuf);
    if (opc != XTENSA_UNDEFINED) {
        return opc;
    }

    xtisa_errno = xtensa_isa_bad_opcode;
    strcpy(xtisa_error_msg, "cannot decode opcode");
    return XTENSA_UNDEFINED;
}


int xtensa_opcode_encode(xtensa_isa isa, xtensa_format fmt, int slot,
                         xtensa_insnbuf slotbuf, xtensa_opcode opc)
{
    xtensa_isa_internal *intisa = (xtensa_isa_internal *)isa;
    int slot_id;
    xtensa_opcode_encode_fn encode_fn;

    CHECK_FORMAT(intisa, fmt, -1);
    CHECK_SLOT(intisa, fmt, slot, -1);
    CHECK_OPCODE(intisa, opc, -1);

    slot_id = intisa->formats[fmt].slot_id[slot];
    encode_fn = intisa->opcodes[opc].encode_fns[slot_id];
    if (!encode_fn) {
        xtisa_errno = xtensa_isa_wrong_slot;
        sprintf(xtisa_error_msg,
                "opcode \"%s\" is not allowed in slot %d of format \"%s\"",
                intisa->opcodes[opc].name, slot, intisa->formats[fmt].name);
        return -1;
    }
    (*encode_fn)(slotbuf);
    return 0;
}


const char *xtensa_opcode_name(xtensa_isa isa, xtensa_opcode opc)
{
    xtensa_isa_internal *intisa = (xtensa_isa_internal *)isa;

    CHECK_OPCODE(intisa, opc, NULL);
    return intisa->opcodes[opc].name;
}


int xtensa_opcode_is_branch(xtensa_isa isa, xtensa_opcode opc)
{
    xtensa_isa_internal *intisa = (xtensa_isa_internal *)isa;

    CHECK_OPCODE(intisa, opc, XTENSA_UNDEFINED);
    if ((intisa->opcodes[opc].flags & XTENSA_OPCODE_IS_BRANCH) != 0) {
        return 1;
    }
    return 0;
}


int xtensa_opcode_is_jump(xtensa_isa isa, xtensa_opcode opc)
{
    xtensa_isa_internal *intisa = (xtensa_isa_internal *)isa;

    CHECK_OPCODE(intisa, opc, XTENSA_UNDEFINED);
    if ((intisa->opcodes[opc].flags & XTENSA_OPCODE_IS_JUMP) != 0) {
        return 1;
    }
    return 0;
}


int xtensa_opcode_is_loop(xtensa_isa isa, xtensa_opcode opc)
{
    xtensa_isa_internal *intisa = (xtensa_isa_internal *)isa;

    CHECK_OPCODE(intisa, opc, XTENSA_UNDEFINED);
    if ((intisa->opcodes[opc].flags & XTENSA_OPCODE_IS_LOOP) != 0) {
        return 1;
    }
    return 0;
}


int xtensa_opcode_is_call(xtensa_isa isa, xtensa_opcode opc)
{
    xtensa_isa_internal *intisa = (xtensa_isa_internal *)isa;

    CHECK_OPCODE(intisa, opc, XTENSA_UNDEFINED);
    if ((intisa->opcodes[opc].flags & XTENSA_OPCODE_IS_CALL) != 0) {
        return 1;
    }
    return 0;
}


int xtensa_opcode_num_operands(xtensa_isa isa, xtensa_opcode opc)
{
    xtensa_isa_internal *intisa = (xtensa_isa_internal *)isa;
    int iclass_id;

    CHECK_OPCODE(intisa, opc, XTENSA_UNDEFINED);
    iclass_id = intisa->opcodes[opc].iclass_id;
    return intisa->iclasses[iclass_id].num_operands;
}


int xtensa_opcode_num_stateOperands(xtensa_isa isa, xtensa_opcode opc)
{
    xtensa_isa_internal *intisa = (xtensa_isa_internal *)isa;
    int iclass_id;

    CHECK_OPCODE(intisa, opc, XTENSA_UNDEFINED);
    iclass_id = intisa->opcodes[opc].iclass_id;
    return intisa->iclasses[iclass_id].num_stateOperands;
}


int xtensa_opcode_num_interfaceOperands(xtensa_isa isa, xtensa_opcode opc)
{
    xtensa_isa_internal *intisa = (xtensa_isa_internal *)isa;
    int iclass_id;

    CHECK_OPCODE(intisa, opc, XTENSA_UNDEFINED);
    iclass_id = intisa->opcodes[opc].iclass_id;
    return intisa->iclasses[iclass_id].num_interfaceOperands;
}


int xtensa_opcode_num_funcUnit_uses(xtensa_isa isa, xtensa_opcode opc)
{
    xtensa_isa_internal *intisa = (xtensa_isa_internal *)isa;

    CHECK_OPCODE(intisa, opc, XTENSA_UNDEFINED);
    return intisa->opcodes[opc].num_funcUnit_uses;
}


xtensa_funcUnit_use *xtensa_opcode_funcUnit_use(xtensa_isa isa,
                                                xtensa_opcode opc, int u)
{
    xtensa_isa_internal *intisa = (xtensa_isa_internal *)isa;

    CHECK_OPCODE(intisa, opc, NULL);
    if (u < 0 || u >= intisa->opcodes[opc].num_funcUnit_uses) {
        xtisa_errno = xtensa_isa_bad_funcUnit;
        sprintf(xtisa_error_msg, "invalid functional unit use number (%d); "
                "opcode \"%s\" has %d", u, intisa->opcodes[opc].name,
                intisa->opcodes[opc].num_funcUnit_uses);
        return NULL;
    }
    return &intisa->opcodes[opc].funcUnit_uses[u];
}


/* Operand information. */


#define CHECK_OPERAND(INTISA, OPC, ICLASS, OPND, ERRVAL) \
    do { \
        if ((OPND) < 0 || (OPND) >= (ICLASS)->num_operands) { \
            xtisa_errno = xtensa_isa_bad_operand; \
            sprintf(xtisa_error_msg, "invalid operand number (%d); " \
                    "opcode \"%s\" has %d operands", (OPND), \
                    (INTISA)->opcodes[(OPC)].name, (ICLASS)->num_operands); \
            return ERRVAL; \
        } \
    } while (0)


static xtensa_operand_internal *get_operand(xtensa_isa_internal *intisa,
                                            xtensa_opcode opc, int opnd)
{
    xtensa_iclass_internal *iclass;
    int iclass_id, operand_id;

    CHECK_OPCODE(intisa, opc, NULL);
    iclass_id = intisa->opcodes[opc].iclass_id;
    iclass = &intisa->iclasses[iclass_id];
    CHECK_OPERAND(intisa, opc, iclass, opnd, NULL);
    operand_id = iclass->operands[opnd].u.operand_id;
    return &intisa->operands[operand_id];
}


const char *xtensa_operand_name(xtensa_isa isa, xtensa_opcode opc, int opnd)
{
    xtensa_isa_internal *intisa = (xtensa_isa_internal *)isa;
    xtensa_operand_internal *intop;

    intop = get_operand(intisa, opc, opnd);
    if (!intop) {
        return NULL;
    }
    return intop->name;
}


int xtensa_operand_is_visible(xtensa_isa isa, xtensa_opcode opc, int opnd)
{
    xtensa_isa_internal *intisa = (xtensa_isa_internal *)isa;
    xtensa_iclass_internal *iclass;
    int iclass_id, operand_id;
    xtensa_operand_internal *intop;

    CHECK_OPCODE(intisa, opc, XTENSA_UNDEFINED);
    iclass_id = intisa->opcodes[opc].iclass_id;
    iclass = &intisa->iclasses[iclass_id];
    CHECK_OPERAND(intisa, opc, iclass, opnd, XTENSA_UNDEFINED);

    /* Special case for "sout" operands. */
    if (iclass->operands[opnd].inout == 's') {
        return 0;
    }

    operand_id = iclass->operands[opnd].u.operand_id;
    intop = &intisa->operands[operand_id];

    if ((intop->flags & XTENSA_OPERAND_IS_INVISIBLE) == 0) {
        return 1;
    }
    return 0;
}


char xtensa_operand_inout(xtensa_isa isa, xtensa_opcode opc, int opnd)
{
    xtensa_isa_internal *intisa = (xtensa_isa_internal *)isa;
    xtensa_iclass_internal *iclass;
    int iclass_id;
    char inout;

    CHECK_OPCODE(intisa, opc, 0);
    iclass_id = intisa->opcodes[opc].iclass_id;
    iclass = &intisa->iclasses[iclass_id];
    CHECK_OPERAND(intisa, opc, iclass, opnd, 0);
    inout = iclass->operands[opnd].inout;

    /* Special case for "sout" and "_sin" operands. */
    if (inout == 's') {
        return 'o';
    }
    if (inout == 't') {
        return 'i';
    }
    return inout;
}


int xtensa_operand_get_field(xtensa_isa isa, xtensa_opcode opc, int opnd,
                             xtensa_format fmt, int slot,
                             const xtensa_insnbuf slotbuf, uint32_t *valp)
{
    xtensa_isa_internal *intisa = (xtensa_isa_internal *)isa;
    xtensa_operand_internal *intop;
    int slot_id;
    xtensa_get_field_fn get_fn;

    intop = get_operand(intisa, opc, opnd);
    if (!intop) {
        return -1;
    }

    CHECK_FORMAT(intisa, fmt, -1);
    CHECK_SLOT(intisa, fmt, slot, -1);

    slot_id = intisa->formats[fmt].slot_id[slot];
    if (intop->field_id == XTENSA_UNDEFINED) {
        xtisa_errno = xtensa_isa_no_field;
        strcpy(xtisa_error_msg, "implicit operand has no field");
        return -1;
    }
    get_fn = intisa->slots[slot_id].get_field_fns[intop->field_id];
    if (!get_fn) {
        xtisa_errno = xtensa_isa_wrong_slot;
        sprintf(xtisa_error_msg,
                "operand \"%s\" does not exist in slot %d of format \"%s\"",
                intop->name, slot, intisa->formats[fmt].name);
        return -1;
    }
    *valp = (*get_fn)(slotbuf);
    return 0;
}


int xtensa_operand_set_field(xtensa_isa isa, xtensa_opcode opc, int opnd,
                             xtensa_format fmt, int slot,
                             xtensa_insnbuf slotbuf, uint32_t val)
{
    xtensa_isa_internal *intisa = (xtensa_isa_internal *)isa;
    xtensa_operand_internal *intop;
    int slot_id;
    xtensa_set_field_fn set_fn;

    intop = get_operand(intisa, opc, opnd);
    if (!intop) {
        return -1;
    }

    CHECK_FORMAT(intisa, fmt, -1);
    CHECK_SLOT(intisa, fmt, slot, -1);

    slot_id = intisa->formats[fmt].slot_id[slot];
    if (intop->field_id == XTENSA_UNDEFINED) {
        xtisa_errno = xtensa_isa_no_field;
        strcpy(xtisa_error_msg, "implicit operand has no field");
        return -1;
    }
    set_fn = intisa->slots[slot_id].set_field_fns[intop->field_id];
    if (!set_fn) {
        xtisa_errno = xtensa_isa_wrong_slot;
        sprintf(xtisa_error_msg,
                "operand \"%s\" does not exist in slot %d of format \"%s\"",
                intop->name, slot, intisa->formats[fmt].name);
        return -1;
    }
    (*set_fn)(slotbuf, val);
    return 0;
}


int xtensa_operand_encode(xtensa_isa isa, xtensa_opcode opc, int opnd,
                          uint32_t *valp)
{
    xtensa_isa_internal *intisa = (xtensa_isa_internal *)isa;
    xtensa_operand_internal *intop;
    uint32_t test_val, orig_val;

    intop = get_operand(intisa, opc, opnd);
    if (!intop) {
        return -1;
    }

    if (!intop->encode) {
        /*
         * This is a default operand for a field. How can we tell if the
         * value fits in the field?  Write the value into the field,
         * read it back, and then make sure we get the same value.
         */
        static xtensa_insnbuf tmpbuf;
        int slot_id;

        if (!tmpbuf) {
            tmpbuf = xtensa_insnbuf_alloc(isa);
            CHECK_ALLOC(tmpbuf, -1);
        }

        /*
         * A default operand is always associated with a field,
         * but check just to be sure....
         */
        if (intop->field_id == XTENSA_UNDEFINED) {
            xtisa_errno = xtensa_isa_internal_error;
            strcpy(xtisa_error_msg, "operand has no field");
            return -1;
        }

        /* Find some slot that includes the field. */
        for (slot_id = 0; slot_id < intisa->num_slots; slot_id++) {
            xtensa_get_field_fn get_fn =
                intisa->slots[slot_id].get_field_fns[intop->field_id];
            xtensa_set_field_fn set_fn =
                intisa->slots[slot_id].set_field_fns[intop->field_id];

            if (get_fn && set_fn) {
                (*set_fn)(tmpbuf, *valp);
                return (*get_fn)(tmpbuf) != *valp;
            }
        }

        /* Couldn't find any slot containing the field.... */
        xtisa_errno = xtensa_isa_no_field;
        strcpy(xtisa_error_msg, "field does not exist in any slot");
        return -1;
    }

    /*
     * Encode the value. In some cases, the encoding function may detect
     * errors, but most of the time the only way to determine if the value
     * was successfully encoded is to decode it and check if it matches
     * the original value.
     */
    orig_val = *valp;
    if ((*intop->encode)(valp) ||
        (test_val = *valp, (*intop->decode)(&test_val)) ||
        test_val != orig_val) {
        xtisa_errno = xtensa_isa_bad_value;
        sprintf(xtisa_error_msg, "cannot encode operand value 0x%08x", *valp);
        return -1;
    }

    return 0;
}


int xtensa_operand_decode(xtensa_isa isa, xtensa_opcode opc, int opnd,
                          uint32_t *valp)
{
    xtensa_isa_internal *intisa = (xtensa_isa_internal *)isa;
    xtensa_operand_internal *intop;

    intop = get_operand(intisa, opc, opnd);
    if (!intop) {
        return -1;
    }

    /* Use identity function for "default" operands. */
    if (!intop->decode) {
        return 0;
    }

    if ((*intop->decode)(valp)) {
        xtisa_errno = xtensa_isa_bad_value;
        sprintf(xtisa_error_msg, "cannot decode operand value 0x%08x", *valp);
        return -1;
    }
    return 0;
}


int xtensa_operand_is_register(xtensa_isa isa, xtensa_opcode opc, int opnd)
{
    xtensa_isa_internal *intisa = (xtensa_isa_internal *)isa;
    xtensa_operand_internal *intop;

    intop = get_operand(intisa, opc, opnd);
    if (!intop) {
        return XTENSA_UNDEFINED;
    }

    if ((intop->flags & XTENSA_OPERAND_IS_REGISTER) != 0) {
        return 1;
    }
    return 0;
}


xtensa_regfile xtensa_operand_regfile(xtensa_isa isa, xtensa_opcode opc,
                                      int opnd)
{
    xtensa_isa_internal *intisa = (xtensa_isa_internal *)isa;
    xtensa_operand_internal *intop;

    intop = get_operand(intisa, opc, opnd);
    if (!intop) {
        return XTENSA_UNDEFINED;
    }

    return intop->regfile;
}


int xtensa_operand_num_regs(xtensa_isa isa, xtensa_opcode opc, int opnd)
{
    xtensa_isa_internal *intisa = (xtensa_isa_internal *)isa;
    xtensa_operand_internal *intop;

    intop = get_operand(intisa, opc, opnd);
    if (!intop) {
        return XTENSA_UNDEFINED;
    }

    return intop->num_regs;
}


int xtensa_operand_is_known_reg(xtensa_isa isa, xtensa_opcode opc, int opnd)
{
    xtensa_isa_internal *intisa = (xtensa_isa_internal *)isa;
    xtensa_operand_internal *intop;

    intop = get_operand(intisa, opc, opnd);
    if (!intop) {
        return XTENSA_UNDEFINED;
    }

    if ((intop->flags & XTENSA_OPERAND_IS_UNKNOWN) == 0) {
        return 1;
    }
    return 0;
}


int xtensa_operand_is_PCrelative(xtensa_isa isa, xtensa_opcode opc, int opnd)
{
    xtensa_isa_internal *intisa = (xtensa_isa_internal *)isa;
    xtensa_operand_internal *intop;

    intop = get_operand(intisa, opc, opnd);
    if (!intop) {
        return XTENSA_UNDEFINED;
    }

    if ((intop->flags & XTENSA_OPERAND_IS_PCRELATIVE) != 0) {
        return 1;
    }
    return 0;
}


int xtensa_operand_do_reloc(xtensa_isa isa, xtensa_opcode opc, int opnd,
                            uint32_t *valp, uint32_t pc)
{
    xtensa_isa_internal *intisa = (xtensa_isa_internal *)isa;
    xtensa_operand_internal *intop;

    intop = get_operand(intisa, opc, opnd);
    if (!intop) {
        return -1;
    }

    if ((intop->flags & XTENSA_OPERAND_IS_PCRELATIVE) == 0) {
        return 0;
    }

    if (!intop->do_reloc) {
        xtisa_errno = xtensa_isa_internal_error;
        strcpy(xtisa_error_msg, "operand missing do_reloc function");
        return -1;
    }

    if ((*intop->do_reloc)(valp, pc)) {
        xtisa_errno = xtensa_isa_bad_value;
        sprintf(xtisa_error_msg,
                "do_reloc failed for value 0x%08x at PC 0x%08x", *valp, pc);
        return -1;
    }

    return 0;
}


int xtensa_operand_undo_reloc(xtensa_isa isa, xtensa_opcode opc, int opnd,
                              uint32_t *valp, uint32_t pc)
{
    xtensa_isa_internal *intisa = (xtensa_isa_internal *)isa;
    xtensa_operand_internal *intop;

    intop = get_operand(intisa, opc, opnd);
    if (!intop) {
        return -1;
    }

    if ((intop->flags & XTENSA_OPERAND_IS_PCRELATIVE) == 0) {
        return 0;
    }

    if (!intop->undo_reloc) {
        xtisa_errno = xtensa_isa_internal_error;
        strcpy(xtisa_error_msg, "operand missing undo_reloc function");
        return -1;
    }

    if ((*intop->undo_reloc)(valp, pc)) {
        xtisa_errno = xtensa_isa_bad_value;
        sprintf(xtisa_error_msg,
                "undo_reloc failed for value 0x%08x at PC 0x%08x", *valp, pc);
        return -1;
    }

    return 0;
}


/* State Operands. */


#define CHECK_STATE_OPERAND(INTISA, OPC, ICLASS, STOP, ERRVAL) \
    do { \
        if ((STOP) < 0 || (STOP) >= (ICLASS)->num_stateOperands) { \
            xtisa_errno = xtensa_isa_bad_operand; \
            sprintf(xtisa_error_msg, "invalid state operand number (%d); " \
                    "opcode \"%s\" has %d state operands", (STOP), \
                    (INTISA)->opcodes[(OPC)].name, \
                    (ICLASS)->num_stateOperands); \
            return ERRVAL; \
        } \
    } while (0)


xtensa_state xtensa_stateOperand_state(xtensa_isa isa, xtensa_opcode opc,
                                       int stOp)
{
    xtensa_isa_internal *intisa = (xtensa_isa_internal *)isa;
    xtensa_iclass_internal *iclass;
    int iclass_id;

    CHECK_OPCODE(intisa, opc, XTENSA_UNDEFINED);
    iclass_id = intisa->opcodes[opc].iclass_id;
    iclass = &intisa->iclasses[iclass_id];
    CHECK_STATE_OPERAND(intisa, opc, iclass, stOp, XTENSA_UNDEFINED);
    return iclass->stateOperands[stOp].u.state;
}


char xtensa_stateOperand_inout(xtensa_isa isa, xtensa_opcode opc, int stOp)
{
    xtensa_isa_internal *intisa = (xtensa_isa_internal *)isa;
    xtensa_iclass_internal *iclass;
    int iclass_id;

    CHECK_OPCODE(intisa, opc, 0);
    iclass_id = intisa->opcodes[opc].iclass_id;
    iclass = &intisa->iclasses[iclass_id];
    CHECK_STATE_OPERAND(intisa, opc, iclass, stOp, 0);
    return iclass->stateOperands[stOp].inout;
}


/* Interface Operands. */


#define CHECK_INTERFACE_OPERAND(INTISA, OPC, ICLASS, IFOP, ERRVAL) \
    do { \
        if ((IFOP) < 0 || (IFOP) >= (ICLASS)->num_interfaceOperands) { \
            xtisa_errno = xtensa_isa_bad_operand; \
            sprintf(xtisa_error_msg, \
                    "invalid interface operand number (%d); " \
                    "opcode \"%s\" has %d interface operands", (IFOP), \
                    (INTISA)->opcodes[(OPC)].name, \
                    (ICLASS)->num_interfaceOperands); \
            return ERRVAL; \
        } \
    } while (0)


xtensa_interface xtensa_interfaceOperand_interface(xtensa_isa isa,
                                                   xtensa_opcode opc,
                                                   int ifOp)
{
    xtensa_isa_internal *intisa = (xtensa_isa_internal *)isa;
    xtensa_iclass_internal *iclass;
    int iclass_id;

    CHECK_OPCODE(intisa, opc, XTENSA_UNDEFINED);
    iclass_id = intisa->opcodes[opc].iclass_id;
    iclass = &intisa->iclasses[iclass_id];
    CHECK_INTERFACE_OPERAND(intisa, opc, iclass, ifOp, XTENSA_UNDEFINED);
    return iclass->interfaceOperands[ifOp];
}


/* Register Files. */


#define CHECK_REGFILE(INTISA, RF, ERRVAL) \
    do { \
        if ((RF) < 0 || (RF) >= (INTISA)->num_regfiles) { \
            xtisa_errno = xtensa_isa_bad_regfile; \
            strcpy(xtisa_error_msg, "invalid regfile specifier"); \
            return ERRVAL; \
        } \
    } while (0)


xtensa_regfile xtensa_regfile_lookup(xtensa_isa isa, const char *name)
{
    xtensa_isa_internal *intisa = (xtensa_isa_internal *)isa;
    int n;

    if (!name || !*name) {
        xtisa_errno = xtensa_isa_bad_regfile;
        strcpy(xtisa_error_msg, "invalid regfile name");
        return XTENSA_UNDEFINED;
    }

    /* The expected number of regfiles is small; use a linear search. */
    for (n = 0; n < intisa->num_regfiles; n++) {
        if (!strcmp(intisa->regfiles[n].name, name)) {
            return n;
        }
    }

    xtisa_errno = xtensa_isa_bad_regfile;
    sprintf(xtisa_error_msg, "regfile \"%s\" not recognized", name);
    return XTENSA_UNDEFINED;
}


xtensa_regfile xtensa_regfile_lookup_shortname(xtensa_isa isa,
                                               const char *shortname)
{
    xtensa_isa_internal *intisa = (xtensa_isa_internal *)isa;
    int n;

    if (!shortname || !*shortname) {
        xtisa_errno = xtensa_isa_bad_regfile;
        strcpy(xtisa_error_msg, "invalid regfile shortname");
        return XTENSA_UNDEFINED;
    }

    /* The expected number of regfiles is small; use a linear search. */
    for (n = 0; n < intisa->num_regfiles; n++) {
        /*
         * Ignore regfile views since they always have the same shortnames
         * as their parents.
         */
        if (intisa->regfiles[n].parent != n) {
            continue;
        }
        if (!strcmp(intisa->regfiles[n].shortname, shortname)) {
            return n;
        }
    }

    xtisa_errno = xtensa_isa_bad_regfile;
    sprintf(xtisa_error_msg, "regfile shortname \"%s\" not recognized",
            shortname);
    return XTENSA_UNDEFINED;
}


const char *xtensa_regfile_name(xtensa_isa isa, xtensa_regfile rf)
{
    xtensa_isa_internal *intisa = (xtensa_isa_internal *)isa;

    CHECK_REGFILE(intisa, rf, NULL);
    return intisa->regfiles[rf].name;
}


const char *xtensa_regfile_shortname(xtensa_isa isa, xtensa_regfile rf)
{
    xtensa_isa_internal *intisa = (xtensa_isa_internal *)isa;

    CHECK_REGFILE(intisa, rf, NULL);
    return intisa->regfiles[rf].shortname;
}


xtensa_regfile xtensa_regfile_view_parent(xtensa_isa isa, xtensa_regfile rf)
{
    xtensa_isa_internal *intisa = (xtensa_isa_internal *)isa;

    CHECK_REGFILE(intisa, rf, XTENSA_UNDEFINED);
    return intisa->regfiles[rf].parent;
}


int xtensa_regfile_num_bits(xtensa_isa isa, xtensa_regfile rf)
{
    xtensa_isa_internal *intisa = (xtensa_isa_internal *)isa;

    CHECK_REGFILE(intisa, rf, XTENSA_UNDEFINED);
    return intisa->regfiles[rf].num_bits;
}


int xtensa_regfile_num_entries(xtensa_isa isa, xtensa_regfile rf)
{
    xtensa_isa_internal *intisa = (xtensa_isa_internal *)isa;

    CHECK_REGFILE(intisa, rf, XTENSA_UNDEFINED);
    return intisa->regfiles[rf].num_entries;
}


/* Processor States. */


#define CHECK_STATE(INTISA, ST, ERRVAL) \
    do { \
        if ((ST) < 0 || (ST) >= (INTISA)->num_states) { \
            xtisa_errno = xtensa_isa_bad_state; \
            strcpy(xtisa_error_msg, "invalid state specifier"); \
            return ERRVAL; \
        } \
    } while (0)


xtensa_state xtensa_state_lookup(xtensa_isa isa, const char *name)
{
    xtensa_isa_internal *intisa = (xtensa_isa_internal *)isa;
    xtensa_lookup_entry entry, *result = 0;

    if (!name || !*name) {
        xtisa_errno = xtensa_isa_bad_state;
        strcpy(xtisa_error_msg, "invalid state name");
        return XTENSA_UNDEFINED;
    }

    if (intisa->num_states != 0) {
        entry.key = name;
        result = bsearch(&entry, intisa->state_lookup_table,
                         intisa->num_states, sizeof(xtensa_lookup_entry),
                         xtensa_isa_name_compare);
    }

    if (!result) {
        xtisa_errno = xtensa_isa_bad_state;
        sprintf(xtisa_error_msg, "state \"%s\" not recognized", name);
        return XTENSA_UNDEFINED;
    }

    return result->u.state;
}


const char *xtensa_state_name(xtensa_isa isa, xtensa_state st)
{
    xtensa_isa_internal *intisa = (xtensa_isa_internal *)isa;

    CHECK_STATE(intisa, st, NULL);
    return intisa->states[st].name;
}


int xtensa_state_num_bits(xtensa_isa isa, xtensa_state st)
{
    xtensa_isa_internal *intisa = (xtensa_isa_internal *)isa;

    CHECK_STATE(intisa, st, XTENSA_UNDEFINED);
    return intisa->states[st].num_bits;
}


int xtensa_state_is_exported(xtensa_isa isa, xtensa_state st)
{
    xtensa_isa_internal *intisa = (xtensa_isa_internal *)isa;

    CHECK_STATE(intisa, st, XTENSA_UNDEFINED);
    if ((intisa->states[st].flags & XTENSA_STATE_IS_EXPORTED) != 0) {
        return 1;
    }
    return 0;
}


int xtensa_state_is_shared_or(xtensa_isa isa, xtensa_state st)
{
    xtensa_isa_internal *intisa = (xtensa_isa_internal *)isa;

    CHECK_STATE(intisa, st, XTENSA_UNDEFINED);
    if ((intisa->states[st].flags & XTENSA_STATE_IS_SHARED_OR) != 0) {
        return 1;
    }
    return 0;
}


/* Sysregs. */


#define CHECK_SYSREG(INTISA, SYSREG, ERRVAL) \
    do { \
        if ((SYSREG) < 0 || (SYSREG) >= (INTISA)->num_sysregs) { \
            xtisa_errno = xtensa_isa_bad_sysreg; \
            strcpy(xtisa_error_msg, "invalid sysreg specifier"); \
            return ERRVAL; \
        } \
    } while (0)


xtensa_sysreg xtensa_sysreg_lookup(xtensa_isa isa, int num, int is_user)
{
    xtensa_isa_internal *intisa = (xtensa_isa_internal *)isa;

    if (is_user != 0) {
        is_user = 1;
    }

    if (num < 0 || num > intisa->max_sysreg_num[is_user] ||
        intisa->sysreg_table[is_user][num] == XTENSA_UNDEFINED) {
        xtisa_errno = xtensa_isa_bad_sysreg;
        strcpy(xtisa_error_msg, "sysreg not recognized");
        return XTENSA_UNDEFINED;
    }

    return intisa->sysreg_table[is_user][num];
}


xtensa_sysreg xtensa_sysreg_lookup_name(xtensa_isa isa, const char *name)
{
    xtensa_isa_internal *intisa = (xtensa_isa_internal *)isa;
    xtensa_lookup_entry entry, *result = 0;

    if (!name || !*name) {
        xtisa_errno = xtensa_isa_bad_sysreg;
        strcpy(xtisa_error_msg, "invalid sysreg name");
        return XTENSA_UNDEFINED;
    }

    if (intisa->num_sysregs != 0) {
        entry.key = name;
        result = bsearch(&entry, intisa->sysreg_lookup_table,
                         intisa->num_sysregs, sizeof(xtensa_lookup_entry),
                         xtensa_isa_name_compare);
    }

    if (!result) {
        xtisa_errno = xtensa_isa_bad_sysreg;
        sprintf(xtisa_error_msg, "sysreg \"%s\" not recognized", name);
        return XTENSA_UNDEFINED;
    }

    return result->u.sysreg;
}


const char *xtensa_sysreg_name(xtensa_isa isa, xtensa_sysreg sysreg)
{
    xtensa_isa_internal *intisa = (xtensa_isa_internal *)isa;

    CHECK_SYSREG(intisa, sysreg, NULL);
    return intisa->sysregs[sysreg].name;
}


int xtensa_sysreg_number(xtensa_isa isa, xtensa_sysreg sysreg)
{
    xtensa_isa_internal *intisa = (xtensa_isa_internal *)isa;

    CHECK_SYSREG(intisa, sysreg, XTENSA_UNDEFINED);
    return intisa->sysregs[sysreg].number;
}


int xtensa_sysreg_is_user(xtensa_isa isa, xtensa_sysreg sysreg)
{
    xtensa_isa_internal *intisa = (xtensa_isa_internal *)isa;

    CHECK_SYSREG(intisa, sysreg, XTENSA_UNDEFINED);
    if (intisa->sysregs[sysreg].is_user) {
        return 1;
    }
    return 0;
}


/* Interfaces. */


#define CHECK_INTERFACE(INTISA, INTF, ERRVAL) \
    do { \
        if ((INTF) < 0 || (INTF) >= (INTISA)->num_interfaces) { \
            xtisa_errno = xtensa_isa_bad_interface; \
            strcpy(xtisa_error_msg, "invalid interface specifier"); \
            return ERRVAL; \
        } \
    } while (0)


xtensa_interface xtensa_interface_lookup(xtensa_isa isa, const char *ifname)
{
    xtensa_isa_internal *intisa = (xtensa_isa_internal *)isa;
    xtensa_lookup_entry entry, *result = 0;

    if (!ifname || !*ifname) {
        xtisa_errno = xtensa_isa_bad_interface;
        strcpy(xtisa_error_msg, "invalid interface name");
        return XTENSA_UNDEFINED;
    }

    if (intisa->num_interfaces != 0) {
        entry.key = ifname;
        result = bsearch(&entry, intisa->interface_lookup_table,
                         intisa->num_interfaces, sizeof(xtensa_lookup_entry),
                         xtensa_isa_name_compare);
    }

    if (!result) {
        xtisa_errno = xtensa_isa_bad_interface;
        sprintf(xtisa_error_msg, "interface \"%s\" not recognized", ifname);
        return XTENSA_UNDEFINED;
    }

    return result->u.intf;
}


const char *xtensa_interface_name(xtensa_isa isa, xtensa_interface intf)
{
    xtensa_isa_internal *intisa = (xtensa_isa_internal *)isa;

    CHECK_INTERFACE(intisa, intf, NULL);
    return intisa->interfaces[intf].name;
}


int xtensa_interface_num_bits(xtensa_isa isa, xtensa_interface intf)
{
    xtensa_isa_internal *intisa = (xtensa_isa_internal *)isa;

    CHECK_INTERFACE(intisa, intf, XTENSA_UNDEFINED);
    return intisa->interfaces[intf].num_bits;
}


char xtensa_interface_inout(xtensa_isa isa, xtensa_interface intf)
{
    xtensa_isa_internal *intisa = (xtensa_isa_internal *)isa;

    CHECK_INTERFACE(intisa, intf, 0);
    return intisa->interfaces[intf].inout;
}


int xtensa_interface_has_side_effect(xtensa_isa isa, xtensa_interface intf)
{
    xtensa_isa_internal *intisa = (xtensa_isa_internal *)isa;

    CHECK_INTERFACE(intisa, intf, XTENSA_UNDEFINED);
    if ((intisa->interfaces[intf].flags &
         XTENSA_INTERFACE_HAS_SIDE_EFFECT) != 0) {
        return 1;
    }
    return 0;
}


int xtensa_interface_class_id(xtensa_isa isa, xtensa_interface intf)
{
    xtensa_isa_internal *intisa = (xtensa_isa_internal *)isa;

    CHECK_INTERFACE(intisa, intf, XTENSA_UNDEFINED);
    return intisa->interfaces[intf].class_id;
}


/* Functional Units. */


#define CHECK_FUNCUNIT(INTISA, FUN, ERRVAL) \
    do { \
        if ((FUN) < 0 || (FUN) >= (INTISA)->num_funcUnits) { \
            xtisa_errno = xtensa_isa_bad_funcUnit; \
            strcpy(xtisa_error_msg, "invalid functional unit specifier"); \
            return ERRVAL; \
        } \
    } while (0)


xtensa_funcUnit xtensa_funcUnit_lookup(xtensa_isa isa, const char *fname)
{
    xtensa_isa_internal *intisa = (xtensa_isa_internal *)isa;
    xtensa_lookup_entry entry, *result = 0;

    if (!fname || !*fname) {
        xtisa_errno = xtensa_isa_bad_funcUnit;
        strcpy(xtisa_error_msg, "invalid functional unit name");
        return XTENSA_UNDEFINED;
    }

    if (intisa->num_funcUnits != 0) {
        entry.key = fname;
        result = bsearch(&entry, intisa->funcUnit_lookup_table,
                         intisa->num_funcUnits, sizeof(xtensa_lookup_entry),
                         xtensa_isa_name_compare);
    }

    if (!result) {
        xtisa_errno = xtensa_isa_bad_funcUnit;
        sprintf(xtisa_error_msg,
                "functional unit \"%s\" not recognized", fname);
        return XTENSA_UNDEFINED;
    }

    return result->u.fun;
}


const char *xtensa_funcUnit_name(xtensa_isa isa, xtensa_funcUnit fun)
{
    xtensa_isa_internal *intisa = (xtensa_isa_internal *)isa;

    CHECK_FUNCUNIT(intisa, fun, NULL);
    return intisa->funcUnits[fun].name;
}


int xtensa_funcUnit_num_copies(xtensa_isa isa, xtensa_funcUnit fun)
{
    xtensa_isa_internal *intisa = (xtensa_isa_internal *)isa;

    CHECK_FUNCUNIT(intisa, fun, XTENSA_UNDEFINED);
    return intisa->funcUnits[fun].num_copies;
}
