This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Efficient NaN detection on 6748 / Omap-L138



Hello,

I'm searching for an efficient way to detect Not a Number values on my Omap L138 platform.

Using the "isnan" library function generates very slow code as a function call is generated which prevents the compiler from pipelining my loop.

A look into the implementation of the isnan function shows that it is coded as return (volatile)x != (volatile)x, rather interesting but correct according to the IEEE754 rules. And ideed, the corresponding CMPEQSP functions correctly. The problem is now, that if I declare an inlinable function (not declaring x volatile, because this obviously kills my effort to speed it up):

inline int myisnan(x)
{return(x != x);
}

the compiler optimizes away the comparision (which it assumes always to be false, though this is NOT correct in case of a NaN!!!).
I did not find any way to include the correct assembler command CMPEQSP in my c code! (no intrinsic, no way to wire the registers correctly with inline assembly)

Does anybody know how I can instanciate CMPEQSP for an efficient, pipelinable NaN detection?

I'm using CC3.3, CG tools 6.1.20

Thanks

Christoph

  • The compiler presently does not handle NaN and Infinity values correctly in all expressions.  Fixing this will require a non-trivial amount of work in the compiler.  This is the subject of defect report SDSCM00008670, which is not externally visible.  There is no official timeline for when this might get fixed.  I don't know of any workaround.

  • Dear Archeologist,

    many thanks for the answer. in the meantime I implemented this workaraound, which however is not optimal concerning resource usage and execution time (but nearly optimal)

    typedef union {
       float f;
       u32 i;
    } t_floatintunion;

    inline int myisnan(float x)
    { t_floatintunion fiu;
      fiu.f=x;
      return((fiu.i & 0x7FC00000) == 0x7fc00000);
    }

    It gets compiled to a register (A4) preloaded with 0x7fc0000, an EXTU bitmasking and CMPEQ integer compare;

    ;*                     EXTU    .S1     A18,1,23,A6       ; |128|
    ;*  12              CMPEQ   .L1     A6,A4,A2          ; |128|

    Best regards

    Christoph