/* * xfold will remove constant nodes and return the values to * the calling routines. */ __int64 xfold(ENODE *node) { __int64 i; if( node == NULL ) return 0; switch( node->nodetype ) { case en_icon: i = node->i; node->i = 0; return i; case en_add: return xfold(node->p[0]) + xfold(node->p[1]); case en_sub: return xfold(node->p[0]) - xfold(node->p[1]); case en_mul: case en_mulu: if( node->p[0]->nodetype == en_icon ) return xfold(node->p[1]) * node->p[0]->i; else if( node->p[1]->nodetype == en_icon ) return xfold(node->p[0]) * node->p[1]->i; else return 0; case en_shl: if( node->p[0]->nodetype == en_icon ) return xfold(node->p[1]) << node->p[0]->i; else if( node->p[1]->nodetype == en_icon ) return xfold(node->p[0]) << node->p[1]->i; else return 0; case en_uminus: return - xfold(node->p[0]); case en_shr: case en_div: case en_udiv: case en_shru: case en_mod: case en_asadd: case en_assub: case en_asmul: case en_asdiv: case en_asmod: case en_and: case en_land: case en_or: case en_lor: case en_xor: case en_asand: case en_asor: case en_void: case en_fcall: case en_assign: fold_const(&node->p[0]); fold_const(&node->p[1]); return 0; case en_ub_ref: case en_uw_ref: case en_uc_ref: case en_uh_ref: case en_b_ref: case en_w_ref: case en_c_ref: case en_h_ref: case en_compl: case en_not: fold_const(&node->p[0]); return 0; } return 0; }
/* * reorganize an expression for optimal constant grouping. */ static void fold_const(ENODE **node) { ENODE *ep; int64_t i; ep = *node; if( ep == 0 ) return; if( ep->nodetype == en_add ) { if( ep->p[0]->nodetype == en_icon ) { ep->p[0]->i += xfold(ep->p[1]); return; } else if( ep->p[1]->nodetype == en_icon ) { ep->p[1]->i += xfold(ep->p[0]); return; } } else if( ep->nodetype == en_sub ) { if( ep->p[0]->nodetype == en_icon ) { ep->p[0]->i -= xfold(ep->p[1]); return; } else if( ep->p[1]->nodetype == en_icon ) { ep->p[1]->i -= xfold(ep->p[0]); // ??? other order ??? xfold - p[1] return; } } i = xfold(ep); if( i != 0 ) { ep = makeinode(en_icon,i); ep->etype = (*node)->etype; ep->tp = (*node)->tp; ep = makenode(en_add,ep,*node); ep->etype = (*node)->etype; ep->tp = (*node)->tp; *node = ep; } }
/* * reorganize an expression for optimal constant grouping. */ void fold_const(ENODE **node) { ENODE *ep; __int64 i; ep = *node; if( ep == 0 ) return; if( ep->nodetype == en_add ) { if( ep->p[0]->nodetype == en_icon ) { ep->p[0]->i += xfold(ep->p[1]); return; } else if( ep->p[1]->nodetype == en_icon ) { ep->p[1]->i += xfold(ep->p[0]); return; } } else if( ep->nodetype == en_sub ) { if( ep->p[0]->nodetype == en_icon ) { ep->p[0]->i -= xfold(ep->p[1]); return; } else if( ep->p[1]->nodetype == en_icon ) { ep->p[1]->i -= xfold(ep->p[0]); return; } } i = xfold(ep); if( i != 0 ) { ep = makeinode(en_icon,i); ep = makenode(en_add,ep,*node); *node = ep; } }
/* * xfold will remove constant nodes and return the values to * the calling routines. */ static int64_t xfold(ENODE *node) { int64_t i; if( node == NULL ) return 0; switch( node->nodetype ) { case en_icon: i = node->i; node->i = 0; return i; case en_sxb: case en_sxc: case en_sxh: case en_zxb: case en_zxc: case en_zxh: case en_abs: case en_isnullptr: return (0); return xfold(node->p[0]); case en_add: return xfold(node->p[0]) + xfold(node->p[1]); case en_sub: return xfold(node->p[0]) - xfold(node->p[1]); case en_mulf: case en_mul: case en_mulu: return (0); if( node->p[0]->nodetype == en_icon ) return xfold(node->p[1]) * node->p[0]->i; else if( node->p[1]->nodetype == en_icon ) return xfold(node->p[0]) * node->p[1]->i; else return 0; case en_asl: case en_shl: case en_shlu: if( node->p[0]->nodetype == en_icon ) return xfold(node->p[1]) << node->p[0]->i; else if( node->p[1]->nodetype == en_icon ) return xfold(node->p[0]) << node->p[1]->i; else return 0; case en_uminus: return - xfold(node->p[0]); case en_shr: case en_div: case en_udiv: case en_shru: case en_asr: case en_mod: case en_asadd: case en_assub: case en_asmul: case en_asdiv: case en_asmod: case en_and: case en_land: case en_land_safe: case en_or: case en_lor: case en_lor_safe: case en_xor: case en_asand: case en_asor: case en_void: case en_fcall: case en_assign: fold_const(&node->p[0]); fold_const(&node->p[1]); return 0; case en_ref32: case en_ref32u: case en_ub_ref: case en_uw_ref: case en_uc_ref: case en_uh_ref: case en_b_ref: case en_w_ref: case en_c_ref: case en_h_ref: case en_wp_ref: case en_hp_ref: case en_vector_ref: case en_compl: case en_not: fold_const(&node->p[0]); return 0; } return 0; }