Please forgive me if my explanation is not crystal clear, English is not my first language.
I found a probable bug in cc21k compiler regarding DAG length register handling. Take the following C *code as a example:
#include <sys/platform.h> #include <sys/adi_core.h> #include "Bug_Test_Core1.h" #include <stdio.h> int Buffer[128]; int *Buffer_Ptr1 = Buffer; int *Buffer_Ptr2 = Buffer + 10; void Func1(int *data) { printf("%d\n", *data); } void Func2(void) { int signal = 0; int phase; int *res = NULL; int *ptr = Buffer_Ptr1; while(ptr != Buffer_Ptr2) { ptr = __builtin_circptr(ptr, sizeof(int), Buffer, sizeof(Buffer)); if(!res || *ptr > *res) res = ptr; } Func1(res); } int main(void) { Func2(); return 0; }
Func2's while loop uses DAG4 for circular buffer. Looking at the assembly produced by the compiler:
Func2.: .LNFunc2.: //------------------------------------------------------------------- // Procedure statistics: // Frame size = 16 bytes // Scratch registers used: {r0-r2,r4,r12,i4,i12,b4,acc,scc} // Call preserved registers used: {i5,l4} // Registers that could be clobbered by function calls: {r0-r1,r4,r8,r12,s0-s15,i4,i6-i7,i12-i13,b4,b12-b13,m4,m12,ustat1-ustat4,acc,mcc,scc,btf,sacc,smcc,sscc,sbtf,stky,stkyy,mrf,mrb,msf,msb,lcntr,px} //------------------------------------------------------------------- // line "..\src\Bug_Test_Core1.c":16 modify(i7,-2) (nw); r4=r4-r4, r2=i5; dm(-2,i6)=r2; .LN4: // line 21 r2=dm(Buffer_Ptr1.); .LN5: // line 23 r1=dm(Buffer_Ptr2.); comp(r2,r1), i5=r4; if eq jump (pc,.P39L2); b4=Buffer.; i4=r2; l4=128; r2=leftz r4; .P39L3: //------------------------------------------------------------------- // Loop at "..\src\Bug_Test_Core1.c" line 23 col 2 //------------------------------------------------------------------- .LN6: // line 26 if sv jump (pc,.P39L4) (db); .LN7: // line 24 modify(i4,m6) (nw); r2=i4; .LN8: // line 26 r0=dm(i4,m5); r12=dm(i5,m5); comp(r12,r0); if ge jump (pc,.P39L8); .P39L4: r4=i4; .P39L8: .LN9: // line 23 comp(r1,r2); if ne jump (pc,.P39L3) (db); r2=leftz r4, i5=r4; nop; //------------------------------------------------------------------- // End Loop L3 //------------------------------------------------------------------- //------------------------------------------------------------------- // Part of top level (no loop) //------------------------------------------------------------------- .P39L2: .LN10: // line 30 cjump Func1. (db); dm(i7,m7)=r2; dm(i7,m7)=.LCJ1-1; .LCJ1: .LN11: // line 31 i12=dm(m7,i6); // -- 6 stalls -- jump (m14,i12) (db); i5=dm(-2,i6); rframe; .LN.Func2..end: .Func2..end: .global Func2.; .type Func2.,STT_FUNC;
the L4 register is set to 128 (line 25), but never set back to 0. If you break the C code at line 12 or 37, the L4 register is set to 128 instead of 0 as it should be.
Am I missing some detail or is this a bug in the compiler?
Added sample project.
[edited by: GTBosco at 1:20 PM (GMT -4) on 26 Sep 2022]