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

📄 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 页
字号:
/* 
Copyright 1994-2003 Free Software Foundation, Inc.

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA.  

This program is derived from the cc68k complier by 
Matthew Brandt (mattb@walkingdog.net) 

You may contact the author of this derivative at:

mailto::camille@bluegrass.net

or by snail mail at:

David Lindauer
850 Washburn Ave Apt 99
Louisville, KY 40222
 */
/* no support for complex.  Floating point currently commented out */
/*
 * this module combines constants at compile time.  Integer constants
 * will get combined slightly better than floating point ones
 */
#include <stdio.h>
#include <string.h>
#include "lists.h"
#include "expr.h"
#include "c.h"

extern int stdpragmas;
extern int stdshortsize, stdintsize, stdlongsize, stdlonglongsize;

static ENODE *asidehead,  **asidetail;
LLONG_TYPE reint(ENODE *node);

static unsigned LLONG_TYPE shifts[sizeof(LLONG_TYPE)*8] ;
void constoptinit(void)
{
    LLONG_TYPE i;
    for (i=0; i < sizeof(LLONG_TYPE) * 8; i++)
        shifts[i] = (1 << i);
}
static int optimizerfloatconst(ENODE *en)
{
    if (en->cflags &DF_FENV_ACCESS)
        return FALSE;

    return isfloatconst(en->nodetype) || isimaginaryconst(en->nodetype) || iscomplexconst(en->nodetype);
}

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

static int isoptconst(ENODE *en)
{
    if (!en)
        return FALSE;
    return isintconst(en->nodetype) || optimizerfloatconst(en);
}

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

int maxinttype(ENODE *ep1, ENODE *ep2)
{
    int type1 = ep1->nodetype;
    int type2 = ep2->nodetype;
    if (type1 == en_llucon || type2 == en_llucon)
        return en_llucon;
    if (type1 == en_llcon || type2 == en_llcon)
        return en_llcon;
    if (type1 == en_lucon || type2 == en_lucon)
        return en_lucon;
    if (type1 == en_lcon || type2 == en_lcon)
        return en_lcon;
    if (type1 == en_iucon || type2 == en_iucon)
        return en_iucon;
    if (type1 == en_icon || type2 == en_icon)
        return en_icon;
    if (type1 == en_cucon || type2 == en_cucon)
        return en_cucon;
    if (type1 == en_ccon || type2 == en_ccon)
        return en_ccon;
    return en_boolcon;
}

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

int isunsigned(ENODE *ep1)
{
    switch (ep1->nodetype)
    {
        case en_lucon:
        case en_iucon:
        case en_llucon:
            return TRUE;
        default:
            return FALSE;
    }
}

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

int maxfloattype(ENODE *ep1, ENODE *ep2)
{
    int type1 = ep1->nodetype;
    int type2 = ep2->nodetype;
    if (type1 == en_lrcon || type2 == en_lrcon || type1 == en_lrimaginarycon ||
        type2 == en_lrimaginarycon)
        return en_lrcon;
    if (type1 == en_rcon || type2 == en_rcon || type1 == en_rimaginarycon ||
        type2 == en_rimaginarycon)
        return en_rcon;
    return en_fcon;
}

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

int maximaginarytype(ENODE *ep1, ENODE *ep2)
{
    int type1 = ep1->nodetype;
    int type2 = ep2->nodetype;
    if (type1 == en_lrcon || type2 == en_lrcon || type1 == en_lrimaginarycon ||
        type2 == en_lrimaginarycon)
        return en_lrimaginarycon;
    if (type1 == en_rcon || type2 == en_rcon || type1 == en_rimaginarycon ||
        type2 == en_rimaginarycon)
        return en_rimaginarycon;
    return en_fimaginarycon;
}

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

int maxcomplextype(ENODE *ep1, ENODE *ep2)
{
    int type1 = ep1->nodetype;
    int type2 = ep2->nodetype;
    if (type1 == en_lrcon || type2 == en_lrcon || type1 == en_lrimaginarycon ||
        type2 == en_lrimaginarycon || type1 == en_lrcomplexcon ||
        type2 == en_lrcomplexcon)
        return en_lrcomplexcon;
    if (type1 == en_rcon || type2 == en_rcon || type1 == en_rimaginarycon ||
        type2 == en_rimaginarycon || type1 == en_rcomplexcon || type2 == en_rcomplexcon)
        return en_rcomplexcon;
    return en_fcomplexcon;
}
//-------------------------------------------------------------------------

