6f038e17da612d406eeae59ad9fde3221cff0d27
[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 .text
26
27 %include "libavcodec/x86/huffyuvdsp_template.asm"
28
29 ;------------------------------------------------------------------------------
30 ; void (*add_int16)(uint16_t *dst, const uint16_t *src, unsigned mask, int w);
31 ;------------------------------------------------------------------------------
32
33 %macro ADD_INT16 0
34 cglobal add_int16, 4,4,5, dst, src, mask, w, tmp
35 %if mmsize > 8
36     test srcq, mmsize-1
37     jnz .unaligned
38     test dstq, mmsize-1
39     jnz .unaligned
40 %endif
41     INT16_LOOP a, add
42 %if mmsize > 8
43 .unaligned:
44     INT16_LOOP u, add
45 %endif
46 %endmacro
47
48 %if ARCH_X86_32
49 INIT_MMX mmx
50 ADD_INT16
51 %endif
52
53 INIT_XMM sse2
54 ADD_INT16
55
56 ; void add_hfyu_left_pred_bgr32(uint8_t *dst, const uint8_t *src,
57 ;                               intptr_t w, uint8_t *left)
58 %macro LEFT_BGR32 0
59 cglobal add_hfyu_left_pred_bgr32, 4,4,3, dst, src, w, left
60     shl           wq, 2
61     movd          m0, [leftq]
62     lea         dstq, [dstq + wq]
63     lea         srcq, [srcq + wq]
64     LSHIFT        m0, mmsize-4
65     neg           wq
66 .loop:
67     movu          m1, [srcq+wq]
68     mova          m2, m1
69 %if mmsize == 8
70     punpckhdq     m0, m0
71 %endif
72     LSHIFT        m1, 4
73     paddb         m1, m2
74 %if mmsize == 16
75     pshufd        m0, m0, q3333
76     mova          m2, m1
77     LSHIFT        m1, 8
78     paddb         m1, m2
79 %endif
80     paddb         m0, m1
81     movu   [dstq+wq], m0
82     add           wq, mmsize
83     jl         .loop
84     movd          m0, [dstq-4]
85     movd     [leftq], m0
86     REP_RET
87 %endmacro
88
89 %if ARCH_X86_32
90 INIT_MMX mmx
91 LEFT_BGR32
92 %endif
93 INIT_XMM sse2
94 LEFT_BGR32
95
96 ; void add_hfyu_median_prediction_mmxext(uint8_t *dst, const uint8_t *top, const uint8_t *diff, int mask, int w, int *left, int *left_top)
97 INIT_MMX mmxext
98 cglobal add_hfyu_median_pred_int16, 7,7,0, dst, top, diff, mask, w, left, left_top
99     add      wd, wd
100     movd    mm6, maskd
101     SPLATW  mm6, mm6
102     movq    mm0, [topq]
103     movq    mm2, mm0
104     movd    mm4, [left_topq]
105     psllq   mm2, 16
106     movq    mm1, mm0
107     por     mm4, mm2
108     movd    mm3, [leftq]
109     psubw   mm0, mm4 ; t-tl
110     add    dstq, wq
111     add    topq, wq
112     add   diffq, wq
113     neg      wq
114     jmp .skip
115 .loop:
116     movq    mm4, [topq+wq]
117     movq    mm0, mm4
118     psllq   mm4, 16
119     por     mm4, mm1
120     movq    mm1, mm0 ; t
121     psubw   mm0, mm4 ; t-tl
122 .skip:
123     movq    mm2, [diffq+wq]
124 %assign i 0
125 %rep 4
126     movq    mm4, mm0
127     paddw   mm4, mm3 ; t-tl+l
128     pand    mm4, mm6
129     movq    mm5, mm3
130     pmaxsw  mm3, mm1
131     pminsw  mm5, mm1
132     pminsw  mm3, mm4
133     pmaxsw  mm3, mm5 ; median
134     paddw   mm3, mm2 ; +residual
135     pand    mm3, mm6
136 %if i==0
137     movq    mm7, mm3
138     psllq   mm7, 48
139 %else
140     movq    mm4, mm3
141     psrlq   mm7, 16
142     psllq   mm4, 48
143     por     mm7, mm4
144 %endif
145 %if i<3
146     psrlq   mm0, 16
147     psrlq   mm1, 16
148     psrlq   mm2, 16
149 %endif
150 %assign i i+1
151 %endrep
152     movq [dstq+wq], mm7
153     add      wq, 8
154     jl .loop
155     movzx   r2d, word [dstq-2]
156     mov [leftq], r2d
157     movzx   r2d, word [topq-2]
158     mov [left_topq], r2d
159     RET