/*
 * x86 identifier recognition and instruction handling
 *
 *  Copyright (C) 2002-2007  Peter Johnson
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND OTHER CONTRIBUTORS ``AS IS''
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR OTHER CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */
#include <ctype.h>
#include <util.h>
RCSID("$Id$");

#include <libyasm.h>
#include <libyasm/phash.h>

#include "modules/arch/x86/x86arch.h"


static const char *cpu_find_reverse(unsigned int cpu0, unsigned int cpu1,
                                    unsigned int cpu2);

/* Opcode modifiers. */
#define MOD_Gap     0   /* Eats a parameter / does nothing */
#define MOD_PreAdd  1   /* Parameter adds to "special" prefix */
#define MOD_Op0Add  2   /* Parameter adds to opcode byte 0 */
#define MOD_Op1Add  3   /* Parameter adds to opcode byte 1 */
#define MOD_Op2Add  4   /* Parameter adds to opcode byte 2 */
#define MOD_SpAdd   5   /* Parameter adds to "spare" value */
#define MOD_OpSizeR 6   /* Parameter replaces opersize */
#define MOD_Imm8    7   /* Parameter is included as immediate byte */
#define MOD_AdSizeR 8   /* Parameter replaces addrsize (jmp only) */
#define MOD_DOpS64R 9   /* Parameter replaces default 64-bit opersize */
#define MOD_Op1AddSp 10 /* Parameter is added as "spare" to opcode byte 2 */

/* GAS suffix flags for instructions */
enum x86_gas_suffix_flags {
    NONE = 0,
    SUF_B = 1<<0,
    SUF_W = 1<<1,
    SUF_L = 1<<2,
    SUF_Q = 1<<3,
    SUF_S = 1<<4,
    SUF_MASK = SUF_B|SUF_W|SUF_L|SUF_Q|SUF_S,

    /* Flags only used in x86_insn_info */
    GAS_ONLY = 1<<5,        /* Only available in GAS mode */
    GAS_ILLEGAL = 1<<6,     /* Illegal in GAS mode */
    GAS_NO_REV = 1<<7,      /* Don't reverse operands in GAS mode */

    /* Flags only used in insnprefix_parse_data */
    WEAK = 1<<5             /* Relaxed operand mode for GAS */
};

enum x86_operand_type {
    OPT_Imm = 0,        /* immediate */
    OPT_Reg = 1,        /* any general purpose or FPU register */
    OPT_Mem = 2,        /* memory */
    OPT_RM = 3,         /* any general purpose or FPU register OR memory */
    OPT_SIMDReg = 4,    /* any MMX or XMM register */
    OPT_SIMDRM = 5,     /* any MMX or XMM register OR memory */
    OPT_SegReg = 6,     /* any segment register */
    OPT_CRReg = 7,      /* any CR register */
    OPT_DRReg = 8,      /* any DR register */
    OPT_TRReg = 9,      /* any TR register */
    OPT_ST0 = 10,       /* ST0 */
    OPT_Areg = 11,      /* AL/AX/EAX/RAX (depending on size) */
    OPT_Creg = 12,      /* CL/CX/ECX/RCX (depending on size) */
    OPT_Dreg = 13,      /* DL/DX/EDX/RDX (depending on size) */
    OPT_CS = 14,        /* CS */
    OPT_DS = 15,        /* DS */
    OPT_ES = 16,        /* ES */
    OPT_FS = 17,        /* FS */
    OPT_GS = 18,        /* GS */
    OPT_SS = 19,        /* SS */
    OPT_CR4 = 20,       /* CR4 */
    /* memory offset (an EA, but with no registers allowed)
     * [special case for MOV opcode]
     */
    OPT_MemOffs = 21,
    OPT_Imm1 = 22,      /* immediate, value=1 (for special-case shift) */
    /* immediate, does not contain SEG:OFF (for jmp/call) */
    OPT_ImmNotSegOff = 23,
    OPT_XMM0 = 24,      /* XMM0 */
    /* AX/EAX/RAX memory operand only (EA) [special case for SVM opcodes]
     */
    OPT_MemrAX = 25,
    /* EAX memory operand only (EA) [special case for SVM skinit opcode] */
    OPT_MemEAX = 26,
    /* SIMDReg with value equal to operand 0 SIMDReg */
    OPT_SIMDRegMatch0 = 27
};

enum x86_operand_size {
    /* any size acceptable/no size spec acceptable (dep. on strict) */
    OPS_Any = 0,
    /* 8/16/32/64 bits (from user or reg size) */
    OPS_8 = 1,
    OPS_16 = 2,
    OPS_32 = 3,
    OPS_64 = 4,
    /* 80/128 bits (from user) */
    OPS_80 = 5,
    OPS_128 = 6,
    /* current BITS setting; when this is used the size matched
     * gets stored into the opersize as well.
     */
    OPS_BITS = 7
};

enum x86_operand_targetmod {
    OPTM_None = 0,  /* no target mod acceptable */
    OPTM_Near = 1,  /* NEAR */
    OPTM_Short = 2, /* SHORT */
    OPTM_Far = 3,   /* FAR (or SEG:OFF immediate) */
    OPTM_To = 4     /* TO */
};

enum x86_operand_action {
    OPA_None = 0,   /* does nothing (operand data is discarded) */
    OPA_EA = 1,     /* operand data goes into ea field */
    OPA_Imm = 2,    /* operand data goes into imm field */
    OPA_SImm = 3,   /* operand data goes into sign-extended imm field */
    OPA_Spare = 4,  /* operand data goes into "spare" field */
    OPA_Op0Add = 5, /* operand data is added to opcode byte 0 */
    OPA_Op1Add = 6, /* operand data is added to opcode byte 1 */
    /* operand data goes into BOTH ea and spare
     * (special case for imul opcode)
     */
    OPA_SpareEA = 7,
    /* relative jump (outputs a jmp instead of normal insn) */
    OPA_JmpRel = 8,
    /* operand size goes into address size (jmp only) */
    OPA_AdSizeR = 9,
    /* far jump (outputs a farjmp instead of normal insn) */
    OPA_JmpFar = 10,
    /* ea operand only sets address size (no actual ea field) */
    OPA_AdSizeEA = 11,
    OPA_DREX = 12   /* operand data goes into DREX "dest" field */
};

enum x86_operand_post_action {
    OPAP_None = 0,
    /* sign-extended imm8 that could expand to a large imm16/32 */
    OPAP_SImm8 = 1,
    /* could become a short opcode mov with bits=64 and a32 prefix */
    OPAP_ShortMov = 2,
    /* forced 16-bit address size (override ignored, no prefix) */
    OPAP_A16 = 3,
    /* large imm64 that can become a sign-extended imm32 */
    OPAP_SImm32Avail = 4
};

typedef struct x86_info_operand {
    /* Operand types.  These are more detailed than the "general" types for all
     * architectures, as they include the size, for instance.
     */

    /* general type (must be exact match, except for RM types): */
    unsigned int type:5;

    /* size (user-specified, or from register size) */
    unsigned int size:3;

    /* size implicit or explicit ("strictness" of size matching on
     * non-registers -- registers are always strictly matched):
     * 0 = user size must exactly match size above.
     * 1 = user size either unspecified or exactly match size above.
     */
    unsigned int relaxed:1;

    /* effective address size
     * 0 = any address size allowed except for 64-bit
     * 1 = only 64-bit address size allowed
     */
    unsigned int eas64:1;

    /* target modification */
    unsigned int targetmod:3;

    /* Actions: what to do with the operand if the instruction matches.
     * Essentially describes what part of the output bytecode gets the
     * operand.  This may require conversion (e.g. a register going into
     * an ea field).  Naturally, only one of each of these may be contained
     * in the operands of a single insn_info structure.
     */
    unsigned int action:4;

    /* Postponed actions: actions which can't be completed at
     * parse-time due to possibly dependent expressions.  For these, some
     * additional data (stored in the second byte of the opcode with a
     * one-byte opcode) is passed to later stages of the assembler with
     * flags set to indicate postponed actions.
     */
    unsigned int post_action:3;
} x86_info_operand;

