Beispiel #1
0
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;
}
Beispiel #2
0
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 );
}
Beispiel #3
0
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;
}
Beispiel #4
0
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 );
            }
        }
    }
}
Beispiel #5
0
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;
    }
}
Beispiel #6
0
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 );
}
Beispiel #7
0
static  void    DumpRgSet( hw_reg_set *possible )
/**************************************************/
{
    if( possible != NULL ) {
        DumpLiteral( " Choices " );
        for( ; !HW_CEqual( *possible, HW_EMPTY ); ++possible ) {
            DumpRegName( *possible );
            DumpChar( ' ' );
        }
    }
}
Beispiel #8
0
static  void    DumpRgSet( hw_reg_set *possible )
/**************************************************/
{
    if( possible != NULL ) {
        DumpLiteral( " Choices " );
        while( !HW_CEqual( *possible, HW_EMPTY ) ) {
            DumpRegName( *possible );
            ++ possible;
            DumpLiteral( " " );
        }
    }
}
Beispiel #9
0
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 );
}
Beispiel #10
0
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 );
}
Beispiel #11
0
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();
}
Beispiel #12
0
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 );
}
Beispiel #13
0
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 );
    }
}
Beispiel #14
0
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 );
}
Beispiel #15
0
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 );
}
Beispiel #16
0
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 );
}
Beispiel #17
0
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 );
    }
}
Beispiel #18
0
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;
        }
    }
}
Beispiel #19
0
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;
        }
    }
}
Beispiel #20
0
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;
}
Beispiel #21
0
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 );
}
Beispiel #22
0
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 );
}
Beispiel #23
0
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 );
}
Beispiel #24
0
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;
        }
    }
}
Beispiel #25
0
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;
    }
}
Beispiel #26
0
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
        }
    }
}
Beispiel #27
0
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;
        }
    }
}
Beispiel #28
0
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 ) );
}
Beispiel #29
0
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 );
}
Beispiel #30
0
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 );
}