fcdo.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 178 行
C
178 行
/****************************************************************************
*
* 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!
*
****************************************************************************/
//
// FCDO : DO loop F-Code processor
//
#include "ftnstd.h"
#include "wf77defs.h"
#include "cg.h"
#include "tmpdefs.h"
#include "symbol.h"
#include "emitobj.h"
#include "fctypes.h"
//=================== Back End Code Generation Routines ====================
extern void CGDone(cg_name);
extern cg_name CGCompare(cg_op,cg_name,cg_name,cg_type);
extern void CGControl(cg_op,cg_name,label_handle);
extern cg_name CGAssign(cg_name,cg_name,cg_type);
extern cg_name CGBinary(cg_op,cg_name,cg_name,cg_type);
extern cg_name CGInteger(signed_32,cg_type);
extern cg_name CGEval(cg_name);
extern cg_name CGTrash(cg_name);
//=========================================================================
extern cg_name GetTypedValue(void);
extern cg_name SymValue(sym_id);
extern cg_name SymAddr(sym_id);
extern label_handle GetLabel(label_id);
void FCDoBegin( void ) {
//===================
// Initialize DO loop processing.
cg_name e1;
cg_name e2;
cg_name e3;
sym_id do_var;
sym_id increment;
sym_id loop_ctrl;
label_handle top;
label_handle bottom;
cg_type do_type;
intstar4 incr_value;
int cmp_op;
cg_name tmp;
do_var = GetPtr();
increment = GetPtr();
if( increment == NULL ) {
incr_value = GetConst32();
loop_ctrl = GetPtr();
} else {
loop_ctrl = GetPtr();
e3 = CGEval( GetTypedValue() );
}
e2 = CGEval( GetTypedValue() );
e1 = GetTypedValue();
top = GetLabel( GetU16() );
bottom = GetLabel( GetU16() );
do_type = F772CGType( do_var );
CGTrash( CGAssign( SymAddr( do_var ), e1, do_type ) );
if( increment == NULL ) { // INTEGER DO variable/constant increment
if( incr_value < 0 ) {
cmp_op = O_GE;
} else {
cmp_op = O_LE;
}
CGDone( CGAssign( SymAddr( loop_ctrl ), e2, do_type ) );
CGControl( O_LABEL, NULL, top );
CGControl( O_IF_FALSE,
CGCompare( cmp_op, SymValue( do_var ), SymValue( loop_ctrl ),
do_type ),
bottom );
} else {
// compute: e2 - e1
tmp = CGBinary( O_MINUS, e2, SymValue( do_var ), do_type ); // e2 - e1
// compute: e2 - e1 + e3
tmp = CGBinary( O_PLUS, tmp, CGAssign( SymAddr( increment ),
e3, do_type ), do_type );
// compute: ( e2 - e1 + e3 ) / e3
tmp = CGBinary( O_DIV, tmp, SymValue( increment ), do_type );
// set type of interation count
if( !_IsTypeInteger( do_var->ns.typ ) ) {
do_type = T_INT_4;
}
// save interation count
tmp = CGAssign( SymAddr( loop_ctrl ), tmp, do_type );
// goto bottom of loop if iteration count <= 0
tmp = CGCompare( O_GT, tmp, CGInteger( 0, T_INTEGER ), do_type );
CGControl( O_IF_FALSE, tmp, bottom );
CGControl( O_LABEL, NULL, top );
}
}
void FCDoEnd( void ) {
//=================
// Terminal DO loop processing.
sym_id do_var;
sym_id increment;
sym_id iteration;
label_handle top;
cg_type do_type;
intstar4 incr_value;
cg_name tmp;
do_var = GetPtr();
increment = GetPtr();
if( increment == NULL ) {
incr_value = GetConst32();
} else {
iteration = GetPtr();
}
top = GetLabel( GetU16() );
do_type = F772CGType( do_var );
if( increment == NULL ) { // INTEGER DO variable with constant increment
CGDone( CGAssign( SymAddr( do_var ),
CGBinary( O_PLUS, SymValue( do_var ),
CGInteger( incr_value, do_type ),
do_type ),
do_type ) );
CGControl( O_GOTO, NULL, top );
} else {
// compute: do_var += increment
tmp = CGBinary( O_PLUS, SymValue( do_var ), SymValue( increment ),
do_type );
CGDone( CGAssign( SymAddr( do_var ), tmp, do_type ) );
// set type of iteration
if( !_IsTypeInteger( do_var->ns.typ ) ) {
do_type = T_INT_4;
}
// compute: --iteration
tmp = CGBinary( O_MINUS, SymValue( iteration ),
CGInteger( 1, T_INTEGER ), do_type );
tmp = CGAssign( SymAddr( iteration ), tmp, do_type );
// goto top of loop if iteration != 0
tmp = CGCompare( O_EQ, tmp, CGInteger( 0, T_INTEGER ), do_type );
CGControl( O_IF_FALSE, tmp, top );
}
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?