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.

Coverage deficiency



We are currently working on TMS320F28004x MCU.

This is regarding testing of testing for floorf function.  

Prototype is : float floarf(float x); 

We are unable to get the coverage for the highlighted part in red below. Please note that, we had tried all possible values including normal and +ve inf, -inf, NaN etc. Please advise us on what values of x can cover the implicit if blcoks. 

Thanks in advance.

  • Hi
    What is the value of huge1?What is i0? Can you make sure there is no overflow/underflow in the FPU registers. DId you enable fpu32 support in the project?

    -Shantanu

  • Hi,
    Thank you for the response.
    The below information that is present in _def.h – might be handy for you
     
    static __inline __uint32_t __f32_bits_as_u32(float x) {
        const union { float f; __uint32_t i; } rep = {.f = x};
        return rep.i;
    }
     
    static __inline float __u32_bits_as_f32(__uint32_t x) {
        const union { float f; __uint32_t i; } rep = {.i = x};
        return rep.f;
    }
     
    #define GET_FLOAT_WORD(dst,f) (dst=__f32_bits_as_u32(f))
    #define SET_FLOAT_WORD(dst,u) (dst=__u32_bits_as_f32(u))
     
     
    And also the below are the includes and huge value and also the complete code..
     
    #include <float.h>
    #include <stdint.h>
    #include "math.h"
    #include "math_private.h"
     
    _DATA_ACCESS static const float huge = 1.0e30;   (actually I changed this to a variable and renamed as while debugging I noticed it is not holding the same value as defined.
     
    float
    floorf(float x)
    {
                    int32_t i0,j0;
                    uint32_t i;
                    GET_FLOAT_WORD(i0,x);
                    j0 = ((i0>>23)&0xff)-0x7f;
                    if(j0<23) {
                        if(j0<0) {           /* raise inexact if x != 0 */
                                    if(huge+x>(float)0.0) {/* return 0*sign(x) if |x|<1 */
                                        if(i0>=0) {i0=0;}
                                        else if((i0&0x7fffffff)!=0)
                                                    { i0=0xbf800000;}
                                    }
                        } else {
                                    i = (0x007fffff)>>j0;
                                    if((i0&i)==0) return x; /* x is integral */
                                    if(huge+x>(float)0.0) {   /* raise inexact flag */
                                        if(i0<0) i0 += (0x00800000)>>j0;
                                        i0 &= (~i);
                                    }
                        }
                    } else {
                        if(j0==0x80) return x+x;            /* inf or NaN */
                        else return x;                 /* x is integral */
                    }
                    SET_FLOAT_WORD(x,i0);
                    return x;
    }
     
    #if DBL_MANT_DIG == FLT_MANT_DIG
    double floor(double x) __attribute__((__alias__("floorf")));
    #endif
     
    #if LDBL_MANT_DIG == FLT_MANT_DIG
    long double floorl(long double x) __attribute__((__alias__("floorf")));
    #endif
     
    Thanks and Best Regards,
    Mohan
     
  • static const float huge = 1.0e30; 

    Wouldn't this exceed 32 bits?

  • No,  it is with in float max value

  • The function floorf is supplied with the compiler RTS library.  As the comments indicate, TI did not implement this function.  With permission, we obtained it from an open source project.  Unfortunately, I do not understand how it works well enough to reply.  I am getting help.  But that will take some time.  Please be patient.

    Thanks and regards,

    -George

  • I apologize for the delay.  I took a closer look at the implementation of floorf.  It does appear the condition in these if statements ...

    if(huge+x>(float)0.0)

    can never be false.  Discussion on that point is ongoing.

    At the same time, please check on the code coverage you get when the input value is negative 0: -0.0f.

    Thanks and regards,

    -George

  • Thanks for the response.

    Please find the overage for -0.0f

    Thanks and Best Regards,

    Mohan

  • I filed EXT_EP-10756 to request that floorf be changed.  It requests that the unnecessary if tests be removed.  And that some other, needlessly confusing, if-else lines be simplified.  Please understand that this entry not considered a bug, but a request for an improvement.

    The attachment is a floorf source file, with a minimal set of changes in it.  Remove the .txt file extension.  Please understand that this code has only been through minimal testing, and should not be considered as part of an official release of the C2000 compiler.  That requires much more testing than I am able to perform.  Despite all those caveats, I thought it would be useful.

    Thanks and regards,

    -George

    /*
     * Copyright (c) 2015-2015 Texas Instruments Incorporated
     *
     * s_floorf.c -- float version of s_floor.c.
     * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
     */
    
    /*
     * ====================================================
     * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
     *
     * Developed at SunPro, a Sun Microsystems, Inc. business.
     * Permission to use, copy, modify, and distribute this
     * software is freely granted, provided that this notice
     * is preserved.
     * ====================================================
     */
    
    /*
     * floorf(x)
     * Return x rounded toward -inf to integral value
     * Method:
     *	Bit twiddling.
     * Exception:
     *	Inexact flag raised if x not equal to floorf(x).
     */
    
    #include <float.h>
    #include <stdint.h>
    #include "math.h"
    #include "math_private.h"
    
    // _DATA_ACCESS static const float huge = 1.0e30;
    
    float
    floorf(float x)
    {
    	int32_t i0,j0;
    	uint32_t i;
    	GET_FLOAT_WORD(i0,x);
    	j0 = ((i0>>23)&0xff)-0x7f;
    	if(j0<23) {
    	    if(j0<0) { 	/* raise inexact if x != 0 */
    	#if 0
    		if(huge+x>(float)0.0) {/* return 0*sign(x) if |x|<1 */
    		    if(i0>=0) {i0=0;}
    		    else if((i0&0x7fffffff)!=0)
    			{ i0=0xbf800000;}
    		}
    	#else
    		if (i0 >= 0)
        		return 0.0f;
    		else if (i0 == 0x80000000) // negative 0
        		return -0.0f;
    		else
        		return -1.0f;
    	#endif
    	    } else {
    		i = (0x007fffff)>>j0;
    		if((i0&i)==0) return x; /* x is integral */
    		// if(huge+x>(float)0.0) {	/* raise inexact flag */
    		    if(i0<0) i0 += (0x00800000)>>j0;
    		    i0 &= (~i);
    		// }
    	    }
    	} else {
    	    if(j0==0x80) return x+x;	/* inf or NaN */
    	    else return x;		/* x is integral */
    	}
    	SET_FLOAT_WORD(x,i0);
    	return x;
    }
    
    #if DBL_MANT_DIG == FLT_MANT_DIG
    double floor(double x) __attribute__((__alias__("floorf")));
    #endif
    
    #if LDBL_MANT_DIG == FLT_MANT_DIG
    long double floorl(long double x) __attribute__((__alias__("floorf")));
    #endif
    

  • Thank you very much for the response and updated code. Eventhough it is not an official version ,, noted the prospective changes.

    We will see how to handle internally for time being.

    Thanks and Best Regards,

    Mohan