/*
 * 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$");

#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 /*@only@*/ yasm_expr *expr_level_op
    (/*@returned@*/ /*@only@*/ yasm_expr *e, int fold_const,
     int simplify_ident, int simplify_reg_mul);
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 expr_level_op(ptr, 1, 1, 0);
}
/*@=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=fold_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--;
        } else
            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);
    }
}

unsigned int
yasm_expr_size(const yasm_expr *e)
{
    int i;
    int seen = 0;
    unsigned int size = 0, newsize;

    if (e->op == YASM_EXPR_IDENT) {
        if (e->terms[0].type == YASM_EXPR_SYM)
            return yasm_symrec_get_size(e->terms[0].data.sym);
        return 0;
    }
    if (e->op != YASM_EXPR_ADD && e->op != YASM_EXPR_SUB)
        return 0;

    for (i=0; i<e->numterms; i++) {
        newsize = 0;
        switch (e->terms[i].type) {
        case YASM_EXPR_EXPR:
            newsize = yasm_expr_size(e->terms[i].data.expn);
            break;
        case YASM_EXPR_SYM:
            newsize = yasm_symrec_get_size(e->terms[i].data.sym);
            break;
        default:
            break;
        }
        if (newsize) {
            size = newsize;
            if (seen)
                /* either sum of idents (?!) or substract of idents */
                return 0;
            seen = 1;
        }
    }
    /* exactly one offset */
    return size;
}

const char *
yasm_expr_segment(const yasm_expr *e)
{
    int i;
    int seen = 0;
    const char *segment = NULL;

    if (e->op == YASM_EXPR_IDENT) {
        if (e->terms[0].type == YASM_EXPR_SYM)
            return yasm_symrec_get_segment(e->terms[0].data.sym);
        return NULL;
    }
    if (e->op != YASM_EXPR_ADD && e->op != YASM_EXPR_SUB)
        return NULL;

    for (i=0; i<e->numterms; i++) {
        if ((e->op == YASM_EXPR_ADD || !i) &&
                e->terms[i].type == YASM_EXPR_EXPR) {
            if ((segment = yasm_expr_segment(e->terms[i].data.expn))) {
                if (seen) {
                    /* either sum of idents (?!) or substract of idents */
                    return NULL;
                }
                seen = 1;
            }
        }
    }
    /* exactly one offset */
    return segment;
}
