s37proc.c

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

C
724
字号
/****************************************************************************
*
*                            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 "procdef.h"
#include "model.h"
#include "rtclass.h"
#include "offset.h"
#include "s37bead.h"
#include "zoiks.h"

#include "s37proc.def"

#define _4K     (4*1024)
#define DWORD_SIZE (2*WORD_SIZE)

extern  sym_handle      AskForLblSym(label_handle);
extern  void            RelocParms();
extern  hw_sym          *CodeLabel(label_handle,unsigned);
extern  unsigned        DepthAlign(unsigned);
extern  bead_drop       *HWDrop(char);
extern  bead_using      *HWUsing(hw_sym *,char);
extern  void            CodeLineNum(unsigned_16);
extern  seg_id          SetOP(seg_id);
extern  seg_id          AskCodeSeg();
extern  hw_reg_set      SaveRegs();
extern  hw_reg_set      StackReg();
extern  int             RegTrans(hw_reg_set);
extern  bool            AdjustFarLocals(type_length);
extern  void            AdjustNearLocals(type_length);
extern  ref_any         *HWLitIntGen(offset,int);
extern  hw_reg_set      FixedRegs();
extern  hw_reg_set      LNReg();
extern  void            HWStartProc(void );
extern  void            HWEpilogue(void );
extern  void            HWEndProc(void );
extern  void            EmitRtnEnd();
extern  memory_name     *SAllocMemory(pointer,type_length,cg_class,type_class_def,type_length);
extern  name            *AllocAddrConst(name*,int,constant_class,type_class_def);
extern  label_handle    AskForNewLabel(void);
extern  seg_id          AskBackSeg(void);
extern  void            DataLabel(label_handle);
extern  void            DGUBytes(unsigned_32);
extern  void            GetOpName(hwins_op_any*,name*);
extern  label_handle    RTLabel(int);
extern  bool            FEStackChk(sym_handle);
extern  void            GetRALN(name*,char*,char*);
extern  type_length     FarLocalSize();

extern void HWInsGen( hwins_opcode hwop, hwins_op_any *op1,
                                         hwins_op_any *op2,
                                         hwins_op_any *op3);
/* debug */
extern  void            DumpString(char *);
extern  void            DumpNL();

extern  block           *HeadBlock;
extern  proc_def        *CurrProc;
extern  bool            BlockByBlock;
extern  type_length     MaxStack;

typedef struct {
        hw_reg_set      reg;
        int             i;
} float_save;

float_save      FloatSave[] = {
/*****************************/

        HW_D( HW_D0 ),  0,
        HW_D( HW_D2 ),  2,
        HW_D( HW_D4 ),  4,
        HW_D( HW_D6 ),  6,
        HW_D( HW_EMPTY ),  0
};

static hw_reg_set RegNames[] = {
/******************************/

    HW_D( HW_G0 ),
    HW_D( HW_G1 ),
    HW_D( HW_G2 ),
    HW_D( HW_G3 ),
    HW_D( HW_G4 ),
    HW_D( HW_G5 ),
    HW_D( HW_G6 ),
    HW_D( HW_G7 ),
    HW_D( HW_G8 ),
    HW_D( HW_G9 ),
    HW_D( HW_G10 ),
    HW_D( HW_G11 ),
    HW_D( HW_G12 ),
    HW_D( HW_G13 ),
    HW_D( HW_G14 ),
    HW_D( HW_G15 )
};

extern  void    GenProlog() {
/***************************/

    seg_id      old;

    old = SetOP( AskCodeSeg() );
    if( _IsModel( NUMBERS ) ) {
        CodeLineNum( HeadBlock->ins.hd.line_num );
    }
    if( _IsModel( INTERNAL_DBG_OUTPUT ) ) {
        DumpNL();
        DumpString( "===================================" );
        DumpNL();
    }
    HWStartProc();
    CurrProc->targ.using_label = CodeLabel( CurrProc->label, DepthAlign( 1 ) );
    CurrProc->parms.base = 0;
    CalcUsedRegs();
    MakeSaveArea();
    RelocParms();
    CurrProc->prolog_state |= GENERATED_PROLOG;
    SetOP( old );
}

extern  void    CalcUsedRegs() {
/******************************/


    block       *blk;
    instruction *ins;
    name        *result;
    hw_reg_set  used;

    HW_CAsgn( used, HW_EMPTY );
    blk = HeadBlock;
    while( blk != NULL ) {
        ins = blk->ins.hd.next;
        while( ins->head.opcode != OP_BLOCK ) {
            result = ins->result;
            if( result != NULL && result->n.class == N_REGISTER ) {
                HW_TurnOn( used, result->r.reg );
            }
            /* place holder for big label doesn't really zap anything*/
            if( ins->head.opcode != OP_NOP ) {
                HW_TurnOn( used, ins->zap->reg );
            }
            ins = ins->head.next;
        }
        blk = blk->next_block;
    }
    HW_TurnOn( CurrProc->state.used, used );
}


static  void    RefInt( hwins_op_any *hwop, offset i ) {
/******************************************************/

    hwop->sx.a = 0;
    hwop->sx.b = CurrProc->state.regs.LN;
    hwop->sx.ref = HWLitIntGen( i, WORD_SIZE );
    hwop->sx.disp = 0;
}


