/* * 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); }