/media/libvpx/vp8/encoder/arm/neon/vp8_subpixelvariance16x16s_neon.asm

http://github.com/zpao/v8monkey · Assembly · 572 lines · 391 code · 110 blank · 71 comment · 0 complexity · 39f3aff7b4fc5fb978ab5378837c5fa7 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_variance_halfpixvar16x16_h_neon|
  11. EXPORT |vp8_variance_halfpixvar16x16_v_neon|
  12. EXPORT |vp8_variance_halfpixvar16x16_hv_neon|
  13. EXPORT |vp8_sub_pixel_variance16x16s_neon|
  14. ARM
  15. REQUIRE8
  16. PRESERVE8
  17. AREA ||.text||, CODE, READONLY, ALIGN=2
  18. ;================================================
  19. ;unsigned int vp8_variance_halfpixvar16x16_h_neon
  20. ;(
  21. ; unsigned char *src_ptr, r0
  22. ; int src_pixels_per_line, r1
  23. ; unsigned char *dst_ptr, r2
  24. ; int dst_pixels_per_line, r3
  25. ; unsigned int *sse
  26. ;);
  27. ;================================================
  28. |vp8_variance_halfpixvar16x16_h_neon| PROC
  29. push {lr}
  30. mov r12, #4 ;loop counter
  31. ldr lr, [sp, #4] ;load *sse from stack
  32. vmov.i8 q8, #0 ;q8 - sum
  33. vmov.i8 q9, #0 ;q9, q10 - sse
  34. vmov.i8 q10, #0
  35. ;First Pass: output_height lines x output_width columns (16x16)
  36. vp8_filt_fpo16x16s_4_0_loop_neon
  37. vld1.u8 {d0, d1, d2, d3}, [r0], r1 ;load src data
  38. vld1.8 {q11}, [r2], r3
  39. vld1.u8 {d4, d5, d6, d7}, [r0], r1
  40. vld1.8 {q12}, [r2], r3
  41. vld1.u8 {d8, d9, d10, d11}, [r0], r1
  42. vld1.8 {q13}, [r2], r3
  43. vld1.u8 {d12, d13, d14, d15}, [r0], r1
  44. ;pld [r0]
  45. ;pld [r0, r1]
  46. ;pld [r0, r1, lsl #1]
  47. vext.8 q1, q0, q1, #1 ;construct src_ptr[1]
  48. vext.8 q3, q2, q3, #1
  49. vext.8 q5, q4, q5, #1
  50. vext.8 q7, q6, q7, #1
  51. vrhadd.u8 q0, q0, q1 ;(src_ptr[0]+src_ptr[1])/round/shift right 1
  52. vld1.8 {q14}, [r2], r3
  53. vrhadd.u8 q1, q2, q3
  54. vrhadd.u8 q2, q4, q5
  55. vrhadd.u8 q3, q6, q7
  56. vsubl.u8 q4, d0, d22 ;diff
  57. vsubl.u8 q5, d1, d23
  58. vsubl.u8 q6, d2, d24
  59. vsubl.u8 q7, d3, d25
  60. vsubl.u8 q0, d4, d26
  61. vsubl.u8 q1, d5, d27
  62. vsubl.u8 q2, d6, d28
  63. vsubl.u8 q3, d7, d29
  64. vpadal.s16 q8, q4 ;sum
  65. vmlal.s16 q9, d8, d8 ;sse
  66. vmlal.s16 q10, d9, d9
  67. subs r12, r12, #1
  68. vpadal.s16 q8, q5
  69. vmlal.s16 q9, d10, d10
  70. vmlal.s16 q10, d11, d11
  71. vpadal.s16 q8, q6
  72. vmlal.s16 q9, d12, d12
  73. vmlal.s16 q10, d13, d13
  74. vpadal.s16 q8, q7
  75. vmlal.s16 q9, d14, d14
  76. vmlal.s16 q10, d15, d15
  77. vpadal.s16 q8, q0 ;sum
  78. vmlal.s16 q9, d0, d0 ;sse
  79. vmlal.s16 q10, d1, d1
  80. vpadal.s16 q8, q1
  81. vmlal.s16 q9, d2, d2
  82. vmlal.s16 q10, d3, d3
  83. vpadal.s16 q8, q2
  84. vmlal.s16 q9, d4, d4
  85. vmlal.s16 q10, d5, d5
  86. vpadal.s16 q8, q3
  87. vmlal.s16 q9, d6, d6
  88. vmlal.s16 q10, d7, d7
  89. bne vp8_filt_fpo16x16s_4_0_loop_neon
  90. vadd.u32 q10, q9, q10 ;accumulate sse
  91. vpaddl.s32 q0, q8 ;accumulate sum
  92. vpaddl.u32 q1, q10
  93. vadd.s64 d0, d0, d1
  94. vadd.u64 d1, d2, d3
  95. vmull.s32 q5, d0, d0
  96. vst1.32 {d1[0]}, [lr] ;store sse
  97. vshr.s32 d10, d10, #8
  98. vsub.s32 d0, d1, d10
  99. vmov.32 r0, d0[0] ;return
  100. pop {pc}
  101. ENDP
  102. ;================================================
  103. ;unsigned int vp8_variance_halfpixvar16x16_v_neon
  104. ;(
  105. ; unsigned char *src_ptr, r0
  106. ; int src_pixels_per_line, r1
  107. ; unsigned char *dst_ptr, r2
  108. ; int dst_pixels_per_line, r3
  109. ; unsigned int *sse
  110. ;);
  111. ;================================================
  112. |vp8_variance_halfpixvar16x16_v_neon| PROC
  113. push {lr}
  114. mov r12, #4 ;loop counter
  115. vld1.u8 {q0}, [r0], r1 ;load src data
  116. ldr lr, [sp, #4] ;load *sse from stack
  117. vmov.i8 q8, #0 ;q8 - sum
  118. vmov.i8 q9, #0 ;q9, q10 - sse
  119. vmov.i8 q10, #0
  120. vp8_filt_spo16x16s_0_4_loop_neon
  121. vld1.u8 {q2}, [r0], r1
  122. vld1.8 {q1}, [r2], r3
  123. vld1.u8 {q4}, [r0], r1
  124. vld1.8 {q3}, [r2], r3
  125. vld1.u8 {q6}, [r0], r1
  126. vld1.8 {q5}, [r2], r3
  127. vld1.u8 {q15}, [r0], r1
  128. vrhadd.u8 q0, q0, q2
  129. vld1.8 {q7}, [r2], r3
  130. vrhadd.u8 q2, q2, q4
  131. vrhadd.u8 q4, q4, q6
  132. vrhadd.u8 q6, q6, q15
  133. vsubl.u8 q11, d0, d2 ;diff
  134. vsubl.u8 q12, d1, d3
  135. vsubl.u8 q13, d4, d6
  136. vsubl.u8 q14, d5, d7
  137. vsubl.u8 q0, d8, d10
  138. vsubl.u8 q1, d9, d11
  139. vsubl.u8 q2, d12, d14
  140. vsubl.u8 q3, d13, d15
  141. vpadal.s16 q8, q11 ;sum
  142. vmlal.s16 q9, d22, d22 ;sse
  143. vmlal.s16 q10, d23, d23
  144. subs r12, r12, #1
  145. vpadal.s16 q8, q12
  146. vmlal.s16 q9, d24, d24
  147. vmlal.s16 q10, d25, d25
  148. vpadal.s16 q8, q13
  149. vmlal.s16 q9, d26, d26
  150. vmlal.s16 q10, d27, d27
  151. vpadal.s16 q8, q14
  152. vmlal.s16 q9, d28, d28
  153. vmlal.s16 q10, d29, d29
  154. vpadal.s16 q8, q0 ;sum
  155. vmlal.s16 q9, d0, d0 ;sse
  156. vmlal.s16 q10, d1, d1
  157. vpadal.s16 q8, q1
  158. vmlal.s16 q9, d2, d2
  159. vmlal.s16 q10, d3, d3
  160. vpadal.s16 q8, q2
  161. vmlal.s16 q9, d4, d4
  162. vmlal.s16 q10, d5, d5
  163. vmov q0, q15
  164. vpadal.s16 q8, q3
  165. vmlal.s16 q9, d6, d6
  166. vmlal.s16 q10, d7, d7
  167. bne vp8_filt_spo16x16s_0_4_loop_neon
  168. vadd.u32 q10, q9, q10 ;accumulate sse
  169. vpaddl.s32 q0, q8 ;accumulate sum
  170. vpaddl.u32 q1, q10
  171. vadd.s64 d0, d0, d1
  172. vadd.u64 d1, d2, d3
  173. vmull.s32 q5, d0, d0
  174. vst1.32 {d1[0]}, [lr] ;store sse
  175. vshr.s32 d10, d10, #8
  176. vsub.s32 d0, d1, d10
  177. vmov.32 r0, d0[0] ;return
  178. pop {pc}
  179. ENDP
  180. ;================================================
  181. ;unsigned int vp8_variance_halfpixvar16x16_hv_neon
  182. ;(
  183. ; unsigned char *src_ptr, r0
  184. ; int src_pixels_per_line, r1
  185. ; unsigned char *dst_ptr, r2
  186. ; int dst_pixels_per_line, r3
  187. ; unsigned int *sse
  188. ;);
  189. ;================================================
  190. |vp8_variance_halfpixvar16x16_hv_neon| PROC
  191. push {lr}
  192. vld1.u8 {d0, d1, d2, d3}, [r0], r1 ;load src data
  193. ldr lr, [sp, #4] ;load *sse from stack
  194. vmov.i8 q13, #0 ;q8 - sum
  195. vext.8 q1, q0, q1, #1 ;construct src_ptr[1]
  196. vmov.i8 q14, #0 ;q9, q10 - sse
  197. vmov.i8 q15, #0
  198. mov r12, #4 ;loop counter
  199. vrhadd.u8 q0, q0, q1 ;(src_ptr[0]+src_ptr[1])/round/shift right 1
  200. ;First Pass: output_height lines x output_width columns (17x16)
  201. vp8_filt16x16s_4_4_loop_neon
  202. vld1.u8 {d4, d5, d6, d7}, [r0], r1
  203. vld1.u8 {d8, d9, d10, d11}, [r0], r1
  204. vld1.u8 {d12, d13, d14, d15}, [r0], r1
  205. vld1.u8 {d16, d17, d18, d19}, [r0], r1
  206. ;pld [r0]
  207. ;pld [r0, r1]
  208. ;pld [r0, r1, lsl #1]
  209. vext.8 q3, q2, q3, #1 ;construct src_ptr[1]
  210. vext.8 q5, q4, q5, #1
  211. vext.8 q7, q6, q7, #1
  212. vext.8 q9, q8, q9, #1
  213. vrhadd.u8 q1, q2, q3 ;(src_ptr[0]+src_ptr[1])/round/shift right 1
  214. vrhadd.u8 q2, q4, q5
  215. vrhadd.u8 q3, q6, q7
  216. vrhadd.u8 q4, q8, q9
  217. vld1.8 {q5}, [r2], r3
  218. vrhadd.u8 q0, q0, q1
  219. vld1.8 {q6}, [r2], r3
  220. vrhadd.u8 q1, q1, q2
  221. vld1.8 {q7}, [r2], r3
  222. vrhadd.u8 q2, q2, q3
  223. vld1.8 {q8}, [r2], r3
  224. vrhadd.u8 q3, q3, q4
  225. vsubl.u8 q9, d0, d10 ;diff
  226. vsubl.u8 q10, d1, d11
  227. vsubl.u8 q11, d2, d12
  228. vsubl.u8 q12, d3, d13
  229. vsubl.u8 q0, d4, d14 ;diff
  230. vsubl.u8 q1, d5, d15
  231. vsubl.u8 q5, d6, d16
  232. vsubl.u8 q6, d7, d17
  233. vpadal.s16 q13, q9 ;sum
  234. vmlal.s16 q14, d18, d18 ;sse
  235. vmlal.s16 q15, d19, d19
  236. vpadal.s16 q13, q10 ;sum
  237. vmlal.s16 q14, d20, d20 ;sse
  238. vmlal.s16 q15, d21, d21
  239. vpadal.s16 q13, q11 ;sum
  240. vmlal.s16 q14, d22, d22 ;sse
  241. vmlal.s16 q15, d23, d23
  242. vpadal.s16 q13, q12 ;sum
  243. vmlal.s16 q14, d24, d24 ;sse
  244. vmlal.s16 q15, d25, d25
  245. subs r12, r12, #1
  246. vpadal.s16 q13, q0 ;sum
  247. vmlal.s16 q14, d0, d0 ;sse
  248. vmlal.s16 q15, d1, d1
  249. vpadal.s16 q13, q1 ;sum
  250. vmlal.s16 q14, d2, d2 ;sse
  251. vmlal.s16 q15, d3, d3
  252. vpadal.s16 q13, q5 ;sum
  253. vmlal.s16 q14, d10, d10 ;sse
  254. vmlal.s16 q15, d11, d11
  255. vmov q0, q4
  256. vpadal.s16 q13, q6 ;sum
  257. vmlal.s16 q14, d12, d12 ;sse
  258. vmlal.s16 q15, d13, d13
  259. bne vp8_filt16x16s_4_4_loop_neon
  260. vadd.u32 q15, q14, q15 ;accumulate sse
  261. vpaddl.s32 q0, q13 ;accumulate sum
  262. vpaddl.u32 q1, q15
  263. vadd.s64 d0, d0, d1
  264. vadd.u64 d1, d2, d3
  265. vmull.s32 q5, d0, d0
  266. vst1.32 {d1[0]}, [lr] ;store sse
  267. vshr.s32 d10, d10, #8
  268. vsub.s32 d0, d1, d10
  269. vmov.32 r0, d0[0] ;return
  270. pop {pc}
  271. ENDP
  272. ;==============================
  273. ; r0 unsigned char *src_ptr,
  274. ; r1 int src_pixels_per_line,
  275. ; r2 int xoffset,
  276. ; r3 int yoffset,
  277. ; stack unsigned char *dst_ptr,
  278. ; stack int dst_pixels_per_line,
  279. ; stack unsigned int *sse
  280. ;note: in vp8_find_best_half_pixel_step()(called when 8<Speed<15), and first call of vp8_find_best_sub_pixel_step()
  281. ;(called when speed<=8). xoffset/yoffset can only be 4 or 0, which means either by pass the filter,
  282. ;or filter coeff is {64, 64}. This simplified program only works in this situation.
  283. ;note: It happens that both xoffset and yoffset are zero. This can be handled in c code later.
  284. |vp8_sub_pixel_variance16x16s_neon| PROC
  285. push {r4, lr}
  286. ldr r4, [sp, #8] ;load *dst_ptr from stack
  287. ldr r12, [sp, #12] ;load dst_pixels_per_line from stack
  288. ldr lr, [sp, #16] ;load *sse from stack
  289. cmp r2, #0 ;skip first_pass filter if xoffset=0
  290. beq secondpass_bfilter16x16s_only
  291. cmp r3, #0 ;skip second_pass filter if yoffset=0
  292. beq firstpass_bfilter16x16s_only
  293. vld1.u8 {d0, d1, d2, d3}, [r0], r1 ;load src data
  294. sub sp, sp, #256 ;reserve space on stack for temporary storage
  295. vext.8 q1, q0, q1, #1 ;construct src_ptr[1]
  296. mov r3, sp
  297. mov r2, #4 ;loop counter
  298. vrhadd.u8 q0, q0, q1 ;(src_ptr[0]+src_ptr[1])/round/shift right 1
  299. ;First Pass: output_height lines x output_width columns (17x16)
  300. vp8e_filt_blk2d_fp16x16s_loop_neon
  301. vld1.u8 {d4, d5, d6, d7}, [r0], r1
  302. vld1.u8 {d8, d9, d10, d11}, [r0], r1
  303. vld1.u8 {d12, d13, d14, d15}, [r0], r1
  304. vld1.u8 {d16, d17, d18, d19}, [r0], r1
  305. ;pld [r0]
  306. ;pld [r0, r1]
  307. ;pld [r0, r1, lsl #1]
  308. vext.8 q3, q2, q3, #1 ;construct src_ptr[1]
  309. vext.8 q5, q4, q5, #1
  310. vext.8 q7, q6, q7, #1
  311. vext.8 q9, q8, q9, #1
  312. vrhadd.u8 q1, q2, q3 ;(src_ptr[0]+src_ptr[1])/round/shift right 1
  313. vrhadd.u8 q2, q4, q5
  314. vrhadd.u8 q3, q6, q7
  315. vrhadd.u8 q4, q8, q9
  316. vrhadd.u8 q0, q0, q1
  317. vrhadd.u8 q1, q1, q2
  318. vrhadd.u8 q2, q2, q3
  319. vrhadd.u8 q3, q3, q4
  320. subs r2, r2, #1
  321. vst1.u8 {d0, d1 ,d2, d3}, [r3]! ;store result
  322. vmov q0, q4
  323. vst1.u8 {d4, d5, d6, d7}, [r3]!
  324. bne vp8e_filt_blk2d_fp16x16s_loop_neon
  325. b sub_pixel_variance16x16s_neon
  326. ;--------------------
  327. firstpass_bfilter16x16s_only
  328. mov r2, #2 ;loop counter
  329. sub sp, sp, #256 ;reserve space on stack for temporary storage
  330. mov r3, sp
  331. ;First Pass: output_height lines x output_width columns (16x16)
  332. vp8e_filt_blk2d_fpo16x16s_loop_neon
  333. vld1.u8 {d0, d1, d2, d3}, [r0], r1 ;load src data
  334. vld1.u8 {d4, d5, d6, d7}, [r0], r1
  335. vld1.u8 {d8, d9, d10, d11}, [r0], r1
  336. vld1.u8 {d12, d13, d14, d15}, [r0], r1
  337. ;pld [r0]
  338. ;pld [r0, r1]
  339. ;pld [r0, r1, lsl #1]
  340. vext.8 q1, q0, q1, #1 ;construct src_ptr[1]
  341. vld1.u8 {d16, d17, d18, d19}, [r0], r1
  342. vext.8 q3, q2, q3, #1
  343. vld1.u8 {d20, d21, d22, d23}, [r0], r1
  344. vext.8 q5, q4, q5, #1
  345. vld1.u8 {d24, d25, d26, d27}, [r0], r1
  346. vext.8 q7, q6, q7, #1
  347. vld1.u8 {d28, d29, d30, d31}, [r0], r1
  348. vext.8 q9, q8, q9, #1
  349. vext.8 q11, q10, q11, #1
  350. vext.8 q13, q12, q13, #1
  351. vext.8 q15, q14, q15, #1
  352. vrhadd.u8 q0, q0, q1 ;(src_ptr[0]+src_ptr[1])/round/shift right 1
  353. vrhadd.u8 q1, q2, q3
  354. vrhadd.u8 q2, q4, q5
  355. vrhadd.u8 q3, q6, q7
  356. vrhadd.u8 q4, q8, q9
  357. vrhadd.u8 q5, q10, q11
  358. vrhadd.u8 q6, q12, q13
  359. vrhadd.u8 q7, q14, q15
  360. subs r2, r2, #1
  361. vst1.u8 {d0, d1, d2, d3}, [r3]! ;store result
  362. vst1.u8 {d4, d5, d6, d7}, [r3]!
  363. vst1.u8 {d8, d9, d10, d11}, [r3]!
  364. vst1.u8 {d12, d13, d14, d15}, [r3]!
  365. bne vp8e_filt_blk2d_fpo16x16s_loop_neon
  366. b sub_pixel_variance16x16s_neon
  367. ;---------------------
  368. secondpass_bfilter16x16s_only
  369. sub sp, sp, #256 ;reserve space on stack for temporary storage
  370. mov r2, #2 ;loop counter
  371. vld1.u8 {d0, d1}, [r0], r1 ;load src data
  372. mov r3, sp
  373. vp8e_filt_blk2d_spo16x16s_loop_neon
  374. vld1.u8 {d2, d3}, [r0], r1
  375. vld1.u8 {d4, d5}, [r0], r1
  376. vld1.u8 {d6, d7}, [r0], r1
  377. vld1.u8 {d8, d9}, [r0], r1
  378. vrhadd.u8 q0, q0, q1
  379. vld1.u8 {d10, d11}, [r0], r1
  380. vrhadd.u8 q1, q1, q2
  381. vld1.u8 {d12, d13}, [r0], r1
  382. vrhadd.u8 q2, q2, q3
  383. vld1.u8 {d14, d15}, [r0], r1
  384. vrhadd.u8 q3, q3, q4
  385. vld1.u8 {d16, d17}, [r0], r1
  386. vrhadd.u8 q4, q4, q5
  387. vrhadd.u8 q5, q5, q6
  388. vrhadd.u8 q6, q6, q7
  389. vrhadd.u8 q7, q7, q8
  390. subs r2, r2, #1
  391. vst1.u8 {d0, d1, d2, d3}, [r3]! ;store result
  392. vmov q0, q8
  393. vst1.u8 {d4, d5, d6, d7}, [r3]!
  394. vst1.u8 {d8, d9, d10, d11}, [r3]! ;store result
  395. vst1.u8 {d12, d13, d14, d15}, [r3]!
  396. bne vp8e_filt_blk2d_spo16x16s_loop_neon
  397. b sub_pixel_variance16x16s_neon
  398. ;----------------------------
  399. ;variance16x16
  400. sub_pixel_variance16x16s_neon
  401. vmov.i8 q8, #0 ;q8 - sum
  402. vmov.i8 q9, #0 ;q9, q10 - sse
  403. vmov.i8 q10, #0
  404. sub r3, r3, #256
  405. mov r2, #4
  406. sub_pixel_variance16x16s_neon_loop
  407. vld1.8 {q0}, [r3]! ;Load up source and reference
  408. vld1.8 {q1}, [r4], r12
  409. vld1.8 {q2}, [r3]!
  410. vld1.8 {q3}, [r4], r12
  411. vld1.8 {q4}, [r3]!
  412. vld1.8 {q5}, [r4], r12
  413. vld1.8 {q6}, [r3]!
  414. vld1.8 {q7}, [r4], r12
  415. vsubl.u8 q11, d0, d2 ;diff
  416. vsubl.u8 q12, d1, d3
  417. vsubl.u8 q13, d4, d6
  418. vsubl.u8 q14, d5, d7
  419. vsubl.u8 q0, d8, d10
  420. vsubl.u8 q1, d9, d11
  421. vsubl.u8 q2, d12, d14
  422. vsubl.u8 q3, d13, d15
  423. vpadal.s16 q8, q11 ;sum
  424. vmlal.s16 q9, d22, d22 ;sse
  425. vmlal.s16 q10, d23, d23
  426. subs r2, r2, #1
  427. vpadal.s16 q8, q12
  428. vmlal.s16 q9, d24, d24
  429. vmlal.s16 q10, d25, d25
  430. vpadal.s16 q8, q13
  431. vmlal.s16 q9, d26, d26
  432. vmlal.s16 q10, d27, d27
  433. vpadal.s16 q8, q14
  434. vmlal.s16 q9, d28, d28
  435. vmlal.s16 q10, d29, d29
  436. vpadal.s16 q8, q0 ;sum
  437. vmlal.s16 q9, d0, d0 ;sse
  438. vmlal.s16 q10, d1, d1
  439. vpadal.s16 q8, q1
  440. vmlal.s16 q9, d2, d2
  441. vmlal.s16 q10, d3, d3
  442. vpadal.s16 q8, q2
  443. vmlal.s16 q9, d4, d4
  444. vmlal.s16 q10, d5, d5
  445. vpadal.s16 q8, q3
  446. vmlal.s16 q9, d6, d6
  447. vmlal.s16 q10, d7, d7
  448. bne sub_pixel_variance16x16s_neon_loop
  449. vadd.u32 q10, q9, q10 ;accumulate sse
  450. vpaddl.s32 q0, q8 ;accumulate sum
  451. vpaddl.u32 q1, q10
  452. vadd.s64 d0, d0, d1
  453. vadd.u64 d1, d2, d3
  454. vmull.s32 q5, d0, d0
  455. vst1.32 {d1[0]}, [lr] ;store sse
  456. vshr.s32 d10, d10, #8
  457. vsub.s32 d0, d1, d10
  458. add sp, sp, #256
  459. vmov.32 r0, d0[0] ;return
  460. pop {r4, pc}
  461. ENDP
  462. END