/*
 * Expression handling
 *
 *  Copyright (C) 2001-2007  Michael Urman, Peter Johnson
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND OTHER CONTRIBUTORS ``AS IS''
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR OTHER CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */
#include "util.h"
/*@unused@*/ RCSID("$Id: expr.c,v 1.1.1.1 2012/03/29 17:21:04 uid42307 Exp $");

#include "libyasm-stdint.h"
#include "coretype.h"
#include "bitvect.h"

#include "errwarn.h"
#include "intnum.h"
#include "floatnum.h"
#include "expr.h"
#include "symrec.h"

#include "bytecode.h"
#include "section.h"

#include "arch.h"


static int expr_traverse_nodes_post(/*@null@*/ yasm_expr *e,
                                    /*@null@*/ void *d,
                                    int (*func) (/*@null@*/ yasm_expr *e,
                                                 /*@null@*/ void *d));
static void expr_delete_term(yasm_expr__item *term, int recurse);

/* Bitmap of used items.  We should really never need more than 2 at a time,
 * so 31 is pretty much overkill.
 */
static unsigned long itempool_used = 0;
static yasm_expr__item itempool[31];

/* allocate a new expression node, with children as defined.
 * If it's a unary operator, put the element in left and set right=NULL. */
/*@-compmempass@*/
yasm_expr *
yasm_expr_create(yasm_expr_op op, yasm_expr__item *left,
                 yasm_expr__item *right, unsigned long line)
{
    yasm_expr *ptr, *sube;
    unsigned long z;
    ptr = yasm_xmalloc(sizeof(yasm_expr));

    ptr->op = op;
    ptr->numterms = 0;
    ptr->terms[0].type = YASM_EXPR_NONE;
    ptr->terms[1].type = YASM_EXPR_NONE;
    if (left) {
        ptr->terms[0] = *left;  /* structure copy */
        z = (unsigned long)(left-itempool);
        if (z>=31)
            yasm_internal_error(N_("could not find expritem in pool"));
        itempool_used &= ~(1<<z);
        ptr->numterms++;

        /* Search downward until we find something *other* than an
         * IDENT, then bring it up to the current level.
         */
        while (ptr->terms[0].type == YASM_EXPR_EXPR &&
               ptr->terms[0].data.expn->op == YASM_EXPR_IDENT) {
            sube = ptr->terms[0].data.expn;
            ptr->terms[0] = sube->terms[0];     /* structure copy */
            /*@-usereleased@*/
            yasm_xfree(sube);
            /*@=usereleased@*/
        }
    } else {
        yasm_internal_error(N_("Right side of expression must exist"));
    }

    if (right) {
        ptr->terms[1] = *right; /* structure copy */
        z = (unsigned long)(right-itempool);
        if (z>=31)
            yasm_internal_error(N_("could not find expritem in pool"));
        itempool_used &= ~(1<<z);
        ptr->numterms++;

        /* Search downward until we find something *other* than an
         * IDENT, then bring it up to the current level.
         */
        while (ptr->terms[1].type == YASM_EXPR_EXPR &&
               ptr->terms[1].data.expn->op == YASM_EXPR_IDENT) {
            sube = ptr->terms[1].data.expn;
            ptr->terms[1] = sube->terms[0];     /* structure copy */
            /*@-usereleased@*/
            yasm_xfree(sube);
            /*@=usereleased@*/
        }
    }

    ptr->line = line;

    return ptr;
}
/*@=compmempass@*/

/* helpers */
static yasm_expr__item *
expr_get_item(void)
{
    int z = 0;
    unsigned long v = itempool_used & 0x7fffffff;

    while (v & 1) {
        v >>= 1;
        z++;
    }
    if (z>=31)
        yasm_internal_error(N_("too many expritems"));
    itempool_used |= 1<<z;
    return &itempool[z];
}

yasm_expr__item *
yasm_expr_precbc(yasm_bytecode *precbc)
{
    yasm_expr__item *e = expr_get_item();
    e->type = YASM_EXPR_PRECBC;
    e->data.precbc = precbc;
    return e;
}

yasm_expr__item *
yasm_expr_sym(yasm_symrec *s)
{
    yasm_expr__item *e = expr_get_item();
    e->type = YASM_EXPR_SYM;
    e->data.sym = s;
    return e;
}

yasm_expr__item *
yasm_expr_expr(yasm_expr *x)
{
    yasm_expr__item *e = expr_get_item();
    e->type = YASM_EXPR_EXPR;
    e->data.expn = x;
    return e;
}

yasm_expr__item *
yasm_expr_int(yasm_intnum *i)
{
    yasm_expr__item *e = expr_get_item();
    e->type = YASM_EXPR_INT;
    e->data.intn = i;
    return e;
}

yasm_expr__item *
yasm_expr_float(yasm_floatnum *f)
{
    yasm_expr__item *e = expr_get_item();
    e->type = YASM_EXPR_FLOAT;
    e->data.flt = f;
    return e;
}

yasm_expr__item *
yasm_expr_reg(uintptr_t reg)
{
    yasm_expr__item *e = expr_get_item();
    e->type = YASM_EXPR_REG;
    e->data.reg = reg;
    return e;
}

/* Transforms instances of symrec-symrec [symrec+(-1*symrec)] into single
 * expritems if possible.  Uses a simple n^2 algorithm because n is usually
 * quite small.  Also works for precbc-precbc (or symrec-precbc,
 * precbc-symrec).
 */
