860 lines · 32.0 KB · Assembly
RawDownload
/* * Copyright © 2018, VideoLAN and dav1d authors * Copyright © 2020, Martin Storsjo * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this *    list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, *    this list of conditions and the following disclaimer in the documentation *    and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "src/arm/asm.S"#include "util.S" .macro loop_filter wdfunction lpf_4_wd\wd\()_neon        vabd.u16        d0,  d22, d23 // abs(p1 - p0)        vabd.u16        d1,  d25, d24 // abs(q1 - q0)        vabd.u16        d2,  d23, d24 // abs(p0 - q0)        vabd.u16        d3,  d22, d25 // abs(p1 - q1).if \wd >= 6        vabd.u16        d4,  d21, d22 // abs(p2 - p1)        vabd.u16        d5,  d26, d25 // abs(q2 - q1).endif.if \wd >= 8        vabd.u16        d6,  d20, d21 // abs(p3 - p2)        vabd.u16        d7,  d27, d26 // abs(q3 - q3).endif.if \wd >= 6        vmax.u16        d4,  d4,  d5.endif        vqadd.u16       d2,  d2,  d2  // abs(p0 - q0) * 2.if \wd >= 8        vmax.u16        d6,  d6,  d7.endif        vshr.u16        d3,  d3,  #1.if \wd >= 8        vmax.u16        d4,  d4,  d6.endif        vmax.u16        d0,  d0,  d1  // max(abs(p1 - p0), abs(q1 - q0))        vqadd.u16       d2,  d2,  d3  // abs(p0 - q0) * 2 + abs(p1 - q1) >> 1.if \wd >= 6        vmax.u16        d4,  d0,  d4        vcge.u16        d1,  d11, d4  // max(abs(p1 - p0), abs(q1 - q0), abs(), abs(), ...) <= I.else        vcge.u16        d1,  d11, d0  // max(abs(p1 - p0), abs(q1 - q0)) <= I.endif        vcge.u16        d2,  d10, d2  // abs(p0 - q0) * 2 + abs(p1 - q1) >> 1 <= E        vand            d1,  d1,  d2  // fm && wd >= 4 (implicit).if \wd >= 6        vmov            d14, d1       // fm && wd > 4 (implicit).endif.if \wd >= 16        vmov            d15, d1       // fm && wd == 16 (implicit).endif         vmov            r10, r11, d1        orrs            r10, r10, r11        beq             9f            // if (!fm || wd < 4) return; .if \wd >= 6        vmov.i16        d10, #1        vabd.u16        d2,  d21, d23 // abs(p2 - p0)        vabd.u16        d3,  d22, d23 // abs(p1 - p0)        vabd.u16        d4,  d25, d24 // abs(q1 - q0)        vabd.u16        d5,  d26, d24 // abs(q2 - q0)        vdup.16         d9,  r9       // bitdepth_min_8.if \wd >= 8        vabd.u16        d6,  d20, d23 // abs(p3 - p0)        vabd.u16        d7,  d27, d24 // abs(q3 - q0).endif        vmax.u16        d2,  d2,  d3        vmax.u16        d4,  d4,  d5.if \wd >= 8        vmax.u16        d6,  d6,  d7.endif        vmax.u16        d2,  d2,  d4        vshl.u16        d10, d10, d9  // F = 1 << bitdepth_min_8.if \wd >= 8        vmax.u16        d2,  d2,  d6.endif .if \wd == 16        vabd.u16        d3,  d17, d23 // abs(p6 - p0)        vabd.u16        d4,  d18, d23 // abs(p5 - p0)        vabd.u16        d5,  d19, d23 // abs(p4 - p0).endif        vcge.u16        d2,  d10, d2  // flat8in.if \wd == 16        vabd.u16        d6,  d28, d24 // abs(q4 - q0)        vabd.u16        d7,  d29, d24 // abs(q5 - q0)        vabd.u16        d8,  d30, d24 // abs(q6 - q0).endif        vand            d14, d2,  d14 // flat8in && fm && wd > 4        vbic            d1,  d1,  d14 // fm && wd >= 4 && !flat8in.if \wd == 16        vmax.u16        d3,  d3,  d4        vmax.u16        d5,  d5,  d6.endif        vmov            r10, r11, d1.if \wd == 16        vmax.u16        d7,  d7,  d8        vmax.u16        d3,  d3,  d5        vmax.u16        d3,  d3,  d7        vcge.u16        d3,  d10, d3  // flat8out.endif        orrs            r10, r10, r11.if \wd == 16        vand            d15, d15, d3  // flat8out && fm && wd == 16        vand            d15, d15, d14 // flat8out && flat8in && fm && wd == 16        vbic            d14, d14, d15 // flat8in && fm && wd >= 4 && !flat8out.endif        beq             1f            // skip wd == 4 case.endif         vdup.16         d3,  r8       // bitdepth_max        vsub.u16        d2,  d22, d25 // p1 - q1        vshr.u16        d3,  d3,  #1  // 128 << bitdepth_min_8 - 1        vcgt.u16        d0,  d0,  d12 // hev        vmvn            d9,  d3       // - 128 * (1 << bitdepth_min_8)        vmin.s16        d2,  d2,  d3  // iclip_diff(p1 - q1)        vmax.s16        d2,  d2,  d9  // iclip_diff(p1 - q1)        vand            d4,  d2,  d0  // if (hev) iclip_diff(p1 - q1)        vsub.u16        d2,  d24, d23        vmov.i16        d6,  #3        vbic            d0,  d1,  d0  // (fm && wd >= 4 && !hev)        vmul.i16        d2,  d2,  d6        vmov.i16        d6,  #4        vadd.i16        d2,  d2,  d4        vmin.s16        d2,  d2,  d3  // f = iclip_diff()        vmov.i16        d7,  #3        vmax.s16        d2,  d2,  d9  // f = iclip_diff()        vqadd.s16       d4,  d6,  d2  // f + 4        vqadd.s16       d5,  d7,  d2  // f + 3        vmin.s16        d4,  d4,  d3  // imin(f + 4, 128 << bitdepth_min_8 - 1)        vmin.s16        d5,  d5,  d3  // imin(f + 3, 128 << bitdepth_min_8 - 1)        vshr.s16        d4,  d4,  #3  // f1        vshr.s16        d5,  d5,  #3  // f2        vmov.i16        d9,  #0        vdup.16         d3,  r8       // bitdepth_max        vqadd.s16       d2,  d23, d5  // p0 + f2        vqsub.s16       d6,  d24, d4  // q0 - f1        vrshr.s16       d4,  d4,  #1  // (f1 + 1) >> 1        vmin.s16        d2,  d2,  d3  // out p0 = iclip_pixel()        vmin.s16        d6,  d6,  d3  // out q0 = iclip_pixel()        vmax.s16        d2,  d2,  d9  // out p0 = iclip_pixel()        vmax.s16        d6,  d6,  d9  // out q0 = iclip_pixel()        vbit            d23, d2,  d1  // if (fm && wd >= 4)        vbit            d24, d6,  d1  // if (fm && wd >= 4)        vqadd.s16       d2,  d22, d4  // p1 + f        vqsub.s16       d6,  d25, d4  // q1 - f        vmin.s16        d2,  d2,  d3  // out p1 = iclip_pixel()        vmin.s16        d6,  d6,  d3  // out q1 = iclip_pixel()        vmax.s16        d2,  d2,  d9  // out p1 = iclip_pixel()        vmax.s16        d6,  d6,  d9  // out q1 = iclip_pixel()        vbit            d22, d2,  d0  // if (fm && wd >= 4 && !hev)        vbit            d25, d6,  d0  // if (fm && wd >= 4 && !hev)1: .if \wd == 6        vmov            r10, r11, d14        orrs            r10, r10, r11        beq             2f            // skip if there's no flat8in         vadd.i16        d0,  d21, d21 // p2 * 2        vadd.i16        d2,  d21, d22 // p2 + p1        vadd.i16        d4,  d22, d23 // p1 + p0        vadd.i16        d6,  d23, d24 // p0 + q0        vadd.i16        d8,  d0,  d2        vadd.i16        d10, d4,  d6        vadd.i16        d12, d24, d25 // q0 + q1        vadd.i16        d8,  d8,  d10        vsub.i16        d12, d12, d0        vadd.i16        d10, d25, d26 // q1 + q2        vrshr.u16       d0,  d8,  #3  // out p1         vadd.i16        d8,  d8,  d12        vsub.i16        d10, d10, d2        vadd.i16        d12, d26, d26 // q2 + q2        vrshr.u16       d1,  d8,  #3  // out p0         vadd.i16        d8,  d8,  d10        vsub.i16        d12, d12, d4        vrshr.u16       d2,  d8,  #3  // out q0         vbit            d22, d0,  d14 // p1 if (flat8in)        vadd.i16        d8,  d8,  d12        vbit            d23, d1,  d14 // p0 if (flat8in)        vrshr.u16       d3,  d8,  #3  // out q1        vbit            d24, d2,  d14 // q0 if (flat8in)        vbit            d25, d3,  d14 // q1 if (flat8in).elseif \wd >= 8        vmov            r10, r11, d14        orrs            r10, r10, r11.if \wd == 8        beq             8f            // skip if there's no flat8in.else        beq             2f            // skip if there's no flat8in.endif         vadd.i16        d0,  d20, d21 // p3 + p2        vadd.i16        d2,  d22, d25 // p1 + q1        vadd.i16        d4,  d20, d22 // p3 + p1        vadd.i16        d6,  d23, d26 // p0 + q2        vadd.i16        d8,  d0,  d0  // 2 * (p3 + p2)        vadd.i16        d9,  d23, d24 // p0 + q0        vadd.i16        d8,  d8,  d4  // + p3 + p1        vsub.i16        d2,  d2,  d0  // p1 + q1 - p3 - p2        vadd.i16        d8,  d8,  d9  // + p0 + q0        vsub.i16        d6,  d6,  d4  // p0 + q2 - p3 - p1        vrshr.u16       d10, d8,  #3  // out p2         vadd.i16        d8,  d8,  d2        vadd.i16        d0,  d20, d23 // p3 + p0        vadd.i16        d2,  d24, d27 // q0 + q3        vrshr.u16       d11, d8,  #3  // out p1         vadd.i16        d8,  d8,  d6        vsub.i16        d2,  d2,  d0  // q0 + q3 - p3 - p0        vadd.i16        d4,  d21, d24 // p2 + q0        vadd.i16        d6,  d25, d27 // q1 + q3        vrshr.u16       d12, d8,  #3  // out p0         vadd.i16        d8,  d8,  d2        vsub.i16        d6,  d6,  d4  // q1 + q3 - p2 - q0        vadd.i16        d0,  d22, d25 // p1 + q1        vadd.i16        d2,  d26, d27 // q2 + q3        vrshr.u16       d13, d8,  #3  // out q0         vadd.i16        d8,  d8,  d6        vsub.i16        d2,  d2,  d0  // q2 + q3 - p1 - q1        vrshr.u16       d0,  d8,  #3  // out q1         vadd.i16        d8,  d8,  d2         vbit            d21, d10, d14        vbit            d22, d11, d14        vbit            d23, d12, d14        vrshr.u16       d1,  d8,  #3  // out q2        vbit            d24, d13, d14        vbit            d25, d0,  d14        vbit            d26, d1,  d14.endif2:.if \wd == 16        vmov            r10, r11, d15        orrs            r10, r10, r11        bne             1f            // check if flat8out is needed        vmov            r10, r11, d14        orrs            r10, r10, r11        beq             8f            // if there was no flat8in, just write the inner 4 pixels        b               7f            // if flat8in was used, write the inner 6 pixels1:         vadd.i16        d2,  d17, d17 // p6 + p6        vadd.i16        d4,  d17, d18 // p6 + p5        vadd.i16        d6,  d17, d19 // p6 + p4        vadd.i16        d8,  d17, d20 // p6 + p3        vadd.i16        d12, d2,  d4        vadd.i16        d10, d6,  d8        vadd.i16        d6,  d17, d21 // p6 + p2        vadd.i16        d12, d12, d10        vadd.i16        d8,  d17, d22 // p6 + p1        vadd.i16        d10, d18, d23 // p5 + p0        vadd.i16        d6,  d6,  d8        vadd.i16        d8,  d19, d24 // p4 + q0        vadd.i16        d12, d12, d6        vadd.i16        d10, d10, d8        vadd.i16        d6,  d20, d25 // p3 + q1        vadd.i16        d12, d12, d10        vsub.i16        d6,  d6,  d2        vadd.i16        d2,  d21, d26 // p2 + q2        vrshr.u16       d0,  d12, #4  // out p5        vadd.i16        d12, d12, d6  // - (p6 + p6) + (p3 + q1)        vsub.i16        d2,  d2,  d4        vadd.i16        d4,  d22, d27 // p1 + q3        vadd.i16        d6,  d17, d19 // p6 + p4        vrshr.u16       d1,  d12, #4  // out p4        vadd.i16        d12, d12, d2  // - (p6 + p5) + (p2 + q2)        vsub.i16        d4,  d4,  d6        vadd.i16        d6,  d23, d28 // p0 + q4        vadd.i16        d8,  d17, d20 // p6 + p3        vrshr.u16       d2,  d12, #4  // out p3        vadd.i16        d12, d12, d4  // - (p6 + p4) + (p1 + q3)        vsub.i16        d6,  d6,  d8        vadd.i16        d8,  d24, d29 // q0 + q5        vadd.i16        d4,  d17, d21 // p6 + p2        vrshr.u16       d3,  d12, #4  // out p2        vadd.i16        d12, d12, d6  // - (p6 + p3) + (p0 + q4)        vsub.i16        d8,  d8,  d4        vadd.i16        d6,  d25, d30 // q1 + q6        vadd.i16        d10, d17, d22 // p6 + p1        vrshr.u16       d4,  d12, #4  // out p1        vadd.i16        d12, d12, d8  // - (p6 + p2) + (q0 + q5)        vsub.i16        d6,  d6,  d10        vadd.i16        d8,  d26, d30 // q2 + q6        vbif            d0,  d18, d15 // out p5        vadd.i16        d10, d18, d23 // p5 + p0        vrshr.u16       d5,  d12, #4  // out p0        vadd.i16        d12, d12, d6  // - (p6 + p1) + (q1 + q6)        vsub.i16        d8,  d8,  d10        vadd.i16        d10, d27, d30 // q3 + q6        vbif            d1,  d19, d15 // out p4        vadd.i16        d18, d19, d24 // p4 + q0        vrshr.u16       d6,  d12, #4  // out q0        vadd.i16        d12, d12, d8  // - (p5 + p0) + (q2 + q6)        vsub.i16        d10, d10, d18        vadd.i16        d8,  d28, d30 // q4 + q6        vbif            d2,  d20, d15 // out p3        vadd.i16        d18, d20, d25 // p3 + q1        vrshr.u16       d7,  d12, #4  // out q1        vadd.i16        d12, d12, d10 // - (p4 + q0) + (q3 + q6)        vsub.i16        d18, d8,  d18        vadd.i16        d10, d29, d30 // q5 + q6        vbif            d3,  d21, d15 // out p2        vadd.i16        d20, d21, d26 // p2 + q2        vrshr.u16       d8,  d12, #4  // out q2        vadd.i16        d12, d12, d18 // - (p3 + q1) + (q4 + q6)        vsub.i16        d10, d10, d20        vadd.i16        d18, d30, d30 // q6 + q6        vbif            d4,  d22, d15 // out p1        vadd.i16        d20, d22, d27 // p1 + q3        vrshr.u16       d9,  d12, #4  // out q3        vadd.i16        d12, d12, d10 // - (p2 + q2) + (q5 + q6)        vsub.i16        d18, d18, d20        vbif            d5,  d23, d15 // out p0        vrshr.u16       d10, d12, #4  // out q4        vadd.i16        d12, d12, d18 // - (p1 + q3) + (q6 + q6)        vrshr.u16       d11, d12, #4  // out q5        vbif            d6,  d24, d15 // out q0        vbif            d7,  d25, d15 // out q1        vbif            d8,  d26, d15 // out q2        vbif            d9,  d27, d15 // out q3        vbif            d10, d28, d15 // out q4        vbif            d11, d29, d15 // out q5.endif         bx              lr.if \wd == 167:        // Return to a shorter epilogue, writing only the inner 6 pixels        bx              r6.endif.if \wd >= 88:        // Return to a shorter epilogue, writing only the inner 4 pixels        bx              r7.endif9:        // Return directly without writing back any pixels        bx              r12endfunc.endm loop_filter 16loop_filter 8loop_filter 6loop_filter 4 .macro lpf_4_wd16        adr             r6,  7f + CONFIG_THUMB        adr             r7,  8f + CONFIG_THUMB        bl              lpf_4_wd16_neon.endm .macro lpf_4_wd8        adr             r7,  8f + CONFIG_THUMB        bl              lpf_4_wd8_neon.endm .macro lpf_4_wd6        bl              lpf_4_wd6_neon.endm .macro lpf_4_wd4        bl              lpf_4_wd4_neon.endm function lpf_v_4_4_neon        mov             r12, lr        sub             r10, r0,  r1, lsl #1        vld1.16         {d22}, [r10, :64], r1 // p1        vld1.16         {d24}, [r0,  :64], r1 // q0        vld1.16         {d23}, [r10, :64], r1 // p0        vld1.16         {d25}, [r0,  :64], r1 // q1        sub             r0,  r0,  r1, lsl #1         lpf_4_wd4         sub             r10, r0,  r1, lsl #1        vst1.16         {d22}, [r10, :64], r1 // p1        vst1.16         {d24}, [r0,  :64], r1 // q0        vst1.16         {d23}, [r10, :64], r1 // p0        vst1.16         {d25}, [r0,  :64], r1 // q1        sub             r0,  r0,  r1, lsl #1        bx              r12endfunc function lpf_h_4_4_neon        mov             r12, lr        sub             r10, r0,  #4        add             r0,  r10, r1, lsl #1        vld1.16         {d22}, [r10], r1        vld1.16         {d24}, [r0],  r1        vld1.16         {d23}, [r10], r1        vld1.16         {d25}, [r0],  r1        add             r0,  r0,  #4         transpose_4x4h  q11, q12, d22, d23, d24, d25         lpf_4_wd4         sub             r10, r0,  r1, lsl #2        sub             r10, r10, #4        transpose_4x4h  q11, q12, d22, d23, d24, d25        add             r0,  r10, r1, lsl #1         vst1.16         {d22}, [r10], r1        vst1.16         {d24}, [r0],  r1        vst1.16         {d23}, [r10], r1        vst1.16         {d25}, [r0],  r1        add             r0,  r0,  #4        bx              r12endfunc function lpf_v_6_4_neon        mov             r12, lr        sub             r10, r0,  r1, lsl #1        sub             r10, r10, r1        vld1.16         {d21}, [r10, :64], r1 // p2        vld1.16         {d24}, [r0,  :64], r1 // q0        vld1.16         {d22}, [r10, :64], r1 // p1        vld1.16         {d25}, [r0,  :64], r1 // q1        vld1.16         {d23}, [r10, :64], r1 // p0        vld1.16         {d26}, [r0,  :64], r1 // q2        sub             r0,  r0,  r1, lsl #1        sub             r0,  r0,  r1         lpf_4_wd6         sub             r10, r0,  r1, lsl #1        vst1.16         {d22}, [r10, :64], r1 // p1        vst1.16         {d24}, [r0,  :64], r1 // q0        vst1.16         {d23}, [r10, :64], r1 // p0        vst1.16         {d25}, [r0,  :64], r1 // q1        sub             r0,  r0,  r1, lsl #1        bx              r12endfunc function lpf_h_6_4_neon        mov             r12, lr        sub             r10, r0,  #8        vld1.16         {d20}, [r10, :64], r1        vld1.16         {d24}, [r0,  :64], r1        vld1.16         {d21}, [r10, :64], r1        vld1.16         {d25}, [r0,  :64], r1        vld1.16         {d22}, [r10, :64], r1        vld1.16         {d26}, [r0,  :64], r1        vld1.16         {d23}, [r10, :64], r1        vld1.16         {d27}, [r0,  :64], r1         transpose_4x4h  q10, q11, d20, d21, d22, d23        transpose_4x4h  q12, q13, d24, d25, d26, d27         lpf_4_wd6         sub             r0,  r0,  #4        transpose_4x4h  q11, q12, d22, d23, d24, d25        sub             r10, r0,  r1, lsl #2        sub             r0,  r0,  r1, lsl #1         vst1.16         {d22}, [r10], r1        vst1.16         {d24}, [r0],  r1        vst1.16         {d23}, [r10], r1        vst1.16         {d25}, [r0],  r1        add             r0,  r0,  #4        bx              r12endfunc function lpf_v_8_4_neon        mov             r12, lr        sub             r10, r0,  r1, lsl #2        vld1.16         {d20}, [r10, :64], r1 // p3        vld1.16         {d24}, [r0,  :64], r1 // q0

Lines 1–500 of 860.

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t