Optimized subXxX_dct
[x262.git] / common / ppc / dct.c
1 /*****************************************************************************
2  * dct.c: h264 encoder library
3  *****************************************************************************
4  * Copyright (C) 2003 Laurent Aimar
5  * $Id$
6  *
7  * Authors: Eric Petit <titer@m0k.org>
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
22  *****************************************************************************/
23
24 #ifdef SYS_LINUX
25 #include <altivec.h>
26 #endif
27
28 #include "common/common.h"
29 #include "ppccommon.h"
30
31 #define VEC_DCT(a0,a1,a2,a3,b0,b1,b2,b3) \
32     b1 = vec_add( a0, a3 );              \
33     b3 = vec_add( a1, a2 );              \
34     b0 = vec_add( b1, b3 );              \
35     b2 = vec_sub( b1, b3 );              \
36     a0 = vec_sub( a0, a3 );              \
37     a1 = vec_sub( a1, a2 );              \
38     b1 = vec_add( a0, a0 );              \
39     b1 = vec_add( b1, a1 );              \
40     b3 = vec_sub( a0, a1 );              \
41     b3 = vec_sub( b3, a1 )
42
43 void x264_sub4x4_dct_altivec( int16_t dct[4][4],
44         uint8_t *pix1, int i_pix1, uint8_t *pix2, int i_pix2 )
45 {
46     PREP_DIFF;
47     PREP_STORE8;
48     vec_s16_t dct0v, dct1v, dct2v, dct3v;
49     vec_s16_t tmp0v, tmp1v, tmp2v, tmp3v;
50
51     VEC_DIFF_H( pix1, i_pix1, pix2, i_pix2, 4, dct0v );
52     VEC_DIFF_H( pix1, i_pix1, pix2, i_pix2, 4, dct1v );
53     VEC_DIFF_H( pix1, i_pix1, pix2, i_pix2, 4, dct2v );
54     VEC_DIFF_H( pix1, i_pix1, pix2, i_pix2, 4, dct3v );
55     VEC_DCT( dct0v, dct1v, dct2v, dct3v, tmp0v, tmp1v, tmp2v, tmp3v );
56     VEC_TRANSPOSE_4( tmp0v, tmp1v, tmp2v, tmp3v,
57                      dct0v, dct1v, dct2v, dct3v );
58     VEC_DCT( dct0v, dct1v, dct2v, dct3v, tmp0v, tmp1v, tmp2v, tmp3v );
59     VEC_TRANSPOSE_4( tmp0v, tmp1v, tmp2v, tmp3v,
60                      dct0v, dct1v, dct2v, dct3v );
61     VEC_STORE8( dct0v, dct[0] );
62     VEC_STORE8( dct1v, dct[1] );
63     VEC_STORE8( dct2v, dct[2] );
64     VEC_STORE8( dct3v, dct[3] );
65 }
66
67 void x264_sub8x8_dct_altivec( int16_t dct[4][4][4],
68         uint8_t *pix1, int i_pix1, uint8_t *pix2, int i_pix2 )
69 {
70     PREP_DIFF;
71     PREP_STORE8_HL;
72     vec_s16_t dct0v, dct1v, dct2v, dct3v, dct4v, dct5v, dct6v, dct7v;
73     vec_s16_t tmp0v, tmp1v, tmp2v, tmp3v, tmp4v, tmp5v, tmp6v, tmp7v;
74
75     VEC_DIFF_H( pix1, i_pix1, pix2, i_pix2, 8, dct0v );
76     VEC_DIFF_H( pix1, i_pix1, pix2, i_pix2, 8, dct1v );
77     VEC_DIFF_H( pix1, i_pix1, pix2, i_pix2, 8, dct2v );
78     VEC_DIFF_H( pix1, i_pix1, pix2, i_pix2, 8, dct3v );
79     VEC_DIFF_H( pix1, i_pix1, pix2, i_pix2, 8, dct4v );
80     VEC_DIFF_H( pix1, i_pix1, pix2, i_pix2, 8, dct5v );
81     VEC_DIFF_H( pix1, i_pix1, pix2, i_pix2, 8, dct6v );
82     VEC_DIFF_H( pix1, i_pix1, pix2, i_pix2, 8, dct7v );
83     VEC_DCT( dct0v, dct1v, dct2v, dct3v, tmp0v, tmp1v, tmp2v, tmp3v );
84     VEC_DCT( dct4v, dct5v, dct6v, dct7v, tmp4v, tmp5v, tmp6v, tmp7v );
85     VEC_TRANSPOSE_8( tmp0v, tmp1v, tmp2v, tmp3v,
86                      tmp4v, tmp5v, tmp6v, tmp7v,
87                      dct0v, dct1v, dct2v, dct3v,
88                      dct4v, dct5v, dct6v, dct7v );
89     VEC_DCT( dct0v, dct1v, dct2v, dct3v, tmp0v, tmp1v, tmp2v, tmp3v );
90     VEC_DCT( dct4v, dct5v, dct6v, dct7v, tmp4v, tmp5v, tmp6v, tmp7v );
91     VEC_TRANSPOSE_8( tmp0v, tmp1v, tmp2v, tmp3v,
92                      tmp4v, tmp5v, tmp6v, tmp7v,
93                      dct0v, dct1v, dct2v, dct3v,
94                      dct4v, dct5v, dct6v, dct7v );
95     VEC_STORE8_H( dct0v, dct[0][0] );
96     VEC_STORE8_L( dct0v, dct[1][0] );
97     VEC_STORE8_H( dct1v, dct[0][1] );
98     VEC_STORE8_L( dct1v, dct[1][1] );
99     VEC_STORE8_H( dct2v, dct[0][2] );
100     VEC_STORE8_L( dct2v, dct[1][2] );
101     VEC_STORE8_H( dct3v, dct[0][3] );
102     VEC_STORE8_L( dct3v, dct[1][3] );
103     VEC_STORE8_H( dct4v, dct[2][0] );
104     VEC_STORE8_L( dct4v, dct[3][0] );
105     VEC_STORE8_H( dct5v, dct[2][1] );
106     VEC_STORE8_L( dct5v, dct[3][1] );
107     VEC_STORE8_H( dct6v, dct[2][2] );
108     VEC_STORE8_L( dct6v, dct[3][2] );
109     VEC_STORE8_H( dct7v, dct[2][3] );
110     VEC_STORE8_L( dct7v, dct[3][3] );
111 }
112     
113 void x264_sub16x16_dct_altivec( int16_t dct[16][4][4],
114         uint8_t *pix1, int i_pix1, uint8_t *pix2, int i_pix2 ) 
115 {
116     PREP_DIFF;
117     PREP_STORE8_HL;
118     vec_s16_t dcth0v, dcth1v, dcth2v, dcth3v,
119               dcth4v, dcth5v, dcth6v, dcth7v,
120               dctl0v, dctl1v, dctl2v, dctl3v,
121               dctl4v, dctl5v, dctl6v, dctl7v;
122     vec_s16_t temp0v, temp1v, temp2v, temp3v,
123               temp4v, temp5v, temp6v, temp7v;
124
125     VEC_DIFF_HL( pix1, i_pix1, pix2, i_pix2, dcth0v, dctl0v );
126     VEC_DIFF_HL( pix1, i_pix1, pix2, i_pix2, dcth1v, dctl1v );
127     VEC_DIFF_HL( pix1, i_pix1, pix2, i_pix2, dcth2v, dctl2v );
128     VEC_DIFF_HL( pix1, i_pix1, pix2, i_pix2, dcth3v, dctl3v );
129     VEC_DIFF_HL( pix1, i_pix1, pix2, i_pix2, dcth4v, dctl4v );
130     VEC_DIFF_HL( pix1, i_pix1, pix2, i_pix2, dcth5v, dctl5v );
131     VEC_DIFF_HL( pix1, i_pix1, pix2, i_pix2, dcth6v, dctl6v );
132     VEC_DIFF_HL( pix1, i_pix1, pix2, i_pix2, dcth7v, dctl7v );
133
134     VEC_DCT( dcth0v, dcth1v, dcth2v, dcth3v,
135              temp0v, temp1v, temp2v, temp3v );
136     VEC_DCT( dcth4v, dcth5v, dcth6v, dcth7v,
137              temp4v, temp5v, temp6v, temp7v );
138     VEC_TRANSPOSE_8( temp0v, temp1v, temp2v, temp3v,
139                      temp4v, temp5v, temp6v, temp7v,
140                      dcth0v, dcth1v, dcth2v, dcth3v,
141                      dcth4v, dcth5v, dcth6v, dcth7v );
142     VEC_DCT( dcth0v, dcth1v, dcth2v, dcth3v,
143              temp0v, temp1v, temp2v, temp3v );
144     VEC_DCT( dcth4v, dcth5v, dcth6v, dcth7v,
145              temp4v, temp5v, temp6v, temp7v );
146     VEC_TRANSPOSE_8( temp0v, temp1v, temp2v, temp3v,
147                      temp4v, temp5v, temp6v, temp7v,
148                      dcth0v, dcth1v, dcth2v, dcth3v,
149                      dcth4v, dcth5v, dcth6v, dcth7v );
150     VEC_STORE8_H( dcth0v, dct[0][0] );
151     VEC_STORE8_L( dcth0v, dct[1][0] );
152     VEC_STORE8_H( dcth1v, dct[0][1] );
153     VEC_STORE8_L( dcth1v, dct[1][1] );
154     VEC_STORE8_H( dcth2v, dct[0][2] );
155     VEC_STORE8_L( dcth2v, dct[1][2] );
156     VEC_STORE8_H( dcth3v, dct[0][3] );
157     VEC_STORE8_L( dcth3v, dct[1][3] );
158     VEC_STORE8_H( dcth4v, dct[2][0] );
159     VEC_STORE8_L( dcth4v, dct[3][0] );
160     VEC_STORE8_H( dcth5v, dct[2][1] );
161     VEC_STORE8_L( dcth5v, dct[3][1] );
162     VEC_STORE8_H( dcth6v, dct[2][2] );
163     VEC_STORE8_L( dcth6v, dct[3][2] );
164     VEC_STORE8_H( dcth7v, dct[2][3] );
165     VEC_STORE8_L( dcth7v, dct[3][3] );
166
167     VEC_DCT( dctl0v, dctl1v, dctl2v, dctl3v,
168              temp0v, temp1v, temp2v, temp3v );
169     VEC_DCT( dctl4v, dctl5v, dctl6v, dctl7v,
170              temp4v, temp5v, temp6v, temp7v );
171     VEC_TRANSPOSE_8( temp0v, temp1v, temp2v, temp3v,
172                      temp4v, temp5v, temp6v, temp7v,
173                      dctl0v, dctl1v, dctl2v, dctl3v,
174                      dctl4v, dctl5v, dctl6v, dctl7v );
175     VEC_DCT( dctl0v, dctl1v, dctl2v, dctl3v,
176              temp0v, temp1v, temp2v, temp3v );
177     VEC_DCT( dctl4v, dctl5v, dctl6v, dctl7v,
178              temp4v, temp5v, temp6v, temp7v );
179     VEC_TRANSPOSE_8( temp0v, temp1v, temp2v, temp3v,
180                      temp4v, temp5v, temp6v, temp7v,
181                      dctl0v, dctl1v, dctl2v, dctl3v,
182                      dctl4v, dctl5v, dctl6v, dctl7v );
183     VEC_STORE8_H( dctl0v, dct[4][0] );
184     VEC_STORE8_L( dctl0v, dct[5][0] );
185     VEC_STORE8_H( dctl1v, dct[4][1] );
186     VEC_STORE8_L( dctl1v, dct[5][1] );
187     VEC_STORE8_H( dctl2v, dct[4][2] );
188     VEC_STORE8_L( dctl2v, dct[5][2] );
189     VEC_STORE8_H( dctl3v, dct[4][3] );
190     VEC_STORE8_L( dctl3v, dct[5][3] );
191     VEC_STORE8_H( dctl4v, dct[6][0] );
192     VEC_STORE8_L( dctl4v, dct[7][0] );
193     VEC_STORE8_H( dctl5v, dct[6][1] );
194     VEC_STORE8_L( dctl5v, dct[7][1] );
195     VEC_STORE8_H( dctl6v, dct[6][2] );
196     VEC_STORE8_L( dctl6v, dct[7][2] );
197     VEC_STORE8_H( dctl7v, dct[6][3] );
198     VEC_STORE8_L( dctl7v, dct[7][3] );
199
200     VEC_DIFF_HL( pix1, i_pix1, pix2, i_pix2, dcth0v, dctl0v );
201     VEC_DIFF_HL( pix1, i_pix1, pix2, i_pix2, dcth1v, dctl1v );
202     VEC_DIFF_HL( pix1, i_pix1, pix2, i_pix2, dcth2v, dctl2v );
203     VEC_DIFF_HL( pix1, i_pix1, pix2, i_pix2, dcth3v, dctl3v );
204     VEC_DIFF_HL( pix1, i_pix1, pix2, i_pix2, dcth4v, dctl4v );
205     VEC_DIFF_HL( pix1, i_pix1, pix2, i_pix2, dcth5v, dctl5v );
206     VEC_DIFF_HL( pix1, i_pix1, pix2, i_pix2, dcth6v, dctl6v );
207     VEC_DIFF_HL( pix1, i_pix1, pix2, i_pix2, dcth7v, dctl7v );
208
209     VEC_DCT( dcth0v, dcth1v, dcth2v, dcth3v,
210              temp0v, temp1v, temp2v, temp3v );
211     VEC_DCT( dcth4v, dcth5v, dcth6v, dcth7v,
212              temp4v, temp5v, temp6v, temp7v );
213     VEC_TRANSPOSE_8( temp0v, temp1v, temp2v, temp3v,
214                      temp4v, temp5v, temp6v, temp7v,
215                      dcth0v, dcth1v, dcth2v, dcth3v,
216                      dcth4v, dcth5v, dcth6v, dcth7v );
217     VEC_DCT( dcth0v, dcth1v, dcth2v, dcth3v,
218              temp0v, temp1v, temp2v, temp3v );
219     VEC_DCT( dcth4v, dcth5v, dcth6v, dcth7v,
220              temp4v, temp5v, temp6v, temp7v );
221     VEC_TRANSPOSE_8( temp0v, temp1v, temp2v, temp3v,
222                      temp4v, temp5v, temp6v, temp7v,
223                      dcth0v, dcth1v, dcth2v, dcth3v,
224                      dcth4v, dcth5v, dcth6v, dcth7v );
225     VEC_STORE8_H( dcth0v, dct[8][0] );
226     VEC_STORE8_L( dcth0v, dct[9][0] );
227     VEC_STORE8_H( dcth1v, dct[8][1] );
228     VEC_STORE8_L( dcth1v, dct[9][1] );
229     VEC_STORE8_H( dcth2v, dct[8][2] );
230     VEC_STORE8_L( dcth2v, dct[9][2] );
231     VEC_STORE8_H( dcth3v, dct[8][3] );
232     VEC_STORE8_L( dcth3v, dct[9][3] );
233     VEC_STORE8_H( dcth4v, dct[10][0] );
234     VEC_STORE8_L( dcth4v, dct[11][0] );
235     VEC_STORE8_H( dcth5v, dct[10][1] );
236     VEC_STORE8_L( dcth5v, dct[11][1] );
237     VEC_STORE8_H( dcth6v, dct[10][2] );
238     VEC_STORE8_L( dcth6v, dct[11][2] );
239     VEC_STORE8_H( dcth7v, dct[10][3] );
240     VEC_STORE8_L( dcth7v, dct[11][3] );
241
242     VEC_DCT( dctl0v, dctl1v, dctl2v, dctl3v,
243              temp0v, temp1v, temp2v, temp3v );
244     VEC_DCT( dctl4v, dctl5v, dctl6v, dctl7v,
245              temp4v, temp5v, temp6v, temp7v );
246     VEC_TRANSPOSE_8( temp0v, temp1v, temp2v, temp3v,
247                      temp4v, temp5v, temp6v, temp7v,
248                      dctl0v, dctl1v, dctl2v, dctl3v,
249                      dctl4v, dctl5v, dctl6v, dctl7v );
250     VEC_DCT( dctl0v, dctl1v, dctl2v, dctl3v,
251              temp0v, temp1v, temp2v, temp3v );
252     VEC_DCT( dctl4v, dctl5v, dctl6v, dctl7v,
253              temp4v, temp5v, temp6v, temp7v );
254     VEC_TRANSPOSE_8( temp0v, temp1v, temp2v, temp3v,
255                      temp4v, temp5v, temp6v, temp7v,
256                      dctl0v, dctl1v, dctl2v, dctl3v,
257                      dctl4v, dctl5v, dctl6v, dctl7v );
258     VEC_STORE8_H( dctl0v, dct[12][0] );
259     VEC_STORE8_L( dctl0v, dct[13][0] );
260     VEC_STORE8_H( dctl1v, dct[12][1] );
261     VEC_STORE8_L( dctl1v, dct[13][1] );
262     VEC_STORE8_H( dctl2v, dct[12][2] );
263     VEC_STORE8_L( dctl2v, dct[13][2] );
264     VEC_STORE8_H( dctl3v, dct[12][3] );
265     VEC_STORE8_L( dctl3v, dct[13][3] );
266     VEC_STORE8_H( dctl4v, dct[14][0] );
267     VEC_STORE8_L( dctl4v, dct[15][0] );
268     VEC_STORE8_H( dctl5v, dct[14][1] );
269     VEC_STORE8_L( dctl5v, dct[15][1] );
270     VEC_STORE8_H( dctl6v, dct[14][2] );
271     VEC_STORE8_L( dctl6v, dct[15][2] );
272     VEC_STORE8_H( dctl7v, dct[14][3] );
273     VEC_STORE8_L( dctl7v, dct[15][3] );
274 }