static /*@only@*/ yasm_expr *
expr_xform_bc_dist_base(/*@returned@*/ /*@only@*/ yasm_expr *e,
                        /*@null@*/ void *cbd,
                        int (*callback) (yasm_expr__item *ei,
                                         yasm_bytecode *precbc,
                                         yasm_bytecode *precbc2,
                                         void *cbd))
{
    int i;
    /*@dependent@*/ yasm_section *sect;
    /*@dependent@*/ /*@null@*/ yasm_bytecode *precbc;
    int numterms;

    /* Handle symrec-symrec in ADD exprs by looking for (-1*symrec) and
     * symrec term pairs (where both symrecs are in the same segment).
     */
    if (e->op != YASM_EXPR_ADD)
        return e;

    for (i=0; i<e->numterms; i++) {
        int j;
        yasm_expr *sube;
        yasm_intnum *intn;
        yasm_symrec *sym = NULL;
        /*@dependent@*/ yasm_section *sect2;
        /*@dependent@*/ /*@null@*/ yasm_bytecode *precbc2;

        /* First look for an (-1*symrec) term */
        if (e->terms[i].type != YASM_EXPR_EXPR)
            continue;
        sube = e->terms[i].data.expn;
        if (sube->op != YASM_EXPR_MUL || sube->numterms != 2)
            continue;

        if (sube->terms[0].type == YASM_EXPR_INT &&
            (sube->terms[1].type == YASM_EXPR_SYM ||
             sube->terms[1].type == YASM_EXPR_PRECBC)) {
            intn = sube->terms[0].data.intn;
            if (sube->terms[1].type == YASM_EXPR_PRECBC)
                precbc = sube->terms[1].data.precbc;
            else
                sym = sube->terms[1].data.sym;
        } else if ((sube->terms[0].type == YASM_EXPR_SYM ||
                    sube->terms[0].type == YASM_EXPR_PRECBC) &&
                   sube->terms[1].type == YASM_EXPR_INT) {
            if (sube->terms[0].type == YASM_EXPR_PRECBC)
                precbc = sube->terms[0].data.precbc;
            else
                sym = sube->terms[0].data.sym;
            intn = sube->terms[1].data.intn;
        } else
            continue;

        if (!yasm_intnum_is_neg1(intn))
            continue;

        if (sym && !yasm_symrec_get_label(sym, &precbc))
            continue;
        sect2 = yasm_bc_get_section(precbc);

        /* Now look for a symrec term in the same segment */
        for (j=0; j<e->numterms; j++) {
            if (((e->terms[j].type == YASM_EXPR_SYM &&
                  yasm_symrec_get_label(e->terms[j].data.sym, &precbc2)) ||
                 (e->terms[j].type == YASM_EXPR_PRECBC &&
                  (precbc2 = e->terms[j].data.precbc))) &&
                (sect = yasm_bc_get_section(precbc2)) &&
                sect == sect2 &&
                callback(&e->terms[j], precbc, precbc2, cbd)) {
                /* Delete the matching (-1*symrec) term */
                yasm_expr_destroy(sube);
                e->terms[i].type = YASM_EXPR_NONE;
                break;  /* stop looking for matching symrec term */
            }
        }
    }

    /* Clean up any deleted (EXPR_NONE) terms */
    numterms = 0;
    for (i=0; i<e->numterms; i++) {
        if (e->terms[i].type != YASM_EXPR_NONE)
            e->terms[numterms++] = e->terms[i]; /* structure copy */
    }
    if (e->numterms != numterms) {
        e->numterms = numterms;
        e = yasm_xrealloc(e, sizeof(yasm_expr)+((numterms<2) ? 0 :
                          sizeof(yasm_expr__item)*(numterms-2)));
        if (numterms == 1)
            e->op = YASM_EXPR_IDENT;
    }

    return e;
}

static int
expr_xform_bc_dist_cb(yasm_expr__item *ei, yasm_bytecode *precbc,
                      yasm_bytecode *precbc2, /*@null@*/ void *d)
{
    yasm_intnum *dist = yasm_calc_bc_dist(precbc, precbc2);
    if (!dist)
        return 0;
    /* Change the term to an integer */
    ei->type = YASM_EXPR_INT;
    ei->data.intn = dist;
    return 1;
}

/* Transforms instances of symrec-symrec [symrec+(-1*symrec)] into integers if
 * possible.
 */
static /*@only@*/ yasm_expr *
expr_xform_bc_dist(/*@returned@*/ /*@only@*/ yasm_expr *e)
{
    return expr_xform_bc_dist_base(e, NULL, expr_xform_bc_dist_cb);
}

typedef struct bc_dist_subst_cbd {
    void (*callback) (unsigned int subst, yasm_bytecode *precbc,
                      yasm_bytecode *precbc2, void *cbd);
    void *cbd;
    unsigned int subst;
} bc_dist_subst_cbd;

static int
expr_bc_dist_subst_cb(yasm_expr__item *ei, yasm_bytecode *precbc,
                      yasm_bytecode *precbc2, /*@null@*/ void *d)
{
    bc_dist_subst_cbd *my_cbd = d;
    assert(my_cbd != NULL);
    /* Call higher-level callback */
    my_cbd->callback(my_cbd->subst, precbc, precbc2, my_cbd->cbd);
    /* Change the term to an subst */
    ei->type = YASM_EXPR_SUBST;
    ei->data.subst = my_cbd->subst;
    my_cbd->subst++;
    return 1;
}

static yasm_expr *
expr_xform_bc_dist_subst(yasm_expr *e, void *d)
{
    return expr_xform_bc_dist_base(e, d, expr_bc_dist_subst_cb);
}

int
yasm_expr__bc_dist_subst(yasm_expr **ep, void *cbd,
                         void (*callback) (unsigned int subst,
                                           yasm_bytecode *precbc,
                                           yasm_bytecode *precbc2,
                                           void *cbd))
{
    bc_dist_subst_cbd my_cbd;   /* callback info for low-level callback */
    my_cbd.callback = callback;
    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);
    return my_cbd.subst;
}