static long     DWord( long x ) {
/*******************************/

    return( ( x + ( DWORD_SIZE - 1 ) ) & ~( DWORD_SIZE - 1 ) );
}


static name *GetLabelAddress( hwins_op_any *phwop, label_handle lbl )
/******************************************************************/
{
    name                *mem;
    name                *cons;

    mem = SAllocMemory( lbl, 0, CG_LBL, WD, WORD_SIZE );
    cons = AllocAddrConst( mem, 0, CONS_ADDRESS, WD );
    GetOpName( phwop, cons );
    return( mem );
}


static void MakeStack( hwins_op_any *phwop )
/*****************************************/
{
    seg_id              old;
    label_handle        lbl;

    old = SetOP( AskBackSeg() );
    lbl = AskForNewLabel();
    DataLabel( lbl );
    DGUBytes( 72*WORD_SIZE );
    SetOP( old );
    GetLabelAddress( phwop, lbl );
}


#define SA_BACK_LINK    4
#define SA_FWD_LINK     8
#define SA_FIRST_REG    12
#define MAX_SA_WORDS    18

static int STMPos( int reg, int first_reg )
/*****************************************/
{
    int         position;

    position = reg - first_reg;
    if( position > 15 ) position -= 16;
    if( position < 0 ) position += 16;
    return( position );
}


static int RegPosOS( int reg, int first_reg )
/******************************************/
{
    return( SA_FIRST_REG + WORD_SIZE * STMPos( reg, first_reg ) );
}


static int RegPosCLink( int reg, int first_reg )
/**********************************************/
{
    return( WORD_SIZE * STMPos( reg, first_reg ) );
}


static void GetOSSTMOps( hwins_op_any *first_reg,
                         hwins_op_any *last_reg, hwins_op_any *sa_op )
/*****************************************************************/
{
    sa_op->r = CurrProc->state.regs.SA;
    first_reg->r = CurrProc->state.regs.SA + 1;
    if( first_reg->r > 15 ) first_reg->r -= 16;
    last_reg->r = CurrProc->state.regs.SA + 15;
    if( last_reg->r > 15 ) last_reg->r -= 16;
}


static void RegOffset( hwins_op_any *hwop, int offset, char reg )
/***************************************************************/
{
    hwop->sx.a = 0;
    hwop->sx.b = reg;
    hwop->sx.disp = offset;
    hwop->sx.ref  = NULL;
}


static void BranchAndLinkTo( int idx ) {
/**************************************/

    hwins_op_any        hwop;
    hwins_op_any        hwop2;
    name                *mem;
    char                ra,ln;

/*
    L           LN,=A(routine[idx])             - call routine to save/restore
    BALR        RA,LN                             registers 10 and 12
*/
    mem = GetLabelAddress( &hwop, RTLabel( idx-BEG_RTNS ) );
    GetRALN( mem, &ra, &ln );
    hwop2.r = ln;
    HWInsGen( HWOP_L, &hwop2, &hwop, NULL );
    hwop.r = ra;
    HWInsGen( HWOP_BALR, &hwop, &hwop2, NULL );
}


static bool NeedStackCheck()
/**************************/
{
    return( FEStackChk( AskForLblSym( CurrProc->label ) ) );
}


static bool AddTo( hwins_op_any *reg_op, long amt )
/**************************************************/
{
    hwins_op_any        hwop;

    if( amt == 0 ) return( FALSE );
    if( amt < _4K ) {
        RegOffset( &hwop, amt, reg_op->r );
        HWInsGen( HWOP_LA, reg_op, &hwop, NULL );
    } else {
        RefInt( &hwop, amt );
        HWInsGen( HWOP_A, reg_op, &hwop, NULL );
    }
    return( TRUE );
}


static bool SkipOverParms()
/************************/
{
    hwins_op_any        sp_op;

    if( CurrProc->state.attr & ROUTINE_ALTERNATE_AR ||
        CurrProc->targ.save_area >= _4K-(16*WORD_SIZE)-(4*DWORD_SIZE) ||
        NeedStackCheck() ) {

        sp_op.r = CurrProc->state.regs.SP;
        /*
            A        SP,PARM_SIZE       - bump SP past parms
        */
        CurrProc->targ.save_area -= CurrProc->parms.size;
        return( AddTo( &sp_op, CurrProc->parms.size ) );
    }
    return( FALSE );
}


static void StackCheck( int idx )
/*******************************/
{
    hwins_op_any        hwop;
    hwins_op_any        hwop2;

    RefInt( &hwop2,
              DWord( CurrProc->parms.size
                   + CurrProc->locals.size
                   + FarLocalSize() )
            + DWord( MAX_SA_WORDS*WORD_SIZE + 4*(DWORD_SIZE) )
            + DWord( MaxStack ) );
    hwop.r = CurrProc->state.regs.AR;
    HWInsGen( HWOP_L, &hwop, &hwop2, NULL );
    BranchAndLinkTo( idx );
}

⌨️ 快捷键说明

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