2 * Mnemonic instruction bytecode
4 * Copyright (C) 2005-2007 Peter Johnson
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND OTHER CONTRIBUTORS ``AS IS''
16 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR OTHER CONTRIBUTORS BE
19 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25 * POSSIBILITY OF SUCH DAMAGE.
29 #include "libyasm-stdint.h"
42 yasm_ea_set_segreg(yasm_effaddr *ea, uintptr_t segreg)
47 if (segreg != 0 && ea->segreg != 0)
48 yasm_warn_set(YASM_WARN_GENERAL,
49 N_("multiple segment overrides, using leftmost"));
55 yasm_operand_create_reg(uintptr_t reg)
57 yasm_insn_operand *retval = yasm_xmalloc(sizeof(yasm_insn_operand));
59 retval->type = YASM_INSN__OPERAND_REG;
60 retval->data.reg = reg;
62 retval->targetmod = 0;
71 yasm_operand_create_segreg(uintptr_t segreg)
73 yasm_insn_operand *retval = yasm_xmalloc(sizeof(yasm_insn_operand));
75 retval->type = YASM_INSN__OPERAND_SEGREG;
76 retval->data.reg = segreg;
78 retval->targetmod = 0;
87 yasm_operand_create_mem(/*@only@*/ yasm_effaddr *ea)
89 yasm_insn_operand *retval = yasm_xmalloc(sizeof(yasm_insn_operand));
91 retval->type = YASM_INSN__OPERAND_MEMORY;
94 retval->targetmod = 0;
98 retval->size = ea->data_len * 8;
104 yasm_operand_create_imm(/*@only@*/ yasm_expr *val)
106 yasm_insn_operand *retval;
107 const uintptr_t *reg;
109 reg = yasm_expr_get_reg(&val, 0);
111 retval = yasm_operand_create_reg(*reg);
112 yasm_expr_destroy(val);
114 retval = yasm_xmalloc(sizeof(yasm_insn_operand));
115 retval->type = YASM_INSN__OPERAND_IMM;
116 retval->data.val = val;
118 retval->targetmod = 0;
128 yasm_insn_ops_append(yasm_insn *insn, yasm_insn_operand *op)
131 insn->num_operands++;
132 STAILQ_INSERT_TAIL(&insn->operands, op, link);
135 return (yasm_insn_operand *)NULL;
139 yasm_insn_add_prefix(yasm_insn *insn, uintptr_t prefix)
142 yasm_xrealloc(insn->prefixes,
143 (insn->num_prefixes+1)*sizeof(uintptr_t));
144 insn->prefixes[insn->num_prefixes] = prefix;
145 insn->num_prefixes++;
149 yasm_insn_add_seg_prefix(yasm_insn *insn, uintptr_t segreg)
152 yasm_xrealloc(insn->segregs, (insn->num_segregs+1)*sizeof(uintptr_t));
153 insn->segregs[insn->num_segregs] = segreg;
158 yasm_insn_initialize(yasm_insn *insn)
160 STAILQ_INIT(&insn->operands);
162 insn->prefixes = NULL;
163 insn->segregs = NULL;
165 insn->num_operands = 0;
166 insn->num_prefixes = 0;
167 insn->num_segregs = 0;
171 yasm_insn_delete(yasm_insn *insn,
172 void (*ea_destroy) (/*@only@*/ yasm_effaddr *))
174 if (insn->num_operands > 0) {
175 yasm_insn_operand *cur, *next;
177 cur = STAILQ_FIRST(&insn->operands);
179 next = STAILQ_NEXT(cur, link);
181 case YASM_INSN__OPERAND_MEMORY:
182 ea_destroy(cur->data.ea);
184 case YASM_INSN__OPERAND_IMM:
185 yasm_expr_destroy(cur->data.val);
194 if (insn->num_prefixes > 0)
195 yasm_xfree(insn->prefixes);
196 if (insn->num_segregs > 0)
197 yasm_xfree(insn->segregs);
201 yasm_insn_print(const yasm_insn *insn, FILE *f, int indent_level)
203 const yasm_insn_operand *op;
205 STAILQ_FOREACH (op, &insn->operands, link) {
207 case YASM_INSN__OPERAND_REG:
208 fprintf(f, "%*sReg=", indent_level, "");
209 /*yasm_arch_reg_print(arch, op->data.reg, f);*/
212 case YASM_INSN__OPERAND_SEGREG:
213 fprintf(f, "%*sSegReg=", indent_level, "");
214 /*yasm_arch_segreg_print(arch, op->data.reg, f);*/
217 case YASM_INSN__OPERAND_MEMORY:
218 fprintf(f, "%*sMemory=\n", indent_level, "");
219 /*yasm_arch_ea_print(arch, op->data.ea, f, indent_level);*/
221 case YASM_INSN__OPERAND_IMM:
222 fprintf(f, "%*sImm=", indent_level, "");
223 yasm_expr_print(op->data.val, f);
227 fprintf(f, "%*sTargetMod=%lx\n", indent_level+1, "",
228 (unsigned long)op->targetmod);
229 fprintf(f, "%*sSize=%u\n", indent_level+1, "", op->size);
230 fprintf(f, "%*sDeref=%d, Strict=%d\n", indent_level+1, "",
231 (int)op->deref, (int)op->strict);
236 yasm_insn_finalize(yasm_insn *insn)
239 yasm_insn_operand *op;
240 yasm_error_class eclass;
242 unsigned long xrefline;
244 /* Simplify the operands' expressions first. */
245 for (i = 0, op = yasm_insn_ops_first(insn);
246 op && i<insn->num_operands; op = yasm_insn_op_next(op), i++) {
247 /* Check operand type */
249 case YASM_INSN__OPERAND_MEMORY:
250 /* Don't get over-ambitious here; some archs' memory expr
251 * parser are sensitive to the presence of *1, etc, so don't
252 * simplify reg*1 identities.
255 op->data.ea->disp.abs =
256 yasm_expr__level_tree(op->data.ea->disp.abs, 1, 1, 0,
258 if (yasm_error_occurred()) {
259 /* Add a pointer to where it was used to the error */
260 yasm_error_fetch(&eclass, &str, &xrefline, &xrefstr);
262 yasm_error_set_xref(xrefline, "%s", xrefstr);
266 yasm_error_set(eclass, "%s in memory expression", str);
272 case YASM_INSN__OPERAND_IMM:
274 yasm_expr__level_tree(op->data.val, 1, 1, 1, 0, NULL,
276 if (yasm_error_occurred()) {
277 /* Add a pointer to where it was used to the error */
278 yasm_error_fetch(&eclass, &str, &xrefline, &xrefstr);
280 yasm_error_set_xref(xrefline, "%s", xrefstr);
284 yasm_error_set(eclass, "%s in immediate expression",