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.

Calculating constants at compile time, not run time

Other Parts Discussed in Thread: MSP430F2418

Using Code Composer Studio for a MSP430 design,  the compiler is giving me warnings recommending that I not use floating point math because it's processor intensive (or something to that effect). Sorry - I don't have the exact warning.

I am confused because the compiler seems to think that I want to use floating point math during run time, and I certainly do not. However, I do have some #defines that use some intermediate floating point values that eventually will be type cast into integer values for use at run time - or at least that is the plan. Here are the defines.

#define XTAL_FREQ 10000000UL
#define CORE_RESET_TIME (float)(0.000050)

#define MCLK_DIV 8UL
#define SMCLK_DIV 8UL
#define ACLK_DIV 256UL

#define MCLK_FREQ (XTAL_FREQ / MCLK_DIV)
#define SMCLK_FREQ (XTAL_FREQ / SMCLK_DIV)
#define ACLK_FREQ (XTAL_FREQ / ACLK_DIV)

#define ACLK_PERIOD ( (float)1/(float)ACLK_FREQ )
#define SMCLK_PERIOD ( (float)1/(float)SMCLK_FREQ )

#define TIMB1_CORE_RESET_CCR0 (unsigned short)(round(CORE_RESET_TIME / SMCLK_PERIOD))

Ultimately, the only value that is of any interest to me at run time is TIMB1_CORE_RESET_CCR0. This should calculate out to a value of 63 for use at run time. The floating point values are never referenced anywhere else in the code. How can I force the compiler to understand that this is not a run time calculation using floating point, but is instead a parametric way of calculating an integer constant for run time use ?

  • For the source file being compiled when this diagnostic is seen ...

    the compiler is giving me warnings recommending that I not use floating point math

    ... please follow the directions in the article How to Submit a Compiler Test Case.

    Thanks and regards,

    -George

  • #define TIMB1_CORE_RESET_CCR0 (unsigned short)(round(CORE_RESET_TIME / SMCLK_PERIOD))

    That references the round() function. I'm not sure if the compiler constant evaluation would be able to eliminate the function call.

    What happens if you instead try:

    #define TIMB1_CORE_RESET_CCR0 (unsigned short)((CORE_RESET_TIME / SMCLK_PERIOD) + 0.5f)

  • That references the round() function. I'm not sure if the compiler constant evaluation would be able to eliminate the function call.

    Attached are two example projects, both compiled using TI MSP430 compiler v21.6.0 using Optimisation Level 0 (Register Optimisations).

    1. MSP430F2418_compiler_constants_round uses the original TIMB1_CORE_RESET_CCR0 macro definition which uses the round() function:

    #include <msp430.h> 
    #include <math.h>
    
    #define XTAL_FREQ 10000000UL
    #define CORE_RESET_TIME (float)(0.000050)
    
    #define MCLK_DIV 8UL
    #define SMCLK_DIV 8UL
    #define ACLK_DIV 256UL
    
    #define MCLK_FREQ (XTAL_FREQ / MCLK_DIV)
    #define SMCLK_FREQ (XTAL_FREQ / SMCLK_DIV)
    #define ACLK_FREQ (XTAL_FREQ / ACLK_DIV)
    
    #define ACLK_PERIOD ( (float)1/(float)ACLK_FREQ )
    #define SMCLK_PERIOD ( (float)1/(float)SMCLK_FREQ )
    
    #define TIMB1_CORE_RESET_CCR0 (unsigned short)(round(CORE_RESET_TIME / SMCLK_PERIOD))
    
    /**
     * main.c
     */
    int main(void)
    {
    	WDTCTL = WDTPW | WDTHOLD;	// stop watchdog timer
    	
    	return TIMB1_CORE_RESET_CCR0;
    }
    

    When compile the above:

    a. Get "remark #1531-D: (ULP 5.2) Detected floating point operation(s). Recommend moving them to RAM during run time or not using as these are processing/power intensive" reported 52 times.

    b. The linker map file shows floating point library functions are being linked from the compiler run time library, e.g. round, floor, __mspabi_addd, __mspabi_fixdu

    c. The linker map shows the total size is 3276 (code), 64 (ro data), 80 (rw data)

    d. The assembler listing shows for the return TIMB1_CORE_RESET_CCR0 statement functions are being called:

    	.dwpsn	file "../main.c",line 27,column 2,is_stmt,isa 0
            MOV.W     #0,r12                ; [] |27| 
            MOV.W     #57344,r13            ; [] |27| 
            MOV.W     #16383,r14            ; [] |27| 
            MOV.W     #16463,r15            ; [] |27| 
    $C$DW$5	.dwtag  DW_TAG_TI_branch
    
            CALLA     #round                ; [] |27| 
                                              ; [] |27| 
    $C$DW$6	.dwtag  DW_TAG_TI_branch
    
            CALLA     #__mspabi_fixdu       ; [] |27| 
                                              ; [] |27| 
    	.dwpsn	file "../main.c",line 28,column 1,is_stmt,isa 0
    $C$DW$7	.dwtag  DW_TAG_TI_branch
    
            RETA      ; [] 
    

    2. MSP430F2418_compiler_constants_cast uses a cast in the TIMB1_CORE_RESET_CCR0 macro definition:

    #include <msp430.h> 
    
    #define XTAL_FREQ 10000000UL
    #define CORE_RESET_TIME 0.000050
    
    #define MCLK_DIV 8UL
    #define SMCLK_DIV 8UL
    #define ACLK_DIV 256UL
    
    #define MCLK_FREQ (XTAL_FREQ / MCLK_DIV)
    #define SMCLK_FREQ (XTAL_FREQ / SMCLK_DIV)
    #define ACLK_FREQ (XTAL_FREQ / ACLK_DIV)
    
    #define ACLK_PERIOD ( (double)1/(double)ACLK_FREQ )
    #define SMCLK_PERIOD ( (double)1/(double)SMCLK_FREQ )
    
    #define TIMB1_CORE_RESET_CCR0 (unsigned short)((CORE_RESET_TIME / SMCLK_PERIOD) + 0.5)
    
    /**
     * main.c
     */
    int main(void)
    {
    	WDTCTL = WDTPW | WDTHOLD;	// stop watchdog timer
    	
    	return TIMB1_CORE_RESET_CCR0;
    }
    

    When compile the above:

    a. The compiler no longer reports "remark #1531-D: (ULP 5.2) Detected floating point operation(s)."

    b. The linker map doesn't show floating point library function being linked.

    c. The linker map shows the total size is 50 (code), 64 (ro data), 80 (rw data). I.e. significant size reduction due to not pulling in floating point library functions.

    d. The assembler listing shows for the return TIMB1_CORE_RESET_CCR0 statement the compiler uses a constant value 63 calculated at compile time, and there are no function calls:

            MOV.W     #63,r12               ; [] |26| 
    	.dwpsn	file "../main.c",line 27,column 1,is_stmt,isa 0
    $C$DW$3	.dwtag  DW_TAG_TI_branch
    
            RETA      ; [] 
    

    Note that since the calculation for TIMB1_CORE_RESET_CCR0 ends up rounding the value 62.5 to an integer, I had to change the macro to use all double-precision calculations to ensure the rounded integer was 63, rather than 62.

    MSP430F2418_compiler_constants_round.zip

    MSP430F2418_compiler_constants_cast.zip