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.

Compiler/C2000-CGT: 32-bit Register Accesses are optimised by compiler as 16-bit RW. Is there an option to tell the compiler not to optimise to 16-bit RWs?

Part Number: C2000-CGT

Tool/software: TI C/C++ Compiler

We are using C2000 microcontroller to talk to 32-bit peripherals on the APB. We face issues with respect to 32-bit access of the peripheral registers.

CCS Version – 8.2.0

Compiler Version – TI v18.12.1.LTS

 

When we write a code of the format

Snippet 1:

Periph_Reg = Periph_Reg & ~(0x000F0000);

This is supposed to clear the bits <19:16> in the peripheral register.

Roughly translates to assembly code

(XAR4 stores the peripheral register address. P stores the current value of the peripheral register)

AND         @PH, #0xfff0   - An AND operation of the MSB 16 bits is done with 0xFFF0

MOVL       *+XAR4[0], P   - The resulting 32-bit value stored in P register is copied to peripheral register address stored in XAR4


Whereas the same code if written as 

Snippet 2:

Periph_Reg &=  ~(0x000F0000);

Translates to following assembly code

AND         *+XAR4[1], #0xfff8 - The 16-bit AND operation with MSB 16 bits is directly done on the peripheral register  value.

We don't see any issues with snippet 1 whereas snippet 2 corrupts the LSB 16-bits of the data stored in peripheral register. 

Is there a way to qualify the peripheral register access such that they are not optimised for 16-bit optimisation? Are there any other solutions to overcome this issue?

  • For the source file which contains the problem statement, please follow the directions in the article How to Submit a Compiler Test Case.  If it is not obvious which is the problem statement, please indicate which source line number it is on.

    Thanks and regards,

    -George

  • Hi,

    How is it that snippete 2 corrupts the LSB (16 bits)?

    It should not be touching the LSB at all since it is only doing a 16-bit access on XAR4[1].

    sal

  • Please submit the requested test case.

    Thanks and regards,

    -George

  • Hi George,

    Thanks for responding! I have sent the test case to you.

    Regards

    - Sudharsan

  • Thank you for the test case.  I can reproduce the problem.

    Sudharsan Varadharajan said:
    1
    Periph_Reg &=  ~(0x000F0000);

    Translates to following assembly code

    AND         *+XAR4[1], #0xfff8

    The compiler fails to emit this instruction ...

    AND         *+XAR4[0], #0xffff

    Even though this instruction does nothing, because the long variable is volatile, the compiler should emit it.  

    I filed the entry CODEGEN-6399 in the SDOWP system to have this investigated.  You are welcome to follow it with the SDOWP link below in my signature.

    Thanks and regards,

    -George

  • Hi George,

    Thank you for checking on this! I am not able to track the issue using SDOWP. I see this error when I try to search for the bug - 

    Record 'CODEGEN-6399' was not found.

    Regarding the fix, even if the 

    AND         *+XAR4[0], #0xffff

    instruction is emitted, I am not sure if that will fix the data corruption issue because this instruction is still a 16-bit Write to the peripheral register, during which the other 16-bits might get corrupted again.

    Thanks,

    Sudharsan

  • Sudharsan Varadharajan said:
    I am not able to track the issue using SDOWP.

    I apologize for not marking the entry for public view.  I just changed it.  Please wait a few hours for that change to propagate through the system.

    Sudharsan Varadharajan said:
    I am not sure if that will fix the data corruption issue because this instruction is still a 16-bit Write to the peripheral register

    You make a good point.  I added it to the entry.

    Thanks and regards,

    -George