This is a post about a development tool or software, but I seem to have created it in the wrong spot. Please move it as appropriate.
Hello,
Here is my setup:
- Windows 10
- CCS 10.2
- F28379D
- TI v20.12.0.STS
- Processor options: fpu32, tmu0, vcu2, relaxed (fp_mode)
- EABI
- Libraries included: c28x_fpu_dsp_library_eabi, rts2800_fpu32_eabi
I am trying to use the FPU instruction MINF32 and MAXF32. As described on SPRUEO2 (Float Instructions), MINF32 is a single cycle instruction.
Consider the following code:
target=fmaxf(orig,min);
Instead of calling the MAXF32 function, it calls the following code from the ti_fmax.c file in the compiler directory:
#if FLT_MANT_DIG != DBL_MANT_DIG float fmaxf(float x, float y) { if (isnan(x)) return y; if (isnan(y)) return x; /* -0 and +0 compare equal, but we must return +0, so check the sign bit */ if (__FLOAT_SIGN_BIT_ZERO(x) != __FLOAT_SIGN_BIT_ZERO(y)) if (__FLOAT_SIGN_BIT_ZERO(x)) return x; else return y; return (x > y ? x : y); } #else float fmaxf(float x, float y) __attribute__((__alias__("fmax"))); #endif double fmax(double x, double y) { if (isnan(x)) return y; if (isnan(y)) return x; /* -0 and +0 compare equal, but we must return +0, so check the sign bit */ if (__DOUBLE_SIGN_BIT_ZERO(x) != __DOUBLE_SIGN_BIT_ZERO(y)) if (__DOUBLE_SIGN_BIT_ZERO(x)) return x; else return y; return (x > y ? x : y); }
The pre-processor directive fails because in float.h, FLT_MANT_DIG is 24 and DBL_MANT_DIG is 53, so the code defined as a double is called. This code uses 64-bit definitions which I am aware that the processor does not support natively. As you can see in the processor options above, I have set the floating point support setting to fpu32. The code runs very slowly compared to a conditional by an order of magnitude.
In the end, I would like the min and max functions to be 32-bit and run in a single cycle. Ultimately I need to bound a variable so I want something like this:
target= fminf(fmaxf(orig,min),max);
I expect that to compile into several 32-bit register moves and a MINF32 and MAXF32, say 10 cycles at most.
Summary of questions that I would like some answers to:
- Is the call to the ti_fmax.c fmax function a bug? How do I force it to run the FPU instruction? I tried __MAXF32, but it did not work. Ideally, I would like the compiler to do this.
- What is the fastest way to bound a float variable on this system? I have to do this many times in my application. Currently I am doing something very similar to a nested version of "return (x > y ? x : y);".
Thanks in advance for any help or insight.