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

📄 iconst.c

📁 CC386 is a general-purpose 32-bit C compiler. It is not an optimizing compiler but given that the co
💻 C
📖 第 1 页 / 共 3 页
字号:
/* 
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
 */
/*
 * iconst.c
 *
 * Constant folding.  Is done at the same time as CSEs.
 *
 */
#include <stdio.h>
#include <malloc.h>
#include <string.h>
#include "utype.h"	
#include "cmdline.h"	
#include "lists.h"
#include "expr.h"
#include "c.h"
#include "iexpr.h"
#include "iopt.h"
#include "diag.h"

extern int prm_foldconst;
extern **name_hash;

#ifdef XXXXX
IMODE *intconst(LLONG_TYPE val)
{
    return make_immed(val);
}
#endif

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

void badconst(void)
{
    DIAG("ICODE- Bad constant node");
}

void ReassignMulDiv(QUAD *d, enum e_iops op, LLONG_TYPE val, int fromleft)
{
	IMODE *ip = make_immed(val);
	if (fromleft) {
		d->dc.left = d->dc.right;
		if (d->livein & IM_LIVERIGHT)
			d->livein = IM_LIVELEFT;
		else
			d->livein = 0;
	}
	if (!ToQuadConst(&ip))
		d->livein |= IM_LIVERIGHT;
	d->dc.right = ip;	
	d->dc.opcode = op;
}
void ReassignInt(QUAD *d, LLONG_TYPE val)
{
	IMODE *ip = make_immed(val);
	if (ToQuadConst(&ip))
		d->livein = IM_LIVERIGHT;
	else
		d->livein = IM_LIVELEFT | IM_LIVERIGHT;
	d->dc.left = ip ;
	d->dc.right = 0;
	d->dc.opcode = i_assn;
}
void ReassignFloat(QUAD *d, long double val)
{
	IMODE *ip = make_fimmed(val);
	if (ToQuadConst(&ip))
		d->livein = IM_LIVERIGHT;
	else
		d->livein = IM_LIVELEFT | IM_LIVERIGHT;
	d->dc.left = ip ;
	d->dc.right = 0;
	d->dc.opcode = i_assn;
}
void ReassignCompare(QUAD *d, int yes)
{
    if (d->dc.opcode >= i_jc) {
        if (yes)
            d->dc.opcode = i_goto;
        else {
            d->dc.opcode = i_nop;
        }
    } else {
        ReassignInt(d,yes);
    }
}
void ASNFromLeft(QUAD *d)
{
	d->dc.right = 0;
	d->livein |= IM_LIVERIGHT;
	d->dc.opcode = i_assn;
}
void ASNFromRight(QUAD *d)
{
	d->dc.left = d->dc.right;
	d->dc.right = 0;
    if (d->livein & IM_LIVERIGHT)
    	d->livein = IM_LIVERIGHT | IM_LIVELEFT;
    else
        d->livein = IM_LIVERIGHT;
	d->dc.opcode = i_assn;
}
//-------------------------------------------------------------------------
/*
 * when we get here the quad node will have node replacements
 * for named nodes done.  Constants will always have been replaced
 * from the named node describing the constant at this point.
 * If either or both of the
 * node arguments are constants the QUAD left and or right pointers
 * will point to QUAD nodes describing the constants and the
 * appropriate bits in the livein member of the quad will be clear
 */
