x86: huffyuvdsp: fewer functions for x86_64
[ffmpeg.git] / libavcodec / x86 / huffyuvdsp.asm
1 ;******************************************************************************
2 ;* SIMD-optimized HuffYUV functions
3 ;* Copyright (c) 2008 Loren Merritt
4 ;* Copyright (c) 2014 Christophe Gisquet
5 ;*
6 ;* This file is part of FFmpeg.
7 ;*
8 ;* FFmpeg is free software; you can redistribute it and/or
9 ;* modify it under the terms of the GNU Lesser General Public
10 ;* License as published by the Free Software Foundation; either
11 ;* version 2.1 of the License, or (at your option) any later version.
12 ;*
13 ;* FFmpeg is distributed in the hope that it will be useful,
14 ;* but WITHOUT ANY WARRANTY; without even the implied warranty of
15 ;* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16 ;* Lesser General Public License for more details.
17 ;*
18 ;* You should have received a copy of the GNU Lesser General Public
19 ;* License along with FFmpeg; if not, write to the Free Software
20 ;* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 ;******************************************************************************
22
23 %include "libavutil/x86/x86util.asm"
24
25 SECTION_RODATA
26 pb_f: times 16 db 15
27 pb_zzzzzzzz77777777: times 8 db -1
28 pb_7: times 8 db 7
29 pb_zzzz3333zzzzbbbb: db -1,-1,-1,-1,3,3,3,3,-1,-1,-1,-1,11,11,11,11
30 pb_zz11zz55zz99zzdd: db -1,-1,1,1,-1,-1,5,5,-1,-1,9,9,-1,-1,13,13
31
32 SECTION_TEXT
33
34 ; void ff_add_hfyu_median_pred_mmxext(uint8_t *dst, const uint8_t *top,
35 ;                                     const uint8_t *diff, int w,
36 ;                                     int *left, int *left_top)
37 %macro LSHIFT 2
38 %if mmsize > 8
39     pslldq  %1, %2
40 %else
41     psllq   %1, 8*(%2)
42 %endif
43 %endmacro
44
45 %macro RSHIFT 2
46 %if mmsize > 8
47     psrldq  %1, %2
48 %else
49     psrlq   %1, 8*(%2)
50 %endif
51 %endmacro
52
53 %macro HFYU_MEDIAN 0
54 cglobal add_hfyu_median_pred, 6,6,8, dst, top, diff, w, left, left_top
55     movu    m0, [topq]
56     mova    m2, m0
57     movd    m4, [left_topq]
58     LSHIFT  m2, 1
59     mova    m1, m0
60     por     m4, m2
61     movd    m3, [leftq]
62     psubb   m0, m4 ; t-tl
63     add    dstq, wq
64     add    topq, wq
65     add   diffq, wq
66     neg      wq
67     jmp .skip
68 .loop:
69     movu    m4, [topq+wq]
70     mova    m0, m4
71     LSHIFT  m4, 1
72     por     m4, m1
73     mova    m1, m0 ; t
74     psubb   m0, m4 ; t-tl
75 .skip:
76     movu    m2, [diffq+wq]
77 %assign i 0
78 %rep mmsize
79     mova    m4, m0
80     paddb   m4, m3 ; t-tl+l
81     mova    m5, m3
82     pmaxub  m3, m1
83     pminub  m5, m1
84     pminub  m3, m4
85     pmaxub  m3, m5 ; median
86     paddb   m3, m2 ; +residual
87 %if i==0
88     mova    m7, m3
89     LSHIFT  m7, mmsize-1
90 %else
91     mova    m6, m3
92     RSHIFT  m7, 1
93     LSHIFT  m6, mmsize-1
94     por     m7, m6
95 %endif
96 %if i<mmsize-1
97     RSHIFT  m0, 1
98     RSHIFT  m1, 1
99     RSHIFT  m2, 1
100 %endif
101 %assign i i+1
102 %endrep
103     movu [dstq+wq], m7
104     add      wq, mmsize
105     jl .loop
106     movzx   r2d, byte [dstq-1]
107     mov [leftq], r2d
108     movzx   r2d, byte [topq-1]
109     mov [left_topq], r2d
110     RET
111 %endmacro
112
113 %if ARCH_X86_32
114 INIT_MMX mmxext
115 HFYU_MEDIAN
116 %endif
117 INIT_XMM sse2
118 HFYU_MEDIAN
119
120
121 %macro ADD_HFYU_LEFT_LOOP 2 ; %1 = dst_is_aligned, %2 = src_is_aligned
122     add     srcq, wq
123     add     dstq, wq
124     neg     wq
125 %%.loop:
126 %if %2
127     mova    m1, [srcq+wq]
128 %else
129     movu    m1, [srcq+wq]
130 %endif
131     mova    m2, m1
132     psllw   m1, 8
133     paddb   m1, m2
134     mova    m2, m1
135     pshufb  m1, m3
136     paddb   m1, m2
137     pshufb  m0, m5
138     mova    m2, m1
139     pshufb  m1, m4
140     paddb   m1, m2
141 %if mmsize == 16
142     mova    m2, m1
143     pshufb  m1, m6
144     paddb   m1, m2
145 %endif
146     paddb   m0, m1
147 %if %1
148     mova    [dstq+wq], m0
149 %else
150     movq    [dstq+wq], m0
151     movhps  [dstq+wq+8], m0
152 %endif
153     add     wq, mmsize
154     jl %%.loop
155     mov     eax, mmsize-1
156     sub     eax, wd
157     movd    m1, eax
158     pshufb  m0, m1
159     movd    eax, m0
160     RET
161 %endmacro
162
163 ; int ff_add_hfyu_left_pred(uint8_t *dst, const uint8_t *src, int w, int left)
164 INIT_MMX ssse3
165 cglobal add_hfyu_left_pred, 3,3,7, dst, src, w, left
166 .skip_prologue:
167     mova    m5, [pb_7]
168     mova    m4, [pb_zzzz3333zzzzbbbb]
169     mova    m3, [pb_zz11zz55zz99zzdd]
170     movd    m0, leftm
171     psllq   m0, 56
172     ADD_HFYU_LEFT_LOOP 1, 1
173
174 INIT_XMM sse4
175 cglobal add_hfyu_left_pred, 3,3,7, dst, src, w, left
176     mova    m5, [pb_f]
177     mova    m6, [pb_zzzzzzzz77777777]
178     mova    m4, [pb_zzzz3333zzzzbbbb]
179     mova    m3, [pb_zz11zz55zz99zzdd]
180     movd    m0, leftm
181     pslldq  m0, 15
182     test    srcq, 15
183     jnz .src_unaligned
184     test    dstq, 15
185     jnz .dst_unaligned
186     ADD_HFYU_LEFT_LOOP 1, 1
187 .dst_unaligned:
188     ADD_HFYU_LEFT_LOOP 0, 1
189 .src_unaligned:
190     ADD_HFYU_LEFT_LOOP 0, 0
191
192 %macro ADD_BYTES 0
193 cglobal add_bytes, 3,4,2, dst, src, w, size
194     mov  sizeq, wq
195     and  sizeq, -2*mmsize
196     jz  .2
197     add   dstq, sizeq
198     add   srcq, sizeq
199     neg  sizeq
200 .1:
201     mova    m0, [srcq + sizeq]
202     mova    m1, [srcq + sizeq + mmsize]
203     paddb   m0, [dstq + sizeq]
204     paddb   m1, [dstq + sizeq + mmsize]
205     mova   [dstq + sizeq], m0
206     mova   [dstq + sizeq + mmsize], m1
207     add  sizeq, 2*mmsize
208     jl .1
209 .2:
210     and     wq, 2*mmsize-1
211     jz    .end
212     add   dstq, wq
213     add   srcq, wq
214     neg     wq
215 .3
216     mov  sizeb, [srcq + wq]
217     add [dstq + wq], sizeb
218     inc     wq
219     jl .3
220 .end:
221     REP_RET
222 %endmacro
223
224 %if ARCH_X86_32
225 INIT_MMX mmx
226 ADD_BYTES
227 %endif
228 INIT_XMM sse2
229 ADD_BYTES
230
231 ; void add_hfyu_left_pred_bgr32(uint8_t *dst, const uint8_t *src,
232 ;                               intptr_t w, uint8_t *left)
233 %macro LEFT_BGR32 0
234 cglobal add_hfyu_left_pred_bgr32, 4,4,3, dst, src, w, left
235     shl           wq, 2
236     movd          m0, [leftq]
237     lea         dstq, [dstq + wq]
238     lea         srcq, [srcq + wq]
239     LSHIFT        m0, mmsize-4
240     neg           wq
241 .loop:
242     movu          m1, [srcq+wq]
243     mova          m2, m1
244 %if mmsize == 8
245     punpckhdq     m0, m0
246 %endif
247     LSHIFT        m1, 4
248     paddb         m1, m2
249 %if mmsize == 16
250     pshufd        m0, m0, q3333
251     mova          m2, m1
252     LSHIFT        m1, 8
253     paddb         m1, m2
254 %endif
255     paddb         m0, m1
256     movu   [dstq+wq], m0
257     add           wq, mmsize
258     jl         .loop
259     movd          m0, [dstq-4]
260     movd     [leftq], m0
261     REP_RET
262 %endmacro
263
264 %if ARCH_X86_32
265 INIT_MMX mmx
266 LEFT_BGR32
267 %endif
268 INIT_XMM sse2
269 LEFT_BGR32