cgbkutil.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 1,074 行 · 第 1/3 页
C
1,074 行
SYMBOL dtor, // - destructor
cg_name var, // - expression to be DTOR'ed
unsigned cdtor ) // - CDTOR to be used
{
call_handle handle; // - call handle
handle = initDtorCall( dtor );
addDtorArgs( handle, dtor, var, cdtor );
return finiDtorCall( handle, cdtor );
}
static cg_name cgCommaSideEffect( // CONSTRUCT COMMA/SIDE-EFFECT EXPRESSION
cg_name lhs, // - expression on left
cg_name rhs, // - expression on right
cg_type type, // - type of right expression
cg_op opcode ) // - type of opcode
{
cg_name expr; // - result
if( NULL == lhs ) {
expr = rhs;
} else if( NULL == rhs ) {
expr = lhs;
} else {
expr = CGBinary( opcode, lhs, rhs, type );
}
return expr;
}
cg_name CgComma( // CONSTRUCT COMMA EXPRESSION
cg_name lhs, // - expression on left
cg_name rhs, // - expression on right
cg_type type ) // - type of right expression
{
return cgCommaSideEffect( lhs, rhs, type, O_COMMA );
}
void CgCommaWithTopExpr( // PUSH COMMA'D EXPRESSION WITH TOP EXPR
cg_name expr, // - rhs expression
cg_type type ) // - rhs type
{
cg_name lhs; // - lhs expression
if( CgExprPopGarbage() ) {
lhs = NULL;
} else {
lhs = CgExprPop();
}
CgExprPush( CgComma( lhs, expr, type ), type );
}
cg_name CgSideEffect( // CONSTRUCT SIDE-EFFECT EXPRESSION
cg_name lhs, // - expression on left
cg_name rhs, // - expression on right
cg_type type ) // - type of right expression
{
#if 0
return cgCommaSideEffect( lhs, rhs, type, O_SIDE_EFFECT );
#else
cg_name expr; // - result
if( NULL == lhs ) {
expr = rhs;
} else if( NULL == rhs ) {
expr = lhs;
} else {
temp_handle handle; // - handle
expr = CgSaveAsTemp( &handle, lhs, type );
expr = CgComma( expr, rhs, type );
expr = CgComma( expr, CgFetchTemp( handle, type ), type );
}
return expr;
#endif
}
// when expr is non-null, top of stack is replaced by:
//
// COMMA
// | |
// +---------+ +-------+
// | |
// COMMA temp
// | |
// +----+ +----+
// | |
// ASSIGN expr
// | |
// +-+ +-+
// | |
// temp top
//
void CgCommaOptional( // EMIT OPTIONAL COMMA'ED EXPRESSION
cg_name expr, // - expression or NULL
cg_type type ) // - type of expression
{
cg_name orig; // - original expression
cg_type orig_type; // - original expression type
if( expr != NULL ) {
if( ! CgExprPopGarbage() ) {
orig = CgExprPopType( &orig_type );
expr = CgSideEffect( orig, expr, type );
}
CgExprPush( expr, type );
}
}
void CgCommaBefore( // EMIT COMMA'ED EXPRESSION BEFORE
cg_name expr, // - expression
cg_type type ) // - type of above expression
{
cg_name top_expr; // - expression on top
cg_type top_type; // - type on top
top_expr = CgExprPopType( &top_type );
if( top_expr == NULL ) {
if( expr != NULL ) {
CgDone( expr, type );
}
} else {
CgExprPush( CgComma( expr, top_expr, top_type ), top_type );
}
}
SYMBOL CgBackOpDelete( // GET ADDRESIBLE OPERATOR DELETE FOR A TYPE
TYPE type ) // - the type
{
SEARCH_RESULT* result; // - lookup result
SYMBOL op_del; // - operator delete
result = ScopeFindNaked( TypeScope( type )
, CppOperatorName( CO_DELETE ) );
op_del = ClassFunMakeAddressable( result->sym_name->name_syms );
ScopeFreeResult( result );
return op_del;
}
cg_name CgAssignStateVar( // ASSIGN STATE-VAR VALUE
SYMBOL blk, // - R/W Block
SE* se, // - state entry
target_offset_t offset ) // - offset of state variable
{
return CGLVAssign( CgSymbolPlusOffset( blk, offset )
, CgOffset( SeStateVar( se ) )
, CgTypeOffset() );
}
//***********************************************************************
// Code Generation Support -- run-time calls
//***********************************************************************
void CgRtCallInit( // SET UP A R/T CALL
RT_DEF *def, // - definition for call
RTF rt_code ) // - code for run/time call
{
SYMBOL sym; // - symbol for run/time call
sym = RunTimeCallSymbol( rt_code );
def->type = CgTypeOutput( SymFuncReturnType( sym ) );
def->handle = CGInitCall( CgSymbol( sym )
, def->type
, (cg_sym_handle)sym );
}
void CgRtParam( // SET UP A PARAMETER
cg_name expr, // - expression gen'ed
RT_DEF *def, // - definition for call
cg_type type ) // - argument type
{
addArgument( def->handle, expr, type );
}
void CgRtParamConstOffset( // SET UP PARAMETER: CONSTANT OFFSET
RT_DEF *def, // - definition for call
unsigned value ) // - parameter value
{
CgRtParam( CgOffset( value ), def, CgTypeOffset() );
}
void CgRtParamAddrSym( // SET UP PARAMETER: ADDR( SYMBOL )
RT_DEF *def, // - definition for call
SYMBOL sym ) // - symbol
{
CgRtParam( CgAddrSymbol( sym ), def, T_POINTER );
}
cg_name CgRtCallExec( // EXECUTE R/T CALL
RT_DEF *def ) // - definition for call
{
CgBackCallGened( def->handle );
return CgFetchType( CGCall( def->handle ), def->type );
}
void CgRtCallExecDone( // EXECUTE R/T CALL, THEN DONE
RT_DEF *def ) // - definition for call
{
CgDone( CgRtCallExec( def ), def->type );
}
void CgRtCallExecNoArgs( // EXECUTE R/T CALL, WITHOUT ARGUMENTS
RTF rt_code ) // - code for run/time call
{
RT_DEF def; // - call definition
CgRtCallInit( &def, rt_code );
CgRtCallExecDone( &def );
}
//***********************************************************************
// General support
//***********************************************************************
cg_name CgDtorStatic( // DTOR STATIC OBJECT
SYMBOL sym ) // - object symbol
{
STAB_CTL sctl; // - state-table instance
STAB_DEFN dctl; // - state-table definition
RT_DEF def; // - control for run-time call
SE* se; // - state entry
StabCtlInit( &sctl, &dctl );
StabDefnInit( &dctl, DTRG_STATIC_INITLS );
#ifndef NDEBUG
if( PragDbgToggle.dump_stab ) {
printf( "State Table for static object: %x\n", &dctl.state_table );
}
#endif
sctl.rw = CgVarRw( CgbkInfo.size_rw_base + CgbkInfo.size_data_ptr
, SC_STATIC );
dctl.ro = CgVarRo( 1, SC_STATIC, NULL );
se = SeAlloc( DTC_SYM_STATIC );
se->base.gen = TRUE;
se->sym_static.sym = sym;
se->sym_static.dtor = RoDtorFind( sym );
se = StateTableAdd( se, &sctl );
StabGenerate( &sctl );
CgBackGenLabelInternal( sctl.rw );
DgInitBytes( CgbkInfo.size_data_ptr, 0 );
DgPtrSymData( dctl.ro );
DgOffset( 1 );
DgPtrSymData( sym );
CgRtCallInit( &def, RTF_REG_LCL );
CgRtParamAddrSym( &def, sctl.rw );
return CgRtCallExec( &def );
}
void CgDtorAll( // DTOR ALL IN FUNCTION
void )
{
RT_DEF def; // - call definition
CgRtCallInit( &def, RTF_DTOR_ALL );
#if _CPU == _AXP
CgRtParamAddrSym( &def, FstabExcRw() );
#endif
CgRtCallExecDone( &def );
}
void CgDtorSe( // DTOR UNTIL SE ENTRY
SE* bound ) // - bounding entry
{
RT_DEF def; // - call definition
CgRtCallInit( &def, RTF_DTOR );
CgRtParamConstOffset( &def, SeStateOptimal( bound ) );
#if _CPU == _AXP
CgRtParamAddrSym( &def, FstabExcRw() );
#endif
CgRtCallExecDone( &def );
}
#if _CPU == 386
back_handle CgProfData( void )
/****************************/
{
FN_CTL *top;
top = FnCtlTop();
return( top->prof_data );
}
#endif
// The following can be extended for more types, if required
//
TYPE TypeFromCgType( // GET C++ TYPE FOR cg_type
cg_type cgtype ) // - code-gen type
{
TYPE type; // - C++ type
switch( cgtype ) {
case T_UINT_1 :
type = GetBasicType( TYP_UCHAR );
break;
case T_INT_1 :
type = GetBasicType( TYP_SCHAR );
break;
case T_UINT_2 :
type = GetBasicType( TYP_USHORT );
break;
case T_INT_2 :
type = GetBasicType( TYP_SSHORT );
break;
case T_UINT_4 :
#if( TARGET_INT == 4 )
type = GetBasicType( TYP_UINT );
#else
type = GetBasicType( TYP_ULONG );
#endif
break;
case T_INT_4 :
#if( TARGET_INT == 4 )
type = GetBasicType( TYP_SINT );
#else
type = GetBasicType( TYP_SLONG );
#endif
break;
case T_INT_8 :
type = GetBasicType( TYP_SLONG64 );
break;
case T_UINT_8 :
type = GetBasicType( TYP_ULONG64 );
break;
case T_BOOLEAN :
case T_INTEGER :
type = GetBasicType( TYP_SINT );
break;
case TY_UNSIGNED :
type = GetBasicType( TYP_UINT );
break;
default :
type = MakeInternalType( BETypeLength( cgtype ) );
break;
}
return type;
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?