rscsplit.c

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

C
1,383
字号
    first_ins = ( ( prom_ins == NULL ) ? first_ins : prom_ins );
    UpdateLive( first_ins, new_ins );
    return( first_ins );
}

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

    instruction         *new_ins;
    instruction         *first_ins;
    instruction         *prom_ins;
    name                *stack_reg;
    type_class_def      push_class;

    push_class = U8;
    if( _IsFloating( ins->type_class ) ) {
        push_class = FD;
    }
    prom_ins = PromoteOperand( ins );
    stack_reg = AllocRegName( StackReg() );
    first_ins = MakeMove( AllocIndex( stack_reg, NULL, 0, push_class ), ins->result, WD );
    PrefixIns( ins, first_ins );
    new_ins = MakeBinary( OP_ADD, stack_reg, AllocS32Const( TypeClassSize[ push_class ] ), stack_reg, push_class );
    ReplIns( ins, new_ins );
    first_ins = ( ( prom_ins == NULL ) ? first_ins : prom_ins );
    UpdateLive( first_ins, new_ins );
    return( first_ins );
}

static  instruction     *LoadFPConst( instruction *ins, name **constant ) {
/*************************************************************************/

    name                *temp_1;
    name                *temp_2;
    name                *mem;
    instruction         *first_ins;
    instruction         *last_ins;

    temp_1 = AllocTemp( CP );
    temp_2 = AllocTemp( ins->type_class );
    mem = GenFloat( *constant, ins->type_class );
    first_ins = MakeUnary( OP_LA, mem, temp_1, WD );
    PrefixIns( ins, first_ins );
    last_ins = MakeMove( AllocIndex( temp_1, NULL, 0, ins->type_class ), temp_2, ins->type_class );
    PrefixIns( ins, last_ins );
    *constant = temp_2;
    UpdateLive( first_ins, ins );
    return( first_ins );
}

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

    ins = LoadFPConst( ins, &ins->operands[ 0 ] );
    return( ins );
}

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

    ins = LoadFPConst( ins, &ins->operands[ 1 ] );
    return( ins );
}

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

    type_class_def              new;

    assert( ins->type_class == XX );
    switch( ins->operands[ 0 ]->n.size ) {
    case 1:
        new = U1;
        break;
    case 2:
        new = U2;
        break;
    case 4:
        new = U4;
        break;
    case 8:
        new = U8;
        break;
    default:
        new = U1;
        _Zoiks( ZOIKS_120 );
    }
    ChangeType( ins, new );
    return( ins );
}

static void     UseAddress( name *op ) {
/**************************************/

    name        *next;

    switch( op->n.class ) {
    case N_TEMP:
        next = op->t.alias;
        for(;;) {
            next->v.usage |= USE_ADDRESS;
            if( next == op ) break;
            next = next->t.alias;
        }
        break;
    case N_MEMORY:
        op->v.usage |= USE_ADDRESS;
        break;
    }
}

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

    instruction         *first_ins;
    instruction         *new_ins;
    name                *len;
    name                *reg_name;
    label_handle        lbl;
    hw_reg_set          all_regs;
    hw_reg_set          reg;

    reg = FirstReg( RL_PARM_4 );
    all_regs = reg;
    reg_name = AllocRegName( reg );
    first_ins = MakeUnary( OP_LA, ins->result, reg_name, CP );
    PrefixIns( ins, first_ins );
    UseAddress( ins->result );
    reg = FirstReg( RL_PARM2_4 );
    reg_name = AllocRegName( reg );
    HW_TurnOn( all_regs, reg );
    new_ins = MakeUnary( OP_LA, ins->operands[ 0 ], reg_name, CP );
    PrefixIns( ins, new_ins );
    UseAddress( ins->operands[ 0 ] );
    len = AllocS32Const( ins->operands[ 0 ]->n.size );
    reg = FirstReg( RL_PARM3_4 );
    reg_name = AllocRegName( reg );
    HW_TurnOn( all_regs, reg );
    new_ins = MakeMove( len, reg_name, CP );
    PrefixIns( ins, new_ins );
    HW_TurnOn( all_regs, ReturnAddrReg() );
    reg_name = AllocRegName( all_regs );
    lbl = RTLabel( RT_MEMCPY );
    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 );
    HW_CTurnOn( all_regs, HW_FULL );
    HW_TurnOff( all_regs, SavedRegs() );
    HW_CTurnOff( all_regs, HW_UNUSED );
    HW_TurnOn( all_regs, ReturnAddrReg() );
    reg_name = AllocRegName( all_regs );
    new_ins->result = NULL;
    new_ins->num_operands = 2;          /* special case for OP_CALL*/
    HW_CTurnOn( all_regs, HW_FULL );
    HW_TurnOff( all_regs, SavedRegs() );
    HW_CTurnOff( all_regs, HW_UNUSED );
    HW_TurnOn( all_regs, ReturnAddrReg() );
    new_ins->zap = &reg_name->r;        /* all parm regs could be zapped*/
    ReplIns( ins, new_ins );
    UpdateLive( first_ins, new_ins );
    return( first_ins );
}

