/*
 * x86 bytecode utility functions
 *
 *  Copyright (C) 2001-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 <util.h>

#include <libyasm.h>

#include "x86arch.h"


/* Bytecode callback function prototypes */

static void x86_bc_insn_destroy(void *contents);
static void x86_bc_insn_print(const void *contents, FILE *f,
                              int indent_level);
static int x86_bc_insn_calc_len(yasm_bytecode *bc,
                                yasm_bc_add_span_func add_span,
                                void *add_span_data);
static int x86_bc_insn_expand(yasm_bytecode *bc, int span, long old_val,
                              long new_val, /*@out@*/ long *neg_thres,
                              /*@out@*/ long *pos_thres);
static int x86_bc_insn_tobytes(yasm_bytecode *bc, unsigned char **bufp,
                               unsigned char *bufstart,
                               void *d, yasm_output_value_func output_value,
                               /*@null@*/ yasm_output_reloc_func output_reloc);

static void x86_bc_jmp_destroy(void *contents);
static void x86_bc_jmp_print(const void *contents, FILE *f, int indent_level);
static int x86_bc_jmp_calc_len(yasm_bytecode *bc,
                               yasm_bc_add_span_func add_span,
                               void *add_span_data);
static int x86_bc_jmp_expand(yasm_bytecode *bc, int span, long old_val,
                             long new_val, /*@out@*/ long *neg_thres,
                             /*@out@*/ long *pos_thres);
static int x86_bc_jmp_tobytes(yasm_bytecode *bc, unsigned char **bufp,
                              unsigned char *bufstart,
                              void *d, yasm_output_value_func output_value,
                              /*@null@*/ yasm_output_reloc_func output_reloc);

static void x86_bc_jmpfar_destroy(void *contents);
static void x86_bc_jmpfar_print(const void *contents, FILE *f,
                                int indent_level);
static int x86_bc_jmpfar_calc_len(yasm_bytecode *bc,
                                  yasm_bc_add_span_func add_span,
                                  void *add_span_data);
static int x86_bc_jmpfar_tobytes
    (yasm_bytecode *bc, unsigned char **bufp, unsigned char *bufstart, void *d,
     yasm_output_value_func output_value,
     /*@null@*/ yasm_output_reloc_func output_reloc);

/* Bytecode callback structures */

static const yasm_bytecode_callback x86_bc_callback_insn = {
    x86_bc_insn_destroy,
    x86_bc_insn_print,
    yasm_bc_finalize_common,
    NULL,
    x86_bc_insn_calc_len,
    x86_bc_insn_expand,
    x86_bc_insn_tobytes,
    0
};

static const yasm_bytecode_callback x86_bc_callback_jmp = {
    x86_bc_jmp_destroy,
    x86_bc_jmp_print,
    yasm_bc_finalize_common,
    NULL,
    x86_bc_jmp_calc_len,
    x86_bc_jmp_expand,
    x86_bc_jmp_tobytes,
    0
};

static const yasm_bytecode_callback x86_bc_callback_jmpfar = {
    x86_bc_jmpfar_destroy,
    x86_bc_jmpfar_print,
    yasm_bc_finalize_common,
    NULL,
    x86_bc_jmpfar_calc_len,
    yasm_bc_expand_common,
    x86_bc_jmpfar_tobytes,
    0
};

int
yasm_x86__set_rex_from_reg(unsigned char *rex, unsigned char *low3,
                           uintptr_t reg, unsigned int bits,
                           x86_rex_bit_pos rexbit)
{
    *low3 = (unsigned char)(reg&7);

    if (bits == 64) {
        x86_expritem_reg_size size = (x86_expritem_reg_size)(reg & ~0xFUL);

        if (size == X86_REG8X || (reg & 0xF) >= 8) {
            /* Check to make sure we can set it */
            if (*rex == 0xff) {
                yasm_error_set(YASM_ERROR_TYPE,
                    N_("cannot use A/B/C/DH with instruction needing REX"));
                return 1;
            }
            *rex |= 0x40 | (((reg & 8) >> 3) << rexbit);
        } else if (size == X86_REG8 && (reg & 7) >= 4) {
            /* AH/BH/CH/DH, so no REX allowed */
            if (*rex != 0 && *rex != 0xff) {
                yasm_error_set(YASM_ERROR_TYPE,
                    N_("cannot use A/B/C/DH with instruction needing REX"));
                return 1;
            }
            *rex = 0xff;    /* Flag so we can NEVER set it (see above) */
        }
    }

    return 0;
}

void
yasm_x86__bc_transform_insn(yasm_bytecode *bc, x86_insn *insn)
{
    yasm_bc_transform(bc, &x86_bc_callback_insn, insn);
}

void
yasm_x86__bc_transform_jmp(yasm_bytecode *bc, x86_jmp *jmp)
{
    yasm_bc_transform(bc, &x86_bc_callback_jmp, jmp);
}

void
yasm_x86__bc_transform_jmpfar(yasm_bytecode *bc, x86_jmpfar *jmpfar)
{
    yasm_bc_transform(bc, &x86_bc_callback_jmpfar, jmpfar);
}

