makeaddr.c

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

C
612
字号
/****************************************************************************
*
*                            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:  WHEN YOU FIGURE OUT WHAT THIS FILE DOES, PLEASE
*               DESCRIBE IT HERE!
*
****************************************************************************/


#include "standard.h"
#include "coderep.h"
#include "opcodes.h"
#include "cgdefs.h"
#include "model.h"
#include "addrname.h"
#include "procdef.h"
#include "sysmacro.h"
#include "zoiks.h"
#include "freelist.h"
#include "cfloat.h"
#include "feprotos.h"

#include "addrfold.h"

static    pointer       *AddrNameFrl;

extern    an            AddrList;
extern    name          *Names[];
extern    proc_def      *CurrProc;
extern    block         *CurrBlock;

extern  type_class_def  TypeClass(type_def*);
extern  name            *SAllocTemp(type_class_def,type_length);
extern  name            *SAllocUserTemp(pointer,type_class_def,type_length);
extern  instruction     *MakeUnary(opcode_defs,name*,name*,type_class_def);
extern  instruction     *MakeMove(name*,name*,type_class_def);
extern  type_def        *TypeAddress(cg_type);
extern  name            *AllocConst(pointer);
extern  void            FreeIns(instruction*);
extern  void            AddIns(instruction*);
extern  name            *MakeDisplay(name*,int);
extern  name            *BGNewTemp(type_def*);
extern  name            *AllocIntConst(int);
extern  name            *AllocS32Const(signed_32);
extern  name            *SAllocMemory(pointer,type_length,cg_class,type_class_def,type_length);
extern  name            *AllocTemp(type_class_def);
extern  void            AllocALocal(name*);
extern  byte            *Copy(void*,void*,uint);
extern  instruction     *MakeBinary(opcode_defs,name*,name*,name*,type_class_def);
extern  void            BGDone(an);
extern  cg_type         NamePtrType( name *op );
extern  name            *AllocRegName( hw_reg_set );


static  void    CopyAddr( an src, an dst )
/****************************************/
{
    an  link;

    link = dst->link;
    Copy( src, dst, sizeof( address_name ) );
    dst->link = link;
}


extern  an      NewAddrName( void )
/*********************************/
{
    an  addr;

    addr = AllocFrl( &AddrNameFrl, sizeof( address_name ) );
    addr->link = AddrList;
    AddrList = addr;
    addr->tipe = NULL;
    addr->index = NULL;
    addr->offset = 0;
    addr->u.name = NULL;
    addr->format = NF_ADDR;
    addr->flags = 0;
    addr->base = NULL;
    addr->alignment = 0;
    return( addr );
}


extern  an      MakeTypeTempAddr( name *op, type_def *tipe )
/**********************************************************/
{
    an          addr;

    addr = NewAddrName();
    addr->tipe = tipe;
    addr->format = NF_ADDR;
    addr->u.name = op;
    addr->class = CL_ADDR_TEMP;
    return( addr );
}


extern  an      MakeTempAddr( name *op, type_def *tipe )
/******************************************************/
{
    tipe = tipe;
    return( MakeTypeTempAddr( op, TypeAddress( T_NEAR_POINTER ) ) );
}


extern  void    InitMakeAddr( void )
/**********************************/
{
    InitFrl( &AddrNameFrl );
    AddrList = NULL;
}


extern  name    *GenIns( an addr )
/********************************/
{
    return( GetValue( addr, NULL ) );
}


extern  void    AddrFree( an node )
/*********************************/
{
    an  *owner;

    owner = &AddrList;
    for( ;; ) {
        if( *owner == node ) {
            *owner = node->link;
            break;
        }
        owner = &(*owner)->link;
    }
    if( node->format == NF_INS ) {
        FreeIns( node->u.ins );
    }
    FrlFreeSize( &AddrNameFrl, (pointer *)node, sizeof( address_name ) );
}


extern  void    InsToAddr( an addr )
/**********************************/
{
    an          new;
    instruction *ins;

    if( addr->format == NF_INS ) {
        ins = addr->u.ins;
        ins->result = BGNewTemp( addr->tipe );
        new = AddrName( ins->result, addr->tipe );
        new->flags = addr->flags;
        new->base = addr->base;
        new->alignment = addr->alignment;
        CopyAddr( new, addr );
        AddrFree( new );
    }
}


