instruction     *rMOVOP1TEMP( instruction *ins )
/**********************************************/
{
    instruction         *new_ins;
    type_class_def      type_class;
    name                *name;

    type_class = _OpClass( ins );
    name = AllocTemp( type_class );
    new_ins = MakeMove( ins->operands[0], name, type_class );
    ins->operands[0] = name;
    MoveSegOp( ins, new_ins, 0 );
    PrefixIns( ins, new_ins );
    return( new_ins );
}
instruction      *rOP2REG( instruction *ins )
/*******************************************/
{
    instruction         *new_ins;
    name                *name1;
    type_class_def      type_class;

    type_class = _OpClass( ins );
    name1 = AllocTemp( type_class );
    new_ins = MakeMove( ins->operands[1], name1, type_class );
    ins->operands[1] = name1;
    MoveSegOp( ins, new_ins, 0 );
    PrefixIns( ins, new_ins );
    MarkPossible( ins, name1, Op1Possible( ins ) );
    ins->u.gen_table = NULL;
    GiveRegister( NameConflict( ins, name1 ), true );
    return( new_ins );
}
instruction      *rOP1RESREG( instruction *ins )
/**********************************************/
{
    instruction         *new_ins;
    instruction         *ins2;
    name                *name1;
    name                *name2;

    name1 = AllocRegName( Op1Reg( ins ) );
    new_ins = MakeMove( ins->operands[0], name1, _OpClass( ins ) );
    ins->operands[0] = name1;
    MoveSegOp( ins, new_ins, 0 );
    PrefixIns( ins, new_ins );
    name2 = AllocRegName( ResultReg( ins ) );
    ins2 = MakeMove( name2, ins->result, ins->type_class );
    ins->result = name2;
    MoveSegRes( ins, ins2 );
    SuffixIns( ins, ins2 );
    return( new_ins );
}
Exemple #4
0
static  instruction    *FoldAbsolute( instruction *ins ) {
/*********************************************************
    See below.
*/
    instruction *new_ins;
    opcnt       num_operands;
    name        *result;
    tn          fold;
    type_def    *tipe;
    type_def    *left_tipe;
    type_def    *rite_tipe;
    type_def    *fold_tipe;
    pointer     left;
    pointer     rite;
    name        *tmp;
    name        *new_const;
    float_handle value;

    tipe = ClassType( ins->type_class );
    left_tipe = ClassType( _OpClass( ins ) );
    num_operands = OpcodeNumOperands( ins );
    left = NULL;
    rite = NULL;
    if( num_operands != 0 ) {
        left = TName( ins->operands[0], left_tipe );
        if( num_operands > 1 ) {
            if( ins->operands[1]->n.type_class == XX ) {
                rite_tipe = tipe;
            } else {
                rite_tipe = ClassType( ins->operands[1]->n.type_class );
            }
            rite = TName( ins->operands[1], rite_tipe );
        }
    }
    fold = NULL;
    switch( ins->head.opcode ) {
    case OP_ADD:
        fold = FoldPlus( left, rite, tipe );
        break;
    case OP_SUB:
        fold = FoldMinus( left, rite, tipe );
        break;
    case OP_MUL:
        fold = FoldTimes( left, rite, tipe );
        break;
    case OP_DIV:
        fold = FoldDiv( left, rite, tipe );
        break;
    case OP_MOD:
        fold = FoldMod( left, rite, tipe );
        break;
    case OP_AND:
        fold = FoldAnd( left, rite, tipe );
        break;
    case OP_OR:
        fold = FoldOr( left, rite, tipe );
        break;
    case OP_XOR:
        fold = FoldXor( left, rite, tipe );
        break;
    case OP_RSHIFT:
        fold = FoldRShift( left, rite, tipe );
        break;
    case OP_LSHIFT:
        fold = FoldLShift( left, rite, tipe );
        break;
    case OP_NEGATE:
        fold = FoldUMinus( left, tipe );
        break;
    case OP_COMPLEMENT:
        fold = Fold1sComp( left, tipe );
        break;
    case OP_CONVERT:
        // look out for CNV PT U2 t1 type instructions; if sizeof( PT ) is greater
        // than sizeof( U2 ), we don't want to fold or we'll screw up based pointers
        if( IsTrickyPointerConv( ins ) )
            return( NULL );
        // fall through!
    case OP_ROUND:
        fold = FoldCnvRnd( (cg_op)ins->head.opcode, left, tipe );
        break;
    case OP_CMP_EQUAL:
    case OP_CMP_NOT_EQUAL:
    case OP_CMP_GREATER:
    case OP_CMP_LESS_EQUAL:
    case OP_CMP_LESS:
    case OP_CMP_GREATER_EQUAL:
        if( ActiveCompare( ins ) ) {
            fold = FoldCompare( (cg_op)ins->head.opcode, left, rite, tipe );
            if( fold != NULL ) {
                return( StraightLine( ins, fold, true ) );
            }
        }
        break;
    case OP_BIT_TEST_TRUE:
        if( ActiveCompare( ins ) ) {
            fold = FoldAnd( left, rite, tipe );
            if( fold != NULL ) {
                return( StraightLine( ins, fold, true ) );
            }
        }
        break;
    case OP_BIT_TEST_FALSE:
        if( ActiveCompare( ins ) ) {
            fold = FoldAnd( left, rite, tipe );
            if( fold != NULL ) {
                return( StraightLine( ins, fold, false ) );
            }
        }
        break;
    default:
        fold = NULL;
        break;
    }
    if( fold != NULL ) {
        fold_tipe = fold->tipe;
        result = TGetName( fold );
        if( result != NULL && !NeedConvert( fold_tipe, tipe ) ) {
            ins->table = NULL;
            // look out for scary DIV U4 EDX:EAX, c1 -> t1 type instructions
            if( result->n.class != N_CONSTANT &&
                result->n.size != TypeClassSize[ins->type_class] )
                return( NULL );
            // look out for scary MUL U4 EDX:EAX, c1 -> t1 type instructions
            if( result->n.class != N_CONSTANT &&
                ins->result->n.size != TypeClassSize[ins->type_class] )
                return( NULL );
            new_ins = MakeMove( result, ins->result, ins->type_class );
            SetCSEBits( ins, new_ins );
            DupSeg( ins, new_ins );
            ReplIns( ins, new_ins );
            return( new_ins );
        }
Exemple #5
0
static  void    ExpandTlsOp( instruction *ins, name **pop )
/**********************************************************
    If *pop is a ref to a piece of thread-local data, replace
    it by a ref to an index [t1] and prepend the magic sequence
    to get the address of a piece of tls data to the instruction.
    Here is the sequence to access variable foo:
        mov fs:__tls_array -> t1
        mov __tls_index -> t2
        mov t2 * 4 -> t2
        add t1, t2 -> t1
        mov [ t1 ] -> t3
        mov foo[ t3 ] -> result
*/
{
    fe_attr             attr;
    name                *op;
    name                *temp;
    name                *tls_data;
    name                *index;
    name                *base;
    instruction         *new_ins;

    op = *pop;
    switch( op->n.class ) {
    case N_MEMORY:
        if( op->m.memory_type == CG_FE ) {
            attr = FEAttr( op->v.symbol );
            if( ( attr & FE_THREAD_DATA ) != 0 ) {
                *pop = GetTLSDataRef( ins, op, _OpClass(ins) );
            }
        }
        break;
    case N_INDEXED:
        // gotta check for the base being one of these stupid TLS things
        if( op->i.base != NULL && ( op->i.index_flags & X_FAKE_BASE ) == 0 ) {
            base = op->i.base;
            if( base->n.class != N_MEMORY || base->m.memory_type != CG_FE ) break;
            attr = FEAttr( base->v.symbol );
            if( ( attr & FE_THREAD_DATA ) == 0 ) break;
            tls_data = GetTLSDataRef( ins, base, _OpClass(ins) );
            temp = AllocTemp( WD );
            new_ins = MakeUnary( OP_LA, tls_data, temp, WD );
            PrefixIns( ins, new_ins );
            index = op->i.index;
            if( op->i.scale != 0 ) {
                const signed_32 values[] = { 1, 2, 4, 8, 16 };
                if( op->i.scale > 4 ) _Zoiks( ZOIKS_134 );
                index = AllocTemp( WD );
                new_ins = MakeBinary( OP_MUL, op->i.index,
                                AllocS32Const( values[ op->i.scale ] ),
                                index, WD );
                PrefixIns( ins, new_ins );
            }
            new_ins = MakeBinary( OP_ADD, temp, index, temp, WD );
            PrefixIns( ins, new_ins );
            *pop = ScaleIndex( temp, NULL, 0,
                            _OpClass(ins),
                            TypeClassSize[ _OpClass(ins) ],
                            0, 0 );
        }
        break;
    }