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

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__fixed_compute_best_predictor_asm_ia32_mmx_cmov
  33. code_section
  34. ; **********************************************************************
  35. ;
  36. ; unsigned FLAC__fixed_compute_best_predictor(const FLAC__int32 *data, unsigned data_len, FLAC__float residual_bits_per_sample[FLAC__MAX_FIXED_ORDER+1])
  37. ; {
  38. ;  FLAC__int32 last_error_0 = data[-1];
  39. ;  FLAC__int32 last_error_1 = data[-1] - data[-2];
  40. ;  FLAC__int32 last_error_2 = last_error_1 - (data[-2] - data[-3]);
  41. ;  FLAC__int32 last_error_3 = last_error_2 - (data[-2] - 2*data[-3] + data[-4]);
  42. ;  FLAC__int32 error, save;
  43. ;  FLAC__uint32 total_error_0 = 0, total_error_1 = 0, total_error_2 = 0, total_error_3 = 0, total_error_4 = 0;
  44. ;  unsigned i, order;
  45. ;
  46. ;  for(i = 0; i < data_len; i++) {
  47. ;  error  = data[i]     ; total_error_0 += local_abs(error);                      save = error;
  48. ;  error -= last_error_0; total_error_1 += local_abs(error); last_error_0 = save; save = error;
  49. ;  error -= last_error_1; total_error_2 += local_abs(error); last_error_1 = save; save = error;
  50. ;  error -= last_error_2; total_error_3 += local_abs(error); last_error_2 = save; save = error;
  51. ;  error -= last_error_3; total_error_4 += local_abs(error); last_error_3 = save;
  52. ;  }
  53. ;
  54. ;  if(total_error_0 < min(min(min(total_error_1, total_error_2), total_error_3), total_error_4))
  55. ;  order = 0;
  56. ;  else if(total_error_1 < min(min(total_error_2, total_error_3), total_error_4))
  57. ;  order = 1;
  58. ;  else if(total_error_2 < min(total_error_3, total_error_4))
  59. ;  order = 2;
  60. ;  else if(total_error_3 < total_error_4)
  61. ;  order = 3;
  62. ;  else
  63. ;  order = 4;
  64. ;
  65. ;  residual_bits_per_sample[0] = (FLAC__float)((data_len > 0 && total_error_0 > 0) ? log(M_LN2 * (FLAC__double)total_error_0 / (FLAC__double)data_len) / M_LN2 : 0.0);
  66. ;  residual_bits_per_sample[1] = (FLAC__float)((data_len > 0 && total_error_1 > 0) ? log(M_LN2 * (FLAC__double)total_error_1 / (FLAC__double)data_len) / M_LN2 : 0.0);
  67. ;  residual_bits_per_sample[2] = (FLAC__float)((data_len > 0 && total_error_2 > 0) ? log(M_LN2 * (FLAC__double)total_error_2 / (FLAC__double)data_len) / M_LN2 : 0.0);
  68. ;  residual_bits_per_sample[3] = (FLAC__float)((data_len > 0 && total_error_3 > 0) ? log(M_LN2 * (FLAC__double)total_error_3 / (FLAC__double)data_len) / M_LN2 : 0.0);
  69. ;  residual_bits_per_sample[4] = (FLAC__float)((data_len > 0 && total_error_4 > 0) ? log(M_LN2 * (FLAC__double)total_error_4 / (FLAC__double)data_len) / M_LN2 : 0.0);
  70. ;
  71. ;  return order;
  72. ; }
  73. ALIGN 16
  74. cident FLAC__fixed_compute_best_predictor_asm_ia32_mmx_cmov
  75. ; esp + 36 == data[]
  76. ; esp + 40 == data_len
  77. ; esp + 44 == residual_bits_per_sample[]
  78. push ebp
  79. push ebx
  80. push esi
  81. push edi
  82. sub esp, byte 16
  83. ; qword [esp] == temp space for loading FLAC__uint64s to FPU regs
  84. ; ebx == &data[i]
  85. ; ecx == loop counter (i)
  86. ; ebp == order
  87. ; mm0 == total_error_1:total_error_0
  88. ; mm1 == total_error_2:total_error_3
  89. ; mm2 == :total_error_4
  90. ; mm3 == last_error_1:last_error_0
  91. ; mm4 == last_error_2:last_error_3
  92. mov ecx, [esp + 40] ; ecx = data_len
  93. test ecx, ecx
  94. jz near .data_len_is_0
  95. mov ebx, [esp + 36] ; ebx = data[]
  96. movd mm3, [ebx - 4] ; mm3 = 0:last_error_0
  97. movd mm2, [ebx - 8] ; mm2 = 0:data[-2]
  98. movd mm1, [ebx - 12] ; mm1 = 0:data[-3]
  99. movd mm0, [ebx - 16] ; mm0 = 0:data[-4]
  100. movq mm5, mm3 ; mm5 = 0:last_error_0
  101. psubd mm5, mm2 ; mm5 = 0:last_error_1
  102. punpckldq mm3, mm5 ; mm3 = last_error_1:last_error_0
  103. psubd mm2, mm1 ; mm2 = 0:data[-2] - data[-3]
  104. psubd mm5, mm2 ; mm5 = 0:last_error_2
  105. movq mm4, mm5 ; mm4 = 0:last_error_2
  106. psubd mm4, mm2 ; mm4 = 0:last_error_2 - (data[-2] - data[-3])
  107. paddd mm4, mm1 ; mm4 = 0:last_error_2 - (data[-2] - 2 * data[-3])
  108. psubd mm4, mm0 ; mm4 = 0:last_error_3
  109. punpckldq mm4, mm5 ; mm4 = last_error_2:last_error_3
  110. pxor mm0, mm0 ; mm0 = total_error_1:total_error_0
  111. pxor mm1, mm1 ; mm1 = total_error_2:total_error_3
  112. pxor mm2, mm2 ; mm2 = 0:total_error_4
  113. ALIGN 16
  114. .loop:
  115. movd mm7, [ebx] ; mm7 = 0:error_0
  116. add ebx, byte 4
  117. movq mm6, mm7 ; mm6 = 0:error_0
  118. psubd mm7, mm3 ; mm7 = :error_1
  119. punpckldq mm6, mm7 ; mm6 = error_1:error_0
  120. movq mm5, mm6 ; mm5 = error_1:error_0
  121. movq mm7, mm6 ; mm7 = error_1:error_0
  122. psubd mm5, mm3 ; mm5 = error_2:
  123. movq mm3, mm6 ; mm3 = error_1:error_0
  124. psrad mm6, 31
  125. pxor mm7, mm6
  126. psubd mm7, mm6 ; mm7 = abs(error_1):abs(error_0)
  127. paddd mm0, mm7 ; mm0 = total_error_1:total_error_0
  128. movq mm6, mm5 ; mm6 = error_2:
  129. psubd mm5, mm4 ; mm5 = error_3:
  130. punpckhdq mm5, mm6 ; mm5 = error_2:error_3
  131. movq mm7, mm5 ; mm7 = error_2:error_3
  132. movq mm6, mm5 ; mm6 = error_2:error_3
  133. psubd mm5, mm4 ; mm5 = :error_4
  134. movq mm4, mm6 ; mm4 = error_2:error_3
  135. psrad mm6, 31
  136. pxor mm7, mm6
  137. psubd mm7, mm6 ; mm7 = abs(error_2):abs(error_3)
  138. paddd mm1, mm7 ; mm1 = total_error_2:total_error_3
  139. movq mm6, mm5 ; mm6 = :error_4
  140. psrad mm5, 31
  141. pxor mm6, mm5
  142. psubd mm6, mm5 ; mm6 = :abs(error_4)
  143. paddd mm2, mm6 ; mm2 = :total_error_4
  144. dec ecx
  145. jnz short .loop
  146. ;  if(total_error_0 < min(min(min(total_error_1, total_error_2), total_error_3), total_error_4))
  147. ;  order = 0;
  148. ;  else if(total_error_1 < min(min(total_error_2, total_error_3), total_error_4))
  149. ;  order = 1;
  150. ;  else if(total_error_2 < min(total_error_3, total_error_4))
  151. ;  order = 2;
  152. ;  else if(total_error_3 < total_error_4)
  153. ;  order = 3;
  154. ;  else
  155. ;  order = 4;
  156. movq mm3, mm0 ; mm3 = total_error_1:total_error_0
  157. movd edi, mm2 ; edi = total_error_4
  158. movd esi, mm1 ; esi = total_error_3
  159. movd eax, mm0 ; eax = total_error_0
  160. punpckhdq mm1, mm1 ; mm1 = total_error_2:total_error_2
  161. punpckhdq mm3, mm3 ; mm3 = total_error_1:total_error_1
  162. movd edx, mm1 ; edx = total_error_2
  163. movd ecx, mm3 ; ecx = total_error_1
  164. xor ebx, ebx
  165. xor ebp, ebp
  166. inc ebx
  167. cmp ecx, eax
  168. cmovb eax, ecx ; eax = min(total_error_0, total_error_1)
  169. cmovbe ebp, ebx
  170. inc ebx
  171. cmp edx, eax
  172. cmovb eax, edx ; eax = min(total_error_0, total_error_1, total_error_2)
  173. cmovbe ebp, ebx
  174. inc ebx
  175. cmp esi, eax
  176. cmovb eax, esi ; eax = min(total_error_0, total_error_1, total_error_2, total_error_3)
  177. cmovbe ebp, ebx
  178. inc ebx
  179. cmp edi, eax
  180. cmovb eax, edi ; eax = min(total_error_0, total_error_1, total_error_2, total_error_3, total_error_4)
  181. cmovbe ebp, ebx
  182. movd ebx, mm0 ; ebx = total_error_0
  183. emms
  184. ;  residual_bits_per_sample[0] = (FLAC__float)((data_len > 0 && total_error_0 > 0) ? log(M_LN2 * (FLAC__double)total_error_0 / (FLAC__double)data_len) / M_LN2 : 0.0);
  185. ;  residual_bits_per_sample[1] = (FLAC__float)((data_len > 0 && total_error_1 > 0) ? log(M_LN2 * (FLAC__double)total_error_1 / (FLAC__double)data_len) / M_LN2 : 0.0);
  186. ;  residual_bits_per_sample[2] = (FLAC__float)((data_len > 0 && total_error_2 > 0) ? log(M_LN2 * (FLAC__double)total_error_2 / (FLAC__double)data_len) / M_LN2 : 0.0);
  187. ;  residual_bits_per_sample[3] = (FLAC__float)((data_len > 0 && total_error_3 > 0) ? log(M_LN2 * (FLAC__double)total_error_3 / (FLAC__double)data_len) / M_LN2 : 0.0);
  188. ;  residual_bits_per_sample[4] = (FLAC__float)((data_len > 0 && total_error_4 > 0) ? log(M_LN2 * (FLAC__double)total_error_4 / (FLAC__double)data_len) / M_LN2 : 0.0);
  189. xor eax, eax
  190. fild dword [esp + 40] ; ST = data_len (NOTE: assumes data_len is <2gigs)
  191. .rbps_0:
  192. test ebx, ebx
  193. jz .total_error_0_is_0
  194. fld1 ; ST = 1.0 data_len
  195. mov [esp], ebx
  196. mov [esp + 4], eax ; [esp] = (FLAC__uint64)total_error_0
  197. mov ebx, [esp + 44]
  198. fild qword [esp] ; ST = total_error_0 1.0 data_len
  199. fdiv st2 ; ST = total_error_0/data_len 1.0 data_len
  200. fldln2 ; ST = ln2 total_error_0/data_len 1.0 data_len
  201. fmulp st1 ; ST = ln2*total_error_0/data_len 1.0 data_len
  202. fyl2x ; ST = log2(ln2*total_error_0/data_len) data_len
  203. fstp dword [ebx] ; residual_bits_per_sample[0] = log2(ln2*total_error_0/data_len)   ST = data_len
  204. jmp short .rbps_1
  205. .total_error_0_is_0:
  206. mov ebx, [esp + 44]
  207. mov [ebx], eax ; residual_bits_per_sample[0] = 0.0
  208. .rbps_1:
  209. test ecx, ecx
  210. jz .total_error_1_is_0
  211. fld1 ; ST = 1.0 data_len
  212. mov [esp], ecx
  213. mov [esp + 4], eax ; [esp] = (FLAC__uint64)total_error_1
  214. fild qword [esp] ; ST = total_error_1 1.0 data_len
  215. fdiv st2 ; ST = total_error_1/data_len 1.0 data_len
  216. fldln2 ; ST = ln2 total_error_1/data_len 1.0 data_len
  217. fmulp st1 ; ST = ln2*total_error_1/data_len 1.0 data_len
  218. fyl2x ; ST = log2(ln2*total_error_1/data_len) data_len
  219. fstp dword [ebx + 4] ; residual_bits_per_sample[1] = log2(ln2*total_error_1/data_len)   ST = data_len
  220. jmp short .rbps_2
  221. .total_error_1_is_0:
  222. mov [ebx + 4], eax ; residual_bits_per_sample[1] = 0.0
  223. .rbps_2:
  224. test edx, edx
  225. jz .total_error_2_is_0
  226. fld1 ; ST = 1.0 data_len
  227. mov [esp], edx
  228. mov [esp + 4], eax ; [esp] = (FLAC__uint64)total_error_2
  229. fild qword [esp] ; ST = total_error_2 1.0 data_len
  230. fdiv st2 ; ST = total_error_2/data_len 1.0 data_len
  231. fldln2 ; ST = ln2 total_error_2/data_len 1.0 data_len
  232. fmulp st1 ; ST = ln2*total_error_2/data_len 1.0 data_len
  233. fyl2x ; ST = log2(ln2*total_error_2/data_len) data_len
  234. fstp dword [ebx + 8] ; residual_bits_per_sample[2] = log2(ln2*total_error_2/data_len)   ST = data_len
  235. jmp short .rbps_3
  236. .total_error_2_is_0:
  237. mov [ebx + 8], eax ; residual_bits_per_sample[2] = 0.0
  238. .rbps_3:
  239. test esi, esi
  240. jz .total_error_3_is_0
  241. fld1 ; ST = 1.0 data_len
  242. mov [esp], esi
  243. mov [esp + 4], eax ; [esp] = (FLAC__uint64)total_error_3
  244. fild qword [esp] ; ST = total_error_3 1.0 data_len
  245. fdiv st2 ; ST = total_error_3/data_len 1.0 data_len
  246. fldln2 ; ST = ln2 total_error_3/data_len 1.0 data_len
  247. fmulp st1 ; ST = ln2*total_error_3/data_len 1.0 data_len
  248. fyl2x ; ST = log2(ln2*total_error_3/data_len) data_len
  249. fstp dword [ebx + 12] ; residual_bits_per_sample[3] = log2(ln2*total_error_3/data_len)   ST = data_len
  250. jmp short .rbps_4
  251. .total_error_3_is_0:
  252. mov [ebx + 12], eax ; residual_bits_per_sample[3] = 0.0
  253. .rbps_4:
  254. test edi, edi
  255. jz .total_error_4_is_0
  256. fld1 ; ST = 1.0 data_len
  257. mov [esp], edi
  258. mov [esp + 4], eax ; [esp] = (FLAC__uint64)total_error_4
  259. fild qword [esp] ; ST = total_error_4 1.0 data_len
  260. fdiv st2 ; ST = total_error_4/data_len 1.0 data_len
  261. fldln2 ; ST = ln2 total_error_4/data_len 1.0 data_len
  262. fmulp st1 ; ST = ln2*total_error_4/data_len 1.0 data_len
  263. fyl2x ; ST = log2(ln2*total_error_4/data_len) data_len
  264. fstp dword [ebx + 16] ; residual_bits_per_sample[4] = log2(ln2*total_error_4/data_len)   ST = data_len
  265. jmp short .rbps_end
  266. .total_error_4_is_0:
  267. mov [ebx + 16], eax ; residual_bits_per_sample[4] = 0.0
  268. .rbps_end:
  269. fstp st0 ; ST = [empty]
  270. jmp short .end
  271. .data_len_is_0:
  272. ; data_len == 0, so residual_bits_per_sample[*] = 0.0
  273. xor ebp, ebp
  274. mov edi, [esp + 44]
  275. mov [edi], ebp
  276. mov [edi + 4], ebp
  277. mov [edi + 8], ebp
  278. mov [edi + 12], ebp
  279. mov [edi + 16], ebp
  280. add ebp, byte 4 ; order = 4
  281. .end:
  282. mov eax, ebp ; return order
  283. add esp, byte 16
  284. pop edi
  285. pop esi
  286. pop ebx
  287. pop ebp
  288. ret
  289. end