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.

CCS/TMS320F28388D: wrong XAR register value with lib function pow or powf

Part Number: TMS320F28388D
Other Parts Discussed in Thread: C2000WARE, TMS320F28377D

Tool/software: Code Composer Studio

Hello,

use:
lib: rts2800_fpu32_fast_supplement.lib
lib: rts2800_fpu32_fast_supplement_eabi.lib
compiler: ti-cgt-c2000_20.2.0B1 / ti-cgt-c2000_18.1.1.LTS


Customer had a problem with the lib function pow or powf.
Description (in assembler):
Target addresses and parameter addresses are writen into the XAR register. These are not reloaded later before reading or writing of this register. Then the powf function is used. But the XAR register values aren't automatically saved onto the stack. The powf function uses some XAR register (eg XAR2) and overwrites these register. There are the wrong addresses in the XAR register after execution of the powf function and the following code uses the wrong values or jumps to the wrong addresses.

Attached is an example screenshot. I can send the code or what else you need offline.

Regards, HolgerCompiler Library Fehler FPU-Funktion.docx

  • Holger,

    Yes, please send me whatever you have, either in a post or offline, whichever is easier.  I'm not able to reproduce the issue just with the information in the doc.  Also, please let me know to CCS and tools versions involved.  Many thanks.

    Regards,

    Richard

  • Hello Richard,
    I will ask for the sources. Should they send it in following format?

    How to Submit a Compiler Test Case

    Regards, Holger

  • Hi Holger,

    Yes, please do it this way.  Thanks.

    Regards,

    Richard

  • Hi Richard,

    By chance I stumbled over exactly the same problem and the problem is actually very trivial.

    The problem is within the rts2800_fpu32_fast_supplement library v2.01.00.00 and affects the functions "pow" and "exp" (This is part of the C2000Ware package: C2000Ware_2_01_00_00\libraries\math\FPUfastRTS\c28\)

    Both of the mentioned functions (implemented in assembler) use the registers XAR1 and XAR2 but don't restore the original value of that register.

    Relevant sections of "pow":

    ;;*****************************************************************************
    ;; Register Usage:
    ;;   XAR0: pointer to the lookup table | R0H : x, base
    ;;   XAR1: pointer to the exp coeffs   | R1H : y, exponent
    ;;   XAR2: storing the lookup tabe index
    ;; Stack Usage:
    ;;
    ;;   |_______|<- Stack Pointer                    (SP)
    ;;   |_______|<- LF_X_EXP_U                       (SP-1)-----> Local Frame
    ;;   |_______|<- LF_ABS_X_H                       (SP-2)    |
    ;;   |_______|<- LF_ABS_X_L|LF_ABS_X|LF_X_MANT    (SP-3)----
    ;;   |_______|<- R4H                              (SP-5)
    ;;   |_______|<- rpc calling function             (SP-7)
    ;;
    ;;*****************************************************************************
    
    [...]
    
    ;;-----------------------------------------------------------------------------
    ;; Context Save
    ;;-----------------------------------------------------------------------------
        ; The stack pointer is aligned to an even address by the calling function
        MOV32    *SP++,R4H
        ADDB        SP, #LF_SIZE        
    ;;-----------------------------------------------------------------------------
    
    [...]
        MOVL        XAR1, #_FPU32expTableCoeff
    [...]
        MOV32        XAR2, R4H            ; 1|   ACC = sizeof(float)*x_i
    [...]
        MOV32       R4H, *--SP           ; 1|   restore R4H
    [...]
        LRETR
    

    Now to quote the compiler reference (SPRU514P), Chapter 7.3.2 point 1:

    If the called function modifies XAR1, XAR2, or XAR3, it must save them, since the calling function assumes that the values of these registers are preserved upon return.

    As it is easy to see, the function only store register R4H but it should additionally store XAR1 and 2 as well.

  • Thank you for the report.  I understand and will ask for someone to look into this and get back to you.

    Regards,

    Richard

  • Holger, Daniel,

    Thank you both for reporting this - it is indeed a bug.  The fix to push and pop those two registers is straightforward, however we have missed the window to update it in the next C2000Ware release, so it will be 2Q before we're able to get a fix into the public version.  In the interim, you can edit the assembly module yourselves and rebuild the library.  For licensing reasons I am not allowed to attach the modified file, but I can describe how to change it.

    In C2000Ware, the file pow_f32.asm is located in directory:  \libraries\math\FPUfastRTS\c28\source\fpu32 

    You'll need to add the following lines:

    Below line 118, add two instructions to save XAR1 & XAR2:

    MOV32   *SP++,R4H
    PUSH   XAR1
    PUSH   XAR2
    ADDB   SP, #LF_SIZE

    Then, below what is now line 248, add two lines to restore these tow registers:

    ADDF32   R2H, #1.0, R2H ; *|
    POP   XAR2 ; 1| restore XAR2
    POP   XAR1 ; 1| restore XAR1
    MOV32   R4H, *--SP ; 1| restore R4H

    Save this file.  You'll then need to re-build the library, which you can do by opening the CCS project located in directory:  \libraries\math\FPUfastRTS\c28\ccs\fpu32  

    I think this is everything but let me know if you run into any issues.  Thanks again for reporting this issue.  

    Regards,

    Richard

  • I should add that a similar bug exists in the expf() function and will also be addressed in the next C2000Ware release.

    Regards,

    Richard

  • We are also having an issue with the powf() function sometimes not returning the correct value when calculating the following:

    AdjustedThrottle = powf(ThrottleValue, 1.20);
    AdjustedThrottle *= 0.398;

    The correct value is returned when the JTAG programmer first flashes the TMS320F28377D and runs the code from CCS (using Free Run).

    If the power to the processor board is cycled (i.e. standalone Boot to Flash mode) incorrect values are returned.

    We have tried re-compiling the FPUfastRTS library but the compiler complains about a missing 'make' file so have not been able to test if this is the problem.

     

    Do you think our powf() function problem is related or something else.

    Can you help us compile the FPUfastRTS library?

    Regards,

    Scott

  • Scott,

    If it's working with the debugger connected it doesn't sound like an algorithm problem. More likely it's either the FPU tables in the wrong place or an uninitialized variable. Please check p.15-16 in the library user's guide about placement of the tables.  Also, can you check 'ThrottleValue' before the call to powf to be sure it's what you expect?

    To rebuild the library, you should be able to open the following project in CCS:
    C:\ti\c2000\C2000Ware_2_01_00_00\libraries\math\FPUfastRTS\c28\ccs\fpu32

    Then, in the 'General' section of project properties, select the 'Configuration' to either EABI or COFF, and re-build. Is this what you're doing?

    Regards,

    Richard

  • Hello Richard,

    We have tried rebuilding the project but are having an issue (see screen dump).

    We get an Error Message 'Program "make" not found in PATH'

    Can you suggest where we are going wrong?

    Regards

    Scott

  • Hello Scott,

    I'm sorry you're facing this issue.  Below are a couple of references which may help.  Could you take a look at these please?

    http://software-dl.ti.com/ccs/esd/documents/sdto_ccs_build-errors.html#ccs-gmake-errors

    https://e2e.ti.com/support/tools/ccs/f/81/t/607701

    Please let me know if either resolves the issue.  Thanks.

    Regards,

    Richard