bldins.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 818 行 · 第 1/2 页
C
818 行
/****************************************************************************
*
* 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: Turn expression tree into pseudo-assembly instructions.
*
****************************************************************************/
#include "standard.h"
#include "cgdefs.h"
#include "model.h"
#include "coderep.h"
#include "procdef.h"
#include "sysmacro.h"
#include "opcodes.h"
#include "addrname.h"
#include "memcheck.h"
#include "cfloat.h"
#include "regset.h"
#include "rttable.h"
#include "rtclass.h"
#include "feprotos.h"
#include "addrfold.h"
#include "bldins.h"
extern void FPNotStack(name*);
extern an MakeConst(pointer,type_def*);
extern uint Length(char*);
extern an MakeAddrName(cg_class,sym_handle,type_def*);
extern an MakeTypeTempAddr(name*,type_def*);
extern void GenKillLabel(pointer);
extern void GenBlock(int,int);
extern void AddTarget(label_handle,bool);
extern void Generate(bool);
extern void EnLink(label_handle,bool);
extern label_handle AskForNewLabel( void );
extern void AddIns(instruction*);
extern instruction *MakeNop( void );
extern void BigLabel( void );
extern void BigGoto(int);
extern bool TGIsAddress( void );
extern instruction *MakeBinary(opcode_defs,name*,name*,name*,type_class_def);
extern name *GenIns(an);
extern type_class_def TypeClass(type_def*);
extern an InsName(instruction*,type_def*);
extern an MakePoints(an,type_def*);
extern void FixCodePtr(an);
extern void NamesCrossBlocks( void );
extern instruction *MakeCondition(opcode_defs,name*,name*,int,int,type_class_def);
extern an MakeGets(an,an,type_def*);
extern an AddrDuplicate(an);
extern an AddrCopy(an);
extern void AddrFree(an);
extern an AddrSave(an);
extern void AddrDemote(an);
extern instruction *MakeMove(name*,name*,type_class_def);
extern name *AllocIntConst(int);
extern name *AllocS32Const(signed_32);
extern name *AllocS64Const( unsigned_32 low, unsigned_32 high );
extern name *AllocU64Const( unsigned_32 low, unsigned_32 high );
extern instruction *MakeUnary(opcode_defs,name*,name*,type_class_def);
extern instruction *MakeConvert(name*,name*,type_class_def,type_class_def);
extern instruction *MakeNary(opcode_defs,name*,name*,name*,type_class_def,type_class_def,int);
extern instruction *NewIns(int);
extern name *AllocTemp(type_class_def);
extern bool BlkTooBig( void );
extern bool NeedPtrConvert(an,type_def*);
extern type_def *TypeAddress(cg_type );
extern name *AllocRegName( hw_reg_set );
extern name *AllocMemory(pointer,type_length,cg_class,type_class_def);
extern hw_reg_set ReturnAddrReg( void );
extern hw_reg_set ScratchReg( void );
extern hw_reg_set StackReg( void );
extern hw_reg_set VarargsHomePtr( void );
extern an RegName( hw_reg_set, type_def *);
extern label_handle RTLabel( int );
extern name *AllocIndex( name *, name *, type_length, type_class_def );
extern bool BlockByBlock;
extern block *CurrBlock;
extern block *BlockList;
extern proc_def *CurrProc;
extern type_def *TypeInteger;
extern type_def *TypeNone;
extern bool HaveCurrBlock;
static void BoolFree( bn b );
static type_def *LastCmpType;
static unsigned_32 UnrollValue = 0;
extern an BGVarargsBasePtr( type_def *tipe ) {
/**************************************************/
an addr;
addr = RegName( VarargsHomePtr(), tipe );
return( addr );
}
extern an BGStackValue( type_def *tipe ) {
/**********************************************/
an addr;
addr = RegName( StackReg(), tipe );
return( addr );
}
extern an BGInteger( signed_32 value, type_def *tipe ) {
/***********************************************************/
pointer cf;
if( tipe->attr & TYPE_SIGNED ) {
cf = CFCnvI32F( value );
} else {
cf = CFCnvU32F( value );
}
return( MakeConst( cf, tipe ) );
}
extern an BGInt64( signed_64 value, type_def *tipe ) {
/***********************************************************/
name *cname;
if( tipe->attr & TYPE_SIGNED ) {
cname = AllocS64Const( value.u._32[I64LO32],value.u._32[I64HI32] );
} else {
cname = AllocU64Const( value.u._32[I64LO32],value.u._32[I64HI32] );
}
return( AddrName( cname, tipe ) );
}
extern an BGFloat( char *value, type_def *tipe ) {
/********************************************************/
return( MakeConst( CFCnvSF( value, value + Length( value ) ), tipe ) );
}
extern an BGName( cg_class cl, pointer sym, type_def *tipe ) {
/*******************************************************************/
return( MakeAddrName( cl, sym, tipe ) );
}
extern an BGTempName( name *temp, type_def *tipe ) {
/*************************************************************/
temp->v.usage |= USE_IN_ANOTHER_BLOCK;
return( MakeTypeTempAddr( temp, tipe ) );
}
extern bool FiniLabel( label_handle lbl, block *blk ) {
/*********************************************************/
int i;
i = blk->targets;
while( --i >= 0 ) {
if( blk->edge[ i ].destination == lbl ) {
blk->edge[ i ].flags |= DEST_LABEL_DIES;
return( TRUE );
}
}
if( blk->label == lbl ) {
blk->edge[ 0 ].flags |= BLOCK_LABEL_DIES;
return( TRUE );
}
return( FALSE );
}
extern void BGFiniLabel( label_handle lbl ) {
/***********************************************/
block *blk;
if( HaveCurrBlock && FiniLabel( lbl, CurrBlock ) ) return;
blk = BlockList;
while( blk != NULL ) {
if( FiniLabel( lbl, blk ) ) return;
blk = blk->prev_block;
}
GenKillLabel( lbl );
}
extern bool NeedConvert( type_def *from, type_def *to ) {
/*********************************************************/
if( from == to ) return( FALSE );
if( from->attr & TYPE_FLOAT ) return( TRUE );
if( to->attr & TYPE_FLOAT ) return( TRUE );
if( from->length != to->length ) return( TRUE );
#if _TARGET & _TARG_IAPX86
if( ( to->attr & TYPE_POINTER ) != ( from->attr & TYPE_POINTER )
&& to->length != WORD_SIZE ) return( TRUE ); /* long <=> pointer */
#endif
return( FALSE );
}
static cg_name Unary( cg_op op, an left, type_def *tipe ) {
/**********************************************************/
instruction *ins;
an res;
ins = MakeNary( op, GenIns( left ), NULL, NULL,
TypeClass( tipe ), TypeClass( left->tipe ), 1 );
res = InsName( ins, tipe );
AddIns( ins );
BGDone( left );
return( res );
}
static an CnvRnd( an name, type_def *tipe, cg_op op ) {
/***********************************************************/
if( NeedConvert( name->tipe, tipe ) ) {
name = Unary( op, name, tipe );
} else if( name->tipe != tipe ) {
AddrDemote( name ); /* it's not quite the right type */
}
name->tipe = tipe;
return( name );
}
extern name *BGNewTemp( type_def *tipe ) {
/************************************************/
name *temp;
temp = AllocTemp( TypeClass( tipe ) );
if( temp->n.size == 0 ) {
temp->n.size = tipe->length;
}
return( temp );
}
extern temp_name *BGGlobalTemp( type_def *tipe ) {
/*******************************************************/
name *temp;
temp = BGNewTemp( tipe );
temp->v.usage |= USE_IN_ANOTHER_BLOCK;
return( &(temp->t) );
}
static an FlowOut( bn node, type_def *tipe ) {
/**************************************************/
name *temp;
label_handle lbl;
lbl = AskForNewLabel();
temp = BGNewTemp( tipe );
temp->v.usage |= USE_IN_ANOTHER_BLOCK;
AddIns( MakeMove( AllocIntConst( FETrue() ), temp, temp->n.name_class ) );
*(node->t) = CurrBlock->label;
GenBlock( JUMP, 1 );
AddTarget( lbl, FALSE );
EnLink( AskForNewLabel(), TRUE );
AddIns( MakeMove( AllocIntConst( 0 ), temp, temp->n.name_class ) );
*(node->f) = CurrBlock->label;
GenBlock( JUMP, 1 );
AddTarget( lbl, FALSE );
EnLink( lbl, TRUE );
NamesCrossBlocks();
BoolFree( node );
return( AddrName( temp, tipe ) );
}
extern an Arithmetic( an name, type_def *tipe ) {
/*****************************************************/
if( name->format == NF_BOOL ) {
if( ( tipe->attr & TYPE_FLOAT ) != 0
|| ( tipe->length > TypeInteger->length ) ) {
name = FlowOut( (bn)name, TypeInteger );
name = Unary( O_CONVERT, name, tipe );
} else {
name = FlowOut( (bn)name, tipe );
}
}
return( name );
}
extern bn BGCompare( cg_op op, an left, an rite,
label_handle entry, type_def *tipe ) {
/*****************************************************************************/
bn new;
instruction *ins;
name *newleft;
name *newrite;
LastCmpType = tipe;
newleft = GenIns( left );
newrite = GenIns( rite );
BGDone( left );
BGDone( rite );
NamesCrossBlocks();
ins = MakeCondition( op, newleft, newrite, 0, 1, TypeClass( tipe ) );
AddIns( ins );
GenBlock( CONDITIONAL, 2 );
_Alloc( new, sizeof( bool_node ) );
AddTarget( NULL, FALSE );
AddTarget( NULL, FALSE );
new->format = NF_BOOL;
new->e = entry;
new->t = &CurrBlock->edge[ 0 ].destination;
new->f = &CurrBlock->edge[ 1 ].destination;
EnLink( AskForNewLabel(), TRUE );
return( new );
}
extern bn Boolean( an node, label_handle entry ) {
/******************************************************/
if( node->format != NF_BOOL ) {
node = (an) BGCompare( O_NE, node, BGInteger( 0, node->tipe ),
entry, node->tipe );
}
return( (bn) node );
}
extern label_handle BGGetEntry( void ) {
/************************************/
return( CurrBlock->label );
}
extern void BG3WayControl( an node, label_handle lt,
label_handle eq, label_handle gt ) {
/*****************************************************************/
instruction *ins;
name *op;
label_handle lbl;
type_class_def class;
node = Arithmetic( node, node->tipe );
class = TypeClass( node->tipe );
NamesCrossBlocks();
op = GenIns( node );
BGDone( node );
ins = NULL;
#if _TARGET & _TARG_80386
if( class == FS ) {
ins = MakeCondition( OP_BIT_TEST_FALSE, op,
AllocS32Const( 0x7FFFFFFFL ),
0, 1, SW );
}
#endif
if( ins == NULL ) {
ins = MakeCondition( OP_CMP_EQUAL, op, AllocIntConst( 0 ), 0, 1, class );
}
AddIns( ins );
GenBlock( CONDITIONAL, 2 );
AddTarget( eq, FALSE );
lbl = AskForNewLabel();
AddTarget( lbl, FALSE );
EnLink( lbl, TRUE );
#if _TARGET & _TARG_80386
if( class == FS ) {
class = SW;
}
#endif
ins = MakeCondition( OP_CMP_LESS, op, AllocIntConst( 0 ), 0, 1, class );
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?