restored AltiVec 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, uint8_t *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, FENC_STRIDE, pix2, FDEC_STRIDE, 4, dct0v );
52     VEC_DIFF_H( pix1, FENC_STRIDE, pix2, FDEC_STRIDE, 4, dct1v );
53     VEC_DIFF_H( pix1, FENC_STRIDE, pix2, FDEC_STRIDE, 4, dct2v );
54     VEC_DIFF_H( pix1, FENC_STRIDE, pix2, FDEC_STRIDE, 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_STORE8( tmp0v, dct[0] );
60     VEC_STORE8( tmp1v, dct[1] );
61     VEC_STORE8( tmp2v, dct[2] );
62     VEC_STORE8( tmp3v, dct[3] );
63 }
64
65 void x264_sub8x8_dct_altivec( int16_t dct[4][4][4],
66         uint8_t *pix1, uint8_t *pix2 )
67 {
68     PREP_DIFF;
69     PREP_STORE8_HL;
70     vec_s16_t dct0v, dct1v, dct2v, dct3v, dct4v, dct5v, dct6v, dct7v;
71     vec_s16_t tmp0v, tmp1v, tmp2v, tmp3v, tmp4v, tmp5v, tmp6v, tmp7v;
72
73     VEC_DIFF_H( pix1, FENC_STRIDE, pix2, FDEC_STRIDE, 8, dct0v );
74     VEC_DIFF_H( pix1, FENC_STRIDE, pix2, FDEC_STRIDE, 8, dct1v );
75     VEC_DIFF_H( pix1, FENC_STRIDE, pix2, FDEC_STRIDE, 8, dct2v );
76     VEC_DIFF_H( pix1, FENC_STRIDE, pix2, FDEC_STRIDE, 8, dct3v );
77     VEC_DIFF_H( pix1, FENC_STRIDE, pix2, FDEC_STRIDE, 8, dct4v );
78     VEC_DIFF_H( pix1, FENC_STRIDE, pix2, FDEC_STRIDE, 8, dct5v );
79     VEC_DIFF_H( pix1, FENC_STRIDE, pix2, FDEC_STRIDE, 8, dct6v );
80     VEC_DIFF_H( pix1, FENC_STRIDE, pix2, FDEC_STRIDE, 8, dct7v );
81     VEC_DCT( dct0v, dct1v, dct2v, dct3v, tmp0v, tmp1v, tmp2v, tmp3v );
82     VEC_DCT( dct4v, dct5v, dct6v, dct7v, tmp4v, tmp5v, tmp6v, tmp7v );
83     VEC_TRANSPOSE_8( tmp0v, tmp1v, tmp2v, tmp3v,
84                      tmp4v, tmp5v, tmp6v, tmp7v,
85                      dct0v, dct1v, dct2v, dct3v,
86                      dct4v, dct5v, dct6v, dct7v );
87     VEC_DCT( dct0v, dct1v, dct2v, dct3v, tmp0v, tmp1v, tmp2v, tmp3v );
88     VEC_STORE8_H( tmp0v, dct[0][0] );
89     VEC_STORE8_H( tmp1v, dct[0][1] );
90     VEC_STORE8_H( tmp2v, dct[0][2] );
91     VEC_STORE8_H( tmp3v, dct[0][3] );
92     VEC_STORE8_L( tmp0v, dct[2][0] );
93     VEC_STORE8_L( tmp1v, dct[2][1] );
94     VEC_STORE8_L( tmp2v, dct[2][2] );
95     VEC_STORE8_L( tmp3v, dct[2][3] );
96     VEC_DCT( dct4v, dct5v, dct6v, dct7v, tmp4v, tmp5v, tmp6v, tmp7v );
97     VEC_STORE8_H( tmp4v, dct[1][0] );
98     VEC_STORE8_H( tmp5v, dct[1][1] );
99     VEC_STORE8_H( tmp6v, dct[1][2] );
100     VEC_STORE8_H( tmp7v, dct[1][3] );
101     VEC_STORE8_L( tmp4v, dct[3][0] );
102     VEC_STORE8_L( tmp5v, dct[3][1] );
103     VEC_STORE8_L( tmp6v, dct[3][2] );
104     VEC_STORE8_L( tmp7v, dct[3][3] );
105 }
106     
107 void x264_sub16x16_dct_altivec( int16_t dct[16][4][4],
108         uint8_t *pix1, uint8_t *pix2 ) 
109 {
110     PREP_DIFF;
111     PREP_STORE8_HL;
112     vec_s16_t dcth0v, dcth1v, dcth2v, dcth3v,
113               dcth4v, dcth5v, dcth6v, dcth7v,
114               dctl0v, dctl1v, dctl2v, dctl3v,
115               dctl4v, dctl5v, dctl6v, dctl7v;
116     vec_s16_t temp0v, temp1v, temp2v, temp3v,
117               temp4v, temp5v, temp6v, temp7v;
118
119     VEC_DIFF_HL( pix1, FENC_STRIDE, pix2, FDEC_STRIDE, dcth0v, dctl0v );
120     VEC_DIFF_HL( pix1, FENC_STRIDE, pix2, FDEC_STRIDE, dcth1v, dctl1v );
121     VEC_DIFF_HL( pix1, FENC_STRIDE, pix2, FDEC_STRIDE, dcth2v, dctl2v );
122     VEC_DIFF_HL( pix1, FENC_STRIDE, pix2, FDEC_STRIDE, dcth3v, dctl3v );
123     VEC_DIFF_HL( pix1, FENC_STRIDE, pix2, FDEC_STRIDE, dcth4v, dctl4v );
124     VEC_DIFF_HL( pix1, FENC_STRIDE, pix2, FDEC_STRIDE, dcth5v, dctl5v );
125     VEC_DIFF_HL( pix1, FENC_STRIDE, pix2, FDEC_STRIDE, dcth6v, dctl6v );
126     VEC_DIFF_HL( pix1, FENC_STRIDE, pix2, FDEC_STRIDE, dcth7v, dctl7v );
127
128     VEC_DCT( dcth0v, dcth1v, dcth2v, dcth3v,
129              temp0v, temp1v, temp2v, temp3v );
130     VEC_DCT( dcth4v, dcth5v, dcth6v, dcth7v,
131              temp4v, temp5v, temp6v, temp7v );
132     VEC_TRANSPOSE_8( temp0v, temp1v, temp2v, temp3v,
133                      temp4v, temp5v, temp6v, temp7v,
134                      dcth0v, dcth1v, dcth2v, dcth3v,
135                      dcth4v, dcth5v, dcth6v, dcth7v );
136     VEC_DCT( dcth0v, dcth1v, dcth2v, dcth3v,
137              temp0v, temp1v, temp2v, temp3v );
138     VEC_STORE8_H( temp0v, dct[0][0] );
139     VEC_STORE8_H( temp1v, dct[0][1] );
140     VEC_STORE8_H( temp2v, dct[0][2] );
141     VEC_STORE8_H( temp3v, dct[0][3] );
142     VEC_STORE8_L( temp0v, dct[2][0] );
143     VEC_STORE8_L( temp1v, dct[2][1] );
144     VEC_STORE8_L( temp2v, dct[2][2] );
145     VEC_STORE8_L( temp3v, dct[2][3] );
146     VEC_DCT( dcth4v, dcth5v, dcth6v, dcth7v,
147              temp4v, temp5v, temp6v, temp7v );
148     VEC_STORE8_H( temp4v, dct[1][0] );
149     VEC_STORE8_H( temp5v, dct[1][1] );
150     VEC_STORE8_H( temp6v, dct[1][2] );
151     VEC_STORE8_H( temp7v, dct[1][3] );
152     VEC_STORE8_L( temp4v, dct[3][0] );
153     VEC_STORE8_L( temp5v, dct[3][1] );
154     VEC_STORE8_L( temp6v, dct[3][2] );
155     VEC_STORE8_L( temp7v, dct[3][3] );
156
157     VEC_DCT( dctl0v, dctl1v, dctl2v, dctl3v,
158              temp0v, temp1v, temp2v, temp3v );
159     VEC_DCT( dctl4v, dctl5v, dctl6v, dctl7v,
160              temp4v, temp5v, temp6v, temp7v );
161     VEC_TRANSPOSE_8( temp0v, temp1v, temp2v, temp3v,
162                      temp4v, temp5v, temp6v, temp7v,
163                      dctl0v, dctl1v, dctl2v, dctl3v,
164                      dctl4v, dctl5v, dctl6v, dctl7v );
165     VEC_DCT( dctl0v, dctl1v, dctl2v, dctl3v,
166              temp0v, temp1v, temp2v, temp3v );
167     VEC_STORE8_H( temp0v, dct[4][0] );
168     VEC_STORE8_H( temp1v, dct[4][1] );
169     VEC_STORE8_H( temp2v, dct[4][2] );
170     VEC_STORE8_H( temp3v, dct[4][3] );
171     VEC_STORE8_L( temp0v, dct[6][0] );
172     VEC_STORE8_L( temp1v, dct[6][1] );
173     VEC_STORE8_L( temp2v, dct[6][2] );
174     VEC_STORE8_L( temp3v, dct[6][3] );
175     VEC_DCT( dctl4v, dctl5v, dctl6v, dctl7v,
176              temp4v, temp5v, temp6v, temp7v );
177     VEC_STORE8_H( temp4v, dct[5][0] );
178     VEC_STORE8_H( temp5v, dct[5][1] );
179     VEC_STORE8_H( temp6v, dct[5][2] );
180     VEC_STORE8_H( temp7v, dct[5][3] );
181     VEC_STORE8_L( temp4v, dct[7][0] );
182     VEC_STORE8_L( temp5v, dct[7][1] );
183     VEC_STORE8_L( temp6v, dct[7][2] );
184     VEC_STORE8_L( temp7v, dct[7][3] );
185
186     VEC_DIFF_HL( pix1, FENC_STRIDE, pix2, FDEC_STRIDE, dcth0v, dctl0v );
187     VEC_DIFF_HL( pix1, FENC_STRIDE, pix2, FDEC_STRIDE, dcth1v, dctl1v );
188     VEC_DIFF_HL( pix1, FENC_STRIDE, pix2, FDEC_STRIDE, dcth2v, dctl2v );
189     VEC_DIFF_HL( pix1, FENC_STRIDE, pix2, FDEC_STRIDE, dcth3v, dctl3v );
190     VEC_DIFF_HL( pix1, FENC_STRIDE, pix2, FDEC_STRIDE, dcth4v, dctl4v );
191     VEC_DIFF_HL( pix1, FENC_STRIDE, pix2, FDEC_STRIDE, dcth5v, dctl5v );
192     VEC_DIFF_HL( pix1, FENC_STRIDE, pix2, FDEC_STRIDE, dcth6v, dctl6v );
193     VEC_DIFF_HL( pix1, FENC_STRIDE, pix2, FDEC_STRIDE, dcth7v, dctl7v );
194
195     VEC_DCT( dcth0v, dcth1v, dcth2v, dcth3v,
196              temp0v, temp1v, temp2v, temp3v );
197     VEC_DCT( dcth4v, dcth5v, dcth6v, dcth7v,
198              temp4v, temp5v, temp6v, temp7v );
199     VEC_TRANSPOSE_8( temp0v, temp1v, temp2v, temp3v,
200                      temp4v, temp5v, temp6v, temp7v,
201                      dcth0v, dcth1v, dcth2v, dcth3v,
202                      dcth4v, dcth5v, dcth6v, dcth7v );
203     VEC_DCT( dcth0v, dcth1v, dcth2v, dcth3v,
204              temp0v, temp1v, temp2v, temp3v );
205     VEC_STORE8_H( temp0v, dct[8][0] );
206     VEC_STORE8_H( temp1v, dct[8][1] );
207     VEC_STORE8_H( temp2v, dct[8][2] );
208     VEC_STORE8_H( temp3v, dct[8][3] );
209     VEC_STORE8_L( temp0v, dct[10][0] );
210     VEC_STORE8_L( temp1v, dct[10][1] );
211     VEC_STORE8_L( temp2v, dct[10][2] );
212     VEC_STORE8_L( temp3v, dct[10][3] );
213     VEC_DCT( dcth4v, dcth5v, dcth6v, dcth7v,
214              temp4v, temp5v, temp6v, temp7v );
215     VEC_STORE8_H( temp4v, dct[9][0] );
216     VEC_STORE8_H( temp5v, dct[9][1] );
217     VEC_STORE8_H( temp6v, dct[9][2] );
218     VEC_STORE8_H( temp7v, dct[9][3] );
219     VEC_STORE8_L( temp4v, dct[11][0] );
220     VEC_STORE8_L( temp5v, dct[11][1] );
221     VEC_STORE8_L( temp6v, dct[11][2] );
222     VEC_STORE8_L( temp7v, dct[11][3] );
223
224     VEC_DCT( dctl0v, dctl1v, dctl2v, dctl3v,
225              temp0v, temp1v, temp2v, temp3v );
226     VEC_DCT( dctl4v, dctl5v, dctl6v, dctl7v,
227              temp4v, temp5v, temp6v, temp7v );
228     VEC_TRANSPOSE_8( temp0v, temp1v, temp2v, temp3v,
229                      temp4v, temp5v, temp6v, temp7v,
230                      dctl0v, dctl1v, dctl2v, dctl3v,
231                      dctl4v, dctl5v, dctl6v, dctl7v );
232     VEC_DCT( dctl0v, dctl1v, dctl2v, dctl3v,
233              temp0v, temp1v, temp2v, temp3v );
234     VEC_STORE8_H( temp0v, dct[12][0] );
235     VEC_STORE8_H( temp1v, dct[12][1] );
236     VEC_STORE8_H( temp2v, dct[12][2] );
237     VEC_STORE8_H( temp3v, dct[12][3] );
238     VEC_STORE8_L( temp0v, dct[14][0] );
239     VEC_STORE8_L( temp1v, dct[14][1] );
240     VEC_STORE8_L( temp2v, dct[14][2] );
241     VEC_STORE8_L( temp3v, dct[14][3] );
242     VEC_DCT( dctl4v, dctl5v, dctl6v, dctl7v,
243              temp4v, temp5v, temp6v, temp7v );
244     VEC_STORE8_H( temp4v, dct[13][0] );
245     VEC_STORE8_H( temp5v, dct[13][1] );
246     VEC_STORE8_H( temp6v, dct[13][2] );
247     VEC_STORE8_H( temp7v, dct[13][3] );
248     VEC_STORE8_L( temp4v, dct[15][0] );
249     VEC_STORE8_L( temp5v, dct[15][1] );
250     VEC_STORE8_L( temp6v, dct[15][2] );
251     VEC_STORE8_L( temp7v, dct[15][3] );
252 }