rscsplit.c

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

C
1,383
字号
        }
        ins2->table = CodeTable( ins2 );
        new_ins->table = ins2->table;
        ins->operands[0] = temp;
        ins->operands[1] = temp;
        PrefixIns( ins, new_ins );
        PrefixIns( ins, ins2 );
        ins2 = MakeMove( LowPart( temp, WORD ), LowPart( ins->result, WORD ), WORD );
        PrefixIns( ins, ins2 );
        ins2 = MakeMove( HighPart( temp, WORD ),
                          HighPart( ins->result, WORD ), WORD );
        ReplIns( ins, ins2 );
    } else {
        HalfType( ins );
        new_ins = MakeBinary( ins->head.opcode,
                        LowPart( ins->operands[0], ins->type_class ),
                        LowPart( ins->operands[1], ins->type_class ),
                        LowPart( ins->result,      ins->type_class ),
                        ins->type_class );
        ins->operands[0] = HighPart( ins->operands[0], ins->type_class );
        ins->operands[1] = HighPart( ins->operands[1], ins->type_class );
        ins->result = HighPart( ins->result, ins->type_class );
        if( ins->head.opcode == OP_ADD ) {
            ins->head.opcode = OP_EXT_ADD;
        } else if( ins->head.opcode == OP_SUB ) {
            ins->head.opcode = OP_EXT_SUB;
        }
        ins->table = CodeTable( ins );
        new_ins->table = ins->table;

        PrefixIns( ins, new_ins );
    }
    new_ins->ins_flags |= INS_CC_USED;
    return( new_ins );
}


extern instruction *rSPLITMOVE( instruction *ins )
/*************************************************
* Split a multi-word move instruction.
*/
{
    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 );
        ins->operands[0] = temp;
        PrefixIns( ins, new_ins );
        PrefixIns( ins, ins2 );
        ins2 = MakeMove( LowPart( temp, WORD ), LowPart( ins->result, WORD ), WORD );
        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 );
        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 );
        }
    }
    return( new_ins );
}


extern  instruction     *rSPLITNEG( instruction *ins )
/*****************************************************
* Split a multi-word negate instruction.
*/
{
    name            *hi_res;
    name            *lo_res;
    name            *hi_src;
    name            *lo_src;
    instruction     *hi_ins;
    instruction     *lo_ins;
    instruction     *subtract;

    HalfType( ins );
    hi_res = HighPart( ins->result, ins->type_class );
    hi_src = HighPart( ins->operands[0], ins->type_class );
    lo_res = LowPart( ins->result, ins->type_class );
    lo_src = LowPart( ins->operands[0], ins->type_class );
    hi_ins = MakeUnary( OP_NEGATE, hi_src, hi_res, ins->type_class );
    lo_ins = MakeUnary( OP_NEGATE, lo_src, lo_res, ins->type_class );
    lo_ins->ins_flags |= INS_CC_USED;
    subtract = MakeBinary( OP_EXT_SUB, hi_res, AllocIntConst( 0 ), hi_res,
                            ins->type_class );
    PrefixIns( ins, hi_ins );
    ins->operands[0] = ins->result;
    ins->operands[1] = AllocIntConst( 0 );
    PrefixIns( ins, lo_ins );
    ReplIns( ins, subtract );
    UpdateLive( hi_ins, subtract );
    return( hi_ins );
}


extern instruction      *rSPLITUNARY( instruction *ins )
/*******************************************************
* Split a multi-word unary operation. Only valid for ops
* which can be split into two independent operations on
* constituent types (e.g. bitwise complement).
*/
{
    instruction         *new_ins;
    name                *high_res;
    name                *low_res;

    CnvOpToInt( ins, 0 );
    HalfType( ins );
    if( ins->result == NULL ) {
        high_res = NULL;
        low_res = NULL;
    } else {
        high_res = HighPart( ins->result, ins->type_class );
        low_res  = LowPart( ins->result, ins->type_class );
    }
    new_ins = MakeUnary( ins->head.opcode,
                         LowPart( ins->operands[0], ins->type_class ),
                         low_res, ins->type_class );
    ins->operands[0] = HighPart( ins->operands[0],ins->type_class );
    ins->result = high_res;
    if( ins->head.opcode == OP_PUSH ) {
        SuffixIns( ins, new_ins );
        new_ins = ins;
    } else {
        PrefixIns( ins, new_ins );
    }
    return( new_ins );
}


extern  instruction     *rCLRHI_4( instruction *ins )
/****************************************************
* Clear the high 32 bits of a 64-bit name
*/
{
    name                *high;
    name                *low;
    instruction         *new_ins;
    type_class_def      tipe;

    tipe = HalfClass[ins->type_class];
    low = LowPart( ins->result, tipe );
    high = HighPart( ins->result, tipe );
    ChangeType( ins, tipe );
    ins->head.opcode = OP_MOV;
    ins->result = low;
    new_ins = MakeMove( AllocS32Const( 0 ), high, tipe );
    PrefixIns( ins, new_ins );
    return( new_ins );
}


extern  instruction     *rSEX_4TO8( instruction *ins )
/*****************************************************
* Sign-extend a 32-bit name to 64-bit
*/
{
    instruction         *ins1;
    instruction         *ins2;
    name                *high;

    high = HighPart( ins->result, WD );
    ins->result = LowPart( ins->result, WD );
    ins->head.opcode = OP_MOV;
    ins->type_class = WD;
    ins->base_type_class = WD;
    ins->table = NULL;
    ins1 = MakeMove( ins->operands[0], high, WD );
    SuffixIns( ins, ins1 );
    ins2 = MakeBinary( OP_RSHIFT, high, AllocIntConst( 31 ), high, SW );
    SuffixIns( ins1, ins2 );
    return( ins );
}


extern  instruction     *rSPLITCMP( instruction *ins )
/*****************************************************
* Split a multi-word comparison instruction
*/
{
    name                *left;
    name                *right;
    instruction         *low = NULL;
    instruction         *high = NULL;
    instruction         *not_equal = NULL;
    type_class_def      high_class;
    type_class_def      low_class;
    byte                true_idx;
    byte                false_idx;

    high_class = HalfClass[ins->type_class];
    low_class  = Unsigned[high_class];
    left = ins->operands[0];
    right = ins->operands[1];
    true_idx = _TrueIndex( ins );
    false_idx = _FalseIndex( ins );
    switch( ins->head.opcode ) {
    case OP_BIT_TEST_TRUE:
        high = MakeCondition( ins->head.opcode,
                        HighPart( left, high_class ),
                        HighPart( right, high_class ),
                        true_idx, NO_JUMP,
                        WORD );
        low = MakeCondition( ins->head.opcode,
                        LowPart( left, low_class ),
                        LowPart( right, low_class ),
                        true_idx, false_idx,
                        WORD );
        not_equal = NULL;
        break;
    case OP_BIT_TEST_FALSE:
        high = MakeCondition( OP_BIT_TEST_TRUE,
                        HighPart( left, high_class ),
                        HighPart( right, high_class ),
                        false_idx, NO_JUMP,
                        WORD );
        low = MakeCondition( ins->head.opcode,
                        LowPart( left, low_class ),
                        LowPart( right, low_class ),
                        true_idx, false_idx,
                        WORD );
        not_equal = NULL;
        break;
    case OP_CMP_EQUAL:
        high = MakeCondition( OP_CMP_NOT_EQUAL,
                        HighPart( left, high_class ),
                        HighPart( right, high_class ),
                        false_idx, NO_JUMP,
                        WORD );
        low = MakeCondition( ins->head.opcode,
                        LowPart( left, low_class ),
                        LowPart( right, low_class ),
                        true_idx, false_idx,
                        WORD );
        not_equal = NULL;
        break;
    case OP_CMP_NOT_EQUAL:
        high = MakeCondition( OP_CMP_NOT_EQUAL,
                        HighPart( left, high_class ),
                        HighPart( right, high_class ),
                        true_idx, NO_JUMP,
                        WORD );
        low = MakeCondition( ins->head.opcode,
                        LowPart( left, low_class ),
                        LowPart( right, low_class ),
                        true_idx, false_idx,
                        WORD );
        not_equal = NULL;
        break;
    case OP_CMP_LESS:
    case OP_CMP_LESS_EQUAL:
        not_equal = MakeCondition( OP_CMP_NOT_EQUAL,
                        HighPart( left, high_class ),
                        HighPart( right, high_class ),
                        false_idx, NO_JUMP,
                        high_class );
        if( high_class == WORD
         && right->n.class == N_CONSTANT
         && right->c.const_type == CONS_ABSOLUTE
         && HIGH_WORD( right ) == 0 ) {
            high = NULL;
        } else {
            high = MakeCondition( OP_CMP_LESS,
                        not_equal->operands[0], not_equal->operands[1],
                        true_idx, NO_JUMP,
                        high_class );
        }
        low = MakeCondition( ins->head.opcode,
                        LowPart( left, low_class ),
                        LowPart( right, low_class ),
                        true_idx, false_idx,
                        low_class );
        break;
    case OP_CMP_GREATER_EQUAL:
    case OP_CMP_GREATER:
        not_equal = MakeCondition( OP_CMP_NOT_EQUAL,
                        HighPart( left, high_class ),
                        HighPart( right, high_class ),
                        false_idx, NO_JUMP,
                        high_class );
        if( high_class == WORD
         && right->n.class == N_CONSTANT
         && right->c.const_type == CONS_ABSOLUTE
         && HIGH_WORD( right ) == 0 ) {
            _SetBlockIndex( not_equal, true_idx, NO_JUMP );
            high = NULL;
        } else {
            high = MakeCondition( OP_CMP_GREATER,
                        not_equal->operands[0], not_equal->operands[1],
                        true_idx, NO_JUMP,
                        high_class );
        }
        low = MakeCondition( ins->head.opcode,
                        LowPart( left, low_class ),
                        LowPart( right, low_class ),
                        true_idx, false_idx,
                        low_class );
        break;
    default:
        break;
    }
    if( high != NULL ) {
        PrefixIns( ins, high );
    } else {
        high = not_equal;              /* for return value */
    }
    if( not_equal != NULL ) {
        PrefixIns( ins, not_equal );
    }
    ReplIns( ins, low );
    return( high );
}


extern instruction      *rMOVELOW( instruction *ins )
/****************************************************
* Move low part of a name, in other words chop off the
* high part (e.g. convert U8==>U4)
*/
{
    ins->head.opcode = OP_MOV;
    ins->operands[0] = LowPart( ins->operands[0], ins->type_class );
    ins->table = NULL;
    return( ins );
}

⌨️ 快捷键说明

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