First set of 50 GPL attribution for CV-Contributors added
[goodguy/cinelerra.git] / cinelerra-5.1 / mpeg2enc / predcomp_mmxe.s
1 ;;; 
2 ;;;  predcomp_00_mmxe.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_mmxe
31
32 ;;; void predcomp_<ix><iy>_mmxe(char *src,char *dst,int lx, int w, int h, int mask);
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 SECTION .text
48 align 32
49 predcomp_00_mmxe:
50         push ebp                                        ; save frame pointer
51         mov ebp, esp                            ; link
52
53         push eax
54         push ebx
55         push ecx
56         push edx
57         push edi
58
59         mov ebx, [ebp+8]        ; get psrc
60         mov eax, [ebp+12]       ; get pdst
61         mov edx, [ebp+16]       ; get lx
62         mov edi, [ebp+20]       ;  get w
63         mov ecx, [ebp+24]       ; get h
64         movd mm0, [ebp+28]
65                 ;; Extend addflag into bit-mask
66         pxor mm2, mm2
67         punpckldq       mm0,mm0
68         pcmpeqd         mm0, mm2
69         movq            mm1, mm0
70         pcmpeqd         mm0, mm2
71
72         jmp predrow00           ; align for speed
73 align 32
74 predrow00:
75         movq mm4, [ebx]         ; first 8 bytes of row
76         movq mm2, [eax]
77         pand mm2, mm0
78         movq mm3, mm4
79         pand mm3, mm1
80         por  mm2, mm3
81         pavgb mm4, mm2          ; 
82         movq [eax], mm4         ; 
83
84                         
85         cmp     edi, 8
86         jz  eightwide00
87                 
88         movq mm4, [ebx+8]               ; first 8 bytes of row
89         movq mm2, [eax+8]
90         pand mm2, mm0
91         movq mm3, mm4
92         pand mm3, mm1
93         por  mm2, mm3
94         pavgb mm4, mm2          ; 
95         movq [eax+8], mm4               ; 
96
97                 
98 eightwide00:    
99         add eax, edx            ; update pointer to next row
100         add ebx, edx            ; ditto
101         
102         sub  ecx, 1                                     ; check h left
103         jnz predrow00
104
105         pop edi 
106         pop edx 
107         pop ecx 
108         pop ebx 
109         pop eax 
110         pop ebp 
111         emms
112         ret     
113
114
115 ;;; The x-axis interpolation case...
116
117 global predcomp_10_mmxe
118
119
120 align 32
121 predcomp_10_mmxe:
122         push ebp                                        ; save frame pointer
123         mov ebp, esp                            ; link
124
125         push eax
126         push ebx
127         push ecx
128         push edx
129         push edi
130                 
131         mov ebx, [ebp+8]        ; get psrc
132         mov eax, [ebp+12]       ; get pdst
133         mov edx, [ebp+16]       ; get lx
134         mov edi, [ebp+20]       ;  get w
135         mov ecx, [ebp+24]       ; get h
136         movd mm0, [ebp+28]
137                 ;; Extend addflag into bit-mask
138         pxor mm2,mm2            
139         punpckldq       mm0,mm0
140         pcmpeqd         mm0, mm2
141         movq            mm1, mm0
142         pcmpeqd         mm0, mm2
143
144         jmp predrow10           ; align for speed
145 align 32
146 predrow10:
147         movq mm4, [ebx]         ; first 8 bytes row:     avg src in x
148         pavgb mm4, [ebx+1]
149         movq mm2,  [eax]
150         pand mm2, mm0
151         movq mm3, mm4
152         pand mm3, mm1
153         por  mm2, mm3
154         pavgb mm4, mm2  ; combine
155         movq [eax], mm4
156
157     cmp  edi, 8
158         jz eightwide10
159
160
161         movq mm4, [ebx+8]               ; 2nd 8 bytes row:       avg src in x
162         pavgb mm4, [ebx+9]
163         movq mm2,  [eax+8]
164         pand mm2, mm0
165         movq mm3, mm4
166         pand mm3, mm1
167         por  mm2, mm3
168         pavgb mm4, mm2  ; combine
169         movq [eax+8], mm4
170
171                 
172 eightwide10:                    
173         add eax, edx            ; update pointer to next row
174         add ebx, edx            ; ditto
175         
176
177         sub  ecx, 1                     ; check h left
178         jnz near predrow10
179
180         pop edi         
181         pop edx 
182         pop ecx 
183         pop ebx 
184         pop eax 
185         pop ebp 
186         emms
187         ret
188
189
190 ;;; The x-axis and y-axis interpolation case...
191                 
192 global predcomp_11_mmxe
193
194 ;;; mm2 = [0,0,0,0]W
195 ;;; mm3 = [2,2,2,2]W
196 align 32
197 predcomp_11_mmxe:
198         push ebp                                        ; save frame pointer
199         mov ebp, esp                            ; link
200
201         push eax
202         push ebx
203         push ecx
204         push edx
205         push edi
206
207         mov     eax, 0x00020002
208         movd  mm3, eax
209         punpckldq mm3,mm3
210         mov ebx, [ebp+8]        ; get psrc
211         mov eax, [ebp+12]       ; get pdst
212         mov edx, [ebp+16]       ; get lx
213         mov edi, [ebp+20]       ;  get w
214         mov ecx, [ebp+24]       ; get h
215         movd mm0, [ebp+28]
216                 ;; Extend addflag into bit-mask
217
218         pxor mm2,mm2
219         punpckldq       mm0, mm0
220         pcmpeqd         mm0, mm2
221         movq            mm1, mm0
222         pcmpeqd         mm0, mm2
223         
224         jmp predrow11           ; align for speed
225 align 32
226 predrow11:
227         movq mm4, [ebx]         ; mm4 and mm6 accumulate partial sums for interp.
228         movq mm6, mm4
229         punpcklbw       mm4, mm2
230         punpckhbw       mm6, mm2
231
232         movq mm5, [ebx+1]       
233         movq mm7, mm5
234         punpcklbw       mm5, mm2
235         paddw           mm4, mm5
236         punpckhbw       mm7, mm2
237         paddw           mm6, mm7
238
239         add ebx, edx            ; update pointer to next row
240                 
241         movq mm5, [ebx]         ; first 8 bytes 1st row:         avg src in x
242         movq mm7, mm5
243         punpcklbw       mm5, mm2                ;  Accumulate partial interpolation
244         paddw           mm4, mm5
245         punpckhbw   mm7, mm2
246         paddw           mm6, mm7
247
248         movq mm5, [ebx+1]
249         movq mm7, mm5           
250         punpcklbw       mm5, mm2
251         paddw           mm4, mm5
252         punpckhbw       mm7, mm2
253         paddw           mm6, mm7
254
255                 ;; Now round and repack...
256         paddw           mm4, mm3
257         paddw           mm6, mm3
258         psrlw           mm4, 2
259         psrlw           mm6, 2
260         packuswb        mm4, mm6
261
262         movq  mm7, [eax]
263         pand mm7, mm0
264         movq mm6, mm4
265         pand mm6, mm1
266         por  mm7, mm6
267         pavgb mm4, mm7
268         movq [eax], mm4
269
270         cmp   edi, 8
271         jz eightwide11
272                 
273         sub ebx, edx                            ;  Back to 1st row
274
275         movq mm4, [ebx+8]               ; mm4 and mm6 accumulate partial sums for interp.
276         movq mm6, mm4
277         punpcklbw       mm4, mm2
278         punpckhbw       mm6, mm2
279
280         movq mm5, [ebx+9]       
281         movq mm7, mm5
282         punpcklbw       mm5, mm2
283         paddw           mm4, mm5
284         punpckhbw       mm7, mm2
285         paddw           mm6, mm7
286
287         add ebx, edx            ; update pointer to next row
288                 
289         movq mm5, [ebx+8]               ; first 8 bytes 1st row:         avg src in x
290         movq mm7, mm5
291         punpcklbw       mm5, mm2                ;  Accumulate partial interpolation
292         paddw           mm4, mm5
293         punpckhbw   mm7, mm2
294         paddw           mm6, mm7
295
296         movq mm5, [ebx+9]       
297         movq mm7, mm5
298         punpcklbw       mm5, mm2
299         paddw           mm4, mm5
300         punpckhbw       mm7, mm2
301         paddw           mm6, mm7
302
303                 ;; Now round and repack...
304         paddw           mm4, mm3
305         paddw           mm6, mm3
306         psraw           mm4, 2
307         psraw           mm6, 2
308         packuswb        mm4, mm6
309                 
310         movq  mm7, [eax+8]
311         pand mm7, mm0
312         movq mm6, mm4
313         pand mm6, mm1
314         por  mm7, mm6
315         pavgb mm4, mm7
316         movq [eax+8], mm4
317
318 eightwide11:    
319         add eax, edx            ; update pointer to next row
320
321                 
322         sub  ecx, 1                     ; check h left
323         jnz near predrow11
324
325         pop edi         
326         pop edx 
327         pop ecx 
328         pop ebx 
329         pop eax 
330         pop ebp 
331         emms
332         ret
333
334
335
336 ;;; The  y-axis interpolation case...
337                 
338 global predcomp_01_mmxe
339
340 align 32
341 predcomp_01_mmxe:
342         push ebp                                        ; save frame pointer
343         mov ebp, esp                            ; link
344
345         push eax
346         push ebx
347         push ecx
348         push edx
349         push edi
350
351         mov ebx, [ebp+8]        ; get psrc
352         mov eax, [ebp+12]       ; get pdst
353         mov edx, [ebp+16]       ; get lx
354         mov edi, [ebp+20]       ;  get w
355         mov ecx, [ebp+24]       ; get h
356         movd mm0, [ebp+28]
357                 ;; Extend addflag into bit-mask
358         pxor            mm2, mm2
359         punpckldq       mm0,mm0
360         pcmpeqd         mm0, mm2
361         movq            mm1, mm0
362         pcmpeqd         mm0, mm2
363
364         jmp predrow01           ; align for speed
365 align 32
366 predrow01:
367         movq mm4, [ebx]         ; first 8 bytes row
368         add ebx, edx            ; update pointer to next row
369         pavgb mm4, [ebx]                        ;  Average in y
370         
371         movq mm2, [eax]
372         pand mm2, mm0
373         movq mm3, mm4
374         pand mm3, mm1
375         por  mm2, mm3
376         pavgb mm4, mm2
377         movq [eax], mm4
378
379         cmp     edi, 8
380         jz eightwide01
381
382         sub     ebx, edx                                ; Back to prev row
383         movq mm4, [ebx+8]                       ; first 8 bytes row
384         add ebx, edx                            ; update pointer to next row
385         pavgb mm4, [ebx+8]                      ;  Average in y
386         
387         movq mm2, [eax+8]
388         pand mm2, mm0
389         movq mm3, mm4
390         pand mm3, mm1
391         por  mm2, mm3
392         pavgb mm4, mm2
393         movq [eax+8], mm4
394
395 eightwide01:                                    
396         add eax, edx            ; update pointer to next row
397
398
399         sub  ecx, 1                     ; check h left
400         jnz predrow01
401
402         pop edi         
403         pop edx 
404         pop ecx 
405         pop ebx 
406         pop eax 
407         pop ebp 
408         emms
409         ret