Hi,
I am working on porting FFT functionality from CMSIS DSP library to another architecture.Unfortunate I faced with problem that arm_bitreversal_32 function is implemented in assembler.
Does any body tried to convert it to C code?
Hello,
I cannot access the assembly source code of the arm_bitreversal_32 as of now.I re-wrote it by C as referring the below.
http://www.stargate-tr.com/post/102141475474/arm-cmsis-dsp-software-library-complex-fft
(1) original code.
.syntax unified .thumb .global sg_bitreversal_32 sg_bitreversal_32: ADDS r3,r1,#1 CMP r3,#1 IT LS BXLS lr PUSH {r4-r9} ADDS r1,r2,#2 LSRS r3,r3,#2 sg_bitreversal_32_0: LDRH r8,[r1,#4] LDRH r9,[r1,#2] LDRH r2,[r1,#0] LDRH r12,[r1,#-2] ADD r8,r0,r8 ADD r9,r0,r9 ADD r2,r0,r2 ADD r12,r0,r12 LDR r7,[r9,#0] LDR r6,[r8,#0] LDR r5,[r2,#0] LDR r4,[r12,#0] STR r6,[r9,#0] STR r7,[r8,#0] STR r5,[r12,#0] STR r4,[r2,#0] LDR r7,[r9,#4] LDR r6,[r8,#4] LDR r5,[r2,#4] LDR r4,[r12,#4] STR r6,[r9,#4] STR r7,[r8,#4] STR r5,[r12,#4] STR r4,[r2,#4] ADDS r1,r1,#8 SUBS r3,r3,#1 BNE sg_bitreversal_32_0 POP {r4-r9} BX lr
(2) re-written C code.
void arm_bitreversal_32 (uint32_t * pSrc, const uint16_t bitRevLen, const uint16_t * pBitRevTable) { uint32_t r7,r6,r5,r4,r3; if (bitRevLen <= 0) return; r3 = (bitRevLen >> 2); while (r3 >= 0) { r7 = pSrc[pBitRevTable[3]]; r6 = pSrc[pBitRevTable[2]]; r5 = pSrc[pBitRevTable[1]]; r4 = pSrc[pBitRevTable[0]]; pSrc[pBitRevTable[3]] = r6; pSrc[pBitRevTable[2]] = r7; pSrc[pBitRevTable[1]] = r4; pSrc[pBitRevTable[0]] = r5; r7 = pSrc[pBitRevTable[3] + 1]; r6 = pSrc[pBitRevTable[2] + 1]; r5 = pSrc[pBitRevTable[1] + 1]; r4 = pSrc[pBitRevTable[0] + 1]; pSrc[pBitRevTable[3] + 1] = r6; pSrc[pBitRevTable[2] + 1] = r7; pSrc[pBitRevTable[1] + 1] = r4; pSrc[pBitRevTable[0] + 1] = r5; pBitRevTable += 4; r3--; } }
Although I don't know the functional specification of the arm_bitreversal_32, I think I could interpret it well.
However, there might be some bugs.I hope someone correct my code properly.
Best regards,
Yasuhiko Koumoto.
I'm sorry that the C code was not eqivalent to the original code.
The below is the corrected version.
Yasuhilko Koumoto.
void arm_bitreversal_32 (uint32_t * pSrc, const uint16_t bitRevLen, const uint16_t * pBitRevTable) { uint32_t r7,r6,r5,r4,r3; if (bitRevLen <= 0) return; r3 = ((bitRevLen + 1) >> 2); while (r3 > 0) { r7 = pSrc[(pBitRevTable[3]>>2)]; r6 = pSrc[(pBitRevTable[2]>>2)]; r5 = pSrc[(pBitRevTable[1]>>2)]; r4 = pSrc[(pBitRevTable[0]>>2)]; pSrc[(pBitRevTable[3]>>2)] = r6; pSrc[(pBitRevTable[2]>>2)] = r7; pSrc[(pBitRevTable[1]>>2)] = r4; pSrc[(pBitRevTable[0]>>2)] = r5; r7 = pSrc[(pBitRevTable[3]>>2) + 1]; r6 = pSrc[(pBitRevTable[2]>>2) + 1]; r5 = pSrc[(pBitRevTable[1]>>2) + 1]; r4 = pSrc[(pBitRevTable[0]>>2) + 1]; pSrc[(pBitRevTable[3]>>2) + 1] = r6; pSrc[(pBitRevTable[2]>>2) + 1] = r7; pSrc[(pBitRevTable[1]>>2) + 1] = r4; pSrc[(pBitRevTable[0]>>2) + 1] = r5; pBitRevTable += 4; r3--; } }
I'm very sorry. I revised the code again.
This revision would be identical to the original.
Best regards.
void arm_bitreversal_32 (uint32_t * pSrc, const uint16_t bitRevLen, const uint16_t * pBitRevTable) { uint32_t r7,r6,r5,r4,r3; if (bitRevLen <= 0) return; r3 = ((bitRevLen+1) >> 2); while (r3 > 0) { r7 = *(uint32_t*)((uint8_t*) pSrc + pBitRevTable[3]); r6 = *(uint32_t*)((uint8_t*) pSrc + pBitRevTable[2]); r5 = *(uint32_t*)((uint8_t*) pSrc + pBitRevTable[1]); r4 = *(uint32_t*)((uint8_t*) pSrc + pBitRevTable[0]); *(uint32_t*)((uint8_t*) pSrc + pBitRevTable[3]) = r6; *(uint32_t*)((uint8_t*) pSrc + pBitRevTable[2]) = r7; *(uint32_t*)((uint8_t*) pSrc + pBitRevTable[1]) = r4; *(uint32_t*)((uint8_t*) pSrc + pBitRevTable[0]) = r5; r7 = *(uint32_t*)((uint8_t*) pSrc + pBitRevTable[3] + 4); r6 = *(uint32_t*)((uint8_t*) pSrc + pBitRevTable[2] + 4); r5 = *(uint32_t*)((uint8_t*) pSrc + pBitRevTable[1] + 4); r4 = *(uint32_t*)((uint8_t*) pSrc + pBitRevTable[0] + 4); *(uint32_t*)((uint8_t*) pSrc + pBitRevTable[3] + 4) = r6; *(uint32_t*)((uint8_t*) pSrc + pBitRevTable[2] + 4) = r7; *(uint32_t*)((uint8_t*) pSrc + pBitRevTable[1] + 4) = r4; *(uint32_t*)((uint8_t*) pSrc + pBitRevTable[0] + 4) = r5; pBitRevTable += 4; r3--; } }
Thank you for all your assistance.
BR,
Iurii
If you'd like other strange ways of doing this plus a number of other hacks in C try
Bit Twiddling Hacks
I feel a bit like I'm a drug peddler pushing that!