/media/libvpx/vp8/common/arm/neon/sixtappredict4x4_neon.asm

http://github.com/zpao/v8monkey · Assembly · 422 lines · 303 code · 97 blank · 22 comment · 0 complexity · 0ae14be4b7fbc1d66bc46fea9be7fbd7 MD5 · raw file

  1. ;
  2. ; Copyright (c) 2010 The WebM project authors. All Rights Reserved.
  3. ;
  4. ; Use of this source code is governed by a BSD-style license
  5. ; that can be found in the LICENSE file in the root of the source
  6. ; tree. An additional intellectual property rights grant can be found
  7. ; in the file PATENTS. All contributing project authors may
  8. ; be found in the AUTHORS file in the root of the source tree.
  9. ;
  10. EXPORT |vp8_sixtap_predict_neon|
  11. ARM
  12. REQUIRE8
  13. PRESERVE8
  14. AREA ||.text||, CODE, READONLY, ALIGN=2
  15. filter4_coeff
  16. DCD 0, 0, 128, 0, 0, 0, 0, 0
  17. DCD 0, -6, 123, 12, -1, 0, 0, 0
  18. DCD 2, -11, 108, 36, -8, 1, 0, 0
  19. DCD 0, -9, 93, 50, -6, 0, 0, 0
  20. DCD 3, -16, 77, 77, -16, 3, 0, 0
  21. DCD 0, -6, 50, 93, -9, 0, 0, 0
  22. DCD 1, -8, 36, 108, -11, 2, 0, 0
  23. DCD 0, -1, 12, 123, -6, 0, 0, 0
  24. ; r0 unsigned char *src_ptr,
  25. ; r1 int src_pixels_per_line,
  26. ; r2 int xoffset,
  27. ; r3 int yoffset,
  28. ; stack(r4) unsigned char *dst_ptr,
  29. ; stack(lr) int dst_pitch
  30. |vp8_sixtap_predict_neon| PROC
  31. push {r4, lr}
  32. adr r12, filter4_coeff
  33. ldr r4, [sp, #8] ;load parameters from stack
  34. ldr lr, [sp, #12] ;load parameters from stack
  35. cmp r2, #0 ;skip first_pass filter if xoffset=0
  36. beq secondpass_filter4x4_only
  37. add r2, r12, r2, lsl #5 ;calculate filter location
  38. cmp r3, #0 ;skip second_pass filter if yoffset=0
  39. vld1.s32 {q14, q15}, [r2] ;load first_pass filter
  40. beq firstpass_filter4x4_only
  41. vabs.s32 q12, q14 ;get abs(filer_parameters)
  42. vabs.s32 q13, q15
  43. sub r0, r0, #2 ;go back 2 columns of src data
  44. sub r0, r0, r1, lsl #1 ;go back 2 lines of src data
  45. ;First pass: output_height lines x output_width columns (9x4)
  46. vld1.u8 {q3}, [r0], r1 ;load first 4-line src data
  47. vdup.8 d0, d24[0] ;first_pass filter (d0-d5)
  48. vld1.u8 {q4}, [r0], r1
  49. vdup.8 d1, d24[4]
  50. vld1.u8 {q5}, [r0], r1
  51. vdup.8 d2, d25[0]
  52. vld1.u8 {q6}, [r0], r1
  53. vdup.8 d3, d25[4]
  54. vdup.8 d4, d26[0]
  55. vdup.8 d5, d26[4]
  56. pld [r0]
  57. pld [r0, r1]
  58. pld [r0, r1, lsl #1]
  59. vext.8 d18, d6, d7, #5 ;construct src_ptr[3]
  60. vext.8 d19, d8, d9, #5
  61. vext.8 d20, d10, d11, #5
  62. vext.8 d21, d12, d13, #5
  63. vswp d7, d8 ;discard 2nd half data after src_ptr[3] is done
  64. vswp d11, d12
  65. vzip.32 d18, d19 ;put 2-line data in 1 register (src_ptr[3])
  66. vzip.32 d20, d21
  67. vmull.u8 q7, d18, d5 ;(src_ptr[3] * vp8_filter[5])
  68. vmull.u8 q8, d20, d5
  69. vmov q4, q3 ;keep original src data in q4 q6
  70. vmov q6, q5
  71. vzip.32 d6, d7 ;construct src_ptr[-2], and put 2-line data together
  72. vzip.32 d10, d11
  73. vshr.u64 q9, q4, #8 ;construct src_ptr[-1]
  74. vshr.u64 q10, q6, #8
  75. vmlal.u8 q7, d6, d0 ;+(src_ptr[-2] * vp8_filter[0])
  76. vmlal.u8 q8, d10, d0
  77. vzip.32 d18, d19 ;put 2-line data in 1 register (src_ptr[-1])
  78. vzip.32 d20, d21
  79. vshr.u64 q3, q4, #32 ;construct src_ptr[2]
  80. vshr.u64 q5, q6, #32
  81. vmlsl.u8 q7, d18, d1 ;-(src_ptr[-1] * vp8_filter[1])
  82. vmlsl.u8 q8, d20, d1
  83. vzip.32 d6, d7 ;put 2-line data in 1 register (src_ptr[2])
  84. vzip.32 d10, d11
  85. vshr.u64 q9, q4, #16 ;construct src_ptr[0]
  86. vshr.u64 q10, q6, #16
  87. vmlsl.u8 q7, d6, d4 ;-(src_ptr[2] * vp8_filter[4])
  88. vmlsl.u8 q8, d10, d4
  89. vzip.32 d18, d19 ;put 2-line data in 1 register (src_ptr[0])
  90. vzip.32 d20, d21
  91. vshr.u64 q3, q4, #24 ;construct src_ptr[1]
  92. vshr.u64 q5, q6, #24
  93. vmlal.u8 q7, d18, d2 ;(src_ptr[0] * vp8_filter[2])
  94. vmlal.u8 q8, d20, d2
  95. vzip.32 d6, d7 ;put 2-line data in 1 register (src_ptr[1])
  96. vzip.32 d10, d11
  97. vmull.u8 q9, d6, d3 ;(src_ptr[1] * vp8_filter[3])
  98. vmull.u8 q10, d10, d3
  99. vld1.u8 {q3}, [r0], r1 ;load rest 5-line src data
  100. vld1.u8 {q4}, [r0], r1
  101. vqadd.s16 q7, q9 ;sum of all (src_data*filter_parameters)
  102. vqadd.s16 q8, q10
  103. vld1.u8 {q5}, [r0], r1
  104. vld1.u8 {q6}, [r0], r1
  105. vqrshrun.s16 d27, q7, #7 ;shift/round/saturate to u8
  106. vqrshrun.s16 d28, q8, #7
  107. ;First Pass on rest 5-line data
  108. vld1.u8 {q11}, [r0], r1
  109. vext.8 d18, d6, d7, #5 ;construct src_ptr[3]
  110. vext.8 d19, d8, d9, #5
  111. vext.8 d20, d10, d11, #5
  112. vext.8 d21, d12, d13, #5
  113. vswp d7, d8 ;discard 2nd half data after src_ptr[3] is done
  114. vswp d11, d12
  115. vzip.32 d18, d19 ;put 2-line data in 1 register (src_ptr[3])
  116. vzip.32 d20, d21
  117. vext.8 d31, d22, d23, #5 ;construct src_ptr[3]
  118. vmull.u8 q7, d18, d5 ;(src_ptr[3] * vp8_filter[5])
  119. vmull.u8 q8, d20, d5
  120. vmull.u8 q12, d31, d5 ;(src_ptr[3] * vp8_filter[5])
  121. vmov q4, q3 ;keep original src data in q4 q6
  122. vmov q6, q5
  123. vzip.32 d6, d7 ;construct src_ptr[-2], and put 2-line data together
  124. vzip.32 d10, d11
  125. vshr.u64 q9, q4, #8 ;construct src_ptr[-1]
  126. vshr.u64 q10, q6, #8
  127. vmlal.u8 q7, d6, d0 ;+(src_ptr[-2] * vp8_filter[0])
  128. vmlal.u8 q8, d10, d0
  129. vmlal.u8 q12, d22, d0 ;(src_ptr[-2] * vp8_filter[0])
  130. vzip.32 d18, d19 ;put 2-line data in 1 register (src_ptr[-1])
  131. vzip.32 d20, d21
  132. vshr.u64 q3, q4, #32 ;construct src_ptr[2]
  133. vshr.u64 q5, q6, #32
  134. vext.8 d31, d22, d23, #1 ;construct src_ptr[-1]
  135. vmlsl.u8 q7, d18, d1 ;-(src_ptr[-1] * vp8_filter[1])
  136. vmlsl.u8 q8, d20, d1
  137. vmlsl.u8 q12, d31, d1 ;-(src_ptr[-1] * vp8_filter[1])
  138. vzip.32 d6, d7 ;put 2-line data in 1 register (src_ptr[2])
  139. vzip.32 d10, d11
  140. vshr.u64 q9, q4, #16 ;construct src_ptr[0]
  141. vshr.u64 q10, q6, #16
  142. vext.8 d31, d22, d23, #4 ;construct src_ptr[2]
  143. vmlsl.u8 q7, d6, d4 ;-(src_ptr[2] * vp8_filter[4])
  144. vmlsl.u8 q8, d10, d4
  145. vmlsl.u8 q12, d31, d4 ;-(src_ptr[2] * vp8_filter[4])
  146. vzip.32 d18, d19 ;put 2-line data in 1 register (src_ptr[0])
  147. vzip.32 d20, d21
  148. vshr.u64 q3, q4, #24 ;construct src_ptr[1]
  149. vshr.u64 q5, q6, #24
  150. vext.8 d31, d22, d23, #2 ;construct src_ptr[0]
  151. vmlal.u8 q7, d18, d2 ;(src_ptr[0] * vp8_filter[2])
  152. vmlal.u8 q8, d20, d2
  153. vmlal.u8 q12, d31, d2 ;(src_ptr[0] * vp8_filter[2])
  154. vzip.32 d6, d7 ;put 2-line data in 1 register (src_ptr[1])
  155. vzip.32 d10, d11
  156. vext.8 d31, d22, d23, #3 ;construct src_ptr[1]
  157. vmull.u8 q9, d6, d3 ;(src_ptr[1] * vp8_filter[3])
  158. vmull.u8 q10, d10, d3
  159. vmull.u8 q11, d31, d3 ;(src_ptr[1] * vp8_filter[3])
  160. add r3, r12, r3, lsl #5
  161. vqadd.s16 q7, q9 ;sum of all (src_data*filter_parameters)
  162. vqadd.s16 q8, q10
  163. vqadd.s16 q12, q11
  164. vext.8 d23, d27, d28, #4
  165. vld1.s32 {q5, q6}, [r3] ;load second_pass filter
  166. vqrshrun.s16 d29, q7, #7 ;shift/round/saturate to u8
  167. vqrshrun.s16 d30, q8, #7
  168. vqrshrun.s16 d31, q12, #7
  169. ;Second pass: 4x4
  170. vabs.s32 q7, q5
  171. vabs.s32 q8, q6
  172. vext.8 d24, d28, d29, #4
  173. vext.8 d25, d29, d30, #4
  174. vext.8 d26, d30, d31, #4
  175. vdup.8 d0, d14[0] ;second_pass filter parameters (d0-d5)
  176. vdup.8 d1, d14[4]
  177. vdup.8 d2, d15[0]
  178. vdup.8 d3, d15[4]
  179. vdup.8 d4, d16[0]
  180. vdup.8 d5, d16[4]
  181. vmull.u8 q3, d27, d0 ;(src_ptr[-2] * vp8_filter[0])
  182. vmull.u8 q4, d28, d0
  183. vmull.u8 q5, d25, d5 ;(src_ptr[3] * vp8_filter[5])
  184. vmull.u8 q6, d26, d5
  185. vmlsl.u8 q3, d29, d4 ;-(src_ptr[2] * vp8_filter[4])
  186. vmlsl.u8 q4, d30, d4
  187. vmlsl.u8 q5, d23, d1 ;-(src_ptr[-1] * vp8_filter[1])
  188. vmlsl.u8 q6, d24, d1
  189. vmlal.u8 q3, d28, d2 ;(src_ptr[0] * vp8_filter[2])
  190. vmlal.u8 q4, d29, d2
  191. vmlal.u8 q5, d24, d3 ;(src_ptr[1] * vp8_filter[3])
  192. vmlal.u8 q6, d25, d3
  193. add r0, r4, lr
  194. add r1, r0, lr
  195. add r2, r1, lr
  196. vqadd.s16 q5, q3 ;sum of all (src_data*filter_parameters)
  197. vqadd.s16 q6, q4
  198. vqrshrun.s16 d3, q5, #7 ;shift/round/saturate to u8
  199. vqrshrun.s16 d4, q6, #7
  200. vst1.32 {d3[0]}, [r4] ;store result
  201. vst1.32 {d3[1]}, [r0]
  202. vst1.32 {d4[0]}, [r1]
  203. vst1.32 {d4[1]}, [r2]
  204. pop {r4, pc}
  205. ;---------------------
  206. firstpass_filter4x4_only
  207. vabs.s32 q12, q14 ;get abs(filer_parameters)
  208. vabs.s32 q13, q15
  209. sub r0, r0, #2 ;go back 2 columns of src data
  210. ;First pass: output_height lines x output_width columns (4x4)
  211. vld1.u8 {q3}, [r0], r1 ;load first 4-line src data
  212. vdup.8 d0, d24[0] ;first_pass filter (d0-d5)
  213. vld1.u8 {q4}, [r0], r1
  214. vdup.8 d1, d24[4]
  215. vld1.u8 {q5}, [r0], r1
  216. vdup.8 d2, d25[0]
  217. vld1.u8 {q6}, [r0], r1
  218. vdup.8 d3, d25[4]
  219. vdup.8 d4, d26[0]
  220. vdup.8 d5, d26[4]
  221. vext.8 d18, d6, d7, #5 ;construct src_ptr[3]
  222. vext.8 d19, d8, d9, #5
  223. vext.8 d20, d10, d11, #5
  224. vext.8 d21, d12, d13, #5
  225. vswp d7, d8 ;discard 2nd half data after src_ptr[3] is done
  226. vswp d11, d12
  227. vzip.32 d18, d19 ;put 2-line data in 1 register (src_ptr[3])
  228. vzip.32 d20, d21
  229. vmull.u8 q7, d18, d5 ;(src_ptr[3] * vp8_filter[5])
  230. vmull.u8 q8, d20, d5
  231. vmov q4, q3 ;keep original src data in q4 q6
  232. vmov q6, q5
  233. vzip.32 d6, d7 ;construct src_ptr[-2], and put 2-line data together
  234. vzip.32 d10, d11
  235. vshr.u64 q9, q4, #8 ;construct src_ptr[-1]
  236. vshr.u64 q10, q6, #8
  237. vmlal.u8 q7, d6, d0 ;+(src_ptr[-2] * vp8_filter[0])
  238. vmlal.u8 q8, d10, d0
  239. vzip.32 d18, d19 ;put 2-line data in 1 register (src_ptr[-1])
  240. vzip.32 d20, d21
  241. vshr.u64 q3, q4, #32 ;construct src_ptr[2]
  242. vshr.u64 q5, q6, #32
  243. vmlsl.u8 q7, d18, d1 ;-(src_ptr[-1] * vp8_filter[1])
  244. vmlsl.u8 q8, d20, d1
  245. vzip.32 d6, d7 ;put 2-line data in 1 register (src_ptr[2])
  246. vzip.32 d10, d11
  247. vshr.u64 q9, q4, #16 ;construct src_ptr[0]
  248. vshr.u64 q10, q6, #16
  249. vmlsl.u8 q7, d6, d4 ;-(src_ptr[2] * vp8_filter[4])
  250. vmlsl.u8 q8, d10, d4
  251. vzip.32 d18, d19 ;put 2-line data in 1 register (src_ptr[0])
  252. vzip.32 d20, d21
  253. vshr.u64 q3, q4, #24 ;construct src_ptr[1]
  254. vshr.u64 q5, q6, #24
  255. vmlal.u8 q7, d18, d2 ;(src_ptr[0] * vp8_filter[2])
  256. vmlal.u8 q8, d20, d2
  257. vzip.32 d6, d7 ;put 2-line data in 1 register (src_ptr[1])
  258. vzip.32 d10, d11
  259. vmull.u8 q9, d6, d3 ;(src_ptr[1] * vp8_filter[3])
  260. vmull.u8 q10, d10, d3
  261. add r0, r4, lr
  262. add r1, r0, lr
  263. add r2, r1, lr
  264. vqadd.s16 q7, q9 ;sum of all (src_data*filter_parameters)
  265. vqadd.s16 q8, q10
  266. vqrshrun.s16 d27, q7, #7 ;shift/round/saturate to u8
  267. vqrshrun.s16 d28, q8, #7
  268. vst1.32 {d27[0]}, [r4] ;store result
  269. vst1.32 {d27[1]}, [r0]
  270. vst1.32 {d28[0]}, [r1]
  271. vst1.32 {d28[1]}, [r2]
  272. pop {r4, pc}
  273. ;---------------------
  274. secondpass_filter4x4_only
  275. sub r0, r0, r1, lsl #1
  276. add r3, r12, r3, lsl #5
  277. vld1.32 {d27[0]}, [r0], r1 ;load src data
  278. vld1.s32 {q5, q6}, [r3] ;load second_pass filter
  279. vld1.32 {d27[1]}, [r0], r1
  280. vabs.s32 q7, q5
  281. vld1.32 {d28[0]}, [r0], r1
  282. vabs.s32 q8, q6
  283. vld1.32 {d28[1]}, [r0], r1
  284. vdup.8 d0, d14[0] ;second_pass filter parameters (d0-d5)
  285. vld1.32 {d29[0]}, [r0], r1
  286. vdup.8 d1, d14[4]
  287. vld1.32 {d29[1]}, [r0], r1
  288. vdup.8 d2, d15[0]
  289. vld1.32 {d30[0]}, [r0], r1
  290. vdup.8 d3, d15[4]
  291. vld1.32 {d30[1]}, [r0], r1
  292. vdup.8 d4, d16[0]
  293. vld1.32 {d31[0]}, [r0], r1
  294. vdup.8 d5, d16[4]
  295. vext.8 d23, d27, d28, #4
  296. vext.8 d24, d28, d29, #4
  297. vext.8 d25, d29, d30, #4
  298. vext.8 d26, d30, d31, #4
  299. vmull.u8 q3, d27, d0 ;(src_ptr[-2] * vp8_filter[0])
  300. vmull.u8 q4, d28, d0
  301. vmull.u8 q5, d25, d5 ;(src_ptr[3] * vp8_filter[5])
  302. vmull.u8 q6, d26, d5
  303. vmlsl.u8 q3, d29, d4 ;-(src_ptr[2] * vp8_filter[4])
  304. vmlsl.u8 q4, d30, d4
  305. vmlsl.u8 q5, d23, d1 ;-(src_ptr[-1] * vp8_filter[1])
  306. vmlsl.u8 q6, d24, d1
  307. vmlal.u8 q3, d28, d2 ;(src_ptr[0] * vp8_filter[2])
  308. vmlal.u8 q4, d29, d2
  309. vmlal.u8 q5, d24, d3 ;(src_ptr[1] * vp8_filter[3])
  310. vmlal.u8 q6, d25, d3
  311. add r0, r4, lr
  312. add r1, r0, lr
  313. add r2, r1, lr
  314. vqadd.s16 q5, q3 ;sum of all (src_data*filter_parameters)
  315. vqadd.s16 q6, q4
  316. vqrshrun.s16 d3, q5, #7 ;shift/round/saturate to u8
  317. vqrshrun.s16 d4, q6, #7
  318. vst1.32 {d3[0]}, [r4] ;store result
  319. vst1.32 {d3[1]}, [r0]
  320. vst1.32 {d4[0]}, [r1]
  321. vst1.32 {d4[1]}, [r2]
  322. pop {r4, pc}
  323. ENDP
  324. ;-----------------
  325. END