s37temps.c

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

C
471
字号
/****************************************************************************
*
*                            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 "procdef.h"
#include "cfloat.h"
#include "opcodes.h"
#include "sysmacro.h"

#include "s37temps.def"

extern  void            *SortList(void*,unsigned int,bool(*)(void*,void*));
extern  void            CountTempRefs(void);
extern  void            PropLocal(name*);
extern  name            *AllocAddrConst(name*,int,constant_class,type_class_def);
extern  cfloat          *CFCnvU32F(unsigned_32);
extern  name            *SAllocIndex(name*,name*,type_length,type_class_def,type_length);
extern  instruction     *MakeMove(name*,name*,type_class_def);
extern  name            *DeAlias(name*);
extern  name            *AllocTemp(type_class_def);
extern  void            PrefixIns(instruction*,instruction*);
extern  name            *ScaleIndex(name*,name*,type_length,type_class_def,type_length,int,i_flags);
extern  instruction     *MakeBinary(opcode_defs,name*,name*,name*,type_class_def);
extern  name            *AllocRegName(hw_reg_set);
extern  hw_reg_set      DisplayReg(void);
extern  void            FindReferences();
extern  void            DoNothing( instruction* );

extern  proc_def        *CurrProc;
extern  block           *HeadBlock;
extern  name            *Names[];

#define SLACK           (1*1024)
#define _4K             (4*1024)

#define SAFE            (_4K-SLACK)

static  name            *NoseIn;
static  bool            NoseInAdded;


static  bool    TempBigger( name *t1, name *t2 ) {
/************************************************/

    return( t1->n.size > t2->n.size );
}


static  void    SortTemps() {
/****************************
    Sort the temporaries by size
*/

    Names[ N_TEMP ] = SortList( Names[ N_TEMP ], offsetof( name, n.next_name ),
                                TempBigger );
}


extern  void    PushLocals() {
/*****************************
    Intentionally a stub for 370 version
*/

}


extern  void    SetTempLocation( name *temp, type_length size ) {
/****************************************************************
    Grab a temp off the stack and set its location
*/

    temp->t.location = CurrProc->locals.size + CurrProc->locals.base;
    CurrProc->locals.size += size;
}


extern  void    RelocParms() {
/*****************************
    Relocate parameter locations based on what type of prolog we generated,
    how many registers were pushed on the stack, and all that other stuff
    figured out by GenProlog and TempStrategy
*/

    name        *temp;

    if( CurrProc->state.attr & (ROUTINE_ALTERNATE_AR) ) return;
    for( temp = Names[ N_TEMP ]; temp != NULL; temp = temp->n.next_name ) {
        if( ( temp->v.usage & HAS_MEMORY ) == 0 ) continue;
        if( temp->t.temp_flags & (STACK_PARM|FAR_LOCAL) ) continue;
        if( temp == NoseIn ) continue;
        temp->t.location += CurrProc->parms.size;
    }
}


extern  void    AdjustConsts( type_length size ) {
/*************************************************
    There were some instructions left in HeadBlock of the form
    MOV const => temp, to be used to get access to parms/autos that aren't
    addressable with a register +- 4K. Once we have figured out exactly
    where all our temporaries are going to be, we know what to set
    these constants to.
*/

    name        *cons;

    for( cons = Names[ N_CONSTANT ]; cons != NULL; cons = cons->n.next_name ) {
        if( cons->c.const_type == CONS_OFFSET ) {
            cons->c.const_type = CONS_ABSOLUTE;
            cons->c.int_value *= _4K;
            cons->c.int_value += size;
            cons->c.value = CFCnvU32F( cons->c.int_value );
        }
    }
}


extern type_length FarLocalSize()
/*******************************/
{
    if( NoseIn == NULL || NoseInAdded ) return( CurrProc->targ.far_local_size );
    return( CurrProc->targ.far_local_size + NoseIn->n.size );
}


extern  bool    AdjustFarLocals( type_length size ) {
/****************************************************
    Set the location of NoseIn now that temp locations are known(see OnTheEdge).
*/

    NoseInAdded = TRUE;
    if( NoseIn == NULL ) return( FALSE );
    NoseIn->t.location = size;
    size += NoseIn->n.size;
    CurrProc->targ.far_local_size += NoseIn->n.size;
    AdjustConsts( size );
    return( TRUE );
}



extern  void    AdjustNearLocals( type_length size ) {
/****************************************************
    Bump up the offset of each near local to adjust for the save area
*/
    name        *temp;

    for( temp = Names[ N_TEMP ]; temp != NULL; temp = temp->n.next_name ) {
        if( ( temp->v.usage & HAS_MEMORY ) == 0 ) continue;
        if( temp->t.temp_flags & (STACK_PARM|FAR_LOCAL) ) continue;
        temp->t.location += size;
    }
}



static  void    AddAliasRefs() {
/*******************************

    Add the reference count of any alias to its master temporaries
    reference count, to simplify the subsequent computations.
*/

    name        *temp;
    name        *alias;

    for( temp = Names[ N_TEMP ]; temp != NULL; temp = temp->n.next_name ) {
        if( temp->t.temp_flags & ALIAS ) continue;
        alias = temp->t.alias;
        while( alias != temp ) {
            temp->t.u.ref_count += alias->t.u.ref_count;
            alias = alias->t.alias;
        }
    }
}


static  void    ThrowOutBigTemps( type_length temp_size ) {
/**********************************************************
    Mark temporaries as needing an expensive reference, biggest to smallest,
    until we can address the rest cheaply (within 4K area).
*/

    name        *temp;
    name        *alias;

    NoseIn = NULL;
    for( temp = Names[ N_TEMP ]; temp != NULL; temp = temp->n.next_name ) {
        if( temp_size <= SAFE ) break;
        if( temp->t.temp_flags & (STACK_PARM|ALIAS) ) continue;
        temp_size -= temp->n.size;
        NoseIn = temp;
        alias = temp;
        do {
            alias->t.temp_flags |= VISITED;
            alias = alias->t.alias;
        } while( alias != temp );
    }
}


static  void    ThrowOutParms() {
/********************************
    We're going to be bumping AR past the parameters, so all parameters
    need an expensive reference.
*/

⌨️ 快捷键说明

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