예제 #1
0
static  name    *GetNTTLSDataRef( instruction *ins, name *op, type_class_def tipe )
/**********************************************************************************
    Emit instructions to load allow a reference to op (a piece of
    TLS data) and return the resulting index name.
*/
{
    name                *tls_index;
    name                *tls_array;
    name                *t1;
    name                *t2;
    name                *t3;
    name                *temp_index;
    name                *result_index;
    instruction         *new_ins;

    tls_index = RTMemRef( RT_TLS_INDEX );
    tls_array = RTMemRef( RT_TLS_ARRAY );
    t1 = AllocTemp( WD );
    t2 = AllocTemp( WD );
    t3 = AllocTemp( WD );
    new_ins = MakeMove( tls_array, t1, WD );
    AddSegOverride( new_ins, HW_FS );
    PrefixIns( ins, new_ins );
    new_ins = MakeMove( tls_index, t2, WD );
    PrefixIns( ins, new_ins );
    new_ins = MakeBinary( OP_MUL, t2, AllocS32Const( 4 ), t2, WD );
    PrefixIns( ins, new_ins );
    new_ins = MakeBinary( OP_ADD, t1, t2, t1, WD );
    PrefixIns( ins, new_ins );
    temp_index = AllocIndex( t1, NULL, 0, WD );
    new_ins = MakeMove( temp_index, t3, WD );
    PrefixIns( ins, new_ins );
    result_index = ScaleIndex( t3, op, op->v.offset, tipe, TypeClassSize[ tipe ], 0, 0 );
    return( result_index );
}
예제 #2
0
tLane LaneDetector::DetectLanes(Mat &inputImage, Logger &logger)
{
    DebugImage = Mat::zeros(200, 300, CV_8UC3);

    Mat binaryImage = MakeBinary(inputImage);

//    Mat kernel = getStructuringElement(CV_SHAPE_ELLIPSE, Size(5, 5));
//    morphologyEx(workingImage, workingImage, MORPH_CLOSE, kernel);

    if (reseted)
    {
        ExtractBorder(inputImage);

        CrossingDetector leftBot("left_bot.bmp", Point(28, 24), &IsLeft, 0.6);
        CrossingDetector leftTop("left_top.bmp", Point(25, 39), &IsLeft, 0.55);
        BaseLaneLine *left = new InitLine(0, cvRound(binaryImage.cols / 2.0) - 20, border, CLOCKWISE, leftBot, leftTop, laneLogger);

        CrossingDetector rightBot("right_bot.bmp", Point(13, 12), &IsRight, 0.55);
        CrossingDetector rightTop("right_top.bmp", Point(9, 25), &IsRight, 0.55);
        BaseLaneLine *right = new InitLine(cvRound(binaryImage.cols / 2.0) - 20 + 1, binaryImage.cols - 1, border,
                                           COUNTER_CLOCKWISE, rightBot, rightTop, laneLogger);

        leftLine = Ptr<BaseLaneLine>(left);
        rightLine = Ptr<BaseLaneLine>(right);

        reseted = false;

        tLane result = GenerateNormalizedLaneStruct(binaryImage);

        return result;
    }
    leftLine->Log("Left:");
    leftLine = leftLine->UpdateLaneLine(binaryImage, *rightLine);
    leftLine->Log("------");
    rightLine->Log("Right:");
    rightLine = rightLine->UpdateLaneLine(binaryImage, *leftLine);
    rightLine->Log("------");


#ifndef NDEBUG
    cvtColor(binaryImage, DebugImage, CV_GRAY2RGB);

    leftLine->Draw(DebugImage);
    rightLine->Draw(DebugImage);

    line(DebugImage, Point2f(DebugImage.cols / 2.0f - (15 + 8 + 47), 0), Point2f(DebugImage.cols / 2.0f - (15 + 8 + 47), 199), CV_RGB(0, 0, 255));
    line(DebugImage, Point2f(DebugImage.cols / 2.0f + (15 + 8), 0), Point2f(DebugImage.cols / 2.0f + (15 + 8), 199), CV_RGB(0, 0, 255));
#endif

    tLane result = GenerateNormalizedLaneStruct(binaryImage);

    return result;
}
예제 #3
0
static  void    CheckOp( name **offsets, instruction *ins, name **pop ) {
/************************************************************************
    used by FixFarLocalRefs to change one far local reference to
    an index, using the appropriate multiple of 4K constant to get
    at the temporary. The constant values are adjusted after the
    prolog is generated.
*/

    name        *op;
    name        *base;
    name        *temp;
    unsigned_32 place;
    int         i;
    instruction *new_ins;

    op = *pop;
    if( op->n.class == N_INDEXED ) {
        temp = op->i.index;
        if( temp->n.class != N_TEMP ) return;
        if( !( temp->t.temp_flags & FAR_LOCAL ) ) return;
        new_ins = MakeMove( temp, AllocTemp( temp->n.name_class ), temp->n.name_class );
        *pop = ScaleIndex( new_ins->result, op->i.base,
                          op->i.constant, op->n.class, op->n.size,
                          op->i.scale, op->i.index_flags );
        PrefixIns( ins, new_ins );
        CheckOp( offsets, new_ins, &new_ins->operands[ 0 ] );
    }
    if( op->n.class != N_TEMP ) return;
    if( !( op->t.temp_flags & FAR_LOCAL ) ) return;
    base = DeAlias( op );
    place = base->t.location + ( op->v.offset - base->v.offset );
    i = place/_4K;
    if( offsets[ i ] == NULL ) {
        /*set the symbol field in the AddrConst to non-NULL for score-boarder*/
        new_ins = MakeMove( AllocAddrConst( (name *)&CurrProc, i,
                                            CONS_OFFSET, WD ),
                        AllocTemp( WD ), WD );
        offsets[ i ] = new_ins->result;
        PrefixIns( HeadBlock->ins.hd.next, new_ins );
    }
    temp = AllocTemp( WD ),
    new_ins = MakeMove( offsets[ i ], temp, WD );
    PrefixIns( ins, new_ins );
    new_ins = MakeBinary( OP_ADD, temp, AllocRegName( DisplayReg() ), temp, WD);
    PrefixIns( ins, new_ins );
    *pop = ScaleIndex( temp, op, place%_4K,
                        op->n.name_class, op->n.size, 0, X_FAKE_BASE );
}
예제 #4
0
an      BGCall( cn call, bool use_return, bool in_line )
/******************************************************/
{
    instruction         *call_ins;
    call_state          *state;
    name                *ret_ptr = NULL;
    name                *result;
    name                *temp;
    name                *reg_name;
    instruction         *ret_ins = NULL;
    hw_reg_set          return_reg;
    hw_reg_set          zap_reg;

    if( call->name->tipe == TypeProcParm ) {
        SaveDisplay( OP_PUSH );
    }

    state = call->state;
    result = BGNewTemp( call->tipe );
    call_ins = call->ins;

/*   If we have a return value that won't fit in a register*/
/*   pass a pointer to result as the first parm*/

    if( call_ins->type_class == XX ) {
        if( _RoutineIsFar16( state->attr ) ) {
            if( state->attr & ROUTINE_ALLOCS_RETURN ) {
                HW_CAsgn( state->return_reg, HW_EAX );
            } else {
                HW_CAsgn( state->return_reg, HW_EBX );
            }
        }
        if( ( state->attr & ROUTINE_ALLOCS_RETURN ) == 0 ) {
            if( HW_CEqual( state->return_reg, HW_EMPTY ) ) {
                ret_ptr = AllocTemp( WD );
            } else {
                ret_ptr = AllocRegName( state->return_reg );
            }
            ret_ins = MakeUnary( OP_LA, result, ret_ptr, WD );
            HW_TurnOn( state->parm.used, state->return_reg );
            call_ins->flags.call_flags |= CALL_RETURNS_STRUCT;
        }
    }
    if( _IsTargetModel(FLOATING_DS) && (state->attr&ROUTINE_NEEDS_DS_LOADED) ) {
        HW_CTurnOn( state->parm.used, HW_DS );
    }
    if( _RoutineIsFar16( state->attr ) ) {
#if _TARGET & _TARG_80386
        Far16Parms( call );
#endif
    } else {
        if( AssgnParms( call, in_line ) ) {
            if( state->attr & ROUTINE_REMOVES_PARMS ) {
                call_ins->flags.call_flags |= CALL_POPS_PARMS;
            }
        }
    }

    if( state->attr & (ROUTINE_MODIFIES_NO_MEMORY | ROUTINE_NEVER_RETURNS) ) {
        /* a routine that never returns can not write any memory as far
            as this routine is concerned */
        call_ins->flags.call_flags |= CALL_WRITES_NO_MEMORY;
    }
    if( state->attr & ROUTINE_READS_NO_MEMORY ) {
        call_ins->flags.call_flags |= CALL_READS_NO_MEMORY;
    }
    if( state->attr & ROUTINE_NEVER_RETURNS ) {
        call_ins->flags.call_flags |= CALL_ABORTS;
    }
    if( _RoutineIsInterrupt( state->attr ) ) {
        call_ins->flags.call_flags |= CALL_INTERRUPT | CALL_POPS_PARMS;
    }
    if( !use_return ) {
        call_ins->flags.call_flags |= CALL_IGNORES_RETURN;
    }
    if( call_ins->type_class == XX ) {
        reg_name = AllocRegName( state->return_reg );
        if( state->attr & ROUTINE_ALLOCS_RETURN ) {
            call_ins->result = reg_name;
            AddCall( call_ins, call );
            if( use_return ) {
                temp = AllocTemp( WD ); /* assume near pointer*/
                AddIns( MakeMove( reg_name, temp, WD ) );
                temp = SAllocIndex( temp, NULL, 0,
                                    result->n.type_class, call->tipe->length );
                AddIns( MakeMove( temp, result, result->n.type_class ) );
            }
        } else {
            call_ins->result = result;
            AddIns( ret_ins );
            if( HW_CEqual( state->return_reg, HW_EMPTY ) ) {
                AddIns( MakeUnary( OP_PUSH, ret_ptr, NULL, WD ) );
                state->parm.offset += TypeClassSize[WD];
                call_ins->operands[CALL_OP_POPS] =
                        AllocS32Const( call_ins->operands[CALL_OP_POPS]->c.lo.int_value + TypeClassSize[WD] );
                if( state->attr & ROUTINE_REMOVES_PARMS ) {
                    call_ins->flags.call_flags |= CALL_POPS_PARMS;
                }
            }
            AddCall( call_ins, call );
        }
    } else {
        return_reg = state->return_reg;
        zap_reg = call_ins->zap->reg;
        HW_CTurnOn( zap_reg, HW_FLTS );
        HW_OnlyOn( return_reg, zap_reg );
        call_ins->result = AllocRegName( return_reg );
        reg_name = AllocRegName( state->return_reg );
        AddCall( call_ins, call );
        if( use_return ) {
            ret_ins = MakeMove( reg_name, result, result->n.type_class );
            if( HW_COvlap( reg_name->r.reg, HW_FLTS ) ) {
                ret_ins->stk_entry = 1;
                ret_ins->stk_exit = 0;
            }
            AddIns( ret_ins );
        }
    }
    if( state->parm.offset != 0 && ( state->attr & ROUTINE_REMOVES_PARMS ) == 0 ) {
        reg_name = AllocRegName( HW_SP );
        AddIns( MakeBinary( OP_ADD, reg_name,
                AllocS32Const( state->parm.offset ), reg_name, WD ) );
    }
    return( MakeTempAddr( result ) );
}
예제 #5
0
extern  instruction     *rSPLITOP( instruction *ins ) {
/****************************************************/

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

    if( IndexOverlaps( ins, 0 ) || IndexOverlaps( ins, 1 ) ) {
        temp = AllocTemp( LONG_WORD );
        HalfType( ins );
        new_ins = MakeBinary( ins->head.opcode,
                        LowPart( ins->operands[ 0 ], WORD ),
                        LowPart( ins->operands[ 1 ], WORD ),
                        LowPart( temp,               WORD ),
                        WORD );
        ins2 = MakeBinary( ins->head.opcode,
                        HighPart( ins->operands[ 0 ], WORD ),
                        HighPart( ins->operands[ 1 ], WORD ),
                        HighPart( temp,               WORD ),
                        WORD );
        if( ins->head.opcode == OP_ADD ) {
            ins2->head.opcode = OP_EXT_ADD;
        } else if( ins->head.opcode == OP_SUB ) {
            ins2->head.opcode = OP_EXT_SUB;
        }
        ins2->table = CodeTable( ins2 );
        new_ins->table = ins2->table;
        DupSegOp( ins, new_ins, 0 );
        DupSegOp( ins, ins2, 0 );
        DupSegOp( ins, new_ins, 1 );
        DupSegOp( ins, ins2, 1 );
        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 );
        DupSegRes( ins, ins2 );
        PrefixIns( ins, ins2 );
        ins2 = MakeMove( HighPart( temp, WORD ),
                          HighPart( ins->result, WORD ), WORD );
        DupSegRes( ins, ins2 );
        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 );
        DupSeg( ins, new_ins );
        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;
        }
/* Assign fake reduce table (from OP_EXT) to new_ins; default reduce table
   can generate INC and DEC which'll not set condition codes
 */
        ins->table = CodeTable( ins );
        new_ins->table = ins->table;

        PrefixIns( ins, new_ins );
    }
    new_ins->ins_flags |= INS_CC_USED;
    return( new_ins );
}
예제 #6
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;
    }