fcflow.c

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

C
641
字号
/****************************************************************************
*
*                            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:  simple control structure F-Code processor
*
****************************************************************************/


#include "ftnstd.h"
#include "global.h"
#include "fcgbls.h"
#include "wf77defs.h"
#include "wf77cg.h"
#include "tmpdefs.h"
#include "wf77labe.h"
#include "cgflags.h"
#include "fcodes.h"
#include "cpopt.h"
#include "fmemmgr.h"
#include "emitobj.h"
#include "inout.h"
#include "errcod.h"
#include "ferror.h"
#include "fctypes.h"

//=================== Back End Code Generation Routines ====================

extern  label_handle    BENewLabel(void);
extern  back_handle     BENewBack(sym_handle);
extern  void            BEFiniBack(back_handle);
extern  void            BEFreeBack(back_handle);
extern  void            BEFiniLabel(label_handle);
extern  void            CGControl(cg_op,cg_name,label_handle);
extern  void            CGDone(cg_name);
extern  cg_name         CGAssign(cg_name,cg_name,cg_type);
extern  cg_name         CGUnary(cg_op,cg_name,cg_type);
extern  cg_name         CGFEName(sym_handle,cg_type);
extern  cg_name         CGInteger(signed_32,cg_type);
extern  cg_name         CGBackName(back_handle,cg_type);
extern  cg_name         CGCompare(cg_op,cg_name,cg_name,cg_type);
extern  cg_name         CG3WayControl(cg_name,label_handle,label_handle,
                                      label_handle);
extern  cg_name         CGWarp(cg_name,label_handle,cg_name);
extern  cg_name         CGBinary(cg_op,cg_name,cg_name,cg_type);
extern  void            CGTrash(cg_name);
extern  sel_handle      CGSelInit(void);
extern  void            CGSelCase(sel_handle,label_handle,signed_32);
extern  void            CGSelect(sel_handle,cg_name);
extern  void            CGSelOther(sel_handle,label_handle);
extern  cg_name         CGEval(cg_name);

//=========================================================================

extern  cg_name         XPopValue(cg_type);
extern  cg_name         XPop(void);
extern  void            XPush(cg_name);
extern  cg_name         SymAddr(sym_id);
extern  cg_name         ImagPtr(cg_name,cg_type);
extern  cg_name         Concat(uint,cg_name);
extern  bool            TypeCmplx(TYPE);
extern  void            DoSelect(FCODE);
extern  unsigned_32     GetStmtNum(sym_id);
extern  void            XPopCmplx(cg_cmplx *,cg_type);
extern  cg_type         CmplxBaseType(cg_type);
extern  bool            IntType(PTYPE);
extern  void            FCodeSequence(void);
extern  void            SplitCmplx(cg_name,cg_type);
extern  tmp_handle      MkTmp(cg_name,cg_type);
extern  cg_name         TmpPtr(tmp_handle,cg_type);
extern  cg_name         TmpVal(tmp_handle,cg_type);
extern  cg_type         CmplxBaseType(cg_type);

extern  unsigned_8      CGFlags;

static  obj_ptr         WarpReturn;


void    InitLabels( void ) {
//====================

// Initialize label processing.

    LabelList = NULL;
}


void    FiniLabels( int label_type ) {
//====================================

// Free specified class of labels.

    label_entry **owner;
    label_entry *curr;

    owner = &LabelList;
    for(;;) {
        curr = *owner;
        if( curr == NULL ) break;
        if( ( curr->label & FORMAT_LABEL ) == label_type ) {
            if( ( CGFlags & CG_FATAL ) == 0 ) {
                if( curr->label & FORMAT_LABEL ) {
                    BEFiniBack( curr->handle );
                    BEFreeBack( curr->handle );
                } else {
                    InfoError( CP_ERROR, "unfreed label" );
                    BEFiniLabel( curr->handle );
                }
            }
            *owner = curr->link;
            FMemFree( curr );
        } else {
            owner = &curr->link;
        }
    }
}


static  label_entry     *FindLabel( int label ) {
//===============================================

// Search for given label.

    label_entry *le;

    le = LabelList;
    for(;;) {
        if( le == NULL ) break;
        if( ( le->label & ~FORMAT_LABEL ) == label ) break;
        le = le->link;
    }
    if( le == NULL ) {
        le = FMemAlloc( sizeof( label_entry ) );
        le->label = label;
        le->handle = NULL;
        le->link = LabelList;
        LabelList = le;
    }
    return( le );
}


