Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Firefox/third_party/dav1d/src/x86/   (Browser von der Mozilla Stiftung Version 136.0.1©)  Datei vom 10.2.2025 mit Größe 326 kB image not shown  

Quelle  mc_sse.asm   Sprache: Masm

 
; Copyright © 2018, VideoLAN and dav1d authors
; Copyright © 2018, Two Orioles, LLC
; Copyright © 2018, VideoLabs
; 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 "config.asm"
%include "ext/x86/x86inc.asm"

SECTION_RODATA 16

; dav1d_obmc_masks[] with 64-x interleaved
obmc_masks: db  0,  0,  0,  0
            ; 2 @4
            db 45, 19, 64,  0
            ; 4 @8
            db 39, 25, 50, 14, 59,  5, 64,  0
            ; 8 @16
            db 36, 28, 42, 22, 48, 16, 53, 11, 57,  7, 61,  3, 64,  0, 64,  0
            ; 16 @32
            db 34, 30, 37, 27, 40, 24, 43, 21, 46, 18, 49, 15, 52, 12, 54, 10
            db 56,  8, 58,  6, 60,  4, 61,  3, 64,  0, 64,  0, 64,  0, 64,  0
            ; 32 @64
            db 33, 31, 35, 29, 36, 28, 38, 26, 40, 24, 41, 23, 43, 21, 44, 20
            db 45, 19, 47, 17, 48, 16, 50, 14, 51, 13, 52, 12, 53, 11, 55,  9
            db 56,  8, 57,  7, 58,  6, 59,  5, 60,  4, 60,  4, 61,  3, 62,  2

warp_8x8_shufA: db 0,  2,  4,  6,  1,  3,  5,  7,  1,  3,  5,  7,  2,  4,  6,  8
warp_8x8_shufB: db 4,  6,  8, 10,  5,  7,  9, 11,  5,  7,  9, 11,  6,  8, 10, 12
warp_8x8_shufC: db 2,  4,  6,  8,  3,  5,  7,  9,  3,  5,  7,  9,  4,  6,  8, 10
warp_8x8_shufD: db 6,  8, 10, 12,  7,  9, 11, 13,  7,  9, 11, 13,  8, 10, 12, 14
blend_shuf:     db 0,  1,  0,  1,  0,  1,  0,  1,  2,  3,  2,  3,  2,  3,  2,  3
subpel_h_shuf4: db 0,  1,  2,  3,  1,  2,  3,  4,  8,  9, 10, 11,  9, 10, 11, 12
                db 2,  3,  4,  5,  3,  4,  5,  6, 10, 11, 12, 13, 11, 12, 13, 14
subpel_h_shufA: db 0,  1,  2,  3,  1,  2,  3,  4,  2,  3,  4,  5,  3,  4,  5,  6
subpel_h_shufB: db 4,  5,  6,  7,  5,  6,  7,  8,  6,  7,  8,  9,  7,  8,  9, 10
subpel_h_shufC: db 8,  9, 10, 11,  9, 10, 11, 12, 10, 11, 12, 13, 11, 12, 13, 14
subpel_h_shufD: db 0,  1,  1,  2,  2,  3,  3,  4,  4,  5,  5,  6,  6,  7,  7,  8
subpel_h_shufE: db 2,  3,  3,  4,  4,  5,  5,  6,  6,  7,  7,  8,  8,  9,  9, 10
subpel_h_shufF: db 4,  5,  5,  6,  6,  7,  7,  8,  8,  9,  9, 10, 10, 11, 11, 12
subpel_s_shuf2: db 0,  1,  2,  3,  0,  1,  2,  3,  8,  9, 10, 11,  8,  9, 10, 11
subpel_s_shuf8: db 0,  1,  8,  9,  2,  3, 10, 11,  4,  5, 12, 13,  6,  7, 14, 15
bilin_h_shuf4:  db 0,  1,  1,  2,  2,  3,  3,  4,  8,  9,  9, 10, 10, 11, 11, 12
unpckw:         db 0,  1,  4,  5,  8,  9, 12, 13,  2,  3,  6,  7, 10, 11, 14, 15
rescale_mul:    dd 0,  1,  2,  3
resize_shuf:    db 0,  0,  0,  0,  0,  1,  2,  3,  4,  5,  6,  7,  7,  7,  7,  7

wm_420_sign:    times 4 dw 258
                times 4 dw 257
wm_422_sign:    times 8 db 128
                times 8 db 127

pb_8x0_8x8: times 8 db 0
            times 8 db 8
bdct_lb_dw: times 4 db 0
            times 4 db 4
            times 4 db 8
            times 4 db 12

pb_64:    times 16 db 64
pw_m256:  times 8 dw -256
pw_1:     times 8 dw 1
pw_2:     times 8 dw 2
pw_8:     times 8 dw 8
pw_15:    times 8 dw 15
pw_26:    times 8 dw 26
pw_34:    times 8 dw 34
pw_512:   times 8 dw 512
pw_1024:  times 8 dw 1024
pw_2048:  times 8 dw 2048
pw_6903:  times 8 dw 6903
pw_8192:  times 8 dw 8192
pd_32:    times 4 dd 32
pd_63:    times 4 dd 63
pd_512:   times 4 dd 512
pd_16384: times 4 dd 16484
pd_32768: times 4 dd 32768
pd_262144:times 4 dd 262144
pd_0x3ff: times 4 dd 0x3ff
pd_0x4000:times 4 dd 0x4000
pq_0x40000000: times 2 dq 0x40000000