static int xgetmode(QUAD *d, union ival **left, union ival **right)
{
    int mode = icnone;
    QUAD *ql = d->dc.left,  *qr = d->dc.right;
    *left =  *right = 0;
    if (!(d->livein &IM_LIVELEFT) && (ql && (ql->dc.opcode == i_icon || ql
        ->dc.opcode == i_fcon || ql->dc.opcode == i_imcon || ql->dc.opcode == i_cxcon)))
        *left = &(ql->dc.v);
    if (!(d->livein &IM_LIVERIGHT) && (qr && (qr->dc.opcode == i_icon || qr
        ->dc.opcode == i_fcon || qr->dc.opcode == i_imcon || qr->dc.opcode == i_cxcon)))
        *right = &(qr->dc.v);
	if (*left) {
		if (*right) {
			switch(ql->dc.opcode) {
				case i_icon:
					switch(qr->dc.opcode) {
						case i_icon:
							mode = icll;
							break ;
						case i_fcon:
							mode = iclr;
							break ;
						case i_imcon:
							mode = icli;
							break ;
						case i_cxcon:
							mode = iclc;
							break ;
					}
					break ;
				case i_fcon:
					switch(qr->dc.opcode) {
						case i_icon:
							mode = icrl;
							break ;
						case i_fcon:
							mode = icrr;
							break ;
						case i_imcon:
							mode = icri;
							break ;
						case i_cxcon:
							mode = icrc;
							break ;
					}
					break ;
				case i_imcon:
					switch(qr->dc.opcode) {
						case i_icon:
							mode = icil;
							break ;
						case i_fcon:
							mode = icir;
							break ;
						case i_imcon:
							mode = icii;
							break ;
						case i_cxcon:
							mode = icic;
							break ;
					}
					break ;
				case i_cxcon:
					switch(qr->dc.opcode) {
						case i_icon:
							mode = iccl;
							break ;
						case i_fcon:
							mode = iccr;
							break ;
						case i_imcon:
							mode = icci;
							break ;
						case i_cxcon:
							mode = iccc;
							break ;
					}
					break ;
			}
		} else {
			switch(ql->dc.opcode) {
				case i_icon:
					mode = icln;
					break ;
				case i_fcon:
					mode = icrn;
					break ;
				case i_imcon:
					mode = icin;
					break ;
				case i_cxcon:
					mode = iccn;
					break ;
				default:
					break ;
			}
		}
	} else if (*right) {
		switch(qr->dc.opcode) {
			case i_icon:
				mode = icnl;
				break ;
			case i_fcon:
				mode = icnr;
				break ;
			case i_imcon:
				mode = icni;
				break ;
			case i_cxcon:
				mode = icnc;
				break ;
			default:
				break ;
		}
	}
    return (mode);
}
//-------------------------------------------------------------------------
LLONG_TYPE calmask(int i)
{
	if (pwrof2(i) != -1)
		return i - 1;
	return (LLONG_TYPE)-1;
}
void ReCast(int size, QUAD *in, QUAD *newMode)
{
	if (size) {
		if (size <= ISZ_ULONGLONG) {
			LLONG_TYPE i;
			if (in->dc.opcode == i_icon)
				i = CastToInt(size, 	in->dc.v.i);
			else
				i = CastToInt(size, 	in->dc.v.f);
			if (!newMode) {
				in->dc.v.i = i;
				return in;
			} else {
				memset(&newMode->dc,0,sizeof(newMode->dc));
				newMode->dc.opcode = i_icon;
				newMode->dc.v.i = i;
				newMode->ans = make_immed(i);
				return newMode;
			}
		} else if (size >= ISZ_FLOAT) {
			long double f;
			if (in->dc.opcode == i_icon)
				f = CastToFloat(size, 	in->dc.v.i);
			else
				f = CastToFloat(size, 	in->dc.v.f);
			if (!newMode) {
				in->dc.v.f = f;
				return in;
			} else {
				memset(&newMode->dc,0,sizeof(newMode->dc));
				newMode->dc.opcode = i_fcon;
				newMode->dc.v.f = f;
				newMode->ans = make_fimmed(f);
				return newMode;
			}
		} else
			return in;
	}
	return in;
}
//-------------------------------------------------------------------------
void ConstantFold(QUAD *d)
{
    int index, shift;
    union ival *left = 0,  *right = 0;
    if (!prm_foldconst)
        return ;
    switch (d->dc.opcode)
    {
		case i_setne:
		case i_jne:
            index = xgetmode(d, &left, &right);
            switch(index)
            {
            case icll:
                ReassignCompare(d,left->i != right->i);
                break;
            case iclr:
                ReassignCompare(d,left->i != right->f);
                break;
            case icrl:
                ReassignCompare(d,left->f != right->i);
                break;
            case icrr:
                ReassignCompare(d,left->f != right->f);
                break;
            }		
            break;
		case i_sete:
		case i_je:
            index = xgetmode(d, &left, &right);
            switch(index)
            {
            case icll:
                ReassignCompare(d,left->i == right->i);
                break;
            case iclr:
                ReassignCompare(d,left->i == right->f);
                break;
            case icrl:
                ReassignCompare(d,left->f == right->i);
                break;
            case icrr:
                ReassignCompare(d,left->f == right->f);
                break;
            }		
            break;
		case i_setc:
		case i_jc:
            index = xgetmode(d, &left, &right);
            switch(index)
            {
            case icll:
                if (right->i == 0)
                    ReassignCompare(d,0);
                else
                    ReassignCompare(d,(unsigned LLONG_TYPE)left->i < (unsigned LLONG_TYPE)right->i);
                break;
            case iclr:
                if (right->f == 0)
                    ReassignCompare(d,0);
                else
                    ReassignCompare(d,(unsigned LLONG_TYPE)left->i < right->f);
                break;
            case icrl:
                if (right->i == 0)
                    ReassignCompare(d,0);
                else
                    ReassignCompare(d,left->f < (unsigned LLONG_TYPE)right->i);
                break;
            case icrr:
                if (right->f == 0)
                    ReassignCompare(d,0);

⌨️ 快捷键说明

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