label_handle    GetLabel( label_id label ) {
//==========================================

// Get a label.

    label_entry *le;

    le = FindLabel( label );
    if( le->handle == NULL ) {
        le->handle = BENewLabel();
    }
    return( le->handle  );
}


void    FCJmpFalse( void ) {
//====================

    unsigned_16 typ_info;
    cg_type     typ;
    cg_name     bool_expr;

    typ_info = GetU16();
    typ = GetType( typ_info );
    if( IntType( typ_info ) ) {
        bool_expr = CGCompare( O_NE, XPopValue( typ ),
                               CGInteger( 0, typ ), typ );
    } else {
        bool_expr = XPopValue( typ );
    }
    CGControl( O_IF_FALSE, bool_expr, GetLabel( GetU16() ) );
}


void    FCJmpAlways( void ) {
//=====================

    CGControl( O_GOTO, NULL, GetLabel( GetU16() ) );
}


label_handle    GetStmtLabel( sym_id sn ) {
//=========================================

// Get a statement label.

    return( GetLabel( sn->st.address ) );
}


void    FCStmtJmpAlways( void ) {
//=========================

    sym_id      sn;

    sn = GetPtr();
    CGControl( O_GOTO, NULL, GetStmtLabel( sn ) );
    RefStmtLabel( sn );
}


void    FCDefineLabel( void ) {
//=======================

    CGControl( O_LABEL, NULL, GetLabel( GetU16() ) );
}


void    FCStmtDefineLabel( void ) {
//===========================

    sym_id      sn;

    sn = GetPtr();
    CGControl( O_LABEL, NULL, GetStmtLabel( sn ) );
    RefStmtLabel( sn );
}


back_handle     GetFmtLabel( label_id label ) {
//=============================================

// Get a format label.

    label_entry *le;

    le = FindLabel( label );
    if( le->handle == NULL ) {
        le->handle = BENewBack( NULL );
        le->label |= FORMAT_LABEL;
    }
    return( le->handle  );
}


void    FCAssign( void ) {
//==================

// Process ASSIGN statement.

    sym_id      stmt;

    stmt = GetPtr();
    if( stmt->st.flags & SN_FORMAT ) {
        CGDone( CGAssign( SymAddr( GetPtr() ),
                          CGBackName( GetFmtLabel( stmt->st.address ),
                                      T_LOCAL_POINTER ),
                          T_LOCAL_POINTER ) );
    } else {
        CGDone( CGAssign( SymAddr( GetPtr() ),
                          CGInteger( stmt->st.address, T_INTEGER ),
                          T_INTEGER ) );
        RefStmtLabel( stmt );
    }
}


void    FCIfArith( void ) {
//===================

// Set up control structure for arithmetic if.

    cg_name     if_expr;
    sym_id      lt;
    sym_id      eq;
    sym_id      gt;
    cg_type     typ;

    typ = GetType( GetU16() );
    if_expr = XPopValue( typ );
    lt = GetPtr();
    eq = GetPtr();
    gt = GetPtr();
    if( lt == gt ) {
        CGControl( O_IF_TRUE,
                   CGCompare( O_EQ, if_expr, CGInteger( 0, typ ), typ ),
                   GetStmtLabel( eq ) );
        CGControl( O_GOTO, NULL, GetStmtLabel( lt ) );
    } else if( lt == eq ) {
        CGControl( O_IF_TRUE,
                   CGCompare( O_GT, if_expr, CGInteger( 0, typ ), typ ),
                   GetStmtLabel( gt ) );
        CGControl( O_GOTO, NULL, GetStmtLabel( eq ) );
    } else if( eq == gt ) {
        CGControl( O_IF_TRUE,
                   CGCompare( O_LT, if_expr, CGInteger( 0, typ ), typ ),
                   GetStmtLabel( lt ) );
        CGControl( O_GOTO, NULL, GetStmtLabel( eq ) );
    } else {
        CG3WayControl( if_expr, GetStmtLabel( lt ), GetStmtLabel( eq ),
                       GetStmtLabel( gt ) );
    }
    RefStmtLabel( lt );
    RefStmtLabel( eq );
    RefStmtLabel( gt );
}

⌨️ 快捷键说明

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