]> git.sesse.net Git - x264/blob - common/amd64/predict-a.asm
add support for x86_64 on Darwin9.0 (Mac OS X 10.5, aka Leopard)
[x264] / common / amd64 / predict-a.asm
1 ;*****************************************************************************
2 ;* predict-a.asm: h264 encoder library
3 ;*****************************************************************************
4 ;* Copyright (C) 2005 x264 project
5 ;*
6 ;* Authors: Loren Merritt <lorenm@u.washington.edu>
7 ;*
8 ;* This program is free software; you can redistribute it and/or modify
9 ;* it under the terms of the GNU General Public License as published by
10 ;* the Free Software Foundation; either version 2 of the License, or
11 ;* (at your option) any later version.
12 ;*
13 ;* This program 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
16 ;* GNU General Public License for more details.
17 ;*
18 ;* You should have received a copy of the GNU General Public License
19 ;* along with this program; if not, write to the Free Software
20 ;* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
21 ;*****************************************************************************
22
23 BITS 64
24
25 ;=============================================================================
26 ; Macros and other preprocessor constants
27 ;=============================================================================
28
29 %include "amd64inc.asm"
30
31 %macro STORE8x8 2
32     movq        [parm1q + 0*FDEC_STRIDE], %1
33     movq        [parm1q + 1*FDEC_STRIDE], %1
34     movq        [parm1q + 2*FDEC_STRIDE], %1
35     movq        [parm1q + 3*FDEC_STRIDE], %1
36     movq        [parm1q + 4*FDEC_STRIDE], %2
37     movq        [parm1q + 5*FDEC_STRIDE], %2
38     movq        [parm1q + 6*FDEC_STRIDE], %2
39     movq        [parm1q + 7*FDEC_STRIDE], %2
40 %endmacro
41
42 %macro STORE16x16 2
43     mov         eax, 4
44 ALIGN 4
45 .loop:
46     movq        [parm1q + 1*FDEC_STRIDE], %1
47     movq        [parm1q + 2*FDEC_STRIDE], %1
48     movq        [parm1q + 3*FDEC_STRIDE], %1
49     movq        [parm1q + 4*FDEC_STRIDE], %1
50     movq        [parm1q + 1*FDEC_STRIDE + 8], %2
51     movq        [parm1q + 2*FDEC_STRIDE + 8], %2
52     movq        [parm1q + 3*FDEC_STRIDE + 8], %2
53     movq        [parm1q + 4*FDEC_STRIDE + 8], %2
54     dec         eax
55     lea         parm1q, [parm1q + 4*FDEC_STRIDE]
56     jnz         .loop
57     nop
58 %endmacro
59
60
61 SECTION_RODATA
62
63 pw_2: times 4 dw 2
64 pw_4: times 4 dw 4
65 pw_8: times 4 dw 8
66 pw_3210:
67     dw 0
68     dw 1
69     dw 2
70     dw 3
71 ALIGN 16
72 pb_1: times 16 db 1
73 pb_00s_ff:
74     times 8 db 0
75 pb_0s_ff:
76     times 7 db 0
77     db 0xff
78
79 ;=============================================================================
80 ; Code
81 ;=============================================================================
82
83 SECTION .text
84
85 ; dest, left, right, src, tmp
86 ; output: %1 = (t[n-1] + t[n]*2 + t[n+1] + 2) >> 2
87 %macro PRED8x8_LOWPASS0 6
88     mov%6       %5, %2
89     pavgb       %2, %3
90     pxor        %3, %5
91     mov%6       %1, %4
92     pand        %3, [pb_1 GLOBAL]
93     psubusb     %2, %3
94     pavgb       %1, %2
95 %endmacro
96 %macro PRED8x8_LOWPASS 5
97     PRED8x8_LOWPASS0 %1, %2, %3, %4, %5, q
98 %endmacro
99 %macro PRED8x8_LOWPASS_XMM 5
100     PRED8x8_LOWPASS0 %1, %2, %3, %4, %5, dqa
101 %endmacro
102
103
104 ;-----------------------------------------------------------------------------
105 ; void predict_4x4_ddl_mmxext( uint8_t *src )
106 ;-----------------------------------------------------------------------------
107 cglobal predict_4x4_ddl_mmxext
108     sub         parm1q, FDEC_STRIDE
109     movq        mm3, [parm1q]
110     movq        mm1, [parm1q-1]
111     movq        mm2, mm3
112     movq        mm4, [pb_0s_ff GLOBAL]
113     psrlq       mm2, 8
114     pand        mm4, mm3
115     por         mm2, mm4
116
117     PRED8x8_LOWPASS mm0, mm1, mm2, mm3, mm5
118
119 %assign Y 1
120 %rep 4
121     psrlq       mm0, 8
122     movd        [parm1q+Y*FDEC_STRIDE], mm0
123 %assign Y (Y+1)
124 %endrep
125
126     ret
127
128 ;-----------------------------------------------------------------------------
129 ; void predict_4x4_vl_mmxext( uint8_t *src )
130 ;-----------------------------------------------------------------------------
131 cglobal predict_4x4_vl_mmxext
132     movq        mm1, [parm1q-FDEC_STRIDE]
133     movq        mm3, mm1
134     movq        mm2, mm1
135     psrlq       mm3, 8
136     psrlq       mm2, 16
137     movq        mm4, mm3
138     pavgb       mm4, mm1
139
140     PRED8x8_LOWPASS mm0, mm1, mm2, mm3, mm5
141
142     movd        [parm1q+0*FDEC_STRIDE], mm4
143     movd        [parm1q+1*FDEC_STRIDE], mm0
144     psrlq       mm4, 8
145     psrlq       mm0, 8
146     movd        [parm1q+2*FDEC_STRIDE], mm4
147     movd        [parm1q+3*FDEC_STRIDE], mm0
148
149     ret
150
151 ;-----------------------------------------------------------------------------
152 ; void predict_8x8_v_mmxext( uint8_t *src, uint8_t *edge )
153 ;-----------------------------------------------------------------------------
154 cglobal predict_8x8_v_mmxext
155     movq        mm0, [parm2q+16]
156     STORE8x8    mm0, mm0
157     ret
158
159 ;-----------------------------------------------------------------------------
160 ; void predict_8x8_dc_mmxext( uint8_t *src, uint8_t *edge );
161 ;-----------------------------------------------------------------------------
162 cglobal predict_8x8_dc_mmxext
163     pxor        mm0, mm0
164     pxor        mm1, mm1
165     psadbw      mm0, [parm2q+7]
166     psadbw      mm1, [parm2q+16]
167     paddw       mm0, [pw_8 GLOBAL]
168     paddw       mm0, mm1
169     psrlw       mm0, 4
170     pshufw      mm0, mm0, 0
171     packuswb    mm0, mm0
172     STORE8x8    mm0, mm0
173     ret
174
175 ;-----------------------------------------------------------------------------
176 ; void predict_8x8_dc_top_mmxext( uint8_t *src, uint8_t *edge );
177 ;-----------------------------------------------------------------------------
178 cglobal predict_8x8_dc_top_mmxext
179     pxor        mm0, mm0
180     psadbw      mm0, [parm2q+16]
181     paddw       mm0, [pw_4 GLOBAL]
182     psrlw       mm0, 3
183     pshufw      mm0, mm0, 0
184     packuswb    mm0, mm0
185     STORE8x8    mm0, mm0
186     ret
187
188 ;-----------------------------------------------------------------------------
189 ; void predict_8x8_dc_left_mmxext( uint8_t *src, uint8_t *edge );
190 ;-----------------------------------------------------------------------------
191 cglobal predict_8x8_dc_left_mmxext
192     pxor        mm0, mm0
193     psadbw      mm0, [parm2q+7]
194     paddw       mm0, [pw_4 GLOBAL]
195     psrlw       mm0, 3
196     pshufw      mm0, mm0, 0
197     packuswb    mm0, mm0
198     STORE8x8    mm0, mm0
199     ret
200
201 ;-----------------------------------------------------------------------------
202 ; void predict_8x8_ddl_mmxext( uint8_t *src, uint8_t *edge )
203 ;-----------------------------------------------------------------------------
204 cglobal predict_8x8_ddl_mmxext
205     movq        mm5, [parm2q+16]
206     movq        mm2, [parm2q+17]
207     movq        mm3, [parm2q+23]
208     movq        mm4, [parm2q+25]
209     movq        mm1, mm5
210     psllq       mm1, 8
211     PRED8x8_LOWPASS mm0, mm1, mm2, mm5, mm7
212     PRED8x8_LOWPASS mm1, mm3, mm4, [parm2q+24], mm6
213
214 %assign Y 7
215 %rep 6
216     movq        [parm1q+Y*FDEC_STRIDE], mm1
217     movq        mm2, mm0
218     psllq       mm1, 8
219     psrlq       mm2, 56
220     psllq       mm0, 8
221     por         mm1, mm2
222 %assign Y (Y-1)
223 %endrep
224     movq        [parm1q+Y*FDEC_STRIDE], mm1
225     psllq       mm1, 8
226     psrlq       mm0, 56
227     por         mm1, mm0
228 %assign Y (Y-1)
229     movq        [parm1q+Y*FDEC_STRIDE], mm1
230
231     ret
232
233 ;-----------------------------------------------------------------------------
234 ; void predict_8x8_ddl_sse2( uint8_t *src, uint8_t *edge )
235 ;-----------------------------------------------------------------------------
236 cglobal predict_8x8_ddl_sse2
237     movdqa      xmm3, [parm2q+16]
238     movdqu      xmm2, [parm2q+17]
239     movdqa      xmm1, xmm3
240     pslldq      xmm1, 1
241     PRED8x8_LOWPASS_XMM xmm0, xmm1, xmm2, xmm3, xmm4
242
243 %assign Y 0
244 %rep 8
245     psrldq      xmm0, 1
246     movq        [parm1q+Y*FDEC_STRIDE], xmm0
247 %assign Y (Y+1)
248 %endrep
249     ret
250
251 ;-----------------------------------------------------------------------------
252 ; void predict_8x8_ddr_sse2( uint8_t *src, uint8_t *edge )
253 ;-----------------------------------------------------------------------------
254 cglobal predict_8x8_ddr_sse2
255     movdqu      xmm3, [parm2q+8]
256     movdqu      xmm1, [parm2q+7]
257     movdqa      xmm2, xmm3
258     psrldq      xmm2, 1
259     PRED8x8_LOWPASS_XMM xmm0, xmm1, xmm2, xmm3, xmm4
260
261     movdqa      xmm1, xmm0
262     psrldq      xmm1, 1
263 %assign Y 7
264 %rep 3
265     movq        [parm1q+Y*FDEC_STRIDE], xmm0
266     movq        [parm1q+(Y-1)*FDEC_STRIDE], xmm1
267     psrldq      xmm0, 2
268     psrldq      xmm1, 2
269 %assign Y (Y-2)
270 %endrep
271     movq        [parm1q+1*FDEC_STRIDE], xmm0
272     movq        [parm1q+0*FDEC_STRIDE], xmm1
273
274     ret
275
276 ;-----------------------------------------------------------------------------
277 ; void predict_8x8_vl_sse2( uint8_t *src, uint8_t *edge )
278 ;-----------------------------------------------------------------------------
279 cglobal predict_8x8_vl_sse2
280     movdqa      xmm4, [parm2q+16]
281     movdqa      xmm2, xmm4
282     movdqa      xmm1, xmm4
283     movdqa      xmm3, xmm4
284     psrldq      xmm2, 1
285     pslldq      xmm1, 1
286     pavgb       xmm3, xmm2
287     PRED8x8_LOWPASS_XMM xmm0, xmm1, xmm2, xmm4, xmm5
288 ; xmm0: (t0 + 2*t1 + t2 + 2) >> 2
289 ; xmm3: (t0 + t1 + 1) >> 1
290
291 %assign Y 0
292 %rep 3
293     psrldq      xmm0, 1
294     movq        [parm1q+ Y   *FDEC_STRIDE], xmm3
295     movq        [parm1q+(Y+1)*FDEC_STRIDE], xmm0
296     psrldq      xmm3, 1
297 %assign Y (Y+2)
298 %endrep
299     psrldq      xmm0, 1
300     movq        [parm1q+ Y   *FDEC_STRIDE], xmm3
301     movq        [parm1q+(Y+1)*FDEC_STRIDE], xmm0
302
303     ret
304
305 ;-----------------------------------------------------------------------------
306 ; void predict_8x8_vr_core_mmxext( uint8_t *src, uint8_t *edge )
307 ;-----------------------------------------------------------------------------
308
309 ; fills only some pixels:
310 ; f01234567
311 ; 0........
312 ; 1,,,,,,,,
313 ; 2 .......
314 ; 3 ,,,,,,,
315 ; 4  ......
316 ; 5  ,,,,,,
317 ; 6   .....
318 ; 7   ,,,,,
319
320 cglobal predict_8x8_vr_core_mmxext
321     movq        mm2, [parm2q+16]
322     movq        mm3, [parm2q+15]
323     movq        mm1, [parm2q+14]
324     movq        mm4, mm3
325     pavgb       mm3, mm2
326     PRED8x8_LOWPASS mm0, mm1, mm2, mm4, mm7
327
328 %assign Y 0
329 %rep 3
330     movq        [parm1q+ Y   *FDEC_STRIDE], mm3
331     movq        [parm1q+(Y+1)*FDEC_STRIDE], mm0
332     psllq       mm3, 8
333     psllq       mm0, 8
334 %assign Y (Y+2)
335 %endrep
336     movq        [parm1q+ Y   *FDEC_STRIDE], mm3
337     movq        [parm1q+(Y+1)*FDEC_STRIDE], mm0
338
339     ret
340
341 ;-----------------------------------------------------------------------------
342 ; void predict_8x8c_v_mmx( uint8_t *src )
343 ;-----------------------------------------------------------------------------
344 cglobal predict_8x8c_v_mmx
345     movq        mm0, [parm1q - FDEC_STRIDE]
346     STORE8x8    mm0, mm0
347     ret
348
349 ;-----------------------------------------------------------------------------
350 ; void predict_8x8c_dc_core_mmxext( uint8_t *src, int s2, int s3 )
351 ;-----------------------------------------------------------------------------
352 cglobal predict_8x8c_dc_core_mmxext
353     movq        mm0, [parm1q - FDEC_STRIDE]
354     pxor        mm1, mm1
355     pxor        mm2, mm2
356     punpckhbw   mm1, mm0
357     punpcklbw   mm0, mm2
358     psadbw      mm1, mm2        ; s1
359     psadbw      mm0, mm2        ; s0
360
361     movd        mm4, parm2d
362     movd        mm5, parm3d
363     paddw       mm0, mm4
364     pshufw      mm2, mm5, 0
365     psrlw       mm0, 3
366     paddw       mm1, [pw_2 GLOBAL]
367     movq        mm3, mm2
368     pshufw      mm1, mm1, 0
369     pshufw      mm0, mm0, 0     ; dc0 (w)
370     paddw       mm3, mm1
371     psrlw       mm3, 3          ; dc3 (w)
372     psrlw       mm2, 2          ; dc2 (w)
373     psrlw       mm1, 2          ; dc1 (w)
374
375     packuswb    mm0, mm1        ; dc0,dc1 (b)
376     packuswb    mm2, mm3        ; dc2,dc3 (b)
377
378     STORE8x8    mm0, mm2
379     ret
380
381 ;-----------------------------------------------------------------------------
382 ; void predict_8x8c_p_core_mmxext( uint8_t *src, int i00, int b, int c )
383 ;-----------------------------------------------------------------------------
384 cglobal predict_8x8c_p_core_mmxext
385     movd        mm0, parm2d
386     movd        mm2, parm3d
387     movd        mm4, parm4d
388     pshufw      mm0, mm0, 0
389     pshufw      mm2, mm2, 0
390     pshufw      mm4, mm4, 0
391     movq        mm1, mm2
392     pmullw      mm2, [pw_3210 GLOBAL]
393     psllw       mm1, 2
394     paddsw      mm0, mm2        ; mm0 = {i+0*b, i+1*b, i+2*b, i+3*b}
395     paddsw      mm1, mm0        ; mm1 = {i+4*b, i+5*b, i+6*b, i+7*b}
396
397     mov         eax, 8
398 ALIGN 4
399 .loop:
400     movq        mm5, mm0
401     movq        mm6, mm1
402     psraw       mm5, 5
403     psraw       mm6, 5
404     packuswb    mm5, mm6
405     movq        [parm1q], mm5
406
407     paddsw      mm0, mm4
408     paddsw      mm1, mm4
409     add         parm1q, FDEC_STRIDE
410     dec         eax
411     jg          .loop
412
413     nop
414     ret
415
416 ;-----------------------------------------------------------------------------
417 ; void predict_16x16_p_core_mmxext( uint8_t *src, int i00, int b, int c )
418 ;-----------------------------------------------------------------------------
419 cglobal predict_16x16_p_core_mmxext
420     movd        mm0, parm2d
421     movd        mm2, parm3d
422     movd        mm4, parm4d
423     pshufw      mm0, mm0, 0
424     pshufw      mm2, mm2, 0
425     pshufw      mm4, mm4, 0
426     movq        mm5, mm2
427     movq        mm1, mm2
428     pmullw      mm5, [pw_3210 GLOBAL]
429     psllw       mm2, 3
430     psllw       mm1, 2
431     movq        mm3, mm2
432     paddsw      mm0, mm5        ; mm0 = {i+ 0*b, i+ 1*b, i+ 2*b, i+ 3*b}
433     paddsw      mm1, mm0        ; mm1 = {i+ 4*b, i+ 5*b, i+ 6*b, i+ 7*b}
434     paddsw      mm2, mm0        ; mm2 = {i+ 8*b, i+ 9*b, i+10*b, i+11*b}
435     paddsw      mm3, mm1        ; mm3 = {i+12*b, i+13*b, i+14*b, i+15*b}
436
437     mov         eax, 16
438 ALIGN 4
439 .loop:
440     movq        mm5, mm0
441     movq        mm6, mm1
442     psraw       mm5, 5
443     psraw       mm6, 5
444     packuswb    mm5, mm6
445     movq        [parm1q], mm5
446
447     movq        mm5, mm2
448     movq        mm6, mm3
449     psraw       mm5, 5
450     psraw       mm6, 5
451     packuswb    mm5, mm6
452     movq        [parm1q+8], mm5
453
454     paddsw      mm0, mm4
455     paddsw      mm1, mm4
456     paddsw      mm2, mm4
457     paddsw      mm3, mm4
458     add         parm1q, FDEC_STRIDE
459     dec         eax
460     jg          .loop
461
462     nop
463     ret
464     
465 ;-----------------------------------------------------------------------------
466 ; void predict_16x16_v_mmx( uint8_t *src )
467 ;-----------------------------------------------------------------------------
468 cglobal predict_16x16_v_mmx
469     sub         parm1q, FDEC_STRIDE
470     movq        mm0, [parm1q]
471     movq        mm1, [parm1q + 8]
472     STORE16x16  mm0, mm1
473     ret
474
475 ;-----------------------------------------------------------------------------
476 ; void predict_16x16_dc_core_mmxext( uint8_t *src, int i_dc_left )
477 ;-----------------------------------------------------------------------------
478
479 %macro PRED16x16_DC 2
480     sub         parm1q, FDEC_STRIDE
481
482     pxor        mm0, mm0
483     pxor        mm1, mm1
484     psadbw      mm0, [parm1q]
485     psadbw      mm1, [parm1q + 8]
486     paddusw     mm0, mm1
487     paddusw     mm0, %1
488     psrlw       mm0, %2                       ; dc
489     pshufw      mm0, mm0, 0
490     packuswb    mm0, mm0                      ; dc in bytes
491
492     STORE16x16  mm0, mm0
493 %endmacro
494
495 cglobal predict_16x16_dc_core_mmxext
496     movd         mm2, parm2d
497     PRED16x16_DC mm2, 5
498     ret
499
500 cglobal predict_16x16_dc_top_mmxext
501     PRED16x16_DC [pw_8 GLOBAL], 4
502     ret
503