Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
godotengine
GitHub Repository: godotengine/godot
Path: blob/master/thirdparty/libtheora/x86_vc/mmxfdct.c
9912 views
1
/********************************************************************
2
* *
3
* THIS FILE IS PART OF THE OggTheora SOFTWARE CODEC SOURCE CODE. *
4
* USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS *
5
* GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
6
* IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
7
* *
8
* THE Theora SOURCE CODE IS COPYRIGHT (C) 1999-2006 *
9
* by the Xiph.Org Foundation https://www.xiph.org/ *
10
* *
11
********************************************************************/
12
/*MMX fDCT implementation for x86_32*/
13
/*$Id: fdct_ses2.c 14579 2008-03-12 06:42:40Z xiphmont $*/
14
#include "x86enc.h"
15
#include "x86zigzag.h"
16
17
#if defined(OC_X86_ASM)
18
19
#define OC_FDCT_STAGE1_8x4 __asm{ \
20
/*Stage 1:*/ \
21
/*mm0=t7'=t0-t7*/ \
22
__asm psubw mm0,mm7 \
23
__asm paddw mm7,mm7 \
24
/*mm1=t6'=t1-t6*/ \
25
__asm psubw mm1, mm6 \
26
__asm paddw mm6,mm6 \
27
/*mm2=t5'=t2-t5*/ \
28
__asm psubw mm2,mm5 \
29
__asm paddw mm5,mm5 \
30
/*mm3=t4'=t3-t4*/ \
31
__asm psubw mm3,mm4 \
32
__asm paddw mm4,mm4 \
33
/*mm7=t0'=t0+t7*/ \
34
__asm paddw mm7,mm0 \
35
/*mm6=t1'=t1+t6*/ \
36
__asm paddw mm6,mm1 \
37
/*mm5=t2'=t2+t5*/ \
38
__asm paddw mm5,mm2 \
39
/*mm4=t3'=t3+t4*/ \
40
__asm paddw mm4,mm3\
41
}
42
43
#define OC_FDCT8x4(_r0,_r1,_r2,_r3,_r4,_r5,_r6,_r7) __asm{ \
44
/*Stage 2:*/ \
45
/*mm7=t3''=t0'-t3'*/ \
46
__asm psubw mm7,mm4 \
47
__asm paddw mm4,mm4 \
48
/*mm6=t2''=t1'-t2'*/ \
49
__asm psubw mm6,mm5 \
50
__asm movq [Y+_r6],mm7 \
51
__asm paddw mm5,mm5 \
52
/*mm1=t5''=t6'-t5'*/ \
53
__asm psubw mm1,mm2 \
54
__asm movq [Y+_r2],mm6 \
55
/*mm4=t0''=t0'+t3'*/ \
56
__asm paddw mm4,mm7 \
57
__asm paddw mm2,mm2 \
58
/*mm5=t1''=t1'+t2'*/ \
59
__asm movq [Y+_r0],mm4 \
60
__asm paddw mm5,mm6 \
61
/*mm2=t6''=t6'+t5'*/ \
62
__asm paddw mm2,mm1 \
63
__asm movq [Y+_r4],mm5 \
64
/*mm0=t7', mm1=t5'', mm2=t6'', mm3=t4'.*/ \
65
/*mm4, mm5, mm6, mm7 are free.*/ \
66
/*Stage 3:*/ \
67
/*mm6={2}x4, mm7={27146,0xB500>>1}x2*/ \
68
__asm mov A,0x5A806A0A \
69
__asm pcmpeqb mm6,mm6 \
70
__asm movd mm7,A \
71
__asm psrlw mm6,15 \
72
__asm punpckldq mm7,mm7 \
73
__asm paddw mm6,mm6 \
74
/*mm0=0, m2={-1}x4 \
75
mm5:mm4=t5''*27146+0xB500*/ \
76
__asm movq mm4,mm1 \
77
__asm movq mm5,mm1 \
78
__asm punpcklwd mm4,mm6 \
79
__asm movq [Y+_r3],mm2 \
80
__asm pmaddwd mm4,mm7 \
81
__asm movq [Y+_r7],mm0 \
82
__asm punpckhwd mm5,mm6 \
83
__asm pxor mm0,mm0 \
84
__asm pmaddwd mm5,mm7 \
85
__asm pcmpeqb mm2,mm2 \
86
/*mm2=t6'', mm1=t5''+(t5''!=0) \
87
mm4=(t5''*27146+0xB500>>16)*/ \
88
__asm pcmpeqw mm0,mm1 \
89
__asm psrad mm4,16 \
90
__asm psubw mm0,mm2 \
91
__asm movq mm2, [Y+_r3] \
92
__asm psrad mm5,16 \
93
__asm paddw mm1,mm0 \
94
__asm packssdw mm4,mm5 \
95
/*mm4=s=(t5''*27146+0xB500>>16)+t5''+(t5''!=0)>>1*/ \
96
__asm paddw mm4,mm1 \
97
__asm movq mm0, [Y+_r7] \
98
__asm psraw mm4,1 \
99
__asm movq mm1,mm3 \
100
/*mm3=t4''=t4'+s*/ \
101
__asm paddw mm3,mm4 \
102
/*mm1=t5'''=t4'-s*/ \
103
__asm psubw mm1,mm4 \
104
/*mm1=0, mm3={-1}x4 \
105
mm5:mm4=t6''*27146+0xB500*/ \
106
__asm movq mm4,mm2 \
107
__asm movq mm5,mm2 \
108
__asm punpcklwd mm4,mm6 \
109
__asm movq [Y+_r5],mm1 \
110
__asm pmaddwd mm4,mm7 \
111
__asm movq [Y+_r1],mm3 \
112
__asm punpckhwd mm5,mm6 \
113
__asm pxor mm1,mm1 \
114
__asm pmaddwd mm5,mm7 \
115
__asm pcmpeqb mm3,mm3 \
116
/*mm2=t6''+(t6''!=0), mm4=(t6''*27146+0xB500>>16)*/ \
117
__asm psrad mm4,16 \
118
__asm pcmpeqw mm1,mm2 \
119
__asm psrad mm5,16 \
120
__asm psubw mm1,mm3 \
121
__asm packssdw mm4,mm5 \
122
__asm paddw mm2,mm1 \
123
/*mm1=t1'' \
124
mm4=s=(t6''*27146+0xB500>>16)+t6''+(t6''!=0)>>1*/ \
125
__asm paddw mm4,mm2 \
126
__asm movq mm1,[Y+_r4] \
127
__asm psraw mm4,1 \
128
__asm movq mm2,mm0 \
129
/*mm7={54491-0x7FFF,0x7FFF}x2 \
130
mm0=t7''=t7'+s*/ \
131
__asm paddw mm0,mm4 \
132
/*mm2=t6'''=t7'-s*/ \
133
__asm psubw mm2,mm4 \
134
/*Stage 4:*/ \
135
/*mm0=0, mm2=t0'' \
136
mm5:mm4=t1''*27146+0xB500*/ \
137
__asm movq mm4,mm1 \
138
__asm movq mm5,mm1 \
139
__asm punpcklwd mm4,mm6 \
140
__asm movq [Y+_r3],mm2 \
141
__asm pmaddwd mm4,mm7 \
142
__asm movq mm2,[Y+_r0] \
143
__asm punpckhwd mm5,mm6 \
144
__asm movq [Y+_r7],mm0 \
145
__asm pmaddwd mm5,mm7 \
146
__asm pxor mm0,mm0 \
147
/*mm7={27146,0x4000>>1}x2 \
148
mm0=s=(t1''*27146+0xB500>>16)+t1''+(t1''!=0)*/ \
149
__asm psrad mm4,16 \
150
__asm mov A,0x20006A0A \
151
__asm pcmpeqw mm0,mm1 \
152
__asm movd mm7,A \
153
__asm psrad mm5,16 \
154
__asm psubw mm0,mm3 \
155
__asm packssdw mm4,mm5 \
156
__asm paddw mm0,mm1 \
157
__asm punpckldq mm7,mm7 \
158
__asm paddw mm0,mm4 \
159
/*mm6={0x00000E3D}x2 \
160
mm1=-(t0''==0), mm5:mm4=t0''*27146+0x4000*/ \
161
__asm movq mm4,mm2 \
162
__asm movq mm5,mm2 \
163
__asm punpcklwd mm4,mm6 \
164
__asm mov A,0x0E3D \
165
__asm pmaddwd mm4,mm7 \
166
__asm punpckhwd mm5,mm6 \
167
__asm movd mm6,A \
168
__asm pmaddwd mm5,mm7 \
169
__asm pxor mm1,mm1 \
170
__asm punpckldq mm6,mm6 \
171
__asm pcmpeqw mm1,mm2 \
172
/*mm4=r=(t0''*27146+0x4000>>16)+t0''+(t0''!=0)*/ \
173
__asm psrad mm4,16 \
174
__asm psubw mm1,mm3 \
175
__asm psrad mm5,16 \
176
__asm paddw mm2,mm1 \
177
__asm packssdw mm4,mm5 \
178
__asm movq mm1,[Y+_r5] \
179
__asm paddw mm4,mm2 \
180
/*mm2=t6'', mm0=_y[0]=u=r+s>>1 \
181
The naive implementation could cause overflow, so we use \
182
u=(r&s)+((r^s)>>1).*/ \
183
__asm movq mm2,[Y+_r3] \
184
__asm movq mm7,mm0 \
185
__asm pxor mm0,mm4 \
186
__asm pand mm7,mm4 \
187
__asm psraw mm0,1 \
188
__asm mov A,0x7FFF54DC \
189
__asm paddw mm0,mm7 \
190
__asm movd mm7,A \
191
/*mm7={54491-0x7FFF,0x7FFF}x2 \
192
mm4=_y[4]=v=r-u*/ \
193
__asm psubw mm4,mm0 \
194
__asm punpckldq mm7,mm7 \
195
__asm movq [Y+_r4],mm4 \
196
/*mm0=0, mm7={36410}x4 \
197
mm1=(t5'''!=0), mm5:mm4=54491*t5'''+0x0E3D*/ \
198
__asm movq mm4,mm1 \
199
__asm movq mm5,mm1 \
200
__asm punpcklwd mm4,mm1 \
201
__asm mov A,0x8E3A8E3A \
202
__asm pmaddwd mm4,mm7 \
203
__asm movq [Y+_r0],mm0 \
204
__asm punpckhwd mm5,mm1 \
205
__asm pxor mm0,mm0 \
206
__asm pmaddwd mm5,mm7 \
207
__asm pcmpeqw mm1,mm0 \
208
__asm movd mm7,A \
209
__asm psubw mm1,mm3 \
210
__asm punpckldq mm7,mm7 \
211
__asm paddd mm4,mm6 \
212
__asm paddd mm5,mm6 \
213
/*mm0=0 \
214
mm3:mm1=36410*t6'''+((t5'''!=0)<<16)*/ \
215
__asm movq mm6,mm2 \
216
__asm movq mm3,mm2 \
217
__asm pmulhw mm6,mm7 \
218
__asm paddw mm1,mm2 \
219
__asm pmullw mm3,mm7 \
220
__asm pxor mm0,mm0 \
221
__asm paddw mm6,mm1 \
222
__asm movq mm1,mm3 \
223
__asm punpckhwd mm3,mm6 \
224
__asm punpcklwd mm1,mm6 \
225
/*mm3={-1}x4, mm6={1}x4 \
226
mm4=_y[5]=u=(54491*t5'''+36410*t6'''+0x0E3D>>16)+(t5'''!=0)*/ \
227
__asm paddd mm5,mm3 \
228
__asm paddd mm4,mm1 \
229
__asm psrad mm5,16 \
230
__asm pxor mm6,mm6 \
231
__asm psrad mm4,16 \
232
__asm pcmpeqb mm3,mm3 \
233
__asm packssdw mm4,mm5 \
234
__asm psubw mm6,mm3 \
235
/*mm1=t7'', mm7={26568,0x3400}x2 \
236
mm2=s=t6'''-(36410*u>>16)*/ \
237
__asm movq mm1,mm4 \
238
__asm mov A,0x340067C8 \
239
__asm pmulhw mm4,mm7 \
240
__asm movd mm7,A \
241
__asm movq [Y+_r5],mm1 \
242
__asm punpckldq mm7,mm7 \
243
__asm paddw mm4,mm1 \
244
__asm movq mm1,[Y+_r7] \
245
__asm psubw mm2,mm4 \
246
/*mm6={0x00007B1B}x2 \
247
mm0=(s!=0), mm5:mm4=s*26568+0x3400*/ \
248
__asm movq mm4,mm2 \
249
__asm movq mm5,mm2 \
250
__asm punpcklwd mm4,mm6 \
251
__asm pcmpeqw mm0,mm2 \
252
__asm pmaddwd mm4,mm7 \
253
__asm mov A,0x7B1B \
254
__asm punpckhwd mm5,mm6 \
255
__asm movd mm6,A \
256
__asm pmaddwd mm5,mm7 \
257
__asm psubw mm0,mm3 \
258
__asm punpckldq mm6,mm6 \
259
/*mm7={64277-0x7FFF,0x7FFF}x2 \
260
mm2=_y[3]=v=(s*26568+0x3400>>17)+s+(s!=0)*/ \
261
__asm psrad mm4,17 \
262
__asm paddw mm2,mm0 \
263
__asm psrad mm5,17 \
264
__asm mov A,0x7FFF7B16 \
265
__asm packssdw mm4,mm5 \
266
__asm movd mm7,A \
267
__asm paddw mm2,mm4 \
268
__asm punpckldq mm7,mm7 \
269
/*mm0=0, mm7={12785}x4 \
270
mm1=(t7''!=0), mm2=t4'', mm5:mm4=64277*t7''+0x7B1B*/ \
271
__asm movq mm4,mm1 \
272
__asm movq mm5,mm1 \
273
__asm movq [Y+_r3],mm2 \
274
__asm punpcklwd mm4,mm1 \
275
__asm movq mm2,[Y+_r1] \
276
__asm pmaddwd mm4,mm7 \
277
__asm mov A,0x31F131F1 \
278
__asm punpckhwd mm5,mm1 \
279
__asm pxor mm0,mm0 \
280
__asm pmaddwd mm5,mm7 \
281
__asm pcmpeqw mm1,mm0 \
282
__asm movd mm7,A \
283
__asm psubw mm1,mm3 \
284
__asm punpckldq mm7,mm7 \
285
__asm paddd mm4,mm6 \
286
__asm paddd mm5,mm6 \
287
/*mm3:mm1=12785*t4'''+((t7''!=0)<<16)*/ \
288
__asm movq mm6,mm2 \
289
__asm movq mm3,mm2 \
290
__asm pmulhw mm6,mm7 \
291
__asm pmullw mm3,mm7 \
292
__asm paddw mm6,mm1 \
293
__asm movq mm1,mm3 \
294
__asm punpckhwd mm3,mm6 \
295
__asm punpcklwd mm1,mm6 \
296
/*mm3={-1}x4, mm6={1}x4 \
297
mm4=_y[1]=u=(12785*t4'''+64277*t7''+0x7B1B>>16)+(t7''!=0)*/ \
298
__asm paddd mm5,mm3 \
299
__asm paddd mm4,mm1 \
300
__asm psrad mm5,16 \
301
__asm pxor mm6,mm6 \
302
__asm psrad mm4,16 \
303
__asm pcmpeqb mm3,mm3 \
304
__asm packssdw mm4,mm5 \
305
__asm psubw mm6,mm3 \
306
/*mm1=t3'', mm7={20539,0x3000}x2 \
307
mm4=s=(12785*u>>16)-t4''*/ \
308
__asm movq [Y+_r1],mm4 \
309
__asm pmulhw mm4,mm7 \
310
__asm mov A,0x3000503B \
311
__asm movq mm1,[Y+_r6] \
312
__asm movd mm7,A \
313
__asm psubw mm4,mm2 \
314
__asm punpckldq mm7,mm7 \
315
/*mm6={0x00006CB7}x2 \
316
mm0=(s!=0), mm5:mm4=s*20539+0x3000*/ \
317
__asm movq mm5,mm4 \
318
__asm movq mm2,mm4 \
319
__asm punpcklwd mm4,mm6 \
320
__asm pcmpeqw mm0,mm2 \
321
__asm pmaddwd mm4,mm7 \
322
__asm mov A,0x6CB7 \
323
__asm punpckhwd mm5,mm6 \
324
__asm movd mm6,A \
325
__asm pmaddwd mm5,mm7 \
326
__asm psubw mm0,mm3 \
327
__asm punpckldq mm6,mm6 \
328
/*mm7={60547-0x7FFF,0x7FFF}x2 \
329
mm2=_y[7]=v=(s*20539+0x3000>>20)+s+(s!=0)*/ \
330
__asm psrad mm4,20 \
331
__asm paddw mm2,mm0 \
332
__asm psrad mm5,20 \
333
__asm mov A,0x7FFF6C84 \
334
__asm packssdw mm4,mm5 \
335
__asm movd mm7,A \
336
__asm paddw mm2,mm4 \
337
__asm punpckldq mm7,mm7 \
338
/*mm0=0, mm7={25080}x4 \
339
mm2=t2'', mm5:mm4=60547*t3''+0x6CB7*/ \
340
__asm movq mm4,mm1 \
341
__asm movq mm5,mm1 \
342
__asm movq [Y+_r7],mm2 \
343
__asm punpcklwd mm4,mm1 \
344
__asm movq mm2,[Y+_r2] \
345
__asm pmaddwd mm4,mm7 \
346
__asm mov A,0x61F861F8 \
347
__asm punpckhwd mm5,mm1 \
348
__asm pxor mm0,mm0 \
349
__asm pmaddwd mm5,mm7 \
350
__asm movd mm7,A \
351
__asm pcmpeqw mm1,mm0 \
352
__asm psubw mm1,mm3 \
353
__asm punpckldq mm7,mm7 \
354
__asm paddd mm4,mm6 \
355
__asm paddd mm5,mm6 \
356
/*mm3:mm1=25080*t2''+((t3''!=0)<<16)*/ \
357
__asm movq mm6,mm2 \
358
__asm movq mm3,mm2 \
359
__asm pmulhw mm6,mm7 \
360
__asm pmullw mm3,mm7 \
361
__asm paddw mm6,mm1 \
362
__asm movq mm1,mm3 \
363
__asm punpckhwd mm3,mm6 \
364
__asm punpcklwd mm1,mm6 \
365
/*mm1={-1}x4 \
366
mm4=u=(25080*t2''+60547*t3''+0x6CB7>>16)+(t3''!=0)*/ \
367
__asm paddd mm5,mm3 \
368
__asm paddd mm4,mm1 \
369
__asm psrad mm5,16 \
370
__asm mov A,0x28005460 \
371
__asm psrad mm4,16 \
372
__asm pcmpeqb mm1,mm1 \
373
__asm packssdw mm4,mm5 \
374
/*mm5={1}x4, mm6=_y[2]=u, mm7={21600,0x2800}x2 \
375
mm4=s=(25080*u>>16)-t2''*/ \
376
__asm movq mm6,mm4 \
377
__asm pmulhw mm4,mm7 \
378
__asm pxor mm5,mm5 \
379
__asm movd mm7,A \
380
__asm psubw mm5,mm1 \
381
__asm punpckldq mm7,mm7 \
382
__asm psubw mm4,mm2 \
383
/*mm2=s+(s!=0) \
384
mm4:mm3=s*21600+0x2800*/ \
385
__asm movq mm3,mm4 \
386
__asm movq mm2,mm4 \
387
__asm punpckhwd mm4,mm5 \
388
__asm pcmpeqw mm0,mm2 \
389
__asm pmaddwd mm4,mm7 \
390
__asm psubw mm0,mm1 \
391
__asm punpcklwd mm3,mm5 \
392
__asm paddw mm2,mm0 \
393
__asm pmaddwd mm3,mm7 \
394
/*mm0=_y[4], mm1=_y[7], mm4=_y[0], mm5=_y[5] \
395
mm3=_y[6]=v=(s*21600+0x2800>>18)+s+(s!=0)*/ \
396
__asm movq mm0,[Y+_r4] \
397
__asm psrad mm4,18 \
398
__asm movq mm5,[Y+_r5] \
399
__asm psrad mm3,18 \
400
__asm movq mm1,[Y+_r7] \
401
__asm packssdw mm3,mm4 \
402
__asm movq mm4,[Y+_r0] \
403
__asm paddw mm3,mm2 \
404
}
405
406
/*On input, mm4=_y[0], mm6=_y[2], mm0=_y[4], mm5=_y[5], mm3=_y[6], mm1=_y[7].
407
On output, {_y[4],mm1,mm2,mm3} contains the transpose of _y[4...7] and
408
{mm4,mm5,mm6,mm7} contains the transpose of _y[0...3].*/
409
#define OC_TRANSPOSE8x4(_r0,_r1,_r2,_r3,_r4,_r5,_r6,_r7) __asm{ \
410
/*First 4x4 transpose:*/ \
411
/*mm0 = e3 e2 e1 e0 \
412
mm5 = f3 f2 f1 f0 \
413
mm3 = g3 g2 g1 g0 \
414
mm1 = h3 h2 h1 h0*/ \
415
__asm movq mm2,mm0 \
416
__asm punpcklwd mm0,mm5 \
417
__asm punpckhwd mm2,mm5 \
418
__asm movq mm5,mm3 \
419
__asm punpcklwd mm3,mm1 \
420
__asm punpckhwd mm5,mm1 \
421
/*mm0 = f1 e1 f0 e0 \
422
mm2 = f3 e3 f2 e2 \
423
mm3 = h1 g1 h0 g0 \
424
mm5 = h3 g3 h2 g2*/ \
425
__asm movq mm1,mm0 \
426
__asm punpckldq mm0,mm3 \
427
__asm movq [Y+_r4],mm0 \
428
__asm punpckhdq mm1,mm3 \
429
__asm movq mm0,[Y+_r1] \
430
__asm movq mm3,mm2 \
431
__asm punpckldq mm2,mm5 \
432
__asm punpckhdq mm3,mm5 \
433
__asm movq mm5,[Y+_r3] \
434
/*_y[4] = h0 g0 f0 e0 \
435
mm1 = h1 g1 f1 e1 \
436
mm2 = h2 g2 f2 e2 \
437
mm3 = h3 g3 f3 e3*/ \
438
/*Second 4x4 transpose:*/ \
439
/*mm4 = a3 a2 a1 a0 \
440
mm0 = b3 b2 b1 b0 \
441
mm6 = c3 c2 c1 c0 \
442
mm5 = d3 d2 d1 d0*/ \
443
__asm movq mm7,mm4 \
444
__asm punpcklwd mm4,mm0 \
445
__asm punpckhwd mm7,mm0 \
446
__asm movq mm0,mm6 \
447
__asm punpcklwd mm6,mm5 \
448
__asm punpckhwd mm0,mm5 \
449
/*mm4 = b1 a1 b0 a0 \
450
mm7 = b3 a3 b2 a2 \
451
mm6 = d1 c1 d0 c0 \
452
mm0 = d3 c3 d2 c2*/ \
453
__asm movq mm5,mm4 \
454
__asm punpckldq mm4,mm6 \
455
__asm punpckhdq mm5,mm6 \
456
__asm movq mm6,mm7 \
457
__asm punpckhdq mm7,mm0 \
458
__asm punpckldq mm6,mm0 \
459
/*mm4 = d0 c0 b0 a0 \
460
mm5 = d1 c1 b1 a1 \
461
mm6 = d2 c2 b2 a2 \
462
mm7 = d3 c3 b3 a3*/ \
463
}
464
465
/*MMX implementation of the fDCT.*/
466
void oc_enc_fdct8x8_mmxext(ogg_int16_t _y[64],const ogg_int16_t _x[64]){
467
OC_ALIGN8(ogg_int16_t buf[64]);
468
ogg_int16_t *bufp;
469
bufp=buf;
470
__asm{
471
#define X edx
472
#define Y eax
473
#define A ecx
474
#define BUF esi
475
/*Add two extra bits of working precision to improve accuracy; any more and
476
we could overflow.*/
477
/*We also add biases to correct for some systematic error that remains in
478
the full fDCT->iDCT round trip.*/
479
mov X, _x
480
mov Y, _y
481
mov BUF, bufp
482
movq mm0,[0x00+X]
483
movq mm1,[0x10+X]
484
movq mm2,[0x20+X]
485
movq mm3,[0x30+X]
486
pcmpeqb mm4,mm4
487
pxor mm7,mm7
488
movq mm5,mm0
489
psllw mm0,2
490
pcmpeqw mm5,mm7
491
movq mm7,[0x70+X]
492
psllw mm1,2
493
psubw mm5,mm4
494
psllw mm2,2
495
mov A,1
496
pslld mm5,16
497
movd mm6,A
498
psllq mm5,16
499
mov A,0x10001
500
psllw mm3,2
501
movd mm4,A
502
punpckhwd mm5,mm6
503
psubw mm1,mm6
504
movq mm6,[0x60+X]
505
paddw mm0,mm5
506
movq mm5,[0x50+X]
507
paddw mm0,mm4
508
movq mm4,[0x40+X]
509
/*We inline stage1 of the transform here so we can get better instruction
510
scheduling with the shifts.*/
511
/*mm0=t7'=t0-t7*/
512
psllw mm7,2
513
psubw mm0,mm7
514
psllw mm6,2
515
paddw mm7,mm7
516
/*mm1=t6'=t1-t6*/
517
psllw mm5,2
518
psubw mm1,mm6
519
psllw mm4,2
520
paddw mm6,mm6
521
/*mm2=t5'=t2-t5*/
522
psubw mm2,mm5
523
paddw mm5,mm5
524
/*mm3=t4'=t3-t4*/
525
psubw mm3,mm4
526
paddw mm4,mm4
527
/*mm7=t0'=t0+t7*/
528
paddw mm7,mm0
529
/*mm6=t1'=t1+t6*/
530
paddw mm6,mm1
531
/*mm5=t2'=t2+t5*/
532
paddw mm5,mm2
533
/*mm4=t3'=t3+t4*/
534
paddw mm4,mm3
535
OC_FDCT8x4(0x00,0x10,0x20,0x30,0x40,0x50,0x60,0x70)
536
OC_TRANSPOSE8x4(0x00,0x10,0x20,0x30,0x40,0x50,0x60,0x70)
537
/*Swap out this 8x4 block for the next one.*/
538
movq mm0,[0x08+X]
539
movq [0x30+Y],mm7
540
movq mm7,[0x78+X]
541
movq [0x50+Y],mm1
542
movq mm1,[0x18+X]
543
movq [0x20+Y],mm6
544
movq mm6,[0x68+X]
545
movq [0x60+Y],mm2
546
movq mm2,[0x28+X]
547
movq [0x10+Y],mm5
548
movq mm5,[0x58+X]
549
movq [0x70+Y],mm3
550
movq mm3,[0x38+X]
551
/*And increase its working precision, too.*/
552
psllw mm0,2
553
movq [0x00+Y],mm4
554
psllw mm7,2
555
movq mm4,[0x48+X]
556
/*We inline stage1 of the transform here so we can get better instruction
557
scheduling with the shifts.*/
558
/*mm0=t7'=t0-t7*/
559
psubw mm0,mm7
560
psllw mm1,2
561
paddw mm7,mm7
562
psllw mm6,2
563
/*mm1=t6'=t1-t6*/
564
psubw mm1,mm6
565
psllw mm2,2
566
paddw mm6,mm6
567
psllw mm5,2
568
/*mm2=t5'=t2-t5*/
569
psubw mm2,mm5
570
psllw mm3,2
571
paddw mm5,mm5
572
psllw mm4,2
573
/*mm3=t4'=t3-t4*/
574
psubw mm3,mm4
575
paddw mm4,mm4
576
/*mm7=t0'=t0+t7*/
577
paddw mm7,mm0
578
/*mm6=t1'=t1+t6*/
579
paddw mm6,mm1
580
/*mm5=t2'=t2+t5*/
581
paddw mm5,mm2
582
/*mm4=t3'=t3+t4*/
583
paddw mm4,mm3
584
OC_FDCT8x4(0x08,0x18,0x28,0x38,0x48,0x58,0x68,0x78)
585
OC_TRANSPOSE8x4(0x08,0x18,0x28,0x38,0x48,0x58,0x68,0x78)
586
/*Here the first 4x4 block of output from the last transpose is the second
587
4x4 block of input for the next transform.
588
We have cleverly arranged that it already be in the appropriate place,
589
so we only have to do half the stores and loads.*/
590
movq mm0,[0x00+Y]
591
movq [0x58+Y],mm1
592
movq mm1,[0x10+Y]
593
movq [0x68+Y],mm2
594
movq mm2,[0x20+Y]
595
movq [0x78+Y],mm3
596
movq mm3,[0x30+Y]
597
OC_FDCT_STAGE1_8x4
598
OC_FDCT8x4(0x00,0x10,0x20,0x30,0x08,0x18,0x28,0x38)
599
/*mm0={-2}x4*/
600
pcmpeqw mm2,mm2
601
paddw mm2,mm2
602
/*Round and store the results (no transpose).*/
603
movq mm7,[Y+0x10]
604
psubw mm4,mm2
605
psubw mm6,mm2
606
psraw mm4,2
607
psubw mm0,mm2
608
movq [BUF+0x00],mm4
609
movq mm4,[Y+0x30]
610
psraw mm6,2
611
psubw mm5,mm2
612
movq [BUF+0x20],mm6
613
psraw mm0,2
614
psubw mm3,mm2
615
movq [BUF+0x40],mm0
616
psraw mm5,2
617
psubw mm1,mm2
618
movq [BUF+0x50],mm5
619
psraw mm3,2
620
psubw mm7,mm2
621
movq [BUF+0x60],mm3
622
psraw mm1,2
623
psubw mm4,mm2
624
movq [BUF+0x70],mm1
625
psraw mm7,2
626
movq [BUF+0x10],mm7
627
psraw mm4,2
628
movq [BUF+0x30],mm4
629
/*Load the next block.*/
630
movq mm0,[0x40+Y]
631
movq mm7,[0x78+Y]
632
movq mm1,[0x50+Y]
633
movq mm6,[0x68+Y]
634
movq mm2,[0x60+Y]
635
movq mm5,[0x58+Y]
636
movq mm3,[0x70+Y]
637
movq mm4,[0x48+Y]
638
OC_FDCT_STAGE1_8x4
639
OC_FDCT8x4(0x40,0x50,0x60,0x70,0x48,0x58,0x68,0x78)
640
/*mm0={-2}x4*/
641
pcmpeqw mm2,mm2
642
paddw mm2,mm2
643
/*Round and store the results (no transpose).*/
644
movq mm7,[Y+0x50]
645
psubw mm4,mm2
646
psubw mm6,mm2
647
psraw mm4,2
648
psubw mm0,mm2
649
movq [BUF+0x08],mm4
650
movq mm4,[Y+0x70]
651
psraw mm6,2
652
psubw mm5,mm2
653
movq [BUF+0x28],mm6
654
psraw mm0,2
655
psubw mm3,mm2
656
movq [BUF+0x48],mm0
657
psraw mm5,2
658
psubw mm1,mm2
659
movq [BUF+0x58],mm5
660
psraw mm3,2
661
psubw mm7,mm2
662
movq [BUF+0x68],mm3
663
psraw mm1,2
664
psubw mm4,mm2
665
movq [BUF+0x78],mm1
666
psraw mm7,2
667
movq [BUF+0x18],mm7
668
psraw mm4,2
669
movq [BUF+0x38],mm4
670
#define OC_ZZ_LOAD_ROW_LO(_row,_reg) \
671
__asm movq _reg,[BUF+16*(_row)] \
672
673
#define OC_ZZ_LOAD_ROW_HI(_row,_reg) \
674
__asm movq _reg,[BUF+16*(_row)+8] \
675
676
OC_TRANSPOSE_ZIG_ZAG_MMXEXT
677
#undef OC_ZZ_LOAD_ROW_LO
678
#undef OC_ZZ_LOAD_ROW_HI
679
#undef X
680
#undef Y
681
#undef A
682
#undef BUF
683
}
684
}
685
686
#endif
687
688