typedef struct x86_insn_info {
    /* GAS suffix flags */
    unsigned int gas_flags:8;      /* Enabled for these GAS suffixes */

    /* The CPU feature flags needed to execute this instruction.  This is OR'ed
     * with arch-specific data[2].  This combined value is compared with
     * cpu_enabled to see if all bits set here are set in cpu_enabled--if so,
     * the instruction is available on this CPU.
     */
    unsigned int cpu0:8;
    unsigned int cpu1:8;
    unsigned int cpu2:8;

    /* Opcode modifiers for variations of instruction.  As each modifier reads
     * its parameter in LSB->MSB order from the arch-specific data[1] from the
     * lexer data, and the LSB of the arch-specific data[1] is reserved for the
     * count of insn_info structures in the instruction grouping, there can
     * only be a maximum of 3 modifiers.
     */
    unsigned char modifiers[3];

    /* Operand Size */
    unsigned char opersize;

    /* Default operand size in 64-bit mode (0 = 32-bit for readability). */
    unsigned char def_opersize_64;

    /* A special instruction prefix, used for some of the Intel SSE and SSE2
     * instructions.  Intel calls these 3-byte opcodes, but in AMD64's 64-bit
     * mode, they're treated like normal prefixes (e.g. the REX prefix needs
     * to be *after* the F2/F3/66 "prefix").
     * (0=no special prefix)
     */
    unsigned char special_prefix;

    /* The DREX base byte value (almost).  The only bit kept from this
     * value is the OC0 bit (0x08).  The MSB (0x80) of this value indicates
     * if the DREX byte needs to be present in the instruction.
     */
#define NEED_DREX_MASK 0x80
#define DREX_OC0_MASK 0x08
    unsigned char drex_oc0;

    /* The length of the basic opcode */
    unsigned char opcode_len;

    /* The basic 1-3 byte opcode (not including the special instruction
     * prefix).
     */
    unsigned char opcode[3];

    /* The 3-bit "spare" value (extended opcode) for the R/M byte field */
    unsigned char spare;

    /* The number of operands this form of the instruction takes */
    unsigned int num_operands:4;

    /* The index into the insn_operands array which contains the type of each
     * operand, see above
     */
    unsigned int operands_index:12;
} x86_insn_info;

typedef struct x86_id_insn {
    yasm_insn insn;     /* base structure */

    /* instruction parse group - NULL if empty instruction (just prefixes) */
    /*@null@*/ const x86_insn_info *group;

    /* CPU feature flags enabled at the time of parsing the instruction */
    wordptr cpu_enabled;

    /* Modifier data */
    unsigned char mod_data[3];

    /* Number of elements in the instruction parse group */
    unsigned int num_info:8;

    /* BITS setting active at the time of parsing the instruction */
    unsigned int mode_bits:8;

    /* Suffix flags */
    unsigned int suffix:8;

    /* Parser enabled at the time of parsing the instruction */
    unsigned int parser:2;

    /* Strict forced setting at the time of parsing the instruction */
    unsigned int force_strict:1;

    /* Default rel setting at the time of parsing the instruction */
    unsigned int default_rel:1;
} x86_id_insn;

static void x86_id_insn_destroy(void *contents);
static void x86_id_insn_print(const void *contents, FILE *f, int indent_level);
static void x86_id_insn_finalize(yasm_bytecode *bc, yasm_bytecode *prev_bc);

static const yasm_bytecode_callback x86_id_insn_callback = {
    x86_id_insn_destroy,
    x86_id_insn_print,
    x86_id_insn_finalize,
    yasm_bc_calc_len_common,
    yasm_bc_expand_common,
    yasm_bc_tobytes_common,
    YASM_BC_SPECIAL_INSN
};

#include "x86insns.c"

static void
x86_finalize_common(x86_common *common, const x86_insn_info *info,
                    unsigned int mode_bits)
{
    common->addrsize = 0;
    common->opersize = info->opersize;
    common->lockrep_pre = 0;
    common->mode_bits = (unsigned char)mode_bits;
}

static void
x86_finalize_opcode(x86_opcode *opcode, const x86_insn_info *info)
{
    opcode->len = info->opcode_len;
    opcode->opcode[0] = info->opcode[0];
    opcode->opcode[1] = info->opcode[1];
    opcode->opcode[2] = info->opcode[2];
}

/* Clear operands so they don't get destroyed after we've copied references. */
static void
x86_id_insn_clear_operands(x86_id_insn *id_insn)
{
    yasm_insn_operand *op = yasm_insn_ops_first(&id_insn->insn);
    while (op) {
        op->type = YASM_INSN__OPERAND_REG;
        op = yasm_insn_op_next(op);
    }
}

static void
x86_finalize_jmpfar(yasm_bytecode *bc, yasm_bytecode *prev_bc,
                    const x86_insn_info *info)
{
    x86_id_insn *id_insn = (x86_id_insn *)bc->contents;
    unsigned int mode_bits = id_insn->mode_bits;
    x86_jmpfar *jmpfar;
    yasm_insn_operand *op;
    /*@only@*/ yasm_expr *segment;

    jmpfar = yasm_xmalloc(sizeof(x86_jmpfar));
    x86_finalize_common(&jmpfar->common, info, mode_bits);
    x86_finalize_opcode(&jmpfar->opcode, info);

    op = yasm_insn_ops_first(&id_insn->insn);

    if (op->type == YASM_INSN__OPERAND_IMM &&
        yasm_expr_is_op(op->data.val, YASM_EXPR_SEGOFF)) {
        /* SEG:OFF expression; split it. */
        segment = yasm_expr_extract_segoff(&op->data.val);
        if (!segment)
            yasm_internal_error(N_("didn't get SEG:OFF expression in jmpfar"));
        if (yasm_value_finalize_expr(&jmpfar->segment, segment, prev_bc, 16))
            yasm_error_set(YASM_ERROR_TOO_COMPLEX,
                           N_("jump target segment too complex"));
        if (yasm_value_finalize_expr(&jmpfar->offset, op->data.val, prev_bc,
                                     0))
            yasm_error_set(YASM_ERROR_TOO_COMPLEX,
                           N_("jump target offset too complex"));
    } else if (op->targetmod == X86_FAR) {
        /* "FAR imm" target needs to become "seg imm:imm". */
        if (yasm_value_finalize_expr(&jmpfar->offset,
                                     yasm_expr_copy(op->data.val), prev_bc, 0)
            || yasm_value_finalize_expr(&jmpfar->segment, op->data.val,
                                        prev_bc, 16))
            yasm_error_set(YASM_ERROR_TOO_COMPLEX,
                           N_("jump target expression too complex"));
        jmpfar->segment.seg_of = 1;
    } else
        yasm_internal_error(N_("didn't get FAR expression in jmpfar"));

    yasm_x86__bc_apply_prefixes((x86_common *)jmpfar, NULL,
                                info->def_opersize_64,
                                id_insn->insn.num_prefixes,
                                id_insn->insn.prefixes);

    x86_id_insn_clear_operands(id_insn);

    /* Transform the bytecode */
    yasm_x86__bc_transform_jmpfar(bc, jmpfar);
}