void
yasm_x86__ea_init(x86_effaddr *x86_ea, unsigned int spare,
                  yasm_bytecode *precbc)
{
    if (yasm_value_finalize(&x86_ea->ea.disp, precbc))
        yasm_error_set(YASM_ERROR_TOO_COMPLEX,
                       N_("effective address too complex"));
    x86_ea->modrm &= 0xC7;                  /* zero spare/reg bits */
    x86_ea->modrm |= (spare << 3) & 0x38;   /* plug in provided bits */
}

void
yasm_x86__ea_set_disponly(x86_effaddr *x86_ea)
{
    x86_ea->valid_modrm = 0;
    x86_ea->need_modrm = 0;
    x86_ea->valid_sib = 0;
    x86_ea->need_sib = 0;
}

static x86_effaddr *
ea_create(void)
{
    x86_effaddr *x86_ea = yasm_xmalloc(sizeof(x86_effaddr));

    yasm_value_initialize(&x86_ea->ea.disp, NULL, 0);
    x86_ea->ea.need_nonzero_len = 0;
    x86_ea->ea.need_disp = 0;
    x86_ea->ea.nosplit = 0;
    x86_ea->ea.strong = 0;
    x86_ea->ea.segreg = 0;
    x86_ea->ea.pc_rel = 0;
    x86_ea->ea.not_pc_rel = 0;
    x86_ea->ea.data_len = 0;
    x86_ea->vsib_mode = 0;
    x86_ea->modrm = 0;
    x86_ea->valid_modrm = 0;
    x86_ea->need_modrm = 0;
    x86_ea->sib = 0;
    x86_ea->valid_sib = 0;
    x86_ea->need_sib = 0;

    return x86_ea;
}

x86_effaddr *
yasm_x86__ea_create_reg(x86_effaddr *x86_ea, unsigned long reg,
                        unsigned char *rex, unsigned int bits)
{
    unsigned char rm;

    if (yasm_x86__set_rex_from_reg(rex, &rm, reg, bits, X86_REX_B))
        return NULL;

    if (!x86_ea)
        x86_ea = ea_create();
    x86_ea->modrm = 0xC0 | rm;  /* Mod=11, R/M=Reg, Reg=0 */
    x86_ea->valid_modrm = 1;
    x86_ea->need_modrm = 1;

    return x86_ea;
}

yasm_effaddr *
yasm_x86__ea_create_expr(yasm_arch *arch, yasm_expr *e)
{
    yasm_arch_x86 *arch_x86 = (yasm_arch_x86 *)arch;
    x86_effaddr *x86_ea;

    x86_ea = ea_create();

    if (arch_x86->parser == X86_PARSER_GAS) {
        /* Need to change foo+rip into foo wrt rip (even in .intel_syntax mode).
         * Note this assumes a particular ordering coming from the parser
         * to work (it's not very smart)!
         */
        if (e->op == YASM_EXPR_ADD && e->terms[0].type == YASM_EXPR_REG
            && e->terms[0].data.reg == X86_RIP) {
            /* replace register with 0 */
            e->terms[0].type = YASM_EXPR_INT;
            e->terms[0].data.intn = yasm_intnum_create_uint(0);
            /* build new wrt expression */
            e = yasm_expr_create(YASM_EXPR_WRT, yasm_expr_expr(e),
                                 yasm_expr_reg(X86_RIP), e->line);
        }
    }
    yasm_value_initialize(&x86_ea->ea.disp, e, 0);
    x86_ea->ea.need_disp = 1;
    x86_ea->need_modrm = 1;
    /* We won't know whether we need an SIB until we know more about expr and
     * the BITS/address override setting.
     */
    x86_ea->need_sib = 0xff;

    x86_ea->ea.data_len = 0;

    return (yasm_effaddr *)x86_ea;
}

/*@-compmempass@*/
x86_effaddr *
yasm_x86__ea_create_imm(x86_effaddr *x86_ea, yasm_expr *imm,
                        unsigned int im_len)
{
    if (!x86_ea)
        x86_ea = ea_create();
    yasm_value_initialize(&x86_ea->ea.disp, imm, im_len);
    x86_ea->ea.need_disp = 1;

    return x86_ea;
}
/*@=compmempass@*/

void
yasm_x86__bc_apply_prefixes(x86_common *common, unsigned char *rex,
                            unsigned int def_opersize_64,
                            unsigned int num_prefixes, uintptr_t *prefixes)
{
    unsigned int i;
    int first = 1;

    for (i=0; i<num_prefixes; i++) {
        switch ((x86_parse_insn_prefix)(prefixes[i] & 0xff00)) {
            /*To be accurate, we should enforce that TSX hints come only with a
            predefined set of instructions, and in most cases only with F0
            prefix. Otherwise they will have completely different semantics.
            But F0 prefix can come only with a predefined set of instructions
            too. And if it comes with other instructions, CPU will #UD.
            Hence, F0-applicability should be enforced too. But it's not
            currently. Maybe it is the decision made, that user should know
            himself what he is doing with LOCK prefix. In this case, we should
            not enforce TSX hints applicability too. And let user take care of
            correct usage of TSX hints.
            That is what we are going to do.*/
            case X86_ACQREL:
                if (common->acqrel_pre != 0)
                    yasm_warn_set(YASM_WARN_GENERAL,
                        N_("multiple XACQUIRE/XRELEASE prefixes, "
                        "using leftmost"));
                common->acqrel_pre = (unsigned char)prefixes[i] & 0xff;
                break;
            case X86_LOCKREP:
                if (common->lockrep_pre != 0)
                    yasm_warn_set(YASM_WARN_GENERAL,
                        N_("multiple LOCK or REP prefixes, using leftmost"));
                common->lockrep_pre = (unsigned char)prefixes[i] & 0xff;
                break;
            case X86_ADDRSIZE:
                common->addrsize = (unsigned char)prefixes[i] & 0xff;
                break;
            case X86_OPERSIZE:
                common->opersize = (unsigned char)prefixes[i] & 0xff;
                if (common->mode_bits == 64 && common->opersize == 64 &&
                    def_opersize_64 != 64) {
                    if (!rex)
                        yasm_warn_set(YASM_WARN_GENERAL,
                                      N_("ignoring REX prefix on jump"));
                    else if (*rex == 0xff)
                        yasm_warn_set(YASM_WARN_GENERAL,
                            N_("REX prefix not allowed on this instruction, ignoring"));
                    else
                        *rex = 0x48;
                }
                break;
            case X86_SEGREG:
                /* This is a hack.. we should really be putting this in the
                 * the effective address!
                 */
                common->lockrep_pre = (unsigned char)prefixes[i] & 0xff;
                break;
            case X86_REX:
                if (!rex)
                    yasm_warn_set(YASM_WARN_GENERAL,
                                  N_("ignoring REX prefix on jump"));
                else if (*rex == 0xff)
                    yasm_warn_set(YASM_WARN_GENERAL,
                        N_("REX prefix not allowed on this instruction, ignoring"));
                else {
                    if (*rex != 0) {
                        if (first)
                            yasm_warn_set(YASM_WARN_GENERAL,
                                N_("overriding generated REX prefix"));
                        else
                            yasm_warn_set(YASM_WARN_GENERAL,
                                N_("multiple REX prefixes, using leftmost"));
                    }
                    /* Here we assume that we can't get this prefix in non
                     * 64 bit mode due to checks in parse_check_prefix().
                     */
                    common->mode_bits = 64;
                    *rex = (unsigned char)prefixes[i] & 0xff;
                }
                first = 0;
                break;
        }
    }
}

static void
x86_bc_insn_destroy(void *contents)
{
    x86_insn *insn = (x86_insn *)contents;
    if (insn->x86_ea)
        yasm_x86__ea_destroy((yasm_effaddr *)insn->x86_ea);
    if (insn->imm) {
        yasm_value_delete(insn->imm);
        yasm_xfree(insn->imm);
    }
    yasm_xfree(contents);
}

static void
x86_bc_jmp_destroy(void *contents)
{
    x86_jmp *jmp = (x86_jmp *)contents;
    yasm_value_delete(&jmp->target);
    yasm_xfree(contents);
}

static void
x86_bc_jmpfar_destroy(void *contents)
{
    x86_jmpfar *jmpfar = (x86_jmpfar *)contents;
    yasm_value_delete(&jmpfar->segment);
    yasm_value_delete(&jmpfar->offset);
    yasm_xfree(contents);
}

void
yasm_x86__ea_destroy(yasm_effaddr *ea)
{
    yasm_value_delete(&ea->disp);
    yasm_xfree(ea);
}

void
yasm_x86__ea_print(const yasm_effaddr *ea, FILE *f, int indent_level)
{
    const x86_effaddr *x86_ea = (const x86_effaddr *)ea;
    fprintf(f, "%*sDisp:\n", indent_level, "");
    yasm_value_print(&ea->disp, f, indent_level+1);
    fprintf(f, "%*sNoSplit=%u\n", indent_level, "", (unsigned int)ea->nosplit);
    fprintf(f, "%*sSegmentOv=%02x\n", indent_level, "",
            (unsigned int)x86_ea->ea.segreg);
    fprintf(f, "%*sVSIBMode=%u\n", indent_level, "",
            (unsigned int)x86_ea->vsib_mode);
    fprintf(f, "%*sModRM=%03o ValidRM=%u NeedRM=%u\n", indent_level, "",
            (unsigned int)x86_ea->modrm, (unsigned int)x86_ea->valid_modrm,
            (unsigned int)x86_ea->need_modrm);
    fprintf(f, "%*sSIB=%03o ValidSIB=%u NeedSIB=%u\n", indent_level, "",
            (unsigned int)x86_ea->sib, (unsigned int)x86_ea->valid_sib,
            (unsigned int)x86_ea->need_sib);
}

