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/UCD3138: two 32-bits data multiplication result is not correct

Part Number: UCD3138
Other Parts Discussed in Thread: AM1808, , , TMS570LC4357, LAUNCHXL2-570LC43

Tool/software: TI C/C++ Compiler

Hi,

I am using CCS6.1 with compiler 5.22. I found the result of multiplication of two 32-bits data is not correct.  I defined the result as 64 bits data. the correct result should be 0x0000 0056  0038 7512. I saw one register R0 has the number 0x0000 0056, another register R1 has the number 0x00387512,  which is correct. however, the result I get is 0x0038 7512 0000 0056, which seems the two registers's data are put in the wrong order.

Is it a bug or I didn't configure the CCS correctly?

Thanks,

Julie

  • Can you show your code snippet?
  • the code is :

    Uint16 uint16_multiply_shift_clamp(Uint32 x, Uint32 y, int16 shift, Uint16 max_value)
    {
    Uint64 scale_product_64;

    scale_product_64 = (Uint64)x*y;

    .............

    }

    I tried to declare the variable scale_product_64 as a global variable, then the result is correct. 

    please refer to attached document.  I put all the screen captures into this document. 

    Thanks

    Julie64-bits multiplication.docx

  • The question is are you casting x to uint64_t or x*y to uint64_t? IF the latter, the multiplication will still be 32 bit.
    Try ((uint64_t)x) * y
  • I am pretty sure that is not the reason.

    first, I used the same statement for the case that scale_product_64 is declared as global variables. the result is correct.

    second, I tried different ways, like scale_product_64 = ((Uint64)x)*((Uint64)y); the result is same.

    but know I figure out it might just be a issue of displaying inside the debugger. I think the display has a bug that arrange the words in the wrong order.
  • This is expected behavior.  When a 64-bit integer value resides in a register pair, the even register holds the high order bits, and the odd register holds the low order bits.  When inspecting 64-bit values, avoid looking at the registers.  It is easy to get confused.  Look in the watch window, or something similar.

    Thanks and regards,

    -George

  • George Mock said:

    This is expected behavior.  When a 64-bit integer value resides in a register pair, the even register holds the high order bits, and the odd register holds the low order bits.  When inspecting 64-bit values, avoid looking at the registers.  It is easy to get confused.  Look in the watch window, or something similar.

    I think Julie gave an example where the watch window would show a wrong 64 bit value (namely, when the variable was stored in a register rather than in memory). That looks like a bug in CCS to me (not in the compiler, though).

    Markus

  • George,

    If you look at the screen capture I provided, the data shown in the watch window is in wrong order when it arranges the 64-bits data from 2 registers.  Should be a problem in the watch window display.

    Julie

  • Julie Zhu said:
    If you look at the screen capture I provided, the data shown in the watch window is in wrong order when it arranges the 64-bits data from 2 registers.  Should be a problem in the watch window display.

    I tried to repeat the problem using the ARM9 core in a AM1808 using CCS 6.1.2.00014 and TI ARM compiler v5.2.0 (the closest versions to those you are using which I had installed). I couldn't repeat the problem, in that the sum 64-bit sum variable held in a register pair was displayed correctly in the variable view:

    In the above working example the 64-bit variable sum is given a register-pair location of "R8:32,R9:32" in the Variables view, whereas in your failure case the location is given as "R0" which is a single 32-bit register.

    Can you post an example project which shows the problem, along with the exact CCS version number? Not sure if the problem is either:

    a) A bug in the CCS version you are using.

    b) The debug information generated by the compiler has specified the wrong register location for the 64-bit scale_product_64 variable.

  • Hi, Chester,

    the CCS version I am using is Version: 6.1.0.00104.  the project is for UCD3138, I have attached the screen capture for the details.

    Julie

  • Julie Zhu said:
    the CCS version I am using is Version: 6.1.0.00104.  the project is for UCD3138, I have attached the screen capture for the details.

    Thanks for the information. I don't have that CCS version installed and don't have a UCD3138 so can't re-create the problem to investigate.

    Not sure if it is significant, but the UCD3138 is big-endian, whereas the ARM devices I failed to re-create the problem with are little-endian. Hopefully someone from TI can repeat the problem with a UCD3138.

    Are you able to try a later CCS version to see if the problem has been fixed in a later version?

    E.g. found Expressions and variables windows not displaying correct values which was reported against CCS  6.1.0.00104, for which bug SDSCM00051806 was raised which was fixed in CCS 6.1.1

  • Hi, Chester,

    Sorry that I don't have any CCS newer than 6.1.0.00104 installed on my computer; therefore I didn't try that on a later version.

    Regards,

    Julie
  • Julie,

    I was able to create a small test case using lab 1 of the UCD3138 training labs firmware package and could verify that both CCSv7.1.0 (Windows) and CCSv6.2.0 (Ubuntu 16.04/64) work fine. 

    I am using my UCD3138OL64EVM-031 with a Spectrum Digital XDS200 USB JTAG debug probe. 

    Therefore I would simply update your copy of CCS to benefit from this bug.

    Hope this helps,

    Rafael

  • Rafael,

    Good to know it is fixed in later version. Thanks for checking this.

    Julie
  • desouza said:
    I was able to create a small test case using lab 1 of the UCD3138 training labs firmware package and could verify that both CCSv7.1.0 (Windows) and CCSv6.2.0 (Ubuntu 16.04/64) work fine

    Rafael, your screen shot shows that the scale_product_64 variable is in memory (on the stack).

    Whereas the problem Julie reported was that a 64-bit variable which the compiler optimizer had placed in a pair of 32-bit variables was displayed incorrectly, while a 64-bit global variable was displayed correctly.

    Are you able to re-check with a UCD3138 example which has optimization level of one (or greater) that CCS v6.2.0 or v7.1.0 correctly display a 64-bit variable held in a register pair?

    It may require some experimentation, but I found with the following code fragment compiled at optimization level one caused the sum 64-bit variable to be stored in a register pair, while the 64-bit scale_product variable was optimized out of the debug information:

    #include <stdint.h>
    #include <stdio.h>
    
    int main(void)
    {
    	uint32_t x = 0x8a2290;
    	uint32_t y = 0xa000;
    	uint64_t scale_product;
    	uint64_t sum;
    	uint32_t iteration;
    
    	sum = 0;
    
    	for (iteration = 0; iteration < 5; iteration++)
    	{
    		scale_product = (uint64_t) x * y;
    		printf ("0x%x * 0x%x = 0x%llx\n", x, y, scale_product);
    		sum += scale_product;
    	}
    	
    	return sum;
    }

  • Julie, Chester,

    Good point; I tried several things but couldn't find a way for the compiler to place the 64-bit result in a register pair in my system here. 

    In search of a possible outstanding bug, I found SDSCM00008685 at the file below:

    C:/ti//ccsv7/tools/compiler/ti-cgt-arm_5.2.9/Open_defects.html

    Given this is still an outstanding bug even on modern ARM compiler releases, there is a chance the debug team implemented the workaround proposed there: arbitrarily pointing the two halves of the variable at Rn:Rn+1 and placing them on the Variables/Expressions Views. As hinted above, the fact this ARM7 is a big endian platform, it may be possible the workaround fails as the data could have been stored in reverse order. 

    I searched around in our bug system for any fixes to the debugger and the closest ones I could find are SDSCM00039488 and SDSCM00042523 - both marked and confirmed as fixed. However, the testcases were targeted for other architectures. 

    At this point I would need a complete testcase to try to fully reproduce this in this platform. I can't confirm if this is still outstanding in our newest IDEs. 

    Regards,

    Rafael

  • desouza said:
    At this point I would need a complete testcase to try to fully reproduce this in this platform.

    I have attached a test case which runs on a LAUNCHXL2-570LC43. While an ARM Cortex-R5F, rather than the ARM7 the problem was reported against, I used a TMS570LC4357 since it is a big-endian ARM device.

    TMS570LC43_multiply.zip

    The program was tested on a number of CCS and TI ARM compiler releases.

    1) CCS 7.1.0.00016 and compiler v5.2.5:

    In this combination the location for the 64-bit variable sum is reported as the single "Register R5" and the value is incorrectly shown as 0x559A000000000056" instead of the expected "0x00000056559A0000".

    2) CCS 7.1.0.00016 and compiler v16.9.3.LTS:

    In the combination the location for the 64-bit variable a pair of 32-bit registers "R7:32,R5:32" and the value is correctly shown as "0x00000056559A0000".

    3) CCS 6.1.3.00033 and compiler v5.2.5:

    In this combination the location for the 64-bit variable sum is reported as the single "Register R5" and the value is incorrectly shown as 0x559A000000000056" instead of the expected "0x00000056559A0000".

    4) CCS 6.1.3.00033 and compiler v16.9.3.LTS:

    In this combination the CCS debugger reports an error the register for the 64-bit variable is unknown.

    The conclusions are:

    a) CCS 7.1.0.00016 (as well as CCS 6.1.3.00033) display the value of a 64-bit variable in a register pair incorrectly, such that the upper and lower 32-bit words are swapped, when used with a TI ARM compiler which only describes the 64-bit variable as in a 32-bit register and the ARM device is big-endian.

    b) Somewhere between the TI ARM compilers v5.2.5 and v16.9.3.LTS there has been a change to describe the location of a 64-bit variable as a register pair which allows the CCS debugger to display the 64-bit variable held in a pair of registers on a ARM big-endian device correctly. However, the new debug information is not understood by older CCS versions. Don't know which CCS version between 6.1.3 and 7.1 in which the change to understand the debug information changed.

  • Chester,

    Thanks for sending the testcase. I found out that CCSv7.1.0 + CGT 15.12.5 shows the issue while, as you saw, 16.9.3 does not.

    I also saw that CCSv6.2.0 behaves just like your 6.1.3.

    I am checking with some other sources what may have happened as I can't locate a specific bug case that was resolved.

    Regards,
    Rafael
  • desouza said:
    I found out that CCSv7.1.0 + CGT 15.12.5 shows the issue while, as you saw, 16.9.3 does not.

    I looked at the debug information generated by the compiler for the 64-bit sum variable held in a register.

    With v16.9.1.LTS a register pair is reported at the location:

    ;* V2    assigned to sum
    $C$DW$7	.dwtag  DW_TAG_variable
    	.dwattr $C$DW$7, DW_AT_name("sum")
    	.dwattr $C$DW$7, DW_AT_TI_symbol_name("sum")
    	.dwattr $C$DW$7, DW_AT_type(*$C$DW$T$71)
    	.dwattr $C$DW$7, DW_AT_location[DW_OP_reg5 DW_OP_piece 4 DW_OP_reg7 DW_OP_piece 4]

    With v15.12.5.LTS only a single register is reported as the location:

    ;* V2    assigned to sum
    $C$DW$8	.dwtag  DW_TAG_variable
    	.dwattr $C$DW$8, DW_AT_name("sum")
    	.dwattr $C$DW$8, DW_AT_TI_symbol_name("sum")
    	.dwattr $C$DW$8, DW_AT_type(*$C$DW$T$71)
    	.dwattr $C$DW$8, DW_AT_location[DW_OP_reg5]

    Where the type of sum is 64-bits via the $C$DW$T$71 type:

    $C$DW$T$71	.dwtag  DW_TAG_typedef
    	.dwattr $C$DW$T$71, DW_AT_name("uint64_t")
    	.dwattr $C$DW$T$71, DW_AT_type(*$C$DW$T$15)
    	.dwattr $C$DW$T$71, DW_AT_language(DW_LANG_C)
    	.dwattr $C$DW$T$71, DW_AT_decl_file("C:/ti_ccs7_1/ccsv7/tools/compiler/ti-cgt-arm_15.12.5.LTS/include/stdint.h")
    	.dwattr $C$DW$T$71, DW_AT_decl_line(0x33)
    	.dwattr $C$DW$T$71, DW_AT_decl_column(0x20)

    Therefore, between the v15.12.x and v16.9.x series compilers there has been an enhancement to the debug information to allow a 64-bit variable held in a register to be given the location of a register pair.