pixel-a.S
上传用户:lctgjx
上传日期:2022-06-04
资源大小:8887k
文件大小:32k
源码类别:

流媒体/Mpeg4/MP4

开发平台:

Visual C++

  1. /*****************************************************************************
  2.  * pixel.S: h264 encoder
  3.  *****************************************************************************
  4.  * Copyright (C) 2009 x264 project
  5.  *
  6.  * Authors: David Conrad <lessen42@gmail.com>
  7.  *
  8.  * This program is free software; you can redistribute it and/or modify
  9.  * it under the terms of the GNU General Public License as published by
  10.  * the Free Software Foundation; either version 2 of the License, or
  11.  * (at your option) any later version.
  12.  *
  13.  * This program is distributed in the hope that it will be useful,
  14.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16.  * GNU General Public License for more details.
  17.  *
  18.  * You should have received a copy of the GNU General Public License
  19.  * along with this program; if not, write to the Free Software
  20.  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02111, USA.
  21.  *****************************************************************************/
  22. #include "asm.S"
  23. .fpu neon
  24. .section .rodata
  25. .align 4
  26. .rept 16 .byte 0xff
  27. .endr
  28. mask_ff:
  29. .rept 16 .byte 0
  30. .endr
  31. mask_ac4:
  32. .short 0, -1, -1, -1,  0, -1, -1, -1
  33. mask_ac8:
  34. .short 0, -1, -1, -1, -1, -1, -1, -1
  35. .text
  36. .macro SAD4_ARMV6 h
  37. function x264_pixel_sad_4xh()_armv6, export=1
  38.     push        {r4-r6,lr}
  39.     ldr         r4, [r2], r3
  40.     ldr         r5, [r0], r1
  41.     ldr         r6, [r2], r3
  42.     ldr         lr, [r0], r1
  43.     usad8       ip, r4, r5
  44. .rept (h - 2)/2
  45.     ldr         r4, [r2], r3
  46.     ldr         r5, [r0], r1
  47.     usada8      ip, r6, lr, ip
  48.     ldr         r6, [r2], r3
  49.     ldr         lr, [r0], r1
  50.     usada8      ip, r4, r5, ip
  51. .endr
  52.     usada8      r0, r6, lr, ip
  53.     pop         {r4-r6,pc}
  54. .endfunc
  55. .endm
  56. SAD4_ARMV6 4
  57. SAD4_ARMV6 8
  58. .macro SAD_START_4 align:vararg
  59.     vld1.32     {d1[]}, [r2 align], r3
  60.     vld1.32     {d0[]}, [r0,:32], r1
  61.     vabdl.u8    q8,  d0,  d1
  62. .endm
  63. .macro SAD_4 align:vararg
  64.     vld1.32     {d1[]}, [r2 align], r3
  65.     vld1.32     {d0[]}, [r0,:32], r1
  66.     vabal.u8    q8,  d0,  d1
  67. .endm
  68. .macro SAD_START_8 align:vararg
  69.     vld1.64     {d1}, [r2 align], r3
  70.     vld1.64     {d0}, [r0,:64], r1
  71.     vabdl.u8    q8,  d0,  d1
  72. .endm
  73. .macro SAD_8 align:vararg
  74.     vld1.64     {d1}, [r2 align], r3
  75.     vld1.64     {d0}, [r0,:64], r1
  76.     vabal.u8    q8,  d0,  d1
  77. .endm
  78. .macro SAD_START_16 align:vararg
  79.     vld1.64     {d2-d3}, [r2 align], r3
  80.     vld1.64     {d0-d1}, [r0,:128], r1
  81.     vabdl.u8    q8,  d0,  d2
  82.     vld1.64     {d6-d7}, [r2 align], r3
  83.     vabdl.u8    q9,  d1,  d3
  84.     vld1.64     {d4-d5}, [r0,:128], r1
  85. .endm
  86. .macro SAD_16 align:vararg
  87.     vabal.u8    q8,  d4,  d6
  88.     vld1.64     {d2-d3}, [r2 align], r3
  89.     vabal.u8    q9,  d5,  d7
  90.     vld1.64     {d0-d1}, [r0,:128], r1
  91.     vabal.u8    q8,  d0,  d2
  92.     vld1.64     {d6-d7}, [r2 align], r3
  93.     vabal.u8    q9,  d1,  d3
  94.     vld1.64     {d4-d5}, [r0,:128], r1
  95. .endm
  96. .macro SAD_FUNC w, h, name, align:vararg
  97. function x264_pixel_sadname()_w()xh()_neon, export=1
  98. .if w == 16
  99.     .set r, h / 2 - 1
  100. .else
  101.     .set r, h - 1
  102. .endif
  103.     SAD_START_w align
  104. .rept r
  105.     SAD_w align
  106. .endr
  107. .if w > 8
  108.     vabal.u8    q8,  d4,  d6
  109.     vabal.u8    q9,  d5,  d7
  110.     vadd.u16    q8,  q8,  q9
  111. .endif
  112. .if w > 4
  113.     vadd.u16    d16, d16, d17
  114. .endif
  115.     vpadd.u16   d0,  d16, d16
  116.     vpaddl.u16  d0,  d0
  117.     vmov.u32    r0,  d0[0]
  118.     bx          lr
  119. .endfunc
  120. .endm
  121. SAD_FUNC  4,  4
  122. SAD_FUNC  4,  8
  123. SAD_FUNC  8,  4
  124. SAD_FUNC  8,  8
  125. SAD_FUNC  8,  16
  126. SAD_FUNC  16, 8
  127. SAD_FUNC  16, 16
  128. SAD_FUNC  4,  4,  _aligned, ,:32
  129. SAD_FUNC  4,  8,  _aligned, ,:32
  130. SAD_FUNC  8,  4,  _aligned, ,:64
  131. SAD_FUNC  8,  8,  _aligned, ,:64
  132. SAD_FUNC  8,  16, _aligned, ,:64
  133. SAD_FUNC  16, 8,  _aligned, ,:128
  134. SAD_FUNC  16, 16, _aligned, ,:128
  135. // If dual issue is possible, use additional accumulators to avoid
  136. // stalls from vadal's latency. This only matters for aligned.
  137. .macro SAD_DUAL_START_8
  138.     SAD_START_8 ,:64
  139.     vld1.64     {d3}, [r2,:64], r3
  140.     vld1.64     {d2}, [r0,:64], r1
  141.     vabdl.u8    q9,  d2,  d3
  142. .endm
  143. .macro SAD_DUAL_8 align:vararg
  144.     vld1.64     {d1}, [r2,:64], r3
  145.     vld1.64     {d0}, [r0,:64], r1
  146.     vabal.u8    q8,  d0,  d1
  147.     vld1.64     {d3}, [r2,:64], r3
  148.     vld1.64     {d2}, [r0,:64], r1
  149.     vabal.u8    q9,  d2,  d3
  150. .endm
  151. .macro SAD_DUAL_START_16
  152.     SAD_START_16 ,:128
  153.     vabdl.u8    q10, d4,  d6
  154.     vld1.64     {d2-d3}, [r2,:128], r3
  155.     vabdl.u8    q11, d5,  d7
  156.     vld1.64     {d0-d1}, [r0,:128], r1
  157. .endm
  158. .macro SAD_DUAL_16
  159.     vabal.u8    q8,  d0,  d2
  160.     vld1.64     {d6-d7}, [r2,:128], r3
  161.     vabal.u8    q9,  d1,  d3
  162.     vld1.64     {d4-d5}, [r0,:128], r1
  163.     vabal.u8    q10, d4,  d6
  164.     vld1.64     {d2-d3}, [r2,:128], r3
  165.     vabal.u8    q11, d5,  d7
  166.     vld1.64     {d0-d1}, [r0,:128], r1
  167. .endm
  168. .macro SAD_DUAL_END_16
  169.     vabal.u8    q8,  d0,  d2
  170.     vld1.64     {d6-d7}, [r2,:128], r3
  171.     vabal.u8    q9,  d1,  d3
  172.     vld1.64     {d4-d5}, [r0,:128], r1
  173.     vabal.u8    q10, d4,  d6
  174.     vabal.u8    q11, d5,  d7
  175. .endm
  176. .macro SAD_FUNC_DUAL w, h
  177. function x264_pixel_sad_aligned_w()xh()_neon_dual, export=1
  178.     SAD_DUAL_START_w
  179. .rept h / 2 - w / 8
  180.     SAD_DUAL_w
  181. .endr
  182. .if w > 8
  183.     SAD_DUAL_END_16
  184.     vadd.u16    q8,  q8,  q9
  185.     vadd.u16    q9,  q10, q11
  186. .endif
  187. .if w > 4
  188.     vadd.u16    q8,  q8,  q9
  189.     vadd.u16    d16, d16, d17
  190. .endif
  191.     vpadd.u16   d0,  d16, d16
  192.     vpaddl.u16  d0,  d0
  193.     vmov.u32    r0,  d0[0]
  194.     bx          lr
  195. .endfunc
  196. .endm
  197. SAD_FUNC_DUAL  8,  4
  198. SAD_FUNC_DUAL  8,  8
  199. SAD_FUNC_DUAL  8,  16
  200. SAD_FUNC_DUAL  16, 8
  201. SAD_FUNC_DUAL  16, 16
  202. .macro SAD_X_START_4 x
  203.     vld1.32     {d0[]}, [r0,:32], lr
  204.     vld1.32     {d1[]}, [r1], r6
  205.     vabdl.u8    q8,  d1,  d0
  206.     vld1.32     {d2[]}, [r2], r6
  207.     vabdl.u8    q9,  d2,  d0
  208.     vld1.32     {d3[]}, [r3], r6
  209.     vabdl.u8    q10, d3,  d0
  210. .if x == 4
  211.     vld1.32     {d4[]}, [r12], r6
  212.     vabdl.u8    q11, d4,  d0
  213. .endif
  214. .endm
  215. .macro SAD_X_4 x
  216.     vld1.32     {d0[]}, [r0,:32], lr
  217.     vld1.32     {d1[]}, [r1], r6
  218.     vabal.u8    q8,  d1,  d0
  219.     vld1.32     {d2[]}, [r2], r6
  220.     vabal.u8    q9,  d2,  d0
  221.     vld1.32     {d3[]}, [r3], r6
  222.     vabal.u8    q10, d3,  d0
  223. .if x == 4
  224.     vld1.32     {d4[]}, [r12], r6
  225.     vabal.u8    q11, d4,  d0
  226. .endif
  227. .endm
  228. .macro SAD_X_START_8 x
  229.     vld1.64     {d0}, [r0,:64], lr
  230.     vld1.64     {d1}, [r1], r6
  231.     vabdl.u8    q8,  d1,  d0
  232.     vld1.64     {d2}, [r2], r6
  233.     vabdl.u8    q9,  d2,  d0
  234.     vld1.64     {d3}, [r3], r6
  235.     vabdl.u8    q10, d3,  d0
  236. .if x == 4
  237.     vld1.64     {d4}, [r12], r6
  238.     vabdl.u8    q11, d4,  d0
  239. .endif
  240. .endm
  241. .macro SAD_X_8 x
  242.     vld1.64     {d0}, [r0,:64], lr
  243.     vld1.64     {d1}, [r1], r6
  244.     vabal.u8    q8,  d1,  d0
  245.     vld1.64     {d2}, [r2], r6
  246.     vabal.u8    q9,  d2,  d0
  247.     vld1.64     {d3}, [r3], r6
  248.     vabal.u8    q10, d3,  d0
  249. .if x == 4
  250.     vld1.64     {d4}, [r12], r6
  251.     vabal.u8    q11, d4,  d0
  252. .endif
  253. .endm
  254. .macro SAD_X_START_16 x
  255.     vld1.64     {d0-d1}, [r0,:128], lr
  256.     vld1.64     {d2-d3}, [r1], r6
  257.     vabdl.u8    q8,  d2,  d0
  258.     vabdl.u8    q12, d3,  d1
  259.     vld1.64     {d4-d5}, [r2], r6
  260.     vabdl.u8    q9,  d4,  d0
  261.     vabdl.u8    q13, d5,  d1
  262.     vld1.64     {d6-d7}, [r3], r6
  263.     vabdl.u8    q10, d6,  d0
  264.     vabdl.u8    q14, d7,  d1
  265. .if x == 4
  266.     vld1.64     {d2-d3}, [r12], r6
  267.     vabdl.u8    q11, d2,  d0
  268.     vabdl.u8    q15, d3,  d1
  269. .endif
  270. .endm
  271. .macro SAD_X_16 x
  272.     vld1.64     {d0-d1}, [r0,:128], lr
  273.     vld1.64     {d2-d3}, [r1], r6
  274.     vabal.u8    q8,  d2,  d0
  275.     vabal.u8    q12, d3,  d1
  276.     vld1.64     {d4-d5}, [r2], r6
  277.     vabal.u8    q9,  d4,  d0
  278.     vabal.u8    q13, d5,  d1
  279.     vld1.64     {d6-d7}, [r3], r6
  280.     vabal.u8    q10, d6,  d0
  281.     vabal.u8    q14, d7,  d1
  282. .if x == 4
  283.     vld1.64     {d2-d3}, [r12], r6
  284.     vabal.u8    q11, d2,  d0
  285.     vabal.u8    q15, d3,  d1
  286. .endif
  287. .endm
  288. .macro SAD_X_FUNC x, w, h
  289. function x264_pixel_sad_xx()_w()xh()_neon, export=1
  290.     push        {r6-r7,lr}
  291. .if x == 3
  292.     ldrd        r6,  [sp, #12]
  293. .else
  294.     ldrd        r6,  [sp, #16]
  295.     ldr         r12, [sp, #12]
  296. .endif
  297.     mov         lr,  #FENC_STRIDE
  298.     SAD_X_START_w x
  299. .rept h - 1
  300.     SAD_X_w x
  301. .endr
  302. // add up the sads
  303. .if w > 8
  304.     vadd.u16    q8,  q8,  q12
  305.     vadd.u16    q9,  q9,  q13
  306.     vadd.u16    q10, q10, q14
  307. .if x == 4
  308.     vadd.u16    q11, q11, q15
  309. .endif
  310. .endif
  311. .if w > 4
  312.     vadd.u16    d16, d16, d17
  313.     vadd.u16    d18, d18, d19
  314.     vadd.u16    d20, d20, d21
  315. .if x == 4
  316.     vadd.u16    d22, d22, d23
  317. .endif
  318. .endif
  319.     vpadd.u16   d0,  d16, d18
  320.     vpadd.u16   d1,  d20, d22
  321.     vpaddl.u16  q0,  q0
  322. .if x == 3
  323.     vst1.32     {d0},    [r7]!
  324.     vst1.32     {d1[0]}, [r7,:32]
  325. .else
  326.     vst1.32     {d0-d1}, [r7]
  327. .endif
  328.     pop         {r6-r7,pc}
  329. .endfunc
  330. .endm
  331. SAD_X_FUNC  3, 4,  4
  332. SAD_X_FUNC  3, 4,  8
  333. SAD_X_FUNC  3, 8,  4
  334. SAD_X_FUNC  3, 8,  8
  335. SAD_X_FUNC  3, 8,  16
  336. SAD_X_FUNC  3, 16, 8
  337. SAD_X_FUNC  3, 16, 16
  338. SAD_X_FUNC  4, 4,  4
  339. SAD_X_FUNC  4, 4,  8
  340. SAD_X_FUNC  4, 8,  4
  341. SAD_X_FUNC  4, 8,  8
  342. SAD_X_FUNC  4, 8,  16
  343. SAD_X_FUNC  4, 16, 8
  344. SAD_X_FUNC  4, 16, 16
  345. .macro SSD_START_4
  346.     vld1.32     {d16[]}, [r0,:32], r1
  347.     vld1.32     {d17[]}, [r2,:32], r3
  348.     vsubl.u8    q2, d16, d17
  349.     vld1.32     {d16[]}, [r0,:32], r1
  350.     vmull.s16   q0, d4, d4
  351.     vld1.32     {d17[]}, [r2,:32], r3
  352. .endm
  353. .macro SSD_4
  354.     vsubl.u8    q2, d16, d17
  355.     vld1.32     {d16[]}, [r0,:32], r1
  356.     vmlal.s16   q0, d4, d4
  357.     vld1.32     {d17[]}, [r2,:32], r3
  358. .endm
  359. .macro SSD_END_4
  360.     vsubl.u8    q2, d16, d17
  361.     vmlal.s16   q0, d4, d4
  362. .endm
  363. .macro SSD_START_8
  364.     vld1.64     {d16}, [r0,:64], r1
  365.     vld1.64     {d17}, [r2,:64], r3
  366.     vsubl.u8    q2, d16, d17
  367.     vld1.64     {d16}, [r0,:64], r1
  368.     vmull.s16   q0, d4, d4
  369.     vmlal.s16   q0, d5, d5
  370.     vld1.64     {d17}, [r2,:64], r3
  371. .endm
  372. .macro SSD_8
  373.     vsubl.u8    q2, d16, d17
  374.     vld1.64     {d16}, [r0,:64], r1
  375.     vmlal.s16   q0, d4, d4
  376.     vmlal.s16   q0, d5, d5
  377.     vld1.64     {d17}, [r2,:64], r3
  378. .endm
  379. .macro SSD_END_8
  380.     vsubl.u8    q2, d16, d17
  381.     vmlal.s16   q0, d4, d4
  382.     vmlal.s16   q0, d5, d5
  383. .endm
  384. .macro SSD_START_16
  385.     vld1.64     {d16-d17}, [r0,:128], r1
  386.     vld1.64     {d18-d19}, [r2,:128], r3
  387.     vsubl.u8    q2, d16, d18
  388.     vsubl.u8    q3, d17, d19
  389.     vld1.64     {d16-d17}, [r0,:128], r1
  390.     vmull.s16   q0, d4, d4
  391.     vmlal.s16   q0, d5, d5
  392.     vld1.64     {d18-d19}, [r2,:128], r3
  393.     vmlal.s16   q0, d6, d6
  394.     vmlal.s16   q0, d7, d7
  395. .endm
  396. .macro SSD_16
  397.     vsubl.u8    q2, d16, d18
  398.     vsubl.u8    q3, d17, d19
  399.     vld1.64     {d16-d17}, [r0,:128], r1
  400.     vmlal.s16   q0, d4, d4
  401.     vmlal.s16   q0, d5, d5
  402.     vld1.64     {d18-d19}, [r2,:128], r3
  403.     vmlal.s16   q0, d6, d6
  404.     vmlal.s16   q0, d7, d7
  405. .endm
  406. .macro SSD_END_16
  407.     vsubl.u8    q2, d16, d18
  408.     vsubl.u8    q3, d17, d19
  409.     vmlal.s16   q0, d4, d4
  410.     vmlal.s16   q0, d5, d5
  411.     vmlal.s16   q0, d6, d6
  412.     vmlal.s16   q0, d7, d7
  413. .endm
  414. .macro SSD_FUNC w h
  415. function x264_pixel_ssd_w()xh()_neon, export=1
  416.     SSD_START_w
  417. .rept h-2
  418.     SSD_w
  419. .endr
  420.     SSD_END_w
  421.     vadd.s32    d0, d0, d1
  422.     vpadd.s32   d0, d0, d0
  423.     vmov.32     r0, d0[0]
  424.     bx          lr
  425. .endfunc
  426. .endm
  427. SSD_FUNC   4, 4
  428. SSD_FUNC   4, 8
  429. SSD_FUNC   8, 4
  430. SSD_FUNC   8, 8
  431. SSD_FUNC   8, 16
  432. SSD_FUNC  16, 8
  433. SSD_FUNC  16, 16
  434. .macro VAR_SQR_SUM qsqr_sum qsqr_last qsqr dsrc vpadal=vpadal.u16
  435.     vmull.u8        qsqr, dsrc, dsrc
  436.     vaddw.u8        q0, q0, dsrc
  437.     vpadal         qsqr_sum, qsqr_last
  438. .endm
  439. function x264_pixel_var_8x8_neon, export=1
  440.     vld1.64         {d16}, [r0,:64], r1
  441.     vmull.u8        q1,  d16, d16
  442.     vmovl.u8        q0,  d16
  443.     vld1.64         {d18}, [r0,:64], r1
  444.     vmull.u8        q2,  d18, d18
  445.     vaddw.u8        q0,  q0,  d18
  446.     vld1.64         {d20}, [r0,:64], r1
  447.     VAR_SQR_SUM     q1,  q1,   q3,  d20, vpaddl.u16
  448.     vld1.64         {d22}, [r0,:64], r1
  449.     VAR_SQR_SUM     q2,  q2,   q8,  d22, vpaddl.u16
  450.     vld1.64         {d24}, [r0,:64], r1
  451.     VAR_SQR_SUM     q1,  q3,   q9,  d24
  452.     vld1.64         {d26}, [r0,:64], r1
  453.     VAR_SQR_SUM     q2,  q8,   q10, d26
  454.     vld1.64         {d24}, [r0,:64], r1
  455.     VAR_SQR_SUM     q1,  q9,   q14, d24
  456.     vld1.64         {d26}, [r0,:64], r1
  457.     VAR_SQR_SUM     q2,  q10,  q15, d26
  458.     mov             r2,  #6
  459.     b               x264_var_end
  460. .endfunc
  461. function x264_pixel_var_16x16_neon, export=1
  462.     vld1.64         {d16-d17}, [r0,:128], r1
  463.     vmull.u8        q12, d16, d16
  464.     vmovl.u8        q0,  d16
  465.     vmull.u8        q13, d17, d17
  466.     vaddw.u8        q0,  q0,  d17
  467.     vld1.64         {d18-d19}, [r0,:128], r1
  468.     VAR_SQR_SUM     q1,  q12,  q14, d18, vpaddl.u16
  469.     VAR_SQR_SUM     q2,  q13,  q15, d19, vpaddl.u16
  470.     mov             ip,  #7
  471.     mov             r2,  #8
  472. var16_loop:
  473.     subs            ip,  ip,  #1
  474.     vld1.64         {d16-d17}, [r0,:128], r1
  475.     VAR_SQR_SUM     q1,  q14,  q12, d16
  476.     VAR_SQR_SUM     q2,  q15,  q13, d17
  477.     vld1.64         {d18-d19}, [r0,:128], r1
  478.     VAR_SQR_SUM     q1,  q12,  q14, d18
  479.     VAR_SQR_SUM     q2,  q13,  q15, d19
  480.     bgt             var16_loop
  481. .endfunc
  482. function x264_var_end
  483.     vpaddl.u16      q8,  q14
  484.     vpaddl.u16      q9,  q15
  485.     vadd.u32        q1,  q1,  q8
  486.     vadd.u16        d0,  d0,  d1
  487.     vadd.u32        q1,  q1,  q9
  488.     vadd.u32        q1,  q1,  q2
  489.     vpaddl.u16      d0,  d0
  490.     vadd.u32        d2,  d2,  d3
  491.     vpadd.u32       d0,  d0,  d2
  492.     vmov            r0,  r1,  d0
  493.     mul             r0,  r0,  r0
  494.     sub             r0,  r1,  r0,  lsr r2
  495.     bx              lr
  496. .endfunc
  497. .macro DIFF_SUM diff da db lastdiff
  498.     vld1.64         {da}, [r0,:64], r1
  499.     vld1.64         {db}, [r2,:64], r3
  500. .ifnb lastdiff
  501.     vadd.s16        q0,  q0,  lastdiff
  502. .endif
  503.     vsubl.u8        diff, da, db
  504. .endm
  505. .macro SQR_ACC acc d0 d1 vmlal=vmlal.s16
  506.     vmlal          acc, d0, d0
  507.     vmlal.s16       acc, d1, d1
  508. .endm
  509. function x264_pixel_var2_8x8_neon, export=1
  510.     DIFF_SUM        q0,  d0,  d1
  511.     DIFF_SUM        q8,  d16, d17
  512.     SQR_ACC         q1,  d0,  d1,  vmull.s16
  513.     DIFF_SUM        q9,  d18, d19, q8
  514.     SQR_ACC         q2,  d16, d17, vmull.s16
  515. .rept 2
  516.     DIFF_SUM        q8,  d16, d17, q9
  517.     SQR_ACC         q1,  d18, d19
  518.     DIFF_SUM        q9,  d18, d19, q8
  519.     SQR_ACC         q2,  d16, d17
  520. .endr
  521.     DIFF_SUM        q8,  d16, d17, q9
  522.     SQR_ACC         q1,  d18, d19
  523.     vadd.s16        q0,  q0,  q8
  524.     SQR_ACC         q2,  d16, d17
  525.     ldr             ip,  [sp]
  526.     vadd.s16        d0,  d0,  d1
  527.     vadd.s32        q1,  q1,  q2
  528.     vpaddl.s16      d0,  d0
  529.     vadd.s32        d1,  d2,  d3
  530.     vpadd.s32       d0,  d0,  d1
  531.     vmov.32         r0,  r1,  d0
  532.     vst1.32         {d0[1]}, [ip,:32]
  533.     mul             r0,  r0,  r0
  534.     sub             r0,  r1,  r0,  lsr #6
  535.     bx              lr
  536. .endfunc
  537. .macro LOAD_DIFF_8x4 q0 q1 q2 q3
  538.     vld1.32     {d1}, [r2], r3
  539.     vld1.32     {d0}, [r0,:64], r1
  540.     vsubl.u8    q0, d0,  d1
  541.     vld1.32     {d3}, [r2], r3
  542.     vld1.32     {d2}, [r0,:64], r1
  543.     vsubl.u8    q1, d2,  d3
  544.     vld1.32     {d5}, [r2], r3
  545.     vld1.32     {d4}, [r0,:64], r1
  546.     vsubl.u8    q2, d4,  d5
  547.     vld1.32     {d7}, [r2], r3
  548.     vld1.32     {d6}, [r0,:64], r1
  549.     vsubl.u8    q3, d6,  d7
  550. .endm
  551. function x264_pixel_satd_4x4_neon, export=1
  552.     vld1.32     {d1[]},  [r2], r3
  553.     vld1.32     {d0[]},  [r0,:32], r1
  554.     vld1.32     {d3[]},  [r2], r3
  555.     vld1.32     {d2[]},  [r0,:32], r1
  556.     vld1.32     {d1[1]}, [r2], r3
  557.     vld1.32     {d0[1]}, [r0,:32], r1
  558.     vld1.32     {d3[1]}, [r2], r3
  559.     vld1.32     {d2[1]}, [r0,:32], r1
  560.     vsubl.u8    q0,  d0,  d1
  561.     vsubl.u8    q1,  d2,  d3
  562.     SUMSUB_AB   q2, q3, q0, q1
  563.     SUMSUB_ABCD d0, d2, d1, d3, d4, d5, d6, d7
  564.     HADAMARD    1, sumsub, q2, q3, q0, q1
  565.     HADAMARD    2, amax,   q0,,    q2, q3
  566.     HORIZ_ADD   d0,  d0,  d1
  567.     vmov.32     r0,  d0[0]
  568.     bx          lr
  569. .endfunc
  570. function x264_pixel_satd_4x8_neon, export=1
  571.     vld1.32     {d1[]},  [r2], r3
  572.     vld1.32     {d0[]},  [r0,:32], r1
  573.     vld1.32     {d3[]},  [r2], r3
  574.     vld1.32     {d2[]},  [r0,:32], r1
  575.     vld1.32     {d5[]},  [r2], r3
  576.     vld1.32     {d4[]},  [r0,:32], r1
  577.     vld1.32     {d7[]},  [r2], r3
  578.     vld1.32     {d6[]},  [r0,:32], r1
  579.     vld1.32     {d1[1]}, [r2], r3
  580.     vld1.32     {d0[1]}, [r0,:32], r1
  581.     vsubl.u8    q0,  d0,  d1
  582.     vld1.32     {d3[1]}, [r2], r3
  583.     vld1.32     {d2[1]}, [r0,:32], r1
  584.     vsubl.u8    q1,  d2,  d3
  585.     vld1.32     {d5[1]}, [r2], r3
  586.     vld1.32     {d4[1]}, [r0,:32], r1
  587.     vsubl.u8    q2,  d4,  d5
  588.     vld1.32     {d7[1]}, [r2], r3
  589.     SUMSUB_AB   q8,  q9,  q0,  q1
  590.     vld1.32     {d6[1]}, [r0,:32], r1
  591.     vsubl.u8    q3,  d6,  d7
  592.     SUMSUB_AB   q10, q11, q2,  q3
  593.     b           x264_satd_4x8_8x4_end_neon
  594. .endfunc
  595. function x264_pixel_satd_8x4_neon, export=1
  596.     vld1.64     {d1}, [r2], r3
  597.     vld1.64     {d0}, [r0,:64], r1
  598.     vsubl.u8    q0,  d0,  d1
  599.     vld1.64     {d3}, [r2], r3
  600.     vld1.64     {d2}, [r0,:64], r1
  601.     vsubl.u8    q1,  d2,  d3
  602.     vld1.64     {d5}, [r2], r3
  603.     vld1.64     {d4}, [r0,:64], r1
  604.     vsubl.u8    q2,  d4,  d5
  605.     vld1.64     {d7}, [r2], r3
  606.     SUMSUB_AB   q8,  q9,  q0,  q1
  607.     vld1.64     {d6}, [r0,:64], r1
  608.     vsubl.u8    q3,  d6,  d7
  609.     SUMSUB_AB   q10, q11, q2,  q3
  610. .endfunc
  611. function x264_satd_4x8_8x4_end_neon
  612.     vadd.s16    q0,  q8,  q10
  613.     vadd.s16    q1,  q9,  q11
  614.     vsub.s16    q2,  q8,  q10
  615.     vsub.s16    q3,  q9,  q11
  616.     vtrn.16     q0,  q1
  617.     vadd.s16    q8,  q0,  q1
  618.     vtrn.16     q2,  q3
  619.     vsub.s16    q9,  q0,  q1
  620.     vadd.s16    q10, q2,  q3
  621.     vsub.s16    q11, q2,  q3
  622.     vtrn.32     q8,  q10
  623.     vabs.s16    q8,  q8
  624.     vtrn.32     q9,  q11
  625.     vabs.s16    q10, q10
  626.     vabs.s16    q9,  q9
  627.     vabs.s16    q11, q11
  628.     vmax.u16    q0,  q8,  q10
  629.     vmax.u16    q1,  q9,  q11
  630.     vadd.u16    q0,  q0,  q1
  631.     HORIZ_ADD   d0,  d0,  d1
  632.     vmov.32     r0,  d0[0]
  633.     bx          lr
  634. .endfunc
  635. function x264_pixel_satd_8x8_neon, export=1
  636.     mov         ip,  lr
  637.     bl x264_satd_8x8_neon
  638.     vadd.u16    q0,  q12, q13
  639.     vadd.u16    q1,  q14, q15
  640.     vadd.u16    q0,  q0,  q1
  641.     HORIZ_ADD   d0,  d0,  d1
  642.     mov         lr,  ip
  643.     vmov.32     r0,  d0[0]
  644.     bx          lr
  645. .endfunc
  646. function x264_pixel_satd_8x16_neon, export=1
  647.     vpush       {d8-d11}
  648.     mov         ip,  lr
  649.     bl x264_satd_8x8_neon
  650.     vadd.u16    q4,  q12, q13
  651.     vadd.u16    q5,  q14, q15
  652.     bl x264_satd_8x8_neon
  653.     vadd.u16    q4,  q4,  q12
  654.     vadd.u16    q5,  q5,  q13
  655.     vadd.u16    q4,  q4,  q14
  656.     vadd.u16    q5,  q5,  q15
  657.     vadd.u16    q0,  q4,  q5
  658.     HORIZ_ADD   d0,  d0,  d1
  659.     vpop        {d8-d11}
  660.     mov         lr,  ip
  661.     vmov.32     r0,  d0[0]
  662.     bx          lr
  663. .endfunc
  664. function x264_satd_8x8_neon
  665.     LOAD_DIFF_8x4 q8,  q9,  q10, q11
  666.     vld1.64     {d7}, [r2], r3
  667.     SUMSUB_AB   q0,  q1,  q8,  q9
  668.     vld1.64     {d6}, [r0,:64], r1
  669.     vsubl.u8    q12, d6,  d7
  670.     vld1.64     {d17}, [r2], r3
  671.     SUMSUB_AB   q2,  q3,  q10, q11
  672.     vld1.64     {d16}, [r0,:64], r1
  673.     vsubl.u8    q13, d16, d17
  674.     vld1.64     {d19}, [r2], r3
  675.     SUMSUB_AB   q8,  q10, q0,  q2
  676.     vld1.64     {d18}, [r0,:64], r1
  677.     vsubl.u8    q14, d18, d19
  678.     vld1.64     {d1}, [r2], r3
  679.     SUMSUB_AB   q9,  q11, q1,  q3
  680.     vld1.64     {d0}, [r0,:64], r1
  681.     vsubl.u8    q15, d0,  d1
  682. .endfunc
  683. // one vertical hadamard pass and two horizontal
  684. function x264_satd_8x4v_8x8h_neon
  685.     SUMSUB_ABCD q0, q1, q2, q3, q12, q13, q14, q15
  686.     vtrn.16     q8,  q9
  687.     SUMSUB_AB   q12, q14, q0,  q2
  688.     vtrn.16     q10, q11
  689.     SUMSUB_AB   q13, q15, q1,  q3
  690.     SUMSUB_AB   q0,  q1,  q8,  q9
  691.     vtrn.16     q12, q13
  692.     SUMSUB_AB   q2,  q3,  q10, q11
  693.     vtrn.16     q14, q15
  694.     SUMSUB_AB   q8,  q9,  q12, q13
  695.     vtrn.32     q0,  q2
  696.     SUMSUB_AB   q10, q11, q14, q15
  697.     vtrn.32     q1,  q3
  698.     ABS2        q0,  q2
  699.     vtrn.32     q8,  q10
  700.     ABS2        q1,  q3
  701.     vtrn.32     q9,  q11
  702.     ABS2        q8,  q10
  703.     ABS2        q9,  q11
  704.     vmax.s16    q12, q0,  q2
  705.     vmax.s16    q13, q1,  q3
  706.     vmax.s16    q14, q8,  q10
  707.     vmax.s16    q15, q9,  q11
  708.     bx          lr
  709. .endfunc
  710. function x264_pixel_satd_16x8_neon, export=1
  711.     vpush       {d8-d11}
  712.     mov         ip, lr
  713.     bl          x264_satd_16x4_neon
  714.     vadd.u16    q4,  q12, q13
  715.     vadd.u16    q5,  q14, q15
  716.     bl          x264_satd_16x4_neon
  717.     vadd.u16    q4,  q4,  q12
  718.     vadd.u16    q5,  q5,  q13
  719.     vadd.u16    q4,  q4,  q14
  720.     vadd.u16    q5,  q5,  q15
  721.     vadd.u16    q0,  q4,  q5
  722.     HORIZ_ADD   d0,  d0,  d1
  723.     vpop        {d8-d11}
  724.     mov         lr,  ip
  725.     vmov.32     r0,  d0[0]
  726.     bx          lr
  727. .endfunc
  728. function x264_pixel_satd_16x16_neon, export=1
  729.     vpush       {d8-d11}
  730.     mov         ip, lr
  731.     bl          x264_satd_16x4_neon
  732.     vadd.u16    q4,  q12, q13
  733.     vadd.u16    q5,  q14, q15
  734.     bl          x264_satd_16x4_neon
  735.     vadd.u16    q4,  q4,  q12
  736.     vadd.u16    q5,  q5,  q13
  737.     vadd.u16    q4,  q4,  q14
  738.     vadd.u16    q5,  q5,  q15
  739.     bl          x264_satd_16x4_neon
  740.     vadd.u16    q4,  q4,  q12
  741.     vadd.u16    q5,  q5,  q13
  742.     vadd.u16    q4,  q4,  q14
  743.     vadd.u16    q5,  q5,  q15
  744.     bl          x264_satd_16x4_neon
  745.     vadd.u16    q4,  q4,  q12
  746.     vadd.u16    q5,  q5,  q13
  747.     vadd.u16    q4,  q4,  q14
  748.     vadd.u16    q5,  q5,  q15
  749.     vadd.u16    q0,  q4,  q5
  750.     HORIZ_ADD   d0,  d0,  d1
  751.     vpop        {d8-d11}
  752.     mov         lr,  ip
  753.     vmov.32     r0,  d0[0]
  754.     bx          lr
  755. .endfunc
  756. function x264_satd_16x4_neon
  757.     vld1.64     {d2-d3}, [r2], r3
  758.     vld1.64     {d0-d1}, [r0,:128], r1
  759.     vsubl.u8    q8,  d0,  d2
  760.     vld1.64     {d6-d7}, [r2], r3
  761.     vsubl.u8    q12, d1,  d3
  762.     vld1.64     {d4-d5}, [r0,:128], r1
  763.     vsubl.u8    q9,  d4,  d6
  764.     vld1.64     {d2-d3}, [r2], r3
  765.     vsubl.u8    q13, d5,  d7
  766.     vld1.64     {d0-d1}, [r0,:128], r1
  767.     vsubl.u8    q10, d0,  d2
  768.     vld1.64     {d6-d7}, [r2], r3
  769.     vsubl.u8    q14, d1,  d3
  770.     vadd.s16    q0,  q8,  q9
  771.     vld1.64     {d4-d5}, [r0,:128], r1
  772.     vsub.s16    q1,  q8,  q9
  773.     vsubl.u8    q11, d4,  d6
  774.     vsubl.u8    q15, d5,  d7
  775.     SUMSUB_AB   q2,  q3,  q10, q11
  776.     SUMSUB_ABCD q8,  q10, q9,  q11, q0,  q2,  q1,  q3
  777.     b           x264_satd_8x4v_8x8h_neon
  778. .endfunc
  779. function x264_pixel_sa8d_8x8_neon, export=1
  780.     mov             ip,  lr
  781.     bl              x264_sa8d_8x8_neon
  782.     vadd.u16        q0,  q8,  q9
  783.     HORIZ_ADD       d0,  d0,  d1
  784.     mov             lr,  ip
  785.     vmov.32         r0,  d0[0]
  786.     add             r0,  r0,  #1
  787.     lsr             r0,  r0,  #1
  788.     bx              lr
  789. .endfunc
  790. function x264_pixel_sa8d_16x16_neon, export=1
  791.     vpush           {d8-d11}
  792.     mov             ip,  lr
  793.     bl              x264_sa8d_8x8_neon
  794.     vpaddl.u16      q4,  q8
  795.     vpaddl.u16      q5,  q9
  796.     bl              x264_sa8d_8x8_neon
  797.     vpadal.u16      q4,  q8
  798.     vpadal.u16      q5,  q9
  799.     sub             r0,  r0,  r1,  lsl #4
  800.     sub             r2,  r2,  r3,  lsl #4
  801.     add             r0,  r0,  #8
  802.     add             r2,  r2,  #8
  803.     bl              x264_sa8d_8x8_neon
  804.     vpadal.u16      q4,  q8
  805.     vpadal.u16      q5,  q9
  806.     bl              x264_sa8d_8x8_neon
  807.     vpaddl.u16      q8,  q8
  808.     vpaddl.u16      q9,  q9
  809.     vadd.u32        q0,  q4,  q8
  810.     vadd.u32        q1,  q5,  q9
  811.     vadd.u32        q0,  q0,  q1
  812.     vadd.u32        d0,  d0,  d1
  813.     vpadd.u32       d0,  d0,  d0
  814.     vpop            {d8-d11}
  815.     mov             lr,  ip
  816.     vmov.32         r0,  d0[0]
  817.     add             r0,  r0,  #1
  818.     lsr             r0,  r0,  #1
  819.     bx              lr
  820. .endfunc
  821. .macro HADAMARD4_V r1, r2, r3, r4, t1, t2, t3, t4
  822.     SUMSUB_ABCD t1, t2, t3, t4, r1, r2, r3, r4
  823.     SUMSUB_ABCD r1, r3, r2, r4, t1, t3, t2, t4
  824. .endm
  825. function x264_sa8d_8x8_neon
  826.     LOAD_DIFF_8x4   q8,  q9,  q10, q11
  827.     vld1.64         {d7}, [r2], r3
  828.     SUMSUB_AB       q0,  q1,  q8,  q9
  829.     vld1.64         {d6}, [r0,:64], r1
  830.     vsubl.u8        q12, d6,  d7
  831.     vld1.64         {d17}, [r2], r3
  832.     SUMSUB_AB       q2,  q3,  q10, q11
  833.     vld1.64         {d16}, [r0,:64], r1
  834.     vsubl.u8        q13, d16, d17
  835.     vld1.64         {d19}, [r2], r3
  836.     SUMSUB_AB       q8,  q10, q0,  q2
  837.     vld1.64         {d18}, [r0,:64], r1
  838.     vsubl.u8        q14, d18, d19
  839.     vld1.64         {d1}, [r2], r3
  840.     SUMSUB_AB       q9,  q11, q1,  q3
  841.     vld1.64         {d0}, [r0,:64], r1
  842.     vsubl.u8        q15, d0,  d1
  843.     HADAMARD4_V     q12, q13, q14, q15,  q0,  q1,  q2,  q3
  844.     SUMSUB_ABCD     q0,  q8,  q1,  q9,   q8,  q12, q9,  q13
  845.     SUMSUB_AB       q2,  q10, q10, q14
  846.     vtrn.16         q8,  q9
  847.     SUMSUB_AB       q3,  q11, q11, q15
  848.     vtrn.16         q0,  q1
  849.     SUMSUB_AB       q12, q13, q8,  q9
  850.     vtrn.16         q10, q11
  851.     SUMSUB_AB       q8,  q9,  q0,  q1
  852.     vtrn.16         q2,  q3
  853.     SUMSUB_AB       q14, q15, q10, q11
  854.     vadd.i16        q10, q2,  q3
  855.     vtrn.32         q12, q14
  856.     vsub.i16        q11, q2,  q3
  857.     vtrn.32         q13, q15
  858.     SUMSUB_AB       q0,  q2,  q12, q14
  859.     vtrn.32         q8,  q10
  860.     SUMSUB_AB       q1,  q3,  q13, q15
  861.     vtrn.32         q9,  q11
  862.     SUMSUB_AB       q12, q14, q8,  q10
  863.     SUMSUB_AB       q13, q15, q9,  q11
  864.     vswp            d1,  d24
  865.     ABS2            q0,  q12
  866.     vswp            d3,  d26
  867.     ABS2            q1,  q13
  868.     vswp            d5,  d28
  869.     ABS2            q2,  q14
  870.     vswp            d7,  d30
  871.     ABS2            q3,  q15
  872.     vmax.s16        q8,  q0,  q12
  873.     vmax.s16        q9,  q1,  q13
  874.     vmax.s16        q10, q2,  q14
  875.     vmax.s16        q11, q3,  q15
  876.     vadd.i16        q8,  q8,  q9
  877.     vadd.i16        q9,  q10, q11
  878.     bx              lr
  879. .endfunc
  880. .macro HADAMARD_AC w h
  881. function x264_pixel_hadamard_ac_w()xh()_neon, export=1
  882.     vpush           {d8-d15}
  883.     movrel          ip, mask_ac4
  884.     vmov.i8         q4, #0
  885.     // note: this assumes mask_ac8 is after mask_ac4 (so don't move it)
  886.     vld1.64         {d12-d15}, [ip,:128]
  887.     vmov.i8         q5, #0
  888.     mov             ip,  lr
  889.     bl              x264_hadamard_ac_8x8_neon
  890. .if h > 8
  891.     bl              x264_hadamard_ac_8x8_neon
  892. .endif
  893. .if w > 8
  894.     sub             r0,  r0,  r1,  lsl #3
  895.     add             r0,  r0,  #8
  896.     bl              x264_hadamard_ac_8x8_neon
  897. .endif
  898. .if w * h == 256
  899.     sub             r0,  r0,  r1,  lsl #4
  900.     bl              x264_hadamard_ac_8x8_neon
  901. .endif
  902.     vadd.s32        d8,  d8,  d9
  903.     vadd.s32        d10, d10, d11
  904.     vpadd.s32       d0,  d8,  d10
  905.     vpop            {d8-d15}
  906.     mov             lr,  ip
  907.     vmov            r0,  r1,  d0
  908.     lsr             r0,  r0,  #1
  909.     lsr             r1,  r1,  #2
  910.     bx              lr
  911. .endfunc
  912. .endm
  913. HADAMARD_AC  8, 8
  914. HADAMARD_AC  8, 16
  915. HADAMARD_AC 16, 8
  916. HADAMARD_AC 16, 16
  917. // q4: satd  q5: sa8d  q6: mask_ac4  q7: mask_ac8
  918. function x264_hadamard_ac_8x8_neon
  919.     vld1.64         {d2},  [r0,:64], r1
  920.     vld1.64         {d3},  [r0,:64], r1
  921.     vaddl.u8        q0,  d2,  d3
  922.     vld1.64         {d6},  [r0,:64], r1
  923.     vsubl.u8        q1,  d2,  d3
  924.     vld1.64         {d7},  [r0,:64], r1
  925.     vaddl.u8        q2,  d6,  d7
  926.     vld1.64         {d18}, [r0,:64], r1
  927.     vsubl.u8        q3,  d6,  d7
  928.     vld1.64         {d19}, [r0,:64], r1
  929.     vaddl.u8        q8,  d18, d19
  930.     vld1.64         {d22}, [r0,:64], r1
  931.     vsubl.u8        q9,  d18, d19
  932.     vld1.64         {d23}, [r0,:64], r1
  933.     SUMSUB_ABCD     q12, q14, q13, q15, q0,  q2,  q1,  q3
  934.     vaddl.u8        q10, d22, d23
  935.     vsubl.u8        q11, d22, d23
  936.     vtrn.16         q12, q13
  937.     SUMSUB_ABCD     q0,  q2,  q1,  q3,  q8,  q10, q9,  q11
  938.     vtrn.16         q14, q15
  939.     SUMSUB_AB       q8,  q9,  q12, q13
  940.     vtrn.16         q0,  q1
  941.     SUMSUB_AB       q10, q11, q14, q15
  942.     vtrn.16         q2,  q3
  943.     SUMSUB_AB       q12, q13, q0,  q1
  944.     vtrn.32         q8,  q10
  945.     SUMSUB_AB       q14, q15, q2,  q3
  946.     vtrn.32         q9,  q11
  947.     SUMSUB_AB       q0,  q2,  q8,  q10
  948.     vtrn.32         q12, q14
  949.     SUMSUB_AB       q1,  q3,  q9,  q11
  950.     vtrn.32         q13, q15
  951.     SUMSUB_ABCD     q8,  q10, q9,  q11, q12, q14, q13, q15
  952.     vabs.s16        q12, q0
  953.     vabs.s16        q13, q8
  954.     vabs.s16        q15, q1
  955.     vadd.s16        q12, q12, q13
  956.     vabs.s16        q14, q2
  957.     vand.s16        q12, q12, q6
  958.     vabs.s16        q13, q3
  959.     vadd.s16        q12, q12, q15
  960.     vabs.s16        q15, q9
  961.     vadd.s16        q12, q12, q14
  962.     vabs.s16        q14, q10
  963.     vadd.s16        q12, q12, q13
  964.     vabs.s16        q13, q11
  965.     vadd.s16        q12, q12, q15
  966.     vsub.s16        q15, q11, q3
  967.     vadd.s16        q12, q12, q14
  968.     vadd.s16        q14, q11, q3
  969.     vadd.s16        q12, q12, q13
  970.     vsub.s16        q13, q10, q2
  971.     vadd.s16        q2,  q10, q2
  972.     vpadal.u16      q4,  q12
  973.     SUMSUB_AB       q10, q11, q9,  q1
  974.     SUMSUB_AB       q9,  q8,  q0,  q8
  975.     vswp            d29, d30
  976.     vabs.s16        q14, q14
  977.     vabs.s16        q15, q15
  978.     vswp            d5,  d26
  979.     vabs.s16        q2,  q2
  980.     vabs.s16        q13, q13
  981.     vswp            d21, d22
  982.     vabs.s16        q10, q10
  983.     vabs.s16        q11, q11
  984.     vmax.s16        q3,  q14, q15
  985.     vmax.s16        q2,  q2,  q13
  986.     vmax.s16        q1,  q10, q11
  987.     vswp            d19, d16
  988.     SUMSUB_AB       q14, q15, q9,  q8
  989.     vadd.s16        q2,  q2,  q3
  990.     vadd.s16        q2,  q2,  q1
  991.     vand            q14, q14, q7
  992.     vadd.s16        q2,  q2,  q2
  993.     vabs.s16        q15, q15
  994.     vabs.s16        q14, q14
  995.     vadd.s16        q2,  q2,  q15
  996.     vadd.s16        q2,  q2,  q14
  997.     vpadal.u16      q5,  q2
  998.     bx              lr
  999. .endfunc
  1000. .macro SSIM_ITER n ssa s12 ssb lastssa lasts12 lastssb da db dnext
  1001.     vld1.64     {db}, [r2], r3
  1002.     vmull.u8    ssa,  da, da
  1003.     vmull.u8    s12,  da, db
  1004. .if n == 1
  1005.     vpaddl.u16  q2,  lastssa
  1006.     vpaddl.u16  q3,  lasts12
  1007.     vaddl.u8    q0,  d0,  da
  1008. .else
  1009.     vpadal.u16  q2,  lastssa
  1010.     vpadal.u16  q3,  lasts12
  1011.     vaddw.u8    q0,  q0,  da
  1012. .endif
  1013.     vpadal.u16  q2,  lastssb
  1014. .if n < 3
  1015.     vld1.64     {dnext}, [r0], r1
  1016. .endif
  1017. .if n == 1
  1018.     vaddl.u8    q1,  d2,  db
  1019. .else
  1020.     vaddw.u8    q1,  q1,  db
  1021. .endif
  1022.     vmull.u8    ssb, db, db
  1023. .endm
  1024. function x264_pixel_ssim_4x4x2_core_neon, export=1
  1025.     ldr         ip, [sp]
  1026.     vld1.64     {d0}, [r0], r1
  1027.     vld1.64     {d2}, [r2], r3
  1028.     vmull.u8    q2,  d0,  d0
  1029.     vmull.u8    q3,  d0,  d2
  1030.     vld1.64     {d28}, [r0], r1
  1031.     vmull.u8    q15, d2,  d2
  1032.     SSIM_ITER 1, q8, q9, q14,  q2, q3, q15,  d28, d29, d26
  1033.     SSIM_ITER 2, q10,q11,q13,  q8, q9, q14,  d26, d27, d28
  1034.     SSIM_ITER 3, q8, q9, q15,  q10,q11,q13,  d28, d29
  1035.     vpadal.u16  q2,  q8
  1036.     vpaddl.u16  q0,  q0
  1037.     vpaddl.u16  q1,  q1
  1038.     vpadal.u16  q2,  q15
  1039.     vpadal.u16  q3,  q9
  1040.     vpadd.u32   d0,  d0,  d1
  1041.     vpadd.u32   d1,  d2,  d3
  1042.     vpadd.u32   d2,  d4,  d5
  1043.     vpadd.u32   d3,  d6,  d7
  1044.     vst4.32     {d0-d3}, [ip]
  1045.     bx          lr
  1046. .endfunc
  1047. // FIXME: see about doing 16x16 -> 32 bit multiplies for s1/s2
  1048. function x264_pixel_ssim_end4_neon, export=1
  1049.     vld1.32     {d16-d19}, [r0,:128]!
  1050.     vld1.32     {d20-d23}, [r1,:128]!
  1051.     vadd.s32    q0,  q8,  q10
  1052.     vadd.s32    q1,  q9,  q11
  1053.     vld1.32     {d24-d27}, [r0,:128]!
  1054.     vadd.s32    q0,  q0,  q1
  1055.     vld1.32     {d28-d31}, [r1,:128]!
  1056.     vadd.s32    q2,  q12, q14
  1057.     vadd.s32    q3,  q13, q15
  1058.     vld1.32     {d16-d17}, [r0,:128]
  1059.     vadd.s32    q1,  q1,  q2
  1060.     vld1.32     {d18-d19}, [r1,:128]
  1061.     vadd.s32    q8,  q8,  q9
  1062.     vadd.s32    q2,  q2,  q3
  1063.     vadd.s32    q3,  q3,  q8
  1064.     vtrn.32     q0,  q1
  1065.     vtrn.32     q2,  q3
  1066.     vswp        d1,  d4
  1067.     vswp        d3,  d6
  1068. //  s1=q0, s2=q1, ss=q2, s12=q3
  1069.     vmul.s32    q8,  q0,  q1    // s1*s2
  1070.     vmul.s32    q0,  q0,  q0
  1071.     vmla.s32    q0,  q1,  q1    // s1*s1 + s2*s2
  1072.     vshl.s32    q3,  q3,  #7
  1073.     vshl.s32    q2,  q2,  #6
  1074.     vadd.s32    q1,  q8,  q8
  1075.     mov         r3, #416        // ssim_c1 = .01*.01*255*255*64
  1076.     movconst    ip, 235963      // ssim_c2 = .03*.03*255*255*64*63
  1077.     vdup.32     q14, r3
  1078.     vdup.32     q15, ip
  1079.     vsub.s32    q2,  q2,  q0    // vars
  1080.     vsub.s32    q3,  q3,  q1    // covar*2
  1081.     vadd.s32    q0,  q0,  q14
  1082.     vadd.s32    q2,  q2,  q15
  1083.     vadd.s32    q1,  q1,  q14
  1084.     vadd.s32    q3,  q3,  q15
  1085.     vcvt.f32.s32    q0,  q0
  1086.     vcvt.f32.s32    q2,  q2
  1087.     vcvt.f32.s32    q1,  q1
  1088.     vcvt.f32.s32    q3,  q3
  1089.     vmul.f32    q0,  q0,  q2
  1090.     vmul.f32    q1,  q1,  q3
  1091.     cmp         r2,  #4
  1092.     vdiv.f32    s0,  s4,  s0
  1093.     vdiv.f32    s1,  s5,  s1
  1094.     vdiv.f32    s2,  s6,  s2
  1095.     vdiv.f32    s3,  s7,  s3
  1096.     beq         ssim_skip
  1097.     movrel      r3,  mask_ff
  1098.     sub         r3,  r3,  r2,  lsl #2
  1099.     vld1.64     {d6-d7}, [r3]
  1100.     vand        q0,  q0,  q3
  1101. ssim_skip:
  1102.     vadd.f32    d0,  d0,  d1
  1103.     vpadd.f32   d0,  d0,  d0
  1104.     vmov.32     r0,  d0[0]
  1105.     bx          lr
  1106. .endfunc