extern  name            *TrimConst( name *c, type_class_def tipe ) {
/******************************************************************/

    signed_32           value;

    switch( tipe ) {
    case U1:
        value = (unsigned_8)c->c.int_value;
        break;
    case I1:
        value = (signed_8)c->c.int_value;
        break;
    case U2:
        value = (unsigned_16)c->c.int_value;
        break;
    case I2:
        value = (signed_16)c->c.int_value;
        break;
    case U4:
    case I4:
        /* FIXME: int_value should be a 64-bit const for the Alpha
         * and we should be doing the same thing here.
         */
    default:
        return( c );
    }
    if( value != c->c.int_value ) {
        c = AllocS32Const( value );
    }
    return( c );
}

static  instruction     *doPromote( instruction *ins, type_class_def tipe ) {
/***************************************************************************/

    instruction *op0_ins;
    instruction *op1_ins;
    instruction *last_ins;
    name        *t0;
    name        *t1;

    t0 = AllocTemp( tipe );
    if( ins->operands[ 0 ]->n.class == N_CONSTANT ) {
        op0_ins = NULL;
        ins->operands[ 0 ] = TrimConst( ins->operands[ 0 ], ins->type_class );
    } else {
        op0_ins = MakeConvert( ins->operands[ 0 ], t0, tipe, ins->type_class );
        ins->operands[ 0 ] = t0;
        PrefixIns( ins, op0_ins );
    }

    if( ins->operands[ 1 ]->n.class == N_CONSTANT ) {
        op1_ins = NULL;
        ins->operands[ 1 ] = TrimConst( ins->operands[ 1 ], ins->type_class );
    } else {
        t1 = AllocTemp( tipe );
        op1_ins = MakeConvert( ins->operands[ 1 ], t1, tipe, ins->type_class );
        ins->operands[ 1 ] = t1;
        PrefixIns( ins, op1_ins );
    }

    last_ins = ins;
    if( ins->result != NULL ) {
        last_ins = MakeConvert( t0, ins->result, ins->type_class, tipe );
        ins->result = t0;
        SuffixIns( ins, last_ins );
    }

    ChangeType( ins, tipe );

    if( op0_ins != NULL ) {
        UpdateLive( op0_ins, last_ins );
        return( op0_ins );
    }
    if( op1_ins != NULL ) {
        UpdateLive( op1_ins, last_ins );
        return( op1_ins );
    }
    return( ins );
}

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

    type_class_def      new;

    new = I4;
    if( Unsigned[ ins->type_class ] == ins->type_class ) {
        new = U4;
    }
    return( doPromote( ins, new ) );
}

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

    type_class_def      new;

    new = I8;
    if( Unsigned[ ins->type_class ] == ins->type_class ) {
        new = U8;
    }

    return( doPromote( ins, new ) );
}

extern  bool    UnChangeable( instruction *ins ) {
/************************************************/

    ins = ins;
    return( FALSE );
}

extern  name    *Int64Equivalent( name *name )
/*********************************************
* Return a U64 equivalent of a double value
*/
{
    constant_defn       *defn;
    unsigned_32         *low;
    unsigned_32         *high;

    defn = GetFloat( name, FD );
    low  = (unsigned_32 *)&defn->value[0];
    high = (unsigned_32 *)&defn->value[2];
    return( AllocU64Const( *low, *high ) );
}

extern  name    *LowPart( name *tosplit, type_class_def class )
/**************************************************************
* Return the low (of type 'class') part of name 'tosplit'
* Note: There may not be any need to support splitting to
* classes other than U4/I4 on RISC (assuming that registers are
* at least 32-bit).
*/
{
    name                *new;
    signed_8            s8;
    unsigned_8          u8;
    signed_16           s16;
    unsigned_16         u16;
    unsigned_32         u32;
    constant_defn       *floatval;

    switch( tosplit->n.class ) {
    case N_CONSTANT:
        if( tosplit->c.const_type == CONS_ABSOLUTE ) {
            if( class == U1 ) {
                u8 = tosplit->c.int_value & 0xff;
                new = AllocUIntConst( u8 );
            } else if( class == I1 ) {
                s8 = tosplit->c.int_value & 0xff;
                new = AllocIntConst( s8 );
            } else if( class == U2 ) {
                u16 = tosplit->c.int_value & 0xffff;
                new = AllocUIntConst( u16 );
            } else if( class == I2 ) {
                s16 = tosplit->c.int_value & 0xffff;
                new = AllocIntConst( s16 );
            } else if( class == I4 ) {
                new = AllocS32Const( tosplit->c.int_value );
            } else if( class == U4 ) {
                new = AllocUIntConst( tosplit->c.int_value );
            } else if( class == FL ) {
                _Zoiks( ZOIKS_129 );
            } else { /* FD */
                floatval = GetFloat( tosplit, FD );
                u32 = (unsigned_32)floatval->value[1] << 16;
                u32 += floatval->value[0];
                new = AllocConst( CFCnvU32F( _TargetLongInt( u32 ) ) );
            }
#if 0
        } else if( tosplit->c.const_type == CONS_ADDRESS ) {
            new = AddrConst( tosplit->c.value,
                                   tosplit->c.int_value, CONS_OFFSET );
#endif
        } else {
            _Zoiks( ZOIKS_044 );
        }

⌨️ 快捷键说明

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