static void
x86_finalize_jmp(yasm_bytecode *bc, yasm_bytecode *prev_bc,
                 const x86_insn_info *jinfo)
{
    x86_id_insn *id_insn = (x86_id_insn *)bc->contents;
    x86_jmp *jmp;
    int num_info = id_insn->num_info;
    const x86_insn_info *info = id_insn->group;
    unsigned char *mod_data = id_insn->mod_data;
    unsigned int mode_bits = id_insn->mode_bits;
    /*unsigned char suffix = id_insn->suffix;*/
    yasm_insn_operand *op;
    static const unsigned char size_lookup[] = {0, 8, 16, 32, 64, 80, 128, 0};
    unsigned int i;

    /* We know the target is in operand 0, but sanity check for Imm. */
    op = yasm_insn_ops_first(&id_insn->insn);
    if (op->type != YASM_INSN__OPERAND_IMM)
        yasm_internal_error(N_("invalid operand conversion"));

    jmp = yasm_xmalloc(sizeof(x86_jmp));
    x86_finalize_common(&jmp->common, jinfo, mode_bits);
    if (yasm_value_finalize_expr(&jmp->target, op->data.val, prev_bc, 0))
        yasm_error_set(YASM_ERROR_TOO_COMPLEX,
                       N_("jump target expression too complex"));
    if (jmp->target.seg_of || jmp->target.rshift || jmp->target.curpos_rel)
        yasm_error_set(YASM_ERROR_VALUE, N_("invalid jump target"));
    yasm_value_set_curpos_rel(&jmp->target, bc, 0);
    jmp->target.jump_target = 1;

    /* See if the user explicitly specified short/near/far. */
    switch (insn_operands[jinfo->operands_index+0].targetmod) {
        case OPTM_Short:
            jmp->op_sel = JMP_SHORT_FORCED;
            break;
        case OPTM_Near:
            jmp->op_sel = JMP_NEAR_FORCED;
            break;
        default:
            jmp->op_sel = JMP_NONE;
    }

    /* Check for address size setting in second operand, if present */
    if (jinfo->num_operands > 1 &&
        insn_operands[jinfo->operands_index+1].action == OPA_AdSizeR)
        jmp->common.addrsize = (unsigned char)
            size_lookup[insn_operands[jinfo->operands_index+1].size];

    /* Check for address size override */
    for (i=0; i<NELEMS(info->modifiers); i++) {
        if (jinfo->modifiers[i] == MOD_AdSizeR)
            jmp->common.addrsize = mod_data[i];
    }

    /* Scan through other infos for this insn looking for short/near versions.
     * Needs to match opersize and number of operands, also be within CPU.
     */
    jmp->shortop.len = 0;
    jmp->nearop.len = 0;
    for (; num_info>0 && (jmp->shortop.len == 0 || jmp->nearop.len == 0);
         num_info--, info++) {
        unsigned int cpu0 = info->cpu0;
        unsigned int cpu1 = info->cpu1;
        unsigned int cpu2 = info->cpu2;

        /* Match CPU */
        if (mode_bits != 64 &&
            (cpu0 == CPU_64 || cpu1 == CPU_64 || cpu2 == CPU_64))
            continue;
        if (mode_bits == 64 &&
            (cpu0 == CPU_Not64 || cpu1 == CPU_Not64 || cpu2 == CPU_Not64))
            continue;

        if (cpu0 == CPU_64 || cpu0 == CPU_Not64)
            cpu0 = CPU_Any;
        if (cpu1 == CPU_64 || cpu1 == CPU_Not64)
            cpu1 = CPU_Any;
        if (cpu2 == CPU_64 || cpu2 == CPU_Not64)
            cpu2 = CPU_Any;
        if (!BitVector_bit_test(id_insn->cpu_enabled, cpu0) ||
            !BitVector_bit_test(id_insn->cpu_enabled, cpu1) ||
            !BitVector_bit_test(id_insn->cpu_enabled, cpu2))
            continue;

        if (info->num_operands == 0)
            continue;

        if (insn_operands[info->operands_index+0].action != OPA_JmpRel)
            continue;

        if (info->opersize != jmp->common.opersize)
            continue;

        switch (insn_operands[info->operands_index+0].targetmod) {
            case OPTM_Short:
                x86_finalize_opcode(&jmp->shortop, info);
                for (i=0; i<NELEMS(info->modifiers); i++) {
                    if (info->modifiers[i] == MOD_Op0Add)
                        jmp->shortop.opcode[0] += mod_data[i];
                }
                break;
            case OPTM_Near:
                x86_finalize_opcode(&jmp->nearop, info);
                for (i=0; i<NELEMS(info->modifiers); i++) {
                    if (info->modifiers[i] == MOD_Op1Add)
                        jmp->nearop.opcode[1] += mod_data[i];
                }
                break;
        }
    }

    if ((jmp->op_sel == JMP_SHORT_FORCED) && (jmp->nearop.len == 0))
        yasm_error_set(YASM_ERROR_TYPE,
                       N_("no SHORT form of that jump instruction exists"));
    if ((jmp->op_sel == JMP_NEAR_FORCED) && (jmp->shortop.len == 0))
        yasm_error_set(YASM_ERROR_TYPE,
                       N_("no NEAR form of that jump instruction exists"));

    if (jmp->op_sel == JMP_NONE) {
        if (jmp->nearop.len == 0)
            jmp->op_sel = JMP_SHORT_FORCED;
        if (jmp->shortop.len == 0)
            jmp->op_sel = JMP_NEAR_FORCED;
    }

    yasm_x86__bc_apply_prefixes((x86_common *)jmp, NULL, info->def_opersize_64,
                                id_insn->insn.num_prefixes,
                                id_insn->insn.prefixes);

    x86_id_insn_clear_operands(id_insn);

    /* Transform the bytecode */
    yasm_x86__bc_transform_jmp(bc, jmp);
}

