Part Number: TMS320F280049M
Tool/software: Code Composer Studio
I have an application that uses the CLA to do extensive processing of unsigned 32 bit values (timer/counter capture events). Based on the CLA disassembly and stepping through the code with the emulator, it appears that CCS is using the CLA's MCMP32 instruction incorrectly. The documentation indicates that the MCMP32 instruction compares two 32 bit signed integers, but the code generated by the CCS does not correctly manipulate the unsigned 32 bit value to make proper use of the signed comparison. Below is the CLA source code, followed by some disassembly views. I tested several combinations of values, and the failure to properly compare the unsigned 32 bit values follows what would be expected from the use of signed comparisons.
I am using CCS version 7.2.0.00013, and an A sample of the DSP.
Source code:
//Test1 = 3, Test2 = 2147483652; Yes (test fails, improper unsigned 32 bit comparison)
//Test1 = 3, Test2 = 2147483651; Yes
//Test1 = 3, Test2 = 2147483650; No (test passed, correct unsigned 32 bit comparison)
//Test1 = 3, Test2 = 2147483649; No
//Test1 = 2, Test2 = 2147483651; Yes
//Test1 = 2, Test2 = 2147483650; Yes
//Test1 = 2, Test2 = 2147483649; No
//Test1 = 2, Test2 = 2147483648; No
//Test1 = 1, Test2 = 4294967295; Yes
//Test1 = 1, Test2 = 4294967294; Yes
//Test1 = 1, Test2 = 2147483651; Yes
//Test1 = 1, Test2 = 2147483650; Yes
//Test1 = 1, Test2 = 2147483649; Yes
//Test1 = 1, Test2 = 2147483648; No
//Test1 = 1, Test2 = 2147483647; No
uint16_t Test0;
uint32_t Test1;
uint32_t Test2;
__mdebugstop();
Test0 = 0;
Test1 = 1;
Test2 = 2147483649;
if ( Test1 > Test2 )
{
Test0 = 1; // This is just a failure indicator; it does not influence the problem.
}
__mdebugstop();
Disassembly with added comments for Test1 = 1 and Test2 = 2147483649:
0000b5d0: 7F600000 MDEBUGSTOP
0000b5d2: 7FA00000 MNOP
0000b5d4: 7FA00000 MNOP
0000b5d6: 7FA00000 MNOP
0000b5d8: 7FA00000 MNOP
0000b5da: 78400000 MMOVIZ MR0, #0x0 // Test0 = 0.
0000b5dc: 75C09D50 MMOV16 @0x9d50, MR0
0000b5de: 78400000 MMOVIZ MR0, #0x0 // Test1 = 0x00000001 = 1.
0000b5e0: 78800001 MMOVXI MR0, #0x1
0000b5e2: 74C09D4C MMOV32 @0x9d4c, MR0
0000b5e4: 78408000 MMOVIZ MR0, #0x8000 // Test2 = 0x80000001 = 2147483649.
0000b5e6: 78800001 MMOVXI MR0, #0x1
0000b5e8: 74C09D4E MMOV32 @0x9d4e, MR0
0000b5ea: 78428000 MMOVIZ MR2, #0x8000
0000b5ec: 78418000 MMOVIZ MR1, #0x8000
0000b5ee: 7CA00004 MXOR32 MR0, MR1, MR0 // MR0 = Test2 XOR 0x80000000 = 0x00000001.
0000b5f0: 73D09D4C MMOV32 MR1, @0x9d4c, UNCF
0000b5f2: 7CA00019 MXOR32 MR1, MR2, MR1 // MR1 = Test1 XOR 0x80000000 = 0x80000001.
0000b5f4: 7F200004 MCMP32 MR0, MR1 // Set flags based on 0x00000001 - 0x80000001, sets NF = 1.
0000b5f6: 7FA00000 MNOP
0000b5f8: 7FA00000 MNOP
0000b5fa: 7FA00000 MNOP
0000b5fc: 79830012 MBCNDD 0x12, GEQ // Test1 > Test2? Branch if NF = 0, so branch will not be taken (see above).
0000b5fe: 7FA00000 MNOP
0000b600: 7FA00000 MNOP
0000b602: 7FA00000 MNOP
0000b604: 78400000 MMOVIZ MR0, #0x0 // Test0 = 1. Comparison has been incorrectly performed.
0000b606: 78800001 MMOVXI MR0, #0x1
0000b608: 75C09D50 MMOV16 @0x9d50, MR0
0000b60a: 7FA00000 MNOP
0000b60c: 7FA00000 MNOP
0000b60e: 7FA00000 MNOP
0000b610: 7FA00000 MNOP
0000b612: 7FA00000 MNOP
0000b614: 7F600000 MDEBUGSTOP
Disassembly with added comments for Test1 = 2 and Test2 = 2147483649:
0000b5d0: 7F600000 MDEBUGSTOP
0000b5d2: 7FA00000 MNOP
0000b5d4: 7FA00000 MNOP
0000b5d6: 7FA00000 MNOP
0000b5d8: 7FA00000 MNOP
0000b5da: 78400000 MMOVIZ MR0, #0x0 // Test0 = 0.
0000b5dc: 75C09D50 MMOV16 @0x9d50, MR0
0000b5de: 78400000 MMOVIZ MR0, #0x0 // Test1 = 0x00000002 = 2.
0000b5e0: 78800002 MMOVXI MR0, #0x2
0000b5e2: 74C09D4C MMOV32 @0x9d4c, MR0
0000b5e4: 78408000 MMOVIZ MR0, #0x8000 // Test2 = 0x80000001 = 2147483649.
0000b5e6: 78800001 MMOVXI MR0, #0x1
0000b5e8: 74C09D4E MMOV32 @0x9d4e, MR0
0000b5ea: 78428000 MMOVIZ MR2, #0x8000
0000b5ec: 78418000 MMOVIZ MR1, #0x8000
0000b5ee: 7CA00004 MXOR32 MR0, MR1, MR0 // MR0 = Test2 XOR 0x80000000 = 0x00000001.
0000b5f0: 73D09D4C MMOV32 MR1, @0x9d4c, UNCF
0000b5f2: 7CA00019 MXOR32 MR1, MR2, MR1 // MR1 = Test1 XOR 0x80000000 = 0x80000002.
0000b5f4: 7F200004 MCMP32 MR0, MR1 // Set flags based on 0x00000001 - 0x80000002, sets NF = 0.
0000b5f6: 7FA00000 MNOP
0000b5f8: 7FA00000 MNOP
0000b5fa: 7FA00000 MNOP
0000b5fc: 79830012 MBCNDD 0x12, GEQ // Test1 > Test2? Branch if NF = 0, so branch will be taken (see above).
0000b5fe: 7FA00000 MNOP
0000b600: 7FA00000 MNOP
0000b602: 7FA00000 MNOP
0000b604: 78400000 MMOVIZ MR0, #0x0 // Test0 = 1 is skipped.
0000b606: 78800001 MMOVXI MR0, #0x1
0000b608: 75C09D50 MMOV16 @0x9d50, MR0
0000b60a: 7FA00000 MNOP
0000b60c: 7FA00000 MNOP
0000b60e: 7FA00000 MNOP
0000b610: 7FA00000 MNOP
0000b612: 7FA00000 MNOP
0000b614: 7F600000 MDEBUGSTOP