split.c

来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 882 行 · 第 1/2 页

C
882
字号
        ins->u.gen_table = NULL;
        GiveRegister( NameConflict( ins, name1 ), TRUE );
    }
    return( new_ins );
}


extern instruction      *rCHANGESHIFT( instruction *ins )
/*******************************************************/
{
    signed_32   shift_count;

    shift_count = ins->operands[ 1 ]->c.int_value;
    assert( shift_count >= 0 );
    ins->operands[ 1 ] = AllocS32Const( shift_count & ( ( WORD_SIZE * 8 ) - 1 ) );
    return( ins );
}


extern instruction      *rFIXSHIFT( instruction *ins )
/****************************************************/
{
    signed_32           shift_count;
    instruction         *new_ins;

    /* Fix up shift instructions that try to shift by too large amounts. This
     * can happen when optimizer merges adjacent shift instructions. Arithmetic
     * rights shifts must never exceed (REGISTER_BITS - 1), logical shifts can
     * be replaced with loads of zero constant.
     */
    assert( ins->operands[ 1 ]->n.class == N_CONSTANT );
    shift_count = ins->operands[ 1 ]->c.int_value;
    assert( shift_count >= REG_SIZE * 8 );
    if( ins->head.opcode == OP_RSHIFT
        && Signed[ ins->type_class ] == ins->type_class ) {
        ins->operands[ 1 ] = AllocS32Const( REG_SIZE * 8 - 1 );
        return( ins );
    } else {
        new_ins = MoveConst( 0, ins->result, ins->type_class );
        DupSeg( ins, new_ins );
        ReplIns( ins, new_ins );
        return( new_ins );
    }
}


extern instruction      *rCLRHI_BW( instruction *ins )
/****************************************************/
{
    instruction         *new_ins;
    instruction         *ins2;
    name                *name1;
    type_class_def      class;

    class = HalfClass[  ins->type_class  ];
    name1 = AllocTemp( ins->type_class );
    new_ins = MakeMove( ins->operands[ 0 ],
                         LowPart( name1, class ), class );
    ins->operands[ 0 ] = name1;
    MoveSegOp( ins, new_ins, 0 );
    PrefixIns( ins, new_ins );
    ins2 = MoveConst( 0, HighPart( name1, class ), class );
    PrefixIns( ins, ins2 );
    ins->head.opcode = OP_MOV;
    ins->table = NULL;
    ins->u.gen_table = NULL;
    return( new_ins );
}


extern instruction      *rCLRHI_R( instruction *ins )
/***************************************************/
{
    instruction         *new_ins;
    instruction         *and_ins;
    type_class_def      class;
    hw_reg_set          high;
    name                *res;
    signed_32           value;
    type_class_def      half_class;
    name                *op;

    half_class = HalfClass[ ins->type_class ];
    op = ins->operands[0];
    class = ins->base_type_class;
    res = ins->result;
    high = HighReg( res->r.reg );
    if( op->n.class == N_INDEXED
        && op->i.index->n.class == N_REGISTER
        && HW_Ovlap( op->i.index->r.reg, res->r.reg ) ) {
        /* would have gen'd movzd  eax,[eax] */
        new_ins = NULL;
    } else if( !HW_CEqual( high, HW_EMPTY ) && half_class == class ) {
        if( op->n.class == N_REGISTER && HW_Equal( op->r.reg, high ) ) {        // BBB - may 19, 1994
            /* look out for movzd ax,ah */
            new_ins = NULL;
        } else {
            new_ins = MoveConst( 0, HighPart( res, class ), class );
        }
    } else if( op->n.class == N_REGISTER
            && HW_Ovlap( op->r.reg, res->r.reg ) ) {
        /* would have gen'd movzd eax,ah */
        new_ins = NULL;
    } else {
        new_ins = MoveConst( 0, res, ins->type_class );
    }
    ins->result = LowPart( res, class );
    if( new_ins != NULL ) {
        PrefixIns( ins, new_ins );
    } else {
        switch( class ) {
        case U1:
        case I1:
            value = 0xff;
            break;
        case U2:
        case I2:
            value = 0xffff;
            break;
        }
        high = res->r.reg;
        HW_TurnOff( high, ins->result->r.reg );
        new_ins = MakeNop();
        new_ins->zap = (register_name *) AllocRegName( high );
        SuffixIns( ins, new_ins ); // don't cause high part to be live on entry

        and_ins = MakeBinary( OP_AND, res, AllocS32Const( value ),
                                res, ins->type_class );
        SuffixIns( new_ins, and_ins );
        new_ins = ins;
    }
    ins->type_class = class;
    ins->head.opcode = OP_MOV;
    ins->table = NULL;
    ins->u.gen_table = NULL;
    return( new_ins );
}


