Hi,
we have encountered a problem with the operator '+='. This is a problem that we have seen 4 times in different places in our code. Each time the problem is the same. The expression is calculated but the addition to the destination parm never takes place. There are two code examples pasted below including the compiled code. The first show a failing version and the second a working solution.
We using the TM4C129DNCPDT with the compiler version 'TI v5.0.4'. If needed I can post additional information about installed modules.
All affected files are C files, so perhaps this bug is related to the C compiler only.
I have tried to search for assignment operater bugs, but have not found any match. But this being such a frequently occurring bug (for us at least) I seriously doubt that no one has encountered it before.
Has anyone run into this bug before?
Has it been solved a newer compiler release?
As we are getting close to finalizing our project we only want to change compiler if there is a good reason to do so. But this being a rather serious issue we need to collect sufficient information to evaluate whether we should upgrade or not.
Kind regards,
Christian
/************************************************************************** Failing: -------- The function below fails in the way that the variable 'uSecCnt' does not get updated. The returned value is always the same. The expressions are calculated correctly but the result is never added to 'uSecCnt'. **************************************************************************/ uint32_t HalTimerUsGet() { // Set the timer to wrap after 1 min. to facilitate check of code) static uint32_t uSecCnt = (uint32_t)(~0 - (60 * 1000 * 1000)); static uint32_t lastTicks = ~0; uint32_t ticks; HalIrqStat_t iState; iState = HalIrqDisable(); ticks = TimerValueGet(TIMER4_BASE, TIMER_A); if (ticks > lastTicks) { // timer wrap, 35.8 more sec passed uSecCnt += (lastTicks - (int32_t)ticks) * CPU_MHZ_INV; } else { uSecCnt += (lastTicks - ticks) * CPU_MHZ_INV; } lastTicks = ticks; HalIrqRestore(iState); return uSecCnt; }
114 {
HalTimerUsGet:
000596d6: B50E PUSH {R1, R2, R3, LR}
121 iState = HalIrqDisable();
000596d8: F00CFB8D BL HalIrqDisable
000596dc: F88D0004 STRB.W R0, [R13, #4]
123 ticks = TimerValueGet(TIMER4_BASE, TIMER_A);
000596e0: 4866 LDR R0, $C$CON4
000596e2: 21FF MOV R1, #0xFF
000596e4: F014F816 BL TimerValueGet
000596e8: 9000 STR R0, [SP]
125 if (ticks > lastTicks)
000596ea: 4865 LDR R0, $C$CON9
000596ec: 9900 LDR R1, [SP]
000596ee: 6800 LDR R0, [R0]
000596f0: 4288 CMP R0, R1
000596f2: D217 BCS $C$L2
128 uSecCnt += (lastTicks - (int32_t)ticks) * CPU_MHZ_INV;
000596f4: 4862 LDR R0, $C$CON9
000596f6: 4963 LDR R1, $C$CON10
000596f8: 9A00 LDR R2, [SP]
000596fa: 6800 LDR R0, [R0]
000596fc: EDD10A00 FLDS S1, [R1, #0]
00059700: 1A80 SUB R0, R0, R2
00059702: EE000A10 FMSR S0, R0
00059706: 4860 LDR R0, $C$CON11
00059708: ED901A00 FLDS S2, [R0, #0]
0005970c: EEB80A40 FUITOS S0, S0
00059710: EEF80A60 FUITOS S1, S1
00059714: EE410A00 FMACS S1, S2, S0
00059718: EEBC0AE0 FTOUIZS S0, S1
0005971c: EE100A10 FMRS R0, S0
00059720: 6008 STR R0, [R1]
129 }
00059722: E016 B $C$L3
132 uSecCnt += (lastTicks - ticks) * CPU_MHZ_INV;
$C$L2:
00059724: 4856 LDR R0, $C$CON9
00059726: 4957 LDR R1, $C$CON10
00059728: 9A00 LDR R2, [SP]
0005972a: 6800 LDR R0, [R0]
0005972c: EDD10A00 FLDS S1, [R1, #0]
00059730: 1A80 SUB R0, R0, R2
00059732: EE000A10 FMSR S0, R0
00059736: 4854 LDR R0, $C$CON11
00059738: ED901A00 FLDS S2, [R0, #0]
0005973c: EEB80A40 FUITOS S0, S0
00059740: EEF80A60 FUITOS S1, S1
00059744: EE410A00 FMACS S1, S2, S0
00059748: EEBC0AE0 FTOUIZS S0, S1
0005974c: EE100A10 FMRS R0, S0
00059750: 6008 STR R0, [R1]
134 lastTicks = ticks;
$C$L3:
00059752: 9800 LDR R0, [SP]
00059754: 494A LDR R1, $C$CON9
00059756: 6008 STR R0, [R1]
136 HalIrqRestore(iState);
00059758: F89D0004 LDRB.W R0, [R13, #4]
0005975c: F00CFB60 BL HalIrqRestore
138 return uSecCnt;
00059760: 4848 LDR R0, $C$CON10
00059762: 6800 LDR R0, [R0]
139 }
00059764: BD0E POP {R1, R2, R3, PC}
/**************************************************************************
Working solution:
By changing the assignment operator and storing the result in a temporary
variable first, the function now works correctly and the parameter 'uSecCnt'
gets updated correctly.
**************************************************************************/
uint32_t HalTimerUsGet()
{
// Set the timer to wrap after 1 min. to facilitate check of code)
static uint32_t uSecCnt = (uint32_t)(~0 - (60 * 1000 * 1000));
static uint32_t lastTicks = ~0;
uint32_t ticks;
uint32_t elapsed;
HalIrqStat_t iState;
iState = HalIrqDisable();
ticks = TimerValueGet(TIMER4_BASE, TIMER_A);
if (ticks > lastTicks)
{
// timer wrap, 35.8 more sec passed
elapsed = (lastTicks - (int32_t)ticks) * CPU_MHZ_INV;
}
else
{
elapsed = (lastTicks - ticks) * CPU_MHZ_INV;
}
uSecCnt += elapsed;
lastTicks = ticks;
HalIrqRestore(iState);
return uSecCnt;
}
114 {
HalTimerUsGet:
0005a51a: B50E PUSH {R1, R2, R3, LR}
122 iState = HalIrqDisable();
0005a51c: F00CF84B BL HalIrqDisable
0005a520: F88D0008 STRB.W R0, [R13, #8]
124 ticks = TimerValueGet(TIMER4_BASE, TIMER_A);
0005a524: 4864 LDR R0, $C$CON4
0005a526: 21FF MOV R1, #0xFF
0005a528: F013FD5C BL TimerValueGet
0005a52c: 9000 STR R0, [SP]
126 if (ticks > lastTicks)
0005a52e: 4863 LDR R0, $C$CON9
0005a530: 9900 LDR R1, [SP]
0005a532: 6800 LDR R0, [R0]
0005a534: 4288 CMP R0, R1
0005a536: D212 BCS $C$L2
129 elapsed = (lastTicks - (int32_t)ticks) * CPU_MHZ_INV;
0005a538: 4860 LDR R0, $C$CON9
0005a53a: 9900 LDR R1, [SP]
0005a53c: 6800 LDR R0, [R0]
0005a53e: 1A40 SUB R0, R0, R1
0005a540: EE000A10 FMSR S0, R0
0005a544: 485E LDR R0, $C$CON10
0005a546: EDD00A00 FLDS S1, [R0, #0]
0005a54a: EEB80A40 FUITOS S0, S0
0005a54e: EE200A80 FMULS S0, S1, S0
0005a552: EEBC0AC0 FTOUIZS S0, S0
0005a556: EE100A10 FMRS R0, S0
0005a55a: 9001 STR R0, [SP, #0x4]
130 }
0005a55c: E011 B $C$L3
133 elapsed = (lastTicks - ticks) * CPU_MHZ_INV;
$C$L2:
0005a55e: 4857 LDR R0, $C$CON9
0005a560: 9900 LDR R1, [SP]
0005a562: 6800 LDR R0, [R0]
0005a564: 1A40 SUB R0, R0, R1
0005a566: EE000A10 FMSR S0, R0
0005a56a: 4855 LDR R0, $C$CON10
0005a56c: EDD00A00 FLDS S1, [R0, #0]
0005a570: EEB80A40 FUITOS S0, S0
0005a574: EE200A80 FMULS S0, S1, S0
0005a578: EEBC0AC0 FTOUIZS S0, S0
0005a57c: EE100A10 FMRS R0, S0
0005a580: 9001 STR R0, [SP, #0x4]
135 uSecCnt += elapsed;
$C$L3:
0005a582: 4950 LDR R1, $C$CON11
0005a584: 9801 LDR R0, [SP, #0x4]
0005a586: 680A LDR R2, [R1]
0005a588: 1880 ADD R0, R0, R2
0005a58a: 6008 STR R0, [R1]
136 lastTicks = ticks;
0005a58c: 9800 LDR R0, [SP]
0005a58e: 494B LDR R1, $C$CON9
0005a590: 6008 STR R0, [R1]
138 HalIrqRestore(iState);
0005a592: F89D0008 LDRB.W R0, [R13, #8]
0005a596: F00CF823 BL HalIrqRestore
140 return uSecCnt;
0005a59a: 484A LDR R0, $C$CON11
0005a59c: 6800 LDR R0, [R0]
141 }
0005a59e: BD0E POP {R1, R2, R3, PC}