123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295 |
- /*
- * 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"
- #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;
- retval->size = ea->data_len * 8;
- 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;
- }
- }
- }
|