i86split.c

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

C
1,100
字号
        name_int = name_flt;
    } else {
        name_int = TempOffset( name_flt, 0, U4 );
    }
    name_flt->v.usage |= USE_MEMORY | NEEDS_MEMORY;
    new_ins = MakeMove( ins->operands[ 0 ], name_int, name_int->n.name_class);
    ins->operands[ 0 ] = name_flt;
    MoveSegOp( ins, new_ins, 0 );
    PrefixIns( ins, new_ins );
    return( new_ins );
}


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


    ins->operands[ 0 ] = Addressable( ins->operands[ 0 ], ins->type_class );
    return( ins );
}


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


    ins->operands[ 1 ] = Addressable( ins->operands[ 1 ], ins->type_class );
    return( ins );
}


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

    instruction         *new_ins;
    instruction         *ins2;
    name                *name1;
    name                *name2;

    ChangeType( ins, U2 );
    name1 = ins->operands[ 0 ];
    name2 = AllocTemp( U2 );
    new_ins = MakeMove( HighPart( name1, U2 ), name2, U2 );
    ins2 = MakeBinary( OP_OR, name2, LowPart( name1, U2 ), name2, U2 );
    ins->operands[ 0 ] = name2;
    DupSeg( ins, new_ins );
    DupSeg( ins, ins2 );
    DelSeg( ins );
    PrefixIns( ins, new_ins );
    PrefixIns( ins, ins2 );
    return( new_ins );
}


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

    instruction         *new_ins;

    new_ins = MakeBinary( OP_SUB, OffsetPart( ins->operands[ 0 ] ),
                           OffsetPart( ins->operands[ 1 ] ),
                           ins->result, SW );
    DupSeg( ins, new_ins );
    ReplIns( ins, new_ins );
    return( new_ins );
}


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

    instruction         *new_ins;

    ChangeType( ins, PT );
    new_ins = rMAKECALL( ins );
    return( new_ins );
}


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

    instruction         *new_ins;
    name                *name1;

    if( ins->ins_flags & INS_CODE_POINTER ) {
        name1 = AllocRegName( HW_CS );
    } else {
        name1 = NearSegment();
    }
    new_ins = MakeMove( name1, SegmentPart( ins->result ), U2 );
    ins->head.opcode = OP_MOV;
    ins->type_class = WD;
    ins->result = OffsetPart( ins->result );
    ins->table = NULL;
    DupSegRes( ins, new_ins );
    PrefixIns( ins, new_ins );
    return( new_ins );
}


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

    ChangeType( ins, U4 );
    ins->operands[ 0 ] = IntEquivalent( ins->operands[ 0 ] );
    return( ins );
}


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

    ins->head.opcode = OP_MOV;
    ChangeType( ins, WD );
    ins->operands[ 0 ] = OffsetPart( ins->operands[ 0 ] );
    return( ins );
}


/* NB: The following two routines are intended for 386 only */

extern instruction      *rMOVPTI8( instruction *ins )
/***************************************************/
{
    instruction         *new_ins;
    instruction         *ins2;

    new_ins = MakeMove( OffsetPart( ins->operands[0] ), LowPart( ins->result, U4 ), U4 );
    ins2    = MakeConvert( SegmentPart( ins->operands[0] ), HighPart( ins->result, U4 ), U4, U2 );
    DupSegRes( ins, ins2 );
    SuffixIns( ins, ins2 );
    ReplIns( ins, new_ins );
    return( new_ins );
}

extern instruction      *rMOVI8PT( instruction *ins )
/***************************************************/
{
    instruction         *new_ins;
    instruction         *ins2;

    new_ins = MakeMove( LowPart( ins->operands[0], U4 ), OffsetPart( ins->result ), U4 );
    ins2    = MakeMove( HighPart( ins->operands[0], U2 ), SegmentPart( ins->result ), U2 );
    DupSegRes( ins, ins2 );
    SuffixIns( ins, ins2 );
    ReplIns( ins, new_ins );
    return( new_ins );
}


extern  void    CheckCC( instruction *ins, instruction *new_ins ) {
/*****************************************************************/


    if( ins->head.opcode == OP_EXT_ADD || ins->head.opcode == OP_EXT_SUB ) {
    #if _TARGET & _TARG_80386
        new_ins->table = Move4; /* ensure it doesn't set the condition codes */
    #else
        new_ins->table = Move2; /* ensure it doesn't set the condition codes */
    #endif
        new_ins->ins_flags |= INS_CC_USED;
    }
}



