logo elektroda
logo elektroda
X
logo elektroda
REKLAMA
REKLAMA
Adblock/uBlockOrigin/AdGuard mogą powodować znikanie niektórych postów z powodu nowej reguły.

Atmel at91sam7s256 - problem z konwersją kodu z C na ASM

krsytar 23 Sie 2007 10:37 1134 1
REKLAMA
  • #1 4206601
    krsytar
    Poziom 11  
    Napisałem funkcję obliczającą filtr FIR - 16 współczynników - w moim playerze mp3 na kontrolerze Atmel at91sam7s256. Wszystko działa super, ale po przepisaniu funkcji z C na assembler (kod w C oraz w asm poniżej) niestety nie działa poprawnie. pętla liczenia filtru dla kolejnych sampli smp_loop jest wykonywana bez przerwy, a nawet jeśli nie to i tak jedyne co słychać w sluchawkach to trzaski, zatem obliczanie filtru jest nieprawidłowe. W C natomiast działa bez zarzutu, ale jest dość powolne. Prosiłbym o informację co jest nie tak. Przyznam, że do tej pory nie pisałem jeszcze niczego na ARMach w assemblerze, zawsze wszystko w C.


    
    __attribute__ ((section (".data"))) void fir_count (short *FIRCoef, unsigned int NofSample)
    {
    //	static int FIRAcc1, FIRAcc2;
    //
    //	for (unsigned short i = 0 ; i<NofSample ; i+=2)
    //	{
    //		FIRCount = ((FIRCount-1) & 0x0f);
    //		pFIRBuf1[FIRCount] = (short)DMASBuf[i];
    //		pFIRBuf2[FIRCount] = (short)DMASBuf[i+1];
    //		FIRAcc1 = 0;
    //		FIRAcc2 = 0;
    //		for (unsigned short j = 0 ; j<16 ; j++)
    //		{
    //			FIRAcc1 += (FIRCoef[j] * pFIRBuf1[FIRCount]);
    //			FIRAcc2 += (FIRCoef[j] * pFIRBuf2[FIRCount++]);
    //			FIRCount &= 0x0f;
    //		}
    //		DMASBuf[i] = (unsigned short)(FIRAcc1>>15);
    //		DMASBuf[i+1] = (unsigned short)(FIRAcc2>>15);
    //	}
    //}
    //
    //	%0 - FIRCount, %1 - DMASBuf, %2 - pFIRBuf1, %3 - pFIRBuf2, %4 - FIRCoef,%5 - NofSample
    	asm volatile (
    		"			stmfd	r13!,{r6-r11}	;"
    		"			mov 	r6,#0			;"
    		"smp_loop:		sub 	%0,%0,#2		;"
    		"			and 	%0,%0,#0x1f		;"
    		"			ldrh	r7,[%1,r6]		;"
    		"			strh	r7,[%2,%0]		;"
    		"			add	r6,r6,#2		;"
    		"			ldrh	r7,[%1,r6]		;"
    		"			strh	r7,[%3,%0]		;"
    		"			sub	r6,r6,#2		;"
    		"			ldrsh	r10,[%4]		;"
    		"			ldrsh	r11,[%2,%0]		;"
    		"			mul	r8,r10,r11		;"
    		"			ldrsh	r11,[%3,%0]		;"
    		"			mul	r9,r10,r11		;"
    		"			add	%0,%0,#2		;"
    		"			and	%0,%0,#0x1f		;"
    		"			mov	r7,#2			;"
    		"fir_loop:		ldrsh	r10,[%4,r7]		;"
    		"			ldrsh	r11,[%2,%0]		;"
    		"			mla	r8,r10,r11,r8		;"
    		"			ldrsh	r11,[%3,%0]		;"
    		"			mla	r9,r10,r11,r9		;"
    		"			add	%0,%0,#2		;"
    		"			and	%0,%0,#0x1f		;"
    		"			add	r7,r7,#2		;"
    		"			cmp	r7,#32			;"
    		"			bne	fir_loop		;"
    		"			mov	r8,r8,ASR #15		;"
    		"			strh	r8,[%1,r6]		;"
    		"			add	r6,r6,#2		;"
    		"			mov	r9,r9,ASR #15		;"
    		"			strh	r9,[%1,r6]		;"
    		"			add	r6,r6,#2		;"
    		"			cmp	r6,%5, LSL #1		;"
    		"			bne	smp_loop		;"
    		"			ldmfd	r13!,{r6-r11}		;"
    		: "=r" (FIRCount)
    		: "0" (FIRCount), "r" (DMASBuf), "r" (pFIRBuf1), "r" (pFIRBuf2), "r" (FIRCoef), "r" (NofSample)
    		: "cc", "memory", "r6", "r7", "r8", "r9", "r10", "r11" );
    }
    
    
  • REKLAMA
  • #2 4210555
    krsytar
    Poziom 11  
    Już znalazłem błąd. Wszystko działa jak należy i jest sporo szybsze w assemblerze zgodnie z oczekiwaniem :)
REKLAMA