This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Convert arm_bitreversal2.S file to c code

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.

  • Hello,

    I'm sorry that the C code was not eqivalent to the original code.

    The below is the corrected version.

    Best regards,

    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--;
        }
    }
    
  • Hello,

    I'm very sorry. I revised the code again.

    This revision would be identical to the original.

    Best regards.

    Yasuhiko 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 = *(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--;
        }
    }
    
  • Hello,

    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!