One of the developers here has come across a problem with the following (simplified) code snippet:
while((Index = GetIndexInBitField(aEnabledBitfield)) < MAX_NUM_INDICES) { pThisParams = &(CtrlParams->aParam[ Index ]); pThisParams->pCtrlAddr = GetBuffAddr(Absolute, 0); /* asm(" NOP 1"); */ pThisParams->pCtrlAddr->Index = 10; }
GetIndexInBitField() is an inline function that included a loop. pThisParams->pCtrlAddr is NULL before this loop and GetBuffAddr() returns a non-NULL value. As shown, the last line triggers a memory protection fault with the FAR being 0x00000000. If the commented out asm statement is included, the code runs normally.
Looking at the assembler produced in the faulting case, the issue seems clear: the code is reading the contents of pThisParams->pCtrlAddr before it is being written. Putting the asm statement in the way forces the compiler to complete the write before the line is inserted and doesn't read it until afterwards.
[...]
$C$RL70: ; CALL OCCURS {GetBuffAddr} {0} ; |1568|
$C$DW$L$ulc_FgrCtrl$74$E:
;** --------------------------------------------------------------------------*
$C$DW$L$ulc_FgrCtrl$75$B:
; EXCLUSIVE CPU CYCLES: 14
MVK .S1 148,A3 ; |1568|
MPY32 .M1 A3,A11,A5 ; |1568|
MVKL .S2 ControlParams,B4
MVKH .S2 ControlParams,B4
MVKL .S1 ControlParams,A31
MVKH .S1 ControlParams,A31
ADD .L2X A5,B4,B4 ; |1572|
ADDK .S2 192,B4 ; |1572|
LDW .D2T2 *B4,B5 ; |1572| <-- Loads pThisParams->pCtrlAddr from memory *** before it has been updated *** => this will read NULL (0x0)
ADD .L1 A31,A5,A3 ; |1568|
MVK .L2 10,B7 ; |1572|
MVK .S2 0x10,B30 ; |190|
ADDAW .D2 SP,110,B31
STW .D2T2 B7,*B5 ; |1572| <-- Writes to address read above => Memory protection fault
|| SUB .L2 B30,2,B7
|| ADDK .S1 192,A3 ; |1568|
|| MVC .S2 B30,RILC
$C$DW$L$ulc_FgrCtrl$75$E:
;*----------------------------------------------------------------------------*
;* SOFTWARE PIPELINE INFORMATION
[...]
;*----------------------------------------------------------------------------*
$C$L73: ; PIPED LOOP PROLOG
; EXCLUSIVE CPU CYCLES: 7
.dwpsn file "ctrl_utils.h",line 190,column 0,is_stmt,isa 0
SPLOOPD 2 ;8 ; (P)
|| STW .D1T1 A4,*A3 ; |1568| <-- Writes pointer returned by GetBuffAddr to memory... too late
|| ADD .L2 8,B31,B5
|| MVC .S2 B7,ILC
;** --------------------------------------------------------------------------*
$C$L74: ; PIPED LOOP KERNEL
[...]
I've spent a couple of hours trying the reproduce this without requiring our codebase and have not been able to. However, if there are any questions that I can answer to help you resolve this issue, please let me know. In the meantime, I've been able to refactor the loop body to get the compiler to produce correct code...
Regards,
SPH