We are running a survey to help us improve the experience for all of our members. If you see the survey appear, please take the time to tell us about your experience if you can.
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!