namelist.c

来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 784 行 · 第 1/2 页

C
784
字号
/****************************************************************************
*
*                            Open Watcom Project
*
*    Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved.
*
*  ========================================================================
*
*    This file contains Original Code and/or Modifications of Original
*    Code as defined in and that are subject to the Sybase Open Watcom
*    Public License version 1.0 (the 'License'). You may not use this file
*    except in compliance with the License. BY USING THIS FILE YOU AGREE TO
*    ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is
*    provided with the Original Code and Modifications, and is also
*    available at www.sybase.com/developer/opensource.
*
*    The Original Code and all software distributed under the License are
*    distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
*    EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM
*    ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF
*    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR
*    NON-INFRINGEMENT. Please see the License for the specific language
*    governing rights and limitations under the License.
*
*  ========================================================================
*
* Description:  Manage a list of names.
*
****************************************************************************/


#include "standard.h"
#include "coderep.h"
#include "sysmacro.h"
#include "hwreg.h"
#include "regset.h"
#include "model.h"
#include "freelist.h"
#include "cfloat.h"
#include "typedef.h"
#include "zoiks.h"

#include "namelist.h"
extern  void            FreeTable(sym_handle);
extern  type_class_def  RegClass(hw_reg_set);
extern  type_def        *ClassType(type_class_def);
extern  pointer         LkAddBack(sym_handle,pointer);
extern  uint_8          RegTrans( hw_reg_set );

extern    name  *Names[];
extern    int   TempId;

static  pointer         FrlHead[N_INDEXED+1];
static  pointer         ConstDefnFrl;
static  name            *NullReg;
static  name            *ConstZero;
static  name            *ConstOne;

extern  name            *LastTemp;
extern  name            *DummyIndex;

static  int     Size[] = {
        sizeof( const_name ),
        sizeof( memory_name ),
        sizeof( temp_name ),
        sizeof( register_name ),
        sizeof( indexed_name )
        };

static  type_length     OneClass[] = {
        U1,             /* U1*/
        U1,             /* I1*/
        U2,             /* U2*/
        U2,             /* I2*/
        U4,             /* U4*/
        U4,             /* I4*/
        U8,             /* U8*/
        U8,             /* U8*/
        CP,             /* CP*/
        PT,             /* PT*/
        FS,             /* FS*/
        FD,             /* FD*/
        FL,             /* FL*/
        XX };           /* XX*/

type_length     TypeClassSize[XX+1];

static  name    *AllocName( int class,
                            type_class_def type_class, type_length size ) {
/*************************************************************************/

    name        *new;

    new = AllocFrl( &FrlHead[  class  ], Size[  class  ] );
    new->n.class = class;
    new->n.next_name = Names[ class ];
    Names[ class ] = new;
    new->n.name_class = type_class;
    new->n.size = TypeClassSize[ type_class ];
    if( new->n.size == 0 ) {
        new->n.size = size;
    }
    return( new );
}

static  name    *findConst64( unsigned_32 low, unsigned_32 high, pointer cf_value ) {
/*******************************************************************************/

    name        *new_c;
    name        **last;

    last = &Names[  N_CONSTANT  ];
    new_c = Names[  N_CONSTANT  ];
    while( new_c != NULL ) {
        if( new_c->c.const_type == CONS_ABSOLUTE ) {
            if( new_c->c.int_value == low && new_c->c.int_value_2 == high ) {
                if( CFCompare( new_c->c.value, cf_value ) == 0 ) {
                    // move constant found to front of list
                    *last = new_c->n.next_name;
                    new_c->n.next_name = Names[ N_CONSTANT ];
                    Names[ N_CONSTANT ] = new_c;
                    break;
                }
            }
        }
        last = &new_c->n.next_name;
        new_c = new_c->n.next_name;
    }
    return( new_c );
}


static void ZapXX( name *xx, type_class_def class, type_length size ) {
/***********************************************************************/

    if( class != XX ) { /* if he's making a type with same size as xx */
        xx->n.name_class = class; /* zap the XX one to be a real type */
        xx->n.size = TypeClassSize[  class  ];
    } else if( size != 0 ) {
        xx->n.size = size;
    }
}


