yasm_value.
svn path=/trunk/yasm/; revision=1740
-Tyasm_expr_xform_func
-Tyasm_expr__item
-Tyasm_floatnum
--Tyasm_immval
-Tyasm_intnum
-Tyasm_insn_operand
-Tyasm_insn_operands
};
-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)
{
*/
};
-/** 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). */
/*@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).
*/
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;
value->curpos_rel = 0;
value->ip_rel = 0;
value->section_rel = 0;
+ value->sign = 0;
value->size = size;
}
value->curpos_rel = 0;
value->ip_rel = 0;
value->section_rel = 0;
+ value->sign = 0;
value->size = size;
}
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;
}
}
}
+ /* 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.
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");
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, "");
}
}
* 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)
* \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
/*@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) */
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);
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);
{
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
}
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 {
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 */
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];
{
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 */
/* 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;
}
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;
* 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;
/* 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;
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)
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
# $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)