extern instruction      *rCONVERT_LOW( instruction *ins )
/*******************************************************/
/* change convert 4 byte==>1 byte to 2 byte ==> 1 byte */
{
    ins->operands[ 0 ] = LowPart( ins->operands[ 0 ],
                            HalfClass[  ins->operands[ 0 ]->n.name_class  ] );
    ins->base_type_class = HalfClass[  ins->base_type_class  ];
    ins->table = NULL;
    return( ins );
}


extern instruction      *rCYPHIGH( instruction *ins )
/***************************************************/
{
    HalfType( ins );
    ins->operands[ 0 ] = HighPart( ins->operands[ 0 ], ins->type_class );
    ins->operands[ 1 ] = HighPart( ins->operands[ 1 ], ins->type_class );
    if( ins->result != NULL && ins->head.opcode < FIRST_CONDITION ) {
        ins->result = HighPart( ins->result, ins->type_class );
    }
    return( ins );
}


extern instruction      *rCYPLOW( instruction *ins )
/**************************************************/
{
    HalfType( ins );
    ins->operands[ 0 ] = LowPart( ins->operands[ 0 ], ins->type_class );
    ins->operands[ 1 ] = LowPart( ins->operands[ 1 ], ins->type_class );
    if( ins->result != NULL && ins->head.opcode < FIRST_CONDITION ) {
        ins->result = LowPart( ins->result, ins->type_class );
    }
    return( ins );
}


extern instruction      *rDOUBLEHALF( instruction *ins )
/******************************************************/
{
    instruction         *new_ins;
    name                *name1;

    name1 = ins->operands[ 1 ];
    name1 = AllocIntConst( name1->c.int_value>>1 );
    ins->operands[ 1 ] = name1;
    new_ins = MakeBinary( ins->head.opcode, ins->operands[ 0 ], name1,
                            ins->result, ins->type_class );
    new_ins->table = ins->table;
    DupSeg( ins, new_ins );
    PrefixIns( ins, new_ins );
    return( new_ins );
}


extern instruction      *rOP1MEM( instruction *ins )
/**************************************************/
{
    ForceToMemory( ins->operands[ 0 ] );
    return( ins );
}


extern instruction      *rOP2MEM( instruction *ins )
/**************************************************/
{
    ForceToMemory( ins->operands[ 1 ] );
    return( ins );
}


extern instruction      *rFORCERESMEM( instruction *ins )
/*******************************************************/
{
    ForceToMemory( ins->result );
    return( ins );
}


extern instruction      *rMAKEMOVE( instruction *ins )
/****************************************************/
{
    instruction         *new_ins;

    new_ins = MakeMove( ins->operands[ 0 ], ins->result, ins->type_class );
    DupSeg( ins, new_ins );
    ReplIns( ins, new_ins );
    return( new_ins );
}


extern instruction      *rMAKEXORRR( instruction *ins )
/*****************************************************/
{
    instruction         *new_ins;

    new_ins = MakeBinary( OP_XOR, ins->result, ins->result, ins->result,
                                    ins->type_class );
    ReplIns( ins, new_ins );
    return( new_ins );
}


extern instruction      *rADDRR( instruction *ins )
/*************************************************/
{
    ins->head.opcode = OP_ADD;
    ins->operands[ 1 ] = ins->operands[ 0 ];
    ins->table = NULL;
    return( ins );
}


extern instruction      *rMOVOP2( instruction *ins )
/**************************************************/
{
    instruction         *new_ins;

    new_ins = MakeMove( ins->operands[ 1 ], ins->result, ins->type_class );
    MoveSegOp( ins, new_ins, 0 );
    DupSegRes( ins, new_ins );
    ReplIns( ins, new_ins );
    return( new_ins );
}


extern instruction      *rMOVOP1RES( instruction *ins )
/*****************************************************/
{
    instruction         *new_ins;

    new_ins = MakeMove( ins->operands[ 0 ], ins->result, ins->type_class );
    ins->operands[ 0 ] = ins->result;
    MoveSegOp( ins, new_ins, 0 );
    DupSegRes( ins, new_ins );
    PrefixIns( ins, new_ins );
    return( new_ins );
}


