Exemplo n.º 1
0
int expr_is_constant(struct expr *e){
	if(!e) return 1; //null is a constant expression
	if(expr_is_constant(e->left) == 0) return 0;
	if(expr_is_constant(e->right) == 0) return 0;

	if(e->kind == EXPR_IDENT) return 0;
	else return 1;
}
Exemplo n.º 2
0
int expr_is_constant(struct expr *e)
{
    if (!e)
        return 1;
    if (e->kind == EXPR_VARIABLE
            || e->kind == EXPR_INCR
            || e->kind == EXPR_DECR
            || e->kind == EXPR_FUNCTION_CALL)
        return 0;

    return (expr_is_constant(e->left) && expr_is_constant(e->right));
}
Exemplo n.º 3
0
/* 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;
}