rtIsNaN implementation does not work on ARM7 target without FPU

Hello there,
I generate code using Matlab Coder for an ARM7TDMI target (Device: ARM compatible, Type: ARM 7, Standard math library: C89/C90) that uses the C89/90 math.h (GNUARM) to do floating point operations.
The code that Coder emits for the function that is used to test for NaN looks like this (in rt_nonfinite.c):
boolean_T rtIsNaN(real_T value)
{
return (value!=value)? 1U:0U;
}
Unfortunately, that test fails on target. It is not true for rtNaN. rtNaN is properly initialized to the pattern required for an LE machine. I assume that the math library just does not support it.
I have worked around that by replacing the statement with:
return ((value!=value) || (value==rtNaN))? 1U:0U;
This works, but I would rather not patch in the generated code.
Is there anything I can do to change/fix what the Coder emits here? Or do I need to disable support for non-finite numbers altogether?
Thanks

5 Comments

What compiler are you using? In general, the emitted code should be working no matter the target, but this pattern is somtimes not handled correctly by C compilers making optimizations. Depending on your compiler, there might be a flag that can be used to stop these optimizations.
I don't think there is a good way to change the code that Coder is emitting.
Thank you for your answer.
Compiler is arm-elf-gcc (GCC) 4.2.2. Overall optimizations are -O3. I have tried disabling optimizations (for all sources), but that exceeds my memory regions. I have not looked into setting -O0 for just this one file yet.
I have played around copying the passed value to a volatile variable in the hopes that the compiler will not optimize, but that did not seem to do anything...
Are you sure that the underlying cause cannot be in math lib? Would have been my best guess because checking for equality with rtNaN works (but if I understand the floating-point inner-workings correctly, it should not because NaN != NaN). But I should say that I am no expert on floating-point inner-workings :).
I have just tried -O0 on just rt_nonfinite.c. That did not do the trick.
-O3 should be safe, so I am not too surprised that -O0 didn't work either. I am not sure what the best workaround is for this situation, but I am looking into it and will hopefully have a more helpful answer soon.
Turning off nonfinites is definitely not what you should do. For the most part, doing so will cause Coder to assume that none of your values are ever Inf or Nan, so this check would be removed altogether and is likely to cause unexpected behavior.
Thanks for looking into it. Please come back to me if you want me to test something.

Sign in to comment.

Answers (1)

I have made some progress. IEEE does not seem to define word order in 64 bit float types. This might have been left for the implementation to define. It appears the pattern that rtGetNaN() produces for rtNaN is not compatible with this target. Here are the outputs of a trial:
isnan() of variable initialized by 0./0. : 1
rtIsNaN() of variable initialized by 0./0. : 1
Low word of variable initialized by 0./0. : 7ff80000
High word of variable initialized by 0./0. : 00000000
isnan() of variable initialized with rtNaN : 0
rtIsNaN() of variable initialized with rtNaN : 0
Low word of variable initialized with rtNaN : 00000000
High word of variable initialized with rtNaN : fff80000
So letting rtGetNaN() return 0./0. would fix it for this target.
The current implementation of rtGetNaN() does only distinguish between BE and LE byte orders and does the initialisation with hard coded patterns. It does not consider word order.
I would say that this target / math library is not supported at this point. Should it be? I would definetly appreciate that :).

1 Comment

I should add that Inf is affected in the same way. My current workaround is replacing rtGetNaN.c and rtGetInf.c with own implementations. These are trivial:
return 0./0.; // NaN
return 0.f/0.f; // NaNF
return 1./0.; // Inf
return 1.f/0.f; // InfF
return -1./0.; // -Inf
return -1.f/0.f; // -InfF

Sign in to comment.

Categories

Find more on MATLAB Coder in Help Center and File Exchange

Products

Release

R2018a

Asked:

on 19 Feb 2021

Commented:

on 24 Feb 2021

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!