/* 386 */
extern instruction      *rMOVOP2RES( instruction *ins )
/*****************************************************/
{
    instruction         *new_ins;

    new_ins = MakeMove( ins->operands[ 1 ], ins->result, ins->type_class );
    ins->operands[ 1 ] = ins->result;
    MoveSegOp( ins, new_ins, 1 );
    DupSegRes( ins, new_ins );
    PrefixIns( ins, new_ins );
    return( new_ins );
}

/* 370 */
extern instruction      *rSWAPOPS( instruction *ins )
/***************************************************/
{
    name                *name1;

    name1 = ins->operands[ 0 ];
    ins->operands[ 0 ] = ins->operands[ 1 ];
    ins->operands[ 1 ] = name1;
    return( ins );
}


/* 370 */
extern instruction      *rSWAPCMP( instruction *ins )
/***************************************************/
{
    RevCond( ins );
    return( rSWAPOPS( ins ) );
}


extern instruction      *rMOVEINDEX( instruction *ins )
/*****************************************************/
{
    instruction         *new_ins;

    new_ins = MakeMove( ins->operands[ 0 ]->i.index,
                         ins->result, ins->type_class );
    ReplIns( ins, new_ins );
    return( new_ins );
}

/* 370 */
extern instruction      *rLOADOP2( instruction *ins )
/***************************************************/
{
    instruction         *new_ins;
    name                *name1;

    name1 = AllocTemp( ins->type_class );
    new_ins = MakeMove( ins->operands[ 1 ], name1, ins->type_class );
    CheckCC( ins, new_ins );
    ins->operands[ 1 ] = name1;
    MoveSegOp( ins, new_ins, 0 );
    PrefixIns( ins, new_ins );
    MarkPossible( ins, name1, Op2Possible( ins ) );
    ins->u.gen_table = NULL;
    GiveRegister( NameConflict( ins, name1 ), TRUE );
    return( new_ins );
}


extern instruction      *rNEGADD( instruction *ins )
/**************************************************/
{
    instruction         *new_ins;

    new_ins = MakeUnary( OP_NEGATE, ins->operands[ 1 ],
                          AllocTemp( U4 ), U4 );
    MoveSegOp( ins, new_ins, 0 );
    ins->operands[ 1 ] = new_ins->result;
    ins->head.opcode = OP_ADD;
    ins->table = NULL;
    PrefixIns( ins, new_ins );
    return( new_ins );
}


static  void    NegOp2( instruction *ins )
/****************************************/
{
    ins->operands[ 1 ] = AllocConst( CFCnvI32F(
                                     -ins->operands[ 1 ]->c.int_value ) );
}


extern instruction      *rMAKEADD( instruction *ins )
/***************************************************/
{
    ins->head.opcode = OP_ADD;
    NegOp2( ins );
    ins->table = NULL;
    return( ins );
}


extern instruction      *rMAKENEG( instruction *ins )
/***************************************************/
{
    instruction         *new_ins;

    new_ins = MakeUnary( OP_NEGATE, ins->operands[ 1 ], ins->result,
                          ins->type_class );
    DupSeg( ins, new_ins );
    ReplIns( ins, new_ins );
    return( new_ins );
}


extern instruction      *rMAKESUB( instruction *ins )
/***************************************************/
{
    ins->head.opcode = OP_SUB;
    NegOp2( ins );
    ins->table = NULL;
    return( ins );
}


extern instruction      *rCMPTRUE( instruction *ins )
/***************************************************/
{
    DoNothing( ins );
    _SetBlockIndex( ins, _TrueIndex( ins ), _TrueIndex( ins ) );
    return( ins );
}


extern instruction      *rCMPFALSE( instruction *ins )
/****************************************************/
{
    DoNothing( ins );
    _SetBlockIndex( ins, _FalseIndex( ins ), _FalseIndex( ins ) );
    return( ins );
}


extern instruction      *rOP1RESTEMP( instruction *ins )
/******************************************************/
{
    instruction         *new_ins;
    instruction         *ins2;
    name                *name1;

    name1 = AllocTemp( ins->type_class );
    new_ins = MakeMove( ins->operands[ 0 ], name1, ins->type_class );
    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 );
    return( new_ins );
}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?