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 ); }
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; }
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 ); }
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 ) ); }
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 ); }
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; }