/*
 * Mnemonic instruction bytecode
 *
 *  Copyright (C) 2005-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"
/*@unused@*/ RCSID("$Id: insn.c,v 1.1.1.1 2012/03/29 17:21:05 uid42307 Exp $");

#include "libyasm-stdint.h"
#include "coretype.h"

#include "errwarn.h"
#include "expr.h"
#include "value.h"

#include "bytecode.h"
#include "insn.h"
#include "arch.h"


void
yasm_ea_set_segreg(yasm_effaddr *ea, uintptr_t segreg)
{
    if (!ea)
        return;

    if (segreg != 0 && ea->segreg != 0)
        yasm_warn_set(YASM_WARN_GENERAL,
                      N_("multiple segment overrides, using leftmost"));

    ea->segreg = segreg;
}

yasm_insn_operand *
yasm_operand_create_reg(uintptr_t reg)
{
    yasm_insn_operand *retval = yasm_xmalloc(sizeof(yasm_insn_operand));

    retval->type = YASM_INSN__OPERAND_REG;
    retval->data.reg = reg;
    retval->seg = 0;
    retval->targetmod = 0;
    retval->size = 0;
    retval->deref = 0;
    retval->strict = 0;

    return retval;
}

yasm_insn_operand *
yasm_operand_create_segreg(uintptr_t segreg)
{
    yasm_insn_operand *retval = yasm_xmalloc(sizeof(yasm_insn_operand));

    retval->type = YASM_INSN__OPERAND_SEGREG;
    retval->data.reg = segreg;
    retval->seg = 0;
    retval->targetmod = 0;
    retval->size = 0;
    retval->deref = 0;
    retval->strict = 0;

    return retval;
}

yasm_insn_operand *
yasm_operand_create_mem(/*@only@*/ yasm_effaddr *ea)
{
    yasm_insn_operand *retval = yasm_xmalloc(sizeof(yasm_insn_operand));

    retval->type = YASM_INSN__OPERAND_MEMORY;
    retval->data.ea = ea;
    retval->seg = 0;
    retval->targetmod = 0;
    retval->size = 0;
    retval->deref = 0;
    retval->strict = 0;

    return retval;
}

yasm_insn_operand *
yasm_operand_create_imm(/*@only@*/ yasm_expr *val)
{
    yasm_insn_operand *retval;
    const uintptr_t *reg;

    reg = yasm_expr_get_reg(&val, 0);
    if (reg) {
        retval = yasm_operand_create_reg(*reg);
        yasm_expr_destroy(val);
    } else {
        retval = yasm_xmalloc(sizeof(yasm_insn_operand));
        retval->type = YASM_INSN__OPERAND_IMM;
        retval->data.val = val;
        retval->seg = 0;
        retval->targetmod = 0;
        retval->size = 0;
        retval->deref = 0;
        retval->strict = 0;
    }

    return retval;
}

yasm_insn_operand *
yasm_insn_ops_append(yasm_insn *insn, yasm_insn_operand *op)
{
    if (op) {
        insn->num_operands++;
        STAILQ_INSERT_TAIL(&insn->operands, op, link);
        return op;
    }
    return (yasm_insn_operand *)NULL;
}

void
yasm_insn_add_prefix(yasm_insn *insn, uintptr_t prefix)
{
    insn->prefixes =
        yasm_xrealloc(insn->prefixes,
                      (insn->num_prefixes+1)*sizeof(uintptr_t));
    insn->prefixes[insn->num_prefixes] = prefix;
    insn->num_prefixes++;
}

void
yasm_insn_add_seg_prefix(yasm_insn *insn, uintptr_t segreg)
{
    insn->segregs =
        yasm_xrealloc(insn->segregs, (insn->num_segregs+1)*sizeof(uintptr_t));
    insn->segregs[insn->num_segregs] = segreg;
    insn->num_segregs++;
}

void
yasm_insn_initialize(yasm_insn *insn)
{
    STAILQ_INIT(&insn->operands);

    insn->prefixes = NULL;
    insn->segregs = NULL;

    insn->num_operands = 0;
    insn->num_prefixes = 0;
    insn->num_segregs = 0;
}