extern  name    *AllocConst( pointer value ) {
/********************************************/

    name        *new_c;
    name        **last;
    signed_32   int_value;
    int         test;
    int_value = CFCnvF32( value );
    test = CFTest( value );
    if( test == 0 && ConstZero != NULL ) {
        CFFree( value );
        return( ConstZero );
    }
    if( int_value == 1 && ConstOne != NULL ) {
        CFFree( value );
        return( ConstOne );
    }
    last = &Names[  N_CONSTANT  ];
    new_c = Names[  N_CONSTANT  ];
    while( new_c != NULL ) {
        if( new_c->c.const_type == CONS_ABSOLUTE ) {
            if( new_c->c.int_value == int_value ) {
                if( CFCompare( new_c->c.value, value ) == 0 ) {
                    CFFree( value );
                    // move constant found to front of list
                    *last = new_c->n.next_name;
                    new_c->n.next_name = Names[ N_CONSTANT ];
                    Names[ N_CONSTANT ] = new_c;
                    return( new_c );
                }
            }
        }
        last = &new_c->n.next_name;
        new_c = new_c->n.next_name;
    }
    new_c = AllocName( N_CONSTANT, XX, 0 );
    new_c->c.value = value;
    new_c->c.int_value = int_value;
    if( test < 0 ){
        new_c->c.int_value_2 = -1; //sign extend
    }else{
        new_c->c.int_value_2 = 0;
    }
    new_c->c.static_defn = NULL;
    new_c->c.const_type = CONS_ABSOLUTE;
    if( ConstOne == NULL && new_c->c.int_value == 1 ) {
        ConstOne = new_c;
    }
    if( ConstZero == NULL && new_c->c.int_value == 0 &&  test == 0 ) {
        ConstZero = new_c;
    }
    if( int_value == 0 ) {
        if( CFIsI64( value ) || CFIsU64( value ) ) {
            unsigned_64         i64val;

            i64val = CFCnvF64( value );
            new_c->c.int_value   = i64val.u._32[ I64LO32 ];
            new_c->c.int_value_2 = i64val.u._32[ I64HI32 ];
        }
    }
    return( new_c );
}

extern  name    *AllocAddrConst( name *value, int seg,
                                 constant_class class,
                                 type_class_def name_class ) {
/************************************************************/

    name        *new_c;

    new_c = Names[  N_CONSTANT  ];
    while( new_c != NULL ) {
        if( new_c->c.const_type == class
         && new_c->c.value == value
         && new_c->n.name_class == name_class
         && new_c->c.int_value == seg ) return( new_c );
        new_c = new_c->n.next_name;
    }
    new_c = AllocName( N_CONSTANT, name_class, 0 );
    new_c->c.value = value;
    new_c->c.int_value = seg;
    new_c->c.static_defn = NULL;
    new_c->c.const_type = class;
    return( new_c );
}


extern  name    *FindIntValue( signed_32 value ) {
/************************************************/

    if( value == 0 && ConstZero != NULL ) return( ConstZero );
    if( value == 1 && ConstOne != NULL ) return( ConstOne );
    return( NULL );
}


extern  name    *AllocIntConst( int value ) {
/*******************************************/

    name        *konst;

    konst = FindIntValue( value );
    if( konst != NULL ) return( konst );
    return( AllocConst( CFCnvIF( value ) ) );
}


extern  name    *AllocS32Const( signed_32 value ) {
/*******************************************/

    name        *konst;

    konst = FindIntValue( value );
    if( konst != NULL ) return( konst );
    return( AllocConst( CFCnvI32F( value ) ) );
}

extern  name    *AllocS64Const( unsigned_32 low, unsigned_32 high ) {
/*******************************************************************/

    name        *new_c;
    pointer     cf_value = CFCnvI64F( low, high );

    new_c = findConst64( low, high, cf_value );
    if( new_c == NULL ){
        new_c = AllocName( N_CONSTANT, XX, 0 );
        new_c->c.value = cf_value;
        new_c->c.int_value = low;
        new_c->c.int_value_2 = high;
        new_c->c.static_defn = NULL;
        new_c->c.const_type = CONS_ABSOLUTE;
    } else {
        CFFree( cf_value );
    }
    return( new_c );
}