int getmode(ENODE *ep1, ENODE *ep2)
/*
 * get the constant mode of a pair of nodes
 * 0 = Neither node is a constant
 * 1 = icon,icon
 * 2 = icon,rcon
 * 3 = rcon,icon
 * 4 = rcon,rcon
 * 5 = icon,nothing
 * 6 = rcon,nothing
 * 7 = nothing,icon
 * 8 = nothing,rcon
 * 9 = rcon, ricon
 * 10 = ricon, rcon
 * 11 = ricon, ricon
 * 12 = ricon, nothing
 * 13 = nothing, ricon
 * 14 = ricon, icon
 * 15 = icon, ricon
 * 16 = ricon, cmplxcon
 * 17 = cmplxcon, ricon
 * 18 = rcon, cmplxcon
 * 19 = cmplxcon, rcon
 * 20 = cmplxcon, cmplxcon
 * 21 = cmplxcon, nothing
 * 22 = nothing, cmplxcon
 * 23 = cmplxcon, icon
 * 24 = icon, cmplxcon
 */
{
    int mode = 0;
    if ((ep1->cflags &DF_FENV_ACCESS) && (isfloatconst(ep1->nodetype) ||
        isimaginaryconst(ep1->nodetype) || iscomplexconst(ep1->nodetype)))
        return 0;
    if (ep2 && (ep2->cflags &DF_FENV_ACCESS) && (isfloatconst(ep2->nodetype) ||
        isimaginaryconst(ep2->nodetype) || iscomplexconst(ep2->nodetype)))
        return 0;
    if (isintconst(ep1->nodetype))
        if (ep2)
        {
            if (isintconst(ep2->nodetype))
                mode = 1;
            else if (ep2->nodetype == en_rcon || ep2->nodetype == en_lrcon || ep2
                ->nodetype == en_fcon)
            {
                    mode = 2;
            }
            else if (ep2->nodetype == en_rimaginarycon || ep2->nodetype == en_fimaginarycon ||
                ep2->nodetype == en_lrimaginarycon)
                    mode = 15;
            else if (ep2->nodetype == en_rcomplexcon || ep2->nodetype == en_fcomplexcon ||
                ep2->nodetype == en_lrcomplexcon)
                    mode = 24;
            else
                mode = 5;
        }
        else
            mode = 5;
    else if (ep1->nodetype == en_rcon || ep1->nodetype == en_lrcon || ep1
        ->nodetype == en_fcon)
        if (ep2)
        {
            if (isintconst(ep2->nodetype))
                    mode = 3;
            else if (ep2->nodetype == en_rcon || ep2->nodetype == en_lrcon ||
                ep2->nodetype == en_fcon)
                    mode = 4;
            else if (ep2->nodetype == en_rimaginarycon || ep2->nodetype == en_fimaginarycon ||
                ep2->nodetype == en_lrimaginarycon)
                    mode = 9;
            else if (ep2->nodetype == en_rcomplexcon || ep2->nodetype == en_fcomplexcon ||
                ep2->nodetype == en_lrcomplexcon)
                    mode = 18;
            else
                mode = 6;
        }
        else
            mode = 6;
    else if (ep1->nodetype == en_rimaginarycon || ep1->nodetype == en_fimaginarycon ||
        ep1->nodetype == en_lrimaginarycon)
        if (ep2)
        {
            if (ep2->nodetype == en_rcon || ep2->nodetype == en_lrcon || ep2
                ->nodetype == en_fcon)
                    mode = 10;
            else if (ep2->nodetype == en_rimaginarycon || ep2->nodetype == en_fimaginarycon ||
                ep2->nodetype == en_lrimaginarycon)
                    mode = 11;
            else if (ep2->nodetype == en_rcomplexcon || ep2->nodetype == en_fcomplexcon ||
                ep2->nodetype == en_lrcomplexcon)
                    mode = 16;
            else if (isintconst(ep2->nodetype))
                    mode = 14;
            else
                mode = 12;
        } else
            mode = 12;
    else if (ep1->nodetype == en_rcomplexcon || ep1->nodetype == en_fcomplexcon ||
        ep1->nodetype == en_lrcomplexcon)
        if (ep2)
        {
            if (ep2->nodetype == en_rcon || ep2->nodetype == en_lrcon || ep2
                ->nodetype == en_fcon)
                    mode = 17;
            else if (ep2->nodetype == en_rimaginarycon || ep2->nodetype == en_fimaginarycon ||
                ep2->nodetype == en_lrimaginarycon)
                    mode = 19;
            else if (ep2->nodetype == en_rcomplexcon || ep2->nodetype == en_fcomplexcon ||
                ep2->nodetype == en_lrcomplexcon)
                    mode = 20;
            else if (isintconst(ep2->nodetype))
                    mode = 23;
            else
                mode = 21;
        } else
            mode = 21;
    else if (ep2)
        if (isintconst(ep2->nodetype))
            mode = 7;
        else if (ep2->nodetype == en_rcon || ep2->nodetype == en_lrcon || ep2
            ->nodetype == en_fcon)
                mode = 8;
        else if (ep2->nodetype == en_rimaginarycon || ep2->nodetype == en_fimaginarycon ||
            ep2->nodetype == en_lrimaginarycon)
                mode = 13;
        else if (ep2->nodetype == en_rcomplexcon || ep2->nodetype == en_fcomplexcon ||
            ep2->nodetype == en_lrcomplexcon)
                mode = 22;
    
    return (mode);
}

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