void
yasm_insn_delete(yasm_insn *insn,
                 void (*ea_destroy) (/*@only@*/ yasm_effaddr *))
{
    if (insn->num_operands > 0) {
        yasm_insn_operand *cur, *next;

        cur = STAILQ_FIRST(&insn->operands);
        while (cur) {
            next = STAILQ_NEXT(cur, link);
            switch (cur->type) {
                case YASM_INSN__OPERAND_MEMORY:
                    ea_destroy(cur->data.ea);
                    break;
                case YASM_INSN__OPERAND_IMM:
                    yasm_expr_destroy(cur->data.val);
                    break;
                default:
                    break;
            }
            yasm_xfree(cur);
            cur = next;
        }
    }
    if (insn->num_prefixes > 0)
        yasm_xfree(insn->prefixes);
    if (insn->num_segregs > 0)
        yasm_xfree(insn->segregs);
}

void
yasm_insn_print(const yasm_insn *insn, FILE *f, int indent_level)
{
    const yasm_insn_operand *op;

    STAILQ_FOREACH (op, &insn->operands, link) {
        switch (op->type) {
            case YASM_INSN__OPERAND_REG:
                fprintf(f, "%*sReg=", indent_level, "");
                /*yasm_arch_reg_print(arch, op->data.reg, f);*/
                fprintf(f, "\n");
                break;
            case YASM_INSN__OPERAND_SEGREG:
                fprintf(f, "%*sSegReg=", indent_level, "");
                /*yasm_arch_segreg_print(arch, op->data.reg, f);*/
                fprintf(f, "\n");
                break;
            case YASM_INSN__OPERAND_MEMORY:
                fprintf(f, "%*sMemory=\n", indent_level, "");
                /*yasm_arch_ea_print(arch, op->data.ea, f, indent_level);*/
                break;
            case YASM_INSN__OPERAND_IMM:
                fprintf(f, "%*sImm=", indent_level, "");
                yasm_expr_print(op->data.val, f);
                fprintf(f, "\n");
                break;
        }
        fprintf(f, "%*sTargetMod=%lx\n", indent_level+1, "",
                (unsigned long)op->targetmod);
        fprintf(f, "%*sSize=%u\n", indent_level+1, "", op->size);
        fprintf(f, "%*sDeref=%d, Strict=%d\n", indent_level+1, "",
                (int)op->deref, (int)op->strict);
    }
}

void
yasm_insn_finalize(yasm_insn *insn)
{
    unsigned int i;
    yasm_insn_operand *op;
    yasm_error_class eclass;
    char *str, *xrefstr;
    unsigned long xrefline;

    /* Simplify the operands' expressions first. */
    for (i = 0, op = yasm_insn_ops_first(insn);
         op && i<insn->num_operands; op = yasm_insn_op_next(op), i++) {
        /* Check operand type */
        switch (op->type) {
            case YASM_INSN__OPERAND_MEMORY:
                /* Don't get over-ambitious here; some archs' memory expr
                 * parser are sensitive to the presence of *1, etc, so don't
                 * simplify reg*1 identities.
                 */
                if (op->data.ea)
                    op->data.ea->disp.abs =
                        yasm_expr__level_tree(op->data.ea->disp.abs, 1, 1, 0,
                                              0, NULL, NULL);
                if (yasm_error_occurred()) {
                    /* Add a pointer to where it was used to the error */
                    yasm_error_fetch(&eclass, &str, &xrefline, &xrefstr);
                    if (xrefstr) {
                        yasm_error_set_xref(xrefline, "%s", xrefstr);
                        yasm_xfree(xrefstr);
                    }
                    if (str) {
                        yasm_error_set(eclass, "%s in memory expression", str);
                        yasm_xfree(str);
                    }
                    return;
                }
                break;
            case YASM_INSN__OPERAND_IMM:
                op->data.val =
                    yasm_expr__level_tree(op->data.val, 1, 1, 1, 0, NULL,
                                          NULL);
                if (yasm_error_occurred()) {
                    /* Add a pointer to where it was used to the error */
                    yasm_error_fetch(&eclass, &str, &xrefline, &xrefstr);
                    if (xrefstr) {
                        yasm_error_set_xref(xrefline, "%s", xrefstr);
                        yasm_xfree(xrefstr);
                    }
                    if (str) {
                        yasm_error_set(eclass, "%s in immediate expression",
                                       str);
                        yasm_xfree(str);
                    }
                    return;
                }
                break;
            default:
                break;
        }
    }
}
