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

📄 igcse.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
 */
/*
 * igcse.c
 *
 * Go through the block list replacing common subexpressions with copy
 * statements
 *
 */
#include <stdio.h>
#include <malloc.h>
#include <string.h>
#include <limits.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"

#define AHASH DAGSIZE
extern int *dfst;
extern int blocknum;
extern BLOCKLIST **blockarray;
extern unsigned char bittab[8];
extern BYTE *temparray4;
extern int sourcebytes, pointer_count, source_count;
extern IMODE **pointerarray;
extern QUAD **sourcearray;
extern int tempnum;

static QUAD **availarray;
static int avail_count, avail_bytes, max_avail;
static QUAD **csearray;
static int cse_max, cse_count;
static LIST3 **availhash,  **availhash2;
static int csesize =  - 1000, csexit;
static SYM **tempindexarray;

#ifdef DUMP_GCSE_INFO
    extern FILE *icdFile,  *outputFile;
    static void dump_avail(void)
    {
        int i;
        char buf[256];
        FILE *temp;
        if (!icdFile)
            return ;
        temp = outputFile;
        outputFile = icdFile;
        fprintf(icdFile, "\n; Available Expressions: %d\n", avail_count);
        for (i = 0; i < avail_count; i++)
        {
            fprintf(icdFile, "; ");
            put_code(availarray[i]);
        }
        fprintf(icdFile, "\n; Sets:\n");
        for (i = 0; i < blocknum; i++)
        {
            sprintf(buf, "; Avail Gen block %d", i + 1);
            dumpset(blockarray[i]->block->p_agen, availarray, buf, avail_count);
            sprintf(buf, "; Avail kill block %d", i + 1);
            dumpset(blockarray[i]->block->p_akill, availarray, buf, avail_count)
                ;
            sprintf(buf, "; Avail in block %d", i + 1);
            dumpset(blockarray[i]->block->p_ain, availarray, buf, avail_count);
            sprintf(buf, "; Avail out block %d", i + 1);
            dumpset(blockarray[i]->block->p_aout, availarray, buf, avail_count);
        }
        outputFile = temp;
    }
#endif 
static int CacheAvail(QUAD *var)
{
    LIST *l = oalloc(sizeof(LIST));
    int hash;
    l->data = var;
    hash = dhash(var, sizeof(struct _basic_dag));
    l->link = availhash2[hash];
    availhash2[hash] = l;
}

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

static QUAD *FindAvail(QUAD *var)
{
    LIST *l;
    int hash = dhash(var, sizeof(struct _basic_dag));
    l = availhash2[hash];
    while (l)
    {
        if (!memcmp(var, l->data, sizeof(struct _basic_dag)))
            return l->data;
        l = l->link;
    } return 0;

}

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

static void enter_avail(QUAD *var)
{
    QUAD *l;
    if (var->dc.opcode == i_assn && var->dc.left->mode == i_immed && 
        (isfloatconst(var->dc.left->offset->nodetype) || isintconst(var
        ->dc.left->offset->nodetype)))
        return ;
    if (var->available)
        return ;
    l = FindAvail(var);
    if (l)
    {
        SYM *sp;
        var->available = l->available;
        sp = varsp(var->ans->offset);
        if (sp->storage_class == sc_temp)
        {
            int hash = dhash(var, sizeof(struct _basic_dag));
            LIST *l = availhash2[hash];
            while (l)
            {
                if (!memcmp(l->data, var, sizeof(struct _basic_dag)))
                {
                    SYM *sp1 = varsp(((QUAD*)l->data)->ans->offset);
                    if (sp1->storage_class == sc_temp && !sp1->iglobal && !sp1
                        ->ipointerindx)
                    {
                        tempindexarray[sp->value.i] = sp1;
                        return ;
                    } 
                }
                l = l->link;
            }
        }
        CacheAvail(var);
        return ;
    }
    if (avail_count >= max_avail)
    {
        QUAD **newarray = oalloc(sizeof(QUAD*)*(max_avail += 256));
        if (availarray)
            memcpy(newarray, availarray, (max_avail - 256) *sizeof(QUAD*));
        availarray = newarray;
    }
    var->available = avail_count + 1;
    availarray[avail_count++] = var;
    anshash(availhash, var->dc.left, (QUAD*)avail_count);
    anshash(availhash, var->dc.right, (QUAD*)avail_count);
    CacheAvail(var);
}

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

