gflow.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 371 行
C
371 行
/****************************************************************************
*
* 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!
*
****************************************************************************/
//
// GFLOW : control flow code generation routines
//
#include "ftnstd.h"
#include "fcodes.h"
#include "global.h"
#include "fcgbls.h"
#include "opn.h"
#include "cpopt.h"
#include "recog.h"
#include "emitobj.h"
#include "utility.h"
extern void GSPProlog(void);
extern sym_id StaticAlloc(uint,TYPE);
extern label_id NextLabel(void);
extern bool TypeCmplx(TYPE typ);
extern TYPE MapTypes(TYPE,uint);
void GLabel( int label ) {
//===========================
// Generate a label.
EmitOp( FC_DEFINE_LABEL );
OutU16( label );
}
void GStmtLabel( sym_id stmt ) {
//=================================
// Generate a statement label.
EmitOp( FC_STMT_DEFINE_LABEL );
GStmtAddr( stmt );
}
void GStmtBr( sym_id stmt ) {
//==============================
// Generate a branch to a statement label.
EmitOp( FC_STMT_JMP_ALWAYS );
GStmtAddr( stmt );
}
void GBranch( int label ) {
//============================
// Generate a branch (non-conditional).
EmitOp( FC_JMP_ALWAYS );
OutU16( label );
}
void GBrFalse( int label ) {
//=============================
// Generate a branch on FALSE.
EmitOp( FC_JMP_FALSE );
GenType( CITNode );
OutU16( label );
}
void G3WayBranch( sym_id lt, sym_id eq, sym_id gt ) {
//======================================================
// Generate a 3-way branch.
IfExpr();
EmitOp( FC_IF_ARITH );
GenType( CITNode );
GStmtAddr( lt );
GStmtAddr( eq );
GStmtAddr( gt );
}
void InitSelect( void ) {
//====================
// Initialize SELECT statement.
sym_id sel_expr;
if( !AError ) {
if( CITNode->opn.ds == DSOPN_NAM ) {
// must be a variable name
CSHead->cs_info.cases->sel_expr = CITNode->sym_ptr;
} else {
if( CITNode->typ == TY_CHAR ) {
sel_expr = StaticAlloc( 1, TY_CHAR );
CSHead->cs_info.cases->sel_expr = sel_expr;
PushSym( sel_expr );
EmitOp( FC_CHAR_1_MOVE );
DumpType( TY_INTEGER_1, 1 );
OutPtr( NULL );
} else {
sel_expr = StaticAlloc( CITNode->size,
MapTypes( TY_INTEGER, CITNode->size));
CSHead->cs_info.cases->sel_expr = sel_expr;
PushOpn( CITNode );
EmitOp( FC_POP ); // pop select expression into temporary
OutPtr( sel_expr );
DumpTypes( MapTypes( TY_INTEGER, CITNode->size ), CITNode->size,
CITNode->typ, CITNode->size );
}
EmitOp( FC_EXPR_DONE );
}
GBranch( CSHead->branch ); // branch to "select table"
}
}
void FiniSelect( void ) {
//====================
// Terminate SELECT statement.
int count;
obj_ptr curr_obj;
case_entry *ptr;
GLabel( CSHead->branch ); // label start of select table
if( CSHead->typ == CS_COMPUTED_GOTO ) {
EmitOp( FC_COMPUTED_GOTO );
} else {
EmitOp( FC_SELECT );
}
curr_obj = ObjTell();
OutU16( 0 ); // emit count
count = 0;
ptr = CSHead->cs_info.cases;
OutU16( ptr->label.g_label ); // label for default case
ptr = ptr->link;
while( ptr != NULL ) { // emit lab,hi,lo for ea. case
if( CSHead->typ == CS_COMPUTED_GOTO ) {
GStmtAddr( ptr->label.st_label );
} else {
OutU16( ptr->label.g_label );
}
OutConst32( ptr->high );
OutConst32( ptr->low );
count++;
ptr = ptr->link;
}
curr_obj = ObjSeek( curr_obj );
OutU16( count );
ObjSeek( curr_obj );
OutPtr( CSHead->cs_info.cases->sel_expr );
}
void GAsgnGoTo( bool list ) {
//==============================
// Generate an ASSIGNed GOTO.
if( !list ) {
if( WildLabel == NULL ) {
WildLabel = StaticAlloc( sizeof( inttarg ), TY_INTEGER_TARG );
}
EmitOp( FC_PUSH );
OutPtr( CITNode->sym_ptr );
EmitOp( FC_POP );
OutPtr( WildLabel );
DumpTypes( TY_INTEGER_TARG, sizeof( inttarg ), CITNode->typ, CITNode->size );
EmitOp( FC_EXPR_DONE );
GBranch( StNumbers.branches ); // goto select table
} else {
EmitOp( FC_ASSIGNED_GOTO_LIST );
OutPtr( CITNode->sym_ptr );
}
}
void GStmtAddr( sym_id stmtno ) {
//==================================
// Generate an entry in the statement table.
if( stmtno != NULL ) {
OutPtr( stmtno );
}
}
void GEndBrTab( void ) {
//===================
// Mark the end of the statement table.
OutPtr( NULL );
}
void GAssign( sym_id label ) {
//===============================
// Generate an ASSIGN <label> to I.
EmitOp( FC_ASSIGN );
OutPtr( label );
OutPtr( CITNode->sym_ptr );
}
void GBreak( FCODE routine ) {
//=====================================
// Generate a STOP or a PAUSE.
EmitOp( routine );
if( RecNOpn() ) {
OutPtr( NULL );
} else {
OutPtr( CITNode->sym_ptr );
CITNode->sym_ptr->lt.flags |= LT_SCB_REQUIRED;
}
}
void GStartSF( void ) {
//==================
// Start a statement function.
EmitOp( FC_START_SF );
if( OZOpts & OZOPT_O_INLINE ) {
SFSymId->ns.si.sf.sequence = ObjTell();
OutObjPtr( 0 );
} else {
OutPtr( SFSymId );
SFSymId->ns.si.sf.location = NextLabel();
OutU16( NextLabel() );
}
}
void GEndSF( void ) {
//================
// Terminate a statement function.
obj_ptr curr_obj;
if( OZOpts & OZOPT_O_INLINE ) {
EmitOp( FC_END_OF_SEQUENCE );
curr_obj = ObjSeek( SFSymId->ns.si.sf.sequence );
OutObjPtr( curr_obj );
ObjSeek( curr_obj );
} else {
if( TypeCmplx( SFSymId->ns.typ ) ) {
EmitOp( FC_CMPLX_EXPR_DONE );
} else {
EmitOp( FC_EXPR_DONE );
}
EmitOp( FC_END_SF );
OutPtr( SFSymId );
}
}
void GStartBlock( void ) {
//=====================
// Start a REMOTE BLOCK.
EmitOp( FC_START_RB );
OutPtr( CITNode->sym_ptr );
}
void GExecute( void ) {
//==================
// Execute a REMOTE BLOCK.
EmitOp( FC_EXECUTE );
OutPtr( CITNode->sym_ptr );
}
void GEndBlock( void ) {
//===================
// Terminate a REMOTE-block.
EmitOp( FC_END_RB );
}
void GPgmLabel( void ) {
//===================
// Generate a program label.
EmitOp( FC_PROLOGUE );
OutPtr( SubProgId );
}
void GSegLabel( void ) {
//===================
// Generate a subprogram label.
EmitOp( FC_PROLOGUE );
OutPtr( SubProgId );
}
void GBlockLabel( void ) {
//=====================
// Generate a block data subprogram label.
EmitOp( FC_PROLOGUE );
OutPtr( SubProgId );
}
void FreeLabel( int label ) {
//==============================
// Generate F-Code indicating we are done with label.
EmitOp( FC_FREE_LABEL );
OutU16( label );
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?