Exemple #1
0
name    *StReturn( an retval, type_def *tipe, instruction **pins )
/****************************************************************/
{
    name        *retp;
    name        *ptr;
    name        *off;
    name        *seg;
    hw_reg_set  reg;

    if( CurrProc->state.attr & ROUTINE_ALLOCS_RETURN ) {
        retp = CurrProc->targ.return_points;
        AddIns( MakeUnary( OP_LA, retp, AllocRegName( CurrProc->state.return_reg ), WD ) );
        *pins = NULL;
    } else {
        if( _IsTargetModel( FLOATING_SS ) || _IsTargetModel( FLOATING_DS ) ) {
            ptr = AllocTemp( CP );
            off = OffsetPart( ptr );
            seg = SegmentPart( ptr );
            AddIns( MakeMove( AllocRegName( HW_SS ), seg, U2 ) );
        } else {
            ptr = AllocTemp( WD );
            off = ptr;
        }
        AddIns( MakeMove( CurrProc->targ.return_points, off, WD ) );
        retp = SAllocIndex( ptr, NULL, 0, TypeClass( retval->tipe ), tipe->length );
        reg = ReturnReg( WD, false );
        *pins = MakeMove( CurrProc->targ.return_points, AllocRegName( reg ), WD );
        CurrProc->state.return_reg = reg;
    }
    return( retp );
}
Exemple #2
0
extern an BGCall( cn call, bool use_return, bool in_line )
/********************************************************/
{
    instruction         *call_ins;
    instruction         *conv_ins;
    call_state          *state;
    name                *result;
    hw_reg_set          ret_addr;
    instruction         *ins;


    call_ins = call->ins;
    state = call->state;

    if( state->attr & ROUTINE_MODIFIES_NO_MEMORY ) {
        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_IS_SETJMP ) {
        call_ins->flags.call_flags |= CALL_IS_SETJMP;
    }
    if( use_return == FALSE ) {
        call_ins->flags.call_flags |= CALL_IGNORES_RETURN;
    }

    result = BGNewTemp( call->tipe );
    if( call_ins->type_class == XX ) {
        call_ins->result = result;
        ret_addr = ParmReg( CP, 4, 8, state );
        ins = MakeUnary( OP_LA, result, AllocRegName( ret_addr ), CP );
        AddIns( ins );
    } else {
        call_ins->result = AllocRegName( state->return_reg );
    }
    AssgnParms( call, in_line );
    AddCallIns( call_ins, call );
    if( use_return ) {
        if( call_ins->type_class != XX ) {
            conv_ins = MakeConvert( call_ins->result, result, TypeClass( call->tipe ), ReturnClass( call->tipe, call->state->attr ) );
            AddIns( conv_ins );
        } else {
            // conv_ins = MakeMove( call_result, result, XX );
        }
    }
    return( MakeTempAddr( result ) );
}
Exemple #3
0
extern void BGProcDecl( cg_sym_handle sym, type_def *tipe )
/******************************************************/
{
    type_class_def      class;
    name                *temp;
    hw_reg_set          reg;

    class = AddCallBlock( sym, tipe );
    SaveTargetModel = TargetModel;
    if( tipe != TypeNone ) {
        if( class == XX ) {
            // Handle structure returns - we need to "eat up" the first
            // register used for argument passing here, so that it isn't
            // used for passing actual arguments. NB: Must also bump
            // parm.offset here so that arguments end up in the right
            // locations.
            reg = HW_D4;
            temp = AllocTemp( WD );
            temp->v.usage |= USE_IN_ANOTHER_BLOCK;
            AddIns( MakeMove( AllocRegName( reg ), temp, WD ) );
            HW_TurnOn( CurrProc->state.parm.used, reg );
// TODO: need to do anything here?
//            HW_CTurnOn( CurrProc->state.parm.used, HW_F16 );
            CurrProc->targ.return_points = temp;
            CurrProc->state.parm.offset += REG_SIZE;
        }
    }
}
Exemple #4
0
extern  void    SaveDisplay( opcode_defs op ) {
/*********************************************/

    name        *reg;

    reg = AllocRegName( DisplayReg() );
    AddIns( MakeUnary( op, reg, NULL, reg->n.name_class ) );
}
Exemple #5
0
extern  an      PassProcParm( an rtn ) {
/**************************************/

    name        *op;
    name        *reg;

    op = AllocTemp( XX );
    op->n.size = TypePtr->length + SizeDisplayReg();
    reg = AllocRegName( DisplayReg() );
    AddIns( MakeMove( GenIns( rtn ),
            TempOffset( op, 0, ClassPointer ),
            ClassPointer ) );
    AddIns( MakeMove( reg, TempOffset( op, TypePtr->length,
                                       reg->n.name_class ),
                      reg->n.name_class ) );
    return( AddrName( op, TypeProcParm ) );
}
Exemple #6
0
extern  void    SetDisplay( name *temp ) {
/****************************************/

    name        *reg;

    reg = AllocRegName( DisplayReg() );
    AddIns( MakeMove( TempOffset( temp, TypePtr->length,
                                  reg->n.name_class ),
                      reg, reg->n.name_class ) );
}
Exemple #7
0
extern  void    BigGoto( int level )
/**********************************/
{
    name        *reg;

    if( level != 0 ) {
        reg = AllocRegName( DisplayReg() );
        AddIns( MakeMove( DisplayField( level ), reg, reg->n.name_class ) );
    }
}
Exemple #8
0
void    MkSelOp( name *idx, type_class_def type_class )
/*****************************************************/
{
    instruction         *ins;

    ins = NewIns( 2 );
    ins->head.opcode = OP_ADD;
    ins->type_class = WD;
    ins->operands[0] = idx->i.index;
    ins->operands[1] = idx->i.index;
    ins->result = idx->i.index;
    AddIns( ins );
    ins = NewIns( 1 );
    ins->operands[0] = idx;
    ins->result = idx->i.index;
    ins->head.opcode = OP_SELECT;
    ins->type_class = type_class;
    ins->ins_flags |= INS_CC_USED;
    AddIns( ins );
}
Exemple #9
0
static  void    AddCall( instruction *ins, cn call ) {
/****************************************************/

    name        *proc_name;

    if( _IsTargetModel(FLOATING_DS) && (call->state->attr&ROUTINE_NEEDS_DS_LOADED) ) {
        AddIns( MakeMove( NearSegment(), AllocRegName( HW_DS ), U2 ) );
    }
    if( call->name->tipe == TypeProcParm ) {
        proc_name = AllocTemp( ClassPointer );
/* what to do?        proc_name->usage |= USE_REGISTER;*/
        AddIns( MakeMove( ins->operands[CALL_OP_ADDR], proc_name, ClassPointer ));
        ins->operands[CALL_OP_ADDR] = proc_name;
        SetDisplay( GenIns( call->name ) );
        AddIns( ins );
        SaveDisplay( OP_POP );
    } else {
        AddCallIns( ins, call );
    }
}
Exemple #10
0
static  an Unary( cg_op op, an left, type_def *tipe )
/***************************************************/
{
    instruction *ins;
    an          res;

    ins = MakeNary( (opcode_defs)op, GenIns( left ), NULL, NULL, TypeClass( tipe ), TypeClass( left->tipe ), 1 );
    res = InsName( ins, tipe );
    AddIns( ins );
    BGDone( left );
    return( res );
}
Exemple #11
0
extern  name    *MakeDisplay( name *op, int level )
/*************************************************/
{
    name        *temp;
    name        *reg;

    reg = AllocRegName( DisplayReg() );
    temp = AllocTemp( U2 );
    AddIns( MakeMove( DisplayField( level ), temp, reg->n.name_class ) );
    op = AllocIndex( temp, NULL, op->t.location, op->n.name_class );
    return( op );
}
Exemple #12
0
static  an      FlowOut( an node, type_def *tipe ) {
/**************************************************/

    name                *temp;
    label_handle        lbl;

    lbl = AskForNewLabel();
    temp = BGGlobalTemp( tipe );
    AddIns( MakeMove( AllocIntConst( FETrue() ), temp, temp->n.type_class ) );
    *(node->u.b.t) = CurrBlock->label;
    GenBlock( BLK_JUMP, 1 );
    AddTarget( lbl, false );
    EnLink( AskForNewLabel(), true );
    AddIns( MakeMove( AllocIntConst( 0 ), temp, temp->n.type_class ) );
    *(node->u.b.f) = CurrBlock->label;
    GenBlock( BLK_JUMP, 1 );
    AddTarget( lbl, false );
    EnLink( lbl, true );
    NamesCrossBlocks();
    AddrFree( node );
    return( AddrName( temp, tipe ) );
}
Exemple #13
0
extern  void    BGParmInline( cg_sym_handle sym, type_def *tipe ) {
/**************************************************************/

    name                *temp;
    name                *parm_value;
    inline_parm         *parm;

    parm = InlineStack->parms;
    InlineStack->parms = InlineStack->parms->next;
//  if( NotEquiv( parm->addr->tipe, tipe ) ) {
//      _Zoiks( ZOIKS_070 );
//  }
    temp = SAllocUserTemp( sym, TypeClass( tipe ), tipe->length );
    temp->v.usage |= USE_IN_ANOTHER_BLOCK;
    parm_value = GenIns( parm->addr );
    BGDone( parm->addr );
    AddIns( MakeMove( parm_value, temp, temp->n.name_class ) );
    CGFree( parm );
}
Exemple #14
0
void    BGProcDecl( cg_sym_handle sym, type_def *tipe )
/*****************************************************/
{
    type_class_def      class;
    name                *temp;
    hw_reg_set          reg;

    class = AddCallBlock( sym, tipe );
    SaveTargetModel = TargetModel;
    if( tipe != TypeNone ) {
        if( class == XX ) {
            reg = HW_D3;
            temp = AllocTemp( WD );
            temp->v.usage |= USE_IN_ANOTHER_BLOCK;
            AddIns( MakeMove( AllocRegName( reg ), temp, WD ) );
            HW_TurnOn( CurrProc->state.parm.used, reg );
            CurrProc->targ.return_points = temp;
        }
    }
}
Exemple #15
0
extern  void    BigLabel( void )
/******************************/
{
    instruction *ins;
    name        *bp;
    name        *sp;

    if( CurrProc->lex_level != 0 ) {
        bp = AllocRegName( DisplayReg() );
        sp = AllocRegName( StackReg() );
        ins = MakeUnary( OP_LA,
                          AllocIndex( bp, NULL, -1, bp->n.name_class ),
                          sp, sp->n.name_class );
    } else {
        ins = MakeNop();
    }
    ins->zap = (register_name *) AllocRegName( AllCacheRegs() );
    ins->flags.nop_flags |= NOP_ZAP_INFO;
    AddIns( ins );
}
Exemple #16
0
void    BGProcDecl( cg_sym_handle sym, type_def *tipe )
/*****************************************************/
{
    hw_reg_set          reg;
    name                *temp;
    type_class_def      type_class;
    segment_id          old_segid;
    label_handle        lbl;

    SaveTargetModel = TargetModel;
    type_class = AddCallBlock( sym, tipe );
    if( tipe != TypeNone ) {
        if( type_class == XX ) {
            if( CurrProc->state.attr & ROUTINE_ALLOCS_RETURN ) {
                old_segid = SetOP( AskBackSeg() );
                lbl = AskForNewLabel();
                DataLabel( lbl );
                DGUBytes( tipe->length );
                CurrProc->targ.return_points = (name *)SAllocMemory( lbl, 0, CG_LBL, TypeClass( tipe ), tipe->length );
                SetOP( old_segid );
            } else {
                reg = CurrProc->state.return_reg;
                if( HW_CEqual( reg, HW_EMPTY ) ) {
                    temp = DoParmDecl( NULL, TypeInteger, HW_EMPTY );
                } else {
                    temp = AllocTemp( WD );
                    temp->v.usage |= USE_IN_ANOTHER_BLOCK;
                    AddIns( MakeMove( AllocRegName( reg ), temp, WD ) );
                    HW_TurnOn( CurrProc->state.parm.used, reg );
                }
                CurrProc->targ.return_points = temp;
            }
        }
    }
    if( CurrProc->state.attr & ROUTINE_FARSS ) {
        TargetModel |= FLOATING_SS;
    }
}
bool
PDetPlacement::Optimize()
{
    bool OptimizationResult = false;
    const int NInss = _problem.size();

    // Save Initial Solution
    BestSolution.reserve(NInss);

    Problem::iterator ifirst = _problem.begin();
    Problem::iterator ilast = _problem.end();
    vector<double>::iterator It = BestSolution.begin();
    while (ifirst != ilast)
	*It++ = (*ifirst++)->GetLeftCornerX();
    
    for(Idx = 0; Idx != NInss; )
	Queue.push_back(Idx++);

    // Init Best Cost
    BBoxFlag++;
    BestCost = InitCost(BBoxFlag);
#ifdef PLACE_DEBUG
    cout<<" Orig Cost: "<< BestCost << endl;
    cout<<" Actual Cost: " << CurrentCost() << endl;
#endif

    // Init Initial Cost
    BBoxFlag++;
    // Init Edges
    LeftEdge = (*_problem.begin())->GetLeftCornerX();
    RightEdge =(*_problem.rbegin())->GetLeftCornerX()
		+ (*_problem.rbegin())->GetMarginWidth();

    UnPlaceAll();
    Cost = InitCost(BBoxFlag);
    

#ifdef PLACE_DEBUG
    cout << " Init Cost: " << Cost << endl;
#endif
    
    UVect.reserve(NInss + 2);
    for (int id = 0; id < NInss + 2; id++)
	UVect.push_back(0);
    UVect[NInss] = NInss;
    UVect[NInss + 1] = NInss + 1;

    Stack.reserve(NInss);

    Idx = NInss - 1;

    unsigned NumAdds = 0;


    while(Idx < NInss)
    {
	AddIns();
	NumAdds++;

        if(UVect[Idx] == 0 || Cost >= BestCost)
      	{

	    UVect[Idx] = 0;	//force a bound

	    if(Cost < BestCost) //got here if:
				// new best complete soln (curWL < best)
				// bounded partial soln (curWL > best)
				//  so there is no need to additionally
				//  check to ensure this is a complete soln
	    {
		OptimizationResult = true;
		BestCost = Cost;
#ifdef PLACE_DEBUG
		cout<<" New Best: "<< Cost <<" found after "<< NumAdds<< endl;
		BBoxFlag++;
		cout << "Cost recalculated " << InitCost(BBoxFlag) << endl;
		cout << "actual Cost" << CurrentCost() << endl;
#endif	

		ifirst = _problem.begin();
		It = BestSolution.begin();
		while (ifirst != ilast)
		{
		    *It++ = (*ifirst++)->GetLeftCornerX();
		}
	    }

            while(UVect[Idx] == 0)
            {
	   	if(Idx < NInss)
		    RemoveIns();
    		UVect[++Idx]--; 
            }
      	}
      	Idx--;
    }
    ifirst = _problem.begin();
    It = BestSolution.begin();
    while (ifirst != ilast)
	(*ifirst++)->SetLeftCornerX(*It++);

    PlaceAll();
    BestSolution.clear();
#ifdef PLACE_DEBUG
    cout<<" Total Add Operations: "<< NumAdds<< endl;
    cout<<" Final solution has cost: "<< BestCost << endl << endl;
#endif
    UVect.clear();
    Queue.clear();
    Stack.clear();
    return OptimizationResult;
}
Exemple #18
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 ) );
}
Exemple #19
0
static  void    Far16Parms( cn call ) {
/*************************************/

    instruction         *ins;
    type_length         parm_size;
    pn                  parm, next;
    instruction         *call_ins;
    name                *eax;
    name                *ecx;
    name                *esi;
    label_handle        lbl;
    type_length         offset;
    name                *parmlist;
    call_state          *state;
    rt_class            rtindex;

    call_ins = call->ins;
    parm_size = 0;
    state = call->state;
    for( parm = call->parms; parm != NULL; parm = parm->next ) {
        parm_size += _RoundUp( parm->name->tipe->length, 2 );
    }
    parmlist = SAllocTemp( XX, parm_size );
    parmlist->v.usage |= NEEDS_MEMORY | USE_IN_ANOTHER_BLOCK | USE_ADDRESS;
    offset = 0;
    for( parm = call->parms; parm != NULL; parm = parm->next ) {
        parm->name->u.i.ins->result = STempOffset( parmlist, offset,
                                                 TypeClass( parm->name->tipe ),
                                                 parm->name->tipe->length );
        offset += _RoundUp( parm->name->tipe->length, 2 );
    }
    for( parm = call->parms; parm != NULL; parm = next ) {
        next = parm->next;
        parm->name->format = NF_ADDR;   /* so instruction doesn't get freed! */
        BGDone( parm->name );
        CGFree( parm );
    }
    eax = AllocRegName( HW_EAX );
    ecx = AllocRegName( HW_ECX );
    esi = AllocRegName( HW_ESI );
    HW_TurnOn( state->parm.used, eax->r.reg );
    HW_TurnOn( state->parm.used, ecx->r.reg );
    HW_TurnOn( state->parm.used, esi->r.reg );
    ins = MakeMove( AllocS32Const( parm_size ), ecx, WD );
    AddIns( ins );
    ins = MakeUnary( OP_LA, parmlist, esi, WD );
    AddIns( ins );
    if( ins->head.opcode == OP_CALL ) {
        ins = MakeUnary( OP_LA, call->name->u.n.name, eax, WD );
    } else {
        ins = MakeMove( GenIns( call->name ), eax, WD );
        call_ins->head.opcode = OP_CALL;
    }
    call_ins->num_operands = 2;
    AddIns( ins );
    if( call_ins->type_class == XX ) {
        if( state->attr & ROUTINE_ALLOCS_RETURN ) {
            rtindex = RT_Far16Cdecl;
        } else {
            rtindex = RT_Far16Pascal;
        }
    } else {
        rtindex = RT_Far16Func;
    }
    lbl = RTLabel( rtindex );
    call->name->u.n.name = AllocMemory( lbl, 0, CG_LBL, WD );
    call_ins->flags.call_flags |= CALL_FAR16 | CALL_POPS_PARMS;
    call_ins->operands[CALL_OP_USED] = AllocRegName( state->parm.used );
    call_ins->operands[CALL_OP_POPS] = AllocS32Const( 0 );
    call_ins->zap = &call_ins->operands[CALL_OP_USED]->r;
}