コード例 #1
0
ファイル: split.c プロジェクト: joncampbell123/open-watcom-v2
/* 370 */
instruction      *rUSEREGISTER( instruction *ins )
/************************************************/
{
    instruction         *new_ins;
    instruction         *ins2;
    name                *name1;

    name1 = ins->operands[0];
    if( CanUseOp1( ins, name1 ) ) {
        new_ins = MakeMove( name1, ins->result, ins->type_class );
        ins->result = name1;
        MoveSegRes( ins, new_ins );
        SuffixIns( ins, new_ins );
        new_ins = ins;
    } else {
        name1 = AllocTemp( ins->type_class );
        new_ins = MakeMove( ins->operands[0], name1, ins->type_class );
        CheckCC( ins, new_ins );
        ins->operands[0] = name1;
        MoveSegOp( ins, new_ins, 0 );
        PrefixIns( ins, new_ins );
        ins2 = MakeMove( name1, ins->result, ins->type_class );
        ins->result = name1;
        MoveSegRes( ins, ins2 );
        SuffixIns( ins, ins2 );
        MarkPossible( ins, name1, ResultPossible( ins ) );
        ins->u.gen_table = NULL;
        GiveRegister( NameConflict( ins, name1 ), true );
    }
    return( new_ins );
}
コード例 #2
0
ファイル: split.c プロジェクト: joncampbell123/open-watcom-v2
instruction      *rMOVRESTEMP( instruction *ins )
/***********************************************/
{
    instruction         *new_ins;
    name                *name1;

    name1 = AllocTemp( ins->type_class );
    new_ins = MakeMove( name1, ins->result, ins->type_class );
    ins->result = name1;
    MoveSegRes( ins, new_ins );
    SuffixIns( ins, new_ins );
    MarkPossible( ins, name1, ResPossible( ins ) );
    ins->u.gen_table = NULL;
    return( ins );
}
コード例 #3
0
ファイル: split.c プロジェクト: joncampbell123/open-watcom-v2
/* 370 */
instruction      *rMOVRESREG( instruction *ins )
/**********************************************/
{
    instruction         *new_ins;
    name                *name1;

    name1 = AllocTemp( ins->type_class );
    new_ins = MakeMove( name1, ins->result, ins->type_class );
    ins->result = name1;
    MoveSegRes( ins, new_ins );
    SuffixIns( ins, new_ins );
    MarkPossible( ins, name1, ResPossible( ins ) );
    ins->u.gen_table = NULL;
    GiveRegister( NameConflict( ins, name1 ), true );
    return( ins );
}
コード例 #4
0
ファイル: i86half.c プロジェクト: bhanug/open-watcom-v2
extern  instruction     *rSPLITMOVE( instruction *ins ) {
/******************************************************/

    instruction *new_ins;
    instruction *ins2;
    name        *temp;

    CnvOpToInt( ins, 0 );
    if( IndexOverlaps( ins, 0 ) ) {
        temp = AllocTemp( LONG_WORD );
        new_ins = MakeMove( LowPart( ins->operands[ 0 ], WORD ),
                             LowPart( temp, WORD ), WORD );
        ins2 = MakeMove( HighPart( ins->operands[ 0 ], WORD ),
                             HighPart( temp, WORD ), WORD );
        DupSegOp( ins, new_ins, 0 );
        DupSegOp( ins, ins2, 0 );
        ins->operands[ 0 ] = temp;
        PrefixIns( ins, new_ins );
        PrefixIns( ins, ins2 );
        ins2 = MakeMove( LowPart( temp, WORD ), LowPart( ins->result, WORD ), WORD );
        DupSegRes( ins, ins2 );
        PrefixIns( ins, ins2 );
        ins2 = MakeMove( HighPart( temp, WORD ),
                          HighPart( ins->result, WORD ), WORD );
        ReplIns( ins, ins2 );
    } else {
        HalfType( ins );
        new_ins = MakeMove( LowPart( ins->operands[ 0 ], ins->type_class ),
                             LowPart( ins->result, ins->type_class ),
                             ins->type_class );
        DupSeg( ins, new_ins );
        ins->operands[ 0 ] = HighPart( ins->operands[ 0 ], ins->type_class );
        ins->result = HighPart( ins->result, ins->type_class );
        if( new_ins->result->n.class == N_REGISTER
         && ins->operands[ 0 ]->n.class == N_REGISTER
         && HW_Ovlap( new_ins->result->r.reg, ins->operands[ 0 ]->r.reg ) ) {
            SuffixIns( ins, new_ins );
            new_ins = ins;
        } else {
            PrefixIns( ins, new_ins );
        }
    }
コード例 #5
0
ファイル: split.c プロジェクト: joncampbell123/open-watcom-v2
instruction      *rOP1RESREG( instruction *ins )
/**********************************************/
{
    instruction         *new_ins;
    instruction         *ins2;
    name                *name1;
    name                *name2;

    name1 = AllocRegName( Op1Reg( ins ) );
    new_ins = MakeMove( ins->operands[0], name1, _OpClass( ins ) );
    ins->operands[0] = name1;
    MoveSegOp( ins, new_ins, 0 );
    PrefixIns( ins, new_ins );
    name2 = AllocRegName( ResultReg( ins ) );
    ins2 = MakeMove( name2, ins->result, ins->type_class );
    ins->result = name2;
    MoveSegRes( ins, ins2 );
    SuffixIns( ins, ins2 );
    return( new_ins );
}
コード例 #6
0
ファイル: flowsave.c プロジェクト: Azarien/open-watcom-v2
void FlowSave( hw_reg_set *preg )
/*******************************/
{
    int                 score;
    int                 i, j;
    int                 best;
    int                 num_blocks;
    int                 num_regs;
    int                 curr_reg;
    hw_reg_set          *curr_push;
    reg_flow_info       *reg_info;
    block               *save;
    block               *restore;
    instruction         *ins;
    type_class_def      reg_type;

    HW_CAsgn( flowedRegs, HW_EMPTY );
    if( _IsntModel( FLOW_REG_SAVES ) ) return;
    if( !HaveDominatorInfo ) return;
    // we can't do this if we have push's which are 'live' at the end of a block
    // - this flag is set when we see a push being generated for a call in a different
    //   block
#if _TARGET & _TARG_INTEL
    if( CurrProc->targ.never_sp_frame ) return;
#endif
    num_regs = CountRegs( *preg );
    if( num_regs == 0 ) return;
    reg_info = CGAlloc( num_regs * sizeof( reg_flow_info ) );
    num_blocks = CountBlocks();
    InitBlockArray();
    curr_push = PushRegs;
    for( curr_reg = 0; curr_reg < num_regs; curr_reg++ ) {
        while( !HW_Ovlap( *curr_push, *preg ) ) curr_push++;
        HW_Asgn( reg_info[curr_reg].reg, *curr_push );
        reg_info[curr_reg].save = NULL;
        reg_info[curr_reg].restore = NULL;
    #if _TARGET & _TARG_INTEL
        if( HW_COvlap( *curr_push, HW_BP ) ) continue;  // don't mess with BP - it's magical
    #endif
        GetRegUsage( &reg_info[curr_reg] );
        best = 0;
        for( i = 0; i < num_blocks; i++ ) {
            for( j = 0; j < num_blocks; j++ ) {
                if( PairOk( blockArray[i], blockArray[j], &reg_info[0], curr_reg ) ) {
                    // we use the number of blocks dominated by the save block plus
                    // the number of blocks post-dominated by the restore block as a
                    // rough metric for determining how much we like a given (valid)
                    // pair of blocks - the more blocks dominated, the further 'in'
                    // we have pushed the save, which should be good
                    score =  CountDomBits( &blockArray[i]->dom.dominator );
                    score += CountDomBits( &blockArray[j]->dom.post_dominator );
                    if( score > best ) {
                        best = score;
                        reg_info[curr_reg].save    = blockArray[i];
                        reg_info[curr_reg].restore = blockArray[j];
                    }
                }
            }
        }
        // so now we know where we are going to save and restore the register
        // emit the instructions to do so, and remove reg from the set to push
        // in the normal prolog sequence
        save = reg_info[curr_reg].save;
        restore = reg_info[curr_reg].restore;
        if( ( save != NULL && save != HeadBlock ) && ( restore != NULL && !_IsBlkAttr( restore, BLK_RETURN ) ) ) {
            reg_type = WD;
        #if _TARGET & _TARG_INTEL
            if( IsSegReg( reg_info[curr_reg].reg ) ) {
                reg_type = U2;
            }
        #endif
            ins = MakeUnary( OP_PUSH, AllocRegName( reg_info[curr_reg].reg ), NULL, reg_type );
            ResetGenEntry( ins );
            PrefixIns( save->ins.hd.next, ins );
            ins = MakeUnary( OP_POP, NULL, AllocRegName( reg_info[curr_reg].reg ), reg_type );
            ins->num_operands = 0;
            ResetGenEntry( ins );
            SuffixIns( restore->ins.hd.prev, ins );
            HW_TurnOff( *preg, reg_info[curr_reg].reg );
            HW_TurnOn( flowedRegs, reg_info[curr_reg].reg );
            FixStackDepth( save, restore );
        }
        curr_push++;
    }
    CGFree( reg_info );
}
コード例 #7
0
ファイル: 386setcc.c プロジェクト: ABratovic/open-watcom-v2
/* Take advantage of the SETcc instruction in cases such as
 * x = y ? 3 : 4;
 * by adding a constant to the result of SETcc to directly obtain
 * the result of the assignment.
 */
static  bool    FindFlowOut( block *blk ) {
/*****************************************/

    signed_64           false_cons;
    signed_64           true_cons;
    signed_64           one;
    signed_64           neg_one;
    signed_64           diff;
    instruction         *ins;
    instruction         *ins0;
    instruction         *ins1;
//    instruction         *prev;
    block               *true_blk;
    block               *false_blk;
    block               *join_blk;
    block_edge          *new_edge;
    bool                reverse;
    name                *u1temp;
    name                *temp;
    name                *result;
    name                *konst;
    type_class_def      class;

    for( ins = blk->ins.hd.prev; !_OpIsCondition( ins->head.opcode ); ) {
        ins = ins->head.prev;
    }
//    prev = ins->head.prev;
    if( TypeClassSize[ ins->type_class ] > WORD_SIZE ) return( FALSE );
    true_blk = blk->edge[ _TrueIndex( ins ) ].destination.u.blk;
    if( true_blk->inputs != 1 ) return( FALSE );
    if( true_blk->targets != 1 ) return( FALSE );

    false_blk = blk->edge[ _FalseIndex( ins ) ].destination.u.blk;
    if( false_blk->inputs != 1 ) return( FALSE );
    if( false_blk->targets != 1 ) return( FALSE );

    join_blk = false_blk->edge[ 0 ].destination.u.blk;
    if( join_blk != true_blk->edge[ 0 ].destination.u.blk ) return( FALSE );
    if( join_blk->inputs != 2 ) return( FALSE );
    if( join_blk->class & UNKNOWN_DESTINATION ) return( FALSE );

    ins0 = SetToConst( false_blk, &false_cons );
    if( ins0 == NULL ) return( FALSE );
    ins1 = SetToConst( true_blk, &true_cons );
    if( ins1 == NULL ) return( FALSE );

    I32ToI64( 1, &one );
    I32ToI64( -1, &neg_one );
    U64Sub( &true_cons, &false_cons, &diff );
    if( U64Cmp( &diff, &neg_one ) == 0 ) {
        U64IncDec( &false_cons, -1 );
        reverse = TRUE;
    } else {
        if( U64Cmp( &diff, &one ) != 0 ) return( FALSE );
        reverse = FALSE;
    }
    result = ins0->result;
    if( result != ins1->result ) return( FALSE );
    class = ins0->type_class;
    if( class != ins1->type_class ) return( FALSE );

    if( reverse ) FlipCond( ins );

    u1temp = AllocTemp( U1 );
    temp = AllocTemp( class );

    ins->result = u1temp;
    ins1 = MakeConvert( u1temp, temp, class, U1 );
    SuffixIns( ins, ins1 );
    ins = ins1;

    if( I64Test( &false_cons ) != 0 ) {
        konst = AllocS64Const( false_cons.u._32[I64LO32], false_cons.u._32[I64HI32] );
        ins1 = MakeBinary( OP_ADD, temp, konst, result, class );
    } else {
コード例 #8
0
ファイル: rtcall.c プロジェクト: ArmstrongJ/open-watcom-v2
instruction     *rMAKECALL( instruction *ins )
/*********************************************
    Using the table RTInfo[], do all the necessary stuff to turn
    instruction "ins" into a call to a runtime support routine.  Move
    the parms into registers, and move the return register of the
    runtime routine into the result. Used for 386 and 370 versions
*/
{
    rtn_info            *info;
    label_handle        lbl;
    instruction         *left_ins;
    instruction         *new_ins;
    instruction         *last_ins;
    name                *reg_name;
    hw_reg_set          regs;
    hw_reg_set          all_regs;
    hw_reg_set          tmp;
    rt_class            rtindex;

    if( !_IsConvert( ins ) ) {
        rtindex = LookupRoutine( ins );
    } else { /* look it up again in case we ran out of memory during expansion*/
        rtindex = LookupConvertRoutine( ins );
    }
    info = &RTInfo[rtindex];
    regs = _ParmReg( info->left );
    all_regs = regs;
    left_ins = MakeMove( ins->operands[0], AllocRegName( regs ),
                          info->operand_class );
    ins->operands[0] = left_ins->result;
    MoveSegOp( ins, left_ins, 0 );
    PrefixIns( ins, left_ins );
    regs = _ParmReg( info->right );
    if( !HW_CEqual( regs, HW_EMPTY ) ) {
        new_ins = MakeMove( ins->operands[1], AllocRegName( regs ),
                                info->operand_class );
        ins->operands[1] = new_ins->result;
        MoveSegOp( ins, new_ins, 0 );
        HW_TurnOn( all_regs, regs );
        PrefixIns( ins, new_ins );
    }
#if _TARGET & _TARG_370
    tmp = RAReg();
    HW_TurnOn( all_regs, tmp );
    tmp = LNReg();
    HW_TurnOn( all_regs, tmp );
#elif _TARGET & _TARG_80386
    {
    tmp = ReturnReg( WD, false );
    HW_TurnOn( all_regs, tmp );
    }
#endif
    reg_name = AllocRegName( all_regs );
    lbl = RTLabel( rtindex );
    new_ins = NewIns( 3 );
    new_ins->head.opcode = OP_CALL;
    new_ins->type_class = ins->type_class;
    new_ins->operands[CALL_OP_USED] = reg_name;
    new_ins->operands[CALL_OP_USED2] = reg_name;
    new_ins->operands[CALL_OP_ADDR] = AllocMemory( lbl, 0, CG_LBL, ins->type_class );
    new_ins->result = NULL;
    new_ins->num_operands = 2;         /* special case for OP_CALL*/
#if _TARGET & _TARG_AXP
    {
    HW_CTurnOn( all_regs, HW_FULL );
    HW_TurnOff( all_regs, SavedRegs() );
    HW_CTurnOff( all_regs, HW_UNUSED );
    HW_TurnOn( all_regs, ReturnAddrReg() );
    }
#endif
    new_ins->zap = (register_name *)AllocRegName( all_regs );   /* all parm regs could be zapped*/
    last_ins = new_ins;
    if( ins->result == NULL || _OpIsCondition( ins->head.opcode ) ) {
        /* comparison, still need conditional jumps*/
        ins->operands[0] = AllocIntConst( 0 );
        ins->operands[1] = AllocIntConst( 1 );
        DelSeg( ins );
        DoNothing( ins );               /* just conditional jumps for ins*/
        PrefixIns( ins, new_ins );
        new_ins->ins_flags |= INS_CC_USED;
        last_ins = ins;
    } else {
        regs = _ParmReg( info->result );
        tmp = regs;
        HW_TurnOn( tmp, new_ins->zap->reg );
        new_ins->zap = (register_name *)AllocRegName( tmp );
        reg_name = AllocRegName( regs );
        new_ins->result = reg_name;
        last_ins = MakeMove( reg_name, ins->result, ins->type_class );
        ins->result = last_ins->operands[0];
        MoveSegRes( ins, last_ins );
        SuffixIns( ins, last_ins );
        ReplIns( ins, new_ins );
    }
    FixCallIns( new_ins );
    UpdateLive( left_ins, last_ins );
    return( left_ins );
}