static void
x86_common_print(const x86_common *common, FILE *f, int indent_level)
{
    fprintf(f, "%*sAddrSize=%u OperSize=%u LockRepPre=%02x "
        "ACQREL_Pre=%02x BITS=%u\n",
            indent_level, "",
            (unsigned int)common->addrsize,
            (unsigned int)common->opersize,
            (unsigned int)common->lockrep_pre,
            (unsigned int)common->acqrel_pre,
            (unsigned int)common->mode_bits);
}

static void
x86_opcode_print(const x86_opcode *opcode, FILE *f, int indent_level)
{
    fprintf(f, "%*sOpcode: %02x %02x %02x OpLen=%u\n", indent_level, "",
            (unsigned int)opcode->opcode[0],
            (unsigned int)opcode->opcode[1],
            (unsigned int)opcode->opcode[2],
            (unsigned int)opcode->len);
}

static void
x86_bc_insn_print(const void *contents, FILE *f, int indent_level)
{
    const x86_insn *insn = (const x86_insn *)contents;

    fprintf(f, "%*s_Instruction_\n", indent_level, "");
    fprintf(f, "%*sEffective Address:", indent_level, "");
    if (insn->x86_ea) {
        fprintf(f, "\n");
        yasm_x86__ea_print((yasm_effaddr *)insn->x86_ea, f, indent_level+1);
    } else
        fprintf(f, " (nil)\n");
    fprintf(f, "%*sImmediate Value:", indent_level, "");
    if (!insn->imm)
        fprintf(f, " (nil)\n");
    else {
        indent_level++;
        fprintf(f, "\n");
        yasm_value_print(insn->imm, f, indent_level);
        indent_level--;
    }
    x86_opcode_print(&insn->opcode, f, indent_level);
    x86_common_print(&insn->common, f, indent_level);
    fprintf(f, "%*sSpPre=%02x REX=%03o PostOp=%u\n", indent_level, "",
            (unsigned int)insn->special_prefix,
            (unsigned int)insn->rex,
            (unsigned int)insn->postop);
}

static void
x86_bc_jmp_print(const void *contents, FILE *f, int indent_level)
{
    const x86_jmp *jmp = (const x86_jmp *)contents;

    fprintf(f, "%*s_Jump_\n", indent_level, "");
    fprintf(f, "%*sTarget:\n", indent_level, "");
    yasm_value_print(&jmp->target, f, indent_level+1);
    /* FIXME
    fprintf(f, "%*sOrigin=\n", indent_level, "");
    yasm_symrec_print(jmp->origin, f, indent_level+1);
    */
    fprintf(f, "\n%*sShort Form:\n", indent_level, "");
    if (jmp->shortop.len == 0)
        fprintf(f, "%*sNone\n", indent_level+1, "");
    else
        x86_opcode_print(&jmp->shortop, f, indent_level+1);
    fprintf(f, "%*sNear Form:\n", indent_level, "");
    if (jmp->nearop.len == 0)
        fprintf(f, "%*sNone\n", indent_level+1, "");
    else
        x86_opcode_print(&jmp->nearop, f, indent_level+1);
    fprintf(f, "%*sOpSel=", indent_level, "");
    switch (jmp->op_sel) {
        case JMP_NONE:
            fprintf(f, "None");
            break;
        case JMP_SHORT:
            fprintf(f, "Short");
            break;
        case JMP_NEAR:
            fprintf(f, "Near");
            break;
        case JMP_SHORT_FORCED:
            fprintf(f, "Forced Short");
            break;
        case JMP_NEAR_FORCED:
            fprintf(f, "Forced Near");
            break;
        default:
            fprintf(f, "UNKNOWN!!");
            break;
    }
    x86_common_print(&jmp->common, f, indent_level);
}

static void
x86_bc_jmpfar_print(const void *contents, FILE *f, int indent_level)
{
    const x86_jmpfar *jmpfar = (const x86_jmpfar *)contents;

    fprintf(f, "%*s_Far_Jump_\n", indent_level, "");
    fprintf(f, "%*sSegment:\n", indent_level, "");
    yasm_value_print(&jmpfar->segment, f, indent_level+1);
    fprintf(f, "%*sOffset:\n", indent_level, "");
    yasm_value_print(&jmpfar->offset, f, indent_level+1);
    x86_opcode_print(&jmpfar->opcode, f, indent_level);
    x86_common_print(&jmpfar->common, f, indent_level);
}

static unsigned int
x86_common_calc_len(const x86_common *common)
{
    unsigned int len = 0;

    if (common->addrsize != 0 && common->addrsize != common->mode_bits)
        len++;
    if (common->opersize != 0 &&
        ((common->mode_bits != 64 && common->opersize != common->mode_bits) ||
         (common->mode_bits == 64 && common->opersize == 16)))
        len++;
    if (common->lockrep_pre != 0)
        len++;
    if (common->acqrel_pre != 0)
        len++;


    return len;
}

