lpc_asm.s
上传用户:wstnjxml
上传日期:2014-04-03
资源大小:7248k
文件大小:9k
源码类别:

Windows CE

开发平台:

C/C++

  1. #  libFLAC - Free Lossless Audio Codec library
  2. #  Copyright (C) 2004,2005  Josh Coalson
  3. #
  4. #  Redistribution and use in source and binary forms, with or without
  5. #  modification, are permitted provided that the following conditions
  6. #  are met:
  7. #
  8. #  - Redistributions of source code must retain the above copyright
  9. #  notice, this list of conditions and the following disclaimer.
  10. #
  11. #  - Redistributions in binary form must reproduce the above copyright
  12. #  notice, this list of conditions and the following disclaimer in the
  13. #  documentation and/or other materials provided with the distribution.
  14. #
  15. #  - Neither the name of the Xiph.org Foundation nor the names of its
  16. #  contributors may be used to endorse or promote products derived from
  17. #  this software without specific prior written permission.
  18. #
  19. #  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  20. #  ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  21. #  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  22. #  A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR
  23. #  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
  24. #  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
  25. #  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
  26. #  PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
  27. #  LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
  28. #  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  29. #  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  30. .text
  31. .align 2
  32. .globl _FLAC__lpc_restore_signal_asm_ppc_altivec_16
  33. .type _FLAC__lpc_restore_signal_asm_ppc_altivec_16, @function
  34. .globl _FLAC__lpc_restore_signal_asm_ppc_altivec_16_order8
  35. .type _FLAC__lpc_restore_signal_asm_ppc_altivec_16_order8, @function
  36. _FLAC__lpc_restore_signal_asm_ppc_altivec_16:
  37. # r3: residual[]
  38. # r4: data_len
  39. # r5: qlp_coeff[]
  40. # r6: order
  41. # r7: lp_quantization
  42. # r8: data[]
  43. # see src/libFLAC/lpc.c:FLAC__lpc_restore_signal()
  44. # these is a PowerPC/Altivec assembly version which requires bps<=16 (or actual
  45. # bps<=15 for mid-side coding, since that uses an extra bit)
  46. # these should be fast; the inner loop is unrolled (it takes no more than
  47. # 3*(order%4) instructions, all of which are arithmetic), and all of the
  48. # coefficients and all relevant history stay in registers, so the outer loop
  49. # has only one load from memory (the residual)
  50. # I have not yet run this through simg4, so there may be some avoidable stalls,
  51. # and there may be a somewhat more clever way to do the outer loop
  52. # the branch mechanism may prevent dynamic loading; I still need to examine
  53. # this issue, and there may be a more elegant method
  54. stmw r31,-4(r1)
  55. addi r9,r1,-28
  56. li r31,0xf
  57. andc r9,r9,r31 # for quadword-aligned stack data
  58. slwi r6,r6,2 # adjust for word size
  59. slwi r4,r4,2
  60. add r4,r4,r8 # r4 = data+data_len
  61. mfspr r0,256 # cache old vrsave
  62. addis r31,0,0xffff
  63. ori r31,r31,0xfc00
  64. mtspr 256,r31 # declare VRs in vrsave
  65. cmplw cr0,r8,r4 # i<data_len
  66. bc 4,0,L1400
  67. # load coefficients into v0-v7 and initial history into v8-v15
  68. li r31,0xf
  69. and r31,r8,r31 # r31: data%4
  70. li r11,16
  71. subf r31,r31,r11 # r31: 4-(data%4)
  72. slwi r31,r31,3 # convert to bits for vsro
  73. li r10,-4
  74. stw r31,-4(r9)
  75. lvewx v0,r10,r9
  76. vspltisb v18,-1
  77. vsro v18,v18,v0 # v18: mask vector
  78. li r31,0x8
  79. lvsl v0,0,r31
  80. vsldoi v0,v0,v0,12
  81. li r31,0xc
  82. lvsl v1,0,r31
  83. vspltisb v2,0
  84. vspltisb v3,-1
  85. vmrglw v2,v2,v3
  86. vsel v0,v1,v0,v2 # v0: reversal permutation vector
  87. add r10,r5,r6
  88. lvsl v17,0,r5 # v17: coefficient alignment permutation vector
  89. vperm v17,v17,v17,v0 # v17: reversal coefficient alignment permutation vector
  90. mr r11,r8
  91. lvsl v16,0,r11 # v16: history alignment permutation vector
  92. lvx v0,0,r5
  93. addi r5,r5,16
  94. lvx v1,0,r5
  95. vperm v0,v0,v1,v17
  96. lvx v8,0,r11
  97. addi r11,r11,-16
  98. lvx v9,0,r11
  99. vperm v8,v9,v8,v16
  100. cmplw cr0,r5,r10
  101. bc 12,0,L1101
  102. vand v0,v0,v18
  103. addis r31,0,L1307@ha
  104. ori r31,r31,L1307@l
  105. b L1199
  106. L1101:
  107. addi r5,r5,16
  108. lvx v2,0,r5
  109. vperm v1,v1,v2,v17
  110. addi r11,r11,-16
  111. lvx v10,0,r11
  112. vperm v9,v10,v9,v16
  113. cmplw cr0,r5,r10
  114. bc 12,0,L1102
  115. vand v1,v1,v18
  116. addis r31,0,L1306@ha
  117. ori r31,r31,L1306@l
  118. b L1199
  119. L1102:
  120. addi r5,r5,16
  121. lvx v3,0,r5
  122. vperm v2,v2,v3,v17
  123. addi r11,r11,-16
  124. lvx v11,0,r11
  125. vperm v10,v11,v10,v16
  126. cmplw cr0,r5,r10
  127. bc 12,0,L1103
  128. vand v2,v2,v18
  129. lis r31,L1305@ha
  130. la r31,L1305@l(r31)
  131. b L1199
  132. L1103:
  133. addi r5,r5,16
  134. lvx v4,0,r5
  135. vperm v3,v3,v4,v17
  136. addi r11,r11,-16
  137. lvx v12,0,r11
  138. vperm v11,v12,v11,v16
  139. cmplw cr0,r5,r10
  140. bc 12,0,L1104
  141. vand v3,v3,v18
  142. lis r31,L1304@ha
  143. la r31,L1304@l(r31)
  144. b L1199
  145. L1104:
  146. addi r5,r5,16
  147. lvx v5,0,r5
  148. vperm v4,v4,v5,v17
  149. addi r11,r11,-16
  150. lvx v13,0,r11
  151. vperm v12,v13,v12,v16
  152. cmplw cr0,r5,r10
  153. bc 12,0,L1105
  154. vand v4,v4,v18
  155. lis r31,L1303@ha
  156. la r31,L1303@l(r31)
  157. b L1199
  158. L1105:
  159. addi r5,r5,16
  160. lvx v6,0,r5
  161. vperm v5,v5,v6,v17
  162. addi r11,r11,-16
  163. lvx v14,0,r11
  164. vperm v13,v14,v13,v16
  165. cmplw cr0,r5,r10
  166. bc 12,0,L1106
  167. vand v5,v5,v18
  168. lis r31,L1302@ha
  169. la r31,L1302@l(r31)
  170. b L1199
  171. L1106:
  172. addi r5,r5,16
  173. lvx v7,0,r5
  174. vperm v6,v6,v7,v17
  175. addi r11,r11,-16
  176. lvx v15,0,r11
  177. vperm v14,v15,v14,v16
  178. cmplw cr0,r5,r10
  179. bc 12,0,L1107
  180. vand v6,v6,v18
  181. lis r31,L1301@ha
  182. la r31,L1301@l(r31)
  183. b L1199
  184. L1107:
  185. addi r5,r5,16
  186. lvx v19,0,r5
  187. vperm v7,v7,v19,v17
  188. addi r11,r11,-16
  189. lvx v19,0,r11
  190. vperm v15,v19,v15,v16
  191. vand v7,v7,v18
  192. lis r31,L1300@ha
  193. la r31,L1300@l(r31)
  194. L1199:
  195. mtctr r31
  196. # set up invariant vectors
  197. vspltish v16,0 # v16: zero vector
  198. li r10,-12
  199. lvsr v17,r10,r8 # v17: result shift vector
  200. lvsl v18,r10,r3 # v18: residual shift back vector
  201. li r10,-4
  202. stw r7,-4(r9)
  203. lvewx v19,r10,r9 # v19: lp_quantization vector
  204. L1200:
  205. vmulosh v20,v0,v8 # v20: sum vector
  206. bcctr 20,0
  207. L1300:
  208. vmulosh v21,v7,v15
  209. vsldoi v15,v15,v14,4 # increment history
  210. vaddsws v20,v20,v21
  211. L1301:
  212. vmulosh v21,v6,v14
  213. vsldoi v14,v14,v13,4
  214. vaddsws v20,v20,v21
  215. L1302:
  216. vmulosh v21,v5,v13
  217. vsldoi v13,v13,v12,4
  218. vaddsws v20,v20,v21
  219. L1303:
  220. vmulosh v21,v4,v12
  221. vsldoi v12,v12,v11,4
  222. vaddsws v20,v20,v21
  223. L1304:
  224. vmulosh v21,v3,v11
  225. vsldoi v11,v11,v10,4
  226. vaddsws v20,v20,v21
  227. L1305:
  228. vmulosh v21,v2,v10
  229. vsldoi v10,v10,v9,4
  230. vaddsws v20,v20,v21
  231. L1306:
  232. vmulosh v21,v1,v9
  233. vsldoi v9,v9,v8,4
  234. vaddsws v20,v20,v21
  235. L1307:
  236. vsumsws v20,v20,v16 # v20[3]: sum
  237. vsraw v20,v20,v19 # v20[3]: sum >> lp_quantization
  238. lvewx v21,0,r3 # v21[n]: *residual
  239. vperm v21,v21,v21,v18 # v21[3]: *residual
  240. vaddsws v20,v21,v20 # v20[3]: *residual + (sum >> lp_quantization)
  241. vsldoi v18,v18,v18,4 # increment shift vector
  242. vperm v21,v20,v20,v17 # v21[n]: shift for storage
  243. vsldoi v17,v17,v17,12 # increment shift vector
  244. stvewx v21,0,r8
  245. vsldoi v20,v20,v20,12
  246. vsldoi v8,v8,v20,4 # insert value onto history
  247. addi r3,r3,4
  248. addi r8,r8,4
  249. cmplw cr0,r8,r4 # i<data_len
  250. bc 12,0,L1200
  251. L1400:
  252. mtspr 256,r0 # restore old vrsave
  253. lmw r31,-4(r1)
  254. blr
  255. _FLAC__lpc_restore_signal_asm_ppc_altivec_16_order8:
  256. # r3: residual[]
  257. # r4: data_len
  258. # r5: qlp_coeff[]
  259. # r6: order
  260. # r7: lp_quantization
  261. # r8: data[]
  262. # see _FLAC__lpc_restore_signal_asm_ppc_altivec_16() above
  263. # this version assumes order<=8; it uses fewer vector registers, which should
  264. # save time in context switches, and has less code, which may improve
  265. # instruction caching
  266. stmw r31,-4(r1)
  267. addi r9,r1,-28
  268. li r31,0xf
  269. andc r9,r9,r31 # for quadword-aligned stack data
  270. slwi r6,r6,2 # adjust for word size
  271. slwi r4,r4,2
  272. add r4,r4,r8 # r4 = data+data_len
  273. mfspr r0,256 # cache old vrsave
  274. addis r31,0,0xffc0
  275. ori r31,r31,0x0000
  276. mtspr 256,r31 # declare VRs in vrsave
  277. cmplw cr0,r8,r4 # i<data_len
  278. bc 4,0,L2400
  279. # load coefficients into v0-v1 and initial history into v2-v3
  280. li r31,0xf
  281. and r31,r8,r31 # r31: data%4
  282. li r11,16
  283. subf r31,r31,r11 # r31: 4-(data%4)
  284. slwi r31,r31,3 # convert to bits for vsro
  285. li r10,-4
  286. stw r31,-4(r9)
  287. lvewx v0,r10,r9
  288. vspltisb v6,-1
  289. vsro v6,v6,v0 # v6: mask vector
  290. li r31,0x8
  291. lvsl v0,0,r31
  292. vsldoi v0,v0,v0,12
  293. li r31,0xc
  294. lvsl v1,0,r31
  295. vspltisb v2,0
  296. vspltisb v3,-1
  297. vmrglw v2,v2,v3
  298. vsel v0,v1,v0,v2 # v0: reversal permutation vector
  299. add r10,r5,r6
  300. lvsl v5,0,r5 # v5: coefficient alignment permutation vector
  301. vperm v5,v5,v5,v0 # v5: reversal coefficient alignment permutation vector
  302. mr r11,r8
  303. lvsl v4,0,r11 # v4: history alignment permutation vector
  304. lvx v0,0,r5
  305. addi r5,r5,16
  306. lvx v1,0,r5
  307. vperm v0,v0,v1,v5
  308. lvx v2,0,r11
  309. addi r11,r11,-16
  310. lvx v3,0,r11
  311. vperm v2,v3,v2,v4
  312. cmplw cr0,r5,r10
  313. bc 12,0,L2101
  314. vand v0,v0,v6
  315. lis r31,L2301@ha
  316. la r31,L2301@l(r31)
  317. b L2199
  318. L2101:
  319. addi r5,r5,16
  320. lvx v7,0,r5
  321. vperm v1,v1,v7,v5
  322. addi r11,r11,-16
  323. lvx v7,0,r11
  324. vperm v3,v7,v3,v4
  325. vand v1,v1,v6
  326. lis r31,L2300@ha
  327. la r31,L2300@l(r31)
  328. L2199:
  329. mtctr r31
  330. # set up invariant vectors
  331. vspltish v4,0 # v4: zero vector
  332. li r10,-12
  333. lvsr v5,r10,r8 # v5: result shift vector
  334. lvsl v6,r10,r3 # v6: residual shift back vector
  335. li r10,-4
  336. stw r7,-4(r9)
  337. lvewx v7,r10,r9 # v7: lp_quantization vector
  338. L2200:
  339. vmulosh v8,v0,v2 # v8: sum vector
  340. bcctr 20,0
  341. L2300:
  342. vmulosh v9,v1,v3
  343. vsldoi v3,v3,v2,4
  344. vaddsws v8,v8,v9
  345. L2301:
  346. vsumsws v8,v8,v4 # v8[3]: sum
  347. vsraw v8,v8,v7 # v8[3]: sum >> lp_quantization
  348. lvewx v9,0,r3 # v9[n]: *residual
  349. vperm v9,v9,v9,v6 # v9[3]: *residual
  350. vaddsws v8,v9,v8 # v8[3]: *residual + (sum >> lp_quantization)
  351. vsldoi v6,v6,v6,4 # increment shift vector
  352. vperm v9,v8,v8,v5 # v9[n]: shift for storage
  353. vsldoi v5,v5,v5,12 # increment shift vector
  354. stvewx v9,0,r8
  355. vsldoi v8,v8,v8,12
  356. vsldoi v2,v2,v8,4 # insert value onto history
  357. addi r3,r3,4
  358. addi r8,r8,4
  359. cmplw cr0,r8,r4 # i<data_len
  360. bc 12,0,L2200
  361. L2400:
  362. mtspr 256,r0 # restore old vrsave
  363. lmw r31,-4(r1)
  364. blr