386splt2.c

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

C
750
字号
    new_ins = MakeUnary( ins->head.opcode,
                         OffsetPart( ins->operands[ 0 ] ),
                         NULL, U4 );
    ins->operands[ 0 ] = SegmentPart( ins->operands[ 0 ] );
    op = ins->operands[ 0 ];
    DupSeg( ins, new_ins );
    if( ins->head.opcode == OP_PUSH ) {
        SuffixIns( ins, new_ins );
        ChangeType( ins, U2 );
        return( ins );
    } else {
        PrefixIns( ins, new_ins );
        if( op->n.class != N_REGISTER ) {
            ChangeType( ins, U4 );
            temp = AllocTemp( U4 );
            ins2 = MakeMove( LowPart( temp, U2 ), op, U2 );
            ins->operands[ 0 ] = temp;
            MoveSegOp( ins, ins2, 1 );
            SuffixIns( ins, ins2 );
        } else {
            ChangeType( ins, U2 );
        }
        return( new_ins );
    }
}

extern  instruction     *rMAKEU2( instruction *ins ) {
/***************************************************/

/* for 48 bit pointers operations */

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

    if( Overlaps( ins->result, ins->operands[ 0 ] )
     || ( ins->num_operands >= 2 &&
            Overlaps( ins->result, ins->operands[ 1 ] ) ) ) {
        ChangeType( ins, U4 );
        if( ins->result != NULL ) {
            new_ins = MakeMove( SegmentPart( ins->operands[ 0 ] ),
                                 AllocTemp( U2 ), U2 );
            temp = SegmentPart( ins->result );
            ins->result = OffsetPart( ins->result );
            DupSegOp( ins, new_ins, 0 );
            PrefixIns( ins, new_ins );
        } else {
            new_ins = ins;
        }
        ins->operands[ 0 ] = OffsetPart( ins->operands[ 0 ] );
        if( ins->result != NULL ) {
            ins2 = MakeMove( new_ins->result, temp, U2 );
            DupSegRes( ins, ins2 );
            SuffixIns( ins, ins2 );
        }
    } else {
        ChangeType( ins, U4 );
        if( ins->result != NULL ) {
            new_ins = MakeMove( SegmentPart( ins->operands[ 0 ] ),
                                 SegmentPart( ins->result ), U2 );
            ins->result = OffsetPart( ins->result );
            DupSegOp( ins, new_ins, 0 );
            DupSegRes( ins, new_ins );
            PrefixIns( ins, new_ins );
        } else {
            new_ins = ins;
        }
        ins->operands[ 0 ] = OffsetPart( ins->operands[ 0 ] );
        if( NumOperands( ins ) >= 2 ) {
            ins->operands[ 1 ] = OffsetPart( ins->operands[ 1 ] );
        }
    }
    return( new_ins );
}



extern instruction      *rLOADLONGADDR( instruction *ins ) {
/*********************************************************/

    instruction         *new_ins;
    name                *name1;

    new_ins = MakeMove( SegName( ins->operands[ 0 ] ),
                            SegmentPart( ins->result ), U2 );
    ChangeType( ins, U4 );
    ins->result = OffsetPart( ins->result );
    name1 = ins->operands[ 0 ];
    if( name1->n.class == N_INDEXED ) {
        if( name1->i.index->n.size == 6 ) {
            ins->operands[ 0 ] = ScaleIndex(
                OffsetPart( name1->i.index ),
                name1->i.base, name1->i.constant,
                name1->n.name_class, name1->n.size,
                name1->i.scale, name1->i.index_flags );
        }
    }
    DupSegRes( ins, new_ins );
    PrefixIns( ins, new_ins );
    return( new_ins );
}


extern  instruction     *rHIGHCMP( instruction *ins ) {
/****************************************************/

/* floating point comparison with 0*/
    if( ins->type_class == FD ) {
        ins->operands[ 0 ] = HighPart( ins->operands[ 0 ], SW );
    }
    ChangeType( ins, SW );
    return( ins );
}


extern  instruction     *rMAKEU4( instruction *ins ) {
/***************************************************/

/* change pointer '==' or '!=' to 6 byte compare */

    name                *left;
    name                *rite;
    instruction         *new_ins;
    instruction         *low;
    instruction         *high;
    instruction         *first;
    byte                true_idx;
    byte                false_idx;
    name                *lseg;
    name                *rseg;
    name                *temp;

    left = ins->operands[ 0 ];
    rite = ins->operands[ 1 ];
    true_idx = _TrueIndex( ins );
    false_idx = _FalseIndex( ins );
    if( ins->head.opcode == OP_CMP_NOT_EQUAL ) {
        low = MakeCondition( ins->head.opcode, OffsetPart( left ),
                             OffsetPart( rite ), true_idx, NO_JUMP, U4 );
    } else {
        low = MakeCondition( ins->head.opcode, OffsetPart( left ),
                             OffsetPart( rite ), false_idx, NO_JUMP, U4 );
    }
    lseg = SegmentPart( left );
    first = NULL;
    if( lseg->n.class == N_REGISTER && ( HW_COvlap( lseg->r.reg, HW_SEGS ) ) ) {
        temp = AllocTemp( U2 );
        new_ins = MakeMove( lseg, temp, U2 );
        PrefixIns( ins, new_ins );
        if( first == NULL ) first = new_ins;
        lseg = temp;
    }
    rseg = SegmentPart( rite );
    if( rseg->n.class == N_REGISTER && ( HW_COvlap( rseg->r.reg, HW_SEGS ) ) ) {
        temp = AllocTemp( U2 );
        new_ins = MakeMove( rseg, temp, U2 );
        PrefixIns( ins, new_ins );
        if( first == NULL ) first = new_ins;
        rseg = temp;
    }
    high = MakeCondition( ins->head.opcode, lseg,
                          rseg, true_idx, false_idx, U2 );
    if( low->head.opcode == OP_CMP_EQUAL ) {
        low->head.opcode = OP_CMP_NOT_EQUAL;
    }
    if( first == NULL ) first = low;
    DupSeg( ins, low );
    PrefixIns( ins, low );
    DupSeg( ins, high );
    ReplIns( ins, high );
    UpdateLive( first, high );
    return( first );
}


extern  instruction     *rCLRHI_D( instruction *ins ) {
/*******************************************************/

    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 );
    DupSegRes( ins, new_ins );         /* 2004-11-01  RomanT (same as bug #341) */
    PrefixIns( ins, new_ins );
    return( new_ins );
}


extern  instruction     *rEXT_PUSH1( instruction *ins ) {
/******************************************************/

    name        *temp;
    instruction *new_ins;

    temp = AllocTemp( U4 );
    new_ins = MakeConvert( ins->operands[ 0 ], temp, U4, U1 );
    ins->operands[ 0 ] = temp;
    ChangeType( ins, U4 );
    MoveSegOp( ins, new_ins, 0 );
    PrefixIns( ins, new_ins );
    return( new_ins );
}



extern  instruction     *rEXT_PUSH2( instruction *ins ) {
/**********************************************************/

    name        *temp;
    instruction *new_ins;

    temp = AllocTemp( U4 );
    new_ins = MakeConvert( ins->operands[ 0 ], temp, U4, U2 );
    ins->operands[ 0 ] = temp;
    ChangeType( ins, U4 );
    MoveSegOp( ins, new_ins, 0 );
    PrefixIns( ins, new_ins );
    return( new_ins );
}

extern  instruction     *rINTCOMP( instruction *ins ) {
/*********************************************************/

    name                *left;
    name                *right;
    instruction         *low;
    instruction         *high;
    type_class_def      half_class;
    byte                true_idx;
    byte                false_idx;
    byte                first_idx;
    bool                rite_is_zero;

    rite_is_zero = CFTest( ins->operands[1]->c.value ) == 0;
    if( ins->type_class == FS ) {
        ChangeType( ins, I4 );
        // V_INTCOMP ensures that this is only called
        // for OP_CMP_EQUAL and OP_CMP_NOT_EQUAL if
        // rite_is_zero
        if( rite_is_zero ) {
            ins->operands[ 1 ] = AllocS32Const( 0x7fffffff );
            if( ins->head.opcode == OP_CMP_EQUAL ) {
                ins->head.opcode = OP_BIT_TEST_FALSE;
            } else if( ins->head.opcode == OP_CMP_NOT_EQUAL ) {
                ins->head.opcode = OP_BIT_TEST_TRUE;
            }
        } else {
            ins->operands[ 1 ] = IntEquivalent( ins->operands[1] );
        }
        return( ins );
    }
    half_class = HalfClass[  ins->type_class  ];
    left = ins->operands[ 0 ];
    if( left->n.class == N_CONSTANT && left->c.const_type == CONS_ABSOLUTE ) {
        CnvOpToInt( ins, 0 );
        left = ins->operands[ 0 ];
    }
    right = ins->operands[ 1 ];
    if( right->n.class == N_CONSTANT && right->c.const_type == CONS_ABSOLUTE ) {
        CnvOpToInt( ins, 1 );
        right = ins->operands[ 1 ];
    }
    true_idx = _TrueIndex( ins );
    false_idx = _FalseIndex( ins );
    first_idx = ( ins->head.opcode == OP_CMP_EQUAL ) ? false_idx : true_idx;
    if( rite_is_zero ) {
        high = MakeCondition( OP_BIT_TEST_TRUE,
                        HighPart( left, half_class ),
                        AllocS32Const( 0x7fffffff ),
                        first_idx, NO_JUMP, half_class );
    } else {
        high = MakeCondition( OP_CMP_NOT_EQUAL,
                        HighPart( left, half_class ),
                        HighPart( right, half_class ),
                        first_idx, NO_JUMP, half_class );
    }
    DupSeg( ins, high );
    PrefixIns( ins, high );
    low = MakeCondition( ins->head.opcode,
                    LowPart( left, half_class ),
                    LowPart( right, half_class ),
                    true_idx, false_idx,
                    half_class );
    DupSeg( ins, low );
    ReplIns( ins, low );
    return( high );
}

extern  instruction     *rCDQ( instruction *ins ) {
/*************************************************/

    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;
    ins2 = MakeBinary( OP_RSHIFT, ins->operands[0], AllocIntConst( 31 ), high, SW );
    DupSeg( ins, ins2 );
    SuffixIns( ins, ins2 );
    return( ins );
}

extern  instruction     *rCONVERT_UP( instruction *ins ) {
/********************************************************/

    name                *temp;
    instruction         *ins1;
    instruction         *ins2;
    type_class_def      tipe;

    // change a CNV I8 I1 op -> res into a pair of instructions
    //          CNV I4 I1 op -> temp and CNV I8 I4 temp -> res
    //
    // 2005-09-25 RomanT
    // Fixed wrong type of temp.variable (must have sign of source operand).
    // Now it goes: U1/2->U4->U8/I8, I1/2->I4->U8/I8.
    //
    if ( Unsigned[ ins->base_type_class ] == ins->base_type_class )
        tipe = U4;
    else
        tipe = I4;
    temp = AllocTemp( tipe );
    ins1 = MakeConvert( ins->operands[ 0 ], temp, tipe, ins->base_type_class );
    DupSegOp( ins, ins1, 0 );    // 2005-09-25 RomanT (bug #341)
    PrefixIns( ins, ins1 );
    ins2 = MakeConvert( temp, ins->result, ins->type_class, tipe );
    DupSegRes( ins, ins2 );      // 2004-11-01 RomanT (same as bug #341, *pInt64=char)
    ReplIns( ins, ins2 );
    return( ins1 );
}

extern  instruction     *rCYP_SEX( instruction *ins ) {
/*****************************************************/

    name        *op;
    name        *new_op;
    instruction *shft;
    unsigned    size;

    op = ins->operands[0];
    size = WORD_SIZE - op->n.size;
    new_op = OpAdjusted( op, -size, SW );
    ChangeType( ins, SW );
    ins->operands[0] = new_op;
    ins->head.opcode = OP_MOV;
    op = ins->result;
    shft = MakeBinary( OP_RSHIFT, op, AllocIntConst( size*8 ), op, SW );
    DupSeg( ins, shft );
    SuffixIns( ins, shft );
    return( ins );
}

extern  instruction     *rSPLIT8( instruction *ins ) { return( ins ); }
extern  instruction     *rSPLIT8BIN( instruction *ins ) { return( ins ); }
extern  instruction     *rSPLIT8NEG( instruction *ins ) { return( ins ); }
extern  instruction     *rSPLIT8TST( instruction *ins ) { return( ins ); }
extern  instruction     *rSPLIT8CMP( instruction *ins ) { return( ins ); }
extern  instruction     *rCLRHIGH_DW( instruction *ins ) { return( ins ); }
extern  instruction     *rSEX_DW( instruction *ins ) { return( ins ); }
extern  instruction     *rCYPSHIFT( instruction *ins ) { return( ins ); }
extern  instruction     *rBYTESHIFT( instruction *ins ) { return( ins ); }
extern  instruction     *rMOVE8LOW( instruction *ins ) { return( ins ); }

⌨️ 快捷键说明

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