⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 optimize.c

📁 CC386 is a general-purpose 32-bit C compiler. It is not an optimizing compiler but given that the co
💻 C
📖 第 1 页 / 共 5 页
字号:
            break;
        case en_and:
            ep->nodetype = maxinttype(ep1, ep2);
            ep->v.i = ep1->v.i &ep2->v.i;
            ep->v.i = reint(ep);
            break;
        case en_or:
            ep->nodetype = maxinttype(ep1, ep2);
            ep->v.i = ep1->v.i | ep2->v.i;
            ep->v.i = reint(ep);
            break;
        case en_xor:
            ep->nodetype = maxinttype(ep1, ep2);
            ep->v.i = ep1->v.i ^ ep2->v.i;
            ep->v.i = reint(ep);
            break;
    }
}

int pwrof2(LLONG_TYPE i)
/*
 *      return which power of two i is or -1.
 */
{
	if (i > 1) 
	{
	    int top = sizeof(shifts)/sizeof(LLONG_TYPE);
    	int bottom =  - 1;
    	while (top - bottom > 1)
    	{
        	int mid = (top + bottom) / 2;
	        if (i < shifts[mid])
    	    {
        	    top = mid;
	        }
    	    else
        	{
	            bottom = mid;
    	    }
		}
	    if (bottom <= 0) // ignore the oth power
    	    return -1;
		if (i == shifts[bottom])
			return bottom;
	}
	return -1 ;
}

//-------------------------------------------------------------------------

LLONG_TYPE mod_mask(int i)
/*
 *      make a mod mask for a power of two.
 */
{
	if (i >= sizeof(shifts)/sizeof(LLONG_TYPE))
		return (LLONG_TYPE)-1;
	return shifts[i] - 1;		
}

//-------------------------------------------------------------------------

void addaside(ENODE *node)
{
    *asidetail = makenode(en_void, node, 0);
    asidetail = &(*asidetail)->v.p[1];
}

//-------------------------------------------------------------------------

