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