/* Negate just a single ExprItem by building a -1*ei subexpression */
static void
expr_xform_neg_item(yasm_expr *e, yasm_expr__item *ei)
{
    yasm_expr *sube = yasm_xmalloc(sizeof(yasm_expr));

    /* Build -1*ei subexpression */
    sube->op = YASM_EXPR_MUL;
    sube->line = e->line;
    sube->numterms = 2;
    sube->terms[0].type = YASM_EXPR_INT;
    sube->terms[0].data.intn = yasm_intnum_create_int(-1);
    sube->terms[1] = *ei;       /* structure copy */

    /* Replace original ExprItem with subexp */
    ei->type = YASM_EXPR_EXPR;
    ei->data.expn = sube;
}

/* Negates e by multiplying by -1, with distribution over lower-precedence
 * operators (eg ADD) and special handling to simplify result w/ADD, NEG, and
 * others.
 *
 * Returns a possibly reallocated e.
 */
static /*@only@*/ yasm_expr *
expr_xform_neg_helper(/*@returned@*/ /*@only@*/ yasm_expr *e)
{
    yasm_expr *ne;
    int i;

    switch (e->op) {
        case YASM_EXPR_ADD:
            /* distribute (recursively if expr) over terms */
            for (i=0; i<e->numterms; i++) {
                if (e->terms[i].type == YASM_EXPR_EXPR)
                    e->terms[i].data.expn =
                        expr_xform_neg_helper(e->terms[i].data.expn);
                else
                    expr_xform_neg_item(e, &e->terms[i]);
            }
            break;
        case YASM_EXPR_SUB:
            /* change op to ADD, and recursively negate left side (if expr) */
            e->op = YASM_EXPR_ADD;
            if (e->terms[0].type == YASM_EXPR_EXPR)
                e->terms[0].data.expn =
                    expr_xform_neg_helper(e->terms[0].data.expn);
            else
                expr_xform_neg_item(e, &e->terms[0]);
            break;
        case YASM_EXPR_NEG:
            /* Negating a negated value?  Make it an IDENT. */
            e->op = YASM_EXPR_IDENT;
            break;
        case YASM_EXPR_IDENT:
            /* Negating an ident?  Change it into a MUL w/ -1 if there's no
             * floatnums present below; if there ARE floatnums, recurse.
             */
            if (e->terms[0].type == YASM_EXPR_FLOAT)
                yasm_floatnum_calc(e->terms[0].data.flt, YASM_EXPR_NEG, NULL);
            else if (e->terms[0].type == YASM_EXPR_INT)
                yasm_intnum_calc(e->terms[0].data.intn, YASM_EXPR_NEG, NULL);
            else if (e->terms[0].type == YASM_EXPR_EXPR &&
                yasm_expr__contains(e->terms[0].data.expn, YASM_EXPR_FLOAT))
                    expr_xform_neg_helper(e->terms[0].data.expn);
            else {
                e->op = YASM_EXPR_MUL;
                e->numterms = 2;
                e->terms[1].type = YASM_EXPR_INT;
                e->terms[1].data.intn = yasm_intnum_create_int(-1);
            }
            break;
        default:
            /* Everything else.  MUL will be combined when it's leveled.
             * Make a new expr (to replace e) with -1*e.
             */
            ne = yasm_xmalloc(sizeof(yasm_expr));
            ne->op = YASM_EXPR_MUL;
            ne->line = e->line;
            ne->numterms = 2;
            ne->terms[0].type = YASM_EXPR_INT;
            ne->terms[0].data.intn = yasm_intnum_create_int(-1);
            ne->terms[1].type = YASM_EXPR_EXPR;
            ne->terms[1].data.expn = e;
            return ne;
    }
    return e;
}

/* Transforms negatives into expressions that are easier to combine:
 * -x -> -1*x
 * a-b -> a+(-1*b)
 *
 * Call post-order on an expression tree to transform the entire tree.
 *
 * Returns a possibly reallocated e.
 */
static /*@only@*/ yasm_expr *
expr_xform_neg(/*@returned@*/ /*@only@*/ yasm_expr *e)
{
    switch (e->op) {
        case YASM_EXPR_NEG:
            /* Turn -x into -1*x */
            e->op = YASM_EXPR_IDENT;
            return expr_xform_neg_helper(e);
        case YASM_EXPR_SUB:
            /* Turn a-b into a+(-1*b) */

            /* change op to ADD, and recursively negate right side (if expr) */
            e->op = YASM_EXPR_ADD;
            if (e->terms[1].type == YASM_EXPR_EXPR)
                e->terms[1].data.expn =
                    expr_xform_neg_helper(e->terms[1].data.expn);
            else
                expr_xform_neg_item(e, &e->terms[1]);
            break;
        default:
            break;
    }

    return e;
}

/* Look for simple identities that make the entire result constant:
 * 0*&x, -1|x, etc.
 */
static int
expr_is_constant(yasm_expr_op op, yasm_intnum *intn)
{
    int iszero = yasm_intnum_is_zero(intn);
    return ((iszero && op == YASM_EXPR_MUL) ||
            (iszero && op == YASM_EXPR_AND) ||
            (iszero && op == YASM_EXPR_LAND) ||
            (yasm_intnum_is_neg1(intn) && op == YASM_EXPR_OR));
}

/* Look for simple "left" identities like 0+x, 1*x, etc. */
static int
expr_can_destroy_int_left(yasm_expr_op op, yasm_intnum *intn)
{
    int iszero = yasm_intnum_is_zero(intn);
    return ((yasm_intnum_is_pos1(intn) && op == YASM_EXPR_MUL) ||
            (iszero && op == YASM_EXPR_ADD) ||
            (yasm_intnum_is_neg1(intn) && op == YASM_EXPR_AND) ||
            (!iszero && op == YASM_EXPR_LAND) ||
            (iszero && op == YASM_EXPR_OR) ||
            (iszero && op == YASM_EXPR_LOR));
}