extern  name    *AllocU64Const( unsigned_32 low, unsigned_32 high ) {
/*******************************************************************/

    name        *new_c;
    pointer     cf_value = CFCnvU64F( low, high );

    new_c = findConst64( low, high, cf_value );
    if( new_c == NULL ){
        new_c = AllocName( N_CONSTANT, XX, 0 );
        new_c->c.value = cf_value;
        new_c->c.int_value = low;
        new_c->c.int_value_2 = high;
        new_c->c.static_defn = NULL;
        new_c->c.const_type = CONS_ABSOLUTE;
    } else {
        CFFree( cf_value );
    }
    return( new_c );
}

extern  name    *AllocUIntConst( uint value ) {
/*********************************************/

    name        *konst;

    konst = FindIntValue( value );
    if( konst != NULL ) return( konst );
    return( AllocConst( CFCnvUF( value ) ) );
}


extern  constant_defn   *GetFloat( name *cons, type_class_def class ) {
/*********************************************************************/

    constant_defn       *defn;

    defn = cons->c.static_defn;
    for(;;) {
        if( defn == NULL ) break;
        if( defn->const_class == class ) return( defn );
        defn = defn->next_defn;
    }
    defn = AllocFrl( &ConstDefnFrl, sizeof( constant_defn ) );
    defn->const_class = class;
    defn->label = NULL;
    CFCnvTarget( cons->c.value, (flt*)&defn->value, TypeClassSize[ class ] );
    defn->next_defn = cons->c.static_defn;
    cons->c.static_defn = defn;
    return( defn );
}


extern  memory_name     *SAllocMemory( pointer symbol, type_length offset,
                                       cg_class class, type_class_def nclass,
                                       type_length size ) {
/*********************************************************/

    name        *new_m;
    name        *other;
    name        *xx;

    new_m = Names[  N_MEMORY  ];
    other = NULL;
    xx = NULL;
    while( new_m != NULL ) {
        if( new_m->v.symbol == symbol && new_m->m.memory_type == class ) {
            if( new_m->v.offset != offset ) {
                other = new_m;
                new_m->v.usage |= USE_MEMORY | NEEDS_MEMORY;
            } else {
                if( nclass == XX && size == 0 ) return( &( new_m->m ) ); /* 89-07-07 */
                if( new_m->n.name_class == nclass && nclass != XX ) {/*exact!*/
                    return( &( new_m->m ) );
                }
                if( new_m->n.name_class == XX && new_m->n.size == size ) {
                    xx = new_m;
                }
                other = new_m;
                new_m->v.usage |= USE_MEMORY | NEEDS_MEMORY;
            }
        }
        new_m = new_m->n.next_name;
    }
    if( xx != NULL ) {
        ZapXX( xx, nclass, size );
        return( &( xx->m ) );
    }
    new_m = AllocName( N_MEMORY, nclass, size );
    new_m->v.symbol = symbol;
    new_m->v.offset = offset;
    new_m->m.memory_type    = class;
    new_m->m.alignment = 0;
    if( other != NULL ) {
        if( other->m.same_sym != NULL ) {
            new_m->m.same_sym = other->m.same_sym;
        } else {
            new_m->m.same_sym = other;
        }
        other->m.same_sym = new_m;
        new_m->v.usage  = USE_MEMORY | NEEDS_MEMORY;
    } else {
        new_m->v.usage = NEEDS_MEMORY;
        new_m->m.same_sym = NULL;
    }
    if( class == CG_FE && _IsModel( NO_OPTIMIZATION ) ) {
        new_m->v.usage |= USE_MEMORY;
    }
    new_m->v.block_usage = EMPTY;
    new_m->v.conflict = NULL;
    if( class == CG_LBL || class == CG_CLB ) {
        new_m->v.usage |= USE_MEMORY; /* so not put in conflict graph*/

⌨️ 快捷键说明

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