void dooper(ENODE **node, int mode)
/*
 *      dooper will execute a constant operation in a node and
 *      modify the node to be the result of the operation.
 *			It will also cast integers to floating point values when
 *			necessary
 */
{
    ENODE *ep,  *ep1,  *ep2;
    ep =  *node;
    ep1 = ep->v.p[0];
    ep2 = ep->v.p[1];
    if (mode == 5)
    {
        if (floatrecurse(ep2))
        {
            ep1->v.f = ep1->v.i;
            ep1->nodetype = en_rcon;
        }
        return ;
    }
    else if (mode == 7)
    {
        if (floatrecurse(ep1))
        {
            ep2->v.f = ep2->v.i;
            ep2->nodetype = en_rcon;
        }
        return ;
    }
    else if (mode == 6 || mode == 8 || mode == 12 || mode == 13 || mode == 21 || mode == 22)
        return ;
    else
    switch (ep->nodetype)
    {
        case en_add:
        case en_addstruc:
		case en_array:
            switch (mode)
            {
            case 1:
                ep->nodetype = maxinttype(ep1, ep2);
                ep->v.i = ep1->v.i + ep2->v.i;
                ep->v.i = reint(ep);
                break;
            case 2:
                ep->nodetype = maxfloattype(ep1, ep2);
                ep->v.f = ep1->v.i + ep2->v.f;
                break;
            case 3:
                ep->nodetype = maxfloattype(ep1, ep2);
                ep->v.f = ep1->v.f + ep2->v.i;
                break;
            case 4:
                ep->nodetype = maxfloattype(ep1, ep2);
                ep->v.f = ep1->v.f + ep2->v.f;
                break;
            case 9:
                ep->nodetype = maxcomplextype(ep1,ep2);
                ep->cflags |= ((ep1->cflags &STD_PRAGMA_CXLIMITED)
                    && (ep2->cflags & STD_PRAGMA_CXLIMITED)) ?
                        DF_CXLIMITED : 0;
                ep->v.c.r = ep1->v.f ;
                ep->v.c.i = ep2->v.f;
                break ;
            case 10:
                ep->nodetype = maxcomplextype(ep1,ep2);
                ep->cflags |= ((ep1->cflags &STD_PRAGMA_CXLIMITED)
                    && (ep2->cflags & STD_PRAGMA_CXLIMITED)) ?
                        DF_CXLIMITED : 0;
                ep->v.c.r = ep2->v.f ;
                ep->v.c.i = ep1->v.f;
                break ;
            case 11:
                ep->nodetype = maximaginarytype(ep1,ep2);
                ep->v.f = ep1->v.f + ep2->v.f;
                break ;
            case 14:
                ep->nodetype = maxcomplextype(ep1,ep2);
                ep->cflags |= ((ep1->cflags &STD_PRAGMA_CXLIMITED)
                    && (ep2->cflags & STD_PRAGMA_CXLIMITED)) ?
                        DF_CXLIMITED : 0;
                ep->v.c.r = ep2->v.i ;
                ep->v.c.i = ep1->v.f ;

⌨️ 快捷键说明

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