static  instruction     *SplitPush( instruction *ins, type_length size ) {
/************************************************************************/

    instruction         *new_ins;
    instruction         *first_ins;
    name                *op;
    name                *new_op = NULL;

    size = (size + (WORD_SIZE-1)) &~(WORD_SIZE-1);
    op = ins->operands[ 0 ];
    first_ins = NULL;
    for( ;; ) {
        size -= WORD_SIZE;
        switch( op->n.class ) {
        case N_MEMORY:
            new_op = AllocMemory( op->v.symbol, op->v.offset + size,
                                  op->m.memory_type, WD );
            break;
        case N_TEMP:
            new_op = TempOffset( op, size, WD );
            new_op->t.temp_flags |= CG_INTRODUCED;
            break;
        case N_INDEXED:
            new_op = ScaleIndex( op->i.index, op->i.base,
                              op->i.constant + size, WD, 0,
                              op->i.scale, op->i.index_flags );
            break;
        default:
            Zoiks( ZOIKS_051 );
            break;
        }
        new_ins = MakeUnary( OP_PUSH, new_op, NULL, WD );
        if( size == 0 ) break;
        if( first_ins == NULL ) {
            first_ins = new_ins;
        }
        DupSeg( ins, new_ins );
        PrefixIns( ins, new_ins );
    }
    DupSeg( ins, new_ins );
    ReplIns( ins, new_ins );
    if( first_ins == NULL ) return( new_ins );
    return( first_ins );
}


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

    name        *sp;
    name        *at_sp;
    name        *temp;
    type_length size;
    instruction *move;
    instruction *sub_sp;
    instruction *temp_ins;
    hw_reg_set  hw_ss_sp;

    size = ins->operands[ 0 ]->n.size;
    if( size <= 4*WORD_SIZE ) {
        return( SplitPush( ins, size ) );
    } else {
        HW_CAsgn( hw_ss_sp, HW_SS );
        HW_CTurnOn( hw_ss_sp, HW_SP );
        sp = AllocRegName( HW_SP );
        if( _IsTargetModel( FLOATING_SS ) ) {
            temp = AllocTemp( CP );
            temp_ins = MakeMove( AllocRegName( hw_ss_sp ), temp, CP );
        } else {
            temp = AllocTemp( WD );
            temp_ins = MakeMove( sp, temp, WD );
        }
        at_sp = AllocIndex( temp, NULL, 0, XX );
        at_sp->n.size = size;
        move = MakeMove( ins->operands[ 0 ], at_sp, XX );
        ReplIns( ins, move );
        ins = LoadStringOps( move, &move->operands[ 0 ], &move->result );
        /*% mov CX,const will be the first if it's there so try for SUB SP,CX*/
        sub_sp = MakeBinary( OP_SUB, sp, AllocIntConst(
                               (size+(WORD_SIZE-1)) & ~(WORD_SIZE-1) ), sp, WD );
        if( ins->result != NULL && HW_CEqual( ins->result->r.reg, hw( CX ) ) ) {
            SuffixIns( ins, sub_sp );
        } else {
            PrefixIns( ins, sub_sp );
            ins = sub_sp;
        }
        SuffixIns( sub_sp, temp_ins );
    }
    return( ins );
}


extern  name    *OpAdjusted( name *op, int bias, type_class_def type ) {
/*********************************************************************

    Return a new op of type 'type' which is offset from the old op by the
    amount specified by 'bias'.

*/
    name        *new_op = NULL;

    switch( op->n.class ) {
    case N_MEMORY:
        new_op = AllocMemory( op->v.symbol, op->v.offset + bias,
                              op->m.memory_type, type );
        break;
    case N_TEMP:
        new_op = TempOffset( op, bias, type );
        new_op->t.temp_flags |= CG_INTRODUCED;
        break;
    case N_INDEXED:
        new_op = ScaleIndex( op->i.index, op->i.base,
                          op->i.constant + bias, SW, 0,
                          op->i.scale, op->i.index_flags );
        break;
    default:
        Zoiks( ZOIKS_051 );
        break;
    }
    return( new_op );
}


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

    instruction         *new;
    name                *new_op;

    new_op = OpAdjusted( ins->operands[0], ins->operands[0]->n.size - 1, U1 );
    new = MakeBinary( OP_XOR, new_op, AllocIntConst( 0x80 ), new_op, U1 );
    DupSegRes( ins, new );
    ReplIns( ins, new );
    return( new );
}


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

    int         i;
    name        *op;

    for( i = ins->num_operands-1; i >= 0; --i ) {
        op = ins->operands[i];
        if( op->n.class != N_TEMP ) continue;
        if( !(op->t.temp_flags & CONST_TEMP) ) continue;
        ins->operands[i] = op->v.symbol;
    }
    return( ins );
}


extern  void            CnvOpToInt( instruction * ins, int op ) {
/***************************************************************/

    name                *name1;

    switch( ins->type_class ) {
    case FS:
        name1 = ins->operands[ op ];
        if( name1->n.class == N_CONSTANT ) {
            ins->operands[ op ] = IntEquivalent( name1 );
        }
        break;
#if _TARGET & _TARG_80386
    // this is for the I8 stuff - can't tell what to do in
    // HighPart and LowPart if we don't get rid on constant
    // here
    case FD:
        name1 = ins->operands[ op ];
        if( name1->n.class == N_CONSTANT ) {
            ins->operands[ op ] = Int64Equivalent( name1 );
        }
        break;
#endif
    default:
        break;
    }
}


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

    assert( ins->type_class == CP );
    assert( ins->operands[ 1 ]->n.class == N_CONSTANT );
    assert( ins->operands[ 1 ]->c.int_value == 0 );
    if( ins->head.opcode == OP_CMP_EQUAL ||
        ins->head.opcode == OP_CMP_NOT_EQUAL ) {
        if( _IsTargetModel( NULL_SELECTOR_BAD ) ) {
            ins->operands[ 0 ] = HighPart( ins->operands[ 0 ], U2 );
            ChangeType( ins, U2 );
            return( ins );
        }
    }
    return( rMAKEU4( ins ) );
}

⌨️ 快捷键说明

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