Пример #1
0
static  void    FlowConditions( void )
/*************************************
    For each block in the program, first "GatherSources" to determine
    what the state of the condition codes are on entry to the routine,
    then "Traverse" the block, to see if there is an instruction that
    sets the condition codes for the conditional branches at the end of
    the block correctly, or if the condition codes from previous blocks
    are unaffected by the block and will suffice for the final branch.
*/
{
    block       *blk;
    name        *zero;
    bool        change;

    zero = AllocIntConst( 0 );
    change = true;
    for( ;; ) {
        for( blk = HeadBlock; blk != NULL; blk = blk->next_block ) {
            GatherSources( blk );
            change |= Traverse( blk, zero );
        }
        if( change == false ) break;
        change = false;
    }
}
Пример #2
0
static  an      FlowOut( an node, type_def *tipe ) {
/**************************************************/

    name                *temp;
    label_handle        lbl;

    lbl = AskForNewLabel();
    temp = BGGlobalTemp( tipe );
    AddIns( MakeMove( AllocIntConst( FETrue() ), temp, temp->n.type_class ) );
    *(node->u.b.t) = CurrBlock->label;
    GenBlock( BLK_JUMP, 1 );
    AddTarget( lbl, false );
    EnLink( AskForNewLabel(), true );
    AddIns( MakeMove( AllocIntConst( 0 ), temp, temp->n.type_class ) );
    *(node->u.b.f) = CurrBlock->label;
    GenBlock( BLK_JUMP, 1 );
    AddTarget( lbl, false );
    EnLink( lbl, true );
    NamesCrossBlocks();
    AddrFree( node );
    return( AddrName( temp, tipe ) );
}
Пример #3
0
static  instruction *CmpRelocZero( instruction *ins, opcnt c, opcnt r )
/*********************************************************************/
{
    name        *cons;
    name        *rel;
    bool        truth;

    if( OpcodeNumOperands( ins ) != 2 )
        return( NULL );
    cons = ins->operands[c];
    if( cons->n.class != N_CONSTANT )
        return( NULL );
    if( cons->c.const_type != CONS_ABSOLUTE )
        return( NULL );
    if( CFTest( cons->c.value ) != 0 )
        return( NULL );
    rel = ins->operands[r];
    if( rel->c.const_type == CONS_OFFSET && !AskSegIsNear( (segment_id)rel->c.lo.int_value ) )
        return( NULL );
    switch( ins->head.opcode ) {
    case OP_BIT_TEST_FALSE:
    case OP_CMP_EQUAL:
    case OP_CMP_LESS:
    case OP_CMP_LESS_EQUAL:
        truth = false;
        break;
    case OP_BIT_TEST_TRUE:
    case OP_CMP_GREATER:
    case OP_CMP_GREATER_EQUAL:
    case OP_CMP_NOT_EQUAL:
        truth = true;
        break;
    default:
        return( false );
    }
    if( !ActiveCompare( ins ) )
        return( NULL );
    if( c != 1 )
        truth = !truth;
    if( truth ) {
        _SetBlockIndex( ins, _TrueIndex(ins), _TrueIndex(ins) );
    } else {
        _SetBlockIndex( ins, _FalseIndex(ins), _FalseIndex(ins) );
    }
    return( KillCompare( ins, AllocIntConst( truth ? FETrue() : 0 ) ) );
}
Пример #4
0
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 );
}