extern  void    NamesCrossBlocks( void )
/**************************************/
{
    an          addr;
    an          new;
    an          next;
    name        *temp;

    addr = AddrList;
    while( addr != NULL ) { /* Careful. The list shifts under our feet.*/
        next = addr->link;
        if( addr->flags & ADDR_OK_ACROSS_BLOCKS ) {
            addr->flags |= ADDR_CROSSED_BLOCKS;
        } else if( addr->format == NF_INS ) {
            InsToAddr( addr );
            addr->u.name->v.usage |= USE_IN_ANOTHER_BLOCK;
        } else if( addr->format != NF_CONS
             && addr->format != NF_BOOL
             && ( addr->format != NF_ADDR
                || ( addr->class != CL_ADDR_GLOBAL
                  && addr->class != CL_ADDR_TEMP ) ) ) {
            temp = GenIns( addr );
            if( temp->n.class == N_TEMP ) {
                temp->v.usage |= USE_IN_ANOTHER_BLOCK;
            } else if( temp->n.class == N_INDEXED ) {
                if( temp->i.index->n.class == N_TEMP ) {
                    temp->i.index->v.usage
                        |= USE_IN_ANOTHER_BLOCK;
                }
            }
            new = AddrName( temp, addr->tipe );
            CopyAddr( new, addr );
            AddrFree( new );
        }
        addr = next;
    }
}


extern  bool    AddrFrlFree( void )
/*********************************/
{
    return( FrlFreeAll( &AddrNameFrl, sizeof( address_name ) ) );
}


static  name    *Display( sym_handle symbol, int level )
/******************************************************/
{
    proc_def    *proc;
    name        *op;
    name        *names;

    proc = CurrProc;
    while( level != CurrProc->lex_level ) {
        CurrProc = CurrProc->next_proc;
    }
    names = Names[  N_TEMP  ];
    Names[  N_TEMP  ] = CurrProc->names[  N_TEMP  ];
    op = Names[  N_TEMP  ];
    while( op->v.symbol != symbol ) {
        op = op->n.next_name;
    }
    op->v.usage |= ( NEEDS_MEMORY | USE_MEMORY | USE_IN_ANOTHER_BLOCK);
    AllocALocal( op );
    CurrProc = proc;
    Names[  N_TEMP  ] = names;
    return( MakeDisplay( op, level ) );
}


extern  an      MakeGets( an dst, an src, type_def *tipe )
/********************************************************/
{
    name                *dst_name;
    name                *src_name;
    instruction         *ins;
    type_class_def      class;
    name                *temp;

    InsToAddr( dst );
    dst_name = Points( dst, tipe );
    ins = src->u.ins;
    if( src->format == NF_INS && CurrBlock->ins.hd.prev == ins ) {
        ins->result = dst_name;
        src->format = NF_ADDR;  /*% so instruction doesn't get freed!*/
    } else {
        src_name = GetValue( src, dst_name );
        if( src_name != dst_name ) {
            class = TypeClass( tipe );
            src_name = GenIns( src );
            if( dst_name->n.class == N_INDEXED &&
             !( dst_name->i.index_flags & X_VOLATILE ) ) {
                /* don't give him back an indexed name - it extends the life of*/
                /* a pointer*/
                temp = SAllocTemp( dst_name->n.name_class, dst_name->n.size );
                AddIns( MakeMove( src_name, dst_name, class ) );
                AddIns( MakeMove( dst_name, temp, class ) );
                dst_name = temp;
            } else {
                AddIns( MakeMove( src_name, dst_name, class ) );
            }
        }
    }
    BGDone( src );
    BGDone( dst );
    return( AddrName( dst_name, tipe ) );
}


extern  an      MakeConst( pointer cf, type_def *tipe )
/*****************************************************/
{
    return( AddrName( AllocConst( cf ), tipe ) );
}


extern  an      MakePoints( an name, type_def *tipe )
/***************************************************/
{
    an  new;

⌨️ 快捷键说明

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