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