static const x86_insn_info *
x86_find_match(x86_id_insn *id_insn, yasm_insn_operand **ops,
               yasm_insn_operand **rev_ops, const unsigned int *size_lookup,
               int bypass)
{
    const x86_insn_info *info = id_insn->group;
    unsigned int num_info = id_insn->num_info;
    unsigned int suffix = id_insn->suffix;
    unsigned int mode_bits = id_insn->mode_bits;
    int found = 0;

    /* Just do a simple linear search through the info array for a match.
     * First match wins.
     */
    for (; num_info>0 && !found; num_info--, info++) {
        yasm_insn_operand *op, **use_ops;
        const x86_info_operand *info_ops =
            &insn_operands[info->operands_index];
        unsigned int cpu0 = info->cpu0;
        unsigned int cpu1 = info->cpu1;
        unsigned int cpu2 = info->cpu2;
        unsigned int gas_flags = info->gas_flags;
        unsigned int size;
        int mismatch = 0;
        int i;

        /* Match CPU */
        if (mode_bits != 64 &&
            (cpu0 == CPU_64 || cpu1 == CPU_64 || cpu2 == CPU_64))
            continue;
        if (mode_bits == 64 &&
            (cpu0 == CPU_Not64 || cpu1 == CPU_Not64 || cpu2 == CPU_Not64))
            continue;

        if (cpu0 == CPU_64 || cpu0 == CPU_Not64)
            cpu0 = CPU_Any;
        if (cpu1 == CPU_64 || cpu1 == CPU_Not64)
            cpu1 = CPU_Any;
        if (cpu2 == CPU_64 || cpu2 == CPU_Not64)
            cpu2 = CPU_Any;
        if (bypass != 8 && (!BitVector_bit_test(id_insn->cpu_enabled, cpu0) ||
                            !BitVector_bit_test(id_insn->cpu_enabled, cpu1) ||
                            !BitVector_bit_test(id_insn->cpu_enabled, cpu2)))
            continue;

        /* Match # of operands */
        if (id_insn->insn.num_operands != info->num_operands)
            continue;

        /* Match parser mode */
        if ((gas_flags & GAS_ONLY) && id_insn->parser != X86_PARSER_GAS)
            continue;
        if ((gas_flags & GAS_ILLEGAL) && id_insn->parser == X86_PARSER_GAS)
            continue;

        /* Match suffix (if required) */
        if (suffix != 0 && suffix != WEAK
            && ((suffix & SUF_MASK) & (gas_flags & SUF_MASK)) == 0)
            continue;

        /* Use reversed operands in GAS mode if not otherwise specified */
        use_ops = ops;
        if (id_insn->parser == X86_PARSER_GAS && !(gas_flags & GAS_NO_REV))
            use_ops = rev_ops;

        if (id_insn->insn.num_operands == 0) {
            found = 1;      /* no operands -> must have a match here. */
            break;
        }

        /* Match each operand type and size */
        for (i = 0, op = use_ops[0]; op && i<info->num_operands && !mismatch;
             op = use_ops[++i]) {
            /* Check operand type */
            switch (info_ops[i].type) {
                case OPT_Imm:
                    if (op->type != YASM_INSN__OPERAND_IMM)
                        mismatch = 1;
                    break;
                case OPT_RM:
                    if (op->type == YASM_INSN__OPERAND_MEMORY)
                        break;
                    /*@fallthrough@*/
                case OPT_Reg:
                    if (op->type != YASM_INSN__OPERAND_REG)
                        mismatch = 1;
                    else {
                        switch ((x86_expritem_reg_size)(op->data.reg&~0xFUL)) {
                            case X86_REG8:
                            case X86_REG8X:
                            case X86_REG16:
                            case X86_REG32:
                            case X86_REG64:
                            case X86_FPUREG:
                                break;
                            default:
                                mismatch = 1;
                                break;
                        }
                    }
                    break;
                case OPT_Mem:
                    if (op->type != YASM_INSN__OPERAND_MEMORY)
                        mismatch = 1;
                    break;
                case OPT_SIMDRM:
                    if (op->type == YASM_INSN__OPERAND_MEMORY)
                        break;
                    /*@fallthrough@*/
                case OPT_SIMDRegMatch0:
                case OPT_SIMDReg:
                    if (op->type != YASM_INSN__OPERAND_REG)
                        mismatch = 1;
                    else {
                        switch ((x86_expritem_reg_size)(op->data.reg&~0xFUL)) {
                            case X86_MMXREG:
                            case X86_XMMREG:
                                break;
                            default:
                                mismatch = 1;
                                break;
                        }
                    }
                    if (!mismatch && info_ops[i].type == OPT_SIMDRegMatch0 &&
                        bypass != 7 && op->data.reg != use_ops[0]->data.reg)
                        mismatch = 1;
                    break;
                case OPT_SegReg:
                    if (op->type != YASM_INSN__OPERAND_SEGREG)
                        mismatch = 1;
                    break;
                case OPT_CRReg:
                    if (op->type != YASM_INSN__OPERAND_REG ||
                        (op->data.reg & ~0xFUL) != X86_CRREG)
                        mismatch = 1;
                    break;
                case OPT_DRReg:
                    if (op->type != YASM_INSN__OPERAND_REG ||
                        (op->data.reg & ~0xFUL) != X86_DRREG)
                        mismatch = 1;
                    break;
                case OPT_TRReg:
                    if (op->type != YASM_INSN__OPERAND_REG ||
                        (op->data.reg & ~0xFUL) != X86_TRREG)
                        mismatch = 1;
                    break;
                case OPT_ST0:
                    if (op->type != YASM_INSN__OPERAND_REG ||
                        op->data.reg != X86_FPUREG)
                        mismatch = 1;
                    break;
                case OPT_Areg:
                    if (op->type != YASM_INSN__OPERAND_REG ||
                        (info_ops[i].size == OPS_8 &&
                         op->data.reg != (X86_REG8 | 0) &&
                         op->data.reg != (X86_REG8X | 0)) ||
                        (info_ops[i].size == OPS_16 &&
                         op->data.reg != (X86_REG16 | 0)) ||
                        (info_ops[i].size == OPS_32 &&
                         op->data.reg != (X86_REG32 | 0)) ||
                        (info_ops[i].size == OPS_64 &&
                         op->data.reg != (X86_REG64 | 0)))
                        mismatch = 1;
                    break;
                case OPT_Creg:
                    if (op->type != YASM_INSN__OPERAND_REG ||
                        (info_ops[i].size == OPS_8 &&
                         op->data.reg != (X86_REG8 | 1) &&
                         op->data.reg != (X86_REG8X | 1)) ||
                        (info_ops[i].size == OPS_16 &&
                         op->data.reg != (X86_REG16 | 1)) ||
                        (info_ops[i].size == OPS_32 &&
                         op->data.reg != (X86_REG32 | 1)) ||
                        (info_ops[i].size == OPS_64 &&
                         op->data.reg != (X86_REG64 | 1)))
                        mismatch = 1;
                    break;
                case OPT_Dreg:
                    if (op->type != YASM_INSN__OPERAND_REG ||
                        (info_ops[i].size == OPS_8 &&
                         op->data.reg != (X86_REG8 | 2) &&
                         op->data.reg != (X86_REG8X | 2)) ||
                        (info_ops[i].size == OPS_16 &&
                         op->data.reg != (X86_REG16 | 2)) ||
                        (info_ops[i].size == OPS_32 &&
                         op->data.reg != (X86_REG32 | 2)) ||
                        (info_ops[i].size == OPS_64 &&
                         op->data.reg != (X86_REG64 | 2)))
                        mismatch = 1;
                    break;
                case OPT_CS:
                    if (op->type != YASM_INSN__OPERAND_SEGREG ||
                        (op->data.reg & 0xF) != 1)
                        mismatch = 1;
                    break;
                case OPT_DS:
                    if (op->type != YASM_INSN__OPERAND_SEGREG ||
                        (op->data.reg & 0xF) != 3)
                        mismatch = 1;
                    break;
                case OPT_ES:
                    if (op->type != YASM_INSN__OPERAND_SEGREG ||
                        (op->data.reg & 0xF) != 0)
                        mismatch = 1;
                    break;
                case OPT_FS:
                    if (op->type != YASM_INSN__OPERAND_SEGREG ||
                        (op->data.reg & 0xF) != 4)
                        mismatch = 1;
                    break;
                case OPT_GS:
                    if (op->type != YASM_INSN__OPERAND_SEGREG ||
                        (op->data.reg & 0xF) != 5)
                        mismatch = 1;
                    break;
                case OPT_SS:
                    if (op->type != YASM_INSN__OPERAND_SEGREG ||
                        (op->data.reg & 0xF) != 2)
                        mismatch = 1;
                    break;
                case OPT_CR4:
                    if (op->type != YASM_INSN__OPERAND_REG ||
                        op->data.reg != (X86_CRREG | 4))
                        mismatch = 1;
                    break;
                case OPT_MemOffs:
                    if (op->type != YASM_INSN__OPERAND_MEMORY ||
                        yasm_expr__contains(op->data.ea->disp.abs,
                                            YASM_EXPR_REG) ||
                        op->data.ea->pc_rel ||
                        (!op->data.ea->not_pc_rel && id_insn->default_rel &&
                         op->data.ea->disp.size != 64))
                        mismatch = 1;
                    break;
                case OPT_Imm1:
                    if (op->type == YASM_INSN__OPERAND_IMM) {
                        const yasm_intnum *num;
                        num = yasm_expr_get_intnum(&op->data.val, 0);
                        if (!num || !yasm_intnum_is_pos1(num))
                            mismatch = 1;
                    } else
                        mismatch = 1;
                    break;
                case OPT_ImmNotSegOff:
                    if (op->type != YASM_INSN__OPERAND_IMM ||
                        op->targetmod != 0 ||
                        yasm_expr_is_op(op->data.val, YASM_EXPR_SEGOFF))
                        mismatch = 1;
                    break;
                case OPT_XMM0:
                    if (op->type != YASM_INSN__OPERAND_REG ||
                        op->data.reg != X86_XMMREG)
                        mismatch = 1;
                    break;
                case OPT_MemrAX: {
                    const uintptr_t *regp;
                    if (op->type != YASM_INSN__OPERAND_MEMORY ||
                        !(regp = yasm_expr_get_reg(&op->data.ea->disp.abs, 0)) ||
                        (*regp != (X86_REG16 | 0) &&
                         *regp != (X86_REG32 | 0) &&
                         *regp != (X86_REG64 | 0)))
                        mismatch = 1;
                    break;
                }
                case OPT_MemEAX: {
                    const uintptr_t *regp;
                    if (op->type != YASM_INSN__OPERAND_MEMORY ||
                        !(regp = yasm_expr_get_reg(&op->data.ea->disp.abs, 0)) ||
                        *regp != (X86_REG32 | 0))
                        mismatch = 1;
                    break;
                }
                default:
                    yasm_internal_error(N_("invalid operand type"));
            }

            if (mismatch)
                break;

            /* Check operand size */
            size = size_lookup[info_ops[i].size];
            if (suffix != 0) {
                /* Require relaxed operands for GAS mode (don't allow
                 * per-operand sizing).
                 */
                if (op->type == YASM_INSN__OPERAND_REG && op->size == 0) {
                    /* Register size must exactly match */
                    if (yasm_x86__get_reg_size(op->data.reg) != size)
                        mismatch = 1;
                } else if ((info_ops[i].type == OPT_Imm
                            || info_ops[i].type == OPT_ImmNotSegOff
                            || info_ops[i].type == OPT_Imm1)
                    && !info_ops[i].relaxed
                    && info_ops[i].action != OPA_JmpRel)
                    mismatch = 1;
            } else {
                if (op->type == YASM_INSN__OPERAND_REG && op->size == 0) {
                    /* Register size must exactly match */
                    if ((bypass == 4 && i == 0) || (bypass == 5 && i == 1)
                        || (bypass == 6 && i == 3))
                        ;
                    else if (yasm_x86__get_reg_size(op->data.reg) != size)
                        mismatch = 1;
                } else {
                    if ((bypass == 1 && i == 0) || (bypass == 2 && i == 1)
                        || (bypass == 3 && i == 3))
                        ;
                    else if (info_ops[i].relaxed) {
                        /* Relaxed checking */
                        if (size != 0 && op->size != size && op->size != 0)
                            mismatch = 1;
                    } else {
                        /* Strict checking */
                        if (op->size != size)
                            mismatch = 1;
                    }
                }
            }

            if (mismatch)
                break;

            /* Check for 64-bit effective address size in NASM mode */
            if (suffix == 0 && op->type == YASM_INSN__OPERAND_MEMORY) {
                if (info_ops[i].eas64) {
                    if (op->data.ea->disp.size != 64)
                        mismatch = 1;
                } else if (op->data.ea->disp.size == 64)
                    mismatch = 1;
            }

            if (mismatch)
                break;

            /* Check target modifier */
            switch (info_ops[i].targetmod) {
                case OPTM_None:
                    if (op->targetmod != 0)
                        mismatch = 1;
                    break;
                case OPTM_Near:
                    if (op->targetmod != X86_NEAR)
                        mismatch = 1;
                    break;
                case OPTM_Short:
                    if (op->targetmod != X86_SHORT)
                        mismatch = 1;
                    break;
                case OPTM_Far:
                    if (op->targetmod != X86_FAR)
                        mismatch = 1;
                    break;
                case OPTM_To:
                    if (op->targetmod != X86_TO)
                        mismatch = 1;
                    break;
                default:
                    yasm_internal_error(N_("invalid target modifier type"));
            }
        }

        if (!mismatch) {
            found = 1;
            break;
        }
    }

    if (!found)
        return NULL;
    return info;
}

