Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. /*
  2.  * Copyright (c) 2014 - 2015 Seppo Tomperi <seppo.tomperi@vtt.fi>
  3.  *
  4.  * This file is part of FFmpeg.
  5.  *
  6.  * FFmpeg is free software; you can redistribute it and/or
  7.  * modify it under the terms of the GNU Lesser General Public
  8.  * License as published by the Free Software Foundation; either
  9.  * version 2.1 of the License, or (at your option) any later version.
  10.  *
  11.  * FFmpeg is distributed in the hope that it will be useful,
  12.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  14.  * Lesser General Public License for more details.
  15.  *
  16.  * You should have received a copy of the GNU Lesser General Public
  17.  * License along with FFmpeg; if not, write to the Free Software
  18.  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  19.  */
  20.  
  21. #include "libavutil/arm/asm.S"
  22. #include "neon.S"
  23.  
  24. #define MAX_PB_SIZE #64
  25.  
  26. .macro regshuffle_d8
  27.     vmov d16, d17
  28.     vmov d17, d18
  29.     vmov d18, d19
  30.     vmov d19, d20
  31.     vmov d20, d21
  32.     vmov d21, d22
  33.     vmov d22, d23
  34. .endm
  35.  
  36. .macro regshuffle_q8
  37.     vmov q0, q1
  38.     vmov q1, q2
  39.     vmov q2, q3
  40.     vmov q3, q4
  41.     vmov q4, q5
  42.     vmov q5, q6
  43.     vmov q6, q7
  44. .endm
  45.  
  46. .macro vextin8
  47.         pld       [r2]
  48.         vld1.8    {q11}, [r2], r3
  49.         vext.8    d16, d22, d23, #1
  50.         vext.8    d17, d22, d23, #2
  51.         vext.8    d18, d22, d23, #3
  52.         vext.8    d19, d22, d23, #4
  53.         vext.8    d20, d22, d23, #5
  54.         vext.8    d21, d22, d23, #6
  55.         vext.8    d22, d22, d23, #7
  56. .endm
  57.  
  58. .macro loadin8
  59.         pld       [r2]
  60.         vld1.8    {d16}, [r2], r3
  61.         pld       [r2]
  62.         vld1.8    {d17}, [r2], r3
  63.         pld       [r2]
  64.         vld1.8    {d18}, [r2], r3
  65.         pld       [r2]
  66.         vld1.8    {d19}, [r2], r3
  67.         pld       [r2]
  68.         vld1.8    {d20}, [r2], r3
  69.         pld       [r2]
  70.         vld1.8    {d21}, [r2], r3
  71.         pld       [r2]
  72.         vld1.8    {d22}, [r2], r3
  73.         pld       [r2]
  74.         vld1.8    {d23}, [r2], r3
  75. .endm
  76.  
  77. .macro qpel_filter_1_32b
  78.         vmov.i16   d16, #58
  79.         vmov.i16   d17, #10
  80.         vmull.s16   q9, d6, d16   // 58 * d0
  81.         vmull.s16  q10, d7, d16   // 58 * d1
  82.         vmov.i16   d16, #17
  83.         vmull.s16  q11, d4, d17   // 10 * c0
  84.         vmull.s16  q12, d5, d17   // 10 * c1
  85.         vmov.i16   d17, #5
  86.         vmull.s16  q13, d8, d16   // 17 * e0
  87.         vmull.s16  q14, d9, d16   // 17 * e1
  88.         vmull.s16  q15, d10, d17  //  5 * f0
  89.         vmull.s16   q8, d11, d17  //  5 * f1
  90.         vsub.s32    q9, q11       // 58 * d0 - 10 * c0
  91.         vsub.s32   q10, q12       // 58 * d1 - 10 * c1
  92.         vshll.s16  q11, d2, #2    // 4 * b0
  93.         vshll.s16  q12, d3, #2    // 4 * b1
  94.         vadd.s32    q9, q13       // 58 * d0 - 10 * c0 + 17 * e0
  95.         vadd.s32   q10, q14       // 58 * d1 - 10 * c1 + 17 * e1
  96.         vsubl.s16  q13, d12, d0   // g0 - a0
  97.         vsubl.s16  q14, d13, d1   // g1 - a1
  98.         vadd.s32    q9, q11       // 58 * d0 - 10 * c0 + 17 * e0 + 4 * b0
  99.         vadd.s32   q10, q12       // 58 * d1 - 10 * c1 + 17 * e1 + 4 * b1
  100.         vsub.s32   q13, q15       // g0 - a0 - 5 * f0
  101.         vsub.s32   q14, q8        // g1 - a1 - 5 * f1
  102.         vadd.s32    q9, q13       // 58 * d0 - 10 * c0 + 17 * e0 + 4 * b0 + g0 - a0 - 5 * f0
  103.         vadd.s32   q10, q14       // 58 * d1 - 10 * c1 + 17 * e1 + 4 * b1 + g1 - a1 - 5 * f1
  104.         vqshrn.s32  d16, q9, #6
  105.         vqshrn.s32  d17, q10, #6
  106. .endm
  107.  
  108. // input  q0 - q7
  109. // output q8
  110. .macro qpel_filter_2_32b
  111.         vmov.i32   q8, #11
  112.         vaddl.s16   q9, d6, d8   // d0 + e0
  113.         vaddl.s16  q10, d7, d9   // d1 + e1
  114.         vaddl.s16  q11, d4, d10  // c0 + f0
  115.         vaddl.s16  q12, d5, d11  // c1 + f1
  116.         vmul.s32   q11, q8       // 11 * (c0 + f0)
  117.         vmul.s32   q12, q8       // 11 * (c1 + f1)
  118.         vmov.i32   q8, #40
  119.         vaddl.s16  q15, d2, d12  // b0 + g0
  120.         vmul.s32    q9, q8       // 40 * (d0 + e0)
  121.         vmul.s32   q10, q8       // 40 * (d1 + e1)
  122.         vaddl.s16   q8, d3, d13  // b1 + g1
  123.         vaddl.s16  q13, d0, d14  // a0 + h0
  124.         vaddl.s16  q14, d1, d15  // a1 + h1
  125.         vshl.s32   q15, #2       // 4*(b0+g0)
  126.         vshl.s32    q8, #2       // 4*(b1+g1)
  127.         vadd.s32   q11, q13      // 11 * (c0 + f0) + a0 + h0
  128.         vadd.s32   q12, q14      // 11 * (c1 + f1) + a1 + h1
  129.         vadd.s32   q9, q15       // 40 * (d0 + e0) + 4*(b0+g0)
  130.         vadd.s32   q10, q8       // 40 * (d1 + e1) + 4*(b1+g1)
  131.         vsub.s32   q9, q11       // 40 * (d0 + e0) + 4*(b0+g0) - (11 * (c0 + f0) + a0 + h0)
  132.         vsub.s32   q10, q12      // 40 * (d1 + e1) + 4*(b1+g1) - (11 * (c1 + f1) + a1 + h1)
  133.         vqshrn.s32  d16, q9, #6
  134.         vqshrn.s32  d17, q10, #6
  135. .endm
  136.  
  137. .macro qpel_filter_3_32b
  138.         vmov.i16   d16, #58
  139.         vmov.i16   d17, #10
  140.         vmull.s16   q9, d8, d16   // 58 * d0
  141.         vmull.s16  q10, d9, d16   // 58 * d1
  142.         vmov.i16   d16, #17
  143.         vmull.s16  q11, d10, d17  // 10 * c0
  144.         vmull.s16  q12, d11, d17  // 10 * c1
  145.         vmov.i16   d17, #5
  146.         vmull.s16  q13, d6, d16   // 17 * e0
  147.         vmull.s16  q14, d7, d16   // 17 * e1
  148.         vmull.s16  q15, d4, d17   //  5 * f0
  149.         vmull.s16   q8, d5, d17   //  5 * f1
  150.         vsub.s32    q9, q11       // 58 * d0 - 10 * c0
  151.         vsub.s32   q10, q12       // 58 * d1 - 10 * c1
  152.         vshll.s16  q11, d12, #2   // 4 * b0
  153.         vshll.s16  q12, d13, #2   // 4 * b1
  154.         vadd.s32    q9, q13       // 58 * d0 - 10 * c0 + 17 * e0
  155.         vadd.s32   q10, q14       // 58 * d1 - 10 * c1 + 17 * e1
  156.         vsubl.s16  q13, d2, d14   // g0 - a0
  157.         vsubl.s16  q14, d3, d15   // g1 - a1
  158.         vadd.s32    q9, q11       // 58 * d0 - 10 * c0 + 17 * e0 + 4 * b0
  159.         vadd.s32   q10, q12       // 58 * d1 - 10 * c1 + 17 * e1 + 4 * b1
  160.         vsub.s32   q13, q15       // g0 - a0 - 5 * f0
  161.         vsub.s32   q14, q8        // g1 - a1 - 5 * f1
  162.         vadd.s32    q9, q13       // 58 * d0 - 10 * c0 + 17 * e0 + 4 * b0 + g0 - a0 - 5 * f0
  163.         vadd.s32   q10, q14       // 58 * d1 - 10 * c1 + 17 * e1 + 4 * b1 + g1 - a1 - 5 * f1
  164.         vqshrn.s32  d16, q9, #6
  165.         vqshrn.s32  d17, q10, #6
  166. .endm
  167.  
  168. .macro qpel_filter_1 out=q7
  169.         vmov.u8    d24, #58
  170.         vmov.u8    d25, #10
  171.         vshll.u8   q13, d20, #4   // 16*e
  172.         vshll.u8   q14, d21, #2   // 4*f
  173.         vmull.u8  \out, d19, d24  // 58*d
  174.         vaddw.u8   q13, q13, d20  // 17*e
  175.         vmull.u8   q15, d18, d25  // 10*c
  176.         vaddw.u8   q14, q14, d21  // 5*f
  177.         vsubl.u8   q12, d22, d16  // g - a
  178.         vadd.u16  \out, q13       // 58d + 17e
  179.         vshll.u8   q13, d17, #2   // 4*b
  180.         vadd.u16   q15, q14       // 10*c + 5*f
  181.         vadd.s16   q13, q12       // - a + 4*b + g
  182.         vsub.s16  \out, q15       // -10*c + 58*d + 17*e -5*f
  183.         vadd.s16  \out, q13       // -a + 4*b -10*c + 58*d + 17*e -5*f
  184. .endm
  185.  
  186. .macro qpel_filter_2 out=q7
  187.         vmov.i16   q12, #10
  188.         vmov.i16   q14, #11
  189.         vaddl.u8   q13, d19, d20   // d + e
  190.         vaddl.u8   q15, d18, d21   // c + f
  191.         vmul.u16   q13, q12        // 10 * (d+e)
  192.         vmul.u16   q15, q14        // 11 * ( c + f)
  193.         vaddl.u8  \out, d17, d22   // b + g
  194.         vaddl.u8   q12, d16, d23   // a + h
  195.         vadd.u16  \out, q13        // b + 10 * (d + e) + g
  196.         vadd.s16   q12, q15
  197.         vshl.u16  \out, #2         // 4 * (b + 10 * (d + e) + g)
  198.         vsub.s16  \out, q12
  199. .endm
  200.  
  201. .macro qpel_filter_3 out=q7
  202.         vmov.u8    d24, #58
  203.         vmov.u8    d25, #10
  204.         vshll.u8   q13, d19, #4     // 16*e
  205.         vshll.u8   q14, d18, #2     // 4*f
  206.         vmull.u8  \out, d20, d24    // 58*d
  207.         vaddw.u8   q13, q13, d19    // 17*e
  208.         vmull.u8   q15, d21, d25    // 10*c
  209.         vaddw.u8   q14, q14, d18    // 5*f
  210.         vsubl.u8   q12, d17, d23    // g - a
  211.         vadd.u16  \out, q13         // 58d + 17e
  212.         vshll.u8   q13, d22, #2     // 4*b
  213.         vadd.u16   q15, q14         // 10*c + 5*f
  214.         vadd.s16   q13, q12         // - a + 4*b + g
  215.         vsub.s16  \out, q15         // -10*c + 58*d + 17*e -5*f
  216.         vadd.s16  \out, q13         // -a + 4*b -10*c + 58*d + 17*e -5*f
  217. .endm
  218.  
  219. .macro  hevc_put_qpel_vX_neon_8 filter
  220.         push   {r4, r5, r6, r7}
  221.         ldr    r4, [sp, #16] // height
  222.         ldr    r5, [sp, #20] // width
  223.         vpush {d8-d15}
  224.         sub       r2, r2, r3, lsl #1
  225.         sub       r2, r3
  226.         mov       r12, r4
  227.         mov       r6, r0
  228.         mov       r7, r2
  229.         lsl       r1, #1
  230. 0:      loadin8
  231.         cmp       r5, #4
  232.         beq       4f
  233. 8:      subs r4, #1
  234.         \filter
  235.         vst1.16    {q7}, [r0], r1
  236.         regshuffle_d8
  237.         vld1.8    {d23}, [r2], r3
  238.         bne 8b
  239.         subs  r5, #8
  240.         beq       99f
  241.         mov r4, r12
  242.         add r6, #16
  243.         mov r0, r6
  244.         add r7, #8
  245.         mov r2, r7
  246.         b     0b
  247. 4:      subs r4, #1
  248.         \filter
  249.         vst1.16    d14, [r0], r1
  250.         regshuffle_d8
  251.         vld1.32    {d23[0]}, [r2], r3
  252.         bne 4b
  253. 99:     vpop {d8-d15}
  254.         pop {r4, r5, r6, r7}
  255.         bx lr
  256. .endm
  257.  
  258. .macro  hevc_put_qpel_uw_vX_neon_8 filter
  259.         push   {r4-r10}
  260.         ldr    r5, [sp, #28] // width
  261.         ldr    r4, [sp, #32] // height
  262.         ldr    r8, [sp, #36] // src2
  263.         ldr    r9, [sp, #40] // src2stride
  264.         vpush {d8-d15}
  265.         sub       r2, r2, r3, lsl #1
  266.         sub       r2, r3
  267.         mov       r12, r4
  268.         mov       r6, r0
  269.         mov       r7, r2
  270.         cmp       r8, #0
  271.         bne       .Lbi\@
  272. 0:      loadin8
  273.         cmp       r5, #4
  274.         beq       4f
  275. 8:      subs r4, #1
  276.         \filter
  277.         vqrshrun.s16   d0, q7, #6
  278.         vst1.8    d0, [r0], r1
  279.         regshuffle_d8
  280.         vld1.8    {d23}, [r2], r3
  281.         bne 8b
  282.         subs  r5, #8
  283.         beq       99f
  284.         mov r4, r12
  285.         add r6, #8
  286.         mov r0, r6
  287.         add r7, #8
  288.         mov r2, r7
  289.         b     0b
  290. 4:      subs r4, #1
  291.         \filter
  292.         vqrshrun.s16   d0, q7, #6
  293.         vst1.32    d0[0], [r0], r1
  294.         regshuffle_d8
  295.         vld1.32    {d23[0]}, [r2], r3
  296.         bne 4b
  297.         b   99f
  298. .Lbi\@: lsl       r9, #1
  299.         mov       r10, r8
  300. 0:      loadin8
  301.         cmp       r5, #4
  302.         beq       4f
  303. 8:      subs r4, #1
  304.         \filter
  305.         vld1.16        {q0}, [r8], r9
  306.         vqadd.s16      q0, q7
  307.         vqrshrun.s16   d0, q0, #7
  308.         vst1.8         d0, [r0], r1
  309.         regshuffle_d8
  310.         vld1.8    {d23}, [r2], r3
  311.         bne 8b
  312.         subs  r5, #8
  313.         beq       99f
  314.         mov r4, r12
  315.         add r6, #8
  316.         mov r0, r6
  317.         add r10, #16
  318.         mov r8, r10
  319.         add r7, #8
  320.         mov r2, r7
  321.         b     0b
  322. 4:      subs r4, #1
  323.         \filter
  324.         vld1.16      d0, [r8], r9
  325.         vqadd.s16    d0, d14
  326.         vqrshrun.s16 d0, q0, #7
  327.         vst1.32      d0[0], [r0], r1
  328.         regshuffle_d8
  329.         vld1.32    {d23[0]}, [r2], r3
  330.         bne 4b
  331. 99:     vpop {d8-d15}
  332.         pop {r4-r10}
  333.         bx lr
  334. .endm
  335.  
  336. function ff_hevc_put_qpel_v1_neon_8, export=1
  337.         hevc_put_qpel_vX_neon_8 qpel_filter_1
  338. endfunc
  339.  
  340. function ff_hevc_put_qpel_v2_neon_8, export=1
  341.         hevc_put_qpel_vX_neon_8 qpel_filter_2
  342. endfunc
  343.  
  344. function ff_hevc_put_qpel_v3_neon_8, export=1
  345.         hevc_put_qpel_vX_neon_8 qpel_filter_3
  346. endfunc
  347.  
  348.  
  349. function ff_hevc_put_qpel_uw_v1_neon_8, export=1
  350.         hevc_put_qpel_uw_vX_neon_8 qpel_filter_1
  351. endfunc
  352.  
  353. function ff_hevc_put_qpel_uw_v2_neon_8, export=1
  354.         hevc_put_qpel_uw_vX_neon_8 qpel_filter_2
  355. endfunc
  356.  
  357. function ff_hevc_put_qpel_uw_v3_neon_8, export=1
  358.         hevc_put_qpel_uw_vX_neon_8 qpel_filter_3
  359. endfunc
  360.  
  361. .macro hevc_put_qpel_hX_neon_8 filter
  362.         push     {r4, r5, r6, r7}
  363.         ldr    r4, [sp, #16] // height
  364.         ldr    r5, [sp, #20] // width
  365.  
  366.         vpush    {d8-d15}
  367.         sub       r2, #4
  368.         lsl       r1, #1
  369.         mov      r12, r4
  370.         mov       r6, r0
  371.         mov       r7, r2
  372.         cmp       r5, #4
  373.         beq       4f
  374. 8:      subs      r4, #1
  375.         vextin8
  376.         \filter
  377.         vst1.16   {q7}, [r0], r1
  378.         bne       8b
  379.         subs      r5, #8
  380.         beq      99f
  381.         mov       r4, r12
  382.         add       r6, #16
  383.         mov       r0, r6
  384.         add       r7, #8
  385.         mov       r2, r7
  386.         cmp       r5, #4
  387.         bne       8b
  388. 4:      subs      r4, #1
  389.         vextin8
  390.         \filter
  391.         vst1.16  d14, [r0], r1
  392.         bne       4b
  393. 99:     vpop     {d8-d15}
  394.         pop      {r4, r5, r6, r7}
  395.         bx lr
  396. .endm
  397.  
  398. .macro hevc_put_qpel_uw_hX_neon_8 filter
  399.         push     {r4-r10}
  400.         ldr       r5, [sp, #28] // width
  401.         ldr       r4, [sp, #32] // height
  402.         ldr       r8, [sp, #36] // src2
  403.         ldr       r9, [sp, #40] // src2stride
  404.         vpush    {d8-d15}
  405.         sub       r2, #4
  406.         mov      r12, r4
  407.         mov       r6, r0
  408.         mov       r7, r2
  409.         cmp       r8, #0
  410.         bne       .Lbi\@
  411.         cmp       r5, #4
  412.         beq       4f
  413. 8:      subs      r4, #1
  414.         vextin8
  415.         \filter
  416.         vqrshrun.s16   d0, q7, #6
  417.         vst1.8    d0, [r0], r1
  418.         bne       8b
  419.         subs      r5, #8
  420.         beq      99f
  421.         mov       r4, r12
  422.         add       r6, #8
  423.         mov       r0, r6
  424.         add       r7, #8
  425.         mov       r2, r7
  426.         cmp       r5, #4
  427.         bne       8b
  428. 4:      subs      r4, #1
  429.         vextin8
  430.         \filter
  431.         vqrshrun.s16   d0, q7, #6
  432.         vst1.32  d0[0], [r0], r1
  433.         bne       4b
  434.         b         99f
  435. .Lbi\@:
  436.         lsl       r9, #1
  437.         cmp       r5, #4
  438.         beq       4f
  439.         mov       r10, r8
  440. 8:      subs      r4, #1
  441.         vextin8
  442.         \filter
  443.         vld1.16        {q0}, [r8], r9
  444.         vqadd.s16      q0, q7
  445.         vqrshrun.s16   d0, q0, #7
  446.         vst1.8         d0, [r0], r1
  447.         bne       8b
  448.         subs      r5, #8
  449.         beq      99f
  450.         mov       r4, r12
  451.         add       r6, #8
  452.         add       r10, #16
  453.         mov       r8, r10
  454.         mov       r0, r6
  455.         add       r7, #8
  456.         mov       r2, r7
  457.         cmp       r5, #4
  458.         bne       8b
  459. 4:      subs      r4, #1
  460.         vextin8
  461.         \filter
  462.         vld1.16      d0, [r8], r9
  463.         vqadd.s16    d0, d14
  464.         vqrshrun.s16 d0, q0, #7
  465.         vst1.32      d0[0], [r0], r1
  466.         bne       4b
  467. 99:     vpop     {d8-d15}
  468.         pop      {r4-r10}
  469.         bx lr
  470. .endm
  471.  
  472. function ff_hevc_put_qpel_h1_neon_8, export=1
  473.         hevc_put_qpel_hX_neon_8 qpel_filter_1
  474. endfunc
  475.  
  476. function ff_hevc_put_qpel_h2_neon_8, export=1
  477.         hevc_put_qpel_hX_neon_8 qpel_filter_2
  478. endfunc
  479.  
  480. function ff_hevc_put_qpel_h3_neon_8, export=1
  481.         hevc_put_qpel_hX_neon_8 qpel_filter_3
  482. endfunc
  483.  
  484.  
  485. function ff_hevc_put_qpel_uw_h1_neon_8, export=1
  486.         hevc_put_qpel_uw_hX_neon_8 qpel_filter_1
  487. endfunc
  488.  
  489. function ff_hevc_put_qpel_uw_h2_neon_8, export=1
  490.         hevc_put_qpel_uw_hX_neon_8 qpel_filter_2
  491. endfunc
  492.  
  493. function ff_hevc_put_qpel_uw_h3_neon_8, export=1
  494.         hevc_put_qpel_uw_hX_neon_8 qpel_filter_3
  495. endfunc
  496.  
  497. .macro hevc_put_qpel_hXvY_neon_8 filterh filterv
  498.         push   {r4, r5, r6, r7}
  499.         ldr    r4, [sp, #16] // height
  500.         ldr    r5, [sp, #20] // width
  501.  
  502.         vpush {d8-d15}
  503.         sub       r2, #4
  504.         sub       r2, r2, r3, lsl #1
  505.         sub       r2, r3  // extra_before 3
  506.         lsl       r1, #1
  507.         mov       r12, r4
  508.         mov       r6, r0
  509.         mov       r7, r2
  510. 0:      vextin8
  511.         \filterh q0
  512.         vextin8
  513.         \filterh q1
  514.         vextin8
  515.         \filterh q2
  516.         vextin8
  517.         \filterh q3
  518.         vextin8
  519.         \filterh q4
  520.         vextin8
  521.         \filterh q5
  522.         vextin8
  523.         \filterh q6
  524.         vextin8
  525.         \filterh q7
  526.         cmp r5, #4
  527.         beq 4f
  528. 8:      subs  r4, #1
  529.         \filterv
  530.         vst1.16    {q8}, [r0], r1
  531.         regshuffle_q8
  532.         vextin8
  533.         \filterh q7
  534.         bne 8b
  535.         subs  r5, #8
  536.         beq 99f
  537.         mov r4, r12
  538.         add r6, #16
  539.         mov r0, r6
  540.         add r7, #8
  541.         mov r2, r7
  542.         b 0b
  543. 4:      subs  r4, #1
  544.         \filterv
  545.         vst1.16    d16, [r0], r1
  546.         regshuffle_q8
  547.         vextin8
  548.         \filterh q7
  549.         bne 4b
  550. 99:     vpop {d8-d15}
  551.         pop {r4, r5, r6, r7}
  552.         bx lr
  553. .endm
  554.  
  555. .macro hevc_put_qpel_uw_hXvY_neon_8 filterh filterv
  556.         push     {r4-r10}
  557.         ldr       r5, [sp, #28] // width
  558.         ldr       r4, [sp, #32] // height
  559.         ldr       r8, [sp, #36] // src2
  560.         ldr       r9, [sp, #40] // src2stride
  561.         vpush {d8-d15}
  562.         sub       r2, #4
  563.         sub       r2, r2, r3, lsl #1
  564.         sub       r2, r3  // extra_before 3
  565.         mov       r12, r4
  566.         mov       r6, r0
  567.         mov       r7, r2
  568.         cmp       r8, #0
  569.         bne       .Lbi\@
  570. 0:      vextin8
  571.         \filterh q0
  572.         vextin8
  573.         \filterh q1
  574.         vextin8
  575.         \filterh q2
  576.         vextin8
  577.         \filterh q3
  578.         vextin8
  579.         \filterh q4
  580.         vextin8
  581.         \filterh q5
  582.         vextin8
  583.         \filterh q6
  584.         vextin8
  585.         \filterh q7
  586.         cmp r5, #4
  587.         beq 4f
  588. 8:      subs  r4, #1
  589.         \filterv
  590.         vqrshrun.s16   d0, q8, #6
  591.         vst1.8    d0, [r0], r1
  592.         regshuffle_q8
  593.         vextin8
  594.         \filterh q7
  595.         bne 8b
  596.         subs  r5, #8
  597.         beq 99f
  598.         mov r4, r12
  599.         add r6, #8
  600.         mov r0, r6
  601.         add r7, #8
  602.         mov r2, r7
  603.         b 0b
  604. 4:      subs  r4, #1
  605.         \filterv
  606.         vqrshrun.s16   d0, q8, #6
  607.         vst1.32        d0[0], [r0], r1
  608.         regshuffle_q8
  609.         vextin8
  610.         \filterh q7
  611.         bne 4b
  612.         b   99f
  613. .Lbi\@: lsl      r9, #1
  614.         mov      r10, r8
  615. 0:      vextin8
  616.         \filterh q0
  617.         vextin8
  618.         \filterh q1
  619.         vextin8
  620.         \filterh q2
  621.         vextin8
  622.         \filterh q3
  623.         vextin8
  624.         \filterh q4
  625.         vextin8
  626.         \filterh q5
  627.         vextin8
  628.         \filterh q6
  629.         vextin8
  630.         \filterh q7
  631.         cmp r5, #4
  632.         beq 4f
  633. 8:      subs  r4, #1
  634.         \filterv
  635.         vld1.16        {q0}, [r8], r9
  636.         vqadd.s16      q0, q8
  637.         vqrshrun.s16   d0, q0, #7
  638.         vst1.8         d0, [r0], r1
  639.         regshuffle_q8
  640.         vextin8
  641.         \filterh q7
  642.         bne 8b
  643.         subs  r5, #8
  644.         beq 99f
  645.         mov r4, r12
  646.         add r6, #8
  647.         mov r0, r6
  648.         add r10, #16
  649.         mov r8, r10
  650.         add r7, #8
  651.         mov r2, r7
  652.         b 0b
  653. 4:      subs  r4, #1
  654.         \filterv
  655.         vld1.16      d0, [r8], r9
  656.         vqadd.s16    d0, d16
  657.         vqrshrun.s16 d0, q0, #7
  658.         vst1.32      d0[0], [r0], r1
  659.         regshuffle_q8
  660.         vextin8
  661.         \filterh q7
  662.         bne 4b
  663. 99:     vpop {d8-d15}
  664.         pop {r4-r10}
  665.         bx lr
  666. .endm
  667.  
  668.  
  669. function ff_hevc_put_qpel_h1v1_neon_8, export=1
  670.         hevc_put_qpel_hXvY_neon_8 qpel_filter_1 qpel_filter_1_32b
  671. endfunc
  672.  
  673. function ff_hevc_put_qpel_h2v1_neon_8, export=1
  674.         hevc_put_qpel_hXvY_neon_8 qpel_filter_2 qpel_filter_1_32b
  675. endfunc
  676.  
  677. function ff_hevc_put_qpel_h3v1_neon_8, export=1
  678.         hevc_put_qpel_hXvY_neon_8 qpel_filter_3 qpel_filter_1_32b
  679. endfunc
  680.  
  681. function ff_hevc_put_qpel_h1v2_neon_8, export=1
  682.         hevc_put_qpel_hXvY_neon_8 qpel_filter_1 qpel_filter_2_32b
  683. endfunc
  684.  
  685. function ff_hevc_put_qpel_h2v2_neon_8, export=1
  686.         hevc_put_qpel_hXvY_neon_8 qpel_filter_2 qpel_filter_2_32b
  687. endfunc
  688.  
  689. function ff_hevc_put_qpel_h3v2_neon_8, export=1
  690.         hevc_put_qpel_hXvY_neon_8 qpel_filter_3 qpel_filter_2_32b
  691. endfunc
  692.  
  693. function ff_hevc_put_qpel_h1v3_neon_8, export=1
  694.         hevc_put_qpel_hXvY_neon_8 qpel_filter_1 qpel_filter_3_32b
  695. endfunc
  696.  
  697. function ff_hevc_put_qpel_h2v3_neon_8, export=1
  698.         hevc_put_qpel_hXvY_neon_8 qpel_filter_2 qpel_filter_3_32b
  699. endfunc
  700.  
  701. function ff_hevc_put_qpel_h3v3_neon_8, export=1
  702.         hevc_put_qpel_hXvY_neon_8 qpel_filter_3 qpel_filter_3_32b
  703. endfunc
  704.  
  705.  
  706. function ff_hevc_put_qpel_uw_h1v1_neon_8, export=1
  707.         hevc_put_qpel_uw_hXvY_neon_8 qpel_filter_1 qpel_filter_1_32b
  708. endfunc
  709.  
  710. function ff_hevc_put_qpel_uw_h2v1_neon_8, export=1
  711.         hevc_put_qpel_uw_hXvY_neon_8 qpel_filter_2 qpel_filter_1_32b
  712. endfunc
  713.  
  714. function ff_hevc_put_qpel_uw_h3v1_neon_8, export=1
  715.         hevc_put_qpel_uw_hXvY_neon_8 qpel_filter_3 qpel_filter_1_32b
  716. endfunc
  717.  
  718. function ff_hevc_put_qpel_uw_h1v2_neon_8, export=1
  719.         hevc_put_qpel_uw_hXvY_neon_8 qpel_filter_1 qpel_filter_2_32b
  720. endfunc
  721.  
  722. function ff_hevc_put_qpel_uw_h2v2_neon_8, export=1
  723.         hevc_put_qpel_uw_hXvY_neon_8 qpel_filter_2 qpel_filter_2_32b
  724. endfunc
  725.  
  726. function ff_hevc_put_qpel_uw_h3v2_neon_8, export=1
  727.         hevc_put_qpel_uw_hXvY_neon_8 qpel_filter_3 qpel_filter_2_32b
  728. endfunc
  729.  
  730. function ff_hevc_put_qpel_uw_h1v3_neon_8, export=1
  731.         hevc_put_qpel_uw_hXvY_neon_8 qpel_filter_1 qpel_filter_3_32b
  732. endfunc
  733.  
  734. function ff_hevc_put_qpel_uw_h2v3_neon_8, export=1
  735.         hevc_put_qpel_uw_hXvY_neon_8 qpel_filter_2 qpel_filter_3_32b
  736. endfunc
  737.  
  738. function ff_hevc_put_qpel_uw_h3v3_neon_8, export=1
  739.         hevc_put_qpel_uw_hXvY_neon_8 qpel_filter_3 qpel_filter_3_32b
  740. endfunc
  741.  
  742. .macro init_put_pixels
  743.         pld    [r1]
  744.         pld    [r1, r2]
  745.         mov    r12, MAX_PB_SIZE
  746.         lsl    r12, #1
  747. .endm
  748.  
  749. function ff_hevc_put_pixels_w2_neon_8, export=1
  750.         init_put_pixels
  751.         vmov.u8      d5, #255
  752.         vshr.u64     d5, #32
  753. 0:      subs r3, #1
  754.         vld1.32     {d0[0]}, [r1], r2
  755.         pld [r1]
  756.         vld1.32     d6, [r0]
  757.         vshll.u8    q0, d0, #6
  758.         vbit        d6, d0, d5
  759.         vst1.32     d6, [r0], r12
  760.         bne 0b
  761.         bx lr
  762. endfunc
  763.  
  764. function ff_hevc_put_pixels_w4_neon_8, export=1
  765.         init_put_pixels
  766. 0:      subs r3, #2
  767.         vld1.32   {d0[0]}, [r1], r2
  768.         vld1.32   {d0[1]}, [r1], r2
  769.         pld       [r1]
  770.         pld       [r1, r2]
  771.         vshll.u8   q0, d0, #6
  772.         vst1.64   {d0}, [r0], r12
  773.         vst1.64   {d1}, [r0], r12
  774.         bne 0b
  775.         bx lr
  776. endfunc
  777.  
  778. function ff_hevc_put_pixels_w6_neon_8, export=1
  779.         init_put_pixels
  780.         vmov.u8      q10, #255
  781.         vshr.u64     d21, #32
  782. 0:      subs r3, #1
  783.         vld1.16     {d0}, [r1], r2
  784.         pld [r1]
  785.         vshll.u8    q0, d0, #6
  786.         vld1.8      {q12}, [r0]
  787.         vbit        q12, q0, q10
  788.         vst1.8      {q12}, [r0], r12
  789.         bne 0b
  790.         bx lr
  791. endfunc
  792.  
  793. function ff_hevc_put_pixels_w8_neon_8, export=1
  794.         init_put_pixels
  795. 0:      subs r3, #2
  796.         vld1.8   {d0}, [r1], r2
  797.         vld1.8   {d2}, [r1], r2
  798.         pld        [r1]
  799.         pld        [r1, r2]
  800.         vshll.u8   q0, d0, #6
  801.         vshll.u8   q1, d2, #6
  802.         vst1.16   {q0}, [r0], r12
  803.         vst1.16   {q1}, [r0], r12
  804.         bne 0b
  805.         bx lr
  806. endfunc
  807.  
  808. function ff_hevc_put_pixels_w12_neon_8, export=1
  809.         init_put_pixels
  810. 0:      subs r3, #2
  811.         vld1.64    {d0}, [r1]
  812.         add       r1, #8
  813.         vld1.32   {d1[0]}, [r1], r2
  814.         sub       r1, #8
  815.         vld1.64    {d2}, [r1]
  816.         add       r1, #8
  817.         vld1.32   {d1[1]}, [r1], r2
  818.         sub       r1, #8
  819.         pld       [r1]
  820.         pld       [r1, r2]
  821.         vshll.u8  q8, d0, #6
  822.         vshll.u8  q9, d1, #6
  823.         vshll.u8  q10, d2, #6
  824.         vmov      d22, d19
  825.         vst1.64   {d16, d17, d18}, [r0], r12
  826.         vst1.64   {d20, d21, d22}, [r0], r12
  827.         bne 0b
  828.         bx lr
  829. endfunc
  830.  
  831. function ff_hevc_put_pixels_w16_neon_8, export=1
  832.         init_put_pixels
  833. 0:      subs r3, #2
  834.         vld1.8   {q0}, [r1], r2
  835.         vld1.8   {q1}, [r1], r2
  836.         pld       [r1]
  837.         pld       [r1, r2]
  838.         vshll.u8  q8, d0, #6
  839.         vshll.u8  q9, d1, #6
  840.         vshll.u8  q10, d2, #6
  841.         vshll.u8  q11, d3, #6
  842.         vst1.8    {q8, q9}, [r0], r12
  843.         vst1.8    {q10, q11}, [r0], r12
  844.         bne 0b
  845.         bx lr
  846. endfunc
  847.  
  848. function ff_hevc_put_pixels_w24_neon_8, export=1
  849.         init_put_pixels
  850. 0:      subs r3, #1
  851.         vld1.8   {d0, d1, d2}, [r1], r2
  852.         pld       [r1]
  853.         vshll.u8  q10, d0, #6
  854.         vshll.u8  q11, d1, #6
  855.         vshll.u8  q12, d2, #6
  856.         vstm     r0, {q10, q11, q12}
  857.         add      r0, r12
  858.         bne 0b
  859.         bx lr
  860. endfunc
  861.  
  862. function ff_hevc_put_pixels_w32_neon_8, export=1
  863.         init_put_pixels
  864. 0:      subs r3, #1
  865.         vld1.8 {q0, q1}, [r1], r2
  866.         pld       [r1]
  867.         vshll.u8  q8, d0, #6
  868.         vshll.u8  q9, d1, #6
  869.         vshll.u8  q10, d2, #6
  870.         vshll.u8  q11, d3, #6
  871.         vstm    r0, {q8, q9, q10, q11}
  872.         add     r0, r12
  873.         bne 0b
  874.         bx lr
  875. endfunc
  876.  
  877. function ff_hevc_put_pixels_w48_neon_8, export=1
  878.         init_put_pixels
  879. 0:      subs r3, #1
  880.         vld1.8    {q0, q1}, [r1]
  881.         add r1, #32
  882.         vld1.8    {q2}, [r1], r2
  883.         sub r1, #32
  884.         pld       [r1]
  885.         vshll.u8  q8, d0, #6
  886.         vshll.u8  q9, d1, #6
  887.         vshll.u8  q10, d2, #6
  888.         vshll.u8  q11, d3, #6
  889.         vshll.u8  q12, d4, #6
  890.         vshll.u8  q13, d5, #6
  891.         vstm r0, {q8, q9, q10, q11, q12, q13}
  892.         add  r0, r12
  893.         bne 0b
  894.         bx lr
  895. endfunc
  896.  
  897. function ff_hevc_put_pixels_w64_neon_8, export=1
  898.         init_put_pixels
  899. 0:      subs r3, #1
  900.         vld1.8    {q0, q1}, [r1]
  901.         add      r1, #32
  902.         vld1.8    {q2, q3}, [r1], r2
  903.         sub      r1, #32
  904.         pld       [r1]
  905.         vshll.u8  q8, d0, #6
  906.         vshll.u8  q9, d1, #6
  907.         vshll.u8  q10, d2, #6
  908.         vshll.u8  q11, d3, #6
  909.         vshll.u8  q12, d4, #6
  910.         vshll.u8  q13, d5, #6
  911.         vshll.u8  q14, d6, #6
  912.         vshll.u8  q15, d7, #6
  913.         vstm    r0, {q8, q9, q10, q11, q12, q13, q14, q15}
  914.         add r0, r12
  915.         bne 0b
  916.         bx lr
  917. endfunc
  918.  
  919. function ff_hevc_put_qpel_uw_pixels_neon_8, export=1
  920.         push   {r4-r9}
  921.         ldr    r5, [sp, #24] // width
  922.         ldr    r4, [sp, #28] // height
  923.         ldr    r8, [sp, #32] // src2
  924.         ldr    r9, [sp, #36] // src2stride
  925.         vpush {d8-d15}
  926.         cmp    r8, #0
  927.         bne    2f
  928. 1:      subs r4, #1
  929.         vld1.8     {d0}, [r2], r3
  930.         vst1.8      d0, [r0], r1
  931.         bne 1b
  932.         vpop {d8-d15}
  933.         pop   {r4-r9}
  934.         bx lr
  935. 2:      subs  r4, #1
  936.         vld1.8         {d0}, [r2], r3
  937.         vld1.16        {q1}, [r8], r9
  938.         vshll.u8       q0, d0, #6
  939.         vqadd.s16      q0, q1
  940.         vqrshrun.s16   d0, q0, #7
  941.         vst1.8      d0, [r0], r1
  942.         bne 2b
  943.         vpop {d8-d15}
  944.         pop   {r4-r9}
  945.         bx lr
  946. endfunc
  947.  
  948. .macro put_qpel_uw_pixels width, regs, regs2, regs3, regs4
  949. function ff_hevc_put_qpel_uw_pixels_w\width\()_neon_8, export=1
  950.         ldr    r12, [sp] // height
  951. 1:      subs   r12, #4
  952.         vld1.32     {\regs}  , [r2], r3
  953.         vld1.32     {\regs2} , [r2], r3
  954.         vld1.32     {\regs3} , [r2], r3
  955.         vld1.32     {\regs4} , [r2], r3
  956.         vst1.32     {\regs}  , [r0], r1
  957.         vst1.32     {\regs2} , [r0], r1
  958.         vst1.32     {\regs3} , [r0], r1
  959.         vst1.32     {\regs4} , [r0], r1
  960.         bne 1b
  961.         bx lr
  962. endfunc
  963. .endm
  964.  
  965. .macro put_qpel_uw_pixels_m width, regs, regs2, regs3, regs4
  966. function ff_hevc_put_qpel_uw_pixels_w\width\()_neon_8, export=1
  967.         push   {r4-r5}
  968.         ldr    r12, [sp, #8] // height
  969. 1:      subs r12, #2
  970.         mov      r4, r2
  971.         vld1.32   {\regs} , [r2]!
  972.         vld1.32   {\regs2} , [r2]
  973.         add      r2, r4, r3
  974.         mov      r4, r2
  975.         vld1.32   {\regs3} , [r2]!
  976.         vld1.32   {\regs4} , [r2]
  977.         add      r2, r4, r3
  978.         mov      r5, r0
  979.         vst1.32   {\regs} , [r0]!
  980.         vst1.32   {\regs2} , [r0]
  981.         add      r0, r5, r1
  982.         mov      r5, r0
  983.         vst1.32   {\regs3} , [r0]!
  984.         vst1.32   {\regs4} , [r0]
  985.         add      r0, r5, r1
  986.         bne 1b
  987.         pop   {r4-r5}
  988.         bx lr
  989. endfunc
  990. .endm
  991.  
  992. put_qpel_uw_pixels    4, d0[0], d0[1], d1[0], d1[1]
  993. put_qpel_uw_pixels    8, d0,    d1,    d2,    d3
  994. put_qpel_uw_pixels_m 12, d0,    d1[0], d2,    d3[0]
  995. put_qpel_uw_pixels   16, q0,    q1,    q2,    q3
  996. put_qpel_uw_pixels   24, d0-d2, d3-d5, d16-d18, d19-d21
  997. put_qpel_uw_pixels   32, q0-q1, q2-q3, q8-q9, q10-q11
  998. put_qpel_uw_pixels_m 48, q0-q1, q2,    q8-q9, q10
  999. put_qpel_uw_pixels_m 64, q0-q1, q2-q3, q8-q9, q10-q11
  1000.