[ECOS] CYG_INSTRUMENT_CLOCK+PowerPC+FPU problem.

Sergei Organov osv@javad.ru
Wed May 3 04:52:00 GMT 2000


Hello,

All the instrumentation macros look like this when instrumentation is
disabled:

#define CYG_INSTRUMENT_CLOCK(_event_,_arg1_,_arg2_)             \
    CYG_MACRO_START                                             \
    CYG_UNUSED_PARAM(CYG_ADDRWORD, (CYG_ADDRWORD)(_arg1_));     \
    CYG_UNUSED_PARAM(CYG_ADDRWORD, (CYG_ADDRWORD)(_arg2_));     \
    CYG_MACRO_END

The problem is that when either _arg1_ or _arg2_ are volatile, the
CYG_UNUSED_PARAM leaves reference to the argument. I mean gcc still put
instruction(s) that fetch the value of the argument, because volatile
specification prevents it from just ignoring the code. Consider:

int volatile iv;
void foo(void) {
  CYG_UNUSED_PARAM(int, iv);
}

This produces the following code for 'foo':

void foo(void) {
  int tmp1 = iv;
  int tmp2 = tmp1;
  tmp1 = tmp2;
}

and gcc will produce load (or address access) instruction for 'tmp1 = iv'
statement.

Still this is not a very big problem. Just a few unnecessary instructions are
left in the code :-) However, in the case of CYG_INSTRUMENT_CLOCK this brings
much greater problem when compiling for PowerPC with hardware floating
point. The instructions that gcc produces are in fact floating point load
instructions (!), the code is actually in DSR (Cyg_RealTimeClock::dsr), thus
every clock tick ends up in floating point context switch! The excuse for FP
operation is that the reference is to the Cyg_Counter::counter that is 64 bits
(type long long), and it requires only one FP load instruction to access the
whole variable. For reference, the code in the DSR looks like this:

    ...
    Cyg_RealTimeClock *rtc = (Cyg_RealTimeClock *)data;

    CYG_INSTRUMENT_CLOCK( TICK_START,
                          rtc->current_value_lo(),
                          rtc->current_value_hi());
    ...

    CYG_INSTRUMENT_CLOCK( TICK_END,
                          rtc->current_value_lo(),
                          rtc->current_value_hi());

It produces total 4 floating point load instructions for 4 accesses to the
'rtc->counter' :-(

Well, I've tried to remove all the CYG_UNUSED_PARAM from all the macros in the
'instrmnt.h', and got only one compiler warning related to the
CYG_INSTRUMENT_INTR macro. Thus I left only this macro to be like this:

#define CYG_INSTRUMENT_INTR(_event_,_arg1_,_arg2_)              \
    CYG_MACRO_START                                             \
    CYG_UNUSED_PARAM(CYG_ADDRWORD, (CYG_ADDRWORD)(_arg1_));     \
    CYG_MACRO_END

Now there are no compiler warnings and no unnecessary loads in the code.

Do I submit the patch, or is there a better solution for the problem?

BR,
Sergei Organov.




More information about the Ecos-discuss mailing list