Tool/software:
Hello,
I am experiencing a problem, when compiling a project for a TMS320F28377D with optimization level greater than "1 - Local Optimizations", which I believe could be the one reported in this issue although the related forum page is not anymore accessible:
https://sir.ext.ti.com/jira/browse/EXT_EP-4848
I have attached few source files which, once added to a new project, will let you easily reproduce the problem.
Essentially the assembly code corresponding to the first source code line of the MyStruct_SetPointers function:
// Retrieve the address of the MyStruct structure associated to the passed identifier.
volatile MyStruct * volatile StructPtr = MyStructsPtrs[MyStructID - FIRST_ASSIGNED_STRUCT_ID];
is generated as follows when the optimization level is increased to "2 - Global Optimizations" or to any higher optimization level:
0000000a 2901 CLRC SXM ; [CPU_ALU]
0000000b 761F! MOVW DP, #||MyStructsPtrs|| ; [CPU_ARAU]
0000000c 0000
0000000d 5603 MOV ACC, AL << 1 ; [CPU_ALU] |71|
0000000e 01A9
0000000f 0700! ADDL ACC, @||MyStructsPtrs|| ; [CPU_ALU] |71|
00000010 8AA9 MOVL XAR4, ACC ; [CPU_ALU] |71|
00000011 8D00 MOVL XAR0, #44568 ; [CPU_ALU] |71|
00000012 AE18
00000013 C494 MOVL XAR6,*+XAR4[AR0] ; [CPU_ALU] |71|
which is completely different from the assembly code generated when the optimization level is reduced to
"1 - Local Optimizations" or to any lower optimization level:
0000000a 28A8 MOV AH, #22284 ; [CPU_ALU] |71|
0000000b 570C
0000000c 2901 CLRC SXM ; [CPU_ALU]
0000000d 761F! MOVW DP, #||MyStructsPtrs|| ; [CPU_ARAU]
0000000e 0000
0000000f 95A9 ADD AH, AL ; [CPU_ALU] |71|
00000010 5603 MOV ACC, AH << 1 ; [CPU_ALU] |71|
00000011 01A8
00000012 0700! ADDL ACC, @||MyStructsPtrs|| ; [CPU_ALU] |71|
00000013 8AA9 MOVL XAR4, ACC ; [CPU_ALU] |71|
00000014 06C4 MOVL ACC, *+XAR4[0] ; [CPU_ALU] |71|
In the first case, the assembly code corresponding to the (MyStructID - FIRST_ASSIGNED_STRUCT_ID) subtraction seems to be completely missing and the calculated value of MyStructPointersArray, which should be stored in XAR6, is wrong. As you can notice, I have placed volatile qualifiers wherever possible even if - I believe - not necessary.
The compiler settings are as follows:
-v28 -ml -mt --cla_support=cla1 --float_support=fpu32 --idiv_support=none --isr_save_vcu_regs=off --tmu_support=tmu0
--vcu_support=vcu2 -O2 --opt_for_speed=5 --include_path="F:/Test" --include_path="C:/ti/ccs1250/ccs/tools/compiler/ti-cgt-c2000_22.6.1.LTS/include"
--include_path="F:/Test/MyStruct" --advice:performance=all -g --c11 --float_operations_allowed=32 --fp_single_precision_constant
--printf_support=minimal --diag_warning=225 --diag_wrap=off --display_error_number --abi=eabi --asm_listing
and the compiler version is the latest one, v22.6.1.LTS
Could you please verify if the problem is effectively a bug in the compiler or if it is due to the source code not being properly written?
Thank you for your support,
Best Regards
Alberto
#include <stdint.h>
#include <stddef.h>
#include <stdarg.h>
#include <stdlib.h>
#include <MyStruct.h>
#define MAX_NUM_STRUCTS 10
#define FIRST_ASSIGNED_STRUCT_ID 0xA8F4
static uint16_t NumCreatedStructs = 0;
static volatile MyStruct * volatile * volatile MyStructsPtrs = NULL;
uint16_t MyStruct_Init(void)
{
if ((MyStructsPtrs = (volatile MyStruct * volatile *) malloc(MAX_NUM_STRUCTS * sizeof(MyStruct *))) == NULL)
return 1;
else
{
for (uint16_t i = 0; i < MAX_NUM_STRUCTS; i++)
MyStructsPtrs[i] = NULL;
return 0;
}
}
uint16_t MyStruct_Terminate(void)
{
if (MyStructsPtrs == NULL)
return 0;
for (uint16_t i = 0; i < NumCreatedStructs; i++)
{
free((void *) MyStructsPtrs[i]);
}
free((void *) MyStructsPtrs);
return 0;
}
uint16_t MyStruct_Create(uint16_t * StructIDptr)
{
volatile MyStruct * volatile MyStructPtr;
if (NumCreatedStructs >= MAX_NUM_STRUCTS)
return 1;
if ((MyStructPtr = (volatile MyStruct *) malloc(sizeof(MyStruct))) == NULL)
return 1;
MyStructsPtrs[NumCreatedStructs] = MyStructPtr;
*StructIDptr = FIRST_ASSIGNED_STRUCT_ID + NumCreatedStructs;
// other struct initialization stuff here
return 0;
}
uint16_t MyStruct_SetPointers(uint16_t MyStructID, size_t FirstPointerOffset, ...)
{
#if defined(DEBUG)
if ((MyStructID - FIRST_ASSIGNED_STRUCT_ID + 1) > NumCreatedStructs)
return 1;
#endif
// Retrieve the address of the MyStruct structure associated to the passed identifier.
volatile MyStruct * volatile StructPtr = MyStructsPtrs[MyStructID - FIRST_ASSIGNED_STRUCT_ID];
// Calculate the address of the 'first_pointer' member of StructPtr.
void * volatile * volatile MyStructPointersArray = (void * volatile *) (((uintptr_t) StructPtr) + FirstPointerOffset);
va_list ExtraArgs;
void * volatile CurrentPtr;
// Initialize the list of variable arguments.
va_start(ExtraArgs, FirstPointerOffset);
for (uint16_t i = 0; (CurrentPtr = va_arg(ExtraArgs, void *)) != ((void *) UINTPTR_MAX) && (FirstPointerOffset + i * sizeof(void *)) < sizeof(MyStruct); i++)
{
MyStructPointersArray[i] = CurrentPtr;
}
// Terminate the list of callback pointers.
va_end(ExtraArgs);
return (CurrentPtr != ((void *) UINTPTR_MAX));
}
#include <stdint.h>
#include <MyStruct.h>
uint16_t var1, var2, var3;
int main(void)
{
uint16_t StructID;
uint16_t result;
if (result = MyStruct_Init())
return result;
if (result = MyStruct_Create(&StructID))
return result;
result = MyStruct_SetPointers(StructID, offsetof(MyStruct, first_pointer), &var1, &var2, &var3);
return result;
}