name *StReturn( an retval, type_def *tipe, instruction **pins ) /****************************************************************/ { name *retp; name *ptr; name *off; name *seg; hw_reg_set reg; if( CurrProc->state.attr & ROUTINE_ALLOCS_RETURN ) { retp = CurrProc->targ.return_points; AddIns( MakeUnary( OP_LA, retp, AllocRegName( CurrProc->state.return_reg ), WD ) ); *pins = NULL; } else { if( _IsTargetModel( FLOATING_SS ) || _IsTargetModel( FLOATING_DS ) ) { ptr = AllocTemp( CP ); off = OffsetPart( ptr ); seg = SegmentPart( ptr ); AddIns( MakeMove( AllocRegName( HW_SS ), seg, U2 ) ); } else { ptr = AllocTemp( WD ); off = ptr; } AddIns( MakeMove( CurrProc->targ.return_points, off, WD ) ); retp = SAllocIndex( ptr, NULL, 0, TypeClass( retval->tipe ), tipe->length ); reg = ReturnReg( WD, false ); *pins = MakeMove( CurrProc->targ.return_points, AllocRegName( reg ), WD ); CurrProc->state.return_reg = reg; } return( retp ); }
extern char *AskRTName( rt_class rtindex ) /********************************************/ { if( _IsTargetModel( INDEXED_GLOBALS ) ) { switch( rtindex ) { case RT_FDA: return( "__FXA" ); case RT_FDS: return( "__FXS" ); case RT_FDM: return( "__FXM" ); case RT_FDD: return( "__FXD" ); case RT_FDC: return( "__FXC" ); case RT_DPOW: return( "RT@XPOW" ); case RT_DATAN2: return( "IF@XATAN2" ); case RT_DFMOD: return( "IF@XFMOD" ); } } return( RTInfo[rtindex].nam ); }
static void OpndSizeIf( bool if_32 ) /**********************************/ { if( ( if_32 && _IsTargetModel( USE_32 ) ) || _IsntTargetModel( USE_32 ) ) { AddToTemp( M_OPND_SIZE ); } }
static void OpndSizeIf( void ) /****************************/ { if( _IsTargetModel( USE_32 ) ) { AddToTemp( M_OPND_SIZE ); } }
static name *GetTLSDataRef( instruction *ins, name *op, type_class_def tipe ) /*******************************************************************************/ { if( _IsTargetModel( GENERIC_TLS ) ) { return( GetNTTLSDataRef( ins, op, tipe ) ); } else { return( GetGenericTLSDataRef( ins, op, tipe ) ); } }
static void TakeUpSlack( type_length size ) /*****************************************/ { for( ; size >= 2; size -= 2 ) { if( _IsTargetModel( USE_32 ) ) AddByte( M_OPND_SIZE ); AddByte( M_MOVSW ); } for( ; size >= 1; --size ) { AddByte( M_MOVSB ); } }
void InitRegTbl( void ) /********************************* Initialize the tables. */ { if( _FPULevel( FPU_87 ) ) { HW_CAsgn( STParmReg[Max87Stk], HW_EMPTY ); } if( _IsTargetModel( INDEXED_GLOBALS ) ) { HW_CAsgn( FPParm2Reg[0], HW_ECX_ESI ); } else { HW_CAsgn( FPParm2Reg[0], HW_ECX_EBX ); } }
extern void DFGenStatic( cg_sym_handle sym, dbg_loc loc ) { /*******************************************************************/ uint flags; fe_attr attr; const char *name; dw_loc_handle dw_loc; dw_loc_handle dw_segloc; dw_handle obj; dbg_type dbtype; attr = FEAttr( sym ); if( attr & FE_GLOBAL ){ flags = DW_FLAG_GLOBAL; }else{ flags = 0; } name = FEName( sym ); if( attr & FE_STATIC ){ #if _TARGET & ( _TARG_IAPX86 | _TARG_80386 ) if( _IsTargetModel( FLAT_MODEL ) ) { dw_segloc = NULL; }else{ dw_segloc = SegLoc( sym ); } #else dw_segloc = NULL; #endif }else{ dw_segloc = NULL; } dbtype = FEDbgType( sym ); /* causes name side effects */ dw_loc = DBGLoc2DF( loc ); obj = DWVariable( Client, dbtype, dw_loc, 0, dw_segloc, name, 0, flags ); if( attr & FE_GLOBAL ){ name = FEName( sym ); DWPubname( Client, obj, name ); } if( dw_loc != NULL ){ DWLocTrash( Client, dw_loc ); } if( dw_segloc != NULL ){ DWLocTrash( Client, dw_segloc ); } }
static void AddCall( instruction *ins, cn call ) { /****************************************************/ name *proc_name; if( _IsTargetModel(FLOATING_DS) && (call->state->attr&ROUTINE_NEEDS_DS_LOADED) ) { AddIns( MakeMove( NearSegment(), AllocRegName( HW_DS ), U2 ) ); } if( call->name->tipe == TypeProcParm ) { proc_name = AllocTemp( ClassPointer ); /* what to do? proc_name->usage |= USE_REGISTER;*/ AddIns( MakeMove( ins->operands[CALL_OP_ADDR], proc_name, ClassPointer )); ins->operands[CALL_OP_ADDR] = proc_name; SetDisplay( GenIns( call->name ) ); AddIns( ins ); SaveDisplay( OP_POP ); } else { AddCallIns( ins, call ); } }
extern void DFLineNum( cue_state *state, offset lc ) { /*******************************************************/ char *fname; if( NeedBaseSet() ) { back_handle bck; bck = MakeLabel(); OutLabel( bck->lbl ); DWLineAddr( Client, (dw_sym_handle)bck, lc ); #if _TARGET & ( _TARG_IAPX86 | _TARG_80386 ) if( !_IsTargetModel( FLAT_MODEL ) ) { DWLineSeg( Client, (dw_sym_handle)bck ); } #endif BEFreeBack( bck ); } if( state->fno != CurrFNo ) { fname = SrcFNoFind( state->fno ); DWSetFile( Client, fname ); CurrFNo = state->fno; } DWLineNum( Client, DW_LN_STMT, state->line, state->col, lc ); }
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 ) ); }
extern void DFObjLineInitDbgInfo( void ) { /*****************************************************/ /* called by objinit to init segments and dwarf writing library */ static const dw_funcs cli_funcs = { CLIReloc, CLIWrite, CLISeek, CLITell, CLIAlloc, CLIFree }; dw_init_info info; dw_cu_info cu; type_def *tipe_addr; info.language = DWLANG_C; info.compiler_options = DW_CM_DEBUGGER; info.abbrev_sym = 0; info.producer_name = SetDwarfProducer(); info.language = SetLang(); if( setjmp( info.exception_handler ) == 0 ) { info.funcs = cli_funcs; InitLineSegBck(); // start each seg with a ref label Client = DWInit( &info ); if( Client == NULL ) { Zoiks( ZOIKS_107 ); /* Bad */ } cu.source_filename = FEAuxInfo( NULL, SOURCE_NAME ); cu.directory = ""; cu.dbg_pch = NULL; cu.inc_list = NULL; cu.inc_list_len = 0; #if _TARGET & ( _TARG_IAPX86 | _TARG_80386 ) if( _IsTargetModel( FLAT_MODEL ) ) { cu.flags = true; cu.segment_size = 0; }else{ cu.flags = false; cu.segment_size = 2; } #else cu.flags = true; cu.segment_size = 0; #endif tipe_addr = TypeAddress( TY_NEAR_POINTER ); cu.offset_size = tipe_addr->length; switch( GetMemModel() ){ case 'h': cu.model = DW_MODEL_HUGE; break; case 'l': cu.model = DW_MODEL_LARGE; break; case 'f': cu.model = DW_MODEL_FLAT; break; case 's': cu.model = DW_MODEL_SMALL; break; default: cu.model = DW_MODEL_NONE; break; } DWInitDebugLine( Client, &cu ); } else { Zoiks( ZOIKS_107 ); /* Big Error */ } }
extern void DFBegCCU( segment_id code, dw_sym_handle dbg_pch ) /****************************************************************/ // Call when codeseg hase been defined { dw_cu_info cu; back_handle bck; segment_id old; type_def *tipe_addr; if( _IsntModel( DBG_LOCALS | DBG_TYPES ) ) { return; } if( CcuDef ) { cu.source_filename = FEAuxInfo( NULL, SOURCE_NAME ); cu.directory = ""; cu.dbg_pch = dbg_pch; cu.inc_list = NULL; cu.inc_list_len = 0; old = SetOP( code ); #if _TARGET & ( _TARG_IAPX86 | _TARG_80386 ) if( _IsTargetModel( FLAT_MODEL ) ) { bck = MakeLabel(); OutLabel( bck->lbl ); Pc_Low = bck; Pc_High = MakeLabel(); // Emitting DW_AT_low_pc and DW_AT_high_pc is valid *only* if the // compilation unit's code is in a single contiguous block (see // DWARF 2, section 3.1). // I don't know how to find out at the time of this call if there's // only one code segment or not, hence these attributes are always // disabled. The low/high pc attribs should probably be handled by // the linker. cu.flags = false; cu.segment_size = 0; } else { bck = NULL; cu.flags = false; Pc_Low = NULL; Pc_High = NULL; cu.segment_size = 2; } #else bck = MakeLabel(); OutLabel( bck->lbl ); Pc_Low = bck; Pc_High = MakeLabel(); cu.flags = true; cu.segment_size = 0; #endif SetOP( old ); Comp_High = Pc_High; tipe_addr = TypeAddress( TY_NEAR_POINTER ); cu.offset_size = tipe_addr->length; switch( GetMemModel() ) { case 'h': cu.model = DW_MODEL_HUGE; break; case 'l': cu.model = DW_MODEL_LARGE; break; case 'f': cu.model = DW_MODEL_FLAT; break; case 's': cu.model = DW_MODEL_SMALL; break; default: cu.model = DW_MODEL_NONE; break; } DWBeginCompileUnit( Client, &cu ); if( cu.flags ) { BEFreeBack( bck ); } } else { CcuDef = true; } }