mirror of
https://github.com/yasm/yasm
synced 2026-08-26 22:26:05 -04:00
Remove yasm_immval, moving remaining unique information (sign flag) into
yasm_value. svn path=/trunk/yasm/; revision=1740
This commit is contained in:
parent
9dd8df8fb6
commit
a1f4c99e94
11 changed files with 45 additions and 92 deletions
1
.indent.pro
vendored
1
.indent.pro
vendored
|
|
@ -61,7 +61,6 @@
|
|||
-Tyasm_expr_xform_func
|
||||
-Tyasm_expr__item
|
||||
-Tyasm_floatnum
|
||||
-Tyasm_immval
|
||||
-Tyasm_intnum
|
||||
-Tyasm_insn_operand
|
||||
-Tyasm_insn_operands
|
||||
|
|
|
|||
|
|
@ -76,19 +76,6 @@ static const yasm_bytecode_callback bc_insn_callback = {
|
|||
};
|
||||
|
||||
|
||||
yasm_immval *
|
||||
yasm_imm_create_expr(yasm_expr *e, yasm_bytecode *precbc)
|
||||
{
|
||||
yasm_immval *im = yasm_xmalloc(sizeof(yasm_immval));
|
||||
|
||||
if (yasm_value_finalize_expr(&im->val, e, precbc, 0))
|
||||
yasm_error_set(YASM_ERROR_TOO_COMPLEX,
|
||||
N_("immediate expression too complex"));
|
||||
im->sign = 0;
|
||||
|
||||
return im;
|
||||
}
|
||||
|
||||
const yasm_expr *
|
||||
yasm_ea_get_disp(const yasm_effaddr *ea)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -73,13 +73,6 @@ struct yasm_effaddr {
|
|||
*/
|
||||
};
|
||||
|
||||
/** An immediate value. */
|
||||
typedef struct yasm_immval {
|
||||
yasm_value val; /**< the immediate value itself */
|
||||
|
||||
unsigned char sign; /**< 1 if final imm is treated as signed */
|
||||
} yasm_immval;
|
||||
|
||||
/** A data value (opaque type). */
|
||||
typedef struct yasm_dataval yasm_dataval;
|
||||
/** A list of data values (opaque type). */
|
||||
|
|
@ -89,14 +82,6 @@ typedef struct yasm_datavalhead yasm_datavalhead;
|
|||
/*@reldef@*/ STAILQ_HEAD(yasm_datavalhead, yasm_dataval);
|
||||
#endif
|
||||
|
||||
/** Create an immediate value from an expression.
|
||||
* \param e expression (kept, do not free).
|
||||
* \param precbc previous bytecode to bytecode containing immediate
|
||||
* \return Newly allocated immediate value.
|
||||
*/
|
||||
/*@only@*/ yasm_immval *yasm_imm_create_expr(/*@keep@*/ yasm_expr *e,
|
||||
/*@null@*/ yasm_bytecode *precbc);
|
||||
|
||||
/** Get the displacement portion of an effective address.
|
||||
* \param ea effective address
|
||||
* \return Expression representing the displacement (read-only).
|
||||
|
|
|
|||
|
|
@ -151,6 +151,11 @@ typedef struct yasm_value {
|
|||
*/
|
||||
unsigned int section_rel : 1;
|
||||
|
||||
/** Sign of the value. Nonzero if the final value should be treated as
|
||||
* signed, 0 if it should be treated as signed.
|
||||
*/
|
||||
unsigned int sign : 1;
|
||||
|
||||
/** Size of the value, in bits. */
|
||||
unsigned int size : 8;
|
||||
} yasm_value;
|
||||
|
|
|
|||
|
|
@ -58,6 +58,7 @@ yasm_value_initialize(/*@out@*/ yasm_value *value,
|
|||
value->curpos_rel = 0;
|
||||
value->ip_rel = 0;
|
||||
value->section_rel = 0;
|
||||
value->sign = 0;
|
||||
value->size = size;
|
||||
}
|
||||
|
||||
|
|
@ -73,6 +74,7 @@ yasm_value_init_sym(/*@out@*/ yasm_value *value, /*@null@*/ yasm_symrec *sym,
|
|||
value->curpos_rel = 0;
|
||||
value->ip_rel = 0;
|
||||
value->section_rel = 0;
|
||||
value->sign = 0;
|
||||
value->size = size;
|
||||
}
|
||||
|
||||
|
|
@ -87,6 +89,7 @@ yasm_value_init_copy(yasm_value *value, const yasm_value *orig)
|
|||
value->curpos_rel = orig->curpos_rel;
|
||||
value->ip_rel = orig->ip_rel;
|
||||
value->section_rel = orig->section_rel;
|
||||
value->sign = orig->sign;
|
||||
value->size = orig->size;
|
||||
}
|
||||
|
||||
|
|
@ -625,6 +628,10 @@ yasm_value_output_basic(yasm_value *value, /*@out@*/ unsigned char *buf,
|
|||
}
|
||||
}
|
||||
|
||||
/* Adjust warn for signed/unsigned integer warnings */
|
||||
if (warn != 0)
|
||||
warn = value->sign ? -1 : 1;
|
||||
|
||||
if (value->rel) {
|
||||
/* If relative portion is not in bc section, don't try to handle it
|
||||
* here. Otherwise get the relative portion's offset.
|
||||
|
|
@ -690,6 +697,8 @@ yasm_value_output_basic(yasm_value *value, /*@out@*/ unsigned char *buf,
|
|||
void
|
||||
yasm_value_print(const yasm_value *value, FILE *f, int indent_level)
|
||||
{
|
||||
fprintf(f, "%*s%u-bit, %ssigned", indent_level, "", value->size,
|
||||
value->sign ? "" : "un");
|
||||
fprintf(f, "%*sAbsolute portion=", indent_level, "");
|
||||
yasm_expr_print(value->abs, f);
|
||||
fprintf(f, "\n");
|
||||
|
|
@ -706,5 +715,9 @@ yasm_value_print(const yasm_value *value, FILE *f, int indent_level)
|
|||
if (value->curpos_rel)
|
||||
fprintf(f, "%*s(Relative to current position)\n", indent_level,
|
||||
"");
|
||||
if (value->ip_rel)
|
||||
fprintf(f, "%*s(IP-relative)\n", indent_level, "");
|
||||
if (value->section_rel)
|
||||
fprintf(f, "%*s(Section-relative)\n", indent_level, "");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@
|
|||
* processing into a #yasm_value. This function is intended for use during
|
||||
* parsing simply to ensure all fields of the value are initialized; after
|
||||
* the parse is complete, yasm_value_extract() should be called to finalize
|
||||
* the value.
|
||||
* the value. The value defaults to unsigned.
|
||||
* \param value value to be initialized
|
||||
* \param e expression (kept)
|
||||
* \param size value size (in bits)
|
||||
|
|
@ -138,9 +138,8 @@ int yasm_value_finalize_expr(/*@out@*/ yasm_value *value,
|
|||
* \param bc current bytecode (usually passed into higher-level
|
||||
* calling function)
|
||||
* \param warn enables standard warnings: zero for none;
|
||||
* nonzero for overflow/underflow floating point warnings;
|
||||
* negative for signed integer warnings,
|
||||
* positive for unsigned integer warnings
|
||||
* nonzero for overflow/underflow floating point and
|
||||
* integer warnings
|
||||
* \param arch architecture
|
||||
* \note Adds in value.rel (correctly) if PC-relative and in the same section
|
||||
* as bc (and there is no WRT or SEG); if this is not the desired
|
||||
|
|
|
|||
|
|
@ -193,7 +193,7 @@ typedef struct x86_insn {
|
|||
|
||||
/*@null@*/ x86_effaddr *x86_ea; /* effective address */
|
||||
|
||||
/*@null@*/ yasm_immval *imm; /* immediate or relative value */
|
||||
/*@null@*/ yasm_value *imm; /* immediate or relative value */
|
||||
|
||||
unsigned char def_opersize_64; /* default operand size in 64-bit mode */
|
||||
unsigned char special_prefix; /* "special" prefix (0=none) */
|
||||
|
|
|
|||
|
|
@ -346,7 +346,7 @@ x86_bc_insn_destroy(void *contents)
|
|||
if (insn->x86_ea)
|
||||
yasm_ea_destroy((yasm_effaddr *)insn->x86_ea);
|
||||
if (insn->imm) {
|
||||
yasm_value_delete(&insn->imm->val);
|
||||
yasm_value_delete(insn->imm);
|
||||
yasm_xfree(insn->imm);
|
||||
}
|
||||
yasm_xfree(contents);
|
||||
|
|
@ -427,9 +427,7 @@ x86_bc_insn_print(const void *contents, FILE *f, int indent_level)
|
|||
else {
|
||||
indent_level++;
|
||||
fprintf(f, "\n");
|
||||
yasm_value_print(&insn->imm->val, f, indent_level);
|
||||
fprintf(f, "%*sSign=%u\n", indent_level, "",
|
||||
(unsigned int)insn->imm->sign);
|
||||
yasm_value_print(insn->imm, f, indent_level);
|
||||
indent_level--;
|
||||
}
|
||||
x86_opcode_print(&insn->opcode, f, indent_level);
|
||||
|
|
@ -523,7 +521,7 @@ x86_bc_insn_calc_len(yasm_bytecode *bc, yasm_bc_add_span_func add_span,
|
|||
{
|
||||
x86_insn *insn = (x86_insn *)bc->contents;
|
||||
x86_effaddr *x86_ea = insn->x86_ea;
|
||||
yasm_immval *imm = insn->imm;
|
||||
yasm_value *imm = insn->imm;
|
||||
|
||||
if (x86_ea) {
|
||||
/* Check validity of effective address and calc R/M bits of
|
||||
|
|
@ -556,28 +554,28 @@ x86_bc_insn_calc_len(yasm_bytecode *bc, yasm_bc_add_span_func add_span,
|
|||
}
|
||||
|
||||
if (imm) {
|
||||
unsigned int immlen = imm->val.size;
|
||||
unsigned int immlen = imm->size;
|
||||
|
||||
/* TODO: check imm->len vs. sized len from expr? */
|
||||
|
||||
/* Handle signext_imm8 postop special-casing */
|
||||
if (insn->postop == X86_POSTOP_SIGNEXT_IMM8) {
|
||||
/*@null@*/ /*@only@*/ yasm_intnum *num;
|
||||
num = yasm_value_get_intnum(&imm->val, NULL, 0);
|
||||
num = yasm_value_get_intnum(imm, NULL, 0);
|
||||
|
||||
if (!num) {
|
||||
/* Unknown; default to byte form and set as critical
|
||||
* expression.
|
||||
*/
|
||||
immlen = 8;
|
||||
add_span(add_span_data, bc, 2, &imm->val, -128, 127);
|
||||
add_span(add_span_data, bc, 2, imm, -128, 127);
|
||||
} else {
|
||||
if (yasm_intnum_in_range(num, -128, 127)) {
|
||||
/* We can use the sign-extended byte form: shorten
|
||||
* the immediate length to 1 and make the byte form
|
||||
* permanent.
|
||||
*/
|
||||
imm->val.size = 8;
|
||||
imm->size = 8;
|
||||
imm->sign = 1;
|
||||
immlen = 8;
|
||||
} else {
|
||||
|
|
@ -612,7 +610,7 @@ x86_bc_insn_expand(yasm_bytecode *bc, int span, long old_val, long new_val,
|
|||
x86_insn *insn = (x86_insn *)bc->contents;
|
||||
x86_effaddr *x86_ea = insn->x86_ea;
|
||||
yasm_effaddr *ea = &x86_ea->ea;
|
||||
yasm_immval *imm = insn->imm;
|
||||
yasm_value *imm = insn->imm;
|
||||
|
||||
if (ea && span == 1) {
|
||||
/* Change displacement length into word-sized */
|
||||
|
|
@ -629,7 +627,7 @@ x86_bc_insn_expand(yasm_bytecode *bc, int span, long old_val, long new_val,
|
|||
if (insn->postop == X86_POSTOP_SIGNEXT_IMM8) {
|
||||
/* Update bc->len for new opcode and immediate size */
|
||||
bc->len -= insn->opcode.len;
|
||||
bc->len += imm->val.size/8;
|
||||
bc->len += imm->size/8;
|
||||
|
||||
/* Change to the word-sized opcode */
|
||||
insn->opcode.opcode[0] = insn->opcode.opcode[insn->opcode.len];
|
||||
|
|
@ -790,7 +788,7 @@ x86_bc_insn_tobytes(yasm_bytecode *bc, unsigned char **bufp, void *d,
|
|||
{
|
||||
x86_insn *insn = (x86_insn *)bc->contents;
|
||||
/*@null@*/ x86_effaddr *x86_ea = (x86_effaddr *)insn->x86_ea;
|
||||
yasm_immval *imm = insn->imm;
|
||||
yasm_value *imm = insn->imm;
|
||||
unsigned char *bufp_orig = *bufp;
|
||||
|
||||
/* Prefixes */
|
||||
|
|
@ -859,14 +857,13 @@ x86_bc_insn_tobytes(yasm_bytecode *bc, unsigned char **bufp, void *d,
|
|||
/* If we got here with this postop still set, we need to force
|
||||
* imm size to 8 here.
|
||||
*/
|
||||
imm->val.size = 8;
|
||||
imm->size = 8;
|
||||
imm->sign = 1;
|
||||
imm_len = 1;
|
||||
} else
|
||||
imm_len = imm->val.size/8;
|
||||
if (output_value(&imm->val, *bufp, imm_len,
|
||||
(unsigned long)(*bufp-bufp_orig), bc, imm->sign?-1:1,
|
||||
d))
|
||||
imm_len = imm->size/8;
|
||||
if (output_value(imm, *bufp, imm_len, (unsigned long)(*bufp-bufp_orig),
|
||||
bc, 1, d))
|
||||
return 1;
|
||||
*bufp += imm_len;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3003,8 +3003,11 @@ yasm_x86__finalize_insn(yasm_arch *arch, yasm_bytecode *bc,
|
|||
yasm_internal_error(N_("unhandled segment prefix"));
|
||||
|
||||
if (imm) {
|
||||
insn->imm = yasm_imm_create_expr(imm, prev_bc);
|
||||
insn->imm->val.size = im_len;
|
||||
insn->imm = yasm_xmalloc(sizeof(yasm_value));
|
||||
if (yasm_value_finalize_expr(insn->imm, imm, prev_bc, 0))
|
||||
yasm_error_set(YASM_ERROR_TOO_COMPLEX,
|
||||
N_("immediate expression too complex"));
|
||||
insn->imm->size = im_len;
|
||||
insn->imm->sign = im_sign;
|
||||
} else
|
||||
insn->imm = NULL;
|
||||
|
|
@ -3041,9 +3044,9 @@ yasm_x86__finalize_insn(yasm_arch *arch, yasm_bytecode *bc,
|
|||
* second byte of the opcode and its ModRM byte is put in the third
|
||||
* byte of the opcode.
|
||||
*/
|
||||
if (!insn->imm->val.abs ||
|
||||
if (!insn->imm->abs ||
|
||||
yasm_intnum_check_size(
|
||||
yasm_expr_get_intnum(&insn->imm->val.abs, 0), 32, 0, 1)) {
|
||||
yasm_expr_get_intnum(&insn->imm->abs, 0), 32, 0, 1)) {
|
||||
/* Throwaway REX byte */
|
||||
unsigned char rex_temp = 0;
|
||||
|
||||
|
|
@ -3055,7 +3058,7 @@ yasm_x86__finalize_insn(yasm_arch *arch, yasm_bytecode *bc,
|
|||
|
||||
/* Make the imm32s form permanent. */
|
||||
insn->opcode.opcode[0] = insn->opcode.opcode[1];
|
||||
insn->imm->val.size = 32;
|
||||
insn->imm->size = 32;
|
||||
}
|
||||
insn->opcode.opcode[1] = 0; /* avoid possible confusion */
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -39,15 +39,9 @@ cdef extern from "libyasm/bytecode.h":
|
|||
unsigned int nosplit
|
||||
unsigned int strong
|
||||
|
||||
cdef struct yasm_immval:
|
||||
yasm_value val
|
||||
unsigned int len
|
||||
unsigned int sign
|
||||
|
||||
cdef struct yasm_dataval
|
||||
cdef struct yasm_datavalhead
|
||||
|
||||
cdef yasm_immval* yasm_imm_create_expr(yasm_expr *e, yasm_bytecode *precbc)
|
||||
cdef yasm_expr* yasm_ea_get_disp(yasm_effaddr *ea)
|
||||
cdef void yasm_ea_set_len(yasm_effaddr *ea, unsigned int len)
|
||||
cdef void yasm_ea_set_nosplit(yasm_effaddr *ea, unsigned int nosplit)
|
||||
|
|
@ -153,28 +147,6 @@ cdef extern from "libyasm/bc-int.h":
|
|||
|
||||
cdef yasm_bytecode *yasm_bc__next(yasm_bytecode *bc)
|
||||
|
||||
cdef object __make_immval(yasm_immval *imm):
|
||||
return ImmVal(__pass_voidp(imm, ImmVal))
|
||||
|
||||
cdef class ImmVal:
|
||||
cdef yasm_immval *imm
|
||||
|
||||
def __new__(self, value, precbc=None):
|
||||
if isinstance(value, Expression):
|
||||
if precbc is None:
|
||||
self.imm = yasm_imm_create_expr(
|
||||
yasm_expr_copy((<Expression>value).expr), NULL)
|
||||
elif isinstance(precbc, Bytecode):
|
||||
self.imm = yasm_imm_create_expr(
|
||||
yasm_expr_copy((<Expression>value).expr),
|
||||
(<Bytecode>precbc).bc)
|
||||
else:
|
||||
raise TypeError("Invalid precbc type '%s'" % type(precbc))
|
||||
elif PyCObject_Check(value):
|
||||
self.imm = <yasm_immval *>__get_voidp(value, ImmVal)
|
||||
else:
|
||||
raise TypeError("Invalid value type '%s'" % type(value))
|
||||
|
||||
cdef class Bytecode:
|
||||
cdef yasm_bytecode *bc
|
||||
|
||||
|
|
|
|||
|
|
@ -1,11 +1,4 @@
|
|||
# $Id$
|
||||
from tests import TestCase, add
|
||||
from yasm import Bytecode, ImmVal, Expression
|
||||
from yasm import Bytecode, Expression
|
||||
|
||||
class TImmVal(TestCase):
|
||||
def test_create(self):
|
||||
self.assertRaises(TypeError, ImmVal, "notimmval")
|
||||
|
||||
imm = ImmVal(Expression('+', 2, 3))
|
||||
|
||||
add(TImmVal)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue