version update
[goodguy/cinelerra.git] / cinelerra-5.1 / mpeg2enc / predcomp_mmx.s
1 ;;; 
2 ;;;  predcomp_00_mmx.s:
3 ;;;
4 ;;;               Extended MMX prediction composition
5 ;;;  routines handling the four different interpolation cases...
6 ;;; 
7 ;;;  Copyright (C) 2000 Andrew Stevens <as@comlab.ox.ac.uk>
8
9 ;;;
10 ;;;  This program is free software; you can reaxstribute it and/or
11 ;;;  modify it under the terms of the GNU General Public License
12 ;;;  as published by the Free Software Foundation; either version 2
13 ;;;  of the License, or (at your option) any later version.
14 ;;;
15 ;;;  This program is distributed in the hope that it will be useful,
16 ;;;  but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;;;  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18 ;;;  GNU General Public License for more details.
19 ;;;
20 ;;;  You should have received a copy of the GNU General Public License
21 ;;;  along with this program; if not, write to the Free Software
22 ;;;  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
23 ;;;  02111-1307, USA.
24 ;;;
25 ;;;
26 ;;;
27
28 ;;; The no interpolation case...
29
30 global predcomp_00_mmx
31
32 ;;; void predcomp_<ix><iy>_mmx(char *src,char *dst,int lx, int w, int h, int addflag);
33
34 ;;; ix - Interpolation in x iy - Interpolation in y
35                 
36 ;;; eax = pdst
37 ;;; ebx = psrc
38 ;;; ecx = h left
39 ;;; edx = lx;
40 ;;; edi = w (8 or 16)
41
42
43 ;;; mm1 = one's mask for src
44 ;;; mm0 = zero mask for src...
45                 
46
47
48 SECTION .text
49 align 32
50 predcomp_00_mmx:
51         push ebp                                        ; save frame pointer
52         mov ebp, esp                            ; link
53
54         push eax
55         push ebx
56         push ecx
57         push edx
58         push edi
59         push esi
60                 
61         mov     eax, 0x00010001
62         movd  mm1, eax
63         punpckldq mm1,mm1
64
65         mov ebx, [ebp+8]        ; get psrc
66         mov eax, [ebp+12]       ; get pdst
67         mov edx, [ebp+16]       ; get lx
68         mov edi, [ebp+20]       ;  get w
69         mov ecx, [ebp+24]       ; get h
70         mov esi, [ebp+28]                       ; get addflag
71                 ;; Extend addflag into bit-mask
72         pxor mm0, mm0
73         jmp predrow00m          ; align for speed
74 align 32
75 predrow00m:
76         movq mm4, [ebx]         ; first 8 bytes of row
77         cmp esi, 0
78         jz      noadd00                                 
79
80         movq mm5, mm4
81         punpcklbw       mm4, mm0
82         punpckhbw       mm5, mm0
83
84         movq mm2, [eax]
85         movq mm3, mm2
86         punpcklbw       mm2, mm0
87         punpckhbw       mm3, mm0
88         paddw           mm4, mm2
89         paddw           mm5, mm3
90         paddw           mm4, mm1
91         paddw           mm5, mm1
92         psrlw           mm4, 1
93         psrlw           mm5, 1
94         packuswb        mm4, mm5
95 noadd00:                
96         movq            [eax], mm4
97                                                 
98         cmp     edi, 8
99         jz  eightwide00
100
101         movq mm4, [ebx+8]               ; first 8 bytes of row
102         cmp esi, 0
103         jz      noadd00w
104                 
105         movq mm5, mm4
106         punpcklbw       mm4, mm0
107         punpckhbw       mm5, mm0
108                                                         
109         movq mm2, [eax+8]
110         movq mm3, mm2
111         punpcklbw       mm2, mm0
112         punpckhbw       mm3, mm0
113         paddw           mm4, mm2
114         paddw           mm5, mm3
115         paddw           mm4, mm1
116         paddw           mm5, mm1
117         psrlw           mm4, 1
118         psrlw           mm5, 1
119         packuswb        mm4, mm5                                        
120 noadd00w:               
121         movq    [eax+8], mm4
122
123 eightwide00:    
124         add eax, edx            ; update pointer to next row
125         add ebx, edx            ; ditto
126         
127         sub  ecx, 1                                     ; check h left
128         jnz near predrow00m
129
130         pop esi
131         pop edi 
132         pop edx 
133         pop ecx 
134         pop ebx 
135         pop eax 
136         pop ebp 
137         emms
138         ret     
139
140
141 ;;; The x-axis interpolation case...
142
143 global predcomp_10_mmx
144
145
146 align 32
147 predcomp_10_mmx:
148         push ebp                                        ; save frame pointer
149         mov ebp, esp                            ; link
150
151         push eax
152         push ebx
153         push ecx
154         push edx
155         push edi
156         push esi
157                 
158         mov     eax, 0x00010001
159         movd  mm1, eax
160         punpckldq mm1,mm1
161
162         mov ebx, [ebp+8]        ; get psrc
163         mov eax, [ebp+12]       ; get pdst
164         mov edx, [ebp+16]       ; get lx
165         mov edi, [ebp+20]       ;  get w
166         mov ecx, [ebp+24]       ; get h
167         mov esi, [ebp+28]                       ; get addflag
168                 ;; Extend addflag into bit-mask
169         pxor mm0, mm0
170         jmp predrow10m          ; align for speed
171 align 32
172 predrow10m:
173         movq mm4, [ebx]         ; first 8 bytes of row
174         movq mm5, mm4
175         punpcklbw       mm4, mm0
176         punpckhbw       mm5, mm0
177         movq mm2, [ebx+1]
178         movq mm3, mm2
179         punpcklbw       mm2, mm0
180         punpckhbw       mm3, mm0
181                 
182         paddw           mm4, mm2                ;  Average mm4/mm5 and mm2/mm3
183         paddw           mm5, mm3
184         paddw           mm4, mm1
185         paddw           mm5, mm1
186         psrlw           mm4, 1
187         psrlw           mm5, 1
188                 
189         cmp esi, 0
190         jz      noadd10                                 
191
192         movq mm2, [eax]                         ;  Add 
193         movq mm3, mm2
194         punpcklbw       mm2, mm0        
195         punpckhbw       mm3, mm0
196         paddw           mm4, mm2                ;  Average mm4/mm5 and mm2/mm3
197         paddw           mm5, mm3
198         paddw           mm4, mm1
199         paddw           mm5, mm1
200         psrlw           mm4, 1
201         psrlw           mm5, 1
202 noadd10:                
203         packuswb        mm4, mm5
204         movq            [eax], mm4
205
206         cmp     edi, 8
207         jz  eightwide10
208                 
209         movq mm4, [ebx+8]               ; first 8 bytes of row
210         movq mm5, mm4
211         punpcklbw       mm4, mm0
212         punpckhbw       mm5, mm0
213         movq mm2, [ebx+9]
214         movq mm3, mm2
215         punpcklbw       mm2, mm0
216         punpckhbw       mm3, mm0
217                 
218         paddw           mm4, mm2                ;  Average mm4/mm5 and mm2/mm3
219         paddw           mm5, mm3
220         paddw           mm4, mm1
221         paddw           mm5, mm1
222         psrlw           mm4, 1
223         psrlw           mm5, 1
224                 
225         cmp esi, 0
226         jz      noadd10w                                        
227
228         movq mm2, [eax+8]                               ;  Add 
229         movq mm3, mm2
230         punpcklbw       mm2, mm0        
231         punpckhbw       mm3, mm0
232         paddw           mm4, mm2                ;  Average mm4/mm5 and mm2/mm3
233         paddw           mm5, mm3
234         paddw           mm4, mm1
235         paddw           mm5, mm1
236         psrlw           mm4, 1
237         psrlw           mm5, 1
238 noadd10w:               
239         packuswb        mm4, mm5
240         movq            [eax+8], mm4            
241
242
243 eightwide10:    
244         add eax, edx            ; update pointer to next row
245         add ebx, edx            ; ditto
246         
247         sub  ecx, 1                                     ; check h left
248         jnz near predrow10m
249
250         pop esi
251         pop edi 
252         pop edx 
253         pop ecx 
254         pop ebx 
255         pop eax 
256         pop ebp 
257         emms
258         ret     
259
260 ;;; The y-axis interpolation case...
261
262 global predcomp_01_mmx
263
264
265 align 32
266 predcomp_01_mmx:
267         push ebp                                        ; save frame pointer
268         mov ebp, esp                            ; link
269
270         push eax
271         push ebx
272         push ecx
273         push edx
274         push edi
275         push esi
276                 
277         mov     eax, 0x00010001
278         movd  mm1, eax
279         punpckldq mm1,mm1
280
281         mov ebx, [ebp+8]        ; get psrc
282         mov eax, [ebp+12]       ; get pdst
283         mov edx, [ebp+16]       ; get lx
284         mov edi, [ebp+20]       ;  get w
285         mov ecx, [ebp+24]       ; get h
286         mov esi, [ebp+28]                       ; get addflag
287         pxor mm0, mm0
288         jmp predrow01m          ; align for speed
289
290 align 32
291 predrow01m:
292         movq mm4, [ebx]         ; first 8 bytes of row
293         movq mm5, mm4
294         add                     ebx, edx                                ; Next row
295         punpcklbw       mm4, mm0
296         punpckhbw       mm5, mm0
297
298         movq mm2, [ebx] 
299         movq mm3, mm2
300         punpcklbw       mm2, mm0
301         punpckhbw       mm3, mm0
302                 
303         paddw           mm4, mm2                ;  Average mm4/mm5 and mm2/mm3
304         paddw           mm5, mm3
305         paddw           mm4, mm1
306         paddw           mm5, mm1
307         psrlw           mm4, 1
308         psrlw           mm5, 1
309                 
310         cmp esi, 0
311         jz      noadd01
312
313         movq mm2, [eax]                         ;  Add 
314         movq mm3, mm2
315         punpcklbw       mm2, mm0        
316         punpckhbw       mm3, mm0
317         paddw           mm4, mm2                ;  Average mm4/mm5 and mm2/mm3
318         paddw           mm5, mm3
319         paddw           mm4, mm1
320         paddw           mm5, mm1
321         psrlw           mm4, 1
322         psrlw           mm5, 1
323 noadd01:                
324         packuswb        mm4, mm5
325         movq            [eax], mm4
326
327         cmp     edi, 8
328         jz  eightwide01
329
330         sub                     ebx, edx                ;  Back to first row...
331         movq mm4, [ebx+8]               ; first 8 bytes of row
332         movq mm5, mm4
333         add                     ebx, edx                                ; Next row
334         punpcklbw       mm4, mm0
335         punpckhbw       mm5, mm0
336         movq mm2, [ebx+8]
337         movq mm3, mm2
338         punpcklbw       mm2, mm0
339         punpckhbw       mm3, mm0
340                 
341         paddw           mm4, mm2                ;  Average mm4/mm5 and mm2/mm3
342         paddw           mm5, mm3
343         paddw           mm4, mm1
344         paddw           mm5, mm1
345         psrlw           mm4, 1
346         psrlw           mm5, 1
347                 
348         cmp esi, 0
349         jz      noadd01w                                        
350
351         movq mm2, [eax+8]                               ;  Add 
352         movq mm3, mm2
353         punpcklbw       mm2, mm0        
354         punpckhbw       mm3, mm0
355         paddw           mm4, mm2                ;  Average mm4/mm5 and mm2/mm3
356         paddw           mm5, mm3
357         paddw           mm4, mm1
358         paddw           mm5, mm1
359         psrlw           mm4, 1
360         psrlw           mm5, 1
361 noadd01w:               
362         packuswb        mm4, mm5
363         movq            [eax+8], mm4            
364
365
366 eightwide01:    
367         add eax, edx            ; ditto
368         
369         sub  ecx, 1                                     ; check h left
370         jnz near predrow01m
371
372         pop esi
373         pop edi 
374         pop edx 
375         pop ecx 
376         pop ebx 
377         pop eax 
378         pop ebp 
379         emms
380         ret     
381
382                 
383 ;;; The x-axis and y-axis interpolation case...
384                 
385 global predcomp_11_mmx
386
387 ;;; mm0 = [0,0,0,0]W
388 ;;; mm1 = [1,1,1,1]W            
389 ;;; mm2 = [2,2,2,2]W
390 align 32
391 predcomp_11_mmx:
392         push ebp                                        ; save frame pointer
393         mov ebp, esp                            ; link
394
395         push eax
396         push ebx
397         push ecx
398         push edx
399         push edi
400         push esi
401                 
402         mov     eax, 0x00020002
403         movd  mm2, eax
404         punpckldq mm2,mm2
405         mov     eax, 0x00010001
406         movd  mm1, eax
407         punpckldq mm1,mm1
408         pxor mm0, mm0
409                                                 
410         mov ebx, [ebp+8]        ; get psrc
411         mov eax, [ebp+12]       ; get pdst
412         mov edx, [ebp+16]       ; get lx
413         mov edi, [ebp+20]       ;  get w
414         mov ecx, [ebp+24]       ; get h
415         mov esi, [ebp+28]                       ;  Addflags
416                 ;; Extend addflag into bit-mask
417
418         
419         jmp predrow11           ; align for speed
420 align 32
421 predrow11:
422         movq mm4, [ebx]         ; mm4 and mm6 accumulate partial sums for interp.
423         movq mm6, mm4
424         punpcklbw       mm4, mm0
425         punpckhbw       mm6, mm0
426
427         movq mm5, [ebx+1]       
428         movq mm7, mm5
429         punpcklbw       mm5, mm0
430         paddw           mm4, mm5
431         punpckhbw       mm7, mm0
432         paddw           mm6, mm7
433
434         add ebx, edx            ; update pointer to next row
435                 
436         movq mm5, [ebx]         ; first 8 bytes 1st row:         avg src in x
437         movq mm7, mm5
438         punpcklbw       mm5, mm0                ;  Accumulate partial interpolation
439         paddw           mm4, mm5
440         punpckhbw   mm7, mm0
441         paddw           mm6, mm7
442
443         movq mm5, [ebx+1]
444         movq mm7, mm5           
445         punpcklbw       mm5, mm0
446         paddw           mm4, mm5
447         punpckhbw       mm7, mm0
448         paddw           mm6, mm7
449
450                 ;; Now round 
451         paddw           mm4, mm2
452         paddw           mm6, mm2
453         psrlw           mm4, 2
454         psrlw           mm6, 2
455
456         cmp esi, 0
457         jz  noadd11
458
459         movq mm5, [eax]                         ;  Add 
460         movq mm7, mm5
461         punpcklbw       mm5, mm0        
462         punpckhbw       mm7, mm0
463         paddw           mm4, mm5                ;  Average mm4/mm6 and mm5/mm7
464         paddw           mm6, mm7
465         paddw           mm4, mm1
466         paddw           mm6, mm1
467         psrlw           mm4, 1
468         psrlw           mm6, 1
469                 
470 noadd11:                
471         packuswb        mm4, mm6
472         movq [eax], mm4
473
474         cmp   edi, 8
475         jz near eightwide11
476
477         sub ebx, edx            ; Back to first row...
478
479         movq mm4, [ebx+8]               ; mm4 and mm6 accumulate partial sums for interp.
480         movq mm6, mm4
481         punpcklbw       mm4, mm0
482         punpckhbw       mm6, mm0
483
484         movq mm5, [ebx+9]       
485         movq mm7, mm5
486         punpcklbw       mm5, mm0
487         paddw           mm4, mm5
488         punpckhbw       mm7, mm0
489         paddw           mm6, mm7
490
491         add ebx, edx            ; update pointer to next row
492                 
493         movq mm5, [ebx+8]               ; first 8 bytes 1st row:         avg src in x
494         movq mm7, mm5
495         punpcklbw       mm5, mm0                ;  Accumulate partial interpolation
496         paddw           mm4, mm5
497         punpckhbw   mm7, mm0
498         paddw           mm6, mm7
499
500         movq mm5, [ebx+9]
501         movq mm7, mm5           
502         punpcklbw       mm5, mm0
503         paddw           mm4, mm5
504         punpckhbw       mm7, mm0
505         paddw           mm6, mm7
506
507                 ;; Now round 
508         paddw           mm4, mm2
509         paddw           mm6, mm2
510         psrlw           mm4, 2
511         psrlw           mm6, 2
512
513         cmp esi, 0
514         jz  noadd11w
515
516         movq mm5, [eax+8]                               ;  Add and average
517         movq mm7, mm5
518         punpcklbw       mm5, mm0        
519         punpckhbw       mm7, mm0
520         paddw           mm4, mm5                ;  Average mm4/mm6 and mm5/mm7
521         paddw           mm6, mm7
522         paddw           mm4, mm1
523         paddw           mm6, mm1
524         psrlw           mm4, 1
525         psrlw           mm6, 1
526 noadd11w:               
527         packuswb        mm4, mm6
528         movq [eax+8], mm4
529
530 eightwide11:    
531         add eax, edx            ; update pointer to next row
532
533                 
534         sub  ecx, 1                     ; check h left
535         jnz near predrow11
536
537         pop esi
538         pop edi         
539         pop edx 
540         pop ecx 
541         pop ebx 
542         pop eax 
543         pop ebp 
544         emms
545         ret
546
547
548