/* Look for simple "right" identities like x+|-0, x*&/1 */
static int
expr_can_destroy_int_right(yasm_expr_op op, yasm_intnum *intn)
{
    int iszero = yasm_intnum_is_zero(intn);
    int ispos1 = yasm_intnum_is_pos1(intn);
    return ((ispos1 && op == YASM_EXPR_MUL) ||
            (ispos1 && op == YASM_EXPR_DIV) ||
            (iszero && op == YASM_EXPR_ADD) ||
            (iszero && op == YASM_EXPR_SUB) ||
            (yasm_intnum_is_neg1(intn) && op == YASM_EXPR_AND) ||
            (!iszero && op == YASM_EXPR_LAND) ||
            (iszero && op == YASM_EXPR_OR) ||
            (iszero && op == YASM_EXPR_LOR) ||
            (iszero && op == YASM_EXPR_SHL) ||
            (iszero && op == YASM_EXPR_SHR));
}

/* Check for and simplify identities.  Returns new number of expr terms.
 * Sets e->op = EXPR_IDENT if numterms ends up being 1.
 * Uses numterms parameter instead of e->numterms for basis of "new" number
 * of terms.
 * Assumes int_term is *only* integer term in e.
 * NOTE: Really designed to only be used by expr_level_op().
 */
static int
expr_simplify_identity(yasm_expr *e, int numterms, int int_term,
                       int simplify_reg_mul)
{
    int i;
    int save_numterms;

    /* Don't do this step if it's 1*REG.  Save and restore numterms so
     * yasm_expr__contains() works correctly.
     */
    save_numterms = e->numterms;
    e->numterms = numterms;
    if (simplify_reg_mul || e->op != YASM_EXPR_MUL
        || !yasm_intnum_is_pos1(e->terms[int_term].data.intn)
        || !yasm_expr__contains(e, YASM_EXPR_REG)) {
        /* Check for simple identities that delete the intnum.
         * Don't delete if the intnum is the only thing in the expn.
         */
        if ((int_term == 0 && numterms > 1 &&
             expr_can_destroy_int_left(e->op, e->terms[0].data.intn)) ||
            (int_term > 0 &&
             expr_can_destroy_int_right(e->op, e->terms[int_term].data.intn))) {
            /* Delete the intnum */
            yasm_intnum_destroy(e->terms[int_term].data.intn);

            /* Slide everything to its right over by 1 */
            if (int_term != numterms-1) /* if it wasn't last.. */
                memmove(&e->terms[int_term], &e->terms[int_term+1],
                        (numterms-1-int_term)*sizeof(yasm_expr__item));

            /* Update numterms */
            numterms--;
            int_term = -1;      /* no longer an int term */
        }
    }
    e->numterms = save_numterms;

    /* Check for simple identites that delete everything BUT the intnum.
     * Don't bother if the intnum is the only thing in the expn.
     */
    if (numterms > 1 && int_term != -1 &&
        expr_is_constant(e->op, e->terms[int_term].data.intn)) {
        /* Loop through, deleting everything but the integer term */
        for (i=0; i<e->numterms; i++)
            if (i != int_term)
                expr_delete_term(&e->terms[i], 1);

        /* Move integer term to the first term (if not already there) */
        if (int_term != 0)
            e->terms[0] = e->terms[int_term];   /* structure copy */

        /* Set numterms to 1 */
        numterms = 1;
    }

    /* Compute NOT, NEG, and LNOT on single intnum. */
    if (numterms == 1 && int_term == 0 &&
        (e->op == YASM_EXPR_NOT || e->op == YASM_EXPR_NEG ||
         e->op == YASM_EXPR_LNOT))
        yasm_intnum_calc(e->terms[0].data.intn, e->op, NULL);

    /* Change expression to IDENT if possible. */
    if (numterms == 1)
        e->op = YASM_EXPR_IDENT;

    /* Return the updated numterms */
    return numterms;
}

/* Levels the expression tree starting at e.  Eg:
 * a+(b+c) -> a+b+c
 * (a+b)+(c+d) -> a+b+c+d
 * Naturally, only levels operators that allow more than two operand terms.
 * NOTE: only does *one* level of leveling (no recursion).  Should be called
 *  post-order on a tree to combine deeper levels.
 * Also brings up any IDENT values into the current level (for ALL operators).
 * Folds (combines by evaluation) *integer* constant values if fold_const != 0.
 *
 * Returns a possibly reallocated e.
 */