static void ReplaceOneTemp(IMODE **v)
{
    SYM *sp;
    if (! *v)
        return ;
    sp = varsp((*v)->offset);
    if (sp)
    if (sp->storage_class == sc_temp)
    {
        if (sp = tempindexarray[sp->value.i])
        {
            if ((*v)->mode == i_ind)
            {
                if (sp->imind == 0)
                {
                    sp->imind == xalloc(sizeof(IMODE));
                    sp->imind->mode == i_ind;
                    sp->imind->offset = makenode(en_tempref, sp, 0);
                    sp->imind->size = (*v)->size;
                }
                *v = sp->imind;
            }
            else if ((*v)->mode == i_direct)
            {
                if (sp->imvalue == 0)
                {
                    sp->imvalue == xalloc(sizeof(IMODE));
                    sp->imvalue->mode == i_direct;
                    sp->imvalue->offset = makenode(en_tempref, sp, 0);
                    sp->imvalue->size = (*v)->size;
                }
                *v = sp->imvalue;
            }
        }
    }
}

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

static void ReplaceTemps(QUAD *list)
{
    ReplaceOneTemp(&list->ans);
    ReplaceOneTemp(&list->dc.left);
    ReplaceOneTemp(&list->dc.right);
}

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

static void CountAvail(void)
{
    int block = 0, i, j, k;

    avail_count = 0;

    availarray = 0;

    max_avail = 0;

    for (i = 0; i < blocknum; i++)
    {
        BLOCK *l = blockarray[i]->block;
        QUAD *head = l->head;
        memcpy(temparray4, l->p_pin, sourcebytes *pointer_count);
        while (head && head->back != l->tail)
        {
            switch (head->dc.opcode)
            {
                case i_add:
                case i_sub:
                case i_udiv:
                case i_umod:
                case i_sdiv:
                case i_smod:
                case i_umul:
                case i_smul:
                case i_lsl:
                case i_lsr:
                case i_asl:
                case i_asr:
                case i_neg:
                case i_not:
                case i_and:
                case i_or:
                case i_eor:
                case i_setne:
                case i_sete:
                case i_setc:
                case i_seta:
                case i_setnc:
                case i_setbe:
                case i_setl:
                case i_setg:
                case i_setle:
                case i_setge:
                case i_assn:
                    ReplaceTemps(head);
                    enter_avail(head);

                    // FALL THROUGH
                case i_coswitch:
                case i_jc:
                case i_ja:
                case i_je:
                case i_jnc:
                case i_jbe:
                case i_jne:
                case i_jl:
                case i_jg:
                case i_jle:
                case i_jge:
                case i_parm:
                    ReplaceTemps(head);
                    break;
                case i_gosub:
                    l->callcount++;
                    break;

            }
            ptrindex(head, l, temparray4);
            head = head->fwd;
        }
    }
}

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

static void CreateAvailBitArrays(void)
{
    int i;
    avail_bytes = (avail_count + 8) / 8;
    if (avail_bytes % 4)
        avail_bytes += 4-avail_bytes % 4;
    for (i = 0; i < blocknum; i++)
    {
        blockarray[i]->block->p_agen = oalloc(avail_bytes);
        blockarray[i]->block->p_akill = oalloc(avail_bytes);
        blockarray[i]->block->p_ain = oalloc(avail_bytes);
        blockarray[i]->block->p_aout = oalloc(avail_bytes);
    }
}

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

int isvolatile(QUAD *item)
{
    if (item->dc.left && item->dc.left->offset && (item->dc.left->offset
        ->cflags &DF_VOL))
        return 1;
    if (item->dc.right && item->dc.right->offset && (item->dc.right->offset
        ->cflags &DF_VOL))
        return 1;
    return 0;
}

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

static void CalculateAvailBasics(void)
{
    int i, j, k, left, right, ans;
    int ptr, ptr2, gencount, pgen, pagen, def2;
    int left1, right1, ans1;
    LIST *l1;
    for (i = 0; i < blocknum; i++)
    {
        BLOCK *l = blockarray[i]->block;
        QUAD *list = l->head;
        memcpy(temparray4, l->p_pin, sourcebytes *pointer_count);
        while (list && list->back != l->tail)
        {
            int skipptr = FALSE;
            ptr = INT_MAX;
            gencount = 0;
            pgen =  - 1;
            switch (list->dc.opcode)
            {
                case i_assn:
                    if (list->ans == list->dc.left)
                    {
                        list->fwd->back = list->back;
                        list->back->fwd = list->fwd;
                        skipptr = TRUE;
                        break;
                    }
                case i_add:
                case i_sub:
                case i_udiv:
                case i_umod:
                case i_sdiv:
                case i_smod:
                case i_umul:
                case i_smul:
                case i_lsl:
                case i_lsr:
                case i_asl:
                case i_asr:
                case i_neg:
                case i_not:
                case i_and:
                case i_or:
                case i_eor:
                case i_setne:
                case i_sete:

⌨️ 快捷键说明

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