const mc_warp_filter2 ; dav1d_mc_warp_filter[] reordered for pmaddubsw usage
    ; [-1, 0)
    db 0, 127,   0, 0,   0,   1, 0, 0, 0, 127,   0, 0,  -1,   2, 0, 0
    db 1, 127,  -1, 0,  -3,   4, 0, 0, 1, 126,  -2, 0,  -4,   6, 1, 0
    db 1, 126,  -3, 0,  -5,   8, 1, 0, 1, 125,  -4, 0,  -6,  11, 1, 0
    db 1, 124,  -4, 0,  -7,  13, 1, 0, 2, 123,  -5, 0,  -8,  15, 1, 0
    db 2, 122,  -6, 0,  -9,  18, 1, 0, 2, 121,  -6, 0, -10,  20, 1, 0
    db 2, 120,  -7, 0, -11,  22, 2, 0, 2, 119,  -8, 0, -12,  25, 2, 0
    db 3, 117,  -8, 0, -13,  27, 2, 0, 3, 116,  -9, 0, -13,  29, 2, 0
    db 3, 114, -10, 0, -14,  32, 3, 0, 3, 113, -10, 0, -15,  35, 2, 0
    db 3, 111, -11, 0, -15,  37, 3, 0, 3, 109, -11, 0, -16,  40, 3, 0
    db 3, 108, -12, 0, -16,  42, 3, 0, 4, 106, -13, 0, -17,  45, 3, 0
    db 4, 104, -13, 0, -17,  47, 3, 0, 4, 102, -14, 0, -17,  50, 3, 0
    db 4, 100, -14, 0, -17,  52, 3, 0, 4,  98, -15, 0, -18,  55, 4, 0
    db 4,  96, -15, 0, -18,  58, 3, 0, 4,  94, -16, 0, -18,  60, 4, 0
    db 4,  91, -16, 0, -18,  63, 4, 0, 4,  89, -16, 0, -18,  65, 4, 0
    db 4,  87, -17, 0, -18,  68, 4, 0, 4,  85, -17, 0, -18,  70, 4, 0
    db 4,  82, -17, 0, -18,  73, 4, 0, 4,  80, -17, 0, -18,  75, 4, 0
    db 4,  78, -18, 0, -18,  78, 4, 0, 4,  75, -18, 0, -17,  80, 4, 0
    db 4,  73, -18, 0, -17,  82, 4, 0, 4,  70, -18, 0, -17,  85, 4, 0
    db 4,  68, -18, 0, -17,  87, 4, 0, 4,  65, -18, 0, -16,  89, 4, 0
    db 4,  63, -18, 0, -16,  91, 4, 0, 4,  60, -18, 0, -16,  94, 4, 0
    db 3,  58, -18, 0, -15,  96, 4, 0, 4,  55, -18, 0, -15,  98, 4, 0
    db 3,  52, -17, 0, -14, 100, 4, 0, 3,  50, -17, 0, -14, 102, 4, 0
    db 3,  47, -17, 0, -13, 104, 4, 0, 3,  45, -17, 0, -13, 106, 4, 0
    db 3,  42, -16, 0, -12, 108, 3, 0, 3,  40, -16, 0, -11, 109, 3, 0
    db 3,  37, -15, 0, -11, 111, 3, 0, 2,  35, -15, 0, -10, 113, 3, 0
    db 3,  32, -14, 0, -10, 114, 3, 0, 2,  29, -13, 0,  -9, 116, 3, 0
    db 2,  27, -13, 0,  -8, 117, 3, 0, 2,  25, -12, 0,  -8, 119, 2, 0
    db 2,  22, -11, 0,  -7, 120, 2, 0, 1,  20, -10, 0,  -6, 121, 2, 0
    db 1,  18,  -9, 0,  -6, 122, 2, 0, 1,  15,  -8, 0,  -5, 123, 2, 0
    db 1,  13,  -7, 0,  -4, 124, 1, 0, 1,  11,  -6, 0,  -4, 125, 1, 0
    db 1,   8,  -5, 0,  -3, 126, 1, 0, 1,   6,  -4, 0,  -2, 126, 1, 0
    db 0,   4,  -3, 0,  -1, 127, 1, 0, 0,   2,  -1, 0,   0, 127, 0, 0
    ; [0, 1)
    db  0,   0,   1, 0, 0, 127,   0,  0,  0,  -1,   2, 0, 0, 127,   0,  0
    db  0,  -3,   4, 1, 1, 127,  -2,  0,  0,  -5,   6, 1, 1, 127,  -2,  0
    db  0,  -6,   8, 1, 2, 126,  -3,  0, -1,  -7,  11, 2, 2, 126,  -4, -1
    db -1,  -8,  13, 2, 3, 125,  -5, -1, -1, -10,  16, 3, 3, 124,  -6, -1
    db -1, -11,  18, 3, 4, 123,  -7, -1, -1, -12,  20, 3, 4, 122,  -7, -1
    db -1, -13,  23, 3, 4, 121,  -8, -1, -2, -14,  25, 4, 5, 120,  -9, -1
    db -1, -15,  27, 4, 5, 119, -10, -1, -1, -16,  30, 4, 5, 118, -11, -1
    db -2, -17,  33, 5, 6, 116, -12, -1, -2, -17,  35, 5, 6, 114, -12, -1
    db -2, -18,  38, 5, 6, 113, -13, -1, -2, -19,  41, 6, 7, 111, -14, -2
    db -2, -19,  43, 6, 7, 110, -15, -2, -2, -20,  46, 6, 7, 108, -15, -2
    db -2, -20,  49, 6, 7, 106, -16, -2, -2, -21,  51, 7, 7, 104, -16, -2
    db -2, -21,  54, 7, 7, 102, -17, -2, -2, -21,  56, 7, 8, 100, -18, -2
    db -2, -22,  59, 7, 8,  98, -18, -2, -2, -22,  62, 7, 8,  96, -19, -2
    db -2, -22,  64, 7, 8,  94, -19, -2, -2, -22,  67, 8, 8,  91, -20, -2
    db -2, -22,  69, 8, 8,  89, -20, -2, -2, -22,  72, 8, 8,  87, -21, -2
    db -2, -21,  74, 8, 8,  84, -21, -2, -2, -22,  77, 8, 8,  82, -21, -2
    db -2, -21,  79, 8, 8,  79, -21, -2, -2, -21,  82, 8, 8,  77, -22, -2
    db -2, -21,  84, 8, 8,  74, -21, -2, -2, -21,  87, 8, 8,  72, -22, -2
    db -2, -20,  89, 8, 8,  69, -22, -2, -2, -20,  91, 8, 8,  67, -22, -2
    db -2, -19,  94, 8, 7,  64, -22, -2, -2, -19,  96, 8, 7,  62, -22, -2
    db -2, -18,  98, 8, 7,  59, -22, -2, -2, -18, 100, 8, 7,  56, -21, -2
    db -2, -17, 102, 7, 7,  54, -21, -2, -2, -16, 104, 7, 7,  51, -21, -2
    db -2, -16, 106, 7, 6,  49, -20, -2, -2, -15, 108, 7, 6,  46, -20, -2
    db -2, -15, 110, 7, 6,  43, -19, -2, -2, -14, 111, 7, 6,  41, -19, -2
    db -1, -13, 113, 6, 5,  38, -18, -2, -1, -12, 114, 6, 5,  35, -17, -2
    db -1, -12, 116, 6, 5,  33, -17, -2, -1, -11, 118, 5, 4,  30, -16, -1
    db -1, -10, 119, 5, 4,  27, -15, -1, -1,  -9, 120, 5, 4,  25, -14, -2
    db -1,  -8, 121, 4, 3,  23, -13, -1, -1,  -7, 122, 4, 3,  20, -12, -1
    db -1,  -7, 123, 4, 3,  18, -11, -1, -1,  -6, 124, 3, 3,  16, -10, -1
    db -1,  -5, 125, 3, 2,  13,  -8, -1, -1,  -4, 126, 2, 2,  11,  -7, -1
    db  0,  -3, 126, 2, 1,   8,  -6,  0,  0,  -2, 127, 1, 1,   6,  -5,  0
    db  0,  -2, 127, 1, 1,   4,  -3,  0,  0,   0, 127, 0, 0,   2,  -1,  0
    ; [1, 2)
    db 0, 0, 127,   0, 0,   1,   0, 0, 0, 0, 127,   0, 0,  -1,   2, 0
    db 0, 1, 127,  -1, 0,  -3,   4, 0, 0, 1, 126,  -2, 0,  -4,   6, 1
    db 0, 1, 126,  -3, 0,  -5,   8, 1, 0, 1, 125,  -4, 0,  -6,  11, 1
    db 0, 1, 124,  -4, 0,  -7,  13, 1, 0, 2, 123,  -5, 0,  -8,  15, 1
    db 0, 2, 122,  -6, 0,  -9,  18, 1, 0, 2, 121,  -6, 0, -10,  20, 1
    db 0, 2, 120,  -7, 0, -11,  22, 2, 0, 2, 119,  -8, 0, -12,  25, 2
    db 0, 3, 117,  -8, 0, -13,  27, 2, 0, 3, 116,  -9, 0, -13,  29, 2
    db 0, 3, 114, -10, 0, -14,  32, 3, 0, 3, 113, -10, 0, -15,  35, 2
    db 0, 3, 111, -11, 0, -15,  37, 3, 0, 3, 109, -11, 0, -16,  40, 3
    db 0, 3, 108, -12, 0, -16,  42, 3, 0, 4, 106, -13, 0, -17,  45, 3
    db 0, 4, 104, -13, 0, -17,  47, 3, 0, 4, 102, -14, 0, -17,  50, 3
    db 0, 4, 100, -14, 0, -17,  52, 3, 0, 4,  98, -15, 0, -18,  55, 4
    db 0, 4,  96, -15, 0, -18,  58, 3, 0, 4,  94, -16, 0, -18,  60, 4
    db 0, 4,  91, -16, 0, -18,  63, 4, 0, 4,  89, -16, 0, -18,  65, 4
    db 0, 4,  87, -17, 0, -18,  68, 4, 0, 4,  85, -17, 0, -18,  70, 4
    db 0, 4,  82, -17, 0, -18,  73, 4, 0, 4,  80, -17, 0, -18,  75, 4
    db 0, 4,  78, -18, 0, -18,  78, 4, 0, 4,  75, -18, 0, -17,  80, 4
    db 0, 4,  73, -18, 0, -17,  82, 4, 0, 4,  70, -18, 0, -17,  85, 4
    db 0, 4,  68, -18, 0, -17,  87, 4, 0, 4,  65, -18, 0, -16,  89, 4
    db 0, 4,  63, -18, 0, -16,  91, 4, 0, 4,  60, -18, 0, -16,  94, 4
    db 0, 3,  58, -18, 0, -15,  96, 4, 0, 4,  55, -18, 0, -15,  98, 4
    db 0, 3,  52, -17, 0, -14, 100, 4, 0, 3,  50, -17, 0, -14, 102, 4
    db 0, 3,  47, -17, 0, -13, 104, 4, 0, 3,  45, -17, 0, -13, 106, 4
    db 0, 3,  42, -16, 0, -12, 108, 3, 0, 3,  40, -16, 0, -11, 109, 3
    db 0, 3,  37, -15, 0, -11, 111, 3, 0, 2,  35, -15, 0, -10, 113, 3
    db 0, 3,  32, -14, 0, -10, 114, 3, 0, 2,  29, -13, 0,  -9, 116, 3
    db 0, 2,  27, -13, 0,  -8, 117, 3, 0, 2,  25, -12, 0,  -8, 119, 2
    db 0, 2,  22, -11, 0,  -7, 120, 2, 0, 1,  20, -10, 0,  -6, 121, 2
    db 0, 1,  18,  -9, 0,  -6, 122, 2, 0, 1,  15,  -8, 0,  -5, 123, 2
    db 0, 1,  13,  -7, 0,  -4, 124, 1, 0, 1,  11,  -6, 0,  -4, 125, 1
    db 0, 1,   8,  -5, 0,  -3, 126, 1, 0, 1,   6,  -4, 0,  -2, 126, 1
    db 0, 0,   4,  -3, 0,  -1, 127, 1, 0, 0,   2,  -1, 0,   0, 127, 0
    db 0, 0,   2,  -1, 0,   0, 127, 0

pw_258:  times 2 dw 258

cextern mc_subpel_filters
%define subpel_filters (mangle(private_prefix %+ _mc_subpel_filters)-8)

%macro BIDIR_JMP_TABLE 2-*
    ;evaluated at definition time (in loop below)
    %xdefine %1_%2_table (%%table - 2*%3)
    %xdefine %%base %1_%2_table
    %xdefine %%prefix mangle(private_prefix %+ _%1_8bpc_%2)
    ; dynamically generated label
    %%table:
    %rep %0 - 2 ; repeat for num args
        dd %%prefix %+ .w%3 - %%base
        %rotate 1
    %endrep
%endmacro

BIDIR_JMP_TABLE avg, ssse3,        4, 8, 16, 32, 64, 128
BIDIR_JMP_TABLE w_avg, ssse3,      4, 8, 16, 32, 64, 128
BIDIR_JMP_TABLE mask, ssse3,       4, 8, 16, 32, 64, 128
BIDIR_JMP_TABLE w_mask_420, ssse3, 4, 8, 16, 32, 64, 128
BIDIR_JMP_TABLE w_mask_422, ssse3, 4, 8, 16, 32, 64, 128
BIDIR_JMP_TABLE w_mask_444, ssse3, 4, 8, 16, 32, 64, 128
BIDIR_JMP_TABLE blend, ssse3,      4, 8, 16, 32
BIDIR_JMP_TABLE blend_v, ssse3, 2, 4, 8, 16, 32
BIDIR_JMP_TABLE blend_h, ssse3, 2, 4, 8, 16, 16, 16, 16

%macro BASE_JMP_TABLE 3-*
    %xdefine %1_%2_table (%%table - %3)
    %xdefine %%base %1_%2
    %%table:
    %rep %0 - 2
        dw %%base %+ _w%3 - %%base
        %rotate 1
    %endrep
%endmacro

%xdefine put_ssse3 mangle(private_prefix %+ _put_bilin_8bpc_ssse3.put)
%xdefine prep_ssse3 mangle(private_prefix %+ _prep_bilin_8bpc_ssse3.prep)

BASE_JMP_TABLE put,  ssse3, 2, 4, 8, 16, 32, 64, 128
BASE_JMP_TABLE prep, ssse3,    4, 8, 16, 32, 64, 128