/*@-mustfree@*/
static /*@only@*/ yasm_expr *
expr_level_op(/*@returned@*/ /*@only@*/ yasm_expr *e, int fold_const,
              int simplify_ident, int simplify_reg_mul)
{
    int i, j, o, fold_numterms, level_numterms, level_fold_numterms;
    int first_int_term = -1;

    /* Determine how many operands will need to be brought up (for leveling).
     * Go ahead and bring up any IDENT'ed values.
     */
    while (e->op == YASM_EXPR_IDENT && e->terms[0].type == YASM_EXPR_EXPR) {
        yasm_expr *sube = e->terms[0].data.expn;
        yasm_xfree(e);
        e = sube;
    }

    /* If non-numeric expression, don't fold constants. */
    if (e->op > YASM_EXPR_NONNUM)
        fold_const = 0;

    level_numterms = e->numterms;
    level_fold_numterms = 0;
    for (i=0; i<e->numterms; i++) {
        /* Search downward until we find something *other* than an
         * IDENT, then bring it up to the current level.
         */
        while (e->terms[i].type == YASM_EXPR_EXPR &&
               e->terms[i].data.expn->op == YASM_EXPR_IDENT) {
            yasm_expr *sube = e->terms[i].data.expn;
            e->terms[i] = sube->terms[0];
            yasm_xfree(sube);
        }

        if (e->terms[i].type == YASM_EXPR_EXPR &&
            e->terms[i].data.expn->op == e->op) {
                /* It's an expression w/the same operator, add in its numterms.
                 * But don't forget to subtract one for the expr itself!
                 */
                level_numterms += e->terms[i].data.expn->numterms - 1;

                /* If we're folding constants, count up the number of constants
                 * that will be merged in.
                 */
                if (fold_const)
                    for (j=0; j<e->terms[i].data.expn->numterms; j++)
                        if (e->terms[i].data.expn->terms[j].type ==
                            YASM_EXPR_INT)
                            level_fold_numterms++;
        }

        /* Find the first integer term (if one is present) if we're folding
         * constants.
         */
        if (fold_const && first_int_term == -1 &&
            e->terms[i].type == YASM_EXPR_INT)
            first_int_term = i;
    }

    /* Look for other integer terms if there's one and combine.
     * Also eliminate empty spaces when combining and adjust numterms
     * variables.
     */
    fold_numterms = e->numterms;
    if (first_int_term != -1) {
        for (i=first_int_term+1, o=first_int_term+1; i<e->numterms; i++) {
            if (e->terms[i].type == YASM_EXPR_INT) {
                yasm_intnum_calc(e->terms[first_int_term].data.intn, e->op,
                                 e->terms[i].data.intn);
                fold_numterms--;
                level_numterms--;
                /* make sure to delete folded intnum */
                yasm_intnum_destroy(e->terms[i].data.intn);
            } else if (o != i) {
                /* copy term if it changed places */
                e->terms[o++] = e->terms[i];
            } else
                o++;
        }

        if (simplify_ident) {
            int new_fold_numterms;
            /* Simplify identities and make IDENT if possible. */
            new_fold_numterms =
                expr_simplify_identity(e, fold_numterms, first_int_term,
                                       simplify_reg_mul);
            level_numterms -= fold_numterms-new_fold_numterms;
            fold_numterms = new_fold_numterms;
        }
        if (fold_numterms == 1)
            e->op = YASM_EXPR_IDENT;
    }

    /* Only level operators that allow more than two operand terms.
     * Also don't bother leveling if it's not necessary to bring up any terms.
     */
    if ((e->op != YASM_EXPR_ADD && e->op != YASM_EXPR_MUL &&
         e->op != YASM_EXPR_OR && e->op != YASM_EXPR_AND &&
         e->op != YASM_EXPR_LOR && e->op != YASM_EXPR_LAND &&
         e->op != YASM_EXPR_LXOR && e->op != YASM_EXPR_XOR) ||
        level_numterms <= fold_numterms) {
        /* Downsize e if necessary */
        if (fold_numterms < e->numterms && e->numterms > 2)
            e = yasm_xrealloc(e, sizeof(yasm_expr)+((fold_numterms<2) ? 0 :
                              sizeof(yasm_expr__item)*(fold_numterms-2)));
        /* Update numterms */
        e->numterms = fold_numterms;
        return e;
    }

    /* Adjust numterms for constant folding from terms being "pulled up".
     * Careful: if there's no integer term in e, then save space for it.
     */
    if (fold_const) {
        level_numterms -= level_fold_numterms;
        if (first_int_term == -1 && level_fold_numterms != 0)
            level_numterms++;
    }

    /* Alloc more (or conceivably less, but not usually) space for e */
    e = yasm_xrealloc(e, sizeof(yasm_expr)+((level_numterms<2) ? 0 :
                      sizeof(yasm_expr__item)*(level_numterms-2)));

    /* Copy up ExprItem's.  Iterate from right to left to keep the same
     * ordering as was present originally.
     * Combine integer terms as necessary.
     */
    for (i=e->numterms-1, o=level_numterms-1; i>=0; i--) {
        if (e->terms[i].type == YASM_EXPR_EXPR &&
            e->terms[i].data.expn->op == e->op) {
            /* bring up subexpression */
            yasm_expr *sube = e->terms[i].data.expn;

            /* copy terms right to left */
            for (j=sube->numterms-1; j>=0; j--) {
                if (fold_const && sube->terms[j].type == YASM_EXPR_INT) {
                    /* Need to fold it in.. but if there's no int term already,
                     * just copy into a new one.
                     */
                    if (first_int_term == -1) {
                        first_int_term = o--;
                        e->terms[first_int_term] = sube->terms[j];  /* struc */
                    } else {
                        yasm_intnum_calc(e->terms[first_int_term].data.intn,
                                         e->op, sube->terms[j].data.intn);
                        /* make sure to delete folded intnum */
                        yasm_intnum_destroy(sube->terms[j].data.intn);
                    }
                } else {
                    if (o == first_int_term)
                        o--;
                    e->terms[o--] = sube->terms[j];     /* structure copy */
                }
            }

            /* delete subexpression, but *don't delete nodes* (as we've just
             * copied them!)
             */
            yasm_xfree(sube);
        } else if (o != i) {
            /* copy operand if it changed places */
            if (o == first_int_term)
                o--;
            e->terms[o] = e->terms[i];
            /* If we moved the first_int_term, change first_int_num too */
            if (i == first_int_term)
                first_int_term = o;
            o--;
        }
    }

    /* Simplify identities, make IDENT if possible, and save to e->numterms. */
    if (simplify_ident && first_int_term != -1) {
        e->numterms = expr_simplify_identity(e, level_numterms,
                                             first_int_term, simplify_reg_mul);
    } else {
        e->numterms = level_numterms;
        if (level_numterms == 1)
            e->op = YASM_EXPR_IDENT;
    }

    return e;
}
/*@=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;

static yasm_expr *
expr_expand_equ(yasm_expr *e, yasm__exprhead *eh)
{
    int i;
    yasm__exprentry ee;

    /* traverse terms */
    for (i=0; i<e->numterms; i++) {
        const yasm_expr *equ_expr;

        /* Expand equ's. */
        if (e->terms[i].type == YASM_EXPR_SYM &&
            (equ_expr = yasm_symrec_get_equ(e->terms[i].data.sym))) {
            yasm__exprentry *np;

            /* Check for circular reference */
            SLIST_FOREACH(np, eh, next) {
                if (np->e == equ_expr) {
                    yasm_error_set(YASM_ERROR_TOO_COMPLEX,
                                   N_("circular reference detected"));
                    return e;
                }
            }

            e->terms[i].type = YASM_EXPR_EXPR;
            e->terms[i].data.expn = yasm_expr_copy(equ_expr);

            /* Remember we saw this equ and recurse */
            ee.e = equ_expr;
            SLIST_INSERT_HEAD(eh, &ee, next);
            e->terms[i].data.expn = expr_expand_equ(e->terms[i].data.expn, eh);
            SLIST_REMOVE_HEAD(eh, next);
        } else if (e->terms[i].type == YASM_EXPR_EXPR)
            /* Recurse */
            e->terms[i].data.expn = expr_expand_equ(e->terms[i].data.expn, eh);
    }

    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) {
        e->op = YASM_EXPR_IDENT;
        e->terms[0].data.expn->op = YASM_EXPR_IDENT;
        /* Destroy the second (offset) term */
        e->terms[0].data.expn->numterms = 1;
        expr_delete_term(&e->terms[0].data.expn->terms[1], 1);
    }

    /* do callback */
    e = expr_level_op(e, fold_const, simplify_ident, simplify_reg_mul);
    if (calc_bc_dist || expr_xform_extra) {
        if (calc_bc_dist)
            e = expr_xform_bc_dist(e);
        if (expr_xform_extra)
            e = expr_xform_extra(e, expr_xform_extra_data);
        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)
{
    yasm__exprhead eh;
    SLIST_INIT(&eh);

    if (!e)
        return 0;

    e = expr_expand_equ(e, &eh);
    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.
 */
static int
expr_order_terms_compare(const void *va, const void *vb)
{
    const yasm_expr__item *a = va, *b = vb;
    return (a->type - b->type);
}

/* Reorder terms of e into canonical order.  Only reorders if reordering
 * doesn't change meaning of expression.  (eg, doesn't reorder SUB).
 * Canonical order: REG, INT, FLOAT, SYM, EXPR.
 * Multiple terms of a single type are kept in the same order as in
 * the original expression.
 * NOTE: Only performs reordering on *one* level (no recursion).
 */
void
yasm_expr__order_terms(yasm_expr *e)
{
    /* don't bother reordering if only one element */
    if (e->numterms == 1)
        return;

    /* only reorder some types of operations */
    switch (e->op) {
        case YASM_EXPR_ADD:
        case YASM_EXPR_MUL:
        case YASM_EXPR_OR:
        case YASM_EXPR_AND:
        case YASM_EXPR_XOR:
        case YASM_EXPR_LOR:
        case YASM_EXPR_LAND:
        case YASM_EXPR_LXOR:
            /* Use mergesort to sort.  It's fast on already sorted values and a
             * stable sort (multiple terms of same type are kept in the same
             * order).
             */
            yasm__mergesort(e->terms, (size_t)e->numterms,
                            sizeof(yasm_expr__item), expr_order_terms_compare);
            break;
        default:
            break;
    }
}

static void
expr_item_copy(yasm_expr__item *dest, const yasm_expr__item *src)
{
    dest->type = src->type;
    switch (src->type) {
        case YASM_EXPR_SYM:
            /* Symbols don't need to be copied */
            dest->data.sym = src->data.sym;
            break;
        case YASM_EXPR_PRECBC:
            /* Nor do direct bytecode references */
            dest->data.precbc = src->data.precbc;
            break;
        case YASM_EXPR_EXPR:
            dest->data.expn = yasm_expr__copy_except(src->data.expn, -1);
            break;
        case YASM_EXPR_INT:
            dest->data.intn = yasm_intnum_copy(src->data.intn);
            break;
        case YASM_EXPR_FLOAT:
            dest->data.flt = yasm_floatnum_copy(src->data.flt);
            break;
        case YASM_EXPR_REG:
            dest->data.reg = src->data.reg;
            break;
        case YASM_EXPR_SUBST:
            dest->data.subst = src->data.subst;
            break;
        default:
            break;
    }
}

/* Copy entire expression EXCEPT for index "except" at *top level only*. */
yasm_expr *
yasm_expr__copy_except(const yasm_expr *e, int except)
{
    yasm_expr *n;
    int i;
    
    n = yasm_xmalloc(sizeof(yasm_expr) +
                     sizeof(yasm_expr__item)*(e->numterms<2?0:e->numterms-2));

    n->op = e->op;
    n->line = e->line;
    n->numterms = e->numterms;
    for (i=0; i<e->numterms; i++) {
        if (i != except)
            expr_item_copy(&n->terms[i], &e->terms[i]);
    }

    return n;
}

static void
expr_delete_term(yasm_expr__item *term, int recurse)
{
    switch (term->type) {
        case YASM_EXPR_INT:
            yasm_intnum_destroy(term->data.intn);
            break;
        case YASM_EXPR_FLOAT:
            yasm_floatnum_destroy(term->data.flt);
            break;
        case YASM_EXPR_EXPR:
            if (recurse)
                yasm_expr_destroy(term->data.expn);
            break;
        default:
            break;
    }
}

static int
expr_destroy_each(/*@only@*/ yasm_expr *e, /*@unused@*/ void *d)
{
    int i;
    for (i=0; i<e->numterms; i++)
        expr_delete_term(&e->terms[i], 0);
    yasm_xfree(e);      /* free ourselves */
    return 0;   /* don't stop recursion */
}

/*@-mustfree@*/
void
yasm_expr_destroy(yasm_expr *e)
{
    expr_traverse_nodes_post(e, NULL, expr_destroy_each);
}
/*@=mustfree@*/

int
yasm_expr_is_op(const yasm_expr *e, yasm_expr_op op)
{
    return (e->op == op);
}

static int
expr_contains_callback(const yasm_expr__item *ei, void *d)
{
    yasm_expr__type *t = d;
    return (ei->type & *t);
}

int
yasm_expr__contains(const yasm_expr *e, yasm_expr__type t)
{
    return yasm_expr__traverse_leaves_in_const(e, &t, expr_contains_callback);
}

typedef struct subst_cbd {
    unsigned int num_items;
    const yasm_expr__item *items;
} subst_cbd;

static int
expr_subst_callback(yasm_expr__item *ei, void *d)
{
    subst_cbd *cbd = d;
    if (ei->type != YASM_EXPR_SUBST)
        return 0;
    if (ei->data.subst >= cbd->num_items)
        return 1;   /* error */
    expr_item_copy(ei, &cbd->items[ei->data.subst]);
    return 0;
}

int
yasm_expr__subst(yasm_expr *e, unsigned int num_items,
                 const yasm_expr__item *items)
{
    subst_cbd cbd;
    cbd.num_items = num_items;
    cbd.items = items;
    return yasm_expr__traverse_leaves_in(e, &cbd, expr_subst_callback);
}

/* Traverse over expression tree, calling func for each operation AFTER the
 * branches (if expressions) have been traversed (eg, postorder
 * traversal).  The data pointer d is passed to each func call.
 *
 * Stops early (and returns 1) if func returns 1.  Otherwise returns 0.
 */
static int
expr_traverse_nodes_post(yasm_expr *e, void *d,
                         int (*func) (/*@null@*/ yasm_expr *e,
                                      /*@null@*/ void *d))
{
    int i;

    if (!e)
        return 0;

    /* traverse terms */
    for (i=0; i<e->numterms; i++) {
        if (e->terms[i].type == YASM_EXPR_EXPR &&
            expr_traverse_nodes_post(e->terms[i].data.expn, d, func))
            return 1;
    }

    /* do callback */
    return func(e, d);
}

/* Traverse over expression tree in order, calling func for each leaf
 * (non-operation).  The data pointer d is passed to each func call.
 *
 * Stops early (and returns 1) if func returns 1.  Otherwise returns 0.
 */
int
yasm_expr__traverse_leaves_in_const(const yasm_expr *e, void *d,
    int (*func) (/*@null@*/ const yasm_expr__item *ei, /*@null@*/ void *d))
{
    int i;

    if (!e)
        return 0;

    for (i=0; i<e->numterms; i++) {
        if (e->terms[i].type == YASM_EXPR_EXPR) {
            if (yasm_expr__traverse_leaves_in_const(e->terms[i].data.expn, d,
                                                    func))
                return 1;
        } else {
            if (func(&e->terms[i], d))
                return 1;
        }
    }
    return 0;
}

/* Traverse over expression tree in order, calling func for each leaf
 * (non-operation).  The data pointer d is passed to each func call.
 *
 * Stops early (and returns 1) if func returns 1.  Otherwise returns 0.
 */
int
yasm_expr__traverse_leaves_in(yasm_expr *e, void *d,
    int (*func) (/*@null@*/ yasm_expr__item *ei, /*@null@*/ void *d))
{
    int i;

    if (!e)
        return 0;

    for (i=0; i<e->numterms; i++) {
        if (e->terms[i].type == YASM_EXPR_EXPR) {
            if (yasm_expr__traverse_leaves_in(e->terms[i].data.expn, d, func))
                return 1;
        } else {
            if (func(&e->terms[i], d))
                return 1;
        }
    }
    return 0;
}

yasm_expr *
yasm_expr_extract_deep_segoff(yasm_expr **ep)
{
    yasm_expr *retval;
    yasm_expr *e = *ep;
    int i;

    /* Try to extract at this level */
    retval = yasm_expr_extract_segoff(ep);
    if (retval)
        return retval;

    /* Not at this level?  Search any expr children. */
    for (i=0; i<e->numterms; i++) {
        if (e->terms[i].type == YASM_EXPR_EXPR) {
            retval = yasm_expr_extract_deep_segoff(&e->terms[i].data.expn);
            if (retval)
                return retval;
        }
    }

    /* Didn't find one */
    return NULL;
}

yasm_expr *
yasm_expr_extract_segoff(yasm_expr **ep)
{
    yasm_expr *retval;
    yasm_expr *e = *ep;

    /* If not SEG:OFF, we can't do this transformation */
    if (e->op != YASM_EXPR_SEGOFF)
        return NULL;

    /* Extract the SEG portion out to its own expression */
    if (e->terms[0].type == YASM_EXPR_EXPR)
        retval = e->terms[0].data.expn;
    else {
        /* Need to build IDENT expression to hold non-expression contents */
        retval = yasm_xmalloc(sizeof(yasm_expr));
        retval->op = YASM_EXPR_IDENT;
        retval->numterms = 1;
        retval->terms[0] = e->terms[0]; /* structure copy */
    }

    /* Delete the SEG: portion by changing the expression into an IDENT */
    e->op = YASM_EXPR_IDENT;
    e->numterms = 1;
    e->terms[0] = e->terms[1];  /* structure copy */

    return retval;
}

yasm_expr *
yasm_expr_extract_wrt(yasm_expr **ep)
{
    yasm_expr *retval;
    yasm_expr *e = *ep;

    /* If not WRT, we can't do this transformation */
    if (e->op != YASM_EXPR_WRT)
        return NULL;

    /* Extract the right side portion out to its own expression */
    if (e->terms[1].type == YASM_EXPR_EXPR)
        retval = e->terms[1].data.expn;
    else {
        /* Need to build IDENT expression to hold non-expression contents */
        retval = yasm_xmalloc(sizeof(yasm_expr));
        retval->op = YASM_EXPR_IDENT;
        retval->numterms = 1;
        retval->terms[0] = e->terms[1]; /* structure copy */
    }

    /* Delete the right side portion by changing the expr into an IDENT */
    e->op = YASM_EXPR_IDENT;
    e->numterms = 1;

    return retval;
}

/*@-unqualifiedtrans -nullderef -nullstate -onlytrans@*/
yasm_intnum *
yasm_expr_get_intnum(yasm_expr **ep, int calc_bc_dist)
{
    *ep = yasm_expr_simplify(*ep, calc_bc_dist);

    if ((*ep)->op == YASM_EXPR_IDENT && (*ep)->terms[0].type == YASM_EXPR_INT)
        return (*ep)->terms[0].data.intn;
    else
        return (yasm_intnum *)NULL;
}
/*@=unqualifiedtrans =nullderef -nullstate -onlytrans@*/

/*@-unqualifiedtrans -nullderef -nullstate -onlytrans@*/
const yasm_symrec *
yasm_expr_get_symrec(yasm_expr **ep, int simplify)
{
    if (simplify)
        *ep = yasm_expr_simplify(*ep, 0);

    if ((*ep)->op == YASM_EXPR_IDENT && (*ep)->terms[0].type == YASM_EXPR_SYM)
        return (*ep)->terms[0].data.sym;
    else
        return (yasm_symrec *)NULL;
}
/*@=unqualifiedtrans =nullderef -nullstate -onlytrans@*/

/*@-unqualifiedtrans -nullderef -nullstate -onlytrans@*/
const uintptr_t *
yasm_expr_get_reg(yasm_expr **ep, int simplify)
{
    if (simplify)
        *ep = yasm_expr_simplify(*ep, 0);

    if ((*ep)->op == YASM_EXPR_IDENT && (*ep)->terms[0].type == YASM_EXPR_REG)
        return &((*ep)->terms[0].data.reg);
    else
        return NULL;
}
/*@=unqualifiedtrans =nullderef -nullstate -onlytrans@*/

void
yasm_expr_print(const yasm_expr *e, FILE *f)
{
    char opstr[8];
    int i;

    if (!e) {
        fprintf(f, "(nil)");
        return;
    }

    switch (e->op) {
        case YASM_EXPR_ADD:
            strcpy(opstr, "+");
            break;
        case YASM_EXPR_SUB:
            strcpy(opstr, "-");
            break;
        case YASM_EXPR_MUL:
            strcpy(opstr, "*");
            break;
        case YASM_EXPR_DIV:
            strcpy(opstr, "/");
            break;
        case YASM_EXPR_SIGNDIV:
            strcpy(opstr, "//");
            break;
        case YASM_EXPR_MOD:
            strcpy(opstr, "%");
            break;
        case YASM_EXPR_SIGNMOD:
            strcpy(opstr, "%%");
            break;
        case YASM_EXPR_NEG:
            fprintf(f, "-");
            opstr[0] = 0;
            break;
        case YASM_EXPR_NOT:
            fprintf(f, "~");
            opstr[0] = 0;
            break;
        case YASM_EXPR_OR:
            strcpy(opstr, "|");
            break;
        case YASM_EXPR_AND:
            strcpy(opstr, "&");
            break;
        case YASM_EXPR_XOR:
            strcpy(opstr, "^");
            break;
        case YASM_EXPR_XNOR:
            strcpy(opstr, "XNOR");
            break;
        case YASM_EXPR_NOR:
            strcpy(opstr, "NOR");
            break;
        case YASM_EXPR_SHL:
            strcpy(opstr, "<<");
            break;
        case YASM_EXPR_SHR:
            strcpy(opstr, ">>");
            break;
        case YASM_EXPR_LOR:
            strcpy(opstr, "||");
            break;
        case YASM_EXPR_LAND:
            strcpy(opstr, "&&");
            break;
        case YASM_EXPR_LNOT:
            strcpy(opstr, "!");
            break;
        case YASM_EXPR_LXOR:
            strcpy(opstr, "^^");
            break;
        case YASM_EXPR_LXNOR:
            strcpy(opstr, "LXNOR");
            break;
        case YASM_EXPR_LNOR:
            strcpy(opstr, "LNOR");
            break;
        case YASM_EXPR_LT:
            strcpy(opstr, "<");
            break;
        case YASM_EXPR_GT:
            strcpy(opstr, ">");
            break;
        case YASM_EXPR_LE:
            strcpy(opstr, "<=");
            break;
        case YASM_EXPR_GE:
            strcpy(opstr, ">=");
            break;
        case YASM_EXPR_NE:
            strcpy(opstr, "!=");
            break;
        case YASM_EXPR_EQ:
            strcpy(opstr, "==");
            break;
        case YASM_EXPR_SEG:
            fprintf(f, "SEG ");
            opstr[0] = 0;
            break;
        case YASM_EXPR_WRT:
            strcpy(opstr, " WRT ");
            break;
        case YASM_EXPR_SEGOFF:
            strcpy(opstr, ":");
            break;
        case YASM_EXPR_IDENT:
            opstr[0] = 0;
            break;
        default:
            strcpy(opstr, " !UNK! ");
            break;
    }
    for (i=0; i<e->numterms; i++) {
        switch (e->terms[i].type) {
            case YASM_EXPR_PRECBC:
                fprintf(f, "{%lx}",
                        yasm_bc_next_offset(e->terms[i].data.precbc));
                break;
            case YASM_EXPR_SYM:
                fprintf(f, "%s", yasm_symrec_get_name(e->terms[i].data.sym));
                break;
            case YASM_EXPR_EXPR:
                fprintf(f, "(");
                yasm_expr_print(e->terms[i].data.expn, f);
                fprintf(f, ")");
                break;
            case YASM_EXPR_INT:
                yasm_intnum_print(e->terms[i].data.intn, f);
                break;
            case YASM_EXPR_FLOAT:
                yasm_floatnum_print(e->terms[i].data.flt, f);
                break;
            case YASM_EXPR_REG:
                /* FIXME */
                /*yasm_arch_reg_print(arch, e->terms[i].data.reg, f);*/
                break;
            case YASM_EXPR_SUBST:
                fprintf(f, "[%u]", e->terms[i].data.subst);
                break;
            case YASM_EXPR_NONE:
                break;
        }
        if (i < e->numterms-1)
            fprintf(f, "%s", opstr);
    }
}
