436abc8b75ab921ccf663f972d75618a412a7c91
[ffmpeg.git] / libavcodec / x86 / huffyuvdsp.asm
1 ;******************************************************************************
2 ;* SIMD-optimized HuffYUV functions
3 ;* Copyright (c) 2008 Loren Merritt
4 ;*
5 ;* This file is part of Libav.
6 ;*
7 ;* Libav is free software; you can redistribute it and/or
8 ;* modify it under the terms of the GNU Lesser General Public
9 ;* License as published by the Free Software Foundation; either
10 ;* version 2.1 of the License, or (at your option) any later version.
11 ;*
12 ;* Libav is distributed in the hope that it will be useful,
13 ;* but WITHOUT ANY WARRANTY; without even the implied warranty of
14 ;* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15 ;* Lesser General Public License for more details.
16 ;*
17 ;* You should have received a copy of the GNU Lesser General Public
18 ;* License along with Libav; if not, write to the Free Software
19 ;* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 ;******************************************************************************
21
22 %include "libavutil/x86/x86util.asm"
23
24 SECTION_RODATA
25 pb_f: times 16 db 15
26 pb_zzzzzzzz77777777: times 8 db -1
27 pb_7: times 8 db 7
28 pb_zzzz3333zzzzbbbb: db -1,-1,-1,-1,3,3,3,3,-1,-1,-1,-1,11,11,11,11
29 pb_zz11zz55zz99zzdd: db -1,-1,1,1,-1,-1,5,5,-1,-1,9,9,-1,-1,13,13
30
31 SECTION_TEXT
32
33 ; void ff_add_hfyu_median_pred_mmxext(uint8_t *dst, const uint8_t *top,
34 ;                                     const uint8_t *diff, int w,
35 ;                                     int *left, int *left_top)
36 INIT_MMX mmxext
37 cglobal add_hfyu_median_pred, 6,6,0, dst, top, diff, w, left, left_top
38     movq    mm0, [topq]
39     movq    mm2, mm0
40     movd    mm4, [left_topq]
41     psllq   mm2, 8
42     movq    mm1, mm0
43     por     mm4, mm2
44     movd    mm3, [leftq]
45     psubb   mm0, mm4 ; t-tl
46     add    dstq, wq
47     add    topq, wq
48     add   diffq, wq
49     neg      wq
50     jmp .skip
51 .loop:
52     movq    mm4, [topq+wq]
53     movq    mm0, mm4
54     psllq   mm4, 8
55     por     mm4, mm1
56     movq    mm1, mm0 ; t
57     psubb   mm0, mm4 ; t-tl
58 .skip:
59     movq    mm2, [diffq+wq]
60 %assign i 0
61 %rep 8
62     movq    mm4, mm0
63     paddb   mm4, mm3 ; t-tl+l
64     movq    mm5, mm3
65     pmaxub  mm3, mm1
66     pminub  mm5, mm1
67     pminub  mm3, mm4
68     pmaxub  mm3, mm5 ; median
69     paddb   mm3, mm2 ; +residual
70 %if i==0
71     movq    mm7, mm3
72     psllq   mm7, 56
73 %else
74     movq    mm6, mm3
75     psrlq   mm7, 8
76     psllq   mm6, 56
77     por     mm7, mm6
78 %endif
79 %if i<7
80     psrlq   mm0, 8
81     psrlq   mm1, 8
82     psrlq   mm2, 8
83 %endif
84 %assign i i+1
85 %endrep
86     movq [dstq+wq], mm7
87     add      wq, 8
88     jl .loop
89     movzx   r2d, byte [dstq-1]
90     mov [leftq], r2d
91     movzx   r2d, byte [topq-1]
92     mov [left_topq], r2d
93     RET
94
95
96 %macro ADD_HFYU_LEFT_LOOP 2 ; %1 = dst_is_aligned, %2 = src_is_aligned
97     add     srcq, wq
98     add     dstq, wq
99     neg     wq
100 %%.loop:
101 %if %2
102     mova    m1, [srcq+wq]
103 %else
104     movu    m1, [srcq+wq]
105 %endif
106     mova    m2, m1
107     psllw   m1, 8
108     paddb   m1, m2
109     mova    m2, m1
110     pshufb  m1, m3
111     paddb   m1, m2
112     pshufb  m0, m5
113     mova    m2, m1
114     pshufb  m1, m4
115     paddb   m1, m2
116 %if mmsize == 16
117     mova    m2, m1
118     pshufb  m1, m6
119     paddb   m1, m2
120 %endif
121     paddb   m0, m1
122 %if %1
123     mova    [dstq+wq], m0
124 %else
125     movq    [dstq+wq], m0
126     movhps  [dstq+wq+8], m0
127 %endif
128     add     wq, mmsize
129     jl %%.loop
130     mov     eax, mmsize-1
131     sub     eax, wd
132     movd    m1, eax
133     pshufb  m0, m1
134     movd    eax, m0
135     RET
136 %endmacro
137
138 ; int ff_add_hfyu_left_pred(uint8_t *dst, const uint8_t *src, int w, int left)
139 INIT_MMX ssse3
140 cglobal add_hfyu_left_pred, 3,3,7, dst, src, w, left
141 .skip_prologue:
142     mova    m5, [pb_7]
143     mova    m4, [pb_zzzz3333zzzzbbbb]
144     mova    m3, [pb_zz11zz55zz99zzdd]
145     movd    m0, leftm
146     psllq   m0, 56
147     ADD_HFYU_LEFT_LOOP 1, 1
148
149 INIT_XMM sse4
150 cglobal add_hfyu_left_pred, 3,3,7, dst, src, w, left
151     mova    m5, [pb_f]
152     mova    m6, [pb_zzzzzzzz77777777]
153     mova    m4, [pb_zzzz3333zzzzbbbb]
154     mova    m3, [pb_zz11zz55zz99zzdd]
155     movd    m0, leftm
156     pslldq  m0, 15
157     test    srcq, 15
158     jnz .src_unaligned
159     test    dstq, 15
160     jnz .dst_unaligned
161     ADD_HFYU_LEFT_LOOP 1, 1
162 .dst_unaligned:
163     ADD_HFYU_LEFT_LOOP 0, 1
164 .src_unaligned:
165     ADD_HFYU_LEFT_LOOP 0, 0