void PragManyRegSets( // GET PRAGMA REGISTER SETS void ) { hw_reg_set buff[ MAXIMUM_PARMSETS ]; int i; hw_reg_set list; hw_reg_set *sets; list = PragRegList(); i = 0; while( !HW_CEqual( list, HW_EMPTY ) && ( i != MAXIMUM_PARMSETS ) ) { buff[ i++ ] = list; list = PragRegList(); } if( !HW_CEqual( list, HW_EMPTY ) ) { CErr1( ERR_TOO_MANY_PARM_SETS ); } HW_CAsgn( buff[i], HW_EMPTY ); i++; i *= sizeof( hw_reg_set ); sets = ( hw_reg_set * ) CMemAlloc( i ); memcpy( sets, buff, i ); if( !IsAuxParmsBuiltIn( CurrInfo->parms ) ) { CMemFree( CurrInfo->parms ); } CurrInfo->parms = sets; }
hw_reg_set MustSaveRegs( void ) /**********************************/ { hw_reg_set save; hw_reg_set tmp; HW_CAsgn( save, HW_FULL ); HW_TurnOff( save, CurrProc->state.modify ); HW_CTurnOff( save, HW_UNUSED ); if( CurrProc->state.attr & ROUTINE_MODIFY_EXACT ) { HW_TurnOff( save, CurrProc->state.return_reg ); } else { tmp = CurrProc->state.parm.used; HW_TurnOn( tmp, CurrProc->state.return_reg ); tmp = FullReg( tmp ); HW_TurnOff( save, tmp ); } tmp = StackReg(); HW_TurnOff( save, tmp ); if( HW_CEqual( CurrProc->state.return_reg, HW_EMPTY ) ) { tmp = ReturnReg( WD, _NPX( CurrProc->state.attr ) ); HW_TurnOff( save, tmp ); } tmp = CurrProc->state.unalterable; HW_TurnOff( tmp, DisplayReg() ); HW_TurnOff( tmp, StackReg() ); HW_TurnOff( save, tmp ); return( save ); }
static void writeAuxInfo( AUX_INFO *info, unsigned index ) { hw_reg_set *regs; hw_reg_set *save_parms; char *save_objname; unsigned len; info->index = index; save_parms = info->parms; save_objname = info->objname; if( save_parms != NULL ) { len = 0; regs = save_parms; for(;;) { len += sizeof( hw_reg_set ); if( HW_CEqual( *regs, HW_EMPTY ) ) break; ++regs; } info->parms = PCHSetUInt( len ); } if( save_objname != NULL ) { info->objname = PCHSetUInt( strlen( save_objname ) + 1 ); } PCHWriteVar( *info ); AsmSysPCHWriteCode( info ); if( save_parms != NULL ) { PCHWrite( save_parms, PCHGetUInt( info->parms ) ); } if( save_objname != NULL ) { PCHWrite( save_objname, PCHGetUInt( info->objname ) ); } info->parms = save_parms; info->objname = save_objname; }
static void CompressSets( reg_tree *tree ) /********************************************/ { hw_reg_set *src; hw_reg_set *dst; int i; if( tree != NULL ) { CompressSets( tree->lo ); CompressSets( tree->hi ); if( tree->regs != NULL ) { dst = tree->regs; src = dst; for( i = REG_COUNT; i > 0; --i ) { if( !HW_CEqual( *src, HW_EMPTY ) ) { *dst++ = *src; } ++src; } while( dst != src ) { HW_CAsgn( *dst++, HW_EMPTY ); } } } }
void UpdateReturn( call_state *state, type_def *tipe, type_class_def type_class, aux_handle aux ) /**************************************************************************************************/ { hw_reg_set normal; if( _FPULevel( FPU_87 ) && _NPX( state->attr ) && (tipe->attr & TYPE_FLOAT) ) { HW_COnlyOn( state->return_reg, HW_ST0 ); } else { HW_CTurnOff( state->return_reg, HW_FLTS ); } if( tipe == TypeNone ) { if( HW_CEqual( state->return_reg, HW_EMPTY ) ) return; FEMessage( MSG_BAD_RETURN_REGISTER, aux ); HW_CAsgn( state->return_reg, HW_EMPTY ); state->attr &= ~ROUTINE_HAS_SPECIAL_RETURN; } else if( type_class == XX ) { normal = ReturnReg( WD, _NPX( state->attr ) ); if( HW_Equal( state->return_reg, normal ) ) return; if( HW_CEqual( state->return_reg, HW_EMPTY ) ) return; // if( !HW_Ovlap( state->return_reg, state->unalterable ) && // IsRegClass( state->return_reg, WD ) ) // return; if( IsRegClass( state->return_reg, WD ) ) return; FEMessage( MSG_BAD_RETURN_REGISTER, aux ); state->return_reg = normal; state->attr &= ~ROUTINE_HAS_SPECIAL_RETURN; } else { normal = ReturnReg( type_class, _NPX( state->attr ) ); if( HW_Equal( state->return_reg, normal ) ) return; // if( !HW_Ovlap( state->return_reg, state->unalterable ) && // IsRegClass( state->return_reg, type_class ) ) // return; if( IsRegClass( state->return_reg, type_class ) ) return; FEMessage( MSG_BAD_RETURN_REGISTER, aux ); state->return_reg = normal; state->attr &= ~ROUTINE_HAS_SPECIAL_RETURN; } }
bool ScAddOk( hw_reg_set reg1, hw_reg_set reg2 ) /********************************************************** Is it ok to say that "reg1" = "reg2"? This is not ok for unalterable registers since there may be hidden modifications of these registers. */ { if( HW_Ovlap( reg1, CurrProc->state.unalterable ) ) { if( !HW_CEqual( reg1, HW_DS ) && !HW_CEqual( reg1, HW_SS ) ) { return( false ); } } if( HW_Ovlap( reg2, CurrProc->state.unalterable ) ) { if( !HW_Equal( reg2, HW_DS ) && !HW_Equal( reg2, HW_SS ) ) { return( false ); } } return( true ); }
static void DumpRgSet( hw_reg_set *possible ) /**************************************************/ { if( possible != NULL ) { DumpLiteral( " Choices " ); for( ; !HW_CEqual( *possible, HW_EMPTY ); ++possible ) { DumpRegName( *possible ); DumpChar( ' ' ); } } }
static void DumpRgSet( hw_reg_set *possible ) /**************************************************/ { if( possible != NULL ) { DumpLiteral( " Choices " ); while( !HW_CEqual( *possible, HW_EMPTY ) ) { DumpRegName( *possible ); ++ possible; DumpLiteral( " " ); } } }
bool IsRegClass( hw_reg_set regs, type_class_def type_class ) /**************************************************************/ { hw_reg_set *list; for( list = RegSets[IsSets[type_class]]; !HW_CEqual( *list, HW_EMPTY ); ++list ) { if( HW_Equal( *list, regs ) ) { return( true ); } } return( false ); }
static bool HasSegRegs( reg_tree *tree ) { hw_reg_set *regs; regs = tree->regs; if( regs != NULL ) { for( ; !HW_CEqual( *regs, HW_EMPTY ); ++regs ) { if( HW_COvlap( *regs, HW_SEGS ) ) return( true ); } } return( false ); }
extern void DumpInOut( instruction *ins ) { /*********************************************/ DumpLiteral( " " ); DumpGBit( &ins->head.live.out_of_block ); DumpChar( ' ' ); DumpLBit( &ins->head.live.within_block ); if( !HW_CEqual( ins->head.live.regs, HW_EMPTY ) && !HW_COvlap( ins->head.live.regs, HW_UNUSED ) ) { DumpLiteral( " " ); DumpRegName( ins->head.live.regs ); } DumpNL(); }
extern hw_reg_set ParmInLineReg( parm_state *state ) { /**********************************************************/ hw_reg_set regs; regs = *state->curr_entry; if( !HW_CEqual( regs, HW_EMPTY ) ) { state->curr_entry++; } regs = InLineParm( regs, state->used ); HW_TurnOn( state->used, regs ); return( regs ); }
static void CopyAuxInfo( void ) /*****************************/ { hw_reg_set default_flt_n_seg; hw_reg_set flt_n_seg; if( CurrEntry == NULL ) { // Redefining a built-in calling convention } else { CurrInfo = (struct aux_info *)CMemAlloc( sizeof( struct aux_info ) ); *CurrInfo = *CurrAlias; } if( AuxInfo.code != NULL ) { CurrInfo->code = AuxInfo.code; } if( AuxInfoFlg.f_near ) { CurrInfo->cclass &= ~FAR; } if( AuxInfoFlg.f_routine_pops ) { CurrInfo->cclass &= ~CALLER_POPS; } if( AuxInfoFlg.f_caller_return ) { CurrInfo->cclass &= ~ROUTINE_RETURN; } if( AuxInfoFlg.f_8087_returns ) { CurrInfo->cclass &= ~NO_8087_RETURNS; } CurrInfo->cclass |= AuxInfo.cclass; CurrInfo->flags |= AuxInfo.flags; if( AuxInfo.objname != NULL ) CurrInfo->objname = AuxInfo.objname; if( AuxInfo.cclass & SPECIAL_RETURN ) CurrInfo->returns = AuxInfo.returns; if( AuxInfo.cclass & SPECIAL_STRUCT_RETURN ) CurrInfo->streturn = AuxInfo.streturn; if( AuxInfo.parms != NULL ) CurrInfo->parms = AuxInfo.parms; if( !HW_CEqual( AuxInfo.save, HW_EMPTY ) ) { HW_CTurnOn( CurrInfo->save, HW_FULL ); if( !( AuxInfo.cclass & MODIFY_EXACT ) && !CompFlags.save_restore_segregs ) { HW_Asgn( default_flt_n_seg, WatcallInfo.save ); HW_CAsgn( flt_n_seg, HW_FLTS ); HW_CTurnOn( flt_n_seg, HW_SEGS ); HW_TurnOff( CurrInfo->save, flt_n_seg ); HW_OnlyOn( default_flt_n_seg, flt_n_seg ); HW_TurnOn( CurrInfo->save, default_flt_n_seg ); } HW_TurnOff( CurrInfo->save, AuxInfo.save ); } }
bool IsIndexReg( hw_reg_set reg, type_class_def type_class, bool is_temp_index ) /*********************************************************************************/ { hw_reg_set *dregs; /* unused parameters */ (void)type_class; (void)is_temp_index; for( dregs = &DWordRegs[0]; !HW_CEqual( *dregs, HW_EMPTY ); ++dregs ) { if( HW_Equal( *dregs, reg ) ) { return( true ); } } return( false ); }
static int CountRegs( hw_reg_set regs ) /*************************************/ { hw_reg_set *curr; int count; count = 0; for( curr = PushRegs; !HW_CEqual( *curr, HW_EMPTY ); ++curr ) { if( HW_Ovlap( *curr, regs ) ) { count++; } } return( count ); }
hw_reg_set *PragManyRegSets( void ) /*********************************/ { int i; hw_reg_set list; hw_reg_set *sets; hw_reg_set buff[ MAXIMUM_PARMSETS ]; list = PragRegList(); i = 0; while( !HW_CEqual( list, HW_EMPTY ) && ( i != MAXIMUM_PARMSETS ) ) { buff[ i++ ] = list; list = PragRegList(); } if( !HW_CEqual( list, HW_EMPTY ) ) { CErr1( ERR_TOO_MANY_PARM_SETS ); } HW_CAsgn( buff[ i ], HW_EMPTY ); i++; i *= sizeof( hw_reg_set ); sets = (hw_reg_set *)CMemAlloc( i ); memcpy( sets, buff, i ); return( sets ); }
static byte Displacement( signed_32 val, hw_reg_set regs ) /************************************************************/ { HW_CTurnOff( regs, HW_SEGS ); if( val == 0 && !HW_CEqual( regs, HW_BP ) ) return( D0 ); if( val <= 127 && val >= -128 ) { AddByte( val & 0xff ); return( D8 ); } else { val &= 0xffff; AddByte( val ); AddByte( val >> 8 ); return( D16 ); } }
extern void RegKill( score *scoreboard, hw_reg_set regs ) { /*************************************************************/ score_reg *entry; score_list *curr_list; score_list **owner; int i; list_head **free_heads; if( !HW_CEqual( regs, HW_EMPTY ) ) { entry = *ScoreList; free_heads = (list_head **)&scoreboard[ ScoreCount ]; for( i = ScoreCount; i > 0; --i ) { if( HW_Ovlap( entry->reg, regs ) ) { if( scoreboard->list != NULL ) { if( scoreboard->next_reg == scoreboard ) { ScoreFreeList( scoreboard ); } else { scoreboard->list = *free_heads; *free_heads = (list_head *)**free_heads; *scoreboard->list = NULL; } } scoreboard->prev_reg->next_reg = scoreboard->next_reg; scoreboard->next_reg->prev_reg = scoreboard->prev_reg; scoreboard->next_reg = scoreboard; scoreboard->prev_reg = scoreboard; scoreboard->generation = 0; } else { owner = scoreboard->list; for( ; ; ) { curr_list = *owner; if( curr_list == NULL ) break; if( curr_list->info.index_reg != NO_INDEX && HW_Ovlap( ScoreList[ curr_list->info.index_reg ]->reg, regs ) ) { *owner = curr_list->next; FreeScListEntry( curr_list ); } else { owner = &curr_list->next; } } } ++entry; ++scoreboard; } } }
static void DumpRegs( hw_reg_set *regs ) { /********************************************/ int i; DumpLiteral( "Choices " ); if( regs != NULL ) { i = SET_SIZE; while( --i >= 0 ) { if( !HW_CEqual( *regs, HW_EMPTY ) ) { DumpRegName( *regs ); DumpLiteral( "," ); } ++regs; } } }
local void CopyParms( void ) /**************************/ { int i; hw_reg_set *regs; if( CurrInfo->parms != CurrAlias->parms ) return; if( IsAuxParmsBuiltIn( CurrInfo->parms ) ) return; for( i = 1, regs = CurrInfo->parms; !HW_CEqual( *regs, HW_EMPTY ); ++i, ++regs ) ; i *= sizeof( hw_reg_set ); regs = (hw_reg_set *)CMemAlloc( i ); memcpy( regs, CurrInfo->parms, i ); CurrInfo->parms = regs; }
type_class_def CallState( aux_handle aux, type_def *tipe, call_state *state ) /****************************************************************************/ { type_class_def class; uint i; hw_reg_set parms[24]; hw_reg_set *parm_src; hw_reg_set *parm_dst; state->unalterable = FixedRegs(); HW_CAsgn( state->modify, HW_FULL ); HW_TurnOff( state->modify, SavedRegs() ); HW_CTurnOff( state->modify, HW_UNUSED ); state->used = state->modify; /* anything not saved is used*/ state->attr = 0; i = 0; parm_src = ParmRegs(); parm_dst = &parms[0]; for(;;) { *parm_dst = *parm_src; if( HW_CEqual( *parm_dst, HW_EMPTY ) ) break; if( HW_Ovlap( *parm_dst, state->unalterable ) ) { FEMessage( MSG_BAD_SAVE, aux ); } HW_CTurnOff( *parm_dst, HW_UNUSED ); parm_dst++; parm_src++; i++; } i++; state->parm.table = CGAlloc( i*sizeof( hw_reg_set ) ); Copy( parms, state->parm.table, i * sizeof( hw_reg_set ) ); HW_CAsgn( state->parm.used, HW_EMPTY ); state->parm.curr_entry = state->parm.table; state->parm.offset = 0; InitPPCParmState( state ); class = ReturnClass( tipe, state->attr ); if( *(call_class *)FEAuxInfo( aux, CALL_CLASS ) & HAS_VARARGS ) { state->attr |= ROUTINE_HAS_VARARGS; } UpdateReturn( state, tipe, class, aux ); return( class ); }
static bool parmSetsIdentical( hw_reg_set *parms1, hw_reg_set *parms2 ) { if( parms1 == parms2 ) { return( TRUE ); } if( parms1 != NULL && parms2 != NULL ) { for(;;) { if( HW_Equal( *parms1, *parms2 ) ) { if( HW_CEqual( *parms1, HW_EMPTY ) ) { return( TRUE ); } ++parms1; ++parms2; } else { break; } } } return( FALSE ); }
hw_reg_set *AuxParmDup( // DUPLICATE AUX PARMS hw_reg_set *parms ) { unsigned amt; hw_reg_set *c; hw_reg_set *p; if( parms == NULL ) { return( parms ); } amt = sizeof( hw_reg_set ); c = parms; for(;;) { if( HW_CEqual( *c, HW_EMPTY ) ) break; ++c; amt += sizeof( hw_reg_set ); } p = CMemAlloc( amt ); memcpy( p, parms, amt ); return( p ); }
static void DumpRegs( hw_reg_set *regs ) { /********************************************/ int i; bool first; DumpLiteral( "Choices " ); if( regs != NULL ) { first = true; for( i = REG_COUNT; i > 0; --i ) { if( !HW_CEqual( *regs, HW_EMPTY ) ) { if( first ) { first = false; } else { DumpChar( ',' ); } DumpRegName( *regs ); } ++regs; } } }
void BGProcDecl( cg_sym_handle sym, type_def *tipe ) /*****************************************************/ { hw_reg_set reg; name *temp; type_class_def type_class; segment_id old_segid; label_handle lbl; SaveTargetModel = TargetModel; type_class = AddCallBlock( sym, tipe ); if( tipe != TypeNone ) { if( type_class == XX ) { if( CurrProc->state.attr & ROUTINE_ALLOCS_RETURN ) { old_segid = SetOP( AskBackSeg() ); lbl = AskForNewLabel(); DataLabel( lbl ); DGUBytes( tipe->length ); CurrProc->targ.return_points = (name *)SAllocMemory( lbl, 0, CG_LBL, TypeClass( tipe ), tipe->length ); SetOP( old_segid ); } else { reg = CurrProc->state.return_reg; if( HW_CEqual( reg, HW_EMPTY ) ) { temp = DoParmDecl( NULL, TypeInteger, HW_EMPTY ); } else { temp = AllocTemp( WD ); temp->v.usage |= USE_IN_ANOTHER_BLOCK; AddIns( MakeMove( AllocRegName( reg ), temp, WD ) ); HW_TurnOn( CurrProc->state.parm.used, reg ); } CurrProc->targ.return_points = temp; } } } if( CurrProc->state.attr & ROUTINE_FARSS ) { TargetModel |= FLOATING_SS; } }
static void BuildPossible( reg_tree *tree ) /*********************************************/ { hw_reg_set *src; hw_reg_set *dst; if( tree != NULL ) { BuildPossible( tree->lo ); BuildPossible( tree->hi ); if( tree->idx != RL_NUMBER_OF_SETS ) { tree->regs = AllocRegSet(); dst = tree->regs; for( src = RegSets[tree->idx]; !HW_CEqual( *src, HW_EMPTY ); ++src ) { *dst++ = *src; } *dst = *src; #ifndef NDEBUG if ( dst - tree->regs >= REG_COUNT ) { /* '>=' 'coz no increment before 'break' */ Zoiks( ZOIKS_143 ); } #endif } } }
extern void DumpRegName( hw_reg_set regname ) { /*************************************************/ bool first; hw_reg_set name; first = true; name = regname; if( !HW_COvlap( name, HW_UNUSED ) ) { while( !HW_CEqual( name, HW_EMPTY ) ) { if( first ) { first = false; } else { DumpChar( ':' ); } #if _TARGET & _TARG_370 if( Check(&name,HW_G0) ) { DumpLiteral( "G0" ); continue; } if( Check(&name,HW_G1) ) { DumpLiteral( "G1" ); continue; } if( Check(&name,HW_G2) ) { DumpLiteral( "G2" ); continue; } if( Check(&name,HW_G3) ) { DumpLiteral( "G3" ); continue; } if( Check(&name,HW_G4) ) { DumpLiteral( "G4" ); continue; } if( Check(&name,HW_G5) ) { DumpLiteral( "G5" ); continue; } if( Check(&name,HW_G6) ) { DumpLiteral( "G6" ); continue; } if( Check(&name,HW_G7) ) { DumpLiteral( "G7" ); continue; } if( Check(&name,HW_G8) ) { DumpLiteral( "G8" ); continue; } if( Check(&name,HW_G9) ) { DumpLiteral( "G9" ); continue; } if( Check(&name,HW_G10)) { DumpLiteral( "G10" ); continue; } if( Check(&name,HW_G11)) { DumpLiteral( "G11" ); continue; } if( Check(&name,HW_G12)) { DumpLiteral( "G12" ); continue; } if( Check(&name,HW_G13)) { DumpLiteral( "G13" ); continue; } if( Check(&name,HW_G14)) { DumpLiteral( "G14" ); continue; } if( Check(&name,HW_G15)) { DumpLiteral( "G15" ); continue; } if( Check(&name,HW_E0) ) { DumpLiteral( "E0" ); continue; } if( Check(&name,HW_E4) ) { DumpLiteral( "E4" ); continue; } if( Check(&name,HW_D0) ) { DumpLiteral( "D0" ); continue; } if( Check(&name,HW_D2) ) { DumpLiteral( "D2" ); continue; } if( Check(&name,HW_D4) ) { DumpLiteral( "D4" ); continue; } if( Check(&name,HW_D6) ) { DumpLiteral( "D6" ); continue; } if( Check(&name,HW_Y0) ) { DumpLiteral( "Y0" ); continue; } if( Check(&name,HW_Y2) ) { DumpLiteral( "Y2" ); continue; } if( Check(&name,HW_Y4) ) { DumpLiteral( "Y4" ); continue; } if( Check(&name,HW_Y6) ) { DumpLiteral( "Y6" ); continue; } #endif #if _TARGET & (_TARG_PPC | _TARG_AXP | _TARG_MIPS) if( Check(&name,HW_R0) ) { DumpLiteral( "R0" ); continue; } if( Check(&name,HW_R1) ) { DumpLiteral( "R1" ); continue; } if( Check(&name,HW_R2) ) { DumpLiteral( "R2" ); continue; } if( Check(&name,HW_R3) ) { DumpLiteral( "R3" ); continue; } if( Check(&name,HW_R4) ) { DumpLiteral( "R4" ); continue; } if( Check(&name,HW_R5) ) { DumpLiteral( "R5" ); continue; } if( Check(&name,HW_R6) ) { DumpLiteral( "R6" ); continue; } if( Check(&name,HW_R7) ) { DumpLiteral( "R7" ); continue; } if( Check(&name,HW_R8) ) { DumpLiteral( "R8" ); continue; } if( Check(&name,HW_R9) ) { DumpLiteral( "R9" ); continue; } if( Check(&name,HW_R10) ) { DumpLiteral( "R10" ); continue; } if( Check(&name,HW_R11) ) { DumpLiteral( "R11" ); continue; } if( Check(&name,HW_R12) ) { DumpLiteral( "R12" ); continue; } if( Check(&name,HW_R13) ) { DumpLiteral( "R13" ); continue; } if( Check(&name,HW_R14) ) { DumpLiteral( "R14" ); continue; } if( Check(&name,HW_R15) ) { DumpLiteral( "R15" ); continue; } if( Check(&name,HW_R16) ) { DumpLiteral( "R16" ); continue; } if( Check(&name,HW_R17) ) { DumpLiteral( "R17" ); continue; } if( Check(&name,HW_R18) ) { DumpLiteral( "R18" ); continue; } if( Check(&name,HW_R19) ) { DumpLiteral( "R19" ); continue; } if( Check(&name,HW_R20) ) { DumpLiteral( "R20" ); continue; } if( Check(&name,HW_R21) ) { DumpLiteral( "R21" ); continue; } if( Check(&name,HW_R22) ) { DumpLiteral( "R22" ); continue; } if( Check(&name,HW_R23) ) { DumpLiteral( "R23" ); continue; } if( Check(&name,HW_R24) ) { DumpLiteral( "R24" ); continue; } if( Check(&name,HW_R25) ) { DumpLiteral( "R25" ); continue; } if( Check(&name,HW_R26) ) { DumpLiteral( "R26" ); continue; } if( Check(&name,HW_R27) ) { DumpLiteral( "R27" ); continue; } if( Check(&name,HW_R28) ) { DumpLiteral( "R28" ); continue; } if( Check(&name,HW_R29) ) { DumpLiteral( "R29" ); continue; } if( Check(&name,HW_R30) ) { DumpLiteral( "R30" ); continue; } if( Check(&name,HW_R31) ) { DumpLiteral( "R31" ); continue; } if( Check(&name,HW_D0) ) { DumpLiteral( "D0" ); continue; } if( Check(&name,HW_D1) ) { DumpLiteral( "D1" ); continue; } if( Check(&name,HW_D2) ) { DumpLiteral( "D2" ); continue; } if( Check(&name,HW_D3) ) { DumpLiteral( "D3" ); continue; } if( Check(&name,HW_D4) ) { DumpLiteral( "D4" ); continue; } if( Check(&name,HW_D5) ) { DumpLiteral( "D5" ); continue; } if( Check(&name,HW_D6) ) { DumpLiteral( "D6" ); continue; } if( Check(&name,HW_D7) ) { DumpLiteral( "D7" ); continue; } if( Check(&name,HW_D8) ) { DumpLiteral( "D8" ); continue; } if( Check(&name,HW_D9) ) { DumpLiteral( "D9" ); continue; } if( Check(&name,HW_D10) ) { DumpLiteral( "D10" ); continue; } if( Check(&name,HW_D11) ) { DumpLiteral( "D11" ); continue; } if( Check(&name,HW_D12) ) { DumpLiteral( "D12" ); continue; } if( Check(&name,HW_D13) ) { DumpLiteral( "D13" ); continue; } if( Check(&name,HW_D14) ) { DumpLiteral( "D14" ); continue; } if( Check(&name,HW_D15) ) { DumpLiteral( "D15" ); continue; } if( Check(&name,HW_D16) ) { DumpLiteral( "D16" ); continue; } if( Check(&name,HW_D17) ) { DumpLiteral( "D17" ); continue; } if( Check(&name,HW_D18) ) { DumpLiteral( "D18" ); continue; } if( Check(&name,HW_D19) ) { DumpLiteral( "D19" ); continue; } if( Check(&name,HW_D20) ) { DumpLiteral( "D20" ); continue; } if( Check(&name,HW_D21) ) { DumpLiteral( "D21" ); continue; } if( Check(&name,HW_D22) ) { DumpLiteral( "D22" ); continue; } if( Check(&name,HW_D23) ) { DumpLiteral( "D23" ); continue; } if( Check(&name,HW_D24) ) { DumpLiteral( "D24" ); continue; } if( Check(&name,HW_D25) ) { DumpLiteral( "D25" ); continue; } if( Check(&name,HW_D26) ) { DumpLiteral( "D26" ); continue; } if( Check(&name,HW_D27) ) { DumpLiteral( "D27" ); continue; } if( Check(&name,HW_D28) ) { DumpLiteral( "D28" ); continue; } if( Check(&name,HW_D29) ) { DumpLiteral( "D29" ); continue; } if( Check(&name,HW_D30) ) { DumpLiteral( "D30" ); continue; } if( Check(&name,HW_D31) ) { DumpLiteral( "D31" ); continue; } if( Check(&name,HW_W0) ) { DumpLiteral( "W0" ); continue; } if( Check(&name,HW_W1) ) { DumpLiteral( "W1" ); continue; } if( Check(&name,HW_W2) ) { DumpLiteral( "W2" ); continue; } if( Check(&name,HW_W3) ) { DumpLiteral( "W3" ); continue; } if( Check(&name,HW_W4) ) { DumpLiteral( "W4" ); continue; } if( Check(&name,HW_W5) ) { DumpLiteral( "W5" ); continue; } if( Check(&name,HW_W6) ) { DumpLiteral( "W6" ); continue; } if( Check(&name,HW_W7) ) { DumpLiteral( "W7" ); continue; } if( Check(&name,HW_W8) ) { DumpLiteral( "W8" ); continue; } if( Check(&name,HW_W9) ) { DumpLiteral( "W9" ); continue; } if( Check(&name,HW_W10) ) { DumpLiteral( "W10" ); continue; } if( Check(&name,HW_W11) ) { DumpLiteral( "W11" ); continue; } if( Check(&name,HW_W12) ) { DumpLiteral( "W12" ); continue; } if( Check(&name,HW_W13) ) { DumpLiteral( "W13" ); continue; } if( Check(&name,HW_W14) ) { DumpLiteral( "W14" ); continue; } if( Check(&name,HW_W15) ) { DumpLiteral( "W15" ); continue; } if( Check(&name,HW_W16) ) { DumpLiteral( "W16" ); continue; } if( Check(&name,HW_W17) ) { DumpLiteral( "W17" ); continue; } if( Check(&name,HW_W18) ) { DumpLiteral( "W18" ); continue; } if( Check(&name,HW_W19) ) { DumpLiteral( "W19" ); continue; } if( Check(&name,HW_W20) ) { DumpLiteral( "W20" ); continue; } if( Check(&name,HW_W21) ) { DumpLiteral( "W21" ); continue; } if( Check(&name,HW_W22) ) { DumpLiteral( "W22" ); continue; } if( Check(&name,HW_W23) ) { DumpLiteral( "W23" ); continue; } if( Check(&name,HW_W24) ) { DumpLiteral( "W24" ); continue; } if( Check(&name,HW_W25) ) { DumpLiteral( "W25" ); continue; } if( Check(&name,HW_W26) ) { DumpLiteral( "W26" ); continue; } if( Check(&name,HW_W27) ) { DumpLiteral( "W27" ); continue; } if( Check(&name,HW_W28) ) { DumpLiteral( "W28" ); continue; } if( Check(&name,HW_W29) ) { DumpLiteral( "W29" ); continue; } if( Check(&name,HW_W30) ) { DumpLiteral( "W30" ); continue; } if( Check(&name,HW_W31) ) { DumpLiteral( "W31" ); continue; } if( Check(&name,HW_B0) ) { DumpLiteral( "B0" ); continue; } if( Check(&name,HW_B1) ) { DumpLiteral( "B1" ); continue; } if( Check(&name,HW_B2) ) { DumpLiteral( "B2" ); continue; } if( Check(&name,HW_B3) ) { DumpLiteral( "B3" ); continue; } if( Check(&name,HW_B4) ) { DumpLiteral( "B4" ); continue; } if( Check(&name,HW_B5) ) { DumpLiteral( "B5" ); continue; } if( Check(&name,HW_B6) ) { DumpLiteral( "B6" ); continue; } if( Check(&name,HW_B7) ) { DumpLiteral( "B7" ); continue; } if( Check(&name,HW_B8) ) { DumpLiteral( "B8" ); continue; } if( Check(&name,HW_B9) ) { DumpLiteral( "B9" ); continue; } if( Check(&name,HW_B10) ) { DumpLiteral( "B10" ); continue; } if( Check(&name,HW_B11) ) { DumpLiteral( "B11" ); continue; } if( Check(&name,HW_B12) ) { DumpLiteral( "B12" ); continue; } if( Check(&name,HW_B13) ) { DumpLiteral( "B13" ); continue; } if( Check(&name,HW_B14) ) { DumpLiteral( "B14" ); continue; } if( Check(&name,HW_B15) ) { DumpLiteral( "B15" ); continue; } if( Check(&name,HW_B16) ) { DumpLiteral( "B16" ); continue; } if( Check(&name,HW_B17) ) { DumpLiteral( "B17" ); continue; } if( Check(&name,HW_B18) ) { DumpLiteral( "B18" ); continue; } if( Check(&name,HW_B19) ) { DumpLiteral( "B19" ); continue; } if( Check(&name,HW_B20) ) { DumpLiteral( "B20" ); continue; } if( Check(&name,HW_B21) ) { DumpLiteral( "B21" ); continue; } if( Check(&name,HW_B22) ) { DumpLiteral( "B22" ); continue; } if( Check(&name,HW_B23) ) { DumpLiteral( "B23" ); continue; } if( Check(&name,HW_B24) ) { DumpLiteral( "B24" ); continue; } if( Check(&name,HW_B25) ) { DumpLiteral( "B25" ); continue; } if( Check(&name,HW_B26) ) { DumpLiteral( "B26" ); continue; } if( Check(&name,HW_B27) ) { DumpLiteral( "B27" ); continue; } if( Check(&name,HW_B28) ) { DumpLiteral( "B28" ); continue; } if( Check(&name,HW_B29) ) { DumpLiteral( "B29" ); continue; } if( Check(&name,HW_B30) ) { DumpLiteral( "B30" ); continue; } if( Check(&name,HW_B31) ) { DumpLiteral( "B31" ); continue; } if( Check(&name,HW_F0) ) { DumpLiteral( "F0" ); continue; } if( Check(&name,HW_F1) ) { DumpLiteral( "F1" ); continue; } if( Check(&name,HW_F2) ) { DumpLiteral( "F2" ); continue; } if( Check(&name,HW_F3) ) { DumpLiteral( "F3" ); continue; } if( Check(&name,HW_F4) ) { DumpLiteral( "F4" ); continue; } if( Check(&name,HW_F5) ) { DumpLiteral( "F5" ); continue; } if( Check(&name,HW_F6) ) { DumpLiteral( "F6" ); continue; } if( Check(&name,HW_F7) ) { DumpLiteral( "F7" ); continue; } if( Check(&name,HW_F8) ) { DumpLiteral( "F8" ); continue; } if( Check(&name,HW_F9) ) { DumpLiteral( "F9" ); continue; } if( Check(&name,HW_F10) ) { DumpLiteral( "F10" ); continue; } if( Check(&name,HW_F11) ) { DumpLiteral( "F11" ); continue; } if( Check(&name,HW_F12) ) { DumpLiteral( "F12" ); continue; } if( Check(&name,HW_F13) ) { DumpLiteral( "F13" ); continue; } if( Check(&name,HW_F14) ) { DumpLiteral( "F14" ); continue; } if( Check(&name,HW_F15) ) { DumpLiteral( "F15" ); continue; } if( Check(&name,HW_F16) ) { DumpLiteral( "F16" ); continue; } if( Check(&name,HW_F17) ) { DumpLiteral( "F17" ); continue; } if( Check(&name,HW_F18) ) { DumpLiteral( "F18" ); continue; } if( Check(&name,HW_F19) ) { DumpLiteral( "F19" ); continue; } if( Check(&name,HW_F20) ) { DumpLiteral( "F20" ); continue; } if( Check(&name,HW_F21) ) { DumpLiteral( "F21" ); continue; } if( Check(&name,HW_F22) ) { DumpLiteral( "F22" ); continue; } if( Check(&name,HW_F23) ) { DumpLiteral( "F23" ); continue; } if( Check(&name,HW_F24) ) { DumpLiteral( "F24" ); continue; } if( Check(&name,HW_F25) ) { DumpLiteral( "F25" ); continue; } if( Check(&name,HW_F26) ) { DumpLiteral( "F26" ); continue; } if( Check(&name,HW_F27) ) { DumpLiteral( "F27" ); continue; } if( Check(&name,HW_F28) ) { DumpLiteral( "F28" ); continue; } if( Check(&name,HW_F29) ) { DumpLiteral( "F29" ); continue; } if( Check(&name,HW_F30) ) { DumpLiteral( "F30" ); continue; } if( Check(&name,HW_F31) ) { DumpLiteral( "F31" ); continue; } #endif #if 0 #if _TARGET & _TARG_PPC if( Check(&name,HW_CTR) ) { DumpLiteral( "CTR" ); continue; } if( Check(&name,HW_CR) ) { DumpLiteral( "CR" ); continue; } if( Check(&name,HW_MQ) ) { DumpLiteral( "MQ" ); continue; } if( Check(&name,HW_LR) ) { DumpLiteral( "LR" ); continue; } #endif #endif #if _TARGET & ( _TARG_80386 | _TARG_IAPX86 ) if( Check(&name,HW_EAX)) { DumpLiteral("EAX"); continue; } if( Check(&name,HW_AX) ) { DumpLiteral( "AX"); continue; } if( Check(&name,HW_AL) ) { DumpLiteral( "AL"); continue; } if( Check(&name,HW_AH) ) { DumpLiteral( "AH"); continue; } if( Check(&name,HW_EBX)) { DumpLiteral("EBX"); continue; } if( Check(&name,HW_BX) ) { DumpLiteral( "BX"); continue; } if( Check(&name,HW_BL) ) { DumpLiteral( "BL"); continue; } if( Check(&name,HW_BH) ) { DumpLiteral( "BH"); continue; } if( Check(&name,HW_ECX)) { DumpLiteral("ECX"); continue; } if( Check(&name,HW_CX) ) { DumpLiteral( "CX"); continue; } if( Check(&name,HW_CL) ) { DumpLiteral( "CL"); continue; } if( Check(&name,HW_CH) ) { DumpLiteral( "CH"); continue; } if( Check(&name,HW_EDX)) { DumpLiteral("EDX"); continue; } if( Check(&name,HW_DX) ) { DumpLiteral( "DX"); continue; } if( Check(&name,HW_DL) ) { DumpLiteral( "DL"); continue; } if( Check(&name,HW_DH) ) { DumpLiteral( "DH"); continue; } if( Check(&name,HW_EDI)) { DumpLiteral("EDI"); continue; } if( Check(&name,HW_DI) ) { DumpLiteral( "DI"); continue; } if( Check(&name,HW_ESI)) { DumpLiteral("ESI"); continue; } if( Check(&name,HW_SI) ) { DumpLiteral( "SI"); continue; } if( Check(&name,HW_BP)) { DumpLiteral("EBP"); continue; } if( Check(&name,HW_SP)) { DumpLiteral("ESP"); continue; } if( Check(&name,HW_GS) ) { DumpLiteral( "GS"); continue; } if( Check(&name,HW_FS) ) { DumpLiteral( "FS"); continue; } if( Check(&name,HW_ES) ) { DumpLiteral( "ES"); continue; } if( Check(&name,HW_DS) ) { DumpLiteral( "DS"); continue; } if( Check(&name,HW_CS) ) { DumpLiteral( "CS"); continue; } if( Check(&name,HW_SS) ) { DumpLiteral( "SS"); continue; } if( Check(&name,HW_ST0) ) { DumpLiteral( "ST(0)"); continue; } if( Check(&name,HW_ST1) ) { DumpLiteral( "ST(1)"); continue; } if( Check(&name,HW_ST2) ) { DumpLiteral( "ST(2)"); continue; } if( Check(&name,HW_ST3) ) { DumpLiteral( "ST(3)"); continue; } if( Check(&name,HW_ST4) ) { DumpLiteral( "ST(4)"); continue; } if( Check(&name,HW_ST5) ) { DumpLiteral( "ST(5)"); continue; } if( Check(&name,HW_ST6) ) { DumpLiteral( "ST(6)"); continue; } if( Check(&name,HW_ST7) ) { DumpLiteral( "ST(7)"); continue; } #endif break; } } }
an BGCall( cn call, bool use_return, bool in_line ) /******************************************************/ { instruction *call_ins; call_state *state; name *ret_ptr = NULL; name *result; name *temp; name *reg_name; instruction *ret_ins = NULL; hw_reg_set return_reg; hw_reg_set zap_reg; if( call->name->tipe == TypeProcParm ) { SaveDisplay( OP_PUSH ); } state = call->state; result = BGNewTemp( call->tipe ); call_ins = call->ins; /* If we have a return value that won't fit in a register*/ /* pass a pointer to result as the first parm*/ if( call_ins->type_class == XX ) { if( _RoutineIsFar16( state->attr ) ) { if( state->attr & ROUTINE_ALLOCS_RETURN ) { HW_CAsgn( state->return_reg, HW_EAX ); } else { HW_CAsgn( state->return_reg, HW_EBX ); } } if( ( state->attr & ROUTINE_ALLOCS_RETURN ) == 0 ) { if( HW_CEqual( state->return_reg, HW_EMPTY ) ) { ret_ptr = AllocTemp( WD ); } else { ret_ptr = AllocRegName( state->return_reg ); } ret_ins = MakeUnary( OP_LA, result, ret_ptr, WD ); HW_TurnOn( state->parm.used, state->return_reg ); call_ins->flags.call_flags |= CALL_RETURNS_STRUCT; } } if( _IsTargetModel(FLOATING_DS) && (state->attr&ROUTINE_NEEDS_DS_LOADED) ) { HW_CTurnOn( state->parm.used, HW_DS ); } if( _RoutineIsFar16( state->attr ) ) { #if _TARGET & _TARG_80386 Far16Parms( call ); #endif } else { if( AssgnParms( call, in_line ) ) { if( state->attr & ROUTINE_REMOVES_PARMS ) { call_ins->flags.call_flags |= CALL_POPS_PARMS; } } } if( state->attr & (ROUTINE_MODIFIES_NO_MEMORY | ROUTINE_NEVER_RETURNS) ) { /* a routine that never returns can not write any memory as far as this routine is concerned */ call_ins->flags.call_flags |= CALL_WRITES_NO_MEMORY; } if( state->attr & ROUTINE_READS_NO_MEMORY ) { call_ins->flags.call_flags |= CALL_READS_NO_MEMORY; } if( state->attr & ROUTINE_NEVER_RETURNS ) { call_ins->flags.call_flags |= CALL_ABORTS; } if( _RoutineIsInterrupt( state->attr ) ) { call_ins->flags.call_flags |= CALL_INTERRUPT | CALL_POPS_PARMS; } if( !use_return ) { call_ins->flags.call_flags |= CALL_IGNORES_RETURN; } if( call_ins->type_class == XX ) { reg_name = AllocRegName( state->return_reg ); if( state->attr & ROUTINE_ALLOCS_RETURN ) { call_ins->result = reg_name; AddCall( call_ins, call ); if( use_return ) { temp = AllocTemp( WD ); /* assume near pointer*/ AddIns( MakeMove( reg_name, temp, WD ) ); temp = SAllocIndex( temp, NULL, 0, result->n.type_class, call->tipe->length ); AddIns( MakeMove( temp, result, result->n.type_class ) ); } } else { call_ins->result = result; AddIns( ret_ins ); if( HW_CEqual( state->return_reg, HW_EMPTY ) ) { AddIns( MakeUnary( OP_PUSH, ret_ptr, NULL, WD ) ); state->parm.offset += TypeClassSize[WD]; call_ins->operands[CALL_OP_POPS] = AllocS32Const( call_ins->operands[CALL_OP_POPS]->c.lo.int_value + TypeClassSize[WD] ); if( state->attr & ROUTINE_REMOVES_PARMS ) { call_ins->flags.call_flags |= CALL_POPS_PARMS; } } AddCall( call_ins, call ); } } else { return_reg = state->return_reg; zap_reg = call_ins->zap->reg; HW_CTurnOn( zap_reg, HW_FLTS ); HW_OnlyOn( return_reg, zap_reg ); call_ins->result = AllocRegName( return_reg ); reg_name = AllocRegName( state->return_reg ); AddCall( call_ins, call ); if( use_return ) { ret_ins = MakeMove( reg_name, result, result->n.type_class ); if( HW_COvlap( reg_name->r.reg, HW_FLTS ) ) { ret_ins->stk_entry = 1; ret_ins->stk_exit = 0; } AddIns( ret_ins ); } } if( state->parm.offset != 0 && ( state->attr & ROUTINE_REMOVES_PARMS ) == 0 ) { reg_name = AllocRegName( HW_SP ); AddIns( MakeBinary( OP_ADD, reg_name, AllocS32Const( state->parm.offset ), reg_name, WD ) ); } return( MakeTempAddr( result ) ); }
type_class_def CallState( aux_handle aux, type_def *tipe, call_state *state ) /****************************************************************************/ { call_class cclass; type_class_def type_class; uint i; hw_reg_set parms[10]; hw_reg_set *parm_src; hw_reg_set *parm_dst; hw_reg_set *pregs; hw_reg_set tmp; state->unalterable = FixedRegs(); pregs = FEAuxInfo( aux, SAVE_REGS ); HW_CAsgn( state->modify, HW_FULL ); HW_TurnOff( state->modify, *pregs ); HW_CTurnOff( state->modify, HW_UNUSED ); state->used = state->modify; /* anything not saved is used*/ tmp = state->used; HW_TurnOff( tmp, StackReg() ); HW_CTurnOff( tmp, HW_BP ); // should be able to call routine which modifies BP if( HW_Ovlap( state->unalterable, tmp ) ) { FEMessage( MSG_BAD_SAVE, aux ); } state->attr = ROUTINE_REMOVES_PARMS; cclass = *(call_class *)FEAuxInfo( aux, CALL_CLASS ); if( cclass & INTERRUPT ) { state->attr |= ROUTINE_INTERRUPT; } else if( cclass & FAR_CALL ) { state->attr |= ROUTINE_LONG; } else if( cclass & FAR16_CALL ) { state->attr |= ROUTINE_FAR16; } if( cclass & CALLER_POPS ) { state->attr &= ~ROUTINE_REMOVES_PARMS; } if( cclass & SUICIDAL ) { state->attr |= ROUTINE_NEVER_RETURNS; } if( cclass & ROUTINE_RETURN ) { state->attr |= ROUTINE_ALLOCS_RETURN; } if( cclass & NO_STRUCT_REG_RETURNS ) { state->attr |= ROUTINE_NO_STRUCT_REG_RETURNS; } if( cclass & NO_FLOAT_REG_RETURNS ) { state->attr |= ROUTINE_NO_FLOAT_REG_RETURNS; state->attr |= ROUTINE_NO_8087_RETURNS; } if( cclass & NO_8087_RETURNS ) { state->attr |= ROUTINE_NO_8087_RETURNS; } if( cclass & MODIFY_EXACT ) { state->attr |= ROUTINE_MODIFY_EXACT; } if( cclass & NO_MEMORY_CHANGED ) { state->attr |= ROUTINE_MODIFIES_NO_MEMORY; } if( cclass & NO_MEMORY_READ ) { state->attr |= ROUTINE_READS_NO_MEMORY; } if( cclass & LOAD_DS_ON_ENTRY ) { state->attr |= ROUTINE_LOADS_DS; } if( cclass & LOAD_DS_ON_CALL ) { state->attr |= ROUTINE_NEEDS_DS_LOADED; } if( cclass & PARMS_STACK_RESERVE ) { state->attr |= ROUTINE_STACK_RESERVE; } if( cclass & PARMS_PREFER_REGS ) { state->attr |= ROUTINE_PREFER_REGS; } if( cclass & FARSS ) { state->attr |= ROUTINE_FARSS; } if( state == &CurrProc->state ) { if( cclass & ( GENERATE_STACK_FRAME | PROLOG_HOOKS | EPILOG_HOOKS ) ) { CurrProc->prolog_state |= GENERATE_FAT_PROLOG; state->attr |= ROUTINE_NEEDS_PROLOG; } if( cclass & PROLOG_HOOKS ) { CurrProc->prolog_state |= GENERATE_PROLOG_HOOKS; } if( cclass & EPILOG_HOOKS ) { CurrProc->prolog_state |= GENERATE_EPILOG_HOOKS; } if( cclass & FAT_WINDOWS_PROLOG ) { CurrProc->prolog_state |= GENERATE_FAT_PROLOG; } if( cclass & EMIT_FUNCTION_NAME ) { CurrProc->prolog_state |= GENERATE_FUNCTION_NAME; } if( cclass & THUNK_PROLOG ) { CurrProc->prolog_state |= GENERATE_THUNK_PROLOG; } if( cclass & GROW_STACK ) { CurrProc->prolog_state |= GENERATE_GROW_STACK; } if( cclass & TOUCH_STACK ) { CurrProc->prolog_state |= GENERATE_TOUCH_STACK; } if( cclass & LOAD_RDOSDEV_ON_ENTRY ) { CurrProc->prolog_state |= GENERATE_RDOSDEV_PROLOG; } } type_class = ReturnClass( tipe, state->attr ); i = 0; parm_dst = &parms[0]; for( parm_src = FEAuxInfo( aux, PARM_REGS ); !HW_CEqual( *parm_src, HW_EMPTY ); ++parm_src ) { *parm_dst = *parm_src; if( HW_Ovlap( *parm_dst, state->unalterable ) ) { FEMessage( MSG_BAD_SAVE, aux ); } HW_CTurnOff( *parm_dst, HW_UNUSED ); parm_dst++; i++; } *parm_dst = *parm_src; i++; state->parm.table = CGAlloc( i*sizeof( hw_reg_set ) ); Copy( parms, state->parm.table, i * sizeof( hw_reg_set ) ); HW_CAsgn( state->parm.used, HW_EMPTY ); state->parm.curr_entry = state->parm.table; state->parm.offset = 0; if( tipe == TypeNone ) { HW_CAsgn( state->return_reg, HW_EMPTY ); } else if( type_class == XX ) { if( cclass & SPECIAL_STRUCT_RETURN ) { pregs = FEAuxInfo( aux, STRETURN_REG ); state->return_reg = *pregs; state->attr |= ROUTINE_HAS_SPECIAL_RETURN; } else { state->return_reg = StructReg(); } if( (state->attr & ROUTINE_ALLOCS_RETURN) == 0 ) { tmp = ReturnReg( WD, false ); HW_TurnOn( state->modify, tmp ); } } else { if( cclass & SPECIAL_RETURN ) { pregs = FEAuxInfo( aux, RETURN_REG ); state->return_reg = *pregs; state->attr |= ROUTINE_HAS_SPECIAL_RETURN; } else { state->return_reg = ReturnReg( type_class, _NPX( state->attr ) ); } } UpdateReturn( state, tipe, type_class, aux ); return( type_class ); }
static aux_info *InfoLookup( SYMPTR sym ) { char *name; aux_info *inf; aux_entry *ent; name = sym->name; inf = &DefaultInfo; /* assume default */ if( name == NULL ) return( inf ); ent = AuxLookup( name ); if( ent != NULL ) inf = ent->info; if( ( ent == NULL ) || (sym->flags & SYM_INTRINSIC) ) { if( sym->flags & SYM_DEFINED ) return( inf ); if( (sym->flags & SYM_INTRINSIC) == 0 ) { if( memcmp( name, "_inline_", 8 ) != 0 ) return( inf ); name += 8; } #if ( _CPU == 8086 ) || ( _CPU == 386 ) { const inline_funcs *ifunc; ifunc = IF_Lookup( name ); if( ifunc == NULL ) return( inf ); #if ( _CPU == 8086 ) if( HW_CEqual( ifunc->returns, HW_DX_AX ) || HW_CEqual( ifunc->returns, HW_DS_SI ) || HW_CEqual( ifunc->returns, HW_ES_DI ) || HW_CEqual( ifunc->returns, HW_CX_DI ) ) { if( SizeOfArg( sym->sym_type->object ) != 4 ) { #else if( HW_CEqual( ifunc->returns, HW_DX_AX ) || HW_CEqual( ifunc->returns, HW_DS_ESI ) || HW_CEqual( ifunc->returns, HW_ES_EDI ) || HW_CEqual( ifunc->returns, HW_CX_DI ) ) { if( SizeOfArg( sym->sym_type->object ) != 6 ) { #endif return( inf ); } } inf = &InlineInfo; inf->cclass = (WatcallInfo.cclass & FAR_CALL) | MODIFY_EXACT; if( (sym->flags & SYM_INTRINSIC) && ( ent != NULL ) ) inf->cclass |= ent->info->cclass; inf->code = ifunc->code; inf->parms = ifunc->parms; inf->returns = ifunc->returns; #if ( _CPU == 8086 ) if( !HW_CEqual( inf->returns, HW_AX ) && !HW_CEqual( inf->returns, HW_EMPTY ) ) { #else if( !HW_CEqual( inf->returns, HW_EAX ) && !HW_CEqual( inf->returns, HW_EMPTY ) ) { #endif inf->cclass |= SPECIAL_RETURN; } HW_CAsgn( inf->streturn, HW_EMPTY ); inf->save = ifunc->save; inf->objname = WatcallInfo.objname; inf->use = 1; } #endif } return( inf ); } aux_info *FindInfo( SYMPTR sym, SYM_HANDLE sym_handle ) { SYM_ENTRY sym_typedef; aux_entry *ent; TYPEPTR typ; aux_info *inf; inf = &DefaultInfo; /* assume default */ if( sym_handle == SYM_NULL ) return( inf ); SymGet( sym, sym_handle ); #if _CPU == 386 if( (sym_handle == SymSTOSB) || (sym_handle == SymSTOSD) ) { return( &STOSBInfo ); } else if( sym_handle == SymFinally ) { InlineInfo = WatcallInfo; InlineInfo.code = (byte_seq *)&FinallyCode; return( &InlineInfo ); } else if( sym_handle == SymTryFini ) { InlineInfo = WatcallInfo; InlineInfo.parms = TryFiniParms; InlineInfo.code = (byte_seq *)&TryFiniCode; return( &InlineInfo ); } #endif if( (sym->flags & SYM_TEMP) == 0 ) { /* not an indirect func call*/ inf = InfoLookup( sym ); } if( inf == &DefaultInfo ) { typ = sym->sym_type; SKIP_DUMMY_TYPEDEFS( typ ); if( typ->decl_type == TYPE_TYPEDEF ) { SymGet( &sym_typedef, typ->u.typedefn ); if( sym_typedef.name != NULL ) { ent = AuxLookup( sym_typedef.name ); if( ent != NULL ) { inf = ent->info; } } } } #if _CPU == 386 if( (inf->flags & AUX_FLAG_FAR16) || (sym->mods & FLAG_FAR16) ) { if( (sym->mods & MASK_LANGUAGES) == LANG_PASCAL || (inf->cclass & REVERSE_PARMS) ) { return( &Far16PascalInfo ); } else { return( &Far16CdeclInfo ); } } #endif return( inf ); } bool FunctionAborts( SYMPTR sym, SYM_HANDLE sym_handle ) { aux_entry *ent; if( sym_handle != SYM_NULL ) { SymGet( sym, sym_handle ); ent = AuxLookup( SymName( sym, sym_handle ) ); if( ent != NULL ) { if( ent->info->cclass & SUICIDAL ) { return( TRUE ); } } } return( FALSE ); } call_class GetCallClass( SYM_HANDLE sym_handle ) { aux_info *inf; SYM_ENTRY sym; call_class cclass; cclass = DefaultInfo.cclass; if( sym_handle != SYM_NULL ) { inf = FindInfo( &sym, sym_handle ); if( sym.flags & SYM_FUNCTION ) { if( inf != &DefaultInfo ) { cclass = inf->cclass; } else { cclass = GetLangInfo( sym.mods )->cclass; #if _CPU == 8086 if( TargSys == TS_WINDOWS ) { if( sym.mods & (LANG_CDECL | LANG_PASCAL) ) { cclass |= FAT_WINDOWS_PROLOG; } } #endif } #if ( _CPU == 8086 ) || ( _CPU == 386 ) if( CompFlags.emit_names ) { cclass |= EMIT_FUNCTION_NAME; } if( sym.mods & FLAG_FAR ) { cclass |= FAR_CALL; if( sym.mods & FLAG_NEAR ) { cclass |= INTERRUPT; } } else if( sym.mods & FLAG_NEAR ) { cclass &= ~ FAR_CALL; } #endif #ifdef DLL_EXPORT if( sym.mods & FLAG_EXPORT ) { cclass |= DLL_EXPORT; } #endif #ifdef LOAD_DS_ON_ENTRY if( sym.mods & FLAG_LOADDS ) { #if 0 if( TargSys == TS_WINDOWS ) { cclass |= FAT_WINDOWS_PROLOG; } else { cclass |= LOAD_DS_ON_ENTRY; } #else cclass |= LOAD_DS_ON_ENTRY; #endif } #endif #ifdef MAKE_CALL_INLINE if( IsInLineFunc( sym_handle ) ) { cclass |= MAKE_CALL_INLINE; } #endif if( VarFunc( &sym ) ) { cclass |= CALLER_POPS | HAS_VARARGS; } } #if ( _CPU == 8086 ) || ( _CPU == 386 ) if( sym.flags & SYM_FUNC_NEEDS_THUNK ) { cclass |= THUNK_PROLOG; } #endif } #ifdef REVERSE cclass &= ~ REVERSE_PARMS; #endif #ifdef PROLOG_HOOKS if( CompFlags.ep_switch_used != 0 ) { cclass |= PROLOG_HOOKS; } #endif #ifdef EPILOG_HOOKS if( CompFlags.ee_switch_used != 0 ) { cclass |= EPILOG_HOOKS; } #endif #ifdef GROW_STACK if( CompFlags.sg_switch_used ) { cclass |= GROW_STACK; } #endif #ifdef TOUCH_STACK if( CompFlags.st_switch_used ) { cclass |= TOUCH_STACK; } #endif return( cclass ); }