Other Parts Discussed in Thread: MSP430F2272
Hi,
Since version 4.x.y of the MSP430 tools (4.1.1 being the latest at the time of writing), the C code optimizer produces invalid code for the case described below. The attached source files (main.c, main.asm) contain an example which reproduces the problem and the resulting assembly code.
/*
* main.c
*/
#include <msp430.h>
/*
* table.c
*/
#define NUM_COLLECTIONS 2
#define NUM_ENTRIES 8
struct entry {
short x;
short y;
short z;
};
struct collection {
struct entry entries[NUM_ENTRIES];
int n;
};
static
struct collection input[NUM_COLLECTIONS];
static
struct collection output[NUM_COLLECTIONS];
static
void init(void)
{
int i, j;
for (i = 0; i < NUM_COLLECTIONS; ++i) {
for (j = 0; j < NUM_ENTRIES; ++j) {
input[i].entries[j].x = i;
input[i].entries[j].y = j;
input[i].entries[j].z = j <= NUM_ENTRIES/2;
output[i].entries[j].z = j;
}
input[i].n = i;
}
}
static
void update(void)
{
int i, j;
for (i = 0; i < NUM_COLLECTIONS; ++i) {
struct entry *r = output[i].entries;
for (j = 0; j < NUM_ENTRIES; ++j) {
if (input[i].entries[j].z) {
r[j].x = input[i].entries[j].x;
r[j].y = input[i].entries[j].y;
} else {
break;
}
}
output[i].n = j;
}
}
void main(void)
{
init();
update();
for (;;)
LPM4;
}
In this example, an update() function copies input data to an output storage. It is implemented with two nested for(;;) loops with a break statement in the inner loop. The outer loop iterates over arrays of 'collection' structures, each containing an array of 'entry' structures and an integer field. The inner loop iterates over the arrays of the 'entry' structure.
When compiling with loop optimizations, the optimizer generates invalid code for this update() function. The resulting assembly code uses R15 as pointer to the input data and R11 as pointer to the output area. Just after the end of the inner loop, register R15 is incremented by 2 to skip the integer field of the 'collection' structure (main.asm:192) and hence to point to the next 'collection' instance in the outer array. Everything works correctly until the inner break statement is executed (main.asm:170) because then, at the beginning of the next outer loop iteration, R15 points to the middle of the first skipped 'entry' instance instead of the beginning of the next 'collection' instance.
Target MCU: MSP430F2272
Compilation options used:
-vmsp --abi=coffabi -O3 --opt_for_speed=3 --include_path="C:/ti/ccsv5/ccs_base/msp430/include" --include_path="C:/ti/ccsv5/tools/compiler/msp430_4.1.1/include" --define=__MSP430F2272__ --diag_warning=225 --display_error_number --printf_support=minimal -k
Best regards,
Robin