%macro HV_JMP_TABLE 5-*
    %xdefine %%prefix mangle(private_prefix %+ _%1_%2_8bpc_%3)
    %xdefine %%base %1_%3
    %assign %%types %4
    %if %%types & 1
        %xdefine %1_%2_h_%3_table  (%%h  - %5)
        %%h:
        %rep %0 - 4
            dw %%prefix %+ .h_w%5 - %%base
            %rotate 1
        %endrep
        %rotate 4
    %endif
    %if %%types & 2
        %xdefine %1_%2_v_%3_table  (%%v  - %5)
        %%v:
        %rep %0 - 4
            dw %%prefix %+ .v_w%5 - %%base
            %rotate 1
        %endrep
        %rotate 4
    %endif
    %if %%types & 4
        %xdefine %1_%2_hv_%3_table (%%hv - %5)
        %%hv:
        %rep %0 - 4
            dw %%prefix %+ .hv_w%5 - %%base
            %rotate 1
        %endrep
    %endif
%endmacro

HV_JMP_TABLE prep,  8tap, ssse3, 1,    4, 8, 16, 32, 64, 128
HV_JMP_TABLE put,  bilin, ssse3, 7, 2, 4, 8, 16, 32, 64, 128
HV_JMP_TABLE prep, bilin, ssse3, 7,    4, 8, 16, 32, 64, 128

%macro SCALED_JMP_TABLE 2-*
    %xdefine %1_%2_table (%%table - %3)
    %xdefine %%base mangle(private_prefix %+ _%1_8bpc_%2)
%%table:
    %rep %0 - 2
        dw %%base %+ .w%3 - %%base
        %rotate 1
    %endrep
    %rotate 2
%%dy_1024:
    %xdefine %1_%2_dy1_table (%%dy_1024 - %3)
    %rep %0 - 2
        dw %%base %+ .dy1_w%3 - %%base
        %rotate 1
    %endrep
    %rotate 2
%%dy_2048:
    %xdefine %1_%2_dy2_table (%%dy_2048 - %3)
    %rep %0 - 2
        dw %%base %+ .dy2_w%3 - %%base
        %rotate 1
    %endrep
%endmacro

SCALED_JMP_TABLE put_8tap_scaled, ssse3, 2, 4, 8, 16, 32, 64, 128
SCALED_JMP_TABLE prep_8tap_scaled, ssse3,   4, 8, 16, 32, 64, 128

%define table_offset(type, fn) type %+ fn %+ SUFFIX %+ _table - type %+ SUFFIX

SECTION .text

INIT_XMM ssse3

%if ARCH_X86_32
 DECLARE_REG_TMP 1
 %define base t0-put_ssse3
%else
 DECLARE_REG_TMP 7
 %define base 0
%endif

%macro RESTORE_DSQ_32 1
 %if ARCH_X86_32
   mov                  %1, dsm ; restore dsq
 %endif
%endmacro

cglobal put_bilin_8bpc, 1, 8, 0, dst, ds, src, ss, w, h, mxy
    movifnidn          mxyd, r6m ; mx
    LEA                  t0, put_ssse3
    movifnidn          srcq, srcmp
    movifnidn           ssq, ssmp
    tzcnt                wd, wm
    mov                  hd, hm
    test               mxyd, mxyd
    jnz .h
    mov                mxyd, r7m ; my
    test               mxyd, mxyd
    jnz .v
.put:
    movzx                wd, word [t0+wq*2+table_offset(put,)]
    add                  wq, t0
    RESTORE_DSQ_32       t0
    jmp                  wq
.put_w2:
    movzx               r4d, word [srcq+ssq*0]
    movzx               r6d, word [srcq+ssq*1]
    lea                srcq, [srcq+ssq*2]
    mov        [dstq+dsq*0], r4w
    mov        [dstq+dsq*1], r6w
    lea                dstq, [dstq+dsq*2]
    sub                  hd, 2
    jg .put_w2
    RET
.put_w4:
    mov                 r4d, [srcq+ssq*0]
    mov                 r6d, [srcq+ssq*1]
    lea                srcq, [srcq+ssq*2]
    mov        [dstq+dsq*0], r4d
    mov        [dstq+dsq*1], r6d
    lea                dstq, [dstq+dsq*2]
    sub                  hd, 2
    jg .put_w4
    RET
.put_w8:
    movq                 m0, [srcq+ssq*0]
    movq                 m1, [srcq+ssq*1]
    lea                srcq, [srcq+ssq*2]
    movq       [dstq+dsq*0], m0
    movq       [dstq+dsq*1], m1
    lea                dstq, [dstq+dsq*2]
    sub                  hd, 2
    jg .put_w8
    RET
.put_w16:
    movu                 m0, [srcq+ssq*0]
    movu                 m1, [srcq+ssq*1]
    lea                srcq, [srcq+ssq*2]
    mova       [dstq+dsq*0], m0
    mova       [dstq+dsq*1], m1
    lea                dstq, [dstq+dsq*2]
    sub                  hd, 2
    jg .put_w16
    RET
.put_w32:
    movu                 m0, [srcq+ssq*0+16*0]
    movu                 m1, [srcq+ssq*0+16*1]
    movu                 m2, [srcq+ssq*1+16*0]
    movu                 m3, [srcq+ssq*1+16*1]
    lea                srcq, [srcq+ssq*2]
    mova  [dstq+dsq*0+16*0], m0
    mova  [dstq+dsq*0+16*1], m1
    mova  [dstq+dsq*1+16*0], m2
    mova  [dstq+dsq*1+16*1], m3
    lea                dstq, [dstq+dsq*2]
    sub                  hd, 2
    jg .put_w32
    RET
.put_w64:
    movu                 m0, [srcq+16*0]
    movu                 m1, [srcq+16*1]
    movu                 m2, [srcq+16*2]
    movu                 m3, [srcq+16*3]
    add                srcq, ssq
    mova        [dstq+16*0], m0
    mova        [dstq+16*1], m1
    mova        [dstq+16*2], m2
    mova        [dstq+16*3], m3
    add                dstq, dsq
    dec                  hd
    jg .put_w64
    RET
.put_w128:
    movu                 m0, [srcq+16*0]
    movu                 m1, [srcq+16*1]
    movu                 m2, [srcq+16*2]
    movu                 m3, [srcq+16*3]
    mova        [dstq+16*0], m0
    mova        [dstq+16*1], m1
    mova        [dstq+16*2], m2
    mova        [dstq+16*3], m3
    movu                 m0, [srcq+16*4]
    movu                 m1, [srcq+16*5]
    movu                 m2, [srcq+16*6]
    movu                 m3, [srcq+16*7]
    mova        [dstq+16*4], m0
    mova        [dstq+16*5], m1
    mova        [dstq+16*6], m2
    mova        [dstq+16*7], m3
    add                srcq, ssq
    add                dstq, dsq
    dec                  hd
    jg .put_w128
    RET
.h:
    ; (16 * src[x] + (mx * (src[x + 1] - src[x])) + 8) >> 4
    ; = ((16 - mx) * src[x] + mx * src[x + 1] + 8) >> 4
    imul               mxyd, 0x00ff00ff
    mova                 m4, [base+subpel_h_shufD]
    mova                 m0, [base+bilin_h_shuf4]
    add                mxyd, 0x00100010
    movd                 m5, mxyd
    mov                mxyd, r7m ; my
    pshufd               m5, m5, q0000
    test               mxyd, mxyd
    jnz .hv
    movzx                wd, word [t0+wq*2+table_offset(put, _bilin_h)]
    mova                 m3, [base+pw_2048]
    add                  wq, t0
    movifnidn           dsq, dsmp
    jmp                  wq
.h_w2:
    pshufd               m4, m4, q3120 ; m4 = {1, 0, 2, 1, 5, 4, 6, 5}
.h_w2_loop:
    movd                 m0, [srcq+ssq*0]
    movd                 m1, [srcq+ssq*1]
    lea                srcq, [srcq+ssq*2]
    punpckldq            m0, m1
    pshufb               m0, m4
    pmaddubsw            m0, m5
    pmulhrsw             m0, m3
    packuswb             m0, m0
    movd                r6d, m0
    mov        [dstq+dsq*0], r6w
    shr                 r6d, 16
    mov        [dstq+dsq*1], r6w
    lea                dstq, [dstq+dsq*2]
    sub                  hd, 2
    jg .h_w2_loop
    RET
.h_w4:
    movq                 m4, [srcq+ssq*0]
    movhps               m4, [srcq+ssq*1]
    lea                srcq, [srcq+ssq*2]
    pshufb               m4, m0
    pmaddubsw            m4, m5
    pmulhrsw             m4, m3
    packuswb             m4, m4
    movd       [dstq+dsq*0], m4
    psrlq                m4, 32
    movd       [dstq+dsq*1], m4
    lea                dstq, [dstq+dsq*2]
    sub                  hd, 2
    jg .h_w4
    RET
.h_w8:
    movu                 m0, [srcq+ssq*0]
    movu                 m1, [srcq+ssq*1]
    lea                srcq, [srcq+ssq*2]
    pshufb               m0, m4
    pshufb               m1, m4
    pmaddubsw            m0, m5
    pmaddubsw            m1, m5
    pmulhrsw             m0, m3
    pmulhrsw             m1, m3
    packuswb             m0, m1
    movq       [dstq+dsq*0], m0
    movhps     [dstq+dsq*1], m0
    lea                dstq, [dstq+dsq*2]
    sub                  hd, 2
    jg .h_w8
    RET
.h_w16:
    movu                 m0, [srcq+8*0]
    movu                 m1, [srcq+8*1]
    add                srcq, ssq
    pshufb               m0, m4
    pshufb               m1, m4
    pmaddubsw            m0, m5
    pmaddubsw            m1, m5
    pmulhrsw             m0, m3
    pmulhrsw             m1, m3
    packuswb             m0, m1
    mova             [dstq], m0
    add                dstq, dsq
    dec                  hd
    jg .h_w16
    RET
.h_w32:
    movu                 m0, [srcq+mmsize*0+8*0]
    movu                 m1, [srcq+mmsize*0+8*1]
    pshufb               m0, m4
    pshufb               m1, m4
    pmaddubsw            m0, m5
    pmaddubsw            m1, m5
    pmulhrsw             m0, m3
    pmulhrsw             m1, m3
    packuswb             m0, m1
    movu                 m1, [srcq+mmsize*1+8*0]
    movu                 m2, [srcq+mmsize*1+8*1]
    add                srcq, ssq
    pshufb               m1, m4
    pshufb               m2, m4
    pmaddubsw            m1, m5
    pmaddubsw            m2, m5
    pmulhrsw             m1, m3
    pmulhrsw             m2, m3
    packuswb             m1, m2
    mova        [dstq+16*0], m0
    mova        [dstq+16*1], m1
    add                dstq, dsq
    dec                  hd
    jg .h_w32
    RET