static int
x86_bc_insn_calc_len(yasm_bytecode *bc, yasm_bc_add_span_func add_span,
                     void *add_span_data)
{
    x86_insn *insn = (x86_insn *)bc->contents;
    x86_effaddr *x86_ea = insn->x86_ea;
    yasm_value *imm = insn->imm;

    if (x86_ea) {
        /* Check validity of effective address and calc R/M bits of
         * Mod/RM byte and SIB byte.  We won't know the Mod field
         * of the Mod/RM byte until we know more about the
         * displacement.
         */
        if (yasm_x86__expr_checkea(x86_ea, &insn->common.addrsize,
                insn->common.mode_bits, insn->postop == X86_POSTOP_ADDRESS16,
                &insn->rex, bc))
            /* failed, don't bother checking rest of insn */
            return -1;

        if (x86_ea->ea.disp.size == 0 && x86_ea->ea.need_nonzero_len) {
            /* Handle unknown case, default to byte-sized and set as
             * critical expression.
             */
            x86_ea->ea.disp.size = 8;
            add_span(add_span_data, bc, 1, &x86_ea->ea.disp, -128, 127);
        }
        bc->len += x86_ea->ea.disp.size/8;

        /* Handle address16 postop case */
        if (insn->postop == X86_POSTOP_ADDRESS16)
            insn->common.addrsize = 0;

        /* Compute length of ea and add to total */
        bc->len += x86_ea->need_modrm + (x86_ea->need_sib ? 1:0);
        bc->len += (x86_ea->ea.segreg != 0) ? 1 : 0;
    }

    if (imm) {
        unsigned int immlen = imm->size;

        /* TODO: check imm->len vs. sized len from expr? */

        /* Handle signext_imm8 postop special-casing */
        if (insn->postop == X86_POSTOP_SIGNEXT_IMM8) {
            /*@null@*/ /*@only@*/ yasm_intnum *num;
            num = yasm_value_get_intnum(imm, NULL, 0);

            if (!num) {
                /* Unknown; default to byte form and set as critical
                 * expression.
                 */
                immlen = 8;
                add_span(add_span_data, bc, 2, imm, -128, 127);
            } else {
                if (yasm_intnum_in_range(num, -128, 127)) {
                    /* We can use the sign-extended byte form: shorten
                     * the immediate length to 1 and make the byte form
                     * permanent.
                     */
                    imm->size = 8;
                    imm->sign = 1;
                    immlen = 8;
                } else {
                    /* We can't.  Copy over the word-sized opcode. */
                    insn->opcode.opcode[0] =
                        insn->opcode.opcode[insn->opcode.len];
                    insn->opcode.len = 1;
                }
                insn->postop = X86_POSTOP_NONE;
                yasm_intnum_destroy(num);
            }
        }

        bc->len += immlen/8;
    }

    /* VEX and XOP prefixes never have REX (it's embedded in the opcode).
     * For VEX, we can come into this function with the three byte form,
     * so we need to see if we can optimize to the two byte form.
     * We can't do it earlier, as we don't know all of the REX byte until now.
     */
    if (insn->special_prefix == 0xC4) {
        /* See if we can shorten the VEX prefix to its two byte form.
         * In order to do this, REX.X, REX.B, and REX.W/VEX.W must all be 0,
         * and the VEX mmmmm field must be 1.
         */
        if ((insn->opcode.opcode[0] & 0x1F) == 1 &&
            (insn->opcode.opcode[1] & 0x80) == 0 &&
            (insn->rex == 0xff || (insn->rex & 0x0B) == 0)) {
            insn->opcode.opcode[0] = insn->opcode.opcode[1];
            insn->opcode.opcode[1] = insn->opcode.opcode[2];
            insn->opcode.opcode[2] = 0; /* sanity */
            insn->opcode.len = 2;
            insn->special_prefix = 0xC5;    /* mark as two-byte VEX */
        }
    } else if (insn->rex != 0xff && insn->rex != 0 &&
               insn->special_prefix != 0xC5 && insn->special_prefix != 0x8F)
        bc->len++;

    bc->len += insn->opcode.len;
    bc->len += x86_common_calc_len(&insn->common);
    bc->len += (insn->special_prefix != 0) ? 1:0;
    return 0;
}

static int
x86_bc_insn_expand(yasm_bytecode *bc, int span, long old_val, long new_val,
                   /*@out@*/ long *neg_thres, /*@out@*/ long *pos_thres)
{
    x86_insn *insn = (x86_insn *)bc->contents;
    x86_effaddr *x86_ea = insn->x86_ea;
    yasm_effaddr *ea = &x86_ea->ea;
    yasm_value *imm = insn->imm;

    if (ea && span == 1) {
        /* Change displacement length into word-sized */
        if (ea->disp.size == 8) {
            ea->disp.size = (insn->common.addrsize == 16) ? 16 : 32;
            x86_ea->modrm &= ~0300;
            x86_ea->modrm |= 0200;
            bc->len--;
            bc->len += ea->disp.size/8;
        }
    }

    if (imm && span == 2) {
        if (insn->postop == X86_POSTOP_SIGNEXT_IMM8) {
            /* Update bc->len for new opcode and immediate size */
            bc->len -= insn->opcode.len;
            bc->len += imm->size/8;

            /* Change to the word-sized opcode */
            insn->opcode.opcode[0] = insn->opcode.opcode[insn->opcode.len];
            insn->opcode.len = 1;
            insn->postop = X86_POSTOP_NONE;
        }
    }

    return 0;
}