int opt0(ENODE **node)
/*
 *      opt0 - delete useless expressions and combine constants.
 *
 *      opt0 will delete expressions such as x + 0, x - 0, x * 0,
 *      x * 1, 0 / x, x / 1, x mod 0, etc from the tree pointed to
 *      by node and combine obvious constant operations. It cannot
 *      combine name and label constants but will combine icon type
 *      nodes.
 *
 * en_addstruc is not optimized to keep from optimizing struct members
 * into regs later...  just en: en_addstruc is now equiv to en_add
 * again.  I have fixed the optimize struct thing another way...
 * leaving en_addstruc in in case we need it later.
 */
{
    ENODE *ep;
    LLONG_TYPE val;
    int sc;
    int rv = FALSE;
    int mode;
    double dval;
    int negtype = en_uminus;

    ep =  *node;

    if (ep == 0)
        return FALSE ;
    switch (ep->nodetype)
    {
        case en_asumul:
        case en_asmul:
        case en_asudiv:
        case en_asdiv:
            negtype = en_asuminus;
    }
    switch (ep->nodetype)
    {
        case en_structret:
            break;
        case en_fp_ref:
        case en_bool_ref:
        case en_cbool:
        case en_b_ref:
        case en_w_ref:
             /* optimize unary node */
        case en_ub_ref:
        case en_uw_ref:
             /* optimize unary node */
		case en_a_ref:
		case en_ua_ref:
		case en_i_ref:
		case en_ui_ref:
        case en_l_ref:
        case en_ul_ref:
        case en_ll_ref:
        case en_ull_ref:
        case en_floatref:
        case en_doubleref:
        case en_longdoubleref:
        case en_fimaginaryref:
        case en_rimaginaryref:
        case en_lrimaginaryref:
        case en_fcomplexref:
        case en_rcomplexref:
        case en_lrcomplexref:
        case en_cb:
        case en_cub:
        case en_cw:
        case en_cuw:
        case en_cl:
        case en_cul:
		case en_ci:
		case en_cui:
        case en_cll:
        case en_cull:
        case en_cf:
        case en_cd:
        case en_cp:
        case en_bits:
        case en_cld:
        case en_cfp:
        case en_csp:
        case en_cl_reg:
            rv |= opt0(&((*node)->v.p[0]));
            return rv ;
        case en_ascompl:
        case en_compl:
            rv |= opt0(&(ep->v.p[0]));
            if (isintconst(ep->v.p[0]->nodetype))
            {
                rv = TRUE;
                ep->nodetype = ep->v.p[0]->nodetype;
                ep->v.i = ~ep->v.p[0]->v.i;
            }
            return rv ;

        case en_uminus:
        case en_asuminus:
            rv = opt0(&(ep->v.p[0]));
            if (isintconst(ep->v.p[0]->nodetype))
            {
                rv = TRUE;
                ep->nodetype = ep->v.p[0]->nodetype;
                ep->v.i =  - ep->v.p[0]->v.i;
            }
            else if (ep->v.p[0]->nodetype == en_rcon || ep->v.p[0]->nodetype ==
                en_fcon || ep->v.p[0]->nodetype == en_lrcon ||
                ep->v.p[0]->nodetype == en_rimaginarycon || ep->v.p[0]->nodetype ==
                en_fimaginarycon || ep->v.p[0]->nodetype == en_lrimaginarycon)
            {
                rv = TRUE;
                ep->nodetype = ep->v.p[0]->nodetype;
                ep->v.f =  - ep->v.p[0]->v.f;
            }
            else if (ep->v.p[0]->nodetype == en_rcomplexcon || ep->v.p[0]->nodetype ==
                en_fcomplexcon || ep->v.p[0]->nodetype == en_lrcomplexcon)
            {
                rv = TRUE;
                ep->nodetype = ep->v.p[0]->nodetype;
                ep->v.c.r =  - ep->v.p[0]->v.c.r;
                ep->v.c.i =  - ep->v.p[0]->v.c.i;
            }
            return rv ;
        case en_add:
        case en_addstruc:
		case en_array:
        case en_sub:
        case en_asadd:
        case en_assub:
            rv |= opt0(&(ep->v.p[0]));
            rv |= opt0(&(ep->v.p[1]));
            mode = getmode(ep->v.p[0], ep->v.p[1]);
            switch (mode)
            {
            case 1:
            case 2:
            case 3:
            case 4:
            default:
                rv = TRUE;
                dooper(node, mode);
                break;
            case 5:
                if (ep->v.p[0]->v.i == 0)
                {
                    if (ep->v.p[0]->nodetype != en_autocon)
                    {
                        if (ep->nodetype == en_sub)
                            *node = makenode(en_uminus, ep->v.p[1], 0);
                        else
                             *node = ep->v.p[1];
                        rv = TRUE;
                    }
                }
                else
                {
                    dooper(node, mode);
                    rv = TRUE;
                }
                break;
            case 6:
                if (ep->v.p[0]->v.f == 0)
                {
                    if (ep->nodetype == en_sub)
                    {
                        *node = ep->v.p[1];
                        ep->v.p[1]->v.f =  - ep->v.p[1]->v.f;

                    }
                    else
                         *node = ep->v.p[1];
                }
                else
                    dooper(node, mode);
                rv = TRUE;
                break;
            case 7:
                if (ep->v.p[1]->v.i == 0)
                {
                    if (ep->v.p[0]->nodetype != en_autocon)
                    {
                        *node = ep->v.p[0];
                        rv = TRUE;
                    }
                }
                else
                {
                    dooper(node, mode);
                    rv = TRUE;
                }
                break;
            case 8:
                if (ep->v.p[1]->v.f == 0)
                {
                    *node = ep->v.p[0];
                }
                else
                    dooper(node, mode);
                rv = TRUE;
                break;
            }
            return rv ;
        case en_mul:
        case en_umul:
        case en_pmul:
		case en_arrayindex:
        case en_asmul:
        case en_asumul:
            rv |= opt0(&(ep->v.p[0]));
            rv |= opt0(&(ep->v.p[1]));
            mode = getmode(ep->v.p[0], ep->v.p[1]);
            switch (mode)
            {
            case 1:
            case 2:
            case 3:
            case 4:
            default:
                dooper(node, mode);
                rv = TRUE;
                break;
            case 5:
                if (!floatrecurse(ep->v.p[1]))
                {
                    sc = pwrof2(ep->v.p[0]->v.i);
                    if (sc !=  - 1)
                    {
                        ENODE *temp = ep->v.p[0];
                        ep->v.p[0] = ep->v.p[1];
                        ep->v.p[1] = temp;
                        ep->v.p[1]->v.i = sc;
                        rv = TRUE;
                        switch (ep->nodetype)
                        {
                        case en_mul:
                            ep->nodetype = en_alsh;
                            break;
                        case en_asmul:
                            ep->nodetype = en_asalsh;
                            break;
                        case en_umul:
                        case en_pmul:
						case en_arrayindex:
                            ep->nodetype = en_lsh;
                            break;
                        case en_asumul:
                            ep->nodetype = en_aslsh;
                            break;
                        }
                        break;
                    }
                }
                val = ep->v.p[0]->v.i;
                if (val == 0)
                {
                    addaside(ep->v.p[1]);
                    *node = ep->v.p[0];
                }
                else if (val == 1)
                    *node = ep->v.p[1];
                else if (val ==  - 1)
                    *node = makenode(negtype, (char*)ep->v.p[1], 0);
                else
                    dooper(node, mode);
                rv = TRUE;
                break;
            case 6:
                dval = ep->v.p[0]->v.f;
                if (dval == 0)
                {
                    addaside(ep->v.p[1]);
                    *node = ep->v.p[0];
                }
                else if (dval == 1)
                    *node = ep->v.p[1];
                else if (dval ==  - 1)
                    *node = makenode(negtype, (char*)ep->v.p[1], 0);
                else
                    dooper(node, mode);
                rv = TRUE;
                break;
            case 7:
                if (!floatrecurse(ep->v.p[0]))
                {
                    sc = pwrof2(ep->v.p[1]->v.i);
                    if (sc !=  - 1)
                    {
                        rv = TRUE;
                        ep->v.p[1]->v.i = sc;
                        switch (ep->nodetype)
                        {
                        case en_mul:
                            ep->nodetype = en_alsh;
                            break;
                        case en_asmul:
                            ep->nodetype = en_asalsh;
                            break;
                        case en_umul:
                        case en_pmul:
						case en_arrayindex:
                            ep->nodetype = en_lsh;
                            break;
                        case en_asumul:
                            ep->nodetype = en_aslsh;
                            break;
                        }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -