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/TMS320F28075: Error in composing a long from 2 words

Part Number: TMS320F28075

Tool/software: TI C/C++ Compiler

Hello,

I'm using Code Composer 8.3.0.9 and compiler TI v16.9.6.LTS.

I've implemented the following function:

void ApplGetParamInfo(unsigned short dataA, unsigned short dataB)
{
    unsigned long dataC;



    /* DataA is cast from word (16 bits) to long (32 bits);
       Data A is masked and left-shifted by 8 bit;
       DataB is masked;
       DataA and DataB are composed together with a bitwise OR and the result is assigned to dataC
   */

    dataC = ((((unsigned long)dataA) & 0x0000FFFFUL) << 8) | (dataB & 0x00FF);

    /* Other stuff */

}

If I have

dataA = 0x1234;

dataB = 0x0056;

I get

dataC = 0x00003456;

while I expect to get

dataC = 0x00123456;

In other words, the least significant byte of the more significant word is lost as if the operation has been executed on 16-bit data instead of 32-bit data. I use the cast operation in order not to lose that byte!

I've tried also with this instruction

    dataC = ((((unsigned long)dataA) & 0x0000FFFFUL) << 8) | (((unsigned long)dataB) & 0x00FF);

but the result is the same.

Is this a compiler bug?

Thank you in advance.

  • Some more information.
    I compile with the following optimization options:

    Optimization level (--opt_level, -O): 2 - Global Optimization
    Speed vs. size trade-offs ( --opt_for_speed, -mf): 4
  • Hello Demis, 

    Demis Biscaro said:
        dataC = ((((unsigned long)dataA) & 0x0000FFFFUL) << 8) | (dataB & 0x00FF);

    Try: dataC = ((unsigned long) dataA << 16) | (unsigned long) dataB;

  • Hello Tom,
    thank you for your answer, but I don't understand it.

    I don't want to shift dataA by 16 bits but only by 8 bits, because I want insert only the least significant byte of dataB.

    Why should I shift dataA by 16 bits?

    Best regards,

    Demis
  • I've changed the function in the following way

    void ApplGetParamInfo(unsigned short dataA, unsigned short dataB)
    {
    volatile unsigned long dataC; // <----------------------------- VOLATILE attribute inserted!



    /* DataA is cast from word (16 bits) to long (32 bits);
    Data A is masked and left-shifted by 8 bit;
    DataB is masked;
    DataA and DataB are composed together with a bitwise OR and the result is assigned to dataC
    */

    dataC = ((((unsigned long)dataA) & 0x0000FFFFUL) << 8) | (dataB & 0x00FF);

    /* Other stuff */

    }

    and now I get the correct result, i.e. if I have

    dataA = 0x1234;

    dataB = 0x0056;

    I get

    dataC = 0x00123456;

    I think maybe there's an issue in compiler beahviour when those optimization options are active.

    Isn't it?

    Best Regards,

    Demis
  • I am unable to reproduce the problem.  For the source file which contains the problem expression, please follow the directions in the article How to Submit a Compiler Test Case.

    Thanks and regards,

    -George

  • I have not checked the comments in your code. My mistake.
  • George Mock said:

    I am unable to reproduce the problem.  For the source file which contains the problem expression, please follow the directions in the article How to Submit a Compiler Test Case.

    Thanks and regards,

    -George

    Hello George,

    thank you for the link, it's the first time I report a (seeming) compiler issue, so I didn't know there was a specific procedure to report it.

    The original source file is Appl.c so I've generated the Preprocess source file Appl.pp (I've renamed as Appl_pp.txt because the forum doesn't let me to attach a .pp file...):

    /cfs-file/__key/communityserver-discussions-components-files/81/Appl_5F00_pp.txt

     

    Then I've copied the output from the build console to get all Compiler options. I've pasted to compiler_options_Appl.txt:

    /cfs-file/__key/communityserver-discussions-components-files/81/compiler_5F00_options_5F00_Appl.txt

     

    Finally the Compiler version is:

    v16.9.9.LTS


    You find the critical instruction in file App.pp at line 31662:

        parameterIndexSubindex = ((((UINT32)parameterIndex) & 0x0000FFFFUL) << 8) | (parameterSubindex & 0x00FF);

    If I have

    parameterIndex = 0x1234

    parameterSubindex = 0x0056

    I get

    parameterIndexSubindex = 0x00003456

    instead of

    parameterIndexSubindex = 0x00123456

    which is tha value I expected.

    One more consideration.

    As you can see in the file App.pp, parameterIndexSubindex is defined as follows:

        UINT32 parameterIndexSubindex;

    However, yesterday I've made some tests to find a temporary workaround. I've found that if I define parameterIndexSubindex in the following way

      volatile UINT32 parameterIndexSubindex;

    the issue disappears, i.e. I get the expected value

    parameterIndexSubindex = 0x00123456

    This led me to think of it as a compiler problem, and specifically as an optimization options problem.

    Anyway, I hope you have all the information to reproduce the issue on your system.

    Best regards,

    Demis

  • Thank you for the test case.  Even though I have everything I need, I am still unable to work out what happened.  Before I pass this issue on to other experts, I have these questions.

    Exactly how do you see the problem?  Is it possible that this is only a problem in how CCS displays the values?  If you run all the way through the function with the problem statement, does the caller to the function act as if it received bad results?

    Thanks and regards,

    -George

  • Hello George

    George Mock said:

    xactly how do you see the problem?  Is it possible that this is only a problem in how CCS displays the values?  If you run all the way through the function with the problem statement, does the caller to the function act as if it received bad results?

    Yes, it does, unfortunately.

    I use parameterIndexSubindex as a key to seek a specific item in a list, but the function doesn't find it because the key value is wrong.

    I stumbled on this issue just because the caller to the function got a bad result: "item not found".

    On the opposite, when I put the "volatile" attribute in parameterIndexSubindex definition the function finds the item, the caller gets the correct result and the software runs correctly.

    To be sincere, I should add the "volatile" attribute both to parameterIndexSubindex and dictionaryParameterIndexSubindex, otherwise even dictionaryParameterIndexSubindex has a wrong value, i.e. the assignment

    dictionaryParameterIndexSubindex = CAN_VOCAB[middleIndex].Indirizzo;

    transfers only the least significant word from CAN_VOCAB[middleIndex].Indirizzo to dictionaryParameterIndexSubindex.

    For instance, suppose I define

     UINT32 dictionaryParameterIndexSubindex;

    and I have

    CAN_VOCAB[middleIndex].Indirizzo = 0x00123456

    After the assignment

    dictionaryParameterIndexSubindex = CAN_VOCAB[middleIndex].Indirizzo;

    I get

    dictionaryParameterIndexSubindex = 0x00003456

    instead of

    dictionaryParameterIndexSubindex = 0x00123456

    Therefore I should define

        volatile UINT32 parameterIndexSubindex;
        volatile UINT32 dictionaryParameterIndexSubindex;

    to get the whole function run correctly.

    Very, very odd.

    I attach a file with the assembly code I get when I compile with and without the "volatile" attribute.

    /cfs-file/__key/communityserver-discussions-components-files/81/assembly_5F00_code.txt

    Don't hesitate to contact me if you need additional information.

    Thank you.

    Best regards,

    Demis

  • Hello George,
    I've done some more tests and I've made a recap of the whole issue history.

    Some days ago, I saw that the function returned "item not found", so I inspected variable contents in "Variables" watch window and I found that parameterIndexSubindex and dictionaryParameterIndexSubindex had wrong values.

    Then I compiled the funcion with the "volatile" attribute and in this way I saw the expected values of parameterIndexSubindex and dictionaryParameterIndexSubindex in "Variables" watch window.
    However, function returned "item not found" because there was no item with the 0x00123456 key in my list.

    So I added the item with the 0x00123456 key in my list and I saw that function returned "item found" correctly.

    This morning I've removed the "volatile" attribute and I've done some new tests.
    I've seen that function returns "item found" correctly even if I see the wrong values of parameterIndexSubindex and dictionaryParameterIndexSubindex in "Variables" watch window!

    Then I've defined a global array

    volatile INT32 sd[32];

    and I've put these assignment in my function

    ...
    ...
    parameterIndexSubindex = ((((UINT32)parameterIndex) & 0x0000FFFFUL) << 8) | (parameterSubindex & 0x00FF);

    sd[10] = parameterIndexSubindex; // <---------- new assignment
    ...
    ...
    dictionaryParameterIndexSubindex = CAN_VOCAB[middleIndex].Indirizzo;

    sd[11] = dictionaryParameterIndexSubindex; // <--------------------- new assignment
    ...
    ...

    In Expressions watch window I've seen
    sd[10] = 0x00123456
    sd[11] = 0x00123456

    i.e. the correct values!


    In conclusion:
    - code works correctly both with and without the "volatile" attribute;
    - Variables watch window shows the correct values only with the "volatile" attribute.

    Then you're right, the issue isn't about the compiler but it concerns only Variables watch window.

    I do apologise for my mistake, I'm verry sorry.

    Thank you very much for your support.

    Best regards,

    Demis
  • Hello Demis,
    I believe this is related to another issue reported against the Variables/Expressions view (CCDSK-3134). We were never able to resolve it because we didn't have a reproducible test case. Could you provide a FULL test case? This would mean the project + all source/header files + executable *.out file. We don't need your actual project, just some basic stripped down "dummy" project that can reproduce the issue. The simpler the better.

    Thanks
    ki
  • Hello Ki-Soo,
    I've reported your request to my boss.
    As you can easily imagine I can't send you the whole project because it's confidential. To strip this project isn't so easy because I've got a lot of tasks to accomplish and the deadline is getting closer and closer. I'll try to find some time to do it but I can't promise you that.

    Thanks.

    Demis
  • I understand your situation - it is a common one because of IP and the not so trivial task of stripping down a full project. If you can find the time to put together a test case, it would be greatly appreciated.

    Thanks
    ki