.h_w64:
    mov                  r6, -16*3
.h_w64_loop:
    movu                 m0, [srcq+r6+16*3+8*0]
    movu                 m1, [srcq+r6+16*3+8*1]
    pshufb               m0, m4
    pshufb               m1, m4
    pmaddubsw            m0, m5
    pmaddubsw            m1, m5
    pmulhrsw             m0, m3
    pmulhrsw             m1, m3
    packuswb             m0, m1
    mova     [dstq+r6+16*3], m0
    add                  r6, 16
    jle .h_w64_loop
    add                srcq, ssq
    add                dstq, dsq
    dec                  hd
    jg .h_w64
    RET
.h_w128:
    mov                  r6, -16*7
.h_w128_loop:
    movu                 m0, [srcq+r6+16*7+8*0]
    movu                 m1, [srcq+r6+16*7+8*1]
    pshufb               m0, m4
    pshufb               m1, m4
    pmaddubsw            m0, m5
    pmaddubsw            m1, m5
    pmulhrsw             m0, m3
    pmulhrsw             m1, m3
    packuswb             m0, m1
    mova     [dstq+r6+16*7], m0
    add                  r6, 16
    jle .h_w128_loop
    add                srcq, ssq
    add                dstq, dsq
    dec                  hd
    jg .h_w128
    RET
.v:
    movzx                wd, word [t0+wq*2+table_offset(put, _bilin_v)]
    imul               mxyd, 0x00ff00ff
    mova                 m5, [base+pw_2048]
    add                mxyd, 0x00100010
    add                  wq, t0
    movd                 m4, mxyd
    pshufd               m4, m4, q0000
    movifnidn           dsq, dsmp
    jmp                  wq
.v_w2:
    movd                 m0, [srcq+ssq*0]
.v_w2_loop:
    pinsrw               m0, [srcq+ssq*1], 1 ; 0 1
    lea                srcq, [srcq+ssq*2]
    pshuflw              m1, m0, q2301
    pinsrw               m0, [srcq+ssq*0], 0 ; 2 1
    punpcklbw            m1, m0
    pmaddubsw            m1, m4
    pmulhrsw             m1, m5
    packuswb             m1, m1
    movd                r6d, m1
    mov        [dstq+dsq*1], r6w
    shr                 r6d, 16
    mov        [dstq+dsq*0], r6w
    lea                dstq, [dstq+dsq*2]
    sub                  hd, 2
    jg .v_w2_loop
    RET
.v_w4:
    movd                 m0, [srcq+ssq*0]
.v_w4_loop:
    movd                 m2, [srcq+ssq*1]
    lea                srcq, [srcq+ssq*2]
    mova                 m1, m0
    movd                 m0, [srcq+ssq*0]
    punpckldq            m1, m2 ; 0 1
    punpckldq            m2, m0 ; 1 2
    punpcklbw            m1, m2
    pmaddubsw            m1, m4
    pmulhrsw             m1, m5
    packuswb             m1, m1
    movd       [dstq+dsq*0], m1
    psrlq                m1, 32
    movd       [dstq+dsq*1], m1
    ;
    lea                dstq, [dstq+dsq*2]
    sub                  hd, 2
    jg .v_w4_loop
    RET
.v_w8:
    movq                 m0, [srcq+ssq*0]
.v_w8_loop:
    movq                 m2, [srcq+ssq*1]
    lea                srcq, [srcq+ssq*2]
    mova                 m1, m0
    movq                 m0, [srcq+ssq*0]
    punpcklbw            m1, m2
    punpcklbw            m2, m0
    pmaddubsw            m1, m4
    pmaddubsw            m2, m4
    pmulhrsw             m1, m5
    pmulhrsw             m2, m5
    packuswb             m1, m2
    movq       [dstq+dsq*0], m1
    movhps     [dstq+dsq*1], m1
    lea                dstq, [dstq+dsq*2]
    sub                  hd, 2
    jg .v_w8_loop
    RET
%macro PUT_BILIN_V_W16 0
    movu                 m0, [srcq+ssq*0]
%%loop:
    movu                 m3, [srcq+ssq*1]
    lea                srcq, [srcq+ssq*2]
    mova                 m1, m0
    mova                 m2, m0
    movu                 m0, [srcq+ssq*0]
    punpcklbw            m1, m3
    punpckhbw            m2, m3
    pmaddubsw            m1, m4
    pmaddubsw            m2, m4
    pmulhrsw             m1, m5
    pmulhrsw             m2, m5
    packuswb             m1, m2
    punpcklbw            m2, m3, m0
    punpckhbw            m3, m0
    pmaddubsw            m2, m4
    pmaddubsw            m3, m4
    pmulhrsw             m2, m5
    pmulhrsw             m3, m5
    packuswb             m2, m3
    mova       [dstq+dsq*0], m1
    mova       [dstq+dsq*1], m2
    lea                dstq, [dstq+dsq*2]
    sub                  hd, 2
    jg %%loop
%endmacro
.v_w16:
    PUT_BILIN_V_W16
    RET
.v_w128:
    lea                 r6d, [hq+(7<<16)]
    jmp .v_w16gt
.v_w64:
    lea                 r6d, [hq+(3<<16)]
    jmp .v_w16gt
.v_w32:
    lea                 r6d, [hq+(1<<16)]
.v_w16gt:
    mov                  r4, srcq
%if ARCH_X86_64
    mov                  r7, dstq
%endif
.v_w16gt_loop:
    PUT_BILIN_V_W16
%if ARCH_X86_64
    add                  r4, 16
    add                  r7, 16
    movzx                hd, r6b
    mov                srcq, r4
    mov                dstq, r7
%else
    mov                dstq, dstmp
    add                  r4, 16
    movzx                hd, r6w
    add                dstq, 16
    mov                srcq, r4
    mov               dstmp, dstq
%endif
    sub                 r6d, 1<<16
    jg .v_w16gt
    RET
.hv:
    ; (16 * src[x] + (my * (src[x + src_stride] - src[x])) + 128) >> 8
    ; = (src[x] + ((my * (src[x + src_stride] - src[x])) >> 4) + 8) >> 4
    movzx                wd, word [t0+wq*2+table_offset(put, _bilin_hv)]
    WIN64_SPILL_XMM       8
    shl                mxyd, 11 ; can't shift by 12 due to signed overflow
    mova                 m7, [base+pw_15]
    movd                 m6, mxyd
    add                  wq, t0
    pshuflw              m6, m6, q0000
    paddb                m5, m5
    punpcklqdq           m6, m6
    jmp                  wq
.hv_w2:
    RESTORE_DSQ_32       t0
    movd                 m0, [srcq+ssq*0]
    punpckldq            m0, m0
    pshufb               m0, m4
    pmaddubsw            m0, m5