static void
x86_match_error(x86_id_insn *id_insn, yasm_insn_operand **ops,
                yasm_insn_operand **rev_ops, const unsigned int *size_lookup)
{
    const x86_insn_info *i;
    int ni;
    int found;
    int bypass;

    /* Check for matching # of operands */
    found = 0;
    for (ni=id_insn->num_info, i=id_insn->group; ni>0; ni--, i++) {
        if (id_insn->insn.num_operands == i->num_operands) {
            found = 1;
            break;
        }
    }
    if (!found) {
        yasm_error_set(YASM_ERROR_TYPE, N_("invalid number of operands"));
        return;
    }

    for (bypass=1; bypass<9; bypass++) {
        i = x86_find_match(id_insn, ops, rev_ops, size_lookup, bypass);
        if (i)
            break;
    }

    switch (bypass) {
        case 1:
        case 4:
            yasm_error_set(YASM_ERROR_TYPE,
                           N_("invalid size for operand %d"), 1);
            break;
        case 2:
        case 5:
            yasm_error_set(YASM_ERROR_TYPE,
                           N_("invalid size for operand %d"), 2);
            break;
        case 3:
        case 6:
            yasm_error_set(YASM_ERROR_TYPE,
                           N_("invalid size for operand %d"), 3);
            break;
        case 7:
            yasm_error_set(YASM_ERROR_TYPE,
                N_("one of source operand 1 or 3 must match dest operand"));
            break;
        case 8:
        {
            unsigned int cpu0 = i->cpu0, cpu1 = i->cpu1, cpu2 = i->cpu2;
            yasm_error_set(YASM_ERROR_TYPE,
                          N_("requires CPU%s"),
                          cpu_find_reverse(cpu0, cpu1, cpu2));
            break;
        }
        default:
            yasm_error_set(YASM_ERROR_TYPE,
                           N_("invalid combination of opcode and operands"));
    }
}

