c_fft.s 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351
  1. .text
  2. .align 4
  3. .code 32
  4. .global c_fft
  5. /* fft not push/pop any registers,and only use r4-r9,so call it first before any other code*/
  6. .func fft_dit_reorder
  7. fft_dit_reorder:
  8. /* Rearrange the input array in bit reversed order */
  9. /* Hard code for evrc */
  10. LDR r4, =fft_64_bit_reorder_tbl
  11. LDR r5, =fft_64_bit_reorder_tbl_end
  12. .DIT_Loop:
  13. LDRD r6,r7,[r4]
  14. LDR r8,[r0,+r6]
  15. LDR r9,[r0,+r7]
  16. STR r8,[r0,+r7]
  17. STR r9,[r0,+r6]
  18. ADD r4,#8
  19. CMP r4,r5
  20. BNE .DIT_Loop
  21. BX lr
  22. .endfunc
  23. .macro call_func_r1
  24. MOV lr,pc
  25. MOV pc,r1
  26. .endm
  27. .macro fft_set_w r0,i0,r1,i1,r2,i2,r3,i3
  28. PUSH { r4,r5 }
  29. MOVW r4,\r0
  30. MOVT r4,\r1
  31. MOVW r5,\r2
  32. MOVT r5,\r3
  33. VMOV D30,r4,r5
  34. MOVW r4,\i0
  35. MOVT r4,\i1
  36. MOVW r5,\i2
  37. MOVT r5,\i3
  38. VMOV D31,r4,r5
  39. POP { r4,r5 }
  40. .endm
  41. /* Q8,Q9 is data to compute,Q0-Q7 unchanged*/
  42. fft_bfly:
  43. VTRN.16 D16,D17
  44. VTRN.16 D18,D19
  45. VTRN.32 Q8,Q9
  46. VQDMULL.S16 Q12,D18,D30 @* D30 = phs_tbl[ji]
  47. VQDMULL.S16 Q13,D19,D31 @* D31 = phs_tbl[ji+1]
  48. VQSUB.S32 Q10,Q12,Q13 @* Q10 is ftmp_real
  49. VQDMULL.S16 Q12,D19,D30
  50. VQDMULL.S16 Q13,D18,D31
  51. VQADD.S32 Q11,Q12,Q13 @* Q11 is ftmp_imag
  52. @* round32 real part Q10
  53. VQADD.S32 Q10,Q14 @* Q14 fill with 0x8000(s32)
  54. VSHRN.S32 D20,Q10,#16 @* D20 is tmp1
  55. @* round32 imag part Q11
  56. VQADD.S32 Q11,Q14
  57. VSHRN.S32 D22,Q11,#16 @* D22 is tmp2
  58. VQSUB.S16 D21,D16,D20
  59. VSHR.S16 D18,D21,#1
  60. VQSUB.S16 D21,D17,D22
  61. VSHR.S16 D19,D21,#1
  62. VQADD.S16 D16,D20
  63. VSHR.S16 D16,#1
  64. VQADD.S16 D17,D22
  65. VSHR.S16 D17,#1
  66. VTRN.16 D16,D17
  67. VTRN.16 D18,D19
  68. VTRN.32 Q8,Q9
  69. BX lr
  70. /* Q8,Q9 is data to compute,Q0-Q7 unchanged*/
  71. ifft_bfly:
  72. VTRN.16 D16,D17
  73. VTRN.16 D18,D19
  74. VTRN.32 Q8,Q9
  75. VQDMULL.S16 Q12,D18,D30 @* D30 = phs_tbl[ji]
  76. VQDMULL.S16 Q13,D19,D31 @* D31 = phs_tbl[ji+1]
  77. VQADD.S32 Q10,Q12,Q13 @* Q10 is ftmp_real
  78. VQDMULL.S16 Q12,D19,D30
  79. VQDMULL.S16 Q13,D18,D31
  80. VQSUB.S32 Q11,Q12,Q13 @* Q11 is ftmp_imag
  81. @* round32 real part Q10
  82. VQADD.S32 Q10,Q14 @* Q14 fill with 0x8000(s32)
  83. VSHRN.S32 D20,Q10,#16 @* D20 is tmp1
  84. @* round32 imag part Q11
  85. VQADD.S32 Q11,Q14
  86. VSHRN.S32 D22,Q11,#16 @* D22 is tmp2
  87. VQSUB.S16 D18,D16,D20
  88. VQSUB.S16 D19,D17,D22
  89. VQADD.S16 D16,D20
  90. VQADD.S16 D17,D22
  91. VTRN.16 D16,D17
  92. VTRN.16 D18,D19
  93. VTRN.32 Q8,Q9
  94. BX lr
  95. @* void c_fft_stageX(short* data)
  96. .func c_fft_stage0
  97. c_fft_stage0:
  98. STMFD sp!,{r4,r5,lr}
  99. MOV r4,r0
  100. ADD r5,r4,#256
  101. .STAGE0_LOOP:
  102. VLDMIA r4,{Q0,Q1,Q2,Q3}
  103. VMOV Q8,Q0
  104. VMOV Q9,Q1
  105. fft_set_w #32767,#0,#32767,#0,#32767,#0,#32767,#0
  106. call_func_r1
  107. VMOV Q0,Q8
  108. VMOV Q1,Q9
  109. VMOV Q8,Q2
  110. VMOV Q9,Q3
  111. fft_set_w #32767,#0,#32767,#0,#32767,#0,#32767,#0
  112. call_func_r1
  113. VMOV Q2,Q8
  114. VMOV Q3,Q9
  115. VSTMIA r4!,{Q0,Q1,Q2,Q3}
  116. CMP r4,r5
  117. BNE .STAGE0_LOOP
  118. LDMFD sp!,{r4,r5,pc}
  119. .endfunc
  120. .func c_fft_stage1
  121. c_fft_stage1:
  122. STMFD sp!,{r4 - r11,lr}
  123. MOV r4,r0
  124. ADD r5,r4,#256
  125. .STAGE1_LOOP:
  126. VLDMIA r4,{Q0,Q1,Q2,Q3}
  127. VTRN.32 D0,D1
  128. VTRN.32 D2,D3
  129. VMOV Q8,Q0
  130. VMOV Q9,Q1
  131. fft_set_w #32767,#0,#0,#0x8000,#32767,#0,#0,#0x8000
  132. call_func_r1
  133. VMOV Q0,Q8
  134. VMOV Q1,Q9
  135. VTRN.32 D0,D1
  136. VTRN.32 D2,D3
  137. VTRN.32 D4,D5
  138. VTRN.32 D6,D7
  139. VMOV Q8,Q2
  140. VMOV Q9,Q3
  141. fft_set_w #32767,#0,#0,#0x8000,#32767,#0,#0,#0x8000
  142. call_func_r1
  143. VMOV Q2,Q8
  144. VMOV Q3,Q9
  145. VTRN.32 D4,D5
  146. VTRN.32 D6,D7
  147. VSTMIA r4!,{Q0,Q1,Q2,Q3}
  148. CMP r4,r5
  149. BNE .STAGE1_LOOP
  150. LDMFD sp!,{r4 - r11,pc}
  151. .endfunc
  152. .func c_fft_stage2
  153. c_fft_stage2:
  154. STMFD sp!,{r4 - r11,lr}
  155. MOV r4,r0
  156. ADD r5,r4,#256
  157. .STAGE2_LOOP:
  158. VLD4.32 {D16,D17,D18,D19}, [r4]
  159. fft_set_w #0x7fff,#0,#0x5a82,#0xa57e,#0,#0x8000,#0xa57e,#0xa57e
  160. call_func_r1
  161. VST4.32 {D16,D17,D18,D19}, [r4]!
  162. CMP r4,r5
  163. BNE .STAGE2_LOOP
  164. LDMFD sp!,{r4 - r11,pc}
  165. .endfunc
  166. .func c_fft_stage3
  167. c_fft_stage3:
  168. STMFD sp!,{r4 - r11,lr}
  169. MOV r4,r0
  170. ADD r5,r4,#256
  171. .STAGE3_LOOP:
  172. VLDMIA r4,{Q0,Q1,Q2,Q3}
  173. VZIP.32 Q0,Q2
  174. VZIP.32 Q1,Q3
  175. VMOV Q8,Q0
  176. VMOV Q9,Q1
  177. fft_set_w #0x7fff,#0,#0x7642,#0xcf04,#0,#0x8000,#0xcf04,#0x89be
  178. call_func_r1
  179. VMOV Q0,Q8
  180. VMOV Q1,Q9
  181. VMOV Q8,Q2
  182. VMOV Q9,Q3
  183. fft_set_w #0x5a82,#0xa57e,#0x30fc,#0x89be,#0xa57e,#0xa57e,#0x89be,#0xcf04
  184. call_func_r1
  185. VMOV Q2,Q8
  186. VMOV Q3,Q9
  187. VUZP.32 Q0,Q2
  188. VUZP.32 Q1,Q3
  189. VSTMIA r4!,{Q0,Q1,Q2,Q3}
  190. CMP r4,r5
  191. BNE .STAGE3_LOOP
  192. LDMFD sp!,{r4 - r11,pc}
  193. .endfunc
  194. .func c_fft_stage4
  195. c_fft_stage4:
  196. STMFD sp!,{r4 - r11,lr}
  197. MOV r4,r0
  198. ADD r5,r4,#256
  199. ADD r6,r4,#64
  200. .STAGE4_LOOP:
  201. VLDMIA r4,{Q0,Q1,Q2,Q3}
  202. VLDMIA r6,{Q4,Q5,Q6,Q7}
  203. VZIP.32 Q0,Q4
  204. VMOV Q8,Q0
  205. VMOV Q9,Q4
  206. fft_set_w #0x7fff,#0,#0x7d8a,#0xe707,#0x7642,#0xcf04,#0x6a6e,#0xb8e3
  207. call_func_r1
  208. VMOV Q0,Q8
  209. VMOV Q4,Q9
  210. VUZP.32 Q0,Q4
  211. VZIP.32 Q1,Q5
  212. VMOV Q8,Q1
  213. VMOV Q9,Q5
  214. fft_set_w #0x5a82,#0xa57e,#0x471d,#0x9592,#0x30fc,#0x89be,#0x18f9,#0x8276
  215. call_func_r1
  216. VMOV Q1,Q8
  217. VMOV Q5,Q9
  218. VUZP.32 Q1,Q5
  219. VZIP.32 Q2,Q6
  220. VMOV Q8,Q2
  221. VMOV Q9,Q6
  222. fft_set_w #0x0,#0x8000,#0xe707,#0x8276,#0xcf04,#0x89be,#0xb8e3,#0x9592
  223. call_func_r1
  224. VMOV Q2,Q8
  225. VMOV Q6,Q9
  226. VUZP.32 Q2,Q6
  227. VZIP.32 Q3,Q7
  228. VMOV Q8,Q3
  229. VMOV Q9,Q7
  230. fft_set_w #0xa57e,#0xa57e,#0x9592,#0xb8e3,#0x89be,#0xcf04,#0x8276,#0xe707
  231. call_func_r1
  232. VMOV Q3,Q8
  233. VMOV Q7,Q9
  234. VUZP.32 Q3,Q7
  235. VSTMIA r4!,{Q0,Q1,Q2,Q3}
  236. VSTMIA r6!,{Q4,Q5,Q6,Q7}
  237. CMP r6,r5
  238. ADDNE r4,#64
  239. ADDNE r6,#64
  240. BNE .STAGE4_LOOP
  241. LDMFD sp!,{r4 - r11,pc}
  242. .endfunc
  243. .func c_fft_stage5
  244. c_fft_stage5:
  245. STMFD sp!,{r4 - r11,lr}
  246. MOV r4,r0
  247. ADD r5,r0,#128
  248. ADD r6,r0,#256
  249. LDR r7,=fft_stage5_phs_tbl
  250. .STAGE5_LOOP:
  251. VLDMIA r4,{Q8}
  252. VLDMIA r5,{Q9}
  253. VZIP.32 Q8,Q9
  254. VLD2.16 {D30,D31},[r7]!
  255. call_func_r1
  256. VUZP.32 Q8,Q9
  257. VSTMIA r4!,{Q8}
  258. VSTMIA r5!,{Q9}
  259. CMP r5,r6
  260. BNE .STAGE5_LOOP
  261. LDMFD sp!,{r4 - r11,pc}
  262. .endfunc
  263. .func c_fft
  264. c_fft:
  265. STMFD sp!,{r4 - r11,lr}
  266. BL fft_dit_reorder
  267. MOV r4,#0x8000
  268. VDUP.32 Q14,r4
  269. CMP r1,#1
  270. LDREQ r1,=fft_bfly
  271. LDRNE r1,=ifft_bfly
  272. BL c_fft_stage0
  273. BL c_fft_stage1
  274. BL c_fft_stage2
  275. BL c_fft_stage3
  276. BL c_fft_stage4
  277. BL c_fft_stage5
  278. LDMFD sp!,{r4 - r11,lr}
  279. BX lr
  280. .endfunc