]> git.sesse.net Git - ffmpeg/blob - libavcodec/x86/simple_idct.c
Merge commit '1ae6cb7d6e4fee30754a46bc91f40ff75ac4412a'
[ffmpeg] / libavcodec / x86 / simple_idct.c
1 /*
2  * Simple IDCT MMX
3  *
4  * Copyright (c) 2001, 2002 Michael Niedermayer <michaelni@gmx.at>
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/mem.h"
24 #include "libavutil/x86/asm.h"
25
26 #include "libavcodec/idctdsp.h"
27 #include "libavcodec/x86/idctdsp.h"
28
29 #include "idctdsp.h"
30 #include "simple_idct.h"
31
32 #if HAVE_INLINE_ASM
33
34 /*
35 23170.475006
36 22725.260826
37 21406.727617
38 19265.545870
39 16384.000000
40 12872.826198
41 8866.956905
42 4520.335430
43 */
44 #define C0 23170 //cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5
45 #define C1 22725 //cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5
46 #define C2 21407 //cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5
47 #define C3 19266 //cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5
48 #define C4 16383 //cos(i*M_PI/16)*sqrt(2)*(1<<14) - 0.5
49 #define C5 12873 //cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5
50 #define C6 8867  //cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5
51 #define C7 4520  //cos(i*M_PI/16)*sqrt(2)*(1<<14) + 0.5
52
53 #define ROW_SHIFT 11
54 #define COL_SHIFT 20 // 6
55
56 DECLARE_ASM_CONST(8, uint64_t, wm1010)= 0xFFFF0000FFFF0000ULL;
57 DECLARE_ASM_CONST(8, uint64_t, d40000)= 0x0000000000040000ULL;
58
59 DECLARE_ALIGNED(8, static const int16_t, coeffs)[]= {
60         1<<(ROW_SHIFT-1), 0, 1<<(ROW_SHIFT-1), 0,
61 //        1<<(COL_SHIFT-1), 0, 1<<(COL_SHIFT-1), 0,
62 //        0, 1<<(COL_SHIFT-1-16), 0, 1<<(COL_SHIFT-1-16),
63         1<<(ROW_SHIFT-1), 1, 1<<(ROW_SHIFT-1), 0,
64         // the 1 = ((1<<(COL_SHIFT-1))/C4)<<ROW_SHIFT :)
65 //        0, 0, 0, 0,
66 //        0, 0, 0, 0,
67
68  C4,  C4,  C4,  C4,
69  C4, -C4,  C4, -C4,
70
71  C2,  C6,  C2,  C6,
72  C6, -C2,  C6, -C2,
73
74  C1,  C3,  C1,  C3,
75  C5,  C7,  C5,  C7,
76
77  C3, -C7,  C3, -C7,
78 -C1, -C5, -C1, -C5,
79
80  C5, -C1,  C5, -C1,
81  C7,  C3,  C7,  C3,
82
83  C7, -C5,  C7, -C5,
84  C3, -C1,  C3, -C1
85 };
86
87 static inline void idct(int16_t *block)
88 {
89         LOCAL_ALIGNED_8(int64_t, align_tmp, [16]);
90         int16_t * const temp= (int16_t*)align_tmp;
91
92         __asm__ volatile(
93 #define DC_COND_IDCT(src0, src4, src1, src5, dst, rounder, shift) \
94         "movq " #src0 ", %%mm0          \n\t" /* R4     R0      r4      r0 */\
95         "movq " #src4 ", %%mm1          \n\t" /* R6     R2      r6      r2 */\
96         "movq " #src1 ", %%mm2          \n\t" /* R3     R1      r3      r1 */\
97         "movq " #src5 ", %%mm3          \n\t" /* R7     R5      r7      r5 */\
98         "movq "MANGLE(wm1010)", %%mm4   \n\t"\
99         "pand %%mm0, %%mm4              \n\t"\
100         "por %%mm1, %%mm4               \n\t"\
101         "por %%mm2, %%mm4               \n\t"\
102         "por %%mm3, %%mm4               \n\t"\
103         "packssdw %%mm4,%%mm4           \n\t"\
104         "movd %%mm4, %%eax              \n\t"\
105         "orl %%eax, %%eax               \n\t"\
106         "jz 1f                          \n\t"\
107         "movq 16(%2), %%mm4             \n\t" /* C4     C4      C4      C4 */\
108         "pmaddwd %%mm0, %%mm4           \n\t" /* C4R4+C4R0      C4r4+C4r0 */\
109         "movq 24(%2), %%mm5             \n\t" /* -C4    C4      -C4     C4 */\
110         "pmaddwd %%mm5, %%mm0           \n\t" /* -C4R4+C4R0     -C4r4+C4r0 */\
111         "movq 32(%2), %%mm5             \n\t" /* C6     C2      C6      C2 */\
112         "pmaddwd %%mm1, %%mm5           \n\t" /* C6R6+C2R2      C6r6+C2r2 */\
113         "movq 40(%2), %%mm6             \n\t" /* -C2    C6      -C2     C6 */\
114         "pmaddwd %%mm6, %%mm1           \n\t" /* -C2R6+C6R2     -C2r6+C6r2 */\
115         "movq 48(%2), %%mm7             \n\t" /* C3     C1      C3      C1 */\
116         "pmaddwd %%mm2, %%mm7           \n\t" /* C3R3+C1R1      C3r3+C1r1 */\
117         #rounder ", %%mm4               \n\t"\
118         "movq %%mm4, %%mm6              \n\t" /* C4R4+C4R0      C4r4+C4r0 */\
119         "paddd %%mm5, %%mm4             \n\t" /* A0             a0 */\
120         "psubd %%mm5, %%mm6             \n\t" /* A3             a3 */\
121         "movq 56(%2), %%mm5             \n\t" /* C7     C5      C7      C5 */\
122         "pmaddwd %%mm3, %%mm5           \n\t" /* C7R7+C5R5      C7r7+C5r5 */\
123         #rounder ", %%mm0               \n\t"\
124         "paddd %%mm0, %%mm1             \n\t" /* A1             a1 */\
125         "paddd %%mm0, %%mm0             \n\t" \
126         "psubd %%mm1, %%mm0             \n\t" /* A2             a2 */\
127         "pmaddwd 64(%2), %%mm2          \n\t" /* -C7R3+C3R1     -C7r3+C3r1 */\
128         "paddd %%mm5, %%mm7             \n\t" /* B0             b0 */\
129         "movq 72(%2), %%mm5             \n\t" /* -C5    -C1     -C5     -C1 */\
130         "pmaddwd %%mm3, %%mm5           \n\t" /* -C5R7-C1R5     -C5r7-C1r5 */\
131         "paddd %%mm4, %%mm7             \n\t" /* A0+B0          a0+b0 */\
132         "paddd %%mm4, %%mm4             \n\t" /* 2A0            2a0 */\
133         "psubd %%mm7, %%mm4             \n\t" /* A0-B0          a0-b0 */\
134         "paddd %%mm2, %%mm5             \n\t" /* B1             b1 */\
135         "psrad $" #shift ", %%mm7       \n\t"\
136         "psrad $" #shift ", %%mm4       \n\t"\
137         "movq %%mm1, %%mm2              \n\t" /* A1             a1 */\
138         "paddd %%mm5, %%mm1             \n\t" /* A1+B1          a1+b1 */\
139         "psubd %%mm5, %%mm2             \n\t" /* A1-B1          a1-b1 */\
140         "psrad $" #shift ", %%mm1       \n\t"\
141         "psrad $" #shift ", %%mm2       \n\t"\
142         "packssdw %%mm1, %%mm7          \n\t" /* A1+B1  a1+b1   A0+B0   a0+b0 */\
143         "packssdw %%mm4, %%mm2          \n\t" /* A0-B0  a0-b0   A1-B1   a1-b1 */\
144         "movq %%mm7, " #dst "           \n\t"\
145         "movq " #src1 ", %%mm1          \n\t" /* R3     R1      r3      r1 */\
146         "movq 80(%2), %%mm4             \n\t" /* -C1    C5      -C1     C5 */\
147         "movq %%mm2, 24+" #dst "        \n\t"\
148         "pmaddwd %%mm1, %%mm4           \n\t" /* -C1R3+C5R1     -C1r3+C5r1 */\
149         "movq 88(%2), %%mm7             \n\t" /* C3     C7      C3      C7 */\
150         "pmaddwd 96(%2), %%mm1          \n\t" /* -C5R3+C7R1     -C5r3+C7r1 */\
151         "pmaddwd %%mm3, %%mm7           \n\t" /* C3R7+C7R5      C3r7+C7r5 */\
152         "movq %%mm0, %%mm2              \n\t" /* A2             a2 */\
153         "pmaddwd 104(%2), %%mm3         \n\t" /* -C1R7+C3R5     -C1r7+C3r5 */\
154         "paddd %%mm7, %%mm4             \n\t" /* B2             b2 */\
155         "paddd %%mm4, %%mm2             \n\t" /* A2+B2          a2+b2 */\
156         "psubd %%mm4, %%mm0             \n\t" /* a2-B2          a2-b2 */\
157         "psrad $" #shift ", %%mm2       \n\t"\
158         "psrad $" #shift ", %%mm0       \n\t"\
159         "movq %%mm6, %%mm4              \n\t" /* A3             a3 */\
160         "paddd %%mm1, %%mm3             \n\t" /* B3             b3 */\
161         "paddd %%mm3, %%mm6             \n\t" /* A3+B3          a3+b3 */\
162         "psubd %%mm3, %%mm4             \n\t" /* a3-B3          a3-b3 */\
163         "psrad $" #shift ", %%mm6       \n\t"\
164         "packssdw %%mm6, %%mm2          \n\t" /* A3+B3  a3+b3   A2+B2   a2+b2 */\
165         "movq %%mm2, 8+" #dst "         \n\t"\
166         "psrad $" #shift ", %%mm4       \n\t"\
167         "packssdw %%mm0, %%mm4          \n\t" /* A2-B2  a2-b2   A3-B3   a3-b3 */\
168         "movq %%mm4, 16+" #dst "        \n\t"\
169         "jmp 2f                         \n\t"\
170         "1:                             \n\t"\
171         "pslld $16, %%mm0               \n\t"\
172         "paddd "MANGLE(d40000)", %%mm0  \n\t"\
173         "psrad $13, %%mm0               \n\t"\
174         "packssdw %%mm0, %%mm0          \n\t"\
175         "movq %%mm0, " #dst "           \n\t"\
176         "movq %%mm0, 8+" #dst "         \n\t"\
177         "movq %%mm0, 16+" #dst "        \n\t"\
178         "movq %%mm0, 24+" #dst "        \n\t"\
179         "2:                             \n\t"
180
181 #define Z_COND_IDCT(src0, src4, src1, src5, dst, rounder, shift, bt) \
182         "movq " #src0 ", %%mm0          \n\t" /* R4     R0      r4      r0 */\
183         "movq " #src4 ", %%mm1          \n\t" /* R6     R2      r6      r2 */\
184         "movq " #src1 ", %%mm2          \n\t" /* R3     R1      r3      r1 */\
185         "movq " #src5 ", %%mm3          \n\t" /* R7     R5      r7      r5 */\
186         "movq %%mm0, %%mm4              \n\t"\
187         "por %%mm1, %%mm4               \n\t"\
188         "por %%mm2, %%mm4               \n\t"\
189         "por %%mm3, %%mm4               \n\t"\
190         "packssdw %%mm4,%%mm4           \n\t"\
191         "movd %%mm4, %%eax              \n\t"\
192         "orl %%eax, %%eax               \n\t"\
193         "jz " #bt "                     \n\t"\
194         "movq 16(%2), %%mm4             \n\t" /* C4     C4      C4      C4 */\
195         "pmaddwd %%mm0, %%mm4           \n\t" /* C4R4+C4R0      C4r4+C4r0 */\
196         "movq 24(%2), %%mm5             \n\t" /* -C4    C4      -C4     C4 */\
197         "pmaddwd %%mm5, %%mm0           \n\t" /* -C4R4+C4R0     -C4r4+C4r0 */\
198         "movq 32(%2), %%mm5             \n\t" /* C6     C2      C6      C2 */\
199         "pmaddwd %%mm1, %%mm5           \n\t" /* C6R6+C2R2      C6r6+C2r2 */\
200         "movq 40(%2), %%mm6             \n\t" /* -C2    C6      -C2     C6 */\
201         "pmaddwd %%mm6, %%mm1           \n\t" /* -C2R6+C6R2     -C2r6+C6r2 */\
202         "movq 48(%2), %%mm7             \n\t" /* C3     C1      C3      C1 */\
203         "pmaddwd %%mm2, %%mm7           \n\t" /* C3R3+C1R1      C3r3+C1r1 */\
204         #rounder ", %%mm4               \n\t"\
205         "movq %%mm4, %%mm6              \n\t" /* C4R4+C4R0      C4r4+C4r0 */\
206         "paddd %%mm5, %%mm4             \n\t" /* A0             a0 */\
207         "psubd %%mm5, %%mm6             \n\t" /* A3             a3 */\
208         "movq 56(%2), %%mm5             \n\t" /* C7     C5      C7      C5 */\
209         "pmaddwd %%mm3, %%mm5           \n\t" /* C7R7+C5R5      C7r7+C5r5 */\
210         #rounder ", %%mm0               \n\t"\
211         "paddd %%mm0, %%mm1             \n\t" /* A1             a1 */\
212         "paddd %%mm0, %%mm0             \n\t" \
213         "psubd %%mm1, %%mm0             \n\t" /* A2             a2 */\
214         "pmaddwd 64(%2), %%mm2          \n\t" /* -C7R3+C3R1     -C7r3+C3r1 */\
215         "paddd %%mm5, %%mm7             \n\t" /* B0             b0 */\
216         "movq 72(%2), %%mm5             \n\t" /* -C5    -C1     -C5     -C1 */\
217         "pmaddwd %%mm3, %%mm5           \n\t" /* -C5R7-C1R5     -C5r7-C1r5 */\
218         "paddd %%mm4, %%mm7             \n\t" /* A0+B0          a0+b0 */\
219         "paddd %%mm4, %%mm4             \n\t" /* 2A0            2a0 */\
220         "psubd %%mm7, %%mm4             \n\t" /* A0-B0          a0-b0 */\
221         "paddd %%mm2, %%mm5             \n\t" /* B1             b1 */\
222         "psrad $" #shift ", %%mm7       \n\t"\
223         "psrad $" #shift ", %%mm4       \n\t"\
224         "movq %%mm1, %%mm2              \n\t" /* A1             a1 */\
225         "paddd %%mm5, %%mm1             \n\t" /* A1+B1          a1+b1 */\
226         "psubd %%mm5, %%mm2             \n\t" /* A1-B1          a1-b1 */\
227         "psrad $" #shift ", %%mm1       \n\t"\
228         "psrad $" #shift ", %%mm2       \n\t"\
229         "packssdw %%mm1, %%mm7          \n\t" /* A1+B1  a1+b1   A0+B0   a0+b0 */\
230         "packssdw %%mm4, %%mm2          \n\t" /* A0-B0  a0-b0   A1-B1   a1-b1 */\
231         "movq %%mm7, " #dst "           \n\t"\
232         "movq " #src1 ", %%mm1          \n\t" /* R3     R1      r3      r1 */\
233         "movq 80(%2), %%mm4             \n\t" /* -C1    C5      -C1     C5 */\
234         "movq %%mm2, 24+" #dst "        \n\t"\
235         "pmaddwd %%mm1, %%mm4           \n\t" /* -C1R3+C5R1     -C1r3+C5r1 */\
236         "movq 88(%2), %%mm7             \n\t" /* C3     C7      C3      C7 */\
237         "pmaddwd 96(%2), %%mm1          \n\t" /* -C5R3+C7R1     -C5r3+C7r1 */\
238         "pmaddwd %%mm3, %%mm7           \n\t" /* C3R7+C7R5      C3r7+C7r5 */\
239         "movq %%mm0, %%mm2              \n\t" /* A2             a2 */\
240         "pmaddwd 104(%2), %%mm3         \n\t" /* -C1R7+C3R5     -C1r7+C3r5 */\
241         "paddd %%mm7, %%mm4             \n\t" /* B2             b2 */\
242         "paddd %%mm4, %%mm2             \n\t" /* A2+B2          a2+b2 */\
243         "psubd %%mm4, %%mm0             \n\t" /* a2-B2          a2-b2 */\
244         "psrad $" #shift ", %%mm2       \n\t"\
245         "psrad $" #shift ", %%mm0       \n\t"\
246         "movq %%mm6, %%mm4              \n\t" /* A3             a3 */\
247         "paddd %%mm1, %%mm3             \n\t" /* B3             b3 */\
248         "paddd %%mm3, %%mm6             \n\t" /* A3+B3          a3+b3 */\
249         "psubd %%mm3, %%mm4             \n\t" /* a3-B3          a3-b3 */\
250         "psrad $" #shift ", %%mm6       \n\t"\
251         "packssdw %%mm6, %%mm2          \n\t" /* A3+B3  a3+b3   A2+B2   a2+b2 */\
252         "movq %%mm2, 8+" #dst "         \n\t"\
253         "psrad $" #shift ", %%mm4       \n\t"\
254         "packssdw %%mm0, %%mm4          \n\t" /* A2-B2  a2-b2   A3-B3   a3-b3 */\
255         "movq %%mm4, 16+" #dst "        \n\t"\
256
257 #define ROW_IDCT(src0, src4, src1, src5, dst, rounder, shift) \
258         "movq " #src0 ", %%mm0          \n\t" /* R4     R0      r4      r0 */\
259         "movq " #src4 ", %%mm1          \n\t" /* R6     R2      r6      r2 */\
260         "movq " #src1 ", %%mm2          \n\t" /* R3     R1      r3      r1 */\
261         "movq " #src5 ", %%mm3          \n\t" /* R7     R5      r7      r5 */\
262         "movq 16(%2), %%mm4             \n\t" /* C4     C4      C4      C4 */\
263         "pmaddwd %%mm0, %%mm4           \n\t" /* C4R4+C4R0      C4r4+C4r0 */\
264         "movq 24(%2), %%mm5             \n\t" /* -C4    C4      -C4     C4 */\
265         "pmaddwd %%mm5, %%mm0           \n\t" /* -C4R4+C4R0     -C4r4+C4r0 */\
266         "movq 32(%2), %%mm5             \n\t" /* C6     C2      C6      C2 */\
267         "pmaddwd %%mm1, %%mm5           \n\t" /* C6R6+C2R2      C6r6+C2r2 */\
268         "movq 40(%2), %%mm6             \n\t" /* -C2    C6      -C2     C6 */\
269         "pmaddwd %%mm6, %%mm1           \n\t" /* -C2R6+C6R2     -C2r6+C6r2 */\
270         "movq 48(%2), %%mm7             \n\t" /* C3     C1      C3      C1 */\
271         "pmaddwd %%mm2, %%mm7           \n\t" /* C3R3+C1R1      C3r3+C1r1 */\
272         #rounder ", %%mm4               \n\t"\
273         "movq %%mm4, %%mm6              \n\t" /* C4R4+C4R0      C4r4+C4r0 */\
274         "paddd %%mm5, %%mm4             \n\t" /* A0             a0 */\
275         "psubd %%mm5, %%mm6             \n\t" /* A3             a3 */\
276         "movq 56(%2), %%mm5             \n\t" /* C7     C5      C7      C5 */\
277         "pmaddwd %%mm3, %%mm5           \n\t" /* C7R7+C5R5      C7r7+C5r5 */\
278         #rounder ", %%mm0               \n\t"\
279         "paddd %%mm0, %%mm1             \n\t" /* A1             a1 */\
280         "paddd %%mm0, %%mm0             \n\t" \
281         "psubd %%mm1, %%mm0             \n\t" /* A2             a2 */\
282         "pmaddwd 64(%2), %%mm2          \n\t" /* -C7R3+C3R1     -C7r3+C3r1 */\
283         "paddd %%mm5, %%mm7             \n\t" /* B0             b0 */\
284         "movq 72(%2), %%mm5             \n\t" /* -C5    -C1     -C5     -C1 */\
285         "pmaddwd %%mm3, %%mm5           \n\t" /* -C5R7-C1R5     -C5r7-C1r5 */\
286         "paddd %%mm4, %%mm7             \n\t" /* A0+B0          a0+b0 */\
287         "paddd %%mm4, %%mm4             \n\t" /* 2A0            2a0 */\
288         "psubd %%mm7, %%mm4             \n\t" /* A0-B0          a0-b0 */\
289         "paddd %%mm2, %%mm5             \n\t" /* B1             b1 */\
290         "psrad $" #shift ", %%mm7       \n\t"\
291         "psrad $" #shift ", %%mm4       \n\t"\
292         "movq %%mm1, %%mm2              \n\t" /* A1             a1 */\
293         "paddd %%mm5, %%mm1             \n\t" /* A1+B1          a1+b1 */\
294         "psubd %%mm5, %%mm2             \n\t" /* A1-B1          a1-b1 */\
295         "psrad $" #shift ", %%mm1       \n\t"\
296         "psrad $" #shift ", %%mm2       \n\t"\
297         "packssdw %%mm1, %%mm7          \n\t" /* A1+B1  a1+b1   A0+B0   a0+b0 */\
298         "packssdw %%mm4, %%mm2          \n\t" /* A0-B0  a0-b0   A1-B1   a1-b1 */\
299         "movq %%mm7, " #dst "           \n\t"\
300         "movq " #src1 ", %%mm1          \n\t" /* R3     R1      r3      r1 */\
301         "movq 80(%2), %%mm4             \n\t" /* -C1    C5      -C1     C5 */\
302         "movq %%mm2, 24+" #dst "        \n\t"\
303         "pmaddwd %%mm1, %%mm4           \n\t" /* -C1R3+C5R1     -C1r3+C5r1 */\
304         "movq 88(%2), %%mm7             \n\t" /* C3     C7      C3      C7 */\
305         "pmaddwd 96(%2), %%mm1          \n\t" /* -C5R3+C7R1     -C5r3+C7r1 */\
306         "pmaddwd %%mm3, %%mm7           \n\t" /* C3R7+C7R5      C3r7+C7r5 */\
307         "movq %%mm0, %%mm2              \n\t" /* A2             a2 */\
308         "pmaddwd 104(%2), %%mm3         \n\t" /* -C1R7+C3R5     -C1r7+C3r5 */\
309         "paddd %%mm7, %%mm4             \n\t" /* B2             b2 */\
310         "paddd %%mm4, %%mm2             \n\t" /* A2+B2          a2+b2 */\
311         "psubd %%mm4, %%mm0             \n\t" /* a2-B2          a2-b2 */\
312         "psrad $" #shift ", %%mm2       \n\t"\
313         "psrad $" #shift ", %%mm0       \n\t"\
314         "movq %%mm6, %%mm4              \n\t" /* A3             a3 */\
315         "paddd %%mm1, %%mm3             \n\t" /* B3             b3 */\
316         "paddd %%mm3, %%mm6             \n\t" /* A3+B3          a3+b3 */\
317         "psubd %%mm3, %%mm4             \n\t" /* a3-B3          a3-b3 */\
318         "psrad $" #shift ", %%mm6       \n\t"\
319         "packssdw %%mm6, %%mm2          \n\t" /* A3+B3  a3+b3   A2+B2   a2+b2 */\
320         "movq %%mm2, 8+" #dst "         \n\t"\
321         "psrad $" #shift ", %%mm4       \n\t"\
322         "packssdw %%mm0, %%mm4          \n\t" /* A2-B2  a2-b2   A3-B3   a3-b3 */\
323         "movq %%mm4, 16+" #dst "        \n\t"\
324
325 //IDCT(         src0,   src4,   src1,   src5,    dst,   rounder, shift)
326 DC_COND_IDCT(  0(%0),  8(%0), 16(%0), 24(%0),  0(%1),paddd 8(%2), 11)
327 Z_COND_IDCT(  32(%0), 40(%0), 48(%0), 56(%0), 32(%1),paddd (%2), 11, 4f)
328 Z_COND_IDCT(  64(%0), 72(%0), 80(%0), 88(%0), 64(%1),paddd (%2), 11, 2f)
329 Z_COND_IDCT(  96(%0),104(%0),112(%0),120(%0), 96(%1),paddd (%2), 11, 1f)
330
331 #undef IDCT
332 #define IDCT(src0, src4, src1, src5, dst, shift) \
333         "movq " #src0 ", %%mm0          \n\t" /* R4     R0      r4      r0 */\
334         "movq " #src4 ", %%mm1          \n\t" /* R6     R2      r6      r2 */\
335         "movq " #src1 ", %%mm2          \n\t" /* R3     R1      r3      r1 */\
336         "movq " #src5 ", %%mm3          \n\t" /* R7     R5      r7      r5 */\
337         "movq 16(%2), %%mm4             \n\t" /* C4     C4      C4      C4 */\
338         "pmaddwd %%mm0, %%mm4           \n\t" /* C4R4+C4R0      C4r4+C4r0 */\
339         "movq 24(%2), %%mm5             \n\t" /* -C4    C4      -C4     C4 */\
340         "pmaddwd %%mm5, %%mm0           \n\t" /* -C4R4+C4R0     -C4r4+C4r0 */\
341         "movq 32(%2), %%mm5             \n\t" /* C6     C2      C6      C2 */\
342         "pmaddwd %%mm1, %%mm5           \n\t" /* C6R6+C2R2      C6r6+C2r2 */\
343         "movq 40(%2), %%mm6             \n\t" /* -C2    C6      -C2     C6 */\
344         "pmaddwd %%mm6, %%mm1           \n\t" /* -C2R6+C6R2     -C2r6+C6r2 */\
345         "movq %%mm4, %%mm6              \n\t" /* C4R4+C4R0      C4r4+C4r0 */\
346         "movq 48(%2), %%mm7             \n\t" /* C3     C1      C3      C1 */\
347         "pmaddwd %%mm2, %%mm7           \n\t" /* C3R3+C1R1      C3r3+C1r1 */\
348         "paddd %%mm5, %%mm4             \n\t" /* A0             a0 */\
349         "psubd %%mm5, %%mm6             \n\t" /* A3             a3 */\
350         "movq %%mm0, %%mm5              \n\t" /* -C4R4+C4R0     -C4r4+C4r0 */\
351         "paddd %%mm1, %%mm0             \n\t" /* A1             a1 */\
352         "psubd %%mm1, %%mm5             \n\t" /* A2             a2 */\
353         "movq 56(%2), %%mm1             \n\t" /* C7     C5      C7      C5 */\
354         "pmaddwd %%mm3, %%mm1           \n\t" /* C7R7+C5R5      C7r7+C5r5 */\
355         "pmaddwd 64(%2), %%mm2          \n\t" /* -C7R3+C3R1     -C7r3+C3r1 */\
356         "paddd %%mm1, %%mm7             \n\t" /* B0             b0 */\
357         "movq 72(%2), %%mm1             \n\t" /* -C5    -C1     -C5     -C1 */\
358         "pmaddwd %%mm3, %%mm1           \n\t" /* -C5R7-C1R5     -C5r7-C1r5 */\
359         "paddd %%mm4, %%mm7             \n\t" /* A0+B0          a0+b0 */\
360         "paddd %%mm4, %%mm4             \n\t" /* 2A0            2a0 */\
361         "psubd %%mm7, %%mm4             \n\t" /* A0-B0          a0-b0 */\
362         "paddd %%mm2, %%mm1             \n\t" /* B1             b1 */\
363         "psrad $" #shift ", %%mm7       \n\t"\
364         "psrad $" #shift ", %%mm4       \n\t"\
365         "movq %%mm0, %%mm2              \n\t" /* A1             a1 */\
366         "paddd %%mm1, %%mm0             \n\t" /* A1+B1          a1+b1 */\
367         "psubd %%mm1, %%mm2             \n\t" /* A1-B1          a1-b1 */\
368         "psrad $" #shift ", %%mm0       \n\t"\
369         "psrad $" #shift ", %%mm2       \n\t"\
370         "packssdw %%mm7, %%mm7          \n\t" /* A0+B0  a0+b0 */\
371         "movd %%mm7, " #dst "           \n\t"\
372         "packssdw %%mm0, %%mm0          \n\t" /* A1+B1  a1+b1 */\
373         "movd %%mm0, 16+" #dst "        \n\t"\
374         "packssdw %%mm2, %%mm2          \n\t" /* A1-B1  a1-b1 */\
375         "movd %%mm2, 96+" #dst "        \n\t"\
376         "packssdw %%mm4, %%mm4          \n\t" /* A0-B0  a0-b0 */\
377         "movd %%mm4, 112+" #dst "       \n\t"\
378         "movq " #src1 ", %%mm0          \n\t" /* R3     R1      r3      r1 */\
379         "movq 80(%2), %%mm4             \n\t" /* -C1    C5      -C1     C5 */\
380         "pmaddwd %%mm0, %%mm4           \n\t" /* -C1R3+C5R1     -C1r3+C5r1 */\
381         "movq 88(%2), %%mm7             \n\t" /* C3     C7      C3      C7 */\
382         "pmaddwd 96(%2), %%mm0          \n\t" /* -C5R3+C7R1     -C5r3+C7r1 */\
383         "pmaddwd %%mm3, %%mm7           \n\t" /* C3R7+C7R5      C3r7+C7r5 */\
384         "movq %%mm5, %%mm2              \n\t" /* A2             a2 */\
385         "pmaddwd 104(%2), %%mm3         \n\t" /* -C1R7+C3R5     -C1r7+C3r5 */\
386         "paddd %%mm7, %%mm4             \n\t" /* B2             b2 */\
387         "paddd %%mm4, %%mm2             \n\t" /* A2+B2          a2+b2 */\
388         "psubd %%mm4, %%mm5             \n\t" /* a2-B2          a2-b2 */\
389         "psrad $" #shift ", %%mm2       \n\t"\
390         "psrad $" #shift ", %%mm5       \n\t"\
391         "movq %%mm6, %%mm4              \n\t" /* A3             a3 */\
392         "paddd %%mm0, %%mm3             \n\t" /* B3             b3 */\
393         "paddd %%mm3, %%mm6             \n\t" /* A3+B3          a3+b3 */\
394         "psubd %%mm3, %%mm4             \n\t" /* a3-B3          a3-b3 */\
395         "psrad $" #shift ", %%mm6       \n\t"\
396         "psrad $" #shift ", %%mm4       \n\t"\
397         "packssdw %%mm2, %%mm2          \n\t" /* A2+B2  a2+b2 */\
398         "packssdw %%mm6, %%mm6          \n\t" /* A3+B3  a3+b3 */\
399         "movd %%mm2, 32+" #dst "        \n\t"\
400         "packssdw %%mm4, %%mm4          \n\t" /* A3-B3  a3-b3 */\
401         "packssdw %%mm5, %%mm5          \n\t" /* A2-B2  a2-b2 */\
402         "movd %%mm6, 48+" #dst "        \n\t"\
403         "movd %%mm4, 64+" #dst "        \n\t"\
404         "movd %%mm5, 80+" #dst "        \n\t"
405
406
407 //IDCT(  src0,   src4,   src1,    src5,    dst, shift)
408 IDCT(    (%1), 64(%1), 32(%1),  96(%1),  0(%0), 20)
409 IDCT(   8(%1), 72(%1), 40(%1), 104(%1),  4(%0), 20)
410 IDCT(  16(%1), 80(%1), 48(%1), 112(%1),  8(%0), 20)
411 IDCT(  24(%1), 88(%1), 56(%1), 120(%1), 12(%0), 20)
412         "jmp 9f                         \n\t"
413
414         "# .p2align 4                   \n\t"\
415         "4:                             \n\t"
416 Z_COND_IDCT(  64(%0), 72(%0), 80(%0), 88(%0), 64(%1),paddd (%2), 11, 6f)
417 Z_COND_IDCT(  96(%0),104(%0),112(%0),120(%0), 96(%1),paddd (%2), 11, 5f)
418
419 #undef IDCT
420 #define IDCT(src0, src4, src1, src5, dst, shift) \
421         "movq " #src0 ", %%mm0          \n\t" /* R4     R0      r4      r0 */\
422         "movq " #src4 ", %%mm1          \n\t" /* R6     R2      r6      r2 */\
423         "movq " #src5 ", %%mm3          \n\t" /* R7     R5      r7      r5 */\
424         "movq 16(%2), %%mm4             \n\t" /* C4     C4      C4      C4 */\
425         "pmaddwd %%mm0, %%mm4           \n\t" /* C4R4+C4R0      C4r4+C4r0 */\
426         "movq 24(%2), %%mm5             \n\t" /* -C4    C4      -C4     C4 */\
427         "pmaddwd %%mm5, %%mm0           \n\t" /* -C4R4+C4R0     -C4r4+C4r0 */\
428         "movq 32(%2), %%mm5             \n\t" /* C6     C2      C6      C2 */\
429         "pmaddwd %%mm1, %%mm5           \n\t" /* C6R6+C2R2      C6r6+C2r2 */\
430         "movq 40(%2), %%mm6             \n\t" /* -C2    C6      -C2     C6 */\
431         "pmaddwd %%mm6, %%mm1           \n\t" /* -C2R6+C6R2     -C2r6+C6r2 */\
432         "movq %%mm4, %%mm6              \n\t" /* C4R4+C4R0      C4r4+C4r0 */\
433         "paddd %%mm5, %%mm4             \n\t" /* A0             a0 */\
434         "psubd %%mm5, %%mm6             \n\t" /* A3             a3 */\
435         "movq %%mm0, %%mm5              \n\t" /* -C4R4+C4R0     -C4r4+C4r0 */\
436         "paddd %%mm1, %%mm0             \n\t" /* A1             a1 */\
437         "psubd %%mm1, %%mm5             \n\t" /* A2             a2 */\
438         "movq 56(%2), %%mm1             \n\t" /* C7     C5      C7      C5 */\
439         "pmaddwd %%mm3, %%mm1           \n\t" /* C7R7+C5R5      C7r7+C5r5 */\
440         "movq 72(%2), %%mm7             \n\t" /* -C5    -C1     -C5     -C1 */\
441         "pmaddwd %%mm3, %%mm7           \n\t" /* -C5R7-C1R5     -C5r7-C1r5 */\
442         "paddd %%mm4, %%mm1             \n\t" /* A0+B0          a0+b0 */\
443         "paddd %%mm4, %%mm4             \n\t" /* 2A0            2a0 */\
444         "psubd %%mm1, %%mm4             \n\t" /* A0-B0          a0-b0 */\
445         "psrad $" #shift ", %%mm1       \n\t"\
446         "psrad $" #shift ", %%mm4       \n\t"\
447         "movq %%mm0, %%mm2              \n\t" /* A1             a1 */\
448         "paddd %%mm7, %%mm0             \n\t" /* A1+B1          a1+b1 */\
449         "psubd %%mm7, %%mm2             \n\t" /* A1-B1          a1-b1 */\
450         "psrad $" #shift ", %%mm0       \n\t"\
451         "psrad $" #shift ", %%mm2       \n\t"\
452         "packssdw %%mm1, %%mm1          \n\t" /* A0+B0  a0+b0 */\
453         "movd %%mm1, " #dst "           \n\t"\
454         "packssdw %%mm0, %%mm0          \n\t" /* A1+B1  a1+b1 */\
455         "movd %%mm0, 16+" #dst "        \n\t"\
456         "packssdw %%mm2, %%mm2          \n\t" /* A1-B1  a1-b1 */\
457         "movd %%mm2, 96+" #dst "        \n\t"\
458         "packssdw %%mm4, %%mm4          \n\t" /* A0-B0  a0-b0 */\
459         "movd %%mm4, 112+" #dst "       \n\t"\
460         "movq 88(%2), %%mm1             \n\t" /* C3     C7      C3      C7 */\
461         "pmaddwd %%mm3, %%mm1           \n\t" /* C3R7+C7R5      C3r7+C7r5 */\
462         "movq %%mm5, %%mm2              \n\t" /* A2             a2 */\
463         "pmaddwd 104(%2), %%mm3         \n\t" /* -C1R7+C3R5     -C1r7+C3r5 */\
464         "paddd %%mm1, %%mm2             \n\t" /* A2+B2          a2+b2 */\
465         "psubd %%mm1, %%mm5             \n\t" /* a2-B2          a2-b2 */\
466         "psrad $" #shift ", %%mm2       \n\t"\
467         "psrad $" #shift ", %%mm5       \n\t"\
468         "movq %%mm6, %%mm1              \n\t" /* A3             a3 */\
469         "paddd %%mm3, %%mm6             \n\t" /* A3+B3          a3+b3 */\
470         "psubd %%mm3, %%mm1             \n\t" /* a3-B3          a3-b3 */\
471         "psrad $" #shift ", %%mm6       \n\t"\
472         "psrad $" #shift ", %%mm1       \n\t"\
473         "packssdw %%mm2, %%mm2          \n\t" /* A2+B2  a2+b2 */\
474         "packssdw %%mm6, %%mm6          \n\t" /* A3+B3  a3+b3 */\
475         "movd %%mm2, 32+" #dst "        \n\t"\
476         "packssdw %%mm1, %%mm1          \n\t" /* A3-B3  a3-b3 */\
477         "packssdw %%mm5, %%mm5          \n\t" /* A2-B2  a2-b2 */\
478         "movd %%mm6, 48+" #dst "        \n\t"\
479         "movd %%mm1, 64+" #dst "        \n\t"\
480         "movd %%mm5, 80+" #dst "        \n\t"
481
482 //IDCT(  src0,   src4,   src1,    src5,    dst, shift)
483 IDCT(    (%1), 64(%1), 32(%1),  96(%1),  0(%0), 20)
484 IDCT(   8(%1), 72(%1), 40(%1), 104(%1),  4(%0), 20)
485 IDCT(  16(%1), 80(%1), 48(%1), 112(%1),  8(%0), 20)
486 IDCT(  24(%1), 88(%1), 56(%1), 120(%1), 12(%0), 20)
487         "jmp 9f                         \n\t"
488
489         "# .p2align 4                   \n\t"\
490         "6:                             \n\t"
491 Z_COND_IDCT(  96(%0),104(%0),112(%0),120(%0), 96(%1),paddd (%2), 11, 7f)
492
493 #undef IDCT
494 #define IDCT(src0, src4, src1, src5, dst, shift) \
495         "movq " #src0 ", %%mm0          \n\t" /* R4     R0      r4      r0 */\
496         "movq " #src5 ", %%mm3          \n\t" /* R7     R5      r7      r5 */\
497         "movq 16(%2), %%mm4             \n\t" /* C4     C4      C4      C4 */\
498         "pmaddwd %%mm0, %%mm4           \n\t" /* C4R4+C4R0      C4r4+C4r0 */\
499         "movq 24(%2), %%mm5             \n\t" /* -C4    C4      -C4     C4 */\
500         "pmaddwd %%mm5, %%mm0           \n\t" /* -C4R4+C4R0     -C4r4+C4r0 */\
501         "movq %%mm4, %%mm6              \n\t" /* C4R4+C4R0      C4r4+C4r0 */\
502         "movq %%mm0, %%mm5              \n\t" /* -C4R4+C4R0     -C4r4+C4r0 */\
503         "movq 56(%2), %%mm1             \n\t" /* C7     C5      C7      C5 */\
504         "pmaddwd %%mm3, %%mm1           \n\t" /* C7R7+C5R5      C7r7+C5r5 */\
505         "movq 72(%2), %%mm7             \n\t" /* -C5    -C1     -C5     -C1 */\
506         "pmaddwd %%mm3, %%mm7           \n\t" /* -C5R7-C1R5     -C5r7-C1r5 */\
507         "paddd %%mm4, %%mm1             \n\t" /* A0+B0          a0+b0 */\
508         "paddd %%mm4, %%mm4             \n\t" /* 2A0            2a0 */\
509         "psubd %%mm1, %%mm4             \n\t" /* A0-B0          a0-b0 */\
510         "psrad $" #shift ", %%mm1       \n\t"\
511         "psrad $" #shift ", %%mm4       \n\t"\
512         "movq %%mm0, %%mm2              \n\t" /* A1             a1 */\
513         "paddd %%mm7, %%mm0             \n\t" /* A1+B1          a1+b1 */\
514         "psubd %%mm7, %%mm2             \n\t" /* A1-B1          a1-b1 */\
515         "psrad $" #shift ", %%mm0       \n\t"\
516         "psrad $" #shift ", %%mm2       \n\t"\
517         "packssdw %%mm1, %%mm1          \n\t" /* A0+B0  a0+b0 */\
518         "movd %%mm1, " #dst "           \n\t"\
519         "packssdw %%mm0, %%mm0          \n\t" /* A1+B1  a1+b1 */\
520         "movd %%mm0, 16+" #dst "        \n\t"\
521         "packssdw %%mm2, %%mm2          \n\t" /* A1-B1  a1-b1 */\
522         "movd %%mm2, 96+" #dst "        \n\t"\
523         "packssdw %%mm4, %%mm4          \n\t" /* A0-B0  a0-b0 */\
524         "movd %%mm4, 112+" #dst "       \n\t"\
525         "movq 88(%2), %%mm1             \n\t" /* C3     C7      C3      C7 */\
526         "pmaddwd %%mm3, %%mm1           \n\t" /* C3R7+C7R5      C3r7+C7r5 */\
527         "movq %%mm5, %%mm2              \n\t" /* A2             a2 */\
528         "pmaddwd 104(%2), %%mm3         \n\t" /* -C1R7+C3R5     -C1r7+C3r5 */\
529         "paddd %%mm1, %%mm2             \n\t" /* A2+B2          a2+b2 */\
530         "psubd %%mm1, %%mm5             \n\t" /* a2-B2          a2-b2 */\
531         "psrad $" #shift ", %%mm2       \n\t"\
532         "psrad $" #shift ", %%mm5       \n\t"\
533         "movq %%mm6, %%mm1              \n\t" /* A3             a3 */\
534         "paddd %%mm3, %%mm6             \n\t" /* A3+B3          a3+b3 */\
535         "psubd %%mm3, %%mm1             \n\t" /* a3-B3          a3-b3 */\
536         "psrad $" #shift ", %%mm6       \n\t"\
537         "psrad $" #shift ", %%mm1       \n\t"\
538         "packssdw %%mm2, %%mm2          \n\t" /* A2+B2  a2+b2 */\
539         "packssdw %%mm6, %%mm6          \n\t" /* A3+B3  a3+b3 */\
540         "movd %%mm2, 32+" #dst "        \n\t"\
541         "packssdw %%mm1, %%mm1          \n\t" /* A3-B3  a3-b3 */\
542         "packssdw %%mm5, %%mm5          \n\t" /* A2-B2  a2-b2 */\
543         "movd %%mm6, 48+" #dst "        \n\t"\
544         "movd %%mm1, 64+" #dst "        \n\t"\
545         "movd %%mm5, 80+" #dst "        \n\t"
546
547
548 //IDCT(  src0,   src4,   src1,    src5,    dst, shift)
549 IDCT(    (%1), 64(%1), 32(%1),  96(%1),  0(%0), 20)
550 IDCT(   8(%1), 72(%1), 40(%1), 104(%1),  4(%0), 20)
551 IDCT(  16(%1), 80(%1), 48(%1), 112(%1),  8(%0), 20)
552 IDCT(  24(%1), 88(%1), 56(%1), 120(%1), 12(%0), 20)
553         "jmp 9f                         \n\t"
554
555         "# .p2align 4                   \n\t"\
556         "2:                             \n\t"
557 Z_COND_IDCT(  96(%0),104(%0),112(%0),120(%0), 96(%1),paddd (%2), 11, 3f)
558
559 #undef IDCT
560 #define IDCT(src0, src4, src1, src5, dst, shift) \
561         "movq " #src0 ", %%mm0          \n\t" /* R4     R0      r4      r0 */\
562         "movq " #src1 ", %%mm2          \n\t" /* R3     R1      r3      r1 */\
563         "movq " #src5 ", %%mm3          \n\t" /* R7     R5      r7      r5 */\
564         "movq 16(%2), %%mm4             \n\t" /* C4     C4      C4      C4 */\
565         "pmaddwd %%mm0, %%mm4           \n\t" /* C4R4+C4R0      C4r4+C4r0 */\
566         "movq 24(%2), %%mm5             \n\t" /* -C4    C4      -C4     C4 */\
567         "pmaddwd %%mm5, %%mm0           \n\t" /* -C4R4+C4R0     -C4r4+C4r0 */\
568         "movq %%mm4, %%mm6              \n\t" /* C4R4+C4R0      C4r4+C4r0 */\
569         "movq 48(%2), %%mm7             \n\t" /* C3     C1      C3      C1 */\
570         "pmaddwd %%mm2, %%mm7           \n\t" /* C3R3+C1R1      C3r3+C1r1 */\
571         "movq %%mm0, %%mm5              \n\t" /* -C4R4+C4R0     -C4r4+C4r0 */\
572         "movq 56(%2), %%mm1             \n\t" /* C7     C5      C7      C5 */\
573         "pmaddwd %%mm3, %%mm1           \n\t" /* C7R7+C5R5      C7r7+C5r5 */\
574         "pmaddwd 64(%2), %%mm2          \n\t" /* -C7R3+C3R1     -C7r3+C3r1 */\
575         "paddd %%mm1, %%mm7             \n\t" /* B0             b0 */\
576         "movq 72(%2), %%mm1             \n\t" /* -C5    -C1     -C5     -C1 */\
577         "pmaddwd %%mm3, %%mm1           \n\t" /* -C5R7-C1R5     -C5r7-C1r5 */\
578         "paddd %%mm4, %%mm7             \n\t" /* A0+B0          a0+b0 */\
579         "paddd %%mm4, %%mm4             \n\t" /* 2A0            2a0 */\
580         "psubd %%mm7, %%mm4             \n\t" /* A0-B0          a0-b0 */\
581         "paddd %%mm2, %%mm1             \n\t" /* B1             b1 */\
582         "psrad $" #shift ", %%mm7       \n\t"\
583         "psrad $" #shift ", %%mm4       \n\t"\
584         "movq %%mm0, %%mm2              \n\t" /* A1             a1 */\
585         "paddd %%mm1, %%mm0             \n\t" /* A1+B1          a1+b1 */\
586         "psubd %%mm1, %%mm2             \n\t" /* A1-B1          a1-b1 */\
587         "psrad $" #shift ", %%mm0       \n\t"\
588         "psrad $" #shift ", %%mm2       \n\t"\
589         "packssdw %%mm7, %%mm7          \n\t" /* A0+B0  a0+b0 */\
590         "movd %%mm7, " #dst "           \n\t"\
591         "packssdw %%mm0, %%mm0          \n\t" /* A1+B1  a1+b1 */\
592         "movd %%mm0, 16+" #dst "        \n\t"\
593         "packssdw %%mm2, %%mm2          \n\t" /* A1-B1  a1-b1 */\
594         "movd %%mm2, 96+" #dst "        \n\t"\
595         "packssdw %%mm4, %%mm4          \n\t" /* A0-B0  a0-b0 */\
596         "movd %%mm4, 112+" #dst "       \n\t"\
597         "movq " #src1 ", %%mm0          \n\t" /* R3     R1      r3      r1 */\
598         "movq 80(%2), %%mm4             \n\t" /* -C1    C5      -C1     C5 */\
599         "pmaddwd %%mm0, %%mm4           \n\t" /* -C1R3+C5R1     -C1r3+C5r1 */\
600         "movq 88(%2), %%mm7             \n\t" /* C3     C7      C3      C7 */\
601         "pmaddwd 96(%2), %%mm0          \n\t" /* -C5R3+C7R1     -C5r3+C7r1 */\
602         "pmaddwd %%mm3, %%mm7           \n\t" /* C3R7+C7R5      C3r7+C7r5 */\
603         "movq %%mm5, %%mm2              \n\t" /* A2             a2 */\
604         "pmaddwd 104(%2), %%mm3         \n\t" /* -C1R7+C3R5     -C1r7+C3r5 */\
605         "paddd %%mm7, %%mm4             \n\t" /* B2             b2 */\
606         "paddd %%mm4, %%mm2             \n\t" /* A2+B2          a2+b2 */\
607         "psubd %%mm4, %%mm5             \n\t" /* a2-B2          a2-b2 */\
608         "psrad $" #shift ", %%mm2       \n\t"\
609         "psrad $" #shift ", %%mm5       \n\t"\
610         "movq %%mm6, %%mm4              \n\t" /* A3             a3 */\
611         "paddd %%mm0, %%mm3             \n\t" /* B3             b3 */\
612         "paddd %%mm3, %%mm6             \n\t" /* A3+B3          a3+b3 */\
613         "psubd %%mm3, %%mm4             \n\t" /* a3-B3          a3-b3 */\
614         "psrad $" #shift ", %%mm6       \n\t"\
615         "psrad $" #shift ", %%mm4       \n\t"\
616         "packssdw %%mm2, %%mm2          \n\t" /* A2+B2  a2+b2 */\
617         "packssdw %%mm6, %%mm6          \n\t" /* A3+B3  a3+b3 */\
618         "movd %%mm2, 32+" #dst "        \n\t"\
619         "packssdw %%mm4, %%mm4          \n\t" /* A3-B3  a3-b3 */\
620         "packssdw %%mm5, %%mm5          \n\t" /* A2-B2  a2-b2 */\
621         "movd %%mm6, 48+" #dst "        \n\t"\
622         "movd %%mm4, 64+" #dst "        \n\t"\
623         "movd %%mm5, 80+" #dst "        \n\t"
624
625 //IDCT(  src0,   src4,   src1,    src5,    dst, shift)
626 IDCT(    (%1), 64(%1), 32(%1),  96(%1),  0(%0), 20)
627 IDCT(   8(%1), 72(%1), 40(%1), 104(%1),  4(%0), 20)
628 IDCT(  16(%1), 80(%1), 48(%1), 112(%1),  8(%0), 20)
629 IDCT(  24(%1), 88(%1), 56(%1), 120(%1), 12(%0), 20)
630         "jmp 9f                         \n\t"
631
632         "# .p2align 4                   \n\t"\
633         "3:                             \n\t"
634 #undef IDCT
635 #define IDCT(src0, src4, src1, src5, dst, shift) \
636         "movq " #src0 ", %%mm0          \n\t" /* R4     R0      r4      r0 */\
637         "movq " #src1 ", %%mm2          \n\t" /* R3     R1      r3      r1 */\
638         "movq 16(%2), %%mm4             \n\t" /* C4     C4      C4      C4 */\
639         "pmaddwd %%mm0, %%mm4           \n\t" /* C4R4+C4R0      C4r4+C4r0 */\
640         "movq 24(%2), %%mm5             \n\t" /* -C4    C4      -C4     C4 */\
641         "pmaddwd %%mm5, %%mm0           \n\t" /* -C4R4+C4R0     -C4r4+C4r0 */\
642         "movq %%mm4, %%mm6              \n\t" /* C4R4+C4R0      C4r4+C4r0 */\
643         "movq 48(%2), %%mm7             \n\t" /* C3     C1      C3      C1 */\
644         "pmaddwd %%mm2, %%mm7           \n\t" /* C3R3+C1R1      C3r3+C1r1 */\
645         "movq %%mm0, %%mm5              \n\t" /* -C4R4+C4R0     -C4r4+C4r0 */\
646         "movq 64(%2), %%mm3             \n\t"\
647         "pmaddwd %%mm2, %%mm3           \n\t" /* -C7R3+C3R1     -C7r3+C3r1 */\
648         "paddd %%mm4, %%mm7             \n\t" /* A0+B0          a0+b0 */\
649         "paddd %%mm4, %%mm4             \n\t" /* 2A0            2a0 */\
650         "psubd %%mm7, %%mm4             \n\t" /* A0-B0          a0-b0 */\
651         "psrad $" #shift ", %%mm7       \n\t"\
652         "psrad $" #shift ", %%mm4       \n\t"\
653         "movq %%mm0, %%mm1              \n\t" /* A1             a1 */\
654         "paddd %%mm3, %%mm0             \n\t" /* A1+B1          a1+b1 */\
655         "psubd %%mm3, %%mm1             \n\t" /* A1-B1          a1-b1 */\
656         "psrad $" #shift ", %%mm0       \n\t"\
657         "psrad $" #shift ", %%mm1       \n\t"\
658         "packssdw %%mm7, %%mm7          \n\t" /* A0+B0  a0+b0 */\
659         "movd %%mm7, " #dst "           \n\t"\
660         "packssdw %%mm0, %%mm0          \n\t" /* A1+B1  a1+b1 */\
661         "movd %%mm0, 16+" #dst "        \n\t"\
662         "packssdw %%mm1, %%mm1          \n\t" /* A1-B1  a1-b1 */\
663         "movd %%mm1, 96+" #dst "        \n\t"\
664         "packssdw %%mm4, %%mm4          \n\t" /* A0-B0  a0-b0 */\
665         "movd %%mm4, 112+" #dst "       \n\t"\
666         "movq 80(%2), %%mm4             \n\t" /* -C1    C5      -C1     C5 */\
667         "pmaddwd %%mm2, %%mm4           \n\t" /* -C1R3+C5R1     -C1r3+C5r1 */\
668         "pmaddwd 96(%2), %%mm2          \n\t" /* -C5R3+C7R1     -C5r3+C7r1 */\
669         "movq %%mm5, %%mm1              \n\t" /* A2             a2 */\
670         "paddd %%mm4, %%mm1             \n\t" /* A2+B2          a2+b2 */\
671         "psubd %%mm4, %%mm5             \n\t" /* a2-B2          a2-b2 */\
672         "psrad $" #shift ", %%mm1       \n\t"\
673         "psrad $" #shift ", %%mm5       \n\t"\
674         "movq %%mm6, %%mm4              \n\t" /* A3             a3 */\
675         "paddd %%mm2, %%mm6             \n\t" /* A3+B3          a3+b3 */\
676         "psubd %%mm2, %%mm4             \n\t" /* a3-B3          a3-b3 */\
677         "psrad $" #shift ", %%mm6       \n\t"\
678         "psrad $" #shift ", %%mm4       \n\t"\
679         "packssdw %%mm1, %%mm1          \n\t" /* A2+B2  a2+b2 */\
680         "packssdw %%mm6, %%mm6          \n\t" /* A3+B3  a3+b3 */\
681         "movd %%mm1, 32+" #dst "        \n\t"\
682         "packssdw %%mm4, %%mm4          \n\t" /* A3-B3  a3-b3 */\
683         "packssdw %%mm5, %%mm5          \n\t" /* A2-B2  a2-b2 */\
684         "movd %%mm6, 48+" #dst "        \n\t"\
685         "movd %%mm4, 64+" #dst "        \n\t"\
686         "movd %%mm5, 80+" #dst "        \n\t"
687
688
689 //IDCT(  src0,   src4,   src1,    src5,    dst, shift)
690 IDCT(    (%1), 64(%1), 32(%1),  96(%1),  0(%0), 20)
691 IDCT(   8(%1), 72(%1), 40(%1), 104(%1),  4(%0), 20)
692 IDCT(  16(%1), 80(%1), 48(%1), 112(%1),  8(%0), 20)
693 IDCT(  24(%1), 88(%1), 56(%1), 120(%1), 12(%0), 20)
694         "jmp 9f                         \n\t"
695
696         "# .p2align 4                   \n\t"\
697         "5:                             \n\t"
698 #undef IDCT
699 #define IDCT(src0, src4, src1, src5, dst, shift) \
700         "movq " #src0 ", %%mm0          \n\t" /* R4     R0      r4      r0 */\
701         "movq " #src4 ", %%mm1          \n\t" /* R6     R2      r6      r2 */\
702         "movq 16(%2), %%mm4             \n\t" /* C4     C4      C4      C4 */\
703         "pmaddwd %%mm0, %%mm4           \n\t" /* C4R4+C4R0      C4r4+C4r0 */\
704         "movq 24(%2), %%mm5             \n\t" /* -C4    C4      -C4     C4 */\
705         "pmaddwd %%mm5, %%mm0           \n\t" /* -C4R4+C4R0     -C4r4+C4r0 */\
706         "movq 32(%2), %%mm5             \n\t" /* C6     C2      C6      C2 */\
707         "pmaddwd %%mm1, %%mm5           \n\t" /* C6R6+C2R2      C6r6+C2r2 */\
708         "movq 40(%2), %%mm6             \n\t" /* -C2    C6      -C2     C6 */\
709         "pmaddwd %%mm6, %%mm1           \n\t" /* -C2R6+C6R2     -C2r6+C6r2 */\
710         "movq %%mm4, %%mm6              \n\t" /* C4R4+C4R0      C4r4+C4r0 */\
711         "paddd %%mm5, %%mm4             \n\t" /* A0             a0 */\
712         "psubd %%mm5, %%mm6             \n\t" /* A3             a3 */\
713         "movq %%mm0, %%mm5              \n\t" /* -C4R4+C4R0     -C4r4+C4r0 */\
714         "paddd %%mm1, %%mm0             \n\t" /* A1             a1 */\
715         "psubd %%mm1, %%mm5             \n\t" /* A2             a2 */\
716         "movq 8+" #src0 ", %%mm2        \n\t" /* R4     R0      r4      r0 */\
717         "movq 8+" #src4 ", %%mm3        \n\t" /* R6     R2      r6      r2 */\
718         "movq 16(%2), %%mm1             \n\t" /* C4     C4      C4      C4 */\
719         "pmaddwd %%mm2, %%mm1           \n\t" /* C4R4+C4R0      C4r4+C4r0 */\
720         "movq 24(%2), %%mm7             \n\t" /* -C4    C4      -C4     C4 */\
721         "pmaddwd %%mm7, %%mm2           \n\t" /* -C4R4+C4R0     -C4r4+C4r0 */\
722         "movq 32(%2), %%mm7             \n\t" /* C6     C2      C6      C2 */\
723         "pmaddwd %%mm3, %%mm7           \n\t" /* C6R6+C2R2      C6r6+C2r2 */\
724         "pmaddwd 40(%2), %%mm3          \n\t" /* -C2R6+C6R2     -C2r6+C6r2 */\
725         "paddd %%mm1, %%mm7             \n\t" /* A0             a0 */\
726         "paddd %%mm1, %%mm1             \n\t" /* 2C0            2c0 */\
727         "psubd %%mm7, %%mm1             \n\t" /* A3             a3 */\
728         "paddd %%mm2, %%mm3             \n\t" /* A1             a1 */\
729         "paddd %%mm2, %%mm2             \n\t" /* 2C1            2c1 */\
730         "psubd %%mm3, %%mm2             \n\t" /* A2             a2 */\
731         "psrad $" #shift ", %%mm4       \n\t"\
732         "psrad $" #shift ", %%mm7       \n\t"\
733         "psrad $" #shift ", %%mm3       \n\t"\
734         "packssdw %%mm7, %%mm4          \n\t" /* A0     a0 */\
735         "movq %%mm4, " #dst "           \n\t"\
736         "psrad $" #shift ", %%mm0       \n\t"\
737         "packssdw %%mm3, %%mm0          \n\t" /* A1     a1 */\
738         "movq %%mm0, 16+" #dst "        \n\t"\
739         "movq %%mm0, 96+" #dst "        \n\t"\
740         "movq %%mm4, 112+" #dst "       \n\t"\
741         "psrad $" #shift ", %%mm5       \n\t"\
742         "psrad $" #shift ", %%mm6       \n\t"\
743         "psrad $" #shift ", %%mm2       \n\t"\
744         "packssdw %%mm2, %%mm5          \n\t" /* A2-B2  a2-b2 */\
745         "movq %%mm5, 32+" #dst "        \n\t"\
746         "psrad $" #shift ", %%mm1       \n\t"\
747         "packssdw %%mm1, %%mm6          \n\t" /* A3+B3  a3+b3 */\
748         "movq %%mm6, 48+" #dst "        \n\t"\
749         "movq %%mm6, 64+" #dst "        \n\t"\
750         "movq %%mm5, 80+" #dst "        \n\t"
751
752
753 //IDCT(  src0,   src4,   src1,    src5,    dst, shift)
754 IDCT(    0(%1), 64(%1), 32(%1),  96(%1),  0(%0), 20)
755 //IDCT(   8(%1), 72(%1), 40(%1), 104(%1),  4(%0), 20)
756 IDCT(  16(%1), 80(%1), 48(%1), 112(%1),  8(%0), 20)
757 //IDCT(  24(%1), 88(%1), 56(%1), 120(%1), 12(%0), 20)
758         "jmp 9f                         \n\t"
759
760
761         "# .p2align 4                   \n\t"\
762         "1:                             \n\t"
763 #undef IDCT
764 #define IDCT(src0, src4, src1, src5, dst, shift) \
765         "movq " #src0 ", %%mm0          \n\t" /* R4     R0      r4      r0 */\
766         "movq " #src4 ", %%mm1          \n\t" /* R6     R2      r6      r2 */\
767         "movq " #src1 ", %%mm2          \n\t" /* R3     R1      r3      r1 */\
768         "movq 16(%2), %%mm4             \n\t" /* C4     C4      C4      C4 */\
769         "pmaddwd %%mm0, %%mm4           \n\t" /* C4R4+C4R0      C4r4+C4r0 */\
770         "movq 24(%2), %%mm5             \n\t" /* -C4    C4      -C4     C4 */\
771         "pmaddwd %%mm5, %%mm0           \n\t" /* -C4R4+C4R0     -C4r4+C4r0 */\
772         "movq 32(%2), %%mm5             \n\t" /* C6     C2      C6      C2 */\
773         "pmaddwd %%mm1, %%mm5           \n\t" /* C6R6+C2R2      C6r6+C2r2 */\
774         "movq 40(%2), %%mm6             \n\t" /* -C2    C6      -C2     C6 */\
775         "pmaddwd %%mm6, %%mm1           \n\t" /* -C2R6+C6R2     -C2r6+C6r2 */\
776         "movq %%mm4, %%mm6              \n\t" /* C4R4+C4R0      C4r4+C4r0 */\
777         "movq 48(%2), %%mm7             \n\t" /* C3     C1      C3      C1 */\
778         "pmaddwd %%mm2, %%mm7           \n\t" /* C3R3+C1R1      C3r3+C1r1 */\
779         "paddd %%mm5, %%mm4             \n\t" /* A0             a0 */\
780         "psubd %%mm5, %%mm6             \n\t" /* A3             a3 */\
781         "movq %%mm0, %%mm5              \n\t" /* -C4R4+C4R0     -C4r4+C4r0 */\
782         "paddd %%mm1, %%mm0             \n\t" /* A1             a1 */\
783         "psubd %%mm1, %%mm5             \n\t" /* A2             a2 */\
784         "movq 64(%2), %%mm1             \n\t"\
785         "pmaddwd %%mm2, %%mm1           \n\t" /* -C7R3+C3R1     -C7r3+C3r1 */\
786         "paddd %%mm4, %%mm7             \n\t" /* A0+B0          a0+b0 */\
787         "paddd %%mm4, %%mm4             \n\t" /* 2A0            2a0 */\
788         "psubd %%mm7, %%mm4             \n\t" /* A0-B0          a0-b0 */\
789         "psrad $" #shift ", %%mm7       \n\t"\
790         "psrad $" #shift ", %%mm4       \n\t"\
791         "movq %%mm0, %%mm3              \n\t" /* A1             a1 */\
792         "paddd %%mm1, %%mm0             \n\t" /* A1+B1          a1+b1 */\
793         "psubd %%mm1, %%mm3             \n\t" /* A1-B1          a1-b1 */\
794         "psrad $" #shift ", %%mm0       \n\t"\
795         "psrad $" #shift ", %%mm3       \n\t"\
796         "packssdw %%mm7, %%mm7          \n\t" /* A0+B0  a0+b0 */\
797         "movd %%mm7, " #dst "           \n\t"\
798         "packssdw %%mm0, %%mm0          \n\t" /* A1+B1  a1+b1 */\
799         "movd %%mm0, 16+" #dst "        \n\t"\
800         "packssdw %%mm3, %%mm3          \n\t" /* A1-B1  a1-b1 */\
801         "movd %%mm3, 96+" #dst "        \n\t"\
802         "packssdw %%mm4, %%mm4          \n\t" /* A0-B0  a0-b0 */\
803         "movd %%mm4, 112+" #dst "       \n\t"\
804         "movq 80(%2), %%mm4             \n\t" /* -C1    C5      -C1     C5 */\
805         "pmaddwd %%mm2, %%mm4           \n\t" /* -C1R3+C5R1     -C1r3+C5r1 */\
806         "pmaddwd 96(%2), %%mm2          \n\t" /* -C5R3+C7R1     -C5r3+C7r1 */\
807         "movq %%mm5, %%mm3              \n\t" /* A2             a2 */\
808         "paddd %%mm4, %%mm3             \n\t" /* A2+B2          a2+b2 */\
809         "psubd %%mm4, %%mm5             \n\t" /* a2-B2          a2-b2 */\
810         "psrad $" #shift ", %%mm3       \n\t"\
811         "psrad $" #shift ", %%mm5       \n\t"\
812         "movq %%mm6, %%mm4              \n\t" /* A3             a3 */\
813         "paddd %%mm2, %%mm6             \n\t" /* A3+B3          a3+b3 */\
814         "psubd %%mm2, %%mm4             \n\t" /* a3-B3          a3-b3 */\
815         "psrad $" #shift ", %%mm6       \n\t"\
816         "packssdw %%mm3, %%mm3          \n\t" /* A2+B2  a2+b2 */\
817         "movd %%mm3, 32+" #dst "        \n\t"\
818         "psrad $" #shift ", %%mm4       \n\t"\
819         "packssdw %%mm6, %%mm6          \n\t" /* A3+B3  a3+b3 */\
820         "movd %%mm6, 48+" #dst "        \n\t"\
821         "packssdw %%mm4, %%mm4          \n\t" /* A3-B3  a3-b3 */\
822         "packssdw %%mm5, %%mm5          \n\t" /* A2-B2  a2-b2 */\
823         "movd %%mm4, 64+" #dst "        \n\t"\
824         "movd %%mm5, 80+" #dst "        \n\t"
825
826
827 //IDCT(  src0,   src4,   src1,    src5,    dst, shift)
828 IDCT(    (%1), 64(%1), 32(%1),  96(%1),  0(%0), 20)
829 IDCT(   8(%1), 72(%1), 40(%1), 104(%1),  4(%0), 20)
830 IDCT(  16(%1), 80(%1), 48(%1), 112(%1),  8(%0), 20)
831 IDCT(  24(%1), 88(%1), 56(%1), 120(%1), 12(%0), 20)
832         "jmp 9f                         \n\t"
833
834
835         "# .p2align 4                   \n\t"
836         "7:                             \n\t"
837 #undef IDCT
838 #define IDCT(src0, src4, src1, src5, dst, shift) \
839         "movq " #src0 ", %%mm0          \n\t" /* R4     R0      r4      r0 */\
840         "movq 16(%2), %%mm4             \n\t" /* C4     C4      C4      C4 */\
841         "pmaddwd %%mm0, %%mm4           \n\t" /* C4R4+C4R0      C4r4+C4r0 */\
842         "movq 24(%2), %%mm5             \n\t" /* -C4    C4      -C4     C4 */\
843         "pmaddwd %%mm5, %%mm0           \n\t" /* -C4R4+C4R0     -C4r4+C4r0 */\
844         "psrad $" #shift ", %%mm4       \n\t"\
845         "psrad $" #shift ", %%mm0       \n\t"\
846         "movq 8+" #src0 ", %%mm2        \n\t" /* R4     R0      r4      r0 */\
847         "movq 16(%2), %%mm1             \n\t" /* C4     C4      C4      C4 */\
848         "pmaddwd %%mm2, %%mm1           \n\t" /* C4R4+C4R0      C4r4+C4r0 */\
849         "movq 24(%2), %%mm7             \n\t" /* -C4    C4      -C4     C4 */\
850         "pmaddwd %%mm7, %%mm2           \n\t" /* -C4R4+C4R0     -C4r4+C4r0 */\
851         "movq 32(%2), %%mm7             \n\t" /* C6     C2      C6      C2 */\
852         "psrad $" #shift ", %%mm1       \n\t"\
853         "packssdw %%mm1, %%mm4          \n\t" /* A0     a0 */\
854         "movq %%mm4, " #dst "           \n\t"\
855         "psrad $" #shift ", %%mm2       \n\t"\
856         "packssdw %%mm2, %%mm0          \n\t" /* A1     a1 */\
857         "movq %%mm0, 16+" #dst "        \n\t"\
858         "movq %%mm0, 96+" #dst "        \n\t"\
859         "movq %%mm4, 112+" #dst "       \n\t"\
860         "movq %%mm0, 32+" #dst "        \n\t"\
861         "movq %%mm4, 48+" #dst "        \n\t"\
862         "movq %%mm4, 64+" #dst "        \n\t"\
863         "movq %%mm0, 80+" #dst "        \n\t"
864
865 //IDCT(  src0,   src4,   src1,    src5,    dst, shift)
866 IDCT(   0(%1), 64(%1), 32(%1),  96(%1),  0(%0), 20)
867 //IDCT(   8(%1), 72(%1), 40(%1), 104(%1),  4(%0), 20)
868 IDCT(  16(%1), 80(%1), 48(%1), 112(%1),  8(%0), 20)
869 //IDCT(  24(%1), 88(%1), 56(%1), 120(%1), 12(%0), 20)
870
871
872 /*
873 Input
874  00 40 04 44 20 60 24 64
875  10 30 14 34 50 70 54 74
876  01 41 03 43 21 61 23 63
877  11 31 13 33 51 71 53 73
878  02 42 06 46 22 62 26 66
879  12 32 16 36 52 72 56 76
880  05 45 07 47 25 65 27 67
881  15 35 17 37 55 75 57 77
882
883 Temp
884  00 04 10 14 20 24 30 34
885  40 44 50 54 60 64 70 74
886  01 03 11 13 21 23 31 33
887  41 43 51 53 61 63 71 73
888  02 06 12 16 22 26 32 36
889  42 46 52 56 62 66 72 76
890  05 07 15 17 25 27 35 37
891  45 47 55 57 65 67 75 77
892 */
893
894 "9: \n\t"
895                 :: "r" (block), "r" (temp), "r" (coeffs)
896                    NAMED_CONSTRAINTS_ADD(wm1010,d40000)
897                 : "%eax"
898         );
899 }
900
901 void ff_simple_idct_mmx(int16_t *block)
902 {
903     idct(block);
904 }
905
906 //FIXME merge add/put into the idct
907
908 void ff_simple_idct_put_mmx(uint8_t *dest, ptrdiff_t line_size, int16_t *block)
909 {
910     idct(block);
911     ff_put_pixels_clamped_mmx(block, dest, line_size);
912 }
913 void ff_simple_idct_add_mmx(uint8_t *dest, ptrdiff_t line_size, int16_t *block)
914 {
915     idct(block);
916     ff_add_pixels_clamped_mmx(block, dest, line_size);
917 }
918 void ff_simple_idct_put_sse2(uint8_t *dest, ptrdiff_t line_size, int16_t *block)
919 {
920     idct(block);
921     ff_put_pixels_clamped_sse2(block, dest, line_size);
922 }
923 void ff_simple_idct_add_sse2(uint8_t *dest, ptrdiff_t line_size, int16_t *block)
924 {
925     idct(block);
926     ff_add_pixels_clamped_sse2(block, dest, line_size);
927 }
928
929 #endif /* HAVE_INLINE_ASM */