static int
x86_bc_jmp_calc_len(yasm_bytecode *bc, yasm_bc_add_span_func add_span,
                    void *add_span_data)
{
    x86_jmp *jmp = (x86_jmp *)bc->contents;
    yasm_bytecode *target_prevbc;
    unsigned char opersize;

    /* As opersize may be 0, figure out its "real" value. */
    opersize = (jmp->common.opersize == 0) ?
        jmp->common.mode_bits : jmp->common.opersize;

    bc->len += x86_common_calc_len(&jmp->common);

    if (jmp->op_sel == JMP_NEAR_FORCED || jmp->shortop.len == 0) {
        if (jmp->nearop.len == 0) {
            yasm_error_set(YASM_ERROR_TYPE, N_("near jump does not exist"));
            return -1;
        }

        /* Near jump, no spans needed */
        if (jmp->shortop.len == 0)
            jmp->op_sel = JMP_NEAR;
        bc->len += jmp->nearop.len;
        bc->len += (opersize == 16) ? 2 : 4;
        return 0;
    }

    if (jmp->op_sel == JMP_SHORT_FORCED || jmp->nearop.len == 0) {
        if (jmp->shortop.len == 0) {
            yasm_error_set(YASM_ERROR_TYPE, N_("short jump does not exist"));
            return -1;
        }

        /* We want to be sure to error if we exceed short length, so
         * put it in as a dependent expression (falling through).
         */
    }

    if (jmp->target.rel
        && (!yasm_symrec_get_label(jmp->target.rel, &target_prevbc)
            || target_prevbc->section != bc->section)) {
        /* External or out of segment, so we can't check distance.
         * Allowing short jumps depends on the objfmt supporting
         * 8-bit relocs.  While most don't, some might, so allow it here.
         * Otherwise default to word-sized.
         * The objfmt will error if not supported.
         */
        if (jmp->op_sel == JMP_SHORT_FORCED || jmp->nearop.len == 0) {
            if (jmp->op_sel == JMP_NONE)
                jmp->op_sel = JMP_SHORT;
            bc->len += jmp->shortop.len + 1;
        } else {
            jmp->op_sel = JMP_NEAR;
            bc->len += jmp->nearop.len;
            bc->len += (opersize == 16) ? 2 : 4;
        }
        return 0;
    }

    /* Default to short jump and generate span */
    if (jmp->op_sel == JMP_NONE)
        jmp->op_sel = JMP_SHORT;
    bc->len += jmp->shortop.len + 1;
    add_span(add_span_data, bc, 1, &jmp->target, -128+(long)bc->len,
             127+(long)bc->len);
    return 0;
}

static int
x86_bc_jmp_expand(yasm_bytecode *bc, int span, long old_val, long new_val,
                  /*@out@*/ long *neg_thres, /*@out@*/ long *pos_thres)
{
    x86_jmp *jmp = (x86_jmp *)bc->contents;
    unsigned char opersize;

    if (span != 1)
        yasm_internal_error(N_("unrecognized span id"));

    /* As opersize may be 0, figure out its "real" value. */
    opersize = (jmp->common.opersize == 0) ?
        jmp->common.mode_bits : jmp->common.opersize;

    if (jmp->op_sel == JMP_SHORT_FORCED || jmp->nearop.len == 0) {
        yasm_error_set(YASM_ERROR_VALUE, N_("short jump out of range"));
        return -1;
    }

    if (jmp->op_sel == JMP_NEAR)
        yasm_internal_error(N_("trying to expand an already-near jump"));

    /* Upgrade to a near jump */
    jmp->op_sel = JMP_NEAR;
    bc->len -= jmp->shortop.len + 1;
    bc->len += jmp->nearop.len;
    bc->len += (opersize == 16) ? 2 : 4;

    return 0;
}

static int
x86_bc_jmpfar_calc_len(yasm_bytecode *bc, yasm_bc_add_span_func add_span,
                       void *add_span_data)
{
    x86_jmpfar *jmpfar = (x86_jmpfar *)bc->contents;
    unsigned char opersize;
   
    opersize = (jmpfar->common.opersize == 0) ?
        jmpfar->common.mode_bits : jmpfar->common.opersize;

    bc->len += jmpfar->opcode.len;
    bc->len += 2;       /* segment */
    bc->len += (opersize == 16) ? 2 : 4;
    bc->len += x86_common_calc_len(&jmpfar->common);

    return 0;
}

static void
x86_common_tobytes(const x86_common *common, unsigned char **bufp,
                   unsigned int segreg)
{
    if (segreg != 0)
        YASM_WRITE_8(*bufp, (unsigned char)segreg);
    if (common->addrsize != 0 && common->addrsize != common->mode_bits)
        YASM_WRITE_8(*bufp, 0x67);
    if (common->opersize != 0 &&
        ((common->mode_bits != 64 && common->opersize != common->mode_bits) ||
         (common->mode_bits == 64 && common->opersize == 16)))
        YASM_WRITE_8(*bufp, 0x66);
    /*TSX hints come before lock prefix*/
    if (common->acqrel_pre != 0)
        YASM_WRITE_8(*bufp, common->acqrel_pre);
    if (common->lockrep_pre != 0)
        YASM_WRITE_8(*bufp, common->lockrep_pre);
}

static void
x86_opcode_tobytes(const x86_opcode *opcode, unsigned char **bufp)
{
    unsigned int i;
    for (i=0; i<opcode->len; i++)
        YASM_WRITE_8(*bufp, opcode->opcode[i]);
}

static int
x86_bc_insn_tobytes(yasm_bytecode *bc, unsigned char **bufp,
                    unsigned char *bufstart, void *d,
                    yasm_output_value_func output_value,
                    /*@unused@*/ yasm_output_reloc_func output_reloc)
{
    x86_insn *insn = (x86_insn *)bc->contents;
    /*@null@*/ x86_effaddr *x86_ea = (x86_effaddr *)insn->x86_ea;
    yasm_value *imm = insn->imm;

    /* Prefixes */
    x86_common_tobytes(&insn->common, bufp,
                       x86_ea ? (unsigned int)(x86_ea->ea.segreg>>8) : 0);
    if (insn->special_prefix != 0)
        YASM_WRITE_8(*bufp, insn->special_prefix);
    if (insn->special_prefix == 0xC4 || insn->special_prefix == 0x8F) {
        /* 3-byte VEX/XOP; merge in 1s complement of REX.R, REX.X, REX.B */
        insn->opcode.opcode[0] &= 0x1F;
        if (insn->rex != 0xff)
            insn->opcode.opcode[0] |= ((~insn->rex) & 0x07) << 5;
        /* merge REX.W via ORing; there should never be a case in which REX.W
         * is important when VEX.W is already set by the instruction.
         */
        if (insn->rex != 0xff && (insn->rex & 0x8) != 0)
            insn->opcode.opcode[1] |= 0x80;
    } else if (insn->special_prefix == 0xC5) {
        /* 2-byte VEX; merge in 1s complement of REX.R */
        insn->opcode.opcode[0] &= 0x7F;
        if (insn->rex != 0xff && (insn->rex & 0x4) == 0)
            insn->opcode.opcode[0] |= 0x80;
        /* No other REX bits should be set */
        if (insn->rex != 0xff && (insn->rex & 0xB) != 0)
            yasm_internal_error(N_("x86: REX.WXB set, but 2-byte VEX"));
    } else if (insn->rex != 0xff && insn->rex != 0) {
        if (insn->common.mode_bits != 64)
            yasm_internal_error(N_("x86: got a REX prefix in non-64-bit mode"));
        YASM_WRITE_8(*bufp, insn->rex);
    }

    /* Opcode */
    x86_opcode_tobytes(&insn->opcode, bufp);

    /* Effective address: ModR/M (if required), SIB (if required), and
     * displacement (if required).
     */
    if (x86_ea) {
        if (x86_ea->need_modrm) {
            if (!x86_ea->valid_modrm)
                yasm_internal_error(N_("invalid Mod/RM in x86 tobytes_insn"));
            YASM_WRITE_8(*bufp, x86_ea->modrm);
        }

        if (x86_ea->need_sib) {
            if (!x86_ea->valid_sib)
                yasm_internal_error(N_("invalid SIB in x86 tobytes_insn"));
            YASM_WRITE_8(*bufp, x86_ea->sib);
        }

        if (x86_ea->ea.need_disp) {
            unsigned int disp_len = x86_ea->ea.disp.size/8;

            if (x86_ea->ea.disp.ip_rel) {
                /* Adjust relative displacement to end of bytecode */
                /*@only@*/ yasm_intnum *delta;
                delta = yasm_intnum_create_int(-(long)bc->len);
                if (!x86_ea->ea.disp.abs)
                    x86_ea->ea.disp.abs =
                        yasm_expr_create_ident(yasm_expr_int(delta), bc->line);
                else
                    x86_ea->ea.disp.abs =
                        yasm_expr_create(YASM_EXPR_ADD,
                                         yasm_expr_expr(x86_ea->ea.disp.abs),
                                         yasm_expr_int(delta), bc->line);
            }
            if (output_value(&x86_ea->ea.disp, *bufp, disp_len,
                             (unsigned long)(*bufp-bufstart), bc, 1, d))
                return 1;
            *bufp += disp_len;
        }
    }

    /* Immediate (if required) */
    if (imm) {
        unsigned int imm_len;
        if (insn->postop == X86_POSTOP_SIGNEXT_IMM8) {
            /* If we got here with this postop still set, we need to force
             * imm size to 8 here.
             */
            imm->size = 8;
            imm->sign = 1;
            imm_len = 1;
        } else
            imm_len = imm->size/8;
        if (output_value(imm, *bufp, imm_len, (unsigned long)(*bufp-bufstart),
                         bc, 1, d))
            return 1;
        *bufp += imm_len;
    }

    return 0;
}

