/*
 * Architecture interface
 *
 *  Copyright (C) 2001  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.
 */
#define YASM_LIB_INTERNAL
#define YASM_ARCH_INTERNAL
#include "util.h"
/*@unused@*/ RCSID("$Id$");

#include "coretype.h"

#include "expr.h"

#include "bytecode.h"

#include "arch.h"


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

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

    return retval;
}

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

    retval->type = YASM_INSN__OPERAND_SEGREG;
    retval->data.reg = segreg;
    retval->targetmod = 0;
    retval->size = 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->targetmod = 0;
    retval->size = 0;

    return retval;
}

yasm_insn_operand *
yasm_operand_create_imm(/*@only@*/ yasm_expr *val)
{
    yasm_insn_operand *retval;
    const unsigned long *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->targetmod = 0;
	retval->size = 0;
    }

    return retval;
}

void
yasm_operand_print(const yasm_insn_operand *op, FILE *f, int indent_level,
		   yasm_arch *arch)
{
    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_ea_print(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, "", op->targetmod);
    fprintf(f, "%*sSize=%u\n", indent_level+1, "", op->size);
}

void
yasm_ops_delete(yasm_insn_operands *headp, int content)
{
    yasm_insn_operand *cur, *next;

    cur = STAILQ_FIRST(headp);
    while (cur) {
	next = STAILQ_NEXT(cur, link);
	if (content)
	    switch (cur->type) {
		case YASM_INSN__OPERAND_MEMORY:
		    yasm_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;
    }
    STAILQ_INIT(headp);
}

/*@null@*/ yasm_insn_operand *
yasm_ops_append(yasm_insn_operands *headp,
		/*@returned@*/ /*@null@*/ yasm_insn_operand *op)
{
    if (op) {
	STAILQ_INSERT_TAIL(headp, op, link);
	return op;
    }
    return (yasm_insn_operand *)NULL;
}

void
yasm_ops_print(const yasm_insn_operands *headp, FILE *f, int indent_level,
	       yasm_arch *arch)
{
    yasm_insn_operand *cur;

    STAILQ_FOREACH (cur, headp, link)
	yasm_operand_print(cur, f, indent_level, arch);
}

yasm_insn_operands *
yasm_ops_create(void)
{
    yasm_insn_operands *headp = yasm_xmalloc(sizeof(yasm_insn_operands));
    yasm_ops_initialize(headp);
    return headp;
}

void
yasm_ops_destroy(yasm_insn_operands *headp, int content)
{
    yasm_ops_delete(headp, content);
    yasm_xfree(headp);
}

/* Non-macro yasm_ops_first() for non-YASM_LIB_INTERNAL users. */
#undef yasm_ops_first
yasm_insn_operand *
yasm_ops_first(yasm_insn_operands *headp)
{
    return STAILQ_FIRST(headp);
}

/* Non-macro yasm_operand_next() for non-YASM_LIB_INTERNAL users. */
#undef yasm_operand_next
yasm_insn_operand *
yasm_operand_next(yasm_insn_operand *cur)
{
    return STAILQ_NEXT(cur, link);
}
