From fd04b1aef6f7d987a66c36dba424cf4863ea224d Mon Sep 17 00:00:00 2001 From: Peter Johnson Date: Wed, 18 Oct 2006 05:36:51 +0000 Subject: [PATCH] Don't mix EQU expansion with other expr leveling; we could get confused with certain combinations. (2nd half of #83) This also hides some internals of yasm_expr_level_tree. svn path=/trunk/yasm/; revision=1655 --- libyasm/bc-insn.c | 4 +- libyasm/expr.c | 67 +++++++++++++++++++++++--------- libyasm/expr.h | 13 +------ libyasm/tests/Makefile.inc | 2 + libyasm/tests/equ-expand.asm | 9 +++++ libyasm/tests/equ-expand.hex | 10 +++++ libyasm/value.c | 8 ++-- modules/arch/x86/x86expr.c | 4 +- modules/objfmts/bin/bin-objfmt.c | 2 +- tools/python-yasm/expr.pxi | 3 +- 10 files changed, 81 insertions(+), 41 deletions(-) create mode 100644 libyasm/tests/equ-expand.asm create mode 100644 libyasm/tests/equ-expand.hex diff --git a/libyasm/bc-insn.c b/libyasm/bc-insn.c index 6e63e311..d6dafb22 100644 --- a/libyasm/bc-insn.c +++ b/libyasm/bc-insn.c @@ -205,7 +205,7 @@ bc_insn_finalize(yasm_bytecode *bc, yasm_bytecode *prev_bc) if (op->data.ea) op->data.ea->disp.abs = yasm_expr__level_tree(op->data.ea->disp.abs, 1, 1, 0, - 0, NULL, NULL, NULL); + 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); @@ -222,7 +222,7 @@ bc_insn_finalize(yasm_bytecode *bc, yasm_bytecode *prev_bc) break; case YASM_INSN__OPERAND_IMM: op->data.val = - yasm_expr__level_tree(op->data.val, 1, 1, 1, 0, NULL, NULL, + 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 */ diff --git a/libyasm/expr.c b/libyasm/expr.c index 6439846b..f5892989 100644 --- a/libyasm/expr.c +++ b/libyasm/expr.c @@ -357,7 +357,7 @@ yasm_expr__bc_dist_subst(yasm_expr **ep, void *cbd, my_cbd.cbd = cbd; my_cbd.subst = 0; *ep = yasm_expr__level_tree(*ep, 1, 1, 1, 0, &expr_xform_bc_dist_subst, - &my_cbd, NULL); + &my_cbd); return my_cbd.subst; } @@ -799,32 +799,24 @@ expr_level_op(/*@returned@*/ /*@only@*/ yasm_expr *e, int fold_const, } /*@=mustfree@*/ +typedef SLIST_HEAD(yasm__exprhead, yasm__exprentry) yasm__exprhead; typedef struct yasm__exprentry { /*@reldef@*/ SLIST_ENTRY(yasm__exprentry) next; /*@null@*/ const yasm_expr *e; } yasm__exprentry; -/* Level an entire expn tree, expanding equ's as we go */ -yasm_expr * -yasm_expr__level_tree(yasm_expr *e, int fold_const, int simplify_ident, - int simplify_reg_mul, int calc_bc_dist, - yasm_expr_xform_func expr_xform_extra, - void *expr_xform_extra_data, yasm__exprhead *eh) +static yasm_expr * +expr_expand_equ(yasm_expr *e, yasm__exprhead *eh) { int i; yasm__exprhead eh_local; yasm__exprentry ee; - if (!e) - return 0; - if (!eh) { eh = &eh_local; SLIST_INIT(eh); } - e = expr_xform_neg(e); - ee.e = NULL; /* traverse terms */ @@ -853,12 +845,9 @@ yasm_expr__level_tree(yasm_expr *e, int fold_const, int simplify_ident, } } + /* Recurse */ if (e->terms[i].type == YASM_EXPR_EXPR) - e->terms[i].data.expn = - yasm_expr__level_tree(e->terms[i].data.expn, fold_const, - simplify_ident, simplify_reg_mul, - calc_bc_dist, expr_xform_extra, - expr_xform_extra_data, eh); + e->terms[i].data.expn = expr_expand_equ(e->terms[i].data.expn, eh); if (ee.e) { SLIST_REMOVE_HEAD(eh, next); @@ -866,6 +855,29 @@ yasm_expr__level_tree(yasm_expr *e, int fold_const, int simplify_ident, } } + return e; +} + +static yasm_expr * +expr_level_tree(yasm_expr *e, int fold_const, int simplify_ident, + int simplify_reg_mul, int calc_bc_dist, + yasm_expr_xform_func expr_xform_extra, + void *expr_xform_extra_data) +{ + int i; + + e = expr_xform_neg(e); + + /* traverse terms */ + for (i=0; inumterms; i++) { + /* Recurse */ + if (e->terms[i].type == YASM_EXPR_EXPR) + e->terms[i].data.expn = + expr_level_tree(e->terms[i].data.expn, fold_const, + simplify_ident, simplify_reg_mul, calc_bc_dist, + expr_xform_extra, expr_xform_extra_data); + } + /* Check for SEG of SEG:OFF, if we match, simplify to just the segment */ if (e->op == YASM_EXPR_SEG && e->terms[0].type == YASM_EXPR_EXPR && e->terms[0].data.expn->op == YASM_EXPR_SEGOFF) { @@ -882,12 +894,29 @@ yasm_expr__level_tree(yasm_expr *e, int fold_const, int simplify_ident, e = expr_xform_bc_dist(e); if (expr_xform_extra) e = expr_xform_extra(e, expr_xform_extra_data); - e = yasm_expr__level_tree(e, fold_const, simplify_ident, - simplify_reg_mul, 0, NULL, NULL, NULL); + e = expr_level_tree(e, fold_const, simplify_ident, simplify_reg_mul, + 0, NULL, NULL); } return e; } +/* Level an entire expn tree, expanding equ's as we go */ +yasm_expr * +yasm_expr__level_tree(yasm_expr *e, int fold_const, int simplify_ident, + int simplify_reg_mul, int calc_bc_dist, + yasm_expr_xform_func expr_xform_extra, + void *expr_xform_extra_data) +{ + if (!e) + return 0; + + e = expr_expand_equ(e, NULL); + e = expr_level_tree(e, fold_const, simplify_ident, simplify_reg_mul, + calc_bc_dist, expr_xform_extra, expr_xform_extra_data); + + return e; +} + /* Comparison function for expr_order_terms(). * Assumes ExprType enum is in canonical order. */ diff --git a/libyasm/expr.h b/libyasm/expr.h index 9c7574fb..1d01e634 100644 --- a/libyasm/expr.h +++ b/libyasm/expr.h @@ -139,15 +139,6 @@ int yasm_expr_is_op(const yasm_expr *e, yasm_expr_op op); typedef /*@only@*/ yasm_expr * (*yasm_expr_xform_func) (/*@returned@*/ /*@only@*/ yasm_expr *e, /*@null@*/ void *d); -/** Linked list of expression entries. - * \internal - * Used internally by yasm_expr__level_tree(). - */ -typedef struct yasm__exprhead yasm__exprhead; -#ifdef YASM_LIB_INTERNAL -SLIST_HEAD(yasm__exprhead, yasm__exprentry); -#endif - /** Level an entire expression tree. * \internal * \param e expression @@ -165,7 +156,7 @@ SLIST_HEAD(yasm__exprhead, yasm__exprentry); (/*@returned@*/ /*@only@*/ /*@null@*/ yasm_expr *e, int fold_const, int simplify_ident, int simplify_reg_mul, int calc_bc_dist, /*@null@*/ yasm_expr_xform_func expr_xform_extra, - /*@null@*/ void *expr_xform_extra_data, /*@null@*/ yasm__exprhead *eh); + /*@null@*/ void *expr_xform_extra_data); /** Simplify an expression as much as possible. Eliminates extraneous * branches and simplifies integer-only subexpressions. Simplified version @@ -175,7 +166,7 @@ SLIST_HEAD(yasm__exprhead, yasm__exprentry); * \return Simplified expression. */ #define yasm_expr_simplify(e, cbd) \ - yasm_expr__level_tree(e, 1, 1, 1, cbd, NULL, NULL, NULL) + yasm_expr__level_tree(e, 1, 1, 1, cbd, NULL, NULL) /** Extract the segment portion of an expression containing SEG:OFF, leaving * the offset. diff --git a/libyasm/tests/Makefile.inc b/libyasm/tests/Makefile.inc index d53e3185..353c3464 100644 --- a/libyasm/tests/Makefile.inc +++ b/libyasm/tests/Makefile.inc @@ -18,6 +18,8 @@ EXTRA_DIST += libyasm/tests/duplabel-err.asm EXTRA_DIST += libyasm/tests/duplabel-err.errwarn EXTRA_DIST += libyasm/tests/emptydata.asm EXTRA_DIST += libyasm/tests/emptydata.hex +EXTRA_DIST += libyasm/tests/equ-expand.asm +EXTRA_DIST += libyasm/tests/equ-expand.hex EXTRA_DIST += libyasm/tests/expr-wide-ident.asm EXTRA_DIST += libyasm/tests/expr-wide-ident.hex EXTRA_DIST += libyasm/tests/externdef.asm diff --git a/libyasm/tests/equ-expand.asm b/libyasm/tests/equ-expand.asm new file mode 100644 index 00000000..eaa94213 --- /dev/null +++ b/libyasm/tests/equ-expand.asm @@ -0,0 +1,9 @@ +nop +end1: + +line_out equ end1+258 ;length = 1 + 263 +real_end equ end1+258+264 + + cmp bx,(real_end-line_out)/4 + cmp bx,((end1+258+264)-(end1+258))/4 + cmp bx,(end1+258+264-end1-258)/4 diff --git a/libyasm/tests/equ-expand.hex b/libyasm/tests/equ-expand.hex new file mode 100644 index 00000000..54a04f3b --- /dev/null +++ b/libyasm/tests/equ-expand.hex @@ -0,0 +1,10 @@ +90 +83 +fb +42 +83 +fb +42 +83 +fb +42 diff --git a/libyasm/value.c b/libyasm/value.c index 6ef16855..84d21243 100644 --- a/libyasm/value.c +++ b/libyasm/value.c @@ -431,8 +431,9 @@ yasm_value_finalize_expr(yasm_value *value, yasm_expr *e, unsigned int size) return 0; } - yasm_value_initialize(value, yasm_expr__level_tree - (e, 1, 1, 0, 0, NULL, NULL, NULL), size); + yasm_value_initialize(value, + yasm_expr__level_tree(e, 1, 1, 0, 0, NULL, NULL), + size); /* quit early if there was an issue in simplify() */ if (yasm_error_occurred()) @@ -473,8 +474,7 @@ yasm_value_finalize_expr(yasm_value *value, yasm_expr *e, unsigned int size) if (value_finalize_scan(value, value->abs, 0)) return 1; - value->abs = yasm_expr__level_tree(value->abs, 1, 1, 0, 0, NULL, NULL, - NULL); + value->abs = yasm_expr__level_tree(value->abs, 1, 1, 0, 0, NULL, NULL); /* Simplify 0 in abs to NULL */ if (value->abs->op == YASM_EXPR_IDENT diff --git a/modules/arch/x86/x86expr.c b/modules/arch/x86/x86expr.c index 2d6b390f..e0dd2141 100644 --- a/modules/arch/x86/x86expr.c +++ b/modules/arch/x86/x86expr.c @@ -259,7 +259,7 @@ x86_expr_checkea_getregusage(yasm_expr **ep, /*@null@*/ int *indexreg, yasm_expr *e, *wrt; /*@-unqualifiedtrans@*/ - *ep = yasm_expr__level_tree(*ep, 1, 1, indexreg == 0, 0, NULL, NULL, NULL); + *ep = yasm_expr__level_tree(*ep, 1, 1, indexreg == 0, 0, NULL, NULL); /* Check for WRT rip first */ wrt = yasm_expr_extract_wrt(ep); @@ -295,7 +295,7 @@ x86_expr_checkea_getregusage(yasm_expr **ep, /*@null@*/ int *indexreg, case 2: /* Need to simplify again */ *ep = yasm_expr__level_tree(*ep, 1, 1, indexreg == 0, 0, NULL, - NULL, NULL); + NULL); e = *ep; break; default: diff --git a/modules/objfmts/bin/bin-objfmt.c b/modules/objfmts/bin/bin-objfmt.c index 17bdfab2..4ed8cde6 100644 --- a/modules/objfmts/bin/bin-objfmt.c +++ b/modules/objfmts/bin/bin-objfmt.c @@ -157,7 +157,7 @@ bin_objfmt_output_value(yasm_value *value, unsigned char *buf, size_t destsize, /* Simplify absolute portion of value, transforming symrecs */ if (value->abs) value->abs = yasm_expr__level_tree - (value->abs, 1, 1, 1, 0, bin_objfmt_expr_xform, NULL, NULL); + (value->abs, 1, 1, 1, 0, bin_objfmt_expr_xform, NULL); /* Output */ switch (yasm_value_output_basic(value, buf, destsize, bc, warn, diff --git a/tools/python-yasm/expr.pxi b/tools/python-yasm/expr.pxi index a33ce687..cdcf37b1 100644 --- a/tools/python-yasm/expr.pxi +++ b/tools/python-yasm/expr.pxi @@ -43,11 +43,10 @@ cdef extern from "libyasm/expr.h": cdef int yasm_expr_is_op(yasm_expr *e, yasm_expr_op op) ctypedef yasm_expr * (*yasm_expr_xform_func) (yasm_expr *e, void *d) - cdef struct yasm__exprhead cdef yasm_expr *yasm_expr__level_tree(yasm_expr *e, int fold_const, int simplify_ident, int simplify_reg_mul, int calc_bc_dist, yasm_expr_xform_func expr_xform_extra, - void *expr_xform_extra_data, yasm__exprhead *eh, int *error) + void *expr_xform_extra_data) cdef yasm_expr *yasm_expr_simplify(yasm_expr *e, int calc_bc_dist) cdef yasm_expr *yasm_expr_extract_segoff(yasm_expr **ep) cdef yasm_expr *yasm_expr_extract_wrt(yasm_expr **ep) -- 2.40.0