static int
x86_bc_jmp_tobytes(yasm_bytecode *bc, unsigned char **bufp,
                   unsigned char *bufstart, void *d,
                   yasm_output_value_func output_value,
                   /*@unused@*/ yasm_output_reloc_func output_reloc)
{
    x86_jmp *jmp = (x86_jmp *)bc->contents;
    unsigned char opersize;
    unsigned int i;
    /*@only@*/ yasm_intnum *delta;

    /* Prefixes */
    x86_common_tobytes(&jmp->common, bufp, 0);

    /* As opersize may be 0, figure out its "real" value. */
    opersize = (jmp->common.opersize == 0) ?
        jmp->common.mode_bits : jmp->common.opersize;

    /* Check here again to see if forms are actually legal. */
    switch (jmp->op_sel) {
        case JMP_SHORT_FORCED:
        case JMP_SHORT:
            /* 1 byte relative displacement */
            if (jmp->shortop.len == 0)
                yasm_internal_error(N_("short jump does not exist"));

            /* Opcode */
            x86_opcode_tobytes(&jmp->shortop, bufp);

            /* Adjust relative displacement to end of bytecode */
            delta = yasm_intnum_create_int(-(long)bc->len);
            if (!jmp->target.abs)
                jmp->target.abs = yasm_expr_create_ident(yasm_expr_int(delta),
                                                         bc->line);
            else
                jmp->target.abs =
                    yasm_expr_create(YASM_EXPR_ADD,
                                     yasm_expr_expr(jmp->target.abs),
                                     yasm_expr_int(delta), bc->line);

            jmp->target.size = 8;
            jmp->target.sign = 1;
            if (output_value(&jmp->target, *bufp, 1,
                             (unsigned long)(*bufp-bufstart), bc, 1, d))
                return 1;
            *bufp += 1;
            break;
        case JMP_NEAR_FORCED:
        case JMP_NEAR:
            /* 2/4 byte relative displacement (depending on operand size) */
            if (jmp->nearop.len == 0) {
                yasm_error_set(YASM_ERROR_TYPE,
                               N_("near jump does not exist"));
                return 1;
            }

            /* Opcode */
            x86_opcode_tobytes(&jmp->nearop, bufp);

            i = (opersize == 16) ? 2 : 4;

            /* Adjust relative displacement to end of bytecode */
            delta = yasm_intnum_create_int(-(long)bc->len);
            if (!jmp->target.abs)
                jmp->target.abs = yasm_expr_create_ident(yasm_expr_int(delta),
                                                         bc->line);
            else
                jmp->target.abs =
                    yasm_expr_create(YASM_EXPR_ADD,
                                     yasm_expr_expr(jmp->target.abs),
                                     yasm_expr_int(delta), bc->line);

            jmp->target.size = i*8;
            jmp->target.sign = 1;
            if (output_value(&jmp->target, *bufp, i,
                             (unsigned long)(*bufp-bufstart), bc, 1, d))
                return 1;
            *bufp += i;
            break;
        case JMP_NONE:
            yasm_internal_error(N_("jump op_sel cannot be JMP_NONE in tobytes"));
        default:
            yasm_internal_error(N_("unrecognized relative jump op_sel"));
    }
    return 0;
}

static int
x86_bc_jmpfar_tobytes(yasm_bytecode *bc, unsigned char **bufp,
                      unsigned char *bufstart, void *d,
                      yasm_output_value_func output_value,
                      /*@unused@*/ yasm_output_reloc_func output_reloc)
{
    x86_jmpfar *jmpfar = (x86_jmpfar *)bc->contents;
    unsigned int i;
    unsigned char opersize;

    x86_common_tobytes(&jmpfar->common, bufp, 0);
    x86_opcode_tobytes(&jmpfar->opcode, bufp);

    /* As opersize may be 0, figure out its "real" value. */
    opersize = (jmpfar->common.opersize == 0) ?
        jmpfar->common.mode_bits : jmpfar->common.opersize;

    /* Absolute displacement: segment and offset */
    i = (opersize == 16) ? 2 : 4;
    jmpfar->offset.size = i*8;
    if (output_value(&jmpfar->offset, *bufp, i,
                     (unsigned long)(*bufp-bufstart), bc, 1, d))
        return 1;
    *bufp += i;
    jmpfar->segment.size = 16;
    if (output_value(&jmpfar->segment, *bufp, 2,
                     (unsigned long)(*bufp-bufstart), bc, 1, d))
        return 1;
    *bufp += 2;

    return 0;
}

int
yasm_x86__intnum_tobytes(yasm_arch *arch, const yasm_intnum *intn,
                         unsigned char *buf, size_t destsize, size_t valsize,
                         int shift, const yasm_bytecode *bc, int warn)
{
    /* Write value out. */
    yasm_intnum_get_sized(intn, buf, destsize, valsize, shift, 0, warn);
    return 0;
}
