]> granicus.if.org Git - yasm/commitdiff
Don't mix EQU expansion with other expr leveling; we could get confused
authorPeter Johnson <peter@tortall.net>
Wed, 18 Oct 2006 05:36:51 +0000 (05:36 -0000)
committerPeter Johnson <peter@tortall.net>
Wed, 18 Oct 2006 05:36:51 +0000 (05:36 -0000)
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
libyasm/expr.c
libyasm/expr.h
libyasm/tests/Makefile.inc
libyasm/tests/equ-expand.asm [new file with mode: 0644]
libyasm/tests/equ-expand.hex [new file with mode: 0644]
libyasm/value.c
modules/arch/x86/x86expr.c
modules/objfmts/bin/bin-objfmt.c
tools/python-yasm/expr.pxi

index 6e63e311754cfa8c2012e80c0bcafd735933ad32..d6dafb226faa8ba1735e7b052c5eda773da68ec3 100644 (file)
@@ -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 */
index 6439846bae2af0932352053c09a3822bbac8b9f8..f5892989bb3b85ded9babeaaa66e24c346b0f6ab 100644 (file)
@@ -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; i<e->numterms; 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.
  */
index 9c7574fb00b000b43da5347b3be919caa5ed1ae3..1d01e634ae63b15658058ae64c93054c6360f7e6 100644 (file)
@@ -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.
index d53e3185ef3c7b274c82881ee2f7a0b923b9336a..353c3464464e6b916873ffed9c705c120f77f92b 100644 (file)
@@ -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 (file)
index 0000000..eaa9421
--- /dev/null
@@ -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 (file)
index 0000000..54a04f3
--- /dev/null
@@ -0,0 +1,10 @@
+90 
+83 
+fb 
+42 
+83 
+fb 
+42 
+83 
+fb 
+42 
index 6ef16855581064afc396932caca03bf7d812829a..84d2124307fdb2f2150bbf46ce2b61f551a3654c 100644 (file)
@@ -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
index 2d6b390f864f1d21fd36e7a30194145ab1bd5374..e0dd21412b532b3db6cced78b2cc764114cca6ae 100644 (file)
@@ -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:
index 17bdfab2184d3661c932ec565931f158f49b69a8..4ed8cde6c0a4bb0b5773e62f9aa1474980913626 100644 (file)
@@ -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,
index a33ce6874ec96ce5c538c55989488c0092a83243..cdcf37b1237d0857cda2264d551bfd7c43fcdf1f 100644 (file)
@@ -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)