static void
x86_id_insn_finalize(yasm_bytecode *bc, yasm_bytecode *prev_bc)
{
    x86_id_insn *id_insn = (x86_id_insn *)bc->contents;
    x86_insn *insn;
    const x86_insn_info *info = id_insn->group;
    unsigned int mode_bits = id_insn->mode_bits;
    unsigned char *mod_data = id_insn->mod_data;
    yasm_insn_operand *op, *ops[4], *rev_ops[4];
    /*@null@*/ yasm_expr *imm;
    unsigned char im_len;
    unsigned char im_sign;
    unsigned char spare;
    unsigned char drex;
    unsigned char *pdrex;
    unsigned int i;
    unsigned int size_lookup[] = {0, 8, 16, 32, 64, 80, 128, 0};
    unsigned long do_postop = 0;

    size_lookup[7] = mode_bits;

    yasm_insn_finalize(&id_insn->insn);

    /* Build local array of operands from list, since we know we have a max
     * of 4 operands.
     */
    if (id_insn->insn.num_operands > 4) {
        yasm_error_set(YASM_ERROR_TYPE, N_("too many operands"));
        return;
    }
    ops[0] = ops[1] = ops[2] = ops[3] = NULL;
    for (i = 0, op = yasm_insn_ops_first(&id_insn->insn);
         op && i < id_insn->insn.num_operands;
         op = yasm_insn_op_next(op), i++)
        ops[i] = op;

    /* If we're running in GAS mode, build a reverse array of the operands
     * as most GAS instructions have reversed operands from Intel style.
     */
    if (id_insn->parser == X86_PARSER_GAS) {
        rev_ops[0] = rev_ops[1] = rev_ops[2] = rev_ops[3] = NULL;
        for (i = id_insn->insn.num_operands-1,
             op = yasm_insn_ops_first(&id_insn->insn);
             op; op = yasm_insn_op_next(op), i--)
            rev_ops[i] = op;
    }

    /* If we're running in GAS mode, look at the first insn_info to see
     * if this is a relative jump (OPA_JmpRel).  If so, run through the
     * operands and adjust for dereferences / lack thereof.
     */
    if (id_insn->parser == X86_PARSER_GAS
        && insn_operands[info->operands_index+0].action == OPA_JmpRel) {
        for (i = 0, op = ops[0]; op; op = ops[++i]) {
            if (!op->deref && (op->type == YASM_INSN__OPERAND_REG
                               || (op->type == YASM_INSN__OPERAND_MEMORY
                                   && op->data.ea->strong)))
                yasm_warn_set(YASM_WARN_GENERAL,
                              N_("indirect call without `*'"));
            if (!op->deref && op->type == YASM_INSN__OPERAND_MEMORY
                && !op->data.ea->strong) {
                /* Memory that is not dereferenced, and not strong, is
                 * actually an immediate for the purposes of relative jumps.
                 */
                if (op->data.ea->segreg != 0)
                    yasm_warn_set(YASM_WARN_GENERAL,
                                  N_("skipping prefixes on this instruction"));
                imm = op->data.ea->disp.abs;
                op->data.ea->disp.abs = NULL;
                yasm_x86__ea_destroy(op->data.ea);
                op->type = YASM_INSN__OPERAND_IMM;
                op->data.val = imm;
            }
        }
    }

    info = x86_find_match(id_insn, ops, rev_ops, size_lookup, 0);

    if (!info) {
        /* Didn't find a match */
        x86_match_error(id_insn, ops, rev_ops, size_lookup);
        return;
    }

    if (id_insn->insn.num_operands > 0) {
        switch (insn_operands[info->operands_index+0].action) {
            case OPA_JmpRel:
                /* Shortcut to JmpRel */
                x86_finalize_jmp(bc, prev_bc, info);
                return;
            case OPA_JmpFar:
                /* Shortcut to JmpFar */
                x86_finalize_jmpfar(bc, prev_bc, info);
                return;
        }
    }

    /* Copy what we can from info */
    insn = yasm_xmalloc(sizeof(x86_insn));
    x86_finalize_common(&insn->common, info, mode_bits);
    x86_finalize_opcode(&insn->opcode, info);
    insn->x86_ea = NULL;
    imm = NULL;
    insn->def_opersize_64 = info->def_opersize_64;
    insn->special_prefix = info->special_prefix;
    spare = info->spare;
    drex = info->drex_oc0 & DREX_OC0_MASK;
    im_len = 0;
    im_sign = 0;
    insn->postop = X86_POSTOP_NONE;
    insn->rex = 0;
    pdrex = (info->drex_oc0 & NEED_DREX_MASK) ? &drex : NULL;

    /* Apply modifiers */
    for (i=0; i<NELEMS(info->modifiers); i++) {
        switch (info->modifiers[i]) {
            case MOD_Gap:
                break;
            case MOD_PreAdd:
                insn->special_prefix += mod_data[i];
                break;
            case MOD_Op0Add:
                insn->opcode.opcode[0] += mod_data[i];
                break;
            case MOD_Op1Add:
                insn->opcode.opcode[1] += mod_data[i];
                break;
            case MOD_Op2Add:
                insn->opcode.opcode[2] += mod_data[i];
                break;
            case MOD_SpAdd:
                spare += mod_data[i];
                break;
            case MOD_OpSizeR:
                insn->common.opersize = mod_data[i];
                break;
            case MOD_Imm8:
                imm = yasm_expr_create_ident(yasm_expr_int(
                    yasm_intnum_create_uint(mod_data[i])), bc->line);
                im_len = 8;
                break;
            case MOD_DOpS64R:
                insn->def_opersize_64 = mod_data[i];
                break;
            case MOD_Op1AddSp:
                insn->opcode.opcode[1] += mod_data[i]<<3;
                break;
            default:
                break;
        }
    }

    /* In 64-bit mode, if opersize is 64 and default is not 64,
     * force REX byte.
     */
    if (mode_bits == 64 && insn->common.opersize == 64 &&
        insn->def_opersize_64 != 64)
        insn->rex = 0x48;

    /* Go through operands and assign */
    if (id_insn->insn.num_operands > 0) {
        yasm_insn_operand **use_ops = ops;
        const x86_info_operand *info_ops =
            &insn_operands[info->operands_index];

        /* Use reversed operands in GAS mode if not otherwise specified */
        if (id_insn->parser == X86_PARSER_GAS
            && !(info->gas_flags & GAS_NO_REV))
            use_ops = rev_ops;

        for (i = 0, op = use_ops[0]; op && i<info->num_operands;
             op = use_ops[++i]) {
            switch (info_ops[i].action) {
                case OPA_None:
                    /* Throw away the operand contents */
                    switch (op->type) {
                        case YASM_INSN__OPERAND_REG:
                        case YASM_INSN__OPERAND_SEGREG:
                            break;
                        case YASM_INSN__OPERAND_MEMORY:
                            yasm_x86__ea_destroy(op->data.ea);
                            break;
                        case YASM_INSN__OPERAND_IMM:
                            yasm_expr_destroy(op->data.val);
                            break;
                    }
                    break;
                case OPA_EA:
                    switch (op->type) {
                        case YASM_INSN__OPERAND_REG:
                            insn->x86_ea =
                                yasm_x86__ea_create_reg(insn->x86_ea,
                                    (unsigned long)op->data.reg, &insn->rex,
                                    pdrex, mode_bits);
                            break;
                        case YASM_INSN__OPERAND_SEGREG:
                            yasm_internal_error(
                                N_("invalid operand conversion"));
                        case YASM_INSN__OPERAND_MEMORY:
                            insn->x86_ea = (x86_effaddr *)op->data.ea;
                            if (info_ops[i].type == OPT_MemOffs)
                                /* Special-case for MOV MemOffs instruction */
                                yasm_x86__ea_set_disponly(insn->x86_ea);
                            else if (id_insn->default_rel &&
                                     !op->data.ea->not_pc_rel &&
                                     op->data.ea->segreg == 0 &&
                                     !yasm_expr__contains(
                                        op->data.ea->disp.abs, YASM_EXPR_REG))
                                /* Enable default PC-rel if no regs/segregs */
                                insn->x86_ea->ea.pc_rel = 1;
                            break;
                        case YASM_INSN__OPERAND_IMM:
                            insn->x86_ea =
                                yasm_x86__ea_create_imm(insn->x86_ea,
                                    op->data.val,
                                    size_lookup[info_ops[i].size]);
                            break;
                    }
                    break;
                case OPA_Imm:
                    if (op->type == YASM_INSN__OPERAND_IMM) {
                        imm = op->data.val;
                        im_len = size_lookup[info_ops[i].size];
                    } else
                        yasm_internal_error(N_("invalid operand conversion"));
                    break;
                case OPA_SImm:
                    if (op->type == YASM_INSN__OPERAND_IMM) {
                        imm = op->data.val;
                        im_len = size_lookup[info_ops[i].size];
                        im_sign = 1;
                    } else
                        yasm_internal_error(N_("invalid operand conversion"));
                    break;
                case OPA_Spare:
                    if (op->type == YASM_INSN__OPERAND_SEGREG)
                        spare = (unsigned char)(op->data.reg&7);
                    else if (op->type == YASM_INSN__OPERAND_REG) {
                        if (yasm_x86__set_rex_from_reg(&insn->rex, pdrex,
                                &spare, op->data.reg, mode_bits, X86_REX_R))
                            return;
                    } else
                        yasm_internal_error(N_("invalid operand conversion"));
                    break;
                case OPA_Op0Add:
                    if (op->type == YASM_INSN__OPERAND_REG) {
                        unsigned char opadd;
                        if (yasm_x86__set_rex_from_reg(&insn->rex, pdrex,
                                &opadd, op->data.reg, mode_bits, X86_REX_B))
                            return;
                        insn->opcode.opcode[0] += opadd;
                    } else
                        yasm_internal_error(N_("invalid operand conversion"));
                    break;
                case OPA_Op1Add:
                    if (op->type == YASM_INSN__OPERAND_REG) {
                        unsigned char opadd;
                        if (yasm_x86__set_rex_from_reg(&insn->rex, pdrex,
                                &opadd, op->data.reg, mode_bits, X86_REX_B))
                            return;
                        insn->opcode.opcode[1] += opadd;
                    } else
                        yasm_internal_error(N_("invalid operand conversion"));
                    break;
                case OPA_SpareEA:
                    if (op->type == YASM_INSN__OPERAND_REG) {
                        insn->x86_ea =
                            yasm_x86__ea_create_reg(insn->x86_ea,
                                (unsigned long)op->data.reg, &insn->rex,
                                pdrex, mode_bits);
                        if (!insn->x86_ea ||
                            yasm_x86__set_rex_from_reg(&insn->rex, pdrex,
                                &spare, op->data.reg, mode_bits, X86_REX_R)) {
                            if (insn->x86_ea)
                                yasm_xfree(insn->x86_ea);
                            yasm_xfree(insn);
                            return;
                        }
                    } else
                        yasm_internal_error(N_("invalid operand conversion"));
                    break;
                case OPA_AdSizeEA: {
                    const uintptr_t *regp = NULL;
                    /* Only implement this for OPT_MemrAX and OPT_MemEAX
                     * for now.
                     */
                    if (op->type != YASM_INSN__OPERAND_MEMORY ||
                        !(regp = yasm_expr_get_reg(&op->data.ea->disp.abs, 0)))
                        yasm_internal_error(N_("invalid operand conversion"));
                    /* 64-bit mode does not allow 16-bit addresses */
                    if (mode_bits == 64 && *regp == (X86_REG16 | 0))
                        yasm_error_set(YASM_ERROR_TYPE,
                            N_("16-bit addresses not supported in 64-bit mode"));
                    else if (*regp == (X86_REG16 | 0))
                        insn->common.addrsize = 16;
                    else if (*regp == (X86_REG32 | 0))
                        insn->common.addrsize = 32;
                    else if (mode_bits == 64 && *regp == (X86_REG64 | 0))
                        insn->common.addrsize = 64;
                    else
                        yasm_error_set(YASM_ERROR_TYPE,
                            N_("unsupported address size"));
                    yasm_x86__ea_destroy(op->data.ea);
                    break;
                }
                case OPA_DREX:
                    drex &= 0x0F;
                    drex |= (op->data.reg << 4) & 0xF0;
                    break;
                default:
                    yasm_internal_error(N_("unknown operand action"));
            }

            if (info_ops[i].size == OPS_BITS)
                insn->common.opersize = (unsigned char)mode_bits;

            switch (info_ops[i].post_action) {
                case OPAP_None:
                    break;
                case OPAP_SImm8:
                    /* Check operand strictness; if strict and non-8-bit,
                     * pre-emptively expand to full size.
                     * For unspecified size case, still optimize.
                     */
                    if (!(id_insn->force_strict || op->strict)
                        || op->size == 0)
                        insn->postop = X86_POSTOP_SIGNEXT_IMM8;
                    else if (op->size != 8) {
                        insn->opcode.opcode[0] =
                            insn->opcode.opcode[insn->opcode.len];
                        insn->opcode.len = 1;
                    }
                    break;
                case OPAP_ShortMov:
                    do_postop = OPAP_ShortMov;
                    break;
                case OPAP_A16:
                    insn->postop = X86_POSTOP_ADDRESS16;
                    break;
                case OPAP_SImm32Avail:
                    do_postop = OPAP_SImm32Avail;
                    break;
                default:
                    yasm_internal_error(
                        N_("unknown operand postponed action"));
            }
        }
    }

    if (insn->x86_ea) {
        yasm_x86__ea_init(insn->x86_ea, spare, drex,
                          (unsigned int)(info->drex_oc0 & NEED_DREX_MASK),
                          prev_bc);
        for (i=0; i<id_insn->insn.num_segregs; i++)
            yasm_ea_set_segreg(&insn->x86_ea->ea, id_insn->insn.segregs[i]);
    } else if (id_insn->insn.num_segregs > 0 && insn->special_prefix == 0) {
        if (id_insn->insn.num_segregs > 1)
            yasm_warn_set(YASM_WARN_GENERAL,
                          N_("multiple segment overrides, using leftmost"));
        insn->special_prefix = (unsigned char)
            (id_insn->insn.segregs[id_insn->insn.num_segregs-1]>>8);
    } else if (id_insn->insn.num_segregs > 0)
        yasm_internal_error(N_("unhandled segment prefix"));

    if (imm) {
        insn->imm = yasm_xmalloc(sizeof(yasm_value));
        if (yasm_value_finalize_expr(insn->imm, imm, prev_bc, 0))
            yasm_error_set(YASM_ERROR_TOO_COMPLEX,
                           N_("immediate expression too complex"));
        insn->imm->size = im_len;
        insn->imm->sign = im_sign;
    } else
        insn->imm = NULL;

    yasm_x86__bc_apply_prefixes((x86_common *)insn, &insn->rex,
                                insn->def_opersize_64,
                                id_insn->insn.num_prefixes,
                                id_insn->insn.prefixes);

    if (insn->postop == X86_POSTOP_ADDRESS16 && insn->common.addrsize) {
        yasm_warn_set(YASM_WARN_GENERAL, N_("address size override ignored"));
        insn->common.addrsize = 0;
    }

    /* Handle non-span-dependent post-ops here */
    switch (do_postop) {
        case OPAP_ShortMov:
            /* Long (modrm+sib) mov instructions in amd64 can be optimized into
             * short mov instructions if a 32-bit address override is applied in
             * 64-bit mode to an EA of just an offset (no registers) and the
             * target register is al/ax/eax/rax.
             *
             * We don't want to do this if we're in default rel mode.
             */
            if (!id_insn->default_rel &&
                insn->common.mode_bits == 64 &&
                insn->common.addrsize == 32 &&
                (!insn->x86_ea->ea.disp.abs ||
                 !yasm_expr__contains(insn->x86_ea->ea.disp.abs,
                                      YASM_EXPR_REG))) {
                yasm_x86__ea_set_disponly(insn->x86_ea);
                /* Make the short form permanent. */
                insn->opcode.opcode[0] = insn->opcode.opcode[1];
            }
            insn->opcode.opcode[1] = 0; /* avoid possible confusion */
            break;
        case OPAP_SImm32Avail:
            /* Used for 64-bit mov immediate, which can take a sign-extended
             * imm32 as well as imm64 values.  The imm32 form is put in the
             * second byte of the opcode and its ModRM byte is put in the third
             * byte of the opcode.
             */
            if (!insn->imm->abs ||
                (yasm_expr_get_intnum(&insn->imm->abs, 0) &&
                 yasm_intnum_check_size(
                    yasm_expr_get_intnum(&insn->imm->abs, 0), 32, 0, 1))) {
                /* Throwaway REX byte */
                unsigned char rex_temp = 0;

                /* Build ModRM EA - CAUTION: this depends on
                 * opcode 0 being a mov instruction!
                 */
                insn->x86_ea = yasm_x86__ea_create_reg(insn->x86_ea,
                    (unsigned long)insn->opcode.opcode[0]-0xB8, &rex_temp,
                    NULL, 64);

                /* Make the imm32s form permanent. */
                insn->opcode.opcode[0] = insn->opcode.opcode[1];
                insn->imm->size = 32;
            }
            insn->opcode.opcode[1] = 0; /* avoid possible confusion */
            break;
        default:
            break;
    }

    x86_id_insn_clear_operands(id_insn);

    /* Transform the bytecode */
    yasm_x86__bc_transform_insn(bc, insn);
}

