blob: 90f7a2333917443d0d6a4975f322aa61e131aef3 [file] [log] [blame]
/*
* 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;
retval->deref = 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;
retval->deref = 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;
retval->deref = 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;
retval->deref = 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);
}