.hv_w2_loop:
    movd                 m1, [srcq+ssq*1]
    lea                srcq, [srcq+ssq*2]
    movd                 m2, [srcq+ssq*0]
    punpckldq            m1, m2
    pshufb               m1, m4
    pmaddubsw            m1, m5             ; 1 _ 2 _
    shufps               m2, m0, m1, q1032  ; 0 _ 1 _
    mova                 m0, m1
    psubw                m1, m2   ; 2 * (src[x + src_stride] - src[x])
    pmulhw               m1, m6   ; (my * (src[x + src_stride] - src[x]) >> 4
    pavgw                m2, m7   ; src[x] + 8
    paddw                m1, m2   ; src[x] + ((my * (src[x + src_stride] - src[x])) >> 4) + 8
    psrlw                m1, 4
    packuswb             m1, m1
%if ARCH_X86_64
    movq                 r6, m1
%else
    pshuflw              m1, m1, q2020
    movd                r6d, m1
%endif
    mov        [dstq+dsq*0], r6w
    shr                  r6, gprsize*4
    mov        [dstq+dsq*1], r6w
    lea                dstq, [dstq+dsq*2]
    sub                  hd, 2
    jg .hv_w2_loop
    RET
.hv_w4:
    mova                 m4, [base+bilin_h_shuf4]
    movddup              m0, [srcq+ssq*0]
    movifnidn           dsq, dsmp
    pshufb               m0, m4
    pmaddubsw            m0, m5
.hv_w4_loop:
    movq                 m1, [srcq+ssq*1]
    lea                srcq, [srcq+ssq*2]
    movhps               m1, [srcq+ssq*0]
    pshufb               m1, m4
    pmaddubsw            m1, m5            ; 1 2
    shufps               m2, m0, m1, q1032 ; 0 1
    mova                 m0, m1
    psubw                m1, m2
    pmulhw               m1, m6
    pavgw                m2, m7
    paddw                m1, m2
    psrlw                m1, 4
    packuswb             m1, m1
    movd       [dstq+dsq*0], m1
    psrlq                m1, 32
    movd       [dstq+dsq*1], m1
    lea                dstq, [dstq+dsq*2]
    sub                  hd, 2
    jg .hv_w4_loop
    RET
.hv_w8:
    movu                 m0, [srcq+ssq*0]
    movifnidn           dsq, dsmp
    pshufb               m0, m4
    pmaddubsw            m0, m5
.hv_w8_loop:
    movu                 m2, [srcq+ssq*1]
    lea                srcq, [srcq+ssq*2]
    pshufb               m2, m4
    pmaddubsw            m2, m5
    psubw                m1, m2, m0
    pmulhw               m1, m6
    pavgw                m0, m7
    paddw                m1, m0
    movu                 m0, [srcq+ssq*0]
    pshufb               m0, m4
    pmaddubsw            m0, m5
    psubw                m3, m0, m2
    pmulhw               m3, m6
    pavgw                m2, m7
    paddw                m3, m2
    psrlw                m1, 4
    psrlw                m3, 4
    packuswb             m1, m3
    movq       [dstq+dsq*0], m1
    movhps     [dstq+dsq*1], m1
    lea                dstq, [dstq+dsq*2]
    sub                  hd, 2
    jg .hv_w8_loop
    RET
.hv_w128:
    lea                 r6d, [hq+(7<<16)]
    jmp .hv_w16_start
.hv_w64:
    lea                 r6d, [hq+(3<<16)]
    jmp .hv_w16_start
.hv_w32:
    lea                 r6d, [hq+(1<<16)]
.hv_w16_start:
    mov                  r4, srcq
%if ARCH_X86_32
    %define m8 [dstq]
%else
    mov                  r7, dstq
%endif
.hv_w16:
    movifnidn           dsq, dsmp
%if WIN64
    movaps              r4m, m8
%endif
.hv_w16_loop0:
    movu                 m0, [srcq+8*0]
    movu                 m1, [srcq+8*1]
    pshufb               m0, m4
    pshufb               m1, m4
    pmaddubsw            m0, m5
    pmaddubsw            m1, m5
.hv_w16_loop:
    add                srcq, ssq
    movu                 m2, [srcq+8*0]
    movu                 m3, [srcq+8*1]
    pshufb               m2, m4
    pshufb               m3, m4
    pmaddubsw            m2, m5
    pmaddubsw            m3, m5
    mova                 m8, m2
    psubw                m2, m0
    pmulhw               m2, m6
    pavgw                m0, m7
    paddw                m2, m0
    mova                 m0, m3
    psubw                m3, m1
    pmulhw               m3, m6
    pavgw                m1, m7
    paddw                m3, m1
    mova                 m1, m0
    mova                 m0, m8
    psrlw                m2, 4
    psrlw                m3, 4
    packuswb             m2, m3
    mova             [dstq], m2
    add                dstq, dsmp
    dec                  hd
    jg .hv_w16_loop
%if ARCH_X86_32
    mov                dstq, dstm
    add                  r4, 16
    movzx                hd, r6w
    add                dstq, 16
    mov                srcq, r4
    mov                dstm, dstq
%else
    add                  r4, 16
    add                  r7, 16
    movzx                hd, r6b
    mov                srcq, r4
    mov                dstq, r7
%endif
    sub                 r6d, 1<<16
    jg .hv_w16_loop0
%if WIN64
    movaps               m8, r4m
%endif
    RET

%if ARCH_X86_32
    %define base r6-prep%+SUFFIX
%else
    %define base 0
%endif

cglobal prep_bilin_8bpc, 3, 7, 0, tmp, src, stride, w, h, mxy, stride3
    movifnidn          mxyd, r5m ; mx
    LEA                  r6, prep_ssse3
    tzcnt                wd, wm
    movifnidn            hd, hm
    test               mxyd, mxyd
    jnz .h
    mov                mxyd, r6m ; my
    test               mxyd, mxyd
    jnz .v
.prep:
    movzx                wd, word [r6+wq*2+table_offset(prep,)]
    pxor                 m4, m4
    add                  wq, r6
    lea            stride3q, [strideq*3]
    jmp                  wq
.prep_w4:
    movd                 m0, [srcq+strideq*0]
    movd                 m1, [srcq+strideq*1]
    movd                 m2, [srcq+strideq*2]
    movd                 m3, [srcq+stride3q ]
    lea                srcq, [srcq+strideq*4]
    punpckldq            m0, m1
    punpckldq            m2, m3
    punpcklbw            m0, m4
    punpcklbw            m2, m4
    psllw                m0, 4
    psllw                m2, 4
    mova        [tmpq+16*0], m0
    mova        [tmpq+16*1], m2
    add                tmpq, 16*2
    sub                  hd, 4
    jg .prep_w4
    RET
.prep_w8:
    movq                 m0, [srcq+strideq*0]
    movq                 m1, [srcq+strideq*1]
    movq                 m2, [srcq+strideq*2]
    movq                 m3, [srcq+stride3q ]
    lea                srcq, [srcq+strideq*4]
    punpcklbw            m0, m4
    punpcklbw            m1, m4
    punpcklbw            m2, m4
    punpcklbw            m3, m4
    psllw                m0, 4
    psllw                m1, 4
    psllw                m2, 4
    psllw                m3, 4
    mova        [tmpq+16*0], m0
    mova        [tmpq+16*1], m1
    mova        [tmpq+16*2], m2
    mova        [tmpq+16*3], m3
    add                tmpq, 16*4
    sub                  hd, 4
    jg .prep_w8
    RET
.prep_w16:
    movu                 m1, [srcq+strideq*0]
    movu                 m3, [srcq+strideq*1]
    lea                srcq, [srcq+strideq*2]
    punpcklbw            m0, m1, m4
    punpckhbw            m1, m4
    punpcklbw            m2, m3, m4
    punpckhbw            m3, m4
    psllw                m0, 4
    psllw                m1, 4
    psllw                m2, 4
    psllw                m3, 4
    mova        [tmpq+16*0], m0
    mova        [tmpq+16*1], m1
    mova        [tmpq+16*2], m2
    mova        [tmpq+16*3], m3
    add                tmpq, 16*4
    sub                  hd, 2
    jg .prep_w16
    RET
.prep_w128:
    mov                  r3, -128
    jmp .prep_w32_start
.prep_w64:
    mov                  r3, -64
    jmp .prep_w32_start
.prep_w32:
    mov                  r3, -32
.prep_w32_start:
    sub                srcq, r3
.prep_w32_vloop:
    mov                  r6, r3
.prep_w32_hloop:
    movu                 m1, [srcq+r6+16*0]
    movu                 m3, [srcq+r6+16*1]
    punpcklbw            m0, m1, m4
    punpckhbw            m1, m4
    punpcklbw            m2, m3, m4
    punpckhbw            m3, m4
    psllw                m0, 4
    psllw                m1, 4
    psllw                m2, 4
    psllw                m3, 4
    mova        [tmpq+16*0], m0
    mova        [tmpq+16*1], m1
    mova        [tmpq+16*2], m2
    mova        [tmpq+16*3], m3
    add                tmpq, 16*4
    add                  r6, 32
    jl .prep_w32_hloop
    add                srcq, strideq
    dec                  hd
    jg .prep_w32_vloop
    RET
.h:
    ; 16 * src[x] + (mx * (src[x + 1] - src[x]))
    ; = (16 - mx) * src[x] + mx * src[x + 1]
    imul               mxyd, 0x00ff00ff
    mova                 m4, [base+subpel_h_shufD]
    add                mxyd, 0x00100010
    movd                 m5, mxyd
    mov                mxyd, r6m ; my
    pshufd               m5, m5, q0000
    test               mxyd, mxyd
    jnz .hv
    movzx                wd, word [r6+wq*2+table_offset(prep, _bilin_h)]
    add                  wq, r6
    jmp                  wq
.h_w4:
    mova                 m4, [base+bilin_h_shuf4]
    lea            stride3q, [strideq*3]
.h_w4_loop:
    movq                 m0, [srcq+strideq*0]
    movhps               m0, [srcq+strideq*1]
    movq                 m1, [srcq+strideq*2]
    movhps               m1, [srcq+stride3q ]
    lea                srcq, [srcq+strideq*4]
    pshufb               m0, m4
    pshufb               m1, m4
    pmaddubsw            m0, m5
    pmaddubsw            m1, m5
    mova          [tmpq+0 ], m0
    mova          [tmpq+16], m1
    add                tmpq, 32
    sub                  hd, 4
    jg .h_w4_loop
    RET
.h_w8:
    lea            stride3q, [strideq*3]
.h_w8_loop:
    movu                 m0, [srcq+strideq*0]
    movu                 m1, [srcq+strideq*1]
    movu                 m2, [srcq+strideq*2]
    movu                 m3, [srcq+stride3q ]
    lea                srcq, [srcq+strideq*4]
    REPX  {pshufb    x, m4}, m0, m1, m2, m3
    REPX  {pmaddubsw x, m5}, m0, m1, m2, m3
    mova        [tmpq+16*0], m0
    mova        [tmpq+16*1], m1
    mova        [tmpq+16*2], m2
    mova        [tmpq+16*3], m3
    add                tmpq, 16*4
    sub                  hd, 4
    jg .h_w8_loop
    RET
.h_w16:
    movu                 m0, [srcq+strideq*0+8*0]
    movu                 m1, [srcq+strideq*0+8*1]
    movu                 m2, [srcq+strideq*1+8*0]
    movu                 m3, [srcq+strideq*1+8*1]
    lea                srcq, [srcq+strideq*2]
    REPX  {pshufb    x, m4}, m0, m1, m2, m3
    REPX  {pmaddubsw x, m5}, m0, m1, m2, m3
    mova        [tmpq+16*0], m0
    mova        [tmpq+16*1], m1
    mova        [tmpq+16*2], m2
    mova        [tmpq+16*3], m3
    add                tmpq, 16*4
    sub                  hd, 2
    jg .h_w16
    RET
.h_w128:
    mov                  r3, -128
    jmp .h_w32_start
.h_w64:
    mov                  r3, -64
    jmp .h_w32_start
.h_w32:
    mov                  r3, -32
.h_w32_start:
    sub                srcq, r3
.h_w32_vloop:
    mov                  r6, r3
.h_w32_hloop:
    movu                 m0, [srcq+r6+8*0]
    movu                 m1, [srcq+r6+8*1]
    movu                 m2, [srcq+r6+8*2]
    movu                 m3, [srcq+r6+8*3]
    REPX  {pshufb    x, m4}, m0, m1, m2, m3
    REPX  {pmaddubsw x, m5}, m0, m1, m2, m3
    mova        [tmpq+16*0], m0
    mova        [tmpq+16*1], m1
    mova        [tmpq+16*2], m2
    mova        [tmpq+16*3], m3
    add                tmpq, 16*4
    add                  r6, 32
    jl .h_w32_hloop
    add                srcq, strideq
    dec                  hd
    jg .h_w32_vloop
    RET
.v:
    movzx                wd, word [r6+wq*2+table_offset(prep, _bilin_v)]
    imul               mxyd, 0x00ff00ff
    add                mxyd, 0x00100010
    add                  wq, r6
    lea            stride3q, [strideq*3]
    movd                 m5, mxyd
    pshufd               m5, m5, q0000
    jmp                  wq
.v_w4:
    movd                 m0, [srcq+strideq*0]
.v_w4_loop:
    movd                 m1, [srcq+strideq*1]
    movd                 m2, [srcq+strideq*2]
    movd                 m3, [srcq+stride3q ]
    lea                srcq, [srcq+strideq*4]
    punpckldq            m0, m1
    punpckldq            m1, m2
    punpcklbw            m0, m1 ; 01 12
    pmaddubsw            m0, m5
    mova        [tmpq+16*0], m0
    movd                 m0, [srcq+strideq*0]
    punpckldq            m2, m3
    punpckldq            m3, m0
    punpcklbw            m2, m3 ; 23 34
    pmaddubsw            m2, m5
    mova        [tmpq+16*1], m2
    add                tmpq, 16*2
    sub                  hd, 4
    jg .v_w4_loop
    RET
.v_w8:
    movq                 m0, [srcq+strideq*0]
.v_w8_loop:
    movq                 m1, [srcq+strideq*1]
    movq                 m2, [srcq+strideq*2]
    movq                 m3, [srcq+stride3q ]
    lea                srcq, [srcq+strideq*4]
    punpcklbw            m0, m1 ; 01
    punpcklbw            m1, m2 ; 12
    pmaddubsw            m0, m5
    pmaddubsw            m1, m5
    mova        [tmpq+16*0], m0
    movq                 m0, [srcq+strideq*0]
    punpcklbw            m2, m3 ; 23
    punpcklbw            m3, m0 ; 34
    pmaddubsw            m2, m5
    mova        [tmpq+16*1], m1
    pmaddubsw            m3, m5
    mova        [tmpq+16*2], m2
    mova        [tmpq+16*3], m3
    add                tmpq, 16*4
    sub                  hd, 4
    jg .v_w8_loop
    RET
.v_w16:
    movu                 m0, [srcq+strideq*0]
.v_w16_loop:
    movu                 m1, [srcq+strideq*1]
    movu                 m2, [srcq+strideq*2]
    movu                 m3, [srcq+stride3q ]
    lea                srcq, [srcq+strideq*4]
    punpcklbw            m4, m0, m1
    punpckhbw            m0, m1
    pmaddubsw            m4, m5
    pmaddubsw            m0, m5
    mova        [tmpq+16*0], m4
    punpcklbw            m4, m1, m2
    punpckhbw            m1, m2
    pmaddubsw            m4, m5
    mova        [tmpq+16*1], m0
    movu                 m0, [srcq+strideq*0]
    pmaddubsw            m1, m5
    mova        [tmpq+16*2], m4
    punpcklbw            m4, m2, m3
    punpckhbw            m2, m3
    pmaddubsw            m4, m5
    mova        [tmpq+16*3], m1
    pmaddubsw            m2, m5
    mova        [tmpq+16*4], m4
    punpcklbw            m4, m3, m0
    punpckhbw            m3, m0
    pmaddubsw            m4, m5
    mova        [tmpq+16*5], m2
    pmaddubsw            m3, m5
    mova        [tmpq+16*6], m4
    mova        [tmpq+16*7], m3
    add                tmpq, 16*8
    sub                  hd, 4
    jg .v_w16_loop
    RET
.v_w128:
    lea                 r3d, [hq+(3<<8)]
    mov                 r6d, 256
    jmp .v_w32_start
.v_w64:
    lea                 r3d, [hq+(1<<8)]
    mov                 r6d, 128
    jmp .v_w32_start
.v_w32:
    xor                 r3d, r3d
    mov                 r6d, 64
.v_w32_start:
%if ARCH_X86_64
 %if WIN64
    PUSH                 r7
 %endif
    mov                  r7, tmpq
%endif
    mov                  r5, srcq
.v_w32_hloop:
    movu                 m0, [srcq+strideq*0+16*0]
    movu                 m1, [srcq+strideq*0+16*1]
.v_w32_vloop:
    movu                 m2, [srcq+strideq*1+16*0]
    movu                 m3, [srcq+strideq*1+16*1]
    lea                srcq, [srcq+strideq*2]
    punpcklbw            m4, m0, m2
    punpckhbw            m0, m2
    pmaddubsw            m4, m5
    pmaddubsw            m0, m5
    mova        [tmpq+16*0], m4
    mova        [tmpq+16*1], m0
    movu                 m0, [srcq+strideq*0+16*0]
    punpcklbw            m4, m1, m3
    punpckhbw            m1, m3
    pmaddubsw            m4, m5
    pmaddubsw            m1, m5
    mova        [tmpq+16*2], m4
    mova        [tmpq+16*3], m1
    movu                 m1, [srcq+strideq*0+16*1]
    add                tmpq, r6
    punpcklbw            m4, m2, m0
    punpckhbw            m2, m0
    pmaddubsw            m4, m5
    pmaddubsw            m2, m5
    mova        [tmpq+16*0], m4
    mova        [tmpq+16*1], m2
    punpcklbw            m4, m3, m1
    punpckhbw            m3, m1
    pmaddubsw            m4, m5
    pmaddubsw            m3, m5
    mova        [tmpq+16*2], m4
    mova        [tmpq+16*3], m3
    add                tmpq, r6
    sub                  hd, 2
    jg .v_w32_vloop
    add                  r5, 32
    movzx                hd, r3b
    mov                srcq, r5
%if ARCH_X86_64
    add                  r7, 16*4
    mov                tmpq, r7
%else
    mov                tmpq, tmpmp
    add                tmpq, 16*4
    mov               tmpmp, tmpq
%endif
    sub                 r3d, 1<<8
    jg .v_w32_hloop
%if WIN64
    POP                  r7
%endif
    RET
.hv:
    ; (16 * src[x] + (my * (src[x + src_stride] - src[x])) + 8) >> 4
    ; = src[x] + (((my * (src[x + src_stride] - src[x])) + 8) >> 4)
    movzx                wd, word [r6+wq*2+table_offset(prep, _bilin_hv)]
    imul               mxyd, 0x08000800
    WIN64_SPILL_XMM 8
    movd                 m6, mxyd
    add                  wq, r6
    pshufd               m6, m6, q0000
    jmp                  wq
.hv_w4:
    mova                 m4, [base+bilin_h_shuf4]
    movddup              m0, [srcq+strideq*0]
    lea                  r3, [strideq*3]
    pshufb               m0, m4
    pmaddubsw            m0, m5            ; _ 0
.hv_w4_loop:
    movq                 m1, [srcq+strideq*1]
    movhps               m1, [srcq+strideq*2]
    movq                 m2, [srcq+r3       ]
    lea                srcq, [srcq+strideq*4]
    movhps               m2, [srcq+strideq*0]
    pshufb               m1, m4
    pshufb               m2, m4
    pmaddubsw            m1, m5            ; 1 2
    pmaddubsw            m2, m5            ; 3 4
    shufpd               m0, m1, 0x01      ; 0 1
    shufpd               m3, m1, m2, 0x01  ; 2 3
    psubw                m1, m0
    pmulhrsw             m1, m6
    paddw                m1, m0
    mova                 m0, m2
    psubw                m2, m3
    pmulhrsw             m2, m6
    paddw                m2, m3
    mova        [tmpq+16*0], m1
    mova        [tmpq+16*1], m2
    add                tmpq, 32
    sub                  hd, 4
    jg .hv_w4_loop
    RET
.hv_w8:
    movu                 m0, [srcq+strideq*0]
    pshufb               m0, m4
    pmaddubsw            m0, m5 ; 0
.hv_w8_loop:
    movu                 m1, [srcq+strideq*1]
    lea                srcq, [srcq+strideq*2]
    movu                 m2, [srcq+strideq*0]
    pshufb               m1, m4
    pshufb               m2, m4
    pmaddubsw            m1, m5 ; 1
    pmaddubsw            m2, m5 ; 2
    psubw                m3, m1, m0
    pmulhrsw             m3, m6
    paddw                m3, m0
    mova                 m0, m2
    psubw                m2, m1
    pmulhrsw             m2, m6
    paddw                m2, m1
    mova        [tmpq+16*0], m3
    mova        [tmpq+16*1], m2
    add                tmpq, 16*2
    sub                  hd, 2
    jg .hv_w8_loop
    RET
.hv_w128:
    lea                 r3d, [hq+(7<<8)]
    mov                 r5d, 256
    jmp .hv_w16_start
.hv_w64:
    lea                 r3d, [hq+(3<<8)]
    mov                 r5d, 128
    jmp .hv_w16_start
.hv_w32:
    lea                 r3d, [hq+(1<<8)]
    mov                 r5d, 64
    jmp .hv_w16_start
.hv_w16:
    xor                 r3d, r3d
    mov                 r5d, 32
.hv_w16_start:
    mov                  r6, srcq
%if ARCH_X86_64
 %if WIN64
    PUSH                 r7
 %endif
    mov                  r7, tmpq
%endif
.hv_w16_hloop:
    movu                 m0, [srcq+strideq*0+8*0]
    movu                 m1, [srcq+strideq*0+8*1]
    pshufb               m0, m4
    pshufb               m1, m4
    pmaddubsw            m0, m5 ; 0a
    pmaddubsw            m1, m5 ; 0b
.hv_w16_vloop:
    movu                 m2, [srcq+strideq*1+8*0]
    pshufb               m2, m4
    pmaddubsw            m2, m5 ; 1a
    psubw                m3, m2, m0
    pmulhrsw             m3, m6
    paddw                m3, m0
    mova        [tmpq+16*0], m3
    movu                 m3, [srcq+strideq*1+8*1]
    lea                srcq, [srcq+strideq*2]
    pshufb               m3, m4
    pmaddubsw            m3, m5 ; 1b
    psubw                m0, m3, m1
    pmulhrsw             m0, m6
    paddw                m0, m1
    mova        [tmpq+16*1], m0
    add                tmpq, r5
    movu                 m0, [srcq+strideq*0+8*0]
    pshufb               m0, m4
    pmaddubsw            m0, m5 ; 2a
    psubw                m1, m0, m2
    pmulhrsw             m1, m6
    paddw                m1, m2
    mova        [tmpq+16*0], m1
    movu                 m1, [srcq+strideq*0+8*1]
    pshufb               m1, m4
    pmaddubsw            m1, m5 ; 2b
    psubw                m2, m1, m3
    pmulhrsw             m2, m6
    paddw                m2, m3
    mova        [tmpq+16*1], m2
    add                tmpq, r5
    sub                  hd, 2
    jg .hv_w16_vloop
    movzx                hd, r3b
%if ARCH_X86_64
    add                  r6, 16
    add                  r7, 2*16
    mov                srcq, r6
    mov                tmpq, r7
%else
    mov                tmpq, tmpm
    add                  r6, 16
    add                tmpq, 2*16
    mov                srcq, r6
    mov                tmpm, tmpq
%endif
    sub                 r3d, 1<<8
    jg .hv_w16_hloop
%if WIN64
    POP                  r7
%endif
    RET

; int8_t subpel_filters[5][15][8]
%assign FILTER_REGULAR (0*15 << 16) | 3*15
%assign FILTER_SMOOTH  (1*15 << 16) | 4*15
%assign FILTER_SHARP   (2*15 << 16) | 3*15

%macro FN 4-5 ; prefix, type, type_h, type_v, jmp_to
cglobal %1_%2_8bpc
    mov                 t0d, FILTER_%3
%ifidn %3, %4
    mov                 t1d, t0d
%else
    mov                 t1d, FILTER_%4
%endif
%if %0 == 5 ; skip the jump in the last filter
    jmp mangle(private_prefix %+ _%5 %+ SUFFIX)
%endif
%endmacro

%if ARCH_X86_32
DECLARE_REG_TMP 1, 2
%elif WIN64
DECLARE_REG_TMP 4, 5
%else
DECLARE_REG_TMP 7, 8
%endif

%if ARCH_X86_32
 %define base_reg r1
 %define base base_reg-put_ssse3
%else
 %define base_reg r8
 %define base 0
%endif

%define PUT_8TAP_FN FN put_8tap,
PUT_8TAP_FN smooth,         SMOOTH,  SMOOTH,  put_6tap_8bpc
PUT_8TAP_FN smooth_regular, SMOOTH,  REGULAR, put_6tap_8bpc
PUT_8TAP_FN regular_smooth, REGULAR, SMOOTH,  put_6tap_8bpc
PUT_8TAP_FN regular,        REGULAR, REGULAR

cglobal put_6tap_8bpc, 1, 9, 0, dst, ds, src, ss, w, h, mx, my, ns
    imul                mxd, mxm, 0x010101
    add                 mxd, t0d ; 8tap_h, mx, 4tap_h
%if ARCH_X86_64
    imul                myd, mym, 0x010101
    add                 myd, t1d ; 8tap_v, my, 4tap_v
%else
    imul                ssd, mym, 0x010101
    add                 ssd, t1d ; 8tap_v, my, 4tap_v
    mov                srcq, srcm
%endif
    mov                  wd, wm
    movifnidn            hd, hm
    LEA            base_reg, put_ssse3
    test                mxd, 0xf00
    jnz .h
%if ARCH_X86_32
    test                ssd, 0xf00
%else
    test                myd, 0xf00
%endif
    jnz .v
.put:
    tzcnt                wd, wd
    movzx                wd, word [base_reg+wq*2+table_offset(put,)]
    movifnidn           ssq, ssmp
    add                  wq, base_reg
    movifnidn           dsq, dsmp
%if WIN64
    pop                  r8
%endif
    lea                  r6, [ssq*3]
    jmp                  wq
.h:
%if ARCH_X86_32
    test                ssd, 0xf00
%else
    test                myd, 0xf00
%endif
    jnz .hv
    movifnidn           ssq, ssmp
    mova                 m5, [base+pw_34] ; 2 + (8 << 2)
    cmp                  wd, 4
    jle mangle(private_prefix %+ _put_8tap_8bpc %+ SUFFIX).h_w4
    WIN64_SPILL_XMM      11
%if ARCH_X86_64
    mova                 m8, [base+subpel_h_shufD]
    mova                 m9, [base+subpel_h_shufE]
    mova                m10, [base+subpel_h_shufF]
%endif
    shr                 mxd, 16
    sub                srcq, 2
    movq                 m7, [base_reg-put_ssse3+subpel_filters+1+mxq*8]
    punpcklwd            m7, m7
    pshufd               m4, m7, q0000
    pshufd               m6, m7, q1111
    pshufd               m7, m7, q2222
    sub                  wd, 16
    jge .h_w16
%macro PUT_6TAP_H 3 ; dst/src, tmp[1-2]
%if ARCH_X86_32
    pshufb               %2, %1, [base+subpel_h_shufD]
    pshufb               %3, %1, [base+subpel_h_shufE]
    pshufb               %1, [base+subpel_h_shufF]
%else
    pshufb               %2, %1, m8
    pshufb               %3, %1, m9
    pshufb               %1, m10
%endif
    pmaddubsw            %2, m4
    pmaddubsw            %3, m6
    pmaddubsw            %1, m7
    paddw                %2, m5
    paddw                %2, %3
    paddw                %1, %2
    psraw                %1, 6
%endmacro
%if ARCH_X86_32
    mov                  r4, dsm
%endif
.h_w8:
    movu                 m0, [srcq+ssq*0]
    movu                 m1, [srcq+ssq*1]
    lea                srcq, [srcq+ssq*2]
    PUT_6TAP_H           m0, m2, m3
    PUT_6TAP_H           m1, m2, m3
    packuswb             m0, m1
%if ARCH_X86_32
    movq        [dstq+r4*0], m0
    movhps      [dstq+r4*1], m0
    lea                dstq, [dstq+r4*2]
%else
    movq       [dstq+dsq*0], m0
    movhps     [dstq+dsq*1], m0
    lea                dstq, [dstq+dsq*2]
%endif
    sub                  hd, 2
    jg .h_w8
    RET
.h_w16:
    add                srcq, wq
    add                dstq, wq
    neg                  wq
.h_w16_loop_v:
    mov                  r6, wq
.h_w16_loop_h:
    movu                 m0, [srcq+r6+8*0]
    movu                 m1, [srcq+r6+8*1]
    PUT_6TAP_H           m0, m2, m3
    PUT_6TAP_H           m1, m2, m3
    packuswb             m0, m1
    mova          [dstq+r6], m0
    add                  r6, 16
    jle .h_w16_loop_h
    add                srcq, ssq
    add                dstq, dsmp
    dec                  hd
    jg .h_w16_loop_v
    RET
.v:
%if ARCH_X86_32
    %define             dsq  r4
    %define              m8  [base+pw_512]
    movzx               mxd, ssb
    shr                 ssd, 16
    cmp                  hd, 6
    cmovs               ssd, mxd
    movq                 m7, [base_reg-put_ssse3+subpel_filters+1+ssq*8]
    mov                 ssq, ssm
    punpcklwd            m7, m7
    pshufd               m5, m7, q0000
    mov                  r6, ssq
    pshufd               m6, m7, q1111
    neg                  r6
    pshufd               m7, m7, q2222
    cmp                  wd, 4
    jge .v_w4
%else
    WIN64_SPILL_XMM       9, 12
    movzx               mxd, myb
    shr                 myd, 16
    cmp                  hd, 6
    cmovs               myd, mxd
    movq                 m7, [base_reg-put_ssse3+subpel_filters+1+myq*8]
    mova                 m8, [base+pw_512]
    punpcklwd            m7, m7
    pshufd               m5, m7, q0000
    mov                 nsq, ssq
    pshufd               m6, m7, q1111
    neg                 nsq
    pshufd               m7, m7, q2222
    cmp                  wd, 4
    je .v_w4
    jg .v_w8
%endif
.v_w2:
%if ARCH_X86_32
    mov                 dsq, dsm
    movd                 m1, [srcq+r6 *2]
    movd                 m3, [srcq+r6 *1]
%else
    movd                 m1, [srcq+nsq*2]
    movd                 m3, [srcq+nsq*1]
%endif
    movd                 m2, [srcq+ssq*0]
    movd                 m4, [srcq+ssq*1]
    lea                srcq, [srcq+ssq*2]
    movd                 m0, [srcq+ssq*0]
    punpcklwd            m1, m3     ; 0 1
    punpcklwd            m3, m2     ; 1 2
    punpcklwd            m2, m4     ; 2 3
    punpcklwd            m4, m0     ; 3 4
    punpcklbw            m1, m3     ; 01 12
    punpcklbw            m2, m4     ; 23 34
.v_w2_loop:
    movd                 m3, [srcq+ssq*1]
    lea                srcq, [srcq+ssq*2]
    pmaddubsw            m4, m1, m5 ; a0 b0
    mova                 m1, m2
    pmaddubsw            m2, m6     ; a1 b1
    paddw                m4, m2
    punpcklwd            m2, m0, m3 ; 4 5
    movd                 m0, [srcq+ssq*0]
    punpcklwd            m3, m0     ; 5 6
    punpcklbw            m2, m3     ; 67 78
    pmaddubsw            m3, m2, m7 ; a2 b2
    paddw                m4, m3
    pmulhrsw             m4, m8
    packuswb             m4, m4
    movd                r6d, m4
    mov        [dstq+dsq*0], r6w
    shr                 r6d, 16
    mov        [dstq+dsq*1], r6w
    lea                dstq, [dstq+dsq*2]
    sub                  hd, 2
    jg .v_w2_loop
    RET
.v_w4:
%if ARCH_X86_32
    shl                  wd, 14
    lea                srcq, [srcq+r6*2]
    lea                 r6d, [hq+wq-(1<<16)]
    mov                srcm, srcq
    mov                 dsq, dsm
.v_w4_loop0:
    movd                 m1, [srcq+ssq*0]
    movd                 m3, [srcq+ssq*1]
    lea                srcq, [srcq+ssq*2]
%else
    movd                 m1, [srcq+nsq*2]
    movd                 m3, [srcq+nsq*1]
%endif
    movd                 m2, [srcq+ssq*0]
    movd                 m4, [srcq+ssq*1]
    lea                srcq, [srcq+ssq*2]
    movd                 m0, [srcq+ssq*0]
    punpckldq            m1, m3     ; 0 1
    punpckldq            m3, m2     ; 1 2
    punpckldq            m2, m4     ; 2 3
    punpckldq            m4, m0     ; 3 4
    punpcklbw            m1, m3     ; 01 12
    punpcklbw            m2, m4     ; 23 34
.v_w4_loop:
    movd                 m3, [srcq+ssq*1]
    lea                srcq, [srcq+ssq*2]
    pmaddubsw            m4, m1, m5 ; a0 b0
    mova                 m1, m2
    pmaddubsw            m2, m6     ; a1 b1
    paddw                m4, m2
    punpckldq            m2, m0, m3 ; 4 5
    movd                 m0, [srcq+ssq*0]
    punpckldq            m3, m0     ; 5 6
    punpcklbw            m2, m3     ; 67 78
    pmaddubsw            m3, m2, m7 ; a2 b2
    paddw                m4, m3
    pmulhrsw             m4, m8
    packuswb             m4, m4
    movd       [dstq+dsq*0], m4
    psrlq                m4, 32
    movd       [dstq+dsq*1], m4
    lea                dstq, [dstq+dsq*2]
    sub                  hd, 2
    jg .v_w4_loop
%if ARCH_X86_32
    mov                srcq, srcm
    mov                dstq, dstm
    movzx                hd, r6w
    add                srcq, 4
    add                dstq, 4
    mov                srcm, srcq
    mov                dstm, dstq
    sub                 r6d, 1<<16
    jg .v_w4_loop0
%endif
    RET
%if ARCH_X86_64
.v_w8:
    WIN64_PUSH_XMM       12
    shl                  wd, 5
    lea                 r6d, [hq+wq-256]
.v_w8_loop0:
    movq                 m1, [srcq+nsq*2]
    movq                 m2, [srcq+nsq*1]
    lea                  r4, [srcq+ssq*2]
    movq                 m3, [srcq+ssq*0]
    movq                 m4, [srcq+ssq*1]
    mov                  r7, dstq
    movq                 m0, [r4  +ssq*0]
    punpcklbw            m1, m2     ; 01
    punpcklbw            m2, m3     ; 12
    punpcklbw            m3, m4     ; 23
    punpcklbw            m4, m0     ; 34
.v_w8_loop:
    pmaddubsw           m10, m1, m5 ; a0
    mova                 m1, m3
    pmaddubsw           m11, m2, m5 ; b0
    mova                 m2, m4
    pmaddubsw            m3, m6     ; a1
    pmaddubsw            m4, m6     ; b1
    paddw               m10, m3
    paddw               m11, m4
    movq                 m4, [r4+ssq*1]
    lea                  r4, [r4+ssq*2]
    punpcklbw            m3, m0, m4 ; 67
    movq                 m0, [r4+ssq*0]
    punpcklbw            m4, m0     ; 78
    pmaddubsw            m9, m3, m7 ; a2
    paddw               m10, m9
    pmaddubsw            m9, m4, m7 ; b2
    paddw               m11, m9
    pmulhrsw            m10, m8
    pmulhrsw            m11, m8
    packuswb            m10, m11
    movq         [r7+dsq*0], m10
    movhps       [r7+dsq*1], m10
    lea                  r7, [r7+dsq*2]
    sub                  hd, 2
    jg .v_w8_loop
    add                srcq, 8
    add                dstq, 8
    movzx                hd, r6b
    sub                 r6d, 1<<8
    jg .v_w8_loop0
    RET
%endif ;ARCH_X86_64
.hv:
    RESET_STACK_STATE
    cmp                  wd, 4
    jg .hv_w8
%if ARCH_X86_32
    and                 mxd, 0x7f
%else
    movzx               mxd, mxb
%endif
    dec                srcq
    movd                 m1, [base_reg-put_ssse3+subpel_filters+2+mxq*8]
%if ARCH_X86_32
    movzx               mxd, ssb
    shr                 ssd, 16
    cmp                  hd, 6
    cmovs               ssd, mxd
    movq                 m0, [base_reg-put_ssse3+subpel_filters+1+ssq*8]
    mov                 ssq, ssmp
    ALLOC_STACK   -mmsize*4
    %define              m8  [rsp+mmsize*0]
    %define              m9  [rsp+mmsize*1]
    %define             m10  [rsp+mmsize*2]
    punpcklbw            m0, m0
    sub                srcq, ssq
    psraw                m0, 8 ; sign-extend
    sub                srcq, ssq
    pshufd               m2, m0, q0000
    mova                 m8, m2
    pshufd               m2, m0, q1111
    mova                 m9, m2
    pshufd               m2, m0, q2222
    mova                m10, m2
%else
    movzx               mxd, myb
    shr                 myd, 16
    cmp                  hd, 6
    cmovs               myd, mxd
    movq                 m0, [base_reg-put_ssse3+subpel_filters+1+myq*8]
    WIN64_SPILL_XMM      11, 14
    mov                 nsq, ssq
    punpcklbw            m0, m0
    neg                 nsq
    psraw                m0, 8 ; sign-extend
    pshufd               m8, m0, q0000
    pshufd               m9, m0, q1111
    pshufd              m10, m0, q2222
%endif
    cmp                  wd, 4
    je .hv_w4
.hv_w2:
    mova                 m5, [base+subpel_h_shuf4]
    mova                 m6, [base+pw_34]
    pshufd               m7, m1, q0000
%if ARCH_X86_32
    movq                 m2, [srcq+ssq*0]
    movhps               m2, [srcq+ssq*1]
    lea                srcq, [srcq+ssq*2]
    mov                 dsq, [rstk+stack_offset+gprsize*2]
%else
    movq                 m2, [srcq+nsq*2]
    movhps               m2, [srcq+nsq*1] ; 0 1
%endif
    movq                 m1, [srcq+ssq*0]
    movhps               m1, [srcq+ssq*1] ; 2 3
    lea                srcq, [srcq+ssq*2]
    movq                 m0, [srcq+ssq*0] ; 4
    REPX  {pshufb    x, m5}, m2, m1, m0
    REPX  {pmaddubsw x, m7}, m2, m1, m0
    phaddw               m2, m1
    phaddw               m0, m0
    paddw                m2, m6
    paddw                m0, m6
    psraw                m2, 2            ; 0 1 2 3
    psraw                m0, 2
    palignr              m0, m2, 4        ; 1 2 3 4
    punpcklwd            m1, m2, m0       ; 01 12
    punpckhwd            m2, m0           ; 23 34
.hv_w2_loop:
    movq                 m3, [srcq+ssq*1]
    lea                srcq, [srcq+ssq*2]
    movhps               m3, [srcq+ssq*0] ; 5 6
    pshufb               m3, m5
    pmaddubsw            m3, m7
    pmaddwd              m4, m8, m1       ; a0 b0
    mova                 m1, m2
    pmaddwd              m2, m9           ; a1 b1
    phaddw               m3, m3
    paddw                m3, m6
    psraw                m3, 2
    paddd                m4, m2
    palignr              m2, m3, m0, 12   ; 4 5
    mova                 m0, m3
    punpcklwd            m2, m3           ; 45 56
    pmaddwd              m3, m10, m2      ; a2 b2
    paddd                m4, m3
    psrad                m4, 10
    packssdw             m4, m5
    packuswb             m4, m4
    movd                r6d, m4
    mov        [dstq+dsq*0], r6w
    shr                 r6d, 16
    mov        [dstq+dsq*1], r6w
    lea                dstq, [dstq+dsq*2]
    sub                  hd, 2
    jg .hv_w2_loop
    RET
.hv_w4:
%if ARCH_X86_32
    movq                 m3, [srcq+ssq*0]
    movq                 m4, [srcq+ssq*1]
    lea                srcq, [srcq+ssq*2]
    mov                 dsq, [rstk+stack_offset+gprsize*2]
    %define             m11  [base+pw_34]
    %define             m12  [base+subpel_h_shufA]
    %define             m13  [rsp+mmsize*3]
    pshufd               m1, m1, q0000
    mova                m13, m1
%else
    WIN64_PUSH_XMM       14
    movq                 m3, [srcq+nsq*2]
    movq                 m4, [srcq+nsq*1]
    pshufd              m13, m1, q0000
    mova                m12, [base+subpel_h_shufA]
    mova                m11, [base+pw_34]
%endif
    movq                 m0, [srcq+ssq*0]
    movq                 m1, [srcq+ssq*1]
    lea                srcq, [srcq+ssq*2]
    movq                 m2, [srcq+ssq*0]
%if ARCH_X86_32
    mova                 m5, m12
    mova                 m6, m13
    REPX {pshufb    x, m5 }, m3, m4, m0, m1, m2
    mova                 m5, m11
    REPX {pmaddubsw x, m6 }, m3, m4, m0, m1, m2
%else
    REPX {pshufb    x, m12}, m3, m4, m0, m1, m2
    REPX {pmaddubsw x, m13}, m3, m4, m0, m1, m2
%endif
    phaddw               m3, m0      ; 0 2
    phaddw               m4, m1      ; 1 3
    phaddw               m0, m2      ; 2 4
%if ARCH_X86_32
    REPX     {paddw x, m5 }, m3, m4, m0
%else
    REPX     {paddw x, m11}, m3, m4, m0
%endif
    REPX     {psraw x, 2  }, m3, m4, m0
    punpcklwd            m1, m3, m4  ; 01
    punpckhwd            m3, m4      ; 23
    punpcklwd            m2, m4, m0  ; 12
    punpckhwd            m4, m0      ; 34
.hv_w4_loop:
    movq                 m7, [srcq+ssq*1]
    lea                srcq, [srcq+ssq*2]
    movq                 m6, [srcq+ssq*0]
    pshufb               m7, m12
    pshufb               m6, m12
    pmaddubsw            m7, m13
    pmaddubsw            m6, m13
    pmaddwd              m5, m8, m1  ; a0
    mova                 m1, m3
    phaddw               m7, m6      ; 5 6
    pmaddwd              m6, m8, m2  ; b0
    mova                 m2, m4
    pmaddwd              m3, m9      ; a1
    pmaddwd              m4, m9      ; b1
    paddw                m7, m11
--> --------------------

--> maximum size reached

--> --------------------

Messung V0.5
C=92 H=79 G=85

¤ Dauer der Verarbeitung: 0.27 Sekunden  (vorverarbeitet)  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.