h264_chromamc_10bit: port x86 simd to cpuflags.
[ffmpeg.git] / libavcodec / x86 / rv34dsp.asm
1 ;******************************************************************************
2 ;* MMX/SSE2-optimized functions for the RV30 and RV40 decoders
3 ;* Copyright (C) 2012 Christophe Gisquet <christophe.gisquet@gmail.com>
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 "x86inc.asm"
23 %include "x86util.asm"
24
25 SECTION_RODATA
26 pw_row_coeffs:  times 4 dw 13
27                 times 4 dw 17
28                 times 4 dw  7
29 pd_512: times 2 dd 0x200
30 pw_col_coeffs:  dw 13,  13,  13, -13
31                 dw 17,   7,   7, -17
32                 dw 13, -13,  13,  13
33                 dw -7,  17, -17,  -7
34
35 SECTION .text
36
37 %macro IDCT_DC_NOROUND 1
38     imul   %1, 13*13*3
39     sar    %1, 11
40 %endmacro
41
42 %macro IDCT_DC_ROUND 1
43     imul   %1, 13*13
44     add    %1, 0x200
45     sar    %1, 10
46 %endmacro
47
48 %macro rv34_idct 1
49 cglobal rv34_idct_%1, 1, 2, 0
50     movsx   r1, word [r0]
51     IDCT_DC r1
52     movd    m0, r1
53     pshufw  m0, m0, 0
54     movq    [r0+ 0], m0
55     movq    [r0+ 8], m0
56     movq    [r0+16], m0
57     movq    [r0+24], m0
58     REP_RET
59 %endmacro
60
61 INIT_MMX mmx2
62 %define IDCT_DC IDCT_DC_ROUND
63 rv34_idct dc
64 %define IDCT_DC IDCT_DC_NOROUND
65 rv34_idct dc_noround
66
67 ; ff_rv34_idct_dc_add_mmx(uint8_t *dst, int stride, int dc);
68 INIT_MMX mmx
69 cglobal rv34_idct_dc_add, 3, 3
70     ; calculate DC
71     IDCT_DC_ROUND r2
72     pxor       m1, m1
73     movd       m0, r2
74     psubw      m1, m0
75     packuswb   m0, m0
76     packuswb   m1, m1
77     punpcklbw  m0, m0
78     punpcklbw  m1, m1
79     punpcklwd  m0, m0
80     punpcklwd  m1, m1
81
82     ; add DC
83     lea        r2, [r0+r1*2]
84     movh       m2, [r0]
85     movh       m3, [r0+r1]
86     movh       m4, [r2]
87     movh       m5, [r2+r1]
88     paddusb    m2, m0
89     paddusb    m3, m0
90     paddusb    m4, m0
91     paddusb    m5, m0
92     psubusb    m2, m1
93     psubusb    m3, m1
94     psubusb    m4, m1
95     psubusb    m5, m1
96     movh       [r0], m2
97     movh       [r0+r1], m3
98     movh       [r2], m4
99     movh       [r2+r1], m5
100     RET
101
102 ; Load coeffs and perform row transform
103 ; Output: coeffs in mm[0467], rounder in mm5
104 %macro ROW_TRANSFORM  1
105     pxor        mm7, mm7
106     mova        mm0, [%1+ 0*8]
107     mova        mm1, [%1+ 1*8]
108     mova        mm2, [%1+ 2*8]
109     mova        mm3, [%1+ 3*8]
110     mova  [%1+ 0*8], mm7
111     mova  [%1+ 1*8], mm7
112     mova  [%1+ 2*8], mm7
113     mova  [%1+ 3*8], mm7
114     mova        mm4, mm0
115     mova        mm6, [pw_row_coeffs+ 0]
116     paddsw      mm0, mm2                ; b0 + b2
117     psubsw      mm4, mm2                ; b0 - b2
118     pmullw      mm0, mm6                ; *13 = z0
119     pmullw      mm4, mm6                ; *13 = z1
120     mova        mm5, mm1
121     pmullw      mm1, [pw_row_coeffs+ 8] ; b1*17
122     pmullw      mm5, [pw_row_coeffs+16] ; b1* 7
123     mova        mm7, mm3
124     pmullw      mm3, [pw_row_coeffs+ 8] ; b3*17
125     pmullw      mm7, [pw_row_coeffs+16] ; b3* 7
126     paddsw      mm1, mm7                ; z3 = b1*17 + b3* 7
127     psubsw      mm5, mm3                ; z2 = b1* 7 - b3*17
128     mova        mm7, mm0
129     mova        mm6, mm4
130     paddsw      mm0, mm1                ; z0 + z3
131     psubsw      mm7, mm1                ; z0 - z3
132     paddsw      mm4, mm5                ; z1 + z2
133     psubsw      mm6, mm5                ; z1 - z2
134     mova        mm5, [pd_512]           ; 0x200
135 %endmacro
136
137 ; ff_rv34_idct_add_mmx2(uint8_t *dst, ptrdiff_t stride, DCTELEM *block);
138 %macro COL_TRANSFORM  4
139     pshufw      mm3, %2, 0xDD        ; col. 1,3,1,3
140     pshufw       %2, %2, 0x88        ; col. 0,2,0,2
141     pmaddwd      %2, %3              ; 13*c0+13*c2 | 13*c0-13*c2 = z0 | z1
142     pmaddwd     mm3, %4              ; 17*c1+ 7*c3 |  7*c1-17*c3 = z3 | z2
143     paddd        %2, mm5
144     pshufw      mm1,  %2, 01001110b  ;    z1 | z0
145     pshufw      mm2, mm3, 01001110b  ;    z2 | z3
146     paddd        %2, mm3             ; z0+z3 | z1+z2
147     psubd       mm1, mm2             ; z1-z2 | z0-z3
148     movd        mm3, %1
149     psrad        %2, 10
150     pxor        mm2, mm2
151     psrad       mm1, 10
152     punpcklbw   mm3, mm2
153     packssdw     %2, mm1
154     paddw        %2, mm3
155     packuswb     %2, %2
156     movd         %1, %2
157 %endmacro
158 INIT_MMX mmx2
159 cglobal rv34_idct_add, 3,3,0, d, s, b
160     ROW_TRANSFORM       bq
161     COL_TRANSFORM     [dq], mm0, [pw_col_coeffs+ 0], [pw_col_coeffs+ 8]
162     mova               mm0, [pw_col_coeffs+ 0]
163     COL_TRANSFORM  [dq+sq], mm4, mm0, [pw_col_coeffs+ 8]
164     mova               mm4, [pw_col_coeffs+ 8]
165     lea                 dq, [dq + 2*sq]
166     COL_TRANSFORM     [dq], mm6, mm0, mm4
167     COL_TRANSFORM  [dq+sq], mm7, mm0, mm4
168     ret
169
170 ; ff_rv34_idct_dc_add_sse4(uint8_t *dst, int stride, int dc);
171 INIT_XMM sse4
172 cglobal rv34_idct_dc_add, 3, 3, 6
173     ; load data
174     IDCT_DC_ROUND r2
175     pxor       m1, m1
176
177     ; calculate DC
178     movd       m0, r2
179     lea        r2, [r0+r1*2]
180     movd       m2, [r0]
181     movd       m3, [r0+r1]
182     pshuflw    m0, m0, 0
183     movd       m4, [r2]
184     movd       m5, [r2+r1]
185     punpcklqdq m0, m0
186     punpckldq  m2, m3
187     punpckldq  m4, m5
188     punpcklbw  m2, m1
189     punpcklbw  m4, m1
190     paddw      m2, m0
191     paddw      m4, m0
192     packuswb   m2, m4
193     movd      [r0], m2
194     pextrd [r0+r1], m2, 1
195     pextrd    [r2], m2, 2
196     pextrd [r2+r1], m2, 3
197     RET