Imported Upstream version 1.3.1
[platform/upstream/libjpeg-turbo.git] / simd / jfss2int-64.asm
1 ;
2 ; jfss2int-64.asm - accurate integer FDCT (64-bit SSE2)
3 ;
4 ; Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB
5 ; Copyright 2009 D. R. Commander
6 ;
7 ; Based on
8 ; x86 SIMD extension for IJG JPEG library
9 ; Copyright (C) 1999-2006, MIYASAKA Masaru.
10 ; For conditions of distribution and use, see copyright notice in jsimdext.inc
11 ;
12 ; This file should be assembled with NASM (Netwide Assembler),
13 ; can *not* be assembled with Microsoft's MASM or any compatible
14 ; assembler (including Borland's Turbo Assembler).
15 ; NASM is available from http://nasm.sourceforge.net/ or
16 ; http://sourceforge.net/project/showfiles.php?group_id=6208
17 ;
18 ; This file contains a slow-but-accurate integer implementation of the
19 ; forward DCT (Discrete Cosine Transform). The following code is based
20 ; directly on the IJG's original jfdctint.c; see the jfdctint.c for
21 ; more details.
22 ;
23 ; [TAB8]
24
25 %include "jsimdext.inc"
26 %include "jdct.inc"
27
28 ; --------------------------------------------------------------------------
29
30 %define CONST_BITS      13
31 %define PASS1_BITS      2
32
33 %define DESCALE_P1      (CONST_BITS-PASS1_BITS)
34 %define DESCALE_P2      (CONST_BITS+PASS1_BITS)
35
36 %if CONST_BITS == 13
37 F_0_298 equ      2446           ; FIX(0.298631336)
38 F_0_390 equ      3196           ; FIX(0.390180644)
39 F_0_541 equ      4433           ; FIX(0.541196100)
40 F_0_765 equ      6270           ; FIX(0.765366865)
41 F_0_899 equ      7373           ; FIX(0.899976223)
42 F_1_175 equ      9633           ; FIX(1.175875602)
43 F_1_501 equ     12299           ; FIX(1.501321110)
44 F_1_847 equ     15137           ; FIX(1.847759065)
45 F_1_961 equ     16069           ; FIX(1.961570560)
46 F_2_053 equ     16819           ; FIX(2.053119869)
47 F_2_562 equ     20995           ; FIX(2.562915447)
48 F_3_072 equ     25172           ; FIX(3.072711026)
49 %else
50 ; NASM cannot do compile-time arithmetic on floating-point constants.
51 %define DESCALE(x,n)  (((x)+(1<<((n)-1)))>>(n))
52 F_0_298 equ     DESCALE( 320652955,30-CONST_BITS)       ; FIX(0.298631336)
53 F_0_390 equ     DESCALE( 418953276,30-CONST_BITS)       ; FIX(0.390180644)
54 F_0_541 equ     DESCALE( 581104887,30-CONST_BITS)       ; FIX(0.541196100)
55 F_0_765 equ     DESCALE( 821806413,30-CONST_BITS)       ; FIX(0.765366865)
56 F_0_899 equ     DESCALE( 966342111,30-CONST_BITS)       ; FIX(0.899976223)
57 F_1_175 equ     DESCALE(1262586813,30-CONST_BITS)       ; FIX(1.175875602)
58 F_1_501 equ     DESCALE(1612031267,30-CONST_BITS)       ; FIX(1.501321110)
59 F_1_847 equ     DESCALE(1984016188,30-CONST_BITS)       ; FIX(1.847759065)
60 F_1_961 equ     DESCALE(2106220350,30-CONST_BITS)       ; FIX(1.961570560)
61 F_2_053 equ     DESCALE(2204520673,30-CONST_BITS)       ; FIX(2.053119869)
62 F_2_562 equ     DESCALE(2751909506,30-CONST_BITS)       ; FIX(2.562915447)
63 F_3_072 equ     DESCALE(3299298341,30-CONST_BITS)       ; FIX(3.072711026)
64 %endif
65
66 ; --------------------------------------------------------------------------
67         SECTION SEG_CONST
68
69         alignz  16
70         global  EXTN(jconst_fdct_islow_sse2)
71
72 EXTN(jconst_fdct_islow_sse2):
73
74 PW_F130_F054    times 4 dw  (F_0_541+F_0_765), F_0_541
75 PW_F054_MF130   times 4 dw  F_0_541, (F_0_541-F_1_847)
76 PW_MF078_F117   times 4 dw  (F_1_175-F_1_961), F_1_175
77 PW_F117_F078    times 4 dw  F_1_175, (F_1_175-F_0_390)
78 PW_MF060_MF089  times 4 dw  (F_0_298-F_0_899),-F_0_899
79 PW_MF089_F060   times 4 dw -F_0_899, (F_1_501-F_0_899)
80 PW_MF050_MF256  times 4 dw  (F_2_053-F_2_562),-F_2_562
81 PW_MF256_F050   times 4 dw -F_2_562, (F_3_072-F_2_562)
82 PD_DESCALE_P1   times 4 dd  1 << (DESCALE_P1-1)
83 PD_DESCALE_P2   times 4 dd  1 << (DESCALE_P2-1)
84 PW_DESCALE_P2X  times 8 dw  1 << (PASS1_BITS-1)
85
86         alignz  16
87
88 ; --------------------------------------------------------------------------
89         SECTION SEG_TEXT
90         BITS    64
91 ;
92 ; Perform the forward DCT on one block of samples.
93 ;
94 ; GLOBAL(void)
95 ; jsimd_fdct_islow_sse2 (DCTELEM * data)
96 ;
97
98 ; r10 = DCTELEM * data
99
100 %define wk(i)           rbp-(WK_NUM-(i))*SIZEOF_XMMWORD ; xmmword wk[WK_NUM]
101 %define WK_NUM          6
102
103         align   16
104         global  EXTN(jsimd_fdct_islow_sse2)
105
106 EXTN(jsimd_fdct_islow_sse2):
107         push    rbp
108         mov     rax,rsp                         ; rax = original rbp
109         sub     rsp, byte 4
110         and     rsp, byte (-SIZEOF_XMMWORD)     ; align to 128 bits
111         mov     [rsp],rax
112         mov     rbp,rsp                         ; rbp = aligned rbp
113         lea     rsp, [wk(0)]
114         collect_args
115
116         ; ---- Pass 1: process rows.
117
118         mov     rdx, r10        ; (DCTELEM *)
119
120         movdqa  xmm0, XMMWORD [XMMBLOCK(0,0,rdx,SIZEOF_DCTELEM)]
121         movdqa  xmm1, XMMWORD [XMMBLOCK(1,0,rdx,SIZEOF_DCTELEM)]
122         movdqa  xmm2, XMMWORD [XMMBLOCK(2,0,rdx,SIZEOF_DCTELEM)]
123         movdqa  xmm3, XMMWORD [XMMBLOCK(3,0,rdx,SIZEOF_DCTELEM)]
124
125         ; xmm0=(00 01 02 03 04 05 06 07), xmm2=(20 21 22 23 24 25 26 27)
126         ; xmm1=(10 11 12 13 14 15 16 17), xmm3=(30 31 32 33 34 35 36 37)
127
128         movdqa    xmm4,xmm0             ; transpose coefficients(phase 1)
129         punpcklwd xmm0,xmm1             ; xmm0=(00 10 01 11 02 12 03 13)
130         punpckhwd xmm4,xmm1             ; xmm4=(04 14 05 15 06 16 07 17)
131         movdqa    xmm5,xmm2             ; transpose coefficients(phase 1)
132         punpcklwd xmm2,xmm3             ; xmm2=(20 30 21 31 22 32 23 33)
133         punpckhwd xmm5,xmm3             ; xmm5=(24 34 25 35 26 36 27 37)
134
135         movdqa  xmm6, XMMWORD [XMMBLOCK(4,0,rdx,SIZEOF_DCTELEM)]
136         movdqa  xmm7, XMMWORD [XMMBLOCK(5,0,rdx,SIZEOF_DCTELEM)]
137         movdqa  xmm1, XMMWORD [XMMBLOCK(6,0,rdx,SIZEOF_DCTELEM)]
138         movdqa  xmm3, XMMWORD [XMMBLOCK(7,0,rdx,SIZEOF_DCTELEM)]
139
140         ; xmm6=( 4 12 20 28 36 44 52 60), xmm1=( 6 14 22 30 38 46 54 62)
141         ; xmm7=( 5 13 21 29 37 45 53 61), xmm3=( 7 15 23 31 39 47 55 63)
142
143         movdqa  XMMWORD [wk(0)], xmm2   ; wk(0)=(20 30 21 31 22 32 23 33)
144         movdqa  XMMWORD [wk(1)], xmm5   ; wk(1)=(24 34 25 35 26 36 27 37)
145
146         movdqa    xmm2,xmm6             ; transpose coefficients(phase 1)
147         punpcklwd xmm6,xmm7             ; xmm6=(40 50 41 51 42 52 43 53)
148         punpckhwd xmm2,xmm7             ; xmm2=(44 54 45 55 46 56 47 57)
149         movdqa    xmm5,xmm1             ; transpose coefficients(phase 1)
150         punpcklwd xmm1,xmm3             ; xmm1=(60 70 61 71 62 72 63 73)
151         punpckhwd xmm5,xmm3             ; xmm5=(64 74 65 75 66 76 67 77)
152
153         movdqa    xmm7,xmm6             ; transpose coefficients(phase 2)
154         punpckldq xmm6,xmm1             ; xmm6=(40 50 60 70 41 51 61 71)
155         punpckhdq xmm7,xmm1             ; xmm7=(42 52 62 72 43 53 63 73)
156         movdqa    xmm3,xmm2             ; transpose coefficients(phase 2)
157         punpckldq xmm2,xmm5             ; xmm2=(44 54 64 74 45 55 65 75)
158         punpckhdq xmm3,xmm5             ; xmm3=(46 56 66 76 47 57 67 77)
159
160         movdqa  xmm1, XMMWORD [wk(0)]   ; xmm1=(20 30 21 31 22 32 23 33)
161         movdqa  xmm5, XMMWORD [wk(1)]   ; xmm5=(24 34 25 35 26 36 27 37)
162         movdqa  XMMWORD [wk(2)], xmm7   ; wk(2)=(42 52 62 72 43 53 63 73)
163         movdqa  XMMWORD [wk(3)], xmm2   ; wk(3)=(44 54 64 74 45 55 65 75)
164
165         movdqa    xmm7,xmm0             ; transpose coefficients(phase 2)
166         punpckldq xmm0,xmm1             ; xmm0=(00 10 20 30 01 11 21 31)
167         punpckhdq xmm7,xmm1             ; xmm7=(02 12 22 32 03 13 23 33)
168         movdqa    xmm2,xmm4             ; transpose coefficients(phase 2)
169         punpckldq xmm4,xmm5             ; xmm4=(04 14 24 34 05 15 25 35)
170         punpckhdq xmm2,xmm5             ; xmm2=(06 16 26 36 07 17 27 37)
171
172         movdqa     xmm1,xmm0            ; transpose coefficients(phase 3)
173         punpcklqdq xmm0,xmm6            ; xmm0=(00 10 20 30 40 50 60 70)=data0
174         punpckhqdq xmm1,xmm6            ; xmm1=(01 11 21 31 41 51 61 71)=data1
175         movdqa     xmm5,xmm2            ; transpose coefficients(phase 3)
176         punpcklqdq xmm2,xmm3            ; xmm2=(06 16 26 36 46 56 66 76)=data6
177         punpckhqdq xmm5,xmm3            ; xmm5=(07 17 27 37 47 57 67 77)=data7
178
179         movdqa  xmm6,xmm1
180         movdqa  xmm3,xmm0
181         psubw   xmm1,xmm2               ; xmm1=data1-data6=tmp6
182         psubw   xmm0,xmm5               ; xmm0=data0-data7=tmp7
183         paddw   xmm6,xmm2               ; xmm6=data1+data6=tmp1
184         paddw   xmm3,xmm5               ; xmm3=data0+data7=tmp0
185
186         movdqa  xmm2, XMMWORD [wk(2)]   ; xmm2=(42 52 62 72 43 53 63 73)
187         movdqa  xmm5, XMMWORD [wk(3)]   ; xmm5=(44 54 64 74 45 55 65 75)
188         movdqa  XMMWORD [wk(0)], xmm1   ; wk(0)=tmp6
189         movdqa  XMMWORD [wk(1)], xmm0   ; wk(1)=tmp7
190
191         movdqa     xmm1,xmm7            ; transpose coefficients(phase 3)
192         punpcklqdq xmm7,xmm2            ; xmm7=(02 12 22 32 42 52 62 72)=data2
193         punpckhqdq xmm1,xmm2            ; xmm1=(03 13 23 33 43 53 63 73)=data3
194         movdqa     xmm0,xmm4            ; transpose coefficients(phase 3)
195         punpcklqdq xmm4,xmm5            ; xmm4=(04 14 24 34 44 54 64 74)=data4
196         punpckhqdq xmm0,xmm5            ; xmm0=(05 15 25 35 45 55 65 75)=data5
197
198         movdqa  xmm2,xmm1
199         movdqa  xmm5,xmm7
200         paddw   xmm1,xmm4               ; xmm1=data3+data4=tmp3
201         paddw   xmm7,xmm0               ; xmm7=data2+data5=tmp2
202         psubw   xmm2,xmm4               ; xmm2=data3-data4=tmp4
203         psubw   xmm5,xmm0               ; xmm5=data2-data5=tmp5
204
205         ; -- Even part
206
207         movdqa  xmm4,xmm3
208         movdqa  xmm0,xmm6
209         paddw   xmm3,xmm1               ; xmm3=tmp10
210         paddw   xmm6,xmm7               ; xmm6=tmp11
211         psubw   xmm4,xmm1               ; xmm4=tmp13
212         psubw   xmm0,xmm7               ; xmm0=tmp12
213
214         movdqa  xmm1,xmm3
215         paddw   xmm3,xmm6               ; xmm3=tmp10+tmp11
216         psubw   xmm1,xmm6               ; xmm1=tmp10-tmp11
217
218         psllw   xmm3,PASS1_BITS         ; xmm3=data0
219         psllw   xmm1,PASS1_BITS         ; xmm1=data4
220
221         movdqa  XMMWORD [wk(2)], xmm3   ; wk(2)=data0
222         movdqa  XMMWORD [wk(3)], xmm1   ; wk(3)=data4
223
224         ; (Original)
225         ; z1 = (tmp12 + tmp13) * 0.541196100;
226         ; data2 = z1 + tmp13 * 0.765366865;
227         ; data6 = z1 + tmp12 * -1.847759065;
228         ;
229         ; (This implementation)
230         ; data2 = tmp13 * (0.541196100 + 0.765366865) + tmp12 * 0.541196100;
231         ; data6 = tmp13 * 0.541196100 + tmp12 * (0.541196100 - 1.847759065);
232
233         movdqa    xmm7,xmm4             ; xmm4=tmp13
234         movdqa    xmm6,xmm4
235         punpcklwd xmm7,xmm0             ; xmm0=tmp12
236         punpckhwd xmm6,xmm0
237         movdqa    xmm4,xmm7
238         movdqa    xmm0,xmm6
239         pmaddwd   xmm7,[rel PW_F130_F054]       ; xmm7=data2L
240         pmaddwd   xmm6,[rel PW_F130_F054]       ; xmm6=data2H
241         pmaddwd   xmm4,[rel PW_F054_MF130]      ; xmm4=data6L
242         pmaddwd   xmm0,[rel PW_F054_MF130]      ; xmm0=data6H
243
244         paddd   xmm7,[rel PD_DESCALE_P1]
245         paddd   xmm6,[rel PD_DESCALE_P1]
246         psrad   xmm7,DESCALE_P1
247         psrad   xmm6,DESCALE_P1
248         paddd   xmm4,[rel PD_DESCALE_P1]
249         paddd   xmm0,[rel PD_DESCALE_P1]
250         psrad   xmm4,DESCALE_P1
251         psrad   xmm0,DESCALE_P1
252
253         packssdw  xmm7,xmm6             ; xmm7=data2
254         packssdw  xmm4,xmm0             ; xmm4=data6
255
256         movdqa  XMMWORD [wk(4)], xmm7   ; wk(4)=data2
257         movdqa  XMMWORD [wk(5)], xmm4   ; wk(5)=data6
258
259         ; -- Odd part
260
261         movdqa  xmm3, XMMWORD [wk(0)]   ; xmm3=tmp6
262         movdqa  xmm1, XMMWORD [wk(1)]   ; xmm1=tmp7
263
264         movdqa  xmm6,xmm2               ; xmm2=tmp4
265         movdqa  xmm0,xmm5               ; xmm5=tmp5
266         paddw   xmm6,xmm3               ; xmm6=z3
267         paddw   xmm0,xmm1               ; xmm0=z4
268
269         ; (Original)
270         ; z5 = (z3 + z4) * 1.175875602;
271         ; z3 = z3 * -1.961570560;  z4 = z4 * -0.390180644;
272         ; z3 += z5;  z4 += z5;
273         ;
274         ; (This implementation)
275         ; z3 = z3 * (1.175875602 - 1.961570560) + z4 * 1.175875602;
276         ; z4 = z3 * 1.175875602 + z4 * (1.175875602 - 0.390180644);
277
278         movdqa    xmm7,xmm6
279         movdqa    xmm4,xmm6
280         punpcklwd xmm7,xmm0
281         punpckhwd xmm4,xmm0
282         movdqa    xmm6,xmm7
283         movdqa    xmm0,xmm4
284         pmaddwd   xmm7,[rel PW_MF078_F117]      ; xmm7=z3L
285         pmaddwd   xmm4,[rel PW_MF078_F117]      ; xmm4=z3H
286         pmaddwd   xmm6,[rel PW_F117_F078]       ; xmm6=z4L
287         pmaddwd   xmm0,[rel PW_F117_F078]       ; xmm0=z4H
288
289         movdqa  XMMWORD [wk(0)], xmm7   ; wk(0)=z3L
290         movdqa  XMMWORD [wk(1)], xmm4   ; wk(1)=z3H
291
292         ; (Original)
293         ; z1 = tmp4 + tmp7;  z2 = tmp5 + tmp6;
294         ; tmp4 = tmp4 * 0.298631336;  tmp5 = tmp5 * 2.053119869;
295         ; tmp6 = tmp6 * 3.072711026;  tmp7 = tmp7 * 1.501321110;
296         ; z1 = z1 * -0.899976223;  z2 = z2 * -2.562915447;
297         ; data7 = tmp4 + z1 + z3;  data5 = tmp5 + z2 + z4;
298         ; data3 = tmp6 + z2 + z3;  data1 = tmp7 + z1 + z4;
299         ;
300         ; (This implementation)
301         ; tmp4 = tmp4 * (0.298631336 - 0.899976223) + tmp7 * -0.899976223;
302         ; tmp5 = tmp5 * (2.053119869 - 2.562915447) + tmp6 * -2.562915447;
303         ; tmp6 = tmp5 * -2.562915447 + tmp6 * (3.072711026 - 2.562915447);
304         ; tmp7 = tmp4 * -0.899976223 + tmp7 * (1.501321110 - 0.899976223);
305         ; data7 = tmp4 + z3;  data5 = tmp5 + z4;
306         ; data3 = tmp6 + z3;  data1 = tmp7 + z4;
307
308         movdqa    xmm7,xmm2
309         movdqa    xmm4,xmm2
310         punpcklwd xmm7,xmm1
311         punpckhwd xmm4,xmm1
312         movdqa    xmm2,xmm7
313         movdqa    xmm1,xmm4
314         pmaddwd   xmm7,[rel PW_MF060_MF089]     ; xmm7=tmp4L
315         pmaddwd   xmm4,[rel PW_MF060_MF089]     ; xmm4=tmp4H
316         pmaddwd   xmm2,[rel PW_MF089_F060]      ; xmm2=tmp7L
317         pmaddwd   xmm1,[rel PW_MF089_F060]      ; xmm1=tmp7H
318
319         paddd   xmm7, XMMWORD [wk(0)]   ; xmm7=data7L
320         paddd   xmm4, XMMWORD [wk(1)]   ; xmm4=data7H
321         paddd   xmm2,xmm6               ; xmm2=data1L
322         paddd   xmm1,xmm0               ; xmm1=data1H
323
324         paddd   xmm7,[rel PD_DESCALE_P1]
325         paddd   xmm4,[rel PD_DESCALE_P1]
326         psrad   xmm7,DESCALE_P1
327         psrad   xmm4,DESCALE_P1
328         paddd   xmm2,[rel PD_DESCALE_P1]
329         paddd   xmm1,[rel PD_DESCALE_P1]
330         psrad   xmm2,DESCALE_P1
331         psrad   xmm1,DESCALE_P1
332
333         packssdw  xmm7,xmm4             ; xmm7=data7
334         packssdw  xmm2,xmm1             ; xmm2=data1
335
336         movdqa    xmm4,xmm5
337         movdqa    xmm1,xmm5
338         punpcklwd xmm4,xmm3
339         punpckhwd xmm1,xmm3
340         movdqa    xmm5,xmm4
341         movdqa    xmm3,xmm1
342         pmaddwd   xmm4,[rel PW_MF050_MF256]     ; xmm4=tmp5L
343         pmaddwd   xmm1,[rel PW_MF050_MF256]     ; xmm1=tmp5H
344         pmaddwd   xmm5,[rel PW_MF256_F050]      ; xmm5=tmp6L
345         pmaddwd   xmm3,[rel PW_MF256_F050]      ; xmm3=tmp6H
346
347         paddd   xmm4,xmm6               ; xmm4=data5L
348         paddd   xmm1,xmm0               ; xmm1=data5H
349         paddd   xmm5, XMMWORD [wk(0)]   ; xmm5=data3L
350         paddd   xmm3, XMMWORD [wk(1)]   ; xmm3=data3H
351
352         paddd   xmm4,[rel PD_DESCALE_P1]
353         paddd   xmm1,[rel PD_DESCALE_P1]
354         psrad   xmm4,DESCALE_P1
355         psrad   xmm1,DESCALE_P1
356         paddd   xmm5,[rel PD_DESCALE_P1]
357         paddd   xmm3,[rel PD_DESCALE_P1]
358         psrad   xmm5,DESCALE_P1
359         psrad   xmm3,DESCALE_P1
360
361         packssdw  xmm4,xmm1             ; xmm4=data5
362         packssdw  xmm5,xmm3             ; xmm5=data3
363
364         ; ---- Pass 2: process columns.
365
366         movdqa  xmm6, XMMWORD [wk(2)]   ; xmm6=col0
367         movdqa  xmm0, XMMWORD [wk(4)]   ; xmm0=col2
368
369         ; xmm6=(00 10 20 30 40 50 60 70), xmm0=(02 12 22 32 42 52 62 72)
370         ; xmm2=(01 11 21 31 41 51 61 71), xmm5=(03 13 23 33 43 53 63 73)
371
372         movdqa    xmm1,xmm6             ; transpose coefficients(phase 1)
373         punpcklwd xmm6,xmm2             ; xmm6=(00 01 10 11 20 21 30 31)
374         punpckhwd xmm1,xmm2             ; xmm1=(40 41 50 51 60 61 70 71)
375         movdqa    xmm3,xmm0             ; transpose coefficients(phase 1)
376         punpcklwd xmm0,xmm5             ; xmm0=(02 03 12 13 22 23 32 33)
377         punpckhwd xmm3,xmm5             ; xmm3=(42 43 52 53 62 63 72 73)
378
379         movdqa  xmm2, XMMWORD [wk(3)]   ; xmm2=col4
380         movdqa  xmm5, XMMWORD [wk(5)]   ; xmm5=col6
381
382         ; xmm2=(04 14 24 34 44 54 64 74), xmm5=(06 16 26 36 46 56 66 76)
383         ; xmm4=(05 15 25 35 45 55 65 75), xmm7=(07 17 27 37 47 57 67 77)
384
385         movdqa  XMMWORD [wk(0)], xmm0   ; wk(0)=(02 03 12 13 22 23 32 33)
386         movdqa  XMMWORD [wk(1)], xmm3   ; wk(1)=(42 43 52 53 62 63 72 73)
387
388         movdqa    xmm0,xmm2             ; transpose coefficients(phase 1)
389         punpcklwd xmm2,xmm4             ; xmm2=(04 05 14 15 24 25 34 35)
390         punpckhwd xmm0,xmm4             ; xmm0=(44 45 54 55 64 65 74 75)
391         movdqa    xmm3,xmm5             ; transpose coefficients(phase 1)
392         punpcklwd xmm5,xmm7             ; xmm5=(06 07 16 17 26 27 36 37)
393         punpckhwd xmm3,xmm7             ; xmm3=(46 47 56 57 66 67 76 77)
394
395         movdqa    xmm4,xmm2             ; transpose coefficients(phase 2)
396         punpckldq xmm2,xmm5             ; xmm2=(04 05 06 07 14 15 16 17)
397         punpckhdq xmm4,xmm5             ; xmm4=(24 25 26 27 34 35 36 37)
398         movdqa    xmm7,xmm0             ; transpose coefficients(phase 2)
399         punpckldq xmm0,xmm3             ; xmm0=(44 45 46 47 54 55 56 57)
400         punpckhdq xmm7,xmm3             ; xmm7=(64 65 66 67 74 75 76 77)
401
402         movdqa  xmm5, XMMWORD [wk(0)]   ; xmm5=(02 03 12 13 22 23 32 33)
403         movdqa  xmm3, XMMWORD [wk(1)]   ; xmm3=(42 43 52 53 62 63 72 73)
404         movdqa  XMMWORD [wk(2)], xmm4   ; wk(2)=(24 25 26 27 34 35 36 37)
405         movdqa  XMMWORD [wk(3)], xmm0   ; wk(3)=(44 45 46 47 54 55 56 57)
406
407         movdqa    xmm4,xmm6             ; transpose coefficients(phase 2)
408         punpckldq xmm6,xmm5             ; xmm6=(00 01 02 03 10 11 12 13)
409         punpckhdq xmm4,xmm5             ; xmm4=(20 21 22 23 30 31 32 33)
410         movdqa    xmm0,xmm1             ; transpose coefficients(phase 2)
411         punpckldq xmm1,xmm3             ; xmm1=(40 41 42 43 50 51 52 53)
412         punpckhdq xmm0,xmm3             ; xmm0=(60 61 62 63 70 71 72 73)
413
414         movdqa     xmm5,xmm6            ; transpose coefficients(phase 3)
415         punpcklqdq xmm6,xmm2            ; xmm6=(00 01 02 03 04 05 06 07)=data0
416         punpckhqdq xmm5,xmm2            ; xmm5=(10 11 12 13 14 15 16 17)=data1
417         movdqa     xmm3,xmm0            ; transpose coefficients(phase 3)
418         punpcklqdq xmm0,xmm7            ; xmm0=(60 61 62 63 64 65 66 67)=data6
419         punpckhqdq xmm3,xmm7            ; xmm3=(70 71 72 73 74 75 76 77)=data7
420
421         movdqa  xmm2,xmm5
422         movdqa  xmm7,xmm6
423         psubw   xmm5,xmm0               ; xmm5=data1-data6=tmp6
424         psubw   xmm6,xmm3               ; xmm6=data0-data7=tmp7
425         paddw   xmm2,xmm0               ; xmm2=data1+data6=tmp1
426         paddw   xmm7,xmm3               ; xmm7=data0+data7=tmp0
427
428         movdqa  xmm0, XMMWORD [wk(2)]   ; xmm0=(24 25 26 27 34 35 36 37)
429         movdqa  xmm3, XMMWORD [wk(3)]   ; xmm3=(44 45 46 47 54 55 56 57)
430         movdqa  XMMWORD [wk(0)], xmm5   ; wk(0)=tmp6
431         movdqa  XMMWORD [wk(1)], xmm6   ; wk(1)=tmp7
432
433         movdqa     xmm5,xmm4            ; transpose coefficients(phase 3)
434         punpcklqdq xmm4,xmm0            ; xmm4=(20 21 22 23 24 25 26 27)=data2
435         punpckhqdq xmm5,xmm0            ; xmm5=(30 31 32 33 34 35 36 37)=data3
436         movdqa     xmm6,xmm1            ; transpose coefficients(phase 3)
437         punpcklqdq xmm1,xmm3            ; xmm1=(40 41 42 43 44 45 46 47)=data4
438         punpckhqdq xmm6,xmm3            ; xmm6=(50 51 52 53 54 55 56 57)=data5
439
440         movdqa  xmm0,xmm5
441         movdqa  xmm3,xmm4
442         paddw   xmm5,xmm1               ; xmm5=data3+data4=tmp3
443         paddw   xmm4,xmm6               ; xmm4=data2+data5=tmp2
444         psubw   xmm0,xmm1               ; xmm0=data3-data4=tmp4
445         psubw   xmm3,xmm6               ; xmm3=data2-data5=tmp5
446
447         ; -- Even part
448
449         movdqa  xmm1,xmm7
450         movdqa  xmm6,xmm2
451         paddw   xmm7,xmm5               ; xmm7=tmp10
452         paddw   xmm2,xmm4               ; xmm2=tmp11
453         psubw   xmm1,xmm5               ; xmm1=tmp13
454         psubw   xmm6,xmm4               ; xmm6=tmp12
455
456         movdqa  xmm5,xmm7
457         paddw   xmm7,xmm2               ; xmm7=tmp10+tmp11
458         psubw   xmm5,xmm2               ; xmm5=tmp10-tmp11
459
460         paddw   xmm7,[rel PW_DESCALE_P2X]
461         paddw   xmm5,[rel PW_DESCALE_P2X]
462         psraw   xmm7,PASS1_BITS         ; xmm7=data0
463         psraw   xmm5,PASS1_BITS         ; xmm5=data4
464
465         movdqa  XMMWORD [XMMBLOCK(0,0,rdx,SIZEOF_DCTELEM)], xmm7
466         movdqa  XMMWORD [XMMBLOCK(4,0,rdx,SIZEOF_DCTELEM)], xmm5
467
468         ; (Original)
469         ; z1 = (tmp12 + tmp13) * 0.541196100;
470         ; data2 = z1 + tmp13 * 0.765366865;
471         ; data6 = z1 + tmp12 * -1.847759065;
472         ;
473         ; (This implementation)
474         ; data2 = tmp13 * (0.541196100 + 0.765366865) + tmp12 * 0.541196100;
475         ; data6 = tmp13 * 0.541196100 + tmp12 * (0.541196100 - 1.847759065);
476
477         movdqa    xmm4,xmm1             ; xmm1=tmp13
478         movdqa    xmm2,xmm1
479         punpcklwd xmm4,xmm6             ; xmm6=tmp12
480         punpckhwd xmm2,xmm6
481         movdqa    xmm1,xmm4
482         movdqa    xmm6,xmm2
483         pmaddwd   xmm4,[rel PW_F130_F054]       ; xmm4=data2L
484         pmaddwd   xmm2,[rel PW_F130_F054]       ; xmm2=data2H
485         pmaddwd   xmm1,[rel PW_F054_MF130]      ; xmm1=data6L
486         pmaddwd   xmm6,[rel PW_F054_MF130]      ; xmm6=data6H
487
488         paddd   xmm4,[rel PD_DESCALE_P2]
489         paddd   xmm2,[rel PD_DESCALE_P2]
490         psrad   xmm4,DESCALE_P2
491         psrad   xmm2,DESCALE_P2
492         paddd   xmm1,[rel PD_DESCALE_P2]
493         paddd   xmm6,[rel PD_DESCALE_P2]
494         psrad   xmm1,DESCALE_P2
495         psrad   xmm6,DESCALE_P2
496
497         packssdw  xmm4,xmm2             ; xmm4=data2
498         packssdw  xmm1,xmm6             ; xmm1=data6
499
500         movdqa  XMMWORD [XMMBLOCK(2,0,rdx,SIZEOF_DCTELEM)], xmm4
501         movdqa  XMMWORD [XMMBLOCK(6,0,rdx,SIZEOF_DCTELEM)], xmm1
502
503         ; -- Odd part
504
505         movdqa  xmm7, XMMWORD [wk(0)]   ; xmm7=tmp6
506         movdqa  xmm5, XMMWORD [wk(1)]   ; xmm5=tmp7
507
508         movdqa  xmm2,xmm0               ; xmm0=tmp4
509         movdqa  xmm6,xmm3               ; xmm3=tmp5
510         paddw   xmm2,xmm7               ; xmm2=z3
511         paddw   xmm6,xmm5               ; xmm6=z4
512
513         ; (Original)
514         ; z5 = (z3 + z4) * 1.175875602;
515         ; z3 = z3 * -1.961570560;  z4 = z4 * -0.390180644;
516         ; z3 += z5;  z4 += z5;
517         ;
518         ; (This implementation)
519         ; z3 = z3 * (1.175875602 - 1.961570560) + z4 * 1.175875602;
520         ; z4 = z3 * 1.175875602 + z4 * (1.175875602 - 0.390180644);
521
522         movdqa    xmm4,xmm2
523         movdqa    xmm1,xmm2
524         punpcklwd xmm4,xmm6
525         punpckhwd xmm1,xmm6
526         movdqa    xmm2,xmm4
527         movdqa    xmm6,xmm1
528         pmaddwd   xmm4,[rel PW_MF078_F117]      ; xmm4=z3L
529         pmaddwd   xmm1,[rel PW_MF078_F117]      ; xmm1=z3H
530         pmaddwd   xmm2,[rel PW_F117_F078]       ; xmm2=z4L
531         pmaddwd   xmm6,[rel PW_F117_F078]       ; xmm6=z4H
532
533         movdqa  XMMWORD [wk(0)], xmm4   ; wk(0)=z3L
534         movdqa  XMMWORD [wk(1)], xmm1   ; wk(1)=z3H
535
536         ; (Original)
537         ; z1 = tmp4 + tmp7;  z2 = tmp5 + tmp6;
538         ; tmp4 = tmp4 * 0.298631336;  tmp5 = tmp5 * 2.053119869;
539         ; tmp6 = tmp6 * 3.072711026;  tmp7 = tmp7 * 1.501321110;
540         ; z1 = z1 * -0.899976223;  z2 = z2 * -2.562915447;
541         ; data7 = tmp4 + z1 + z3;  data5 = tmp5 + z2 + z4;
542         ; data3 = tmp6 + z2 + z3;  data1 = tmp7 + z1 + z4;
543         ;
544         ; (This implementation)
545         ; tmp4 = tmp4 * (0.298631336 - 0.899976223) + tmp7 * -0.899976223;
546         ; tmp5 = tmp5 * (2.053119869 - 2.562915447) + tmp6 * -2.562915447;
547         ; tmp6 = tmp5 * -2.562915447 + tmp6 * (3.072711026 - 2.562915447);
548         ; tmp7 = tmp4 * -0.899976223 + tmp7 * (1.501321110 - 0.899976223);
549         ; data7 = tmp4 + z3;  data5 = tmp5 + z4;
550         ; data3 = tmp6 + z3;  data1 = tmp7 + z4;
551
552         movdqa    xmm4,xmm0
553         movdqa    xmm1,xmm0
554         punpcklwd xmm4,xmm5
555         punpckhwd xmm1,xmm5
556         movdqa    xmm0,xmm4
557         movdqa    xmm5,xmm1
558         pmaddwd   xmm4,[rel PW_MF060_MF089]     ; xmm4=tmp4L
559         pmaddwd   xmm1,[rel PW_MF060_MF089]     ; xmm1=tmp4H
560         pmaddwd   xmm0,[rel PW_MF089_F060]      ; xmm0=tmp7L
561         pmaddwd   xmm5,[rel PW_MF089_F060]      ; xmm5=tmp7H
562
563         paddd   xmm4, XMMWORD [wk(0)]   ; xmm4=data7L
564         paddd   xmm1, XMMWORD [wk(1)]   ; xmm1=data7H
565         paddd   xmm0,xmm2               ; xmm0=data1L
566         paddd   xmm5,xmm6               ; xmm5=data1H
567
568         paddd   xmm4,[rel PD_DESCALE_P2]
569         paddd   xmm1,[rel PD_DESCALE_P2]
570         psrad   xmm4,DESCALE_P2
571         psrad   xmm1,DESCALE_P2
572         paddd   xmm0,[rel PD_DESCALE_P2]
573         paddd   xmm5,[rel PD_DESCALE_P2]
574         psrad   xmm0,DESCALE_P2
575         psrad   xmm5,DESCALE_P2
576
577         packssdw  xmm4,xmm1             ; xmm4=data7
578         packssdw  xmm0,xmm5             ; xmm0=data1
579
580         movdqa  XMMWORD [XMMBLOCK(7,0,rdx,SIZEOF_DCTELEM)], xmm4
581         movdqa  XMMWORD [XMMBLOCK(1,0,rdx,SIZEOF_DCTELEM)], xmm0
582
583         movdqa    xmm1,xmm3
584         movdqa    xmm5,xmm3
585         punpcklwd xmm1,xmm7
586         punpckhwd xmm5,xmm7
587         movdqa    xmm3,xmm1
588         movdqa    xmm7,xmm5
589         pmaddwd   xmm1,[rel PW_MF050_MF256]     ; xmm1=tmp5L
590         pmaddwd   xmm5,[rel PW_MF050_MF256]     ; xmm5=tmp5H
591         pmaddwd   xmm3,[rel PW_MF256_F050]      ; xmm3=tmp6L
592         pmaddwd   xmm7,[rel PW_MF256_F050]      ; xmm7=tmp6H
593
594         paddd   xmm1,xmm2               ; xmm1=data5L
595         paddd   xmm5,xmm6               ; xmm5=data5H
596         paddd   xmm3, XMMWORD [wk(0)]   ; xmm3=data3L
597         paddd   xmm7, XMMWORD [wk(1)]   ; xmm7=data3H
598
599         paddd   xmm1,[rel PD_DESCALE_P2]
600         paddd   xmm5,[rel PD_DESCALE_P2]
601         psrad   xmm1,DESCALE_P2
602         psrad   xmm5,DESCALE_P2
603         paddd   xmm3,[rel PD_DESCALE_P2]
604         paddd   xmm7,[rel PD_DESCALE_P2]
605         psrad   xmm3,DESCALE_P2
606         psrad   xmm7,DESCALE_P2
607
608         packssdw  xmm1,xmm5             ; xmm1=data5
609         packssdw  xmm3,xmm7             ; xmm3=data3
610
611         movdqa  XMMWORD [XMMBLOCK(5,0,rdx,SIZEOF_DCTELEM)], xmm1
612         movdqa  XMMWORD [XMMBLOCK(3,0,rdx,SIZEOF_DCTELEM)], xmm3
613
614         uncollect_args
615         mov     rsp,rbp         ; rsp <- aligned rbp
616         pop     rsp             ; rsp <- original rbp
617         pop     rbp
618         ret
619
620 ; For some reason, the OS X linker does not honor the request to align the
621 ; segment unless we do this.
622         align   16