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 + -
显示快捷键?