/* Static parse data structure for instructions */
typedef struct insnprefix_parse_data {
    const char *name;

    /* instruction parse group - NULL if prefix */
    /*@null@*/ const x86_insn_info *group;

    /* For instruction, number of elements in group in lower 8 bits.
     * For prefix, prefix type shifted right by 8.
     */
    unsigned int num_info:8;

    /* For instruction, GAS suffix flags.
     * For prefix, prefix value.
     */
    unsigned int flags:8;

    /* Instruction modifier data. */
    unsigned int mod_data0:8;
    unsigned int mod_data1:8;
    unsigned int mod_data2:8;

    /* CPU flags */
    unsigned int cpu0:8;
    unsigned int cpu1:8;
    unsigned int cpu2:8;
} insnprefix_parse_data;

/* Pull in all parse data */
#include "x86insn_nasm.c"
#include "x86insn_gas.c"

static const char *
cpu_find_reverse(unsigned int cpu0, unsigned int cpu1, unsigned int cpu2)
{
    static char cpuname[200];
    wordptr cpu = BitVector_Create(128, TRUE);

    if (cpu0 != CPU_Any)
        BitVector_Bit_On(cpu, cpu0);
    if (cpu1 != CPU_Any)
        BitVector_Bit_On(cpu, cpu1);
    if (cpu2 != CPU_Any)
        BitVector_Bit_On(cpu, cpu2);

    cpuname[0] = '\0';

    if (BitVector_bit_test(cpu, CPU_Prot))
        strcat(cpuname, " Protected");
    if (BitVector_bit_test(cpu, CPU_Undoc))
        strcat(cpuname, " Undocumented");
    if (BitVector_bit_test(cpu, CPU_Obs))
        strcat(cpuname, " Obsolete");
    if (BitVector_bit_test(cpu, CPU_Priv))
        strcat(cpuname, " Privileged");

    if (BitVector_bit_test(cpu, CPU_FPU))
        strcat(cpuname, " FPU");
    if (BitVector_bit_test(cpu, CPU_MMX))
        strcat(cpuname, " MMX");
    if (BitVector_bit_test(cpu, CPU_SSE))
        strcat(cpuname, " SSE");
    if (BitVector_bit_test(cpu, CPU_SSE2))
        strcat(cpuname, " SSE2");
    if (BitVector_bit_test(cpu, CPU_SSE3))
        strcat(cpuname, " SSE3");
    if (BitVector_bit_test(cpu, CPU_3DNow))
        strcat(cpuname, " 3DNow");
    if (BitVector_bit_test(cpu, CPU_Cyrix))
        strcat(cpuname, " Cyrix");
    if (BitVector_bit_test(cpu, CPU_AMD))
        strcat(cpuname, " AMD");
    if (BitVector_bit_test(cpu, CPU_SMM))
        strcat(cpuname, " SMM");
    if (BitVector_bit_test(cpu, CPU_SVM))
        strcat(cpuname, " SVM");
    if (BitVector_bit_test(cpu, CPU_PadLock))
        strcat(cpuname, " PadLock");
    if (BitVector_bit_test(cpu, CPU_EM64T))
        strcat(cpuname, " EM64T");
    if (BitVector_bit_test(cpu, CPU_SSSE3))
        strcat(cpuname, " SSSE3");
    if (BitVector_bit_test(cpu, CPU_SSE41))
        strcat(cpuname, " SSE4.1");
    if (BitVector_bit_test(cpu, CPU_SSE42))
        strcat(cpuname, " SSE4.2");

    if (BitVector_bit_test(cpu, CPU_186))
        strcat(cpuname, " 186");
    if (BitVector_bit_test(cpu, CPU_286))
        strcat(cpuname, " 286");
    if (BitVector_bit_test(cpu, CPU_386))
        strcat(cpuname, " 386");
    if (BitVector_bit_test(cpu, CPU_486))
        strcat(cpuname, " 486");
    if (BitVector_bit_test(cpu, CPU_586))
        strcat(cpuname, " 586");
    if (BitVector_bit_test(cpu, CPU_686))
        strcat(cpuname, " 686");
    if (BitVector_bit_test(cpu, CPU_P3))
        strcat(cpuname, " P3");
    if (BitVector_bit_test(cpu, CPU_P4))
        strcat(cpuname, " P4");
    if (BitVector_bit_test(cpu, CPU_IA64))
        strcat(cpuname, " IA64");
    if (BitVector_bit_test(cpu, CPU_K6))
        strcat(cpuname, " K6");
    if (BitVector_bit_test(cpu, CPU_Athlon))
        strcat(cpuname, " Athlon");
    if (BitVector_bit_test(cpu, CPU_Hammer))
        strcat(cpuname, " Hammer");

    BitVector_Destroy(cpu);
    return cpuname;
}

yasm_arch_insnprefix
yasm_x86__parse_check_insnprefix(yasm_arch *arch, const char *id,
                                 size_t id_len, unsigned long line,
                                 yasm_bytecode **bc, uintptr_t *prefix)
{
    yasm_arch_x86 *arch_x86 = (yasm_arch_x86 *)arch;
    /*@null@*/ const insnprefix_parse_data *pdata;
    unsigned int cpu0, cpu1, cpu2;
    size_t i;
    static char lcaseid[16];

    *bc = (yasm_bytecode *)NULL;
    *prefix = 0;

    if (id_len > 15)
        return YASM_ARCH_NOTINSNPREFIX;
    for (i=0; i<id_len; i++)
        lcaseid[i] = tolower(id[i]);
    lcaseid[id_len] = '\0';

    switch (arch_x86->parser) {
        case X86_PARSER_NASM:
            pdata = insnprefix_nasm_find(lcaseid, id_len);
            break;
        case X86_PARSER_GAS:
            pdata = insnprefix_gas_find(lcaseid, id_len);
            break;
        default:
            pdata = NULL;
    }
    if (!pdata)
        return YASM_ARCH_NOTINSNPREFIX;

    cpu0 = pdata->cpu0;
    cpu1 = pdata->cpu1;
    cpu2 = pdata->cpu2;

    if (pdata->group) {
        x86_id_insn *id_insn;
        wordptr cpu_enabled = arch_x86->cpu_enables[arch_x86->active_cpu];

        if (arch_x86->mode_bits != 64 &&
            (cpu0 == CPU_64 || cpu1 == CPU_64 || cpu2 == CPU_64)) {
            yasm_warn_set(YASM_WARN_GENERAL,
                          N_("`%s' is an instruction in 64-bit mode"), id);
            return YASM_ARCH_NOTINSNPREFIX;
        }
        if (arch_x86->mode_bits == 64 &&
            (cpu0 == CPU_Not64 || cpu1 == CPU_Not64 || cpu2 == CPU_Not64)) {
            yasm_error_set(YASM_ERROR_GENERAL,
                           N_("`%s' invalid in 64-bit mode"), id);
            id_insn = yasm_xmalloc(sizeof(x86_id_insn));
            yasm_insn_initialize(&id_insn->insn);
            id_insn->group = not64_insn;
            id_insn->cpu_enabled = cpu_enabled;
            id_insn->mod_data[0] = 0;
            id_insn->mod_data[1] = 0;
            id_insn->mod_data[2] = 0;
            id_insn->num_info = NELEMS(not64_insn);
            id_insn->mode_bits = arch_x86->mode_bits;
            id_insn->suffix = 0;
            id_insn->parser = arch_x86->parser;
            id_insn->force_strict = arch_x86->force_strict != 0;
            id_insn->default_rel = arch_x86->default_rel != 0;
            *bc = yasm_bc_create_common(&x86_id_insn_callback, id_insn, line);
            return YASM_ARCH_INSN;
        }

        if (cpu0 == CPU_64 || cpu0 == CPU_Not64)
            cpu0 = CPU_Any;
        if (cpu1 == CPU_64 || cpu1 == CPU_Not64)
            cpu1 = CPU_Any;
        if (cpu2 == CPU_64 || cpu2 == CPU_Not64)
            cpu2 = CPU_Any;
        if (!BitVector_bit_test(cpu_enabled, cpu0) ||
            !BitVector_bit_test(cpu_enabled, cpu1) ||
            !BitVector_bit_test(cpu_enabled, cpu2)) {
            yasm_warn_set(YASM_WARN_GENERAL,
                          N_("`%s' is an instruction in CPU%s"), id,
                          cpu_find_reverse(cpu0, cpu1, cpu2));
            return YASM_ARCH_NOTINSNPREFIX;
        }

        id_insn = yasm_xmalloc(sizeof(x86_id_insn));
        yasm_insn_initialize(&id_insn->insn);
        id_insn->group = pdata->group;
        id_insn->cpu_enabled = cpu_enabled;
        id_insn->mod_data[0] = pdata->mod_data0;
        id_insn->mod_data[1] = pdata->mod_data1;
        id_insn->mod_data[2] = pdata->mod_data2;
        id_insn->num_info = pdata->num_info;
        id_insn->mode_bits = arch_x86->mode_bits;
        id_insn->suffix = pdata->flags;
        id_insn->parser = arch_x86->parser;
        id_insn->force_strict = arch_x86->force_strict != 0;
        id_insn->default_rel = arch_x86->default_rel != 0;
        *bc = yasm_bc_create_common(&x86_id_insn_callback, id_insn, line);
        return YASM_ARCH_INSN;
    } else {
        unsigned long type = pdata->num_info<<8;
        unsigned long value = pdata->flags;

        if (arch_x86->mode_bits == 64 && type == X86_OPERSIZE && value == 32) {
            yasm_error_set(YASM_ERROR_GENERAL,
                N_("Cannot override data size to 32 bits in 64-bit mode"));
            return YASM_ARCH_NOTINSNPREFIX;
        }

        if (arch_x86->mode_bits == 64 && type == X86_ADDRSIZE && value == 16) {
            yasm_error_set(YASM_ERROR_GENERAL,
                N_("Cannot override address size to 16 bits in 64-bit mode"));
            return YASM_ARCH_NOTINSNPREFIX;
        }

        if (arch_x86->mode_bits != 64 &&
            (cpu0 == CPU_64 || cpu1 == CPU_64 || cpu2 == CPU_64)) {
            yasm_warn_set(YASM_WARN_GENERAL,
                          N_("`%s' is a prefix in 64-bit mode"), id);
            return YASM_ARCH_NOTINSNPREFIX;
        }
        *prefix = type|value;
        return YASM_ARCH_PREFIX;
    }
}

static void
x86_id_insn_destroy(void *contents)
{
    x86_id_insn *id_insn = (x86_id_insn *)contents;
    yasm_insn_delete(&id_insn->insn, yasm_x86__ea_destroy);
    yasm_xfree(contents);
}

static void
x86_id_insn_print(const void *contents, FILE *f, int indent_level)
{
    const x86_id_insn *id_insn = (const x86_id_insn *)contents;
    yasm_insn_print(&id_insn->insn, f, indent_level);
    /*TODO*/
}

/*@only@*/ yasm_bytecode *
yasm_x86__create_empty_insn(yasm_arch *arch, unsigned long line)
{
    yasm_arch_x86 *arch_x86 = (yasm_arch_x86 *)arch;
    x86_id_insn *id_insn = yasm_xmalloc(sizeof(x86_id_insn));

    yasm_insn_initialize(&id_insn->insn);
    id_insn->group = empty_insn;
    id_insn->cpu_enabled = arch_x86->cpu_enables[arch_x86->active_cpu];
    id_insn->mod_data[0] = 0;
    id_insn->mod_data[1] = 0;
    id_insn->mod_data[2] = 0;
    id_insn->num_info = NELEMS(empty_insn);
    id_insn->mode_bits = arch_x86->mode_bits;
    id_insn->suffix = 0;
    id_insn->parser = arch_x86->parser;
    id_insn->force_strict = arch_x86->force_strict != 0;
    id_insn->default_rel = arch_x86->default_rel != 0;

    return yasm_bc_create_common(&x86_id_insn_callback, id_insn, line);
}

