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

Windows CE

开发平台:

C/C++

  1. ;  libFLAC - Free Lossless Audio Codec library
  2. ;  Copyright (C) 2001,2002,2003,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. %include "nasm.h"
  31. data_section
  32. cglobal FLAC__lpc_compute_autocorrelation_asm_ia32
  33. cglobal FLAC__lpc_compute_autocorrelation_asm_ia32_sse_lag_4
  34. cglobal FLAC__lpc_compute_autocorrelation_asm_ia32_sse_lag_8
  35. cglobal FLAC__lpc_compute_autocorrelation_asm_ia32_sse_lag_12
  36. cglobal FLAC__lpc_compute_autocorrelation_asm_ia32_3dnow
  37. cglobal FLAC__lpc_compute_residual_from_qlp_coefficients_asm_ia32
  38. cglobal FLAC__lpc_compute_residual_from_qlp_coefficients_asm_ia32_mmx
  39. cglobal FLAC__lpc_restore_signal_asm_ia32
  40. cglobal FLAC__lpc_restore_signal_asm_ia32_mmx
  41. code_section
  42. ; **********************************************************************
  43. ;
  44. ; void FLAC__lpc_compute_autocorrelation_asm(const FLAC__real data[], unsigned data_len, unsigned lag, FLAC__real autoc[])
  45. ; {
  46. ; FLAC__real d;
  47. ; unsigned sample, coeff;
  48. ; const unsigned limit = data_len - lag;
  49. ;
  50. ; FLAC__ASSERT(lag > 0);
  51. ; FLAC__ASSERT(lag <= data_len);
  52. ;
  53. ; for(coeff = 0; coeff < lag; coeff++)
  54. ; autoc[coeff] = 0.0;
  55. ; for(sample = 0; sample <= limit; sample++) {
  56. ; d = data[sample];
  57. ; for(coeff = 0; coeff < lag; coeff++)
  58. ; autoc[coeff] += d * data[sample+coeff];
  59. ; }
  60. ; for(; sample < data_len; sample++) {
  61. ; d = data[sample];
  62. ; for(coeff = 0; coeff < data_len - sample; coeff++)
  63. ; autoc[coeff] += d * data[sample+coeff];
  64. ; }
  65. ; }
  66. ;
  67. ALIGN 16
  68. cident FLAC__lpc_compute_autocorrelation_asm_ia32
  69. ;[esp + 28] == autoc[]
  70. ;[esp + 24] == lag
  71. ;[esp + 20] == data_len
  72. ;[esp + 16] == data[]
  73. ;ASSERT(lag > 0)
  74. ;ASSERT(lag <= 33)
  75. ;ASSERT(lag <= data_len)
  76. .begin:
  77. push esi
  78. push edi
  79. push ebx
  80. ; for(coeff = 0; coeff < lag; coeff++)
  81. ; autoc[coeff] = 0.0;
  82. mov edi, [esp + 28] ; edi == autoc
  83. mov ecx, [esp + 24] ; ecx = # of dwords (=lag) of 0 to write
  84. xor eax, eax
  85. rep stosd
  86. ; const unsigned limit = data_len - lag;
  87. mov eax, [esp + 24] ; eax == lag
  88. mov ecx, [esp + 20]
  89. sub ecx, eax ; ecx == limit
  90. mov edi, [esp + 28] ; edi == autoc
  91. mov esi, [esp + 16] ; esi == data
  92. inc ecx ; we are looping <= limit so we add one to the counter
  93. ; for(sample = 0; sample <= limit; sample++) {
  94. ; d = data[sample];
  95. ; for(coeff = 0; coeff < lag; coeff++)
  96. ; autoc[coeff] += d * data[sample+coeff];
  97. ; }
  98. fld dword [esi] ; ST = d <- data[sample]
  99. ; each iteration is 11 bytes so we need (-eax)*11, so we do (-12*eax + eax)
  100. lea edx, [eax + eax*2]
  101. neg edx
  102. lea edx, [eax + edx*4 + .jumper1_0 - .get_eip1]
  103. call .get_eip1
  104. .get_eip1:
  105. pop ebx
  106. add edx, ebx
  107. inc edx ; compensate for the shorter opcode on the last iteration
  108. inc edx ; compensate for the shorter opcode on the last iteration
  109. inc edx ; compensate for the shorter opcode on the last iteration
  110. cmp eax, 33
  111. jne .loop1_start
  112. sub edx, byte 9 ; compensate for the longer opcodes on the first iteration
  113. .loop1_start:
  114. jmp edx
  115. fld st0 ; ST = d d
  116. fmul dword [esi + (32*4)] ; ST = d*data[sample+32] d WATCHOUT: not a byte displacement here!
  117. fadd dword [edi + (32*4)] ; ST = autoc[32]+d*data[sample+32] d WATCHOUT: not a byte displacement here!
  118. fstp dword [edi + (32*4)] ; autoc[32]+=d*data[sample+32]  ST = d WATCHOUT: not a byte displacement here!
  119. fld st0 ; ST = d d
  120. fmul dword [esi + (31*4)] ; ST = d*data[sample+31] d
  121. fadd dword [edi + (31*4)] ; ST = autoc[31]+d*data[sample+31] d
  122. fstp dword [edi + (31*4)] ; autoc[31]+=d*data[sample+31]  ST = d
  123. fld st0 ; ST = d d
  124. fmul dword [esi + (30*4)] ; ST = d*data[sample+30] d
  125. fadd dword [edi + (30*4)] ; ST = autoc[30]+d*data[sample+30] d
  126. fstp dword [edi + (30*4)] ; autoc[30]+=d*data[sample+30]  ST = d
  127. fld st0 ; ST = d d
  128. fmul dword [esi + (29*4)] ; ST = d*data[sample+29] d
  129. fadd dword [edi + (29*4)] ; ST = autoc[29]+d*data[sample+29] d
  130. fstp dword [edi + (29*4)] ; autoc[29]+=d*data[sample+29]  ST = d
  131. fld st0 ; ST = d d
  132. fmul dword [esi + (28*4)] ; ST = d*data[sample+28] d
  133. fadd dword [edi + (28*4)] ; ST = autoc[28]+d*data[sample+28] d
  134. fstp dword [edi + (28*4)] ; autoc[28]+=d*data[sample+28]  ST = d
  135. fld st0 ; ST = d d
  136. fmul dword [esi + (27*4)] ; ST = d*data[sample+27] d
  137. fadd dword [edi + (27*4)] ; ST = autoc[27]+d*data[sample+27] d
  138. fstp dword [edi + (27*4)] ; autoc[27]+=d*data[sample+27]  ST = d
  139. fld st0 ; ST = d d
  140. fmul dword [esi + (26*4)] ; ST = d*data[sample+26] d
  141. fadd dword [edi + (26*4)] ; ST = autoc[26]+d*data[sample+26] d
  142. fstp dword [edi + (26*4)] ; autoc[26]+=d*data[sample+26]  ST = d
  143. fld st0 ; ST = d d
  144. fmul dword [esi + (25*4)] ; ST = d*data[sample+25] d
  145. fadd dword [edi + (25*4)] ; ST = autoc[25]+d*data[sample+25] d
  146. fstp dword [edi + (25*4)] ; autoc[25]+=d*data[sample+25]  ST = d
  147. fld st0 ; ST = d d
  148. fmul dword [esi + (24*4)] ; ST = d*data[sample+24] d
  149. fadd dword [edi + (24*4)] ; ST = autoc[24]+d*data[sample+24] d
  150. fstp dword [edi + (24*4)] ; autoc[24]+=d*data[sample+24]  ST = d
  151. fld st0 ; ST = d d
  152. fmul dword [esi + (23*4)] ; ST = d*data[sample+23] d
  153. fadd dword [edi + (23*4)] ; ST = autoc[23]+d*data[sample+23] d
  154. fstp dword [edi + (23*4)] ; autoc[23]+=d*data[sample+23]  ST = d
  155. fld st0 ; ST = d d
  156. fmul dword [esi + (22*4)] ; ST = d*data[sample+22] d
  157. fadd dword [edi + (22*4)] ; ST = autoc[22]+d*data[sample+22] d
  158. fstp dword [edi + (22*4)] ; autoc[22]+=d*data[sample+22]  ST = d
  159. fld st0 ; ST = d d
  160. fmul dword [esi + (21*4)] ; ST = d*data[sample+21] d
  161. fadd dword [edi + (21*4)] ; ST = autoc[21]+d*data[sample+21] d
  162. fstp dword [edi + (21*4)] ; autoc[21]+=d*data[sample+21]  ST = d
  163. fld st0 ; ST = d d
  164. fmul dword [esi + (20*4)] ; ST = d*data[sample+20] d
  165. fadd dword [edi + (20*4)] ; ST = autoc[20]+d*data[sample+20] d
  166. fstp dword [edi + (20*4)] ; autoc[20]+=d*data[sample+20]  ST = d
  167. fld st0 ; ST = d d
  168. fmul dword [esi + (19*4)] ; ST = d*data[sample+19] d
  169. fadd dword [edi + (19*4)] ; ST = autoc[19]+d*data[sample+19] d
  170. fstp dword [edi + (19*4)] ; autoc[19]+=d*data[sample+19]  ST = d
  171. fld st0 ; ST = d d
  172. fmul dword [esi + (18*4)] ; ST = d*data[sample+18] d
  173. fadd dword [edi + (18*4)] ; ST = autoc[18]+d*data[sample+18] d
  174. fstp dword [edi + (18*4)] ; autoc[18]+=d*data[sample+18]  ST = d
  175. fld st0 ; ST = d d
  176. fmul dword [esi + (17*4)] ; ST = d*data[sample+17] d
  177. fadd dword [edi + (17*4)] ; ST = autoc[17]+d*data[sample+17] d
  178. fstp dword [edi + (17*4)] ; autoc[17]+=d*data[sample+17]  ST = d
  179. fld st0 ; ST = d d
  180. fmul dword [esi + (16*4)] ; ST = d*data[sample+16] d
  181. fadd dword [edi + (16*4)] ; ST = autoc[16]+d*data[sample+16] d
  182. fstp dword [edi + (16*4)] ; autoc[16]+=d*data[sample+16]  ST = d
  183. fld st0 ; ST = d d
  184. fmul dword [esi + (15*4)] ; ST = d*data[sample+15] d
  185. fadd dword [edi + (15*4)] ; ST = autoc[15]+d*data[sample+15] d
  186. fstp dword [edi + (15*4)] ; autoc[15]+=d*data[sample+15]  ST = d
  187. fld st0 ; ST = d d
  188. fmul dword [esi + (14*4)] ; ST = d*data[sample+14] d
  189. fadd dword [edi + (14*4)] ; ST = autoc[14]+d*data[sample+14] d
  190. fstp dword [edi + (14*4)] ; autoc[14]+=d*data[sample+14]  ST = d
  191. fld st0 ; ST = d d
  192. fmul dword [esi + (13*4)] ; ST = d*data[sample+13] d
  193. fadd dword [edi + (13*4)] ; ST = autoc[13]+d*data[sample+13] d
  194. fstp dword [edi + (13*4)] ; autoc[13]+=d*data[sample+13]  ST = d
  195. fld st0 ; ST = d d
  196. fmul dword [esi + (12*4)] ; ST = d*data[sample+12] d
  197. fadd dword [edi + (12*4)] ; ST = autoc[12]+d*data[sample+12] d
  198. fstp dword [edi + (12*4)] ; autoc[12]+=d*data[sample+12]  ST = d
  199. fld st0 ; ST = d d
  200. fmul dword [esi + (11*4)] ; ST = d*data[sample+11] d
  201. fadd dword [edi + (11*4)] ; ST = autoc[11]+d*data[sample+11] d
  202. fstp dword [edi + (11*4)] ; autoc[11]+=d*data[sample+11]  ST = d
  203. fld st0 ; ST = d d
  204. fmul dword [esi + (10*4)] ; ST = d*data[sample+10] d
  205. fadd dword [edi + (10*4)] ; ST = autoc[10]+d*data[sample+10] d
  206. fstp dword [edi + (10*4)] ; autoc[10]+=d*data[sample+10]  ST = d
  207. fld st0 ; ST = d d
  208. fmul dword [esi + ( 9*4)] ; ST = d*data[sample+9] d
  209. fadd dword [edi + ( 9*4)] ; ST = autoc[9]+d*data[sample+9] d
  210. fstp dword [edi + ( 9*4)] ; autoc[9]+=d*data[sample+9]  ST = d
  211. fld st0 ; ST = d d
  212. fmul dword [esi + ( 8*4)] ; ST = d*data[sample+8] d
  213. fadd dword [edi + ( 8*4)] ; ST = autoc[8]+d*data[sample+8] d
  214. fstp dword [edi + ( 8*4)] ; autoc[8]+=d*data[sample+8]  ST = d
  215. fld st0 ; ST = d d
  216. fmul dword [esi + ( 7*4)] ; ST = d*data[sample+7] d
  217. fadd dword [edi + ( 7*4)] ; ST = autoc[7]+d*data[sample+7] d
  218. fstp dword [edi + ( 7*4)] ; autoc[7]+=d*data[sample+7]  ST = d
  219. fld st0 ; ST = d d
  220. fmul dword [esi + ( 6*4)] ; ST = d*data[sample+6] d
  221. fadd dword [edi + ( 6*4)] ; ST = autoc[6]+d*data[sample+6] d
  222. fstp dword [edi + ( 6*4)] ; autoc[6]+=d*data[sample+6]  ST = d
  223. fld st0 ; ST = d d
  224. fmul dword [esi + ( 5*4)] ; ST = d*data[sample+4] d
  225. fadd dword [edi + ( 5*4)] ; ST = autoc[4]+d*data[sample+4] d
  226. fstp dword [edi + ( 5*4)] ; autoc[4]+=d*data[sample+4]  ST = d
  227. fld st0 ; ST = d d
  228. fmul dword [esi + ( 4*4)] ; ST = d*data[sample+4] d
  229. fadd dword [edi + ( 4*4)] ; ST = autoc[4]+d*data[sample+4] d
  230. fstp dword [edi + ( 4*4)] ; autoc[4]+=d*data[sample+4]  ST = d
  231. fld st0 ; ST = d d
  232. fmul dword [esi + ( 3*4)] ; ST = d*data[sample+3] d
  233. fadd dword [edi + ( 3*4)] ; ST = autoc[3]+d*data[sample+3] d
  234. fstp dword [edi + ( 3*4)] ; autoc[3]+=d*data[sample+3]  ST = d
  235. fld st0 ; ST = d d
  236. fmul dword [esi + ( 2*4)] ; ST = d*data[sample+2] d
  237. fadd dword [edi + ( 2*4)] ; ST = autoc[2]+d*data[sample+2] d
  238. fstp dword [edi + ( 2*4)] ; autoc[2]+=d*data[sample+2]  ST = d
  239. fld st0 ; ST = d d
  240. fmul dword [esi + ( 1*4)] ; ST = d*data[sample+1] d
  241. fadd dword [edi + ( 1*4)] ; ST = autoc[1]+d*data[sample+1] d
  242. fstp dword [edi + ( 1*4)] ; autoc[1]+=d*data[sample+1]  ST = d
  243. fld st0 ; ST = d d
  244. fmul dword [esi] ; ST = d*data[sample] d WATCHOUT: no displacement byte here!
  245. fadd dword [edi] ; ST = autoc[0]+d*data[sample] d WATCHOUT: no displacement byte here!
  246. fstp dword [edi] ; autoc[0]+=d*data[sample]  ST = d WATCHOUT: no displacement byte here!
  247. .jumper1_0:
  248. fstp st0 ; pop d, ST = empty
  249. add esi, byte 4 ; sample++
  250. dec ecx
  251. jz .loop1_end
  252. fld dword [esi] ; ST = d <- data[sample]
  253. jmp edx
  254. .loop1_end:
  255. ; for(; sample < data_len; sample++) {
  256. ; d = data[sample];
  257. ; for(coeff = 0; coeff < data_len - sample; coeff++)
  258. ; autoc[coeff] += d * data[sample+coeff];
  259. ; }
  260. mov ecx, [esp + 24] ; ecx <- lag
  261. dec ecx ; ecx <- lag - 1
  262. jz near .end ; skip loop if 0 (i.e. lag == 1)
  263. fld dword [esi] ; ST = d <- data[sample]
  264. mov eax, ecx ; eax <- lag - 1 == data_len - sample the first time through
  265. ; each iteration is 11 bytes so we need (-eax)*11, so we do (-12*eax + eax)
  266. lea edx, [eax + eax*2]
  267. neg edx
  268. lea edx, [eax + edx*4 + .jumper2_0 - .get_eip2]
  269. call .get_eip2
  270. .get_eip2:
  271. pop ebx
  272. add edx, ebx
  273. inc edx ; compensate for the shorter opcode on the last iteration
  274. inc edx ; compensate for the shorter opcode on the last iteration
  275. inc edx ; compensate for the shorter opcode on the last iteration
  276. jmp edx
  277. fld st0 ; ST = d d
  278. fmul dword [esi + (31*4)] ; ST = d*data[sample+31] d
  279. fadd dword [edi + (31*4)] ; ST = autoc[31]+d*data[sample+31] d
  280. fstp dword [edi + (31*4)] ; autoc[31]+=d*data[sample+31]  ST = d
  281. fld st0 ; ST = d d
  282. fmul dword [esi + (30*4)] ; ST = d*data[sample+30] d
  283. fadd dword [edi + (30*4)] ; ST = autoc[30]+d*data[sample+30] d
  284. fstp dword [edi + (30*4)] ; autoc[30]+=d*data[sample+30]  ST = d
  285. fld st0 ; ST = d d
  286. fmul dword [esi + (29*4)] ; ST = d*data[sample+29] d
  287. fadd dword [edi + (29*4)] ; ST = autoc[29]+d*data[sample+29] d
  288. fstp dword [edi + (29*4)] ; autoc[29]+=d*data[sample+29]  ST = d
  289. fld st0 ; ST = d d
  290. fmul dword [esi + (28*4)] ; ST = d*data[sample+28] d
  291. fadd dword [edi + (28*4)] ; ST = autoc[28]+d*data[sample+28] d
  292. fstp dword [edi + (28*4)] ; autoc[28]+=d*data[sample+28]  ST = d
  293. fld st0 ; ST = d d
  294. fmul dword [esi + (27*4)] ; ST = d*data[sample+27] d
  295. fadd dword [edi + (27*4)] ; ST = autoc[27]+d*data[sample+27] d
  296. fstp dword [edi + (27*4)] ; autoc[27]+=d*data[sample+27]  ST = d
  297. fld st0 ; ST = d d
  298. fmul dword [esi + (26*4)] ; ST = d*data[sample+26] d
  299. fadd dword [edi + (26*4)] ; ST = autoc[26]+d*data[sample+26] d
  300. fstp dword [edi + (26*4)] ; autoc[26]+=d*data[sample+26]  ST = d
  301. fld st0 ; ST = d d
  302. fmul dword [esi + (25*4)] ; ST = d*data[sample+25] d
  303. fadd dword [edi + (25*4)] ; ST = autoc[25]+d*data[sample+25] d
  304. fstp dword [edi + (25*4)] ; autoc[25]+=d*data[sample+25]  ST = d
  305. fld st0 ; ST = d d
  306. fmul dword [esi + (24*4)] ; ST = d*data[sample+24] d
  307. fadd dword [edi + (24*4)] ; ST = autoc[24]+d*data[sample+24] d
  308. fstp dword [edi + (24*4)] ; autoc[24]+=d*data[sample+24]  ST = d
  309. fld st0 ; ST = d d
  310. fmul dword [esi + (23*4)] ; ST = d*data[sample+23] d
  311. fadd dword [edi + (23*4)] ; ST = autoc[23]+d*data[sample+23] d
  312. fstp dword [edi + (23*4)] ; autoc[23]+=d*data[sample+23]  ST = d
  313. fld st0 ; ST = d d
  314. fmul dword [esi + (22*4)] ; ST = d*data[sample+22] d
  315. fadd dword [edi + (22*4)] ; ST = autoc[22]+d*data[sample+22] d
  316. fstp dword [edi + (22*4)] ; autoc[22]+=d*data[sample+22]  ST = d
  317. fld st0 ; ST = d d
  318. fmul dword [esi + (21*4)] ; ST = d*data[sample+21] d
  319. fadd dword [edi + (21*4)] ; ST = autoc[21]+d*data[sample+21] d
  320. fstp dword [edi + (21*4)] ; autoc[21]+=d*data[sample+21]  ST = d
  321. fld st0 ; ST = d d
  322. fmul dword [esi + (20*4)] ; ST = d*data[sample+20] d
  323. fadd dword [edi + (20*4)] ; ST = autoc[20]+d*data[sample+20] d
  324. fstp dword [edi + (20*4)] ; autoc[20]+=d*data[sample+20]  ST = d
  325. fld st0 ; ST = d d
  326. fmul dword [esi + (19*4)] ; ST = d*data[sample+19] d
  327. fadd dword [edi + (19*4)] ; ST = autoc[19]+d*data[sample+19] d
  328. fstp dword [edi + (19*4)] ; autoc[19]+=d*data[sample+19]  ST = d
  329. fld st0 ; ST = d d
  330. fmul dword [esi + (18*4)] ; ST = d*data[sample+18] d
  331. fadd dword [edi + (18*4)] ; ST = autoc[18]+d*data[sample+18] d
  332. fstp dword [edi + (18*4)] ; autoc[18]+=d*data[sample+18]  ST = d
  333. fld st0 ; ST = d d
  334. fmul dword [esi + (17*4)] ; ST = d*data[sample+17] d
  335. fadd dword [edi + (17*4)] ; ST = autoc[17]+d*data[sample+17] d
  336. fstp dword [edi + (17*4)] ; autoc[17]+=d*data[sample+17]  ST = d
  337. fld st0 ; ST = d d
  338. fmul dword [esi + (16*4)] ; ST = d*data[sample+16] d
  339. fadd dword [edi + (16*4)] ; ST = autoc[16]+d*data[sample+16] d
  340. fstp dword [edi + (16*4)] ; autoc[16]+=d*data[sample+16]  ST = d
  341. fld st0 ; ST = d d
  342. fmul dword [esi + (15*4)] ; ST = d*data[sample+15] d
  343. fadd dword [edi + (15*4)] ; ST = autoc[15]+d*data[sample+15] d
  344. fstp dword [edi + (15*4)] ; autoc[15]+=d*data[sample+15]  ST = d
  345. fld st0 ; ST = d d
  346. fmul dword [esi + (14*4)] ; ST = d*data[sample+14] d
  347. fadd dword [edi + (14*4)] ; ST = autoc[14]+d*data[sample+14] d
  348. fstp dword [edi + (14*4)] ; autoc[14]+=d*data[sample+14]  ST = d
  349. fld st0 ; ST = d d
  350. fmul dword [esi + (13*4)] ; ST = d*data[sample+13] d
  351. fadd dword [edi + (13*4)] ; ST = autoc[13]+d*data[sample+13] d
  352. fstp dword [edi + (13*4)] ; autoc[13]+=d*data[sample+13]  ST = d
  353. fld st0 ; ST = d d
  354. fmul dword [esi + (12*4)] ; ST = d*data[sample+12] d
  355. fadd dword [edi + (12*4)] ; ST = autoc[12]+d*data[sample+12] d
  356. fstp dword [edi + (12*4)] ; autoc[12]+=d*data[sample+12]  ST = d
  357. fld st0 ; ST = d d
  358. fmul dword [esi + (11*4)] ; ST = d*data[sample+11] d
  359. fadd dword [edi + (11*4)] ; ST = autoc[11]+d*data[sample+11] d
  360. fstp dword [edi + (11*4)] ; autoc[11]+=d*data[sample+11]  ST = d
  361. fld st0 ; ST = d d
  362. fmul dword [esi + (10*4)] ; ST = d*data[sample+10] d
  363. fadd dword [edi + (10*4)] ; ST = autoc[10]+d*data[sample+10] d
  364. fstp dword [edi + (10*4)] ; autoc[10]+=d*data[sample+10]  ST = d
  365. fld st0 ; ST = d d
  366. fmul dword [esi + ( 9*4)] ; ST = d*data[sample+9] d
  367. fadd dword [edi + ( 9*4)] ; ST = autoc[9]+d*data[sample+9] d
  368. fstp dword [edi + ( 9*4)] ; autoc[9]+=d*data[sample+9]  ST = d
  369. fld st0 ; ST = d d
  370. fmul dword [esi + ( 8*4)] ; ST = d*data[sample+8] d
  371. fadd dword [edi + ( 8*4)] ; ST = autoc[8]+d*data[sample+8] d
  372. fstp dword [edi + ( 8*4)] ; autoc[8]+=d*data[sample+8]  ST = d
  373. fld st0 ; ST = d d
  374. fmul dword [esi + ( 7*4)] ; ST = d*data[sample+7] d
  375. fadd dword [edi + ( 7*4)] ; ST = autoc[7]+d*data[sample+7] d
  376. fstp dword [edi + ( 7*4)] ; autoc[7]+=d*data[sample+7]  ST = d
  377. fld st0 ; ST = d d
  378. fmul dword [esi + ( 6*4)] ; ST = d*data[sample+6] d
  379. fadd dword [edi + ( 6*4)] ; ST = autoc[6]+d*data[sample+6] d
  380. fstp dword [edi + ( 6*4)] ; autoc[6]+=d*data[sample+6]  ST = d
  381. fld st0 ; ST = d d
  382. fmul dword [esi + ( 5*4)] ; ST = d*data[sample+4] d
  383. fadd dword [edi + ( 5*4)] ; ST = autoc[4]+d*data[sample+4] d
  384. fstp dword [edi + ( 5*4)] ; autoc[4]+=d*data[sample+4]  ST = d
  385. fld st0 ; ST = d d
  386. fmul dword [esi + ( 4*4)] ; ST = d*data[sample+4] d
  387. fadd dword [edi + ( 4*4)] ; ST = autoc[4]+d*data[sample+4] d
  388. fstp dword [edi + ( 4*4)] ; autoc[4]+=d*data[sample+4]  ST = d
  389. fld st0 ; ST = d d
  390. fmul dword [esi + ( 3*4)] ; ST = d*data[sample+3] d
  391. fadd dword [edi + ( 3*4)] ; ST = autoc[3]+d*data[sample+3] d
  392. fstp dword [edi + ( 3*4)] ; autoc[3]+=d*data[sample+3]  ST = d
  393. fld st0 ; ST = d d
  394. fmul dword [esi + ( 2*4)] ; ST = d*data[sample+2] d
  395. fadd dword [edi + ( 2*4)] ; ST = autoc[2]+d*data[sample+2] d
  396. fstp dword [edi + ( 2*4)] ; autoc[2]+=d*data[sample+2]  ST = d
  397. fld st0 ; ST = d d
  398. fmul dword [esi + ( 1*4)] ; ST = d*data[sample+1] d
  399. fadd dword [edi + ( 1*4)] ; ST = autoc[1]+d*data[sample+1] d
  400. fstp dword [edi + ( 1*4)] ; autoc[1]+=d*data[sample+1]  ST = d
  401. fld st0 ; ST = d d
  402. fmul dword [esi] ; ST = d*data[sample] d WATCHOUT: no displacement byte here!
  403. fadd dword [edi] ; ST = autoc[0]+d*data[sample] d WATCHOUT: no displacement byte here!
  404. fstp dword [edi] ; autoc[0]+=d*data[sample]  ST = d WATCHOUT: no displacement byte here!
  405. .jumper2_0:
  406. fstp st0 ; pop d, ST = empty
  407. add esi, byte 4 ; sample++
  408. dec ecx
  409. jz .loop2_end
  410. add edx, byte 11 ; adjust our inner loop counter by adjusting the jump target
  411. fld dword [esi] ; ST = d <- data[sample]
  412. jmp edx
  413. .loop2_end:
  414. .end:
  415. pop ebx
  416. pop edi
  417. pop esi
  418. ret
  419. ALIGN 16
  420. cident FLAC__lpc_compute_autocorrelation_asm_ia32_sse_lag_4
  421. ;[esp + 16] == autoc[]
  422. ;[esp + 12] == lag
  423. ;[esp + 8] == data_len
  424. ;[esp + 4] == data[]
  425. ;ASSERT(lag > 0)
  426. ;ASSERT(lag <= 4)
  427. ;ASSERT(lag <= data_len)
  428. ; for(coeff = 0; coeff < lag; coeff++)
  429. ; autoc[coeff] = 0.0;
  430. xorps xmm5, xmm5
  431. mov edx, [esp + 8] ; edx == data_len
  432. mov eax, [esp + 4] ; eax == &data[sample] <- &data[0]
  433. movss xmm0, [eax] ; xmm0 = 0,0,0,data[0]
  434. add eax, 4
  435. movaps xmm2, xmm0 ; xmm2 = 0,0,0,data[0]
  436. shufps xmm0, xmm0, 0 ; xmm0 == data[sample],data[sample],data[sample],data[sample] = data[0],data[0],data[0],data[0]
  437. .warmup: ; xmm2 == data[sample-3],data[sample-2],data[sample-1],data[sample]
  438. mulps xmm0, xmm2 ; xmm0 = xmm0 * xmm2
  439. addps xmm5, xmm0 ; xmm5 += xmm0 * xmm2
  440. dec edx
  441. jz .loop_end
  442. ALIGN 16
  443. .loop_start:
  444. ; start by reading the next sample
  445. movss xmm0, [eax] ; xmm0 = 0,0,0,data[sample]
  446. add eax, 4
  447. shufps xmm0, xmm0, 0 ; xmm0 = data[sample],data[sample],data[sample],data[sample]
  448. shufps xmm2, xmm2, 93h ; 93h=2-1-0-3 => xmm2 gets rotated left by one float
  449. movss xmm2, xmm0
  450. mulps xmm0, xmm2 ; xmm0 = xmm0 * xmm2
  451. addps xmm5, xmm0 ; xmm5 += xmm0 * xmm2
  452. dec edx
  453. jnz .loop_start
  454. .loop_end:
  455. ; store autoc
  456. mov edx, [esp + 16] ; edx == autoc
  457. movups [edx], xmm5
  458. .end:
  459. ret
  460. ALIGN 16
  461. cident FLAC__lpc_compute_autocorrelation_asm_ia32_sse_lag_8
  462. ;[esp + 16] == autoc[]
  463. ;[esp + 12] == lag
  464. ;[esp + 8] == data_len
  465. ;[esp + 4] == data[]
  466. ;ASSERT(lag > 0)
  467. ;ASSERT(lag <= 8)
  468. ;ASSERT(lag <= data_len)
  469. ; for(coeff = 0; coeff < lag; coeff++)
  470. ; autoc[coeff] = 0.0;
  471. xorps xmm5, xmm5
  472. xorps xmm6, xmm6
  473. mov edx, [esp + 8] ; edx == data_len
  474. mov eax, [esp + 4] ; eax == &data[sample] <- &data[0]
  475. movss xmm0, [eax] ; xmm0 = 0,0,0,data[0]
  476. add eax, 4
  477. movaps xmm2, xmm0 ; xmm2 = 0,0,0,data[0]
  478. shufps xmm0, xmm0, 0 ; xmm0 == data[sample],data[sample],data[sample],data[sample] = data[0],data[0],data[0],data[0]
  479. movaps xmm1, xmm0 ; xmm1 == data[sample],data[sample],data[sample],data[sample] = data[0],data[0],data[0],data[0]
  480. xorps xmm3, xmm3 ; xmm3 = 0,0,0,0
  481. .warmup: ; xmm3:xmm2 == data[sample-7],data[sample-6],...,data[sample]
  482. mulps xmm0, xmm2
  483. mulps xmm1, xmm3 ; xmm1:xmm0 = xmm1:xmm0 * xmm3:xmm2
  484. addps xmm5, xmm0
  485. addps xmm6, xmm1 ; xmm6:xmm5 += xmm1:xmm0 * xmm3:xmm2
  486. dec edx
  487. jz .loop_end
  488. ALIGN 16
  489. .loop_start:
  490. ; start by reading the next sample
  491. movss xmm0, [eax] ; xmm0 = 0,0,0,data[sample]
  492. ; here we reorder the instructions; see the (#) indexes for a logical order
  493. shufps xmm2, xmm2, 93h ; (3) 93h=2-1-0-3 => xmm2 gets rotated left by one float
  494. add eax, 4 ; (0)
  495. shufps xmm3, xmm3, 93h ; (4) 93h=2-1-0-3 => xmm3 gets rotated left by one float
  496. shufps xmm0, xmm0, 0 ; (1) xmm0 = data[sample],data[sample],data[sample],data[sample]
  497. movss xmm3, xmm2 ; (5)
  498. movaps xmm1, xmm0 ; (2) xmm1 = data[sample],data[sample],data[sample],data[sample]
  499. movss xmm2, xmm0 ; (6)
  500. mulps xmm1, xmm3 ; (8)
  501. mulps xmm0, xmm2 ; (7) xmm1:xmm0 = xmm1:xmm0 * xmm3:xmm2
  502. addps xmm6, xmm1 ; (10)
  503. addps xmm5, xmm0 ; (9) xmm6:xmm5 += xmm1:xmm0 * xmm3:xmm2
  504. dec edx
  505. jnz .loop_start
  506. .loop_end:
  507. ; store autoc
  508. mov edx, [esp + 16] ; edx == autoc
  509. movups [edx], xmm5
  510. movups [edx + 16], xmm6
  511. .end:
  512. ret
  513. ALIGN 16
  514. cident FLAC__lpc_compute_autocorrelation_asm_ia32_sse_lag_12
  515. ;[esp + 16] == autoc[]
  516. ;[esp + 12] == lag
  517. ;[esp + 8] == data_len
  518. ;[esp + 4] == data[]
  519. ;ASSERT(lag > 0)
  520. ;ASSERT(lag <= 12)
  521. ;ASSERT(lag <= data_len)
  522. ; for(coeff = 0; coeff < lag; coeff++)
  523. ; autoc[coeff] = 0.0;
  524. xorps xmm5, xmm5
  525. xorps xmm6, xmm6
  526. xorps xmm7, xmm7
  527. mov edx, [esp + 8] ; edx == data_len
  528. mov eax, [esp + 4] ; eax == &data[sample] <- &data[0]
  529. movss xmm0, [eax] ; xmm0 = 0,0,0,data[0]
  530. add eax, 4
  531. movaps xmm2, xmm0 ; xmm2 = 0,0,0,data[0]
  532. shufps xmm0, xmm0, 0 ; xmm0 == data[sample],data[sample],data[sample],data[sample] = data[0],data[0],data[0],data[0]
  533. xorps xmm3, xmm3 ; xmm3 = 0,0,0,0
  534. xorps xmm4, xmm4 ; xmm4 = 0,0,0,0
  535. .warmup: ; xmm3:xmm2 == data[sample-7],data[sample-6],...,data[sample]
  536. movaps xmm1, xmm0
  537. mulps xmm1, xmm2
  538. addps xmm5, xmm1
  539. movaps xmm1, xmm0
  540. mulps xmm1, xmm3
  541. addps xmm6, xmm1
  542. mulps xmm0, xmm4
  543. addps xmm7, xmm0 ; xmm7:xmm6:xmm5 += xmm0:xmm0:xmm0 * xmm4:xmm3:xmm2
  544. dec edx
  545. jz .loop_end
  546. ALIGN 16
  547. .loop_start:
  548. ; start by reading the next sample
  549. movss xmm0, [eax] ; xmm0 = 0,0,0,data[sample]
  550. add eax, 4
  551. shufps xmm0, xmm0, 0 ; xmm0 = data[sample],data[sample],data[sample],data[sample]
  552. ; shift xmm4:xmm3:xmm2 left by one float
  553. shufps xmm2, xmm2, 93h ; 93h=2-1-0-3 => xmm2 gets rotated left by one float
  554. shufps xmm3, xmm3, 93h ; 93h=2-1-0-3 => xmm3 gets rotated left by one float
  555. shufps xmm4, xmm4, 93h ; 93h=2-1-0-3 => xmm4 gets rotated left by one float
  556. movss xmm4, xmm3
  557. movss xmm3, xmm2
  558. movss xmm2, xmm0
  559. ; xmm7:xmm6:xmm5 += xmm0:xmm0:xmm0 * xmm3:xmm3:xmm2
  560. movaps xmm1, xmm0
  561. mulps xmm1, xmm2
  562. addps xmm5, xmm1
  563. movaps xmm1, xmm0
  564. mulps xmm1, xmm3
  565. addps xmm6, xmm1
  566. mulps xmm0, xmm4
  567. addps xmm7, xmm0
  568. dec edx
  569. jnz .loop_start
  570. .loop_end:
  571. ; store autoc
  572. mov edx, [esp + 16] ; edx == autoc
  573. movups [edx], xmm5
  574. movups [edx + 16], xmm6
  575. movups [edx + 32], xmm7
  576. .end:
  577. ret
  578. align 16
  579. cident FLAC__lpc_compute_autocorrelation_asm_ia32_3dnow
  580. ;[ebp + 32] autoc
  581. ;[ebp + 28] lag
  582. ;[ebp + 24] data_len
  583. ;[ebp + 20] data
  584. push ebp
  585. push ebx
  586. push esi
  587. push edi
  588. mov ebp, esp
  589. mov esi, [ebp + 20]
  590. mov edi, [ebp + 24]
  591. mov edx, [ebp + 28]
  592. inc edx
  593. and edx, byte -2
  594. mov eax, edx
  595. neg eax
  596. and esp, byte -8
  597. lea esp, [esp + 4 * eax]
  598. mov ecx, edx
  599. xor eax, eax
  600. .loop0:
  601. dec ecx
  602. mov [esp + 4 * ecx], eax
  603. jnz short .loop0
  604. mov eax, edi
  605. sub eax, edx
  606. mov ebx, edx
  607. and ebx, byte 1
  608. sub eax, ebx
  609. lea ecx, [esi + 4 * eax - 12]
  610. cmp esi, ecx
  611. mov eax, esi
  612. ja short .loop2_pre
  613. align 16 ;4 nops
  614. .loop1_i:
  615. movd mm0, [eax]
  616. movd mm2, [eax + 4]
  617. movd mm4, [eax + 8]
  618. movd mm6, [eax + 12]
  619. mov ebx, edx
  620. punpckldq mm0, mm0
  621. punpckldq mm2, mm2
  622. punpckldq mm4, mm4
  623. punpckldq mm6, mm6
  624. align 16 ;3 nops
  625. .loop1_j:
  626. sub ebx, byte 2
  627. movd mm1, [eax + 4 * ebx]
  628. movd mm3, [eax + 4 * ebx + 4]
  629. movd mm5, [eax + 4 * ebx + 8]
  630. movd mm7, [eax + 4 * ebx + 12]
  631. punpckldq mm1, mm3
  632. punpckldq mm3, mm5
  633. pfmul mm1, mm0
  634. punpckldq mm5, mm7
  635. pfmul mm3, mm2
  636. punpckldq mm7, [eax + 4 * ebx + 16]
  637. pfmul mm5, mm4
  638. pfmul mm7, mm6
  639. pfadd mm1, mm3
  640. movq mm3, [esp + 4 * ebx]
  641. pfadd mm5, mm7
  642. pfadd mm1, mm5
  643. pfadd mm3, mm1
  644. movq [esp + 4 * ebx], mm3
  645. jg short .loop1_j
  646. add eax, byte 16
  647. cmp eax, ecx
  648. jb short .loop1_i
  649. .loop2_pre:
  650. mov ebx, eax
  651. sub eax, esi
  652. shr eax, 2
  653. lea ecx, [esi + 4 * edi]
  654. mov esi, ebx
  655. .loop2_i:
  656. movd mm0, [esi]
  657. mov ebx, edi
  658. sub ebx, eax
  659. cmp ebx, edx
  660. jbe short .loop2_j
  661. mov ebx, edx
  662. .loop2_j:
  663. dec ebx
  664. movd mm1, [esi + 4 * ebx]
  665. pfmul mm1, mm0
  666. movd mm2, [esp + 4 * ebx]
  667. pfadd mm1, mm2
  668. movd [esp + 4 * ebx], mm1
  669. jnz short .loop2_j
  670. add esi, byte 4
  671. inc eax
  672. cmp esi, ecx
  673. jnz short .loop2_i
  674. mov edi, [ebp + 32]
  675. mov edx, [ebp + 28]
  676. .loop3:
  677. dec edx
  678. mov eax, [esp + 4 * edx]
  679. mov [edi + 4 * edx], eax
  680. jnz short .loop3
  681. femms
  682. mov esp, ebp
  683. pop edi
  684. pop esi
  685. pop ebx
  686. pop ebp
  687. ret
  688. ;void FLAC__lpc_compute_residual_from_qlp_coefficients(const FLAC__int32 *data, unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 residual[])
  689. ;
  690. ; for(i = 0; i < data_len; i++) {
  691. ; sum = 0;
  692. ; for(j = 0; j < order; j++)
  693. ; sum += qlp_coeff[j] * data[i-j-1];
  694. ; residual[i] = data[i] - (sum >> lp_quantization);
  695. ; }
  696. ;
  697. ALIGN 16
  698. cident FLAC__lpc_compute_residual_from_qlp_coefficients_asm_ia32
  699. ;[esp + 40] residual[]
  700. ;[esp + 36] lp_quantization
  701. ;[esp + 32] order
  702. ;[esp + 28] qlp_coeff[]
  703. ;[esp + 24] data_len
  704. ;[esp + 20] data[]
  705. ;ASSERT(order > 0)
  706. push ebp
  707. push ebx
  708. push esi
  709. push edi
  710. mov esi, [esp + 20] ; esi = data[]
  711. mov edi, [esp + 40] ; edi = residual[]
  712. mov eax, [esp + 32] ; eax = order
  713. mov ebx, [esp + 24] ; ebx = data_len
  714. test ebx, ebx
  715. jz near .end ; do nothing if data_len == 0
  716. .begin:
  717. cmp eax, byte 1
  718. jg short .i_1more
  719. mov ecx, [esp + 28]
  720. mov edx, [ecx] ; edx = qlp_coeff[0]
  721. mov eax, [esi - 4] ; eax = data[-1]
  722. mov cl, [esp + 36] ; cl = lp_quantization
  723. ALIGN 16
  724. .i_1_loop_i:
  725. imul eax, edx
  726. sar eax, cl
  727. neg eax
  728. add eax, [esi]
  729. mov [edi], eax
  730. mov eax, [esi]
  731. add edi, byte 4
  732. add esi, byte 4
  733. dec ebx
  734. jnz .i_1_loop_i
  735. jmp .end
  736. .i_1more:
  737. cmp eax, byte 32 ; for order <= 32 there is a faster routine
  738. jbe short .i_32
  739. ; This version is here just for completeness, since FLAC__MAX_LPC_ORDER == 32
  740. ALIGN 16
  741. .i_32more_loop_i:
  742. xor ebp, ebp
  743. mov ecx, [esp + 32]
  744. mov edx, ecx
  745. shl edx, 2
  746. add edx, [esp + 28]
  747. neg ecx
  748. ALIGN 16
  749. .i_32more_loop_j:
  750. sub edx, byte 4
  751. mov eax, [edx]
  752. imul eax, [esi + 4 * ecx]
  753. add ebp, eax
  754. inc ecx
  755. jnz short .i_32more_loop_j
  756. mov cl, [esp + 36]
  757. sar ebp, cl
  758. neg ebp
  759. add ebp, [esi]
  760. mov [edi], ebp
  761. add esi, byte 4
  762. add edi, byte 4
  763. dec ebx
  764. jnz .i_32more_loop_i
  765. jmp .end
  766. .i_32:
  767. sub edi, esi
  768. neg eax
  769. lea edx, [eax + eax * 8 + .jumper_0 - .get_eip0]
  770. call .get_eip0
  771. .get_eip0:
  772. pop eax
  773. add edx, eax
  774. inc edx
  775. mov eax, [esp + 28] ; eax = qlp_coeff[]
  776. xor ebp, ebp
  777. jmp edx
  778. mov ecx, [eax + 124]
  779. imul ecx, [esi - 128]
  780. add ebp, ecx
  781. mov ecx, [eax + 120]
  782. imul ecx, [esi - 124]
  783. add ebp, ecx
  784. mov ecx, [eax + 116]
  785. imul ecx, [esi - 120]
  786. add ebp, ecx
  787. mov ecx, [eax + 112]
  788. imul ecx, [esi - 116]
  789. add ebp, ecx
  790. mov ecx, [eax + 108]
  791. imul ecx, [esi - 112]
  792. add ebp, ecx
  793. mov ecx, [eax + 104]
  794. imul ecx, [esi - 108]
  795. add ebp, ecx
  796. mov ecx, [eax + 100]
  797. imul ecx, [esi - 104]
  798. add ebp, ecx
  799. mov ecx, [eax + 96]
  800. imul ecx, [esi - 100]
  801. add ebp, ecx
  802. mov ecx, [eax + 92]
  803. imul ecx, [esi - 96]
  804. add ebp, ecx
  805. mov ecx, [eax + 88]
  806. imul ecx, [esi - 92]
  807. add ebp, ecx
  808. mov ecx, [eax + 84]
  809. imul ecx, [esi - 88]
  810. add ebp, ecx
  811. mov ecx, [eax + 80]
  812. imul ecx, [esi - 84]
  813. add ebp, ecx
  814. mov ecx, [eax + 76]
  815. imul ecx, [esi - 80]
  816. add ebp, ecx
  817. mov ecx, [eax + 72]
  818. imul ecx, [esi - 76]
  819. add ebp, ecx
  820. mov ecx, [eax + 68]
  821. imul ecx, [esi - 72]
  822. add ebp, ecx
  823. mov ecx, [eax + 64]
  824. imul ecx, [esi - 68]
  825. add ebp, ecx
  826. mov ecx, [eax + 60]
  827. imul ecx, [esi - 64]
  828. add ebp, ecx
  829. mov ecx, [eax + 56]
  830. imul ecx, [esi - 60]
  831. add ebp, ecx
  832. mov ecx, [eax + 52]
  833. imul ecx, [esi - 56]
  834. add ebp, ecx
  835. mov ecx, [eax + 48]
  836. imul ecx, [esi - 52]
  837. add ebp, ecx
  838. mov ecx, [eax + 44]
  839. imul ecx, [esi - 48]
  840. add ebp, ecx
  841. mov ecx, [eax + 40]
  842. imul ecx, [esi - 44]
  843. add ebp, ecx
  844. mov ecx, [eax + 36]
  845. imul ecx, [esi - 40]
  846. add ebp, ecx
  847. mov ecx, [eax + 32]
  848. imul ecx, [esi - 36]
  849. add ebp, ecx
  850. mov ecx, [eax + 28]
  851. imul ecx, [esi - 32]
  852. add ebp, ecx
  853. mov ecx, [eax + 24]
  854. imul ecx, [esi - 28]
  855. add ebp, ecx
  856. mov ecx, [eax + 20]
  857. imul ecx, [esi - 24]
  858. add ebp, ecx
  859. mov ecx, [eax + 16]
  860. imul ecx, [esi - 20]
  861. add ebp, ecx
  862. mov ecx, [eax + 12]
  863. imul ecx, [esi - 16]
  864. add ebp, ecx
  865. mov ecx, [eax + 8]
  866. imul ecx, [esi - 12]
  867. add ebp, ecx
  868. mov ecx, [eax + 4]
  869. imul ecx, [esi - 8]
  870. add ebp, ecx
  871. mov ecx, [eax] ; there is one byte missing
  872. imul ecx, [esi - 4]
  873. add ebp, ecx
  874. .jumper_0:
  875. mov cl, [esp + 36]
  876. sar ebp, cl
  877. neg ebp
  878. add ebp, [esi]
  879. mov [edi + esi], ebp
  880. add esi, byte 4
  881. dec ebx
  882. jz short .end
  883. xor ebp, ebp
  884. jmp edx
  885. .end:
  886. pop edi
  887. pop esi
  888. pop ebx
  889. pop ebp
  890. ret
  891. ; WATCHOUT: this routine works on 16 bit data which means bits-per-sample for
  892. ; the channel must be <= 16.  Especially note that this routine cannot be used
  893. ; for side-channel coded 16bps channels since the effective bps is 17.
  894. ALIGN 16
  895. cident FLAC__lpc_compute_residual_from_qlp_coefficients_asm_ia32_mmx
  896. ;[esp + 40] residual[]
  897. ;[esp + 36] lp_quantization
  898. ;[esp + 32] order
  899. ;[esp + 28] qlp_coeff[]
  900. ;[esp + 24] data_len
  901. ;[esp + 20] data[]
  902. ;ASSERT(order > 0)
  903. push ebp
  904. push ebx
  905. push esi
  906. push edi
  907. mov esi, [esp + 20] ; esi = data[]
  908. mov edi, [esp + 40] ; edi = residual[]
  909. mov eax, [esp + 32] ; eax = order
  910. mov ebx, [esp + 24] ; ebx = data_len
  911. test ebx, ebx
  912. jz near .end ; do nothing if data_len == 0
  913. dec ebx
  914. test ebx, ebx
  915. jz near .last_one
  916. mov edx, [esp + 28] ; edx = qlp_coeff[]
  917. movd mm6, [esp + 36] ; mm6 = 0:lp_quantization
  918. mov ebp, esp
  919. and esp, 0xfffffff8
  920. xor ecx, ecx
  921. .copy_qlp_loop:
  922. push word [edx + 4 * ecx]
  923. inc ecx
  924. cmp ecx, eax
  925. jnz short .copy_qlp_loop
  926. and ecx, 0x3
  927. test ecx, ecx
  928. je short .za_end
  929. sub ecx, byte 4
  930. .za_loop:
  931. push word 0
  932. inc eax
  933. inc ecx
  934. jnz short .za_loop
  935. .za_end:
  936. movq mm5, [esp + 2 * eax - 8]
  937. movd mm4, [esi - 16]
  938. punpckldq mm4, [esi - 12]
  939. movd mm0, [esi - 8]
  940. punpckldq mm0, [esi - 4]
  941. packssdw mm4, mm0
  942. cmp eax, byte 4
  943. jnbe short .mmx_4more
  944. align 16
  945. .mmx_4_loop_i:
  946. movd mm1, [esi]
  947. movq mm3, mm4
  948. punpckldq mm1, [esi + 4]
  949. psrlq mm4, 16
  950. movq mm0, mm1
  951. psllq mm0, 48
  952. por mm4, mm0
  953. movq mm2, mm4
  954. psrlq mm4, 16
  955. pxor mm0, mm0
  956. punpckhdq mm0, mm1
  957. pmaddwd mm3, mm5
  958. pmaddwd mm2, mm5
  959. psllq mm0, 16
  960. por mm4, mm0
  961. movq mm0, mm3
  962. punpckldq mm3, mm2
  963. punpckhdq mm0, mm2
  964. paddd mm3, mm0
  965. psrad mm3, mm6
  966. psubd mm1, mm3
  967. movd [edi], mm1
  968. punpckhdq mm1, mm1
  969. movd [edi + 4], mm1
  970. add edi, byte 8
  971. add esi, byte 8
  972. sub ebx, 2
  973. jg .mmx_4_loop_i
  974. jmp .mmx_end
  975. .mmx_4more:
  976. shl eax, 2
  977. neg eax
  978. add eax, byte 16
  979. align 16
  980. .mmx_4more_loop_i:
  981. movd mm1, [esi]
  982. punpckldq mm1, [esi + 4]
  983. movq mm3, mm4
  984. psrlq mm4, 16
  985. movq mm0, mm1
  986. psllq mm0, 48
  987. por mm4, mm0
  988. movq mm2, mm4
  989. psrlq mm4, 16
  990. pxor mm0, mm0
  991. punpckhdq mm0, mm1
  992. pmaddwd mm3, mm5
  993. pmaddwd mm2, mm5
  994. psllq mm0, 16
  995. por mm4, mm0
  996. mov ecx, esi
  997. add ecx, eax
  998. mov edx, esp
  999. align 16
  1000. .mmx_4more_loop_j:
  1001. movd mm0, [ecx - 16]
  1002. movd mm7, [ecx - 8]
  1003. punpckldq mm0, [ecx - 12]
  1004. punpckldq mm7, [ecx - 4]
  1005. packssdw mm0, mm7
  1006. pmaddwd mm0, [edx]
  1007. punpckhdq mm7, mm7
  1008. paddd mm3, mm0
  1009. movd mm0, [ecx - 12]
  1010. punpckldq mm0, [ecx - 8]
  1011. punpckldq mm7, [ecx]
  1012. packssdw mm0, mm7
  1013. pmaddwd mm0, [edx]
  1014. paddd mm2, mm0
  1015. add edx, byte 8
  1016. add ecx, byte 16
  1017. cmp ecx, esi
  1018. jnz .mmx_4more_loop_j
  1019. movq mm0, mm3
  1020. punpckldq mm3, mm2
  1021. punpckhdq mm0, mm2
  1022. paddd mm3, mm0
  1023. psrad mm3, mm6
  1024. psubd mm1, mm3
  1025. movd [edi], mm1
  1026. punpckhdq mm1, mm1
  1027. movd [edi + 4], mm1
  1028. add edi, byte 8
  1029. add esi, byte 8
  1030. sub ebx, 2
  1031. jg near .mmx_4more_loop_i
  1032. .mmx_end:
  1033. emms
  1034. mov esp, ebp
  1035. .last_one:
  1036. mov eax, [esp + 32]
  1037. inc ebx
  1038. jnz near FLAC__lpc_compute_residual_from_qlp_coefficients_asm_ia32.begin
  1039. .end:
  1040. pop edi
  1041. pop esi
  1042. pop ebx
  1043. pop ebp
  1044. ret
  1045. ; **********************************************************************
  1046. ;
  1047. ; void FLAC__lpc_restore_signal(const FLAC__int32 residual[], unsigned data_len, const FLAC__int32 qlp_coeff[], unsigned order, int lp_quantization, FLAC__int32 data[])
  1048. ; {
  1049. ;  unsigned i, j;
  1050. ;  FLAC__int32 sum;
  1051. ;
  1052. ;  FLAC__ASSERT(order > 0);
  1053. ;
  1054. ;  for(i = 0; i < data_len; i++) {
  1055. ;  sum = 0;
  1056. ;  for(j = 0; j < order; j++)
  1057. ;  sum += qlp_coeff[j] * data[i-j-1];
  1058. ;  data[i] = residual[i] + (sum >> lp_quantization);
  1059. ;  }
  1060. ; }
  1061. ALIGN 16
  1062. cident FLAC__lpc_restore_signal_asm_ia32
  1063. ;[esp + 40] data[]
  1064. ;[esp + 36] lp_quantization
  1065. ;[esp + 32] order
  1066. ;[esp + 28] qlp_coeff[]
  1067. ;[esp + 24] data_len
  1068. ;[esp + 20] residual[]
  1069. ;ASSERT(order > 0)
  1070. push ebp
  1071. push ebx
  1072. push esi
  1073. push edi
  1074. mov esi, [esp + 20] ; esi = residual[]
  1075. mov edi, [esp + 40] ; edi = data[]
  1076. mov eax, [esp + 32] ; eax = order
  1077. mov ebx, [esp + 24] ; ebx = data_len
  1078. test ebx, ebx
  1079. jz near .end ; do nothing if data_len == 0
  1080. .begin:
  1081. cmp eax, byte 1
  1082. jg short .x87_1more
  1083. mov ecx, [esp + 28]
  1084. mov edx, [ecx]
  1085. mov eax, [edi - 4]
  1086. mov cl, [esp + 36]
  1087. ALIGN 16
  1088. .x87_1_loop_i:
  1089. imul eax, edx
  1090. sar eax, cl
  1091. add eax, [esi]
  1092. mov [edi], eax
  1093. add esi, byte 4
  1094. add edi, byte 4
  1095. dec ebx
  1096. jnz .x87_1_loop_i
  1097. jmp .end
  1098. .x87_1more:
  1099. cmp eax, byte 32 ; for order <= 32 there is a faster routine
  1100. jbe short .x87_32
  1101. ; This version is here just for completeness, since FLAC__MAX_LPC_ORDER == 32
  1102. ALIGN 16
  1103. .x87_32more_loop_i:
  1104. xor ebp, ebp
  1105. mov ecx, [esp + 32]
  1106. mov edx, ecx
  1107. shl edx, 2
  1108. add edx, [esp + 28]
  1109. neg ecx
  1110. ALIGN 16
  1111. .x87_32more_loop_j:
  1112. sub edx, byte 4
  1113. mov eax, [edx]
  1114. imul eax, [edi + 4 * ecx]
  1115. add ebp, eax
  1116. inc ecx
  1117. jnz short .x87_32more_loop_j
  1118. mov cl, [esp + 36]
  1119. sar ebp, cl
  1120. add ebp, [esi]
  1121. mov [edi], ebp
  1122. add edi, byte 4
  1123. add esi, byte 4
  1124. dec ebx
  1125. jnz .x87_32more_loop_i
  1126. jmp .end
  1127. .x87_32:
  1128. sub esi, edi
  1129. neg eax
  1130. lea edx, [eax + eax * 8 + .jumper_0 - .get_eip0]
  1131. call .get_eip0
  1132. .get_eip0:
  1133. pop eax
  1134. add edx, eax
  1135. inc edx ; compensate for the shorter opcode on the last iteration
  1136. mov eax, [esp + 28] ; eax = qlp_coeff[]
  1137. xor ebp, ebp
  1138. jmp edx
  1139. mov ecx, [eax + 124] ; ecx =  qlp_coeff[31]
  1140. imul ecx, [edi - 128] ; ecx =  qlp_coeff[31] * data[i-32]
  1141. add ebp, ecx ; sum += qlp_coeff[31] * data[i-32]
  1142. mov ecx, [eax + 120] ; ecx =  qlp_coeff[30]
  1143. imul ecx, [edi - 124] ; ecx =  qlp_coeff[30] * data[i-31]
  1144. add ebp, ecx ; sum += qlp_coeff[30] * data[i-31]
  1145. mov ecx, [eax + 116] ; ecx =  qlp_coeff[29]
  1146. imul ecx, [edi - 120] ; ecx =  qlp_coeff[29] * data[i-30]
  1147. add ebp, ecx ; sum += qlp_coeff[29] * data[i-30]
  1148. mov ecx, [eax + 112] ; ecx =  qlp_coeff[28]
  1149. imul ecx, [edi - 116] ; ecx =  qlp_coeff[28] * data[i-29]
  1150. add ebp, ecx ; sum += qlp_coeff[28] * data[i-29]
  1151. mov ecx, [eax + 108] ; ecx =  qlp_coeff[27]
  1152. imul ecx, [edi - 112] ; ecx =  qlp_coeff[27] * data[i-28]
  1153. add ebp, ecx ; sum += qlp_coeff[27] * data[i-28]
  1154. mov ecx, [eax + 104] ; ecx =  qlp_coeff[26]
  1155. imul ecx, [edi - 108] ; ecx =  qlp_coeff[26] * data[i-27]
  1156. add ebp, ecx ; sum += qlp_coeff[26] * data[i-27]
  1157. mov ecx, [eax + 100] ; ecx =  qlp_coeff[25]
  1158. imul ecx, [edi - 104] ; ecx =  qlp_coeff[25] * data[i-26]
  1159. add ebp, ecx ; sum += qlp_coeff[25] * data[i-26]
  1160. mov ecx, [eax + 96] ; ecx =  qlp_coeff[24]
  1161. imul ecx, [edi - 100] ; ecx =  qlp_coeff[24] * data[i-25]
  1162. add ebp, ecx ; sum += qlp_coeff[24] * data[i-25]
  1163. mov ecx, [eax + 92] ; ecx =  qlp_coeff[23]
  1164. imul ecx, [edi - 96] ; ecx =  qlp_coeff[23] * data[i-24]
  1165. add ebp, ecx ; sum += qlp_coeff[23] * data[i-24]
  1166. mov ecx, [eax + 88] ; ecx =  qlp_coeff[22]
  1167. imul ecx, [edi - 92] ; ecx =  qlp_coeff[22] * data[i-23]
  1168. add ebp, ecx ; sum += qlp_coeff[22] * data[i-23]
  1169. mov ecx, [eax + 84] ; ecx =  qlp_coeff[21]
  1170. imul ecx, [edi - 88] ; ecx =  qlp_coeff[21] * data[i-22]
  1171. add ebp, ecx ; sum += qlp_coeff[21] * data[i-22]
  1172. mov ecx, [eax + 80] ; ecx =  qlp_coeff[20]
  1173. imul ecx, [edi - 84] ; ecx =  qlp_coeff[20] * data[i-21]
  1174. add ebp, ecx ; sum += qlp_coeff[20] * data[i-21]
  1175. mov ecx, [eax + 76] ; ecx =  qlp_coeff[19]
  1176. imul ecx, [edi - 80] ; ecx =  qlp_coeff[19] * data[i-20]
  1177. add ebp, ecx ; sum += qlp_coeff[19] * data[i-20]
  1178. mov ecx, [eax + 72] ; ecx =  qlp_coeff[18]
  1179. imul ecx, [edi - 76] ; ecx =  qlp_coeff[18] * data[i-19]
  1180. add ebp, ecx ; sum += qlp_coeff[18] * data[i-19]
  1181. mov ecx, [eax + 68] ; ecx =  qlp_coeff[17]
  1182. imul ecx, [edi - 72] ; ecx =  qlp_coeff[17] * data[i-18]
  1183. add ebp, ecx ; sum += qlp_coeff[17] * data[i-18]
  1184. mov ecx, [eax + 64] ; ecx =  qlp_coeff[16]
  1185. imul ecx, [edi - 68] ; ecx =  qlp_coeff[16] * data[i-17]
  1186. add ebp, ecx ; sum += qlp_coeff[16] * data[i-17]
  1187. mov ecx, [eax + 60] ; ecx =  qlp_coeff[15]
  1188. imul ecx, [edi - 64] ; ecx =  qlp_coeff[15] * data[i-16]
  1189. add ebp, ecx ; sum += qlp_coeff[15] * data[i-16]
  1190. mov ecx, [eax + 56] ; ecx =  qlp_coeff[14]
  1191. imul ecx, [edi - 60] ; ecx =  qlp_coeff[14] * data[i-15]
  1192. add ebp, ecx ; sum += qlp_coeff[14] * data[i-15]
  1193. mov ecx, [eax + 52] ; ecx =  qlp_coeff[13]
  1194. imul ecx, [edi - 56] ; ecx =  qlp_coeff[13] * data[i-14]
  1195. add ebp, ecx ; sum += qlp_coeff[13] * data[i-14]
  1196. mov ecx, [eax + 48] ; ecx =  qlp_coeff[12]
  1197. imul ecx, [edi - 52] ; ecx =  qlp_coeff[12] * data[i-13]
  1198. add ebp, ecx ; sum += qlp_coeff[12] * data[i-13]
  1199. mov ecx, [eax + 44] ; ecx =  qlp_coeff[11]
  1200. imul ecx, [edi - 48] ; ecx =  qlp_coeff[11] * data[i-12]
  1201. add ebp, ecx ; sum += qlp_coeff[11] * data[i-12]
  1202. mov ecx, [eax + 40] ; ecx =  qlp_coeff[10]
  1203. imul ecx, [edi - 44] ; ecx =  qlp_coeff[10] * data[i-11]
  1204. add ebp, ecx ; sum += qlp_coeff[10] * data[i-11]
  1205. mov ecx, [eax + 36] ; ecx =  qlp_coeff[ 9]
  1206. imul ecx, [edi - 40] ; ecx =  qlp_coeff[ 9] * data[i-10]
  1207. add ebp, ecx ; sum += qlp_coeff[ 9] * data[i-10]
  1208. mov ecx, [eax + 32] ; ecx =  qlp_coeff[ 8]
  1209. imul ecx, [edi - 36] ; ecx =  qlp_coeff[ 8] * data[i- 9]
  1210. add ebp, ecx ; sum += qlp_coeff[ 8] * data[i- 9]
  1211. mov ecx, [eax + 28] ; ecx =  qlp_coeff[ 7]
  1212. imul ecx, [edi - 32] ; ecx =  qlp_coeff[ 7] * data[i- 8]
  1213. add ebp, ecx ; sum += qlp_coeff[ 7] * data[i- 8]
  1214. mov ecx, [eax + 24] ; ecx =  qlp_coeff[ 6]
  1215. imul ecx, [edi - 28] ; ecx =  qlp_coeff[ 6] * data[i- 7]
  1216. add ebp, ecx ; sum += qlp_coeff[ 6] * data[i- 7]
  1217. mov ecx, [eax + 20] ; ecx =  qlp_coeff[ 5]
  1218. imul ecx, [edi - 24] ; ecx =  qlp_coeff[ 5] * data[i- 6]
  1219. add ebp, ecx ; sum += qlp_coeff[ 5] * data[i- 6]
  1220. mov ecx, [eax + 16] ; ecx =  qlp_coeff[ 4]
  1221. imul ecx, [edi - 20] ; ecx =  qlp_coeff[ 4] * data[i- 5]
  1222. add ebp, ecx ; sum += qlp_coeff[ 4] * data[i- 5]
  1223. mov ecx, [eax + 12] ; ecx =  qlp_coeff[ 3]
  1224. imul ecx, [edi - 16] ; ecx =  qlp_coeff[ 3] * data[i- 4]
  1225. add ebp, ecx ; sum += qlp_coeff[ 3] * data[i- 4]
  1226. mov ecx, [eax + 8] ; ecx =  qlp_coeff[ 2]
  1227. imul ecx, [edi - 12] ; ecx =  qlp_coeff[ 2] * data[i- 3]
  1228. add ebp, ecx ; sum += qlp_coeff[ 2] * data[i- 3]
  1229. mov ecx, [eax + 4] ; ecx =  qlp_coeff[ 1]
  1230. imul ecx, [edi - 8] ; ecx =  qlp_coeff[ 1] * data[i- 2]
  1231. add ebp, ecx ; sum += qlp_coeff[ 1] * data[i- 2]
  1232. mov ecx, [eax] ; ecx =  qlp_coeff[ 0] (NOTE: one byte missing from instruction)
  1233. imul ecx, [edi - 4] ; ecx =  qlp_coeff[ 0] * data[i- 1]
  1234. add ebp, ecx ; sum += qlp_coeff[ 0] * data[i- 1]
  1235. .jumper_0:
  1236. mov cl, [esp + 36]
  1237. sar ebp, cl ; ebp = (sum >> lp_quantization)
  1238. add ebp, [esi + edi] ; ebp = residual[i] + (sum >> lp_quantization)
  1239. mov [edi], ebp ; data[i] = residual[i] + (sum >> lp_quantization)
  1240. add edi, byte 4
  1241. dec ebx
  1242. jz short .end
  1243. xor ebp, ebp
  1244. jmp edx
  1245. .end:
  1246. pop edi
  1247. pop esi
  1248. pop ebx
  1249. pop ebp
  1250. ret
  1251. ; WATCHOUT: this routine works on 16 bit data which means bits-per-sample for
  1252. ; the channel must be <= 16.  Especially note that this routine cannot be used
  1253. ; for side-channel coded 16bps channels since the effective bps is 17.
  1254. ; WATCHOUT: this routine requires that each data array have a buffer of up to
  1255. ; 3 zeroes in front (at negative indices) for alignment purposes, i.e. for each
  1256. ; channel n, data[n][-1] through data[n][-3] should be accessible and zero.
  1257. ALIGN 16
  1258. cident FLAC__lpc_restore_signal_asm_ia32_mmx
  1259. ;[esp + 40] data[]
  1260. ;[esp + 36] lp_quantization
  1261. ;[esp + 32] order
  1262. ;[esp + 28] qlp_coeff[]
  1263. ;[esp + 24] data_len
  1264. ;[esp + 20] residual[]
  1265. ;ASSERT(order > 0)
  1266. push ebp
  1267. push ebx
  1268. push esi
  1269. push edi
  1270. mov esi, [esp + 20]
  1271. mov edi, [esp + 40]
  1272. mov eax, [esp + 32]
  1273. mov ebx, [esp + 24]
  1274. test ebx, ebx
  1275. jz near .end ; do nothing if data_len == 0
  1276. cmp eax, byte 4
  1277. jb near FLAC__lpc_restore_signal_asm_ia32.begin
  1278. mov edx, [esp + 28]
  1279. movd mm6, [esp + 36]
  1280. mov ebp, esp
  1281. and esp, 0xfffffff8
  1282. xor ecx, ecx
  1283. .copy_qlp_loop:
  1284. push word [edx + 4 * ecx]
  1285. inc ecx
  1286. cmp ecx, eax
  1287. jnz short .copy_qlp_loop
  1288. and ecx, 0x3
  1289. test ecx, ecx
  1290. je short .za_end
  1291. sub ecx, byte 4
  1292. .za_loop:
  1293. push word 0
  1294. inc eax
  1295. inc ecx
  1296. jnz short .za_loop
  1297. .za_end:
  1298. movq mm5, [esp + 2 * eax - 8]
  1299. movd mm4, [edi - 16]
  1300. punpckldq mm4, [edi - 12]
  1301. movd mm0, [edi - 8]
  1302. punpckldq mm0, [edi - 4]
  1303. packssdw mm4, mm0
  1304. cmp eax, byte 4
  1305. jnbe short .mmx_4more
  1306. align 16
  1307. .mmx_4_loop_i:
  1308. movq mm7, mm4
  1309. pmaddwd mm7, mm5
  1310. movq mm0, mm7
  1311. punpckhdq mm7, mm7
  1312. paddd mm7, mm0
  1313. psrad mm7, mm6
  1314. movd mm1, [esi]
  1315. paddd mm7, mm1
  1316. movd [edi], mm7
  1317. psllq mm7, 48
  1318. psrlq mm4, 16
  1319. por mm4, mm7
  1320. add esi, byte 4
  1321. add edi, byte 4
  1322. dec ebx
  1323. jnz .mmx_4_loop_i
  1324. jmp .mmx_end
  1325. .mmx_4more:
  1326. shl eax, 2
  1327. neg eax
  1328. add eax, byte 16
  1329. align 16
  1330. .mmx_4more_loop_i:
  1331. mov ecx, edi
  1332. add ecx, eax
  1333. mov edx, esp
  1334. movq mm7, mm4
  1335. pmaddwd mm7, mm5
  1336. align 16
  1337. .mmx_4more_loop_j:
  1338. movd mm0, [ecx - 16]
  1339. punpckldq mm0, [ecx - 12]
  1340. movd mm1, [ecx - 8]
  1341. punpckldq mm1, [ecx - 4]
  1342. packssdw mm0, mm1
  1343. pmaddwd mm0, [edx]
  1344. paddd mm7, mm0
  1345. add edx, byte 8
  1346. add ecx, byte 16
  1347. cmp ecx, edi
  1348. jnz .mmx_4more_loop_j
  1349. movq mm0, mm7
  1350. punpckhdq mm7, mm7
  1351. paddd mm7, mm0
  1352. psrad mm7, mm6
  1353. movd mm1, [esi]
  1354. paddd mm7, mm1
  1355. movd [edi], mm7
  1356. psllq mm7, 48
  1357. psrlq mm4, 16
  1358. por mm4, mm7
  1359. add esi, byte 4
  1360. add edi, byte 4
  1361. dec ebx
  1362. jnz short .mmx_4more_loop_i
  1363. .mmx_end:
  1364. emms
  1365. mov esp, ebp
  1366. .end:
  1367. pop edi
  1368. pop esi
  1369. pop ebx
  1370. pop ebp
  1371. ret
  1372. end