ffmpeg versioning mods from Andrew
[goodguy/cinelerra.git] / cinelerra-5.1 / mpeg2enc / dist2_mmx.s
1 ;
2 ;  dist2_mmx.s:  mmX optimized squared distance sum
3 ;
4 ;  Original believed to be Copyright (C) 2000 Brent Byeler
5 ;
6 ;  This program is free software; you can reaxstribute it and/or
7 ;  modify it under the terms of the GNU General Public License
8 ;  as published by the Free Software Foundation; either version 2
9 ;  of the License, or (at your option) any later version.
10 ;
11 ;  This program is distributed in the hope that it will be useful,
12 ;  but WITHOUT ANY WARRANTY; without even the implied warranty of
13 ;  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 ;  GNU General Public License for more details.
15 ;
16 ;  You should have received a copy of the GNU General Public License
17 ;  along with this program; if not, write to the Free Software
18 ;  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
19 ;
20
21 ; total squared difference between two (16*h) blocks
22 ; including optional half pel interpolation of [ebp+8] ; blk1 (hx,hy)
23 ; blk1,blk2: addresses of top left pels of both blocks
24 ; lx:        distance (in bytes) of vertically adjacent pels
25 ; hx,hy:     flags for horizontal and/or vertical interpolation
26 ; h:         height of block (usually 8 or 16)
27 ; mmX version
28
29 global dist2_mmx
30 ; int dist2_mmx(unsigned char *blk1, unsigned char *blk2,
31 ;                 int lx, int hx, int hy, int h)
32
33 ; mm7 = 0
34
35 ; eax = pblk1 
36 ; ebx = pblk2
37 ; ecx = temp
38 ; edx = distance_sum
39 ; edi = h
40 ; esi = lx
41
42                 ;; 
43                 ;;  private constants needed
44                 ;; 
45
46 SECTION .data
47 align 16
48 twos:   
49                         dw      2
50                         dw      2
51                         dw      2
52                         dw      2
53
54 SECTION .text
55 align 32
56 dist2_mmx:
57         push ebp                        ; save frame pointer
58         mov ebp, esp            ; link
59         push ebx
60         push ecx
61         push edx
62         push esi     
63         push edi
64
65         mov             esi, [ebp+16] ; lx
66         mov     eax, [ebp+20] ; hx
67         mov     edx, [ebp+24] ; hy
68         mov     edi, [ebp+28] ; h
69
70     pxor      mm5, mm5      ; sum
71         test      edi, edi     ; h = 0?
72         jle       near d2exit
73
74         pxor      mm7, mm7     ; get zeros i mm7
75
76         test      eax, eax     ; hx != 0?
77         jne       near d2is10
78         test      edx, edx     ; hy != 0?
79         jne       near d2is10
80
81         mov       eax, [ebp+8]
82     mov       ebx, [ebp+12]
83         jmp      d2top00
84
85 align 32
86 d2top00:
87         movq      mm0, [eax]
88         movq      mm1, mm0
89         punpcklbw mm0, mm7
90         punpckhbw mm1, mm7
91
92         movq      mm2, [ebx]
93         movq      mm3, mm2
94         punpcklbw mm2, mm7
95         punpckhbw mm3, mm7
96
97         psubw     mm0, mm2
98         psubw     mm1, mm3
99         pmaddwd   mm0, mm0
100         pmaddwd   mm1, mm1
101         paddd     mm0, mm1
102
103         movq      mm1, [eax+8]
104         movq      mm2, mm1
105         punpcklbw mm1, mm7
106         punpckhbw mm2, mm7
107
108         movq      mm3, [ebx+8]
109         movq      mm4, mm3
110         punpcklbw mm3, mm7
111         punpckhbw mm4, mm7
112
113         psubw     mm1, mm3
114         psubw     mm2, mm4
115         pmaddwd   mm1, mm1
116         pmaddwd   mm2, mm2
117         paddd     mm1, mm2
118
119         paddd     mm0, mm1
120         
121                 ;; Accumulate sum in edx... we use mm5
122                 ;movd     ecx, mm0
123         ;add       edx, ecx
124             ;psrlq        mm0, 32
125             ;movd         ecx, mm0
126         ;add       edx, ecx
127                 paddd    mm5, mm0
128
129         add       eax, esi
130         add       ebx, esi
131         dec       edi
132         jg        d2top00
133         jmp       d2exit
134
135
136 d2is10:
137         test      eax, eax
138         je        near d2is01
139         test      edx, edx
140         jne       near d2is01
141
142  
143         mov       eax, [ebp+8] ; blk1
144         mov       ebx, [ebp+12] ; blk1
145
146         pxor      mm6, mm6    ; mm6 = 0 and isn't changed anyplace in the loop..
147         pcmpeqw   mm1, mm1
148         psubw     mm6, mm1
149         jmp               d2top10
150         
151 align 32
152 d2top10:
153         movq      mm0, [eax]
154         movq      mm1, mm0
155         punpcklbw mm0, mm7
156         punpckhbw mm1, mm7
157         movq      mm2, [eax+1]
158         movq      mm3, mm2
159         punpcklbw mm2, mm7
160         punpckhbw mm3, mm7
161         paddw     mm0, mm2
162         paddw     mm1, mm3
163         paddw     mm0, mm6   ; here we add mm6 = 0.... weird...
164         paddw     mm1, mm6
165         psrlw     mm0, 1
166         psrlw     mm1, 1
167
168         movq      mm2, [ebx]
169         movq      mm3, mm2
170         punpcklbw mm2, mm7
171         punpckhbw mm3, mm7
172
173         psubw     mm0, mm2
174         psubw     mm1, mm3
175         pmaddwd   mm0, mm0
176         pmaddwd   mm1, mm1
177         paddd     mm0, mm1
178
179         movq      mm1, [eax+8]
180         movq      mm2, mm1
181         punpcklbw mm1, mm7
182         punpckhbw mm2, mm7
183         movq      mm3, [eax+9]
184         movq      mm4, mm3
185         punpcklbw mm3, mm7
186         punpckhbw mm4, mm7
187         paddw     mm1, mm3
188         paddw     mm2, mm4
189         paddw     mm1, mm6
190         paddw     mm2, mm6
191         psrlw     mm1, 1
192         psrlw     mm2, 1
193
194         movq      mm3, [ebx+8]
195         movq      mm4, mm3
196         punpcklbw mm3, mm7
197         punpckhbw mm4, mm7
198
199         psubw     mm1, mm3
200         psubw     mm2, mm4
201         pmaddwd   mm1, mm1
202         pmaddwd   mm2, mm2
203         paddd     mm1, mm2
204
205
206         paddd     mm0, mm1
207                 ; Accumulate mm0 sum on edx... we'll use mm5 for this and add up at the end
208                 ; movd    ecx, mm0
209         ; add       edx, ecx
210                 ; psrlq   mm0, 32
211                 ; movd    ecx, mm0
212         ; add       edx, ecx
213         paddd     mm5, mm0
214         add       eax, esi
215         add       ebx, esi
216         dec       edi
217         jg        near d2top10
218         
219         
220         jmp       d2exit
221
222 d2is01:
223         test      eax, eax
224         jne       near d2is11
225         test      edx, edx
226         je        near d2is11
227
228         mov       eax, [ebp+8] ; blk1
229         mov       edx, [ebp+12] ; blk2
230         mov       ebx, eax
231         add       ebx, esi ;  blk1 + lx
232
233         pxor      mm6, mm6
234         pcmpeqw   mm1, mm1
235         psubw     mm6, mm1  ; mm6 = 1
236         jmp               d2top01
237         
238 align 32
239 d2top01:
240         movq      mm0, [eax]
241         movq      mm1, mm0
242         punpcklbw mm0, mm7
243         punpckhbw mm1, mm7
244         movq      mm2, [ebx]
245         movq      mm3, mm2
246         punpcklbw mm2, mm7
247         punpckhbw mm3, mm7
248         paddw     mm0, mm2
249         paddw     mm1, mm3
250         paddw     mm0, mm6
251         paddw     mm1, mm6
252         psrlw     mm0, 1
253         psrlw     mm1, 1
254
255         movq      mm2, [edx]
256         movq      mm3, mm2
257     punpcklbw mm2, mm7
258     punpckhbw mm3, mm7
259
260     psubw     mm0, mm2
261     psubw     mm1, mm3
262
263         pmaddwd   mm0, mm0
264     pmaddwd   mm1, mm1
265     paddd     mm0, mm1
266
267         movq      mm1, [eax+8]
268         movq      mm2, mm1
269         punpcklbw mm1, mm7
270         punpckhbw mm2, mm7
271         
272         movq      mm3, [ebx+8]
273         movq      mm4, mm3
274         punpcklbw mm3, mm7
275         punpckhbw mm4, mm7
276
277         paddw     mm1, mm3
278         paddw     mm2, mm4
279         paddw     mm1, mm6
280         paddw     mm2, mm6
281         psrlw     mm1, 1
282         psrlw     mm2, 1
283
284         movq      mm3, [edx+8]
285         movq      mm4, mm3
286     punpcklbw mm3, mm7
287     punpckhbw mm4, mm7
288
289     psubw     mm1, mm3
290     psubw     mm2, mm4
291
292         pmaddwd   mm1, mm1
293     pmaddwd   mm2, mm2
294     paddd     mm0, mm1
295         paddd     mm0, mm2
296
297         ;; Accumulate in "s" - we use mm5 for the purpose
298         ;;
299         ;movd     ecx, mm0
300     ;add       s, ecx
301         ;psrlq    mm0, 32
302         ;movd     ecx, mm0
303         ;add              s, ecx
304         paddd     mm5, mm0
305
306         ;; Originally this moved 
307         mov       eax, ebx    ; eax = eax + lx
308         add       edx, esi    ; edx = edx + lx
309         add       ebx, esi    ; ebx = ebx + lx
310         dec       edi
311         jg        near d2top01
312         jmp       d2exit
313
314 d2is11:
315         mov       eax, [ebp+8] ; blk1
316         mov       edx, [ebp+12] ; blk2
317         mov       ebx, eax  ;  blk1
318         add       ebx, esi  ; ebx = blk1 + lx
319         jmp               d2top11
320         
321 align 32
322 d2top11:
323         movq      mm0, [eax]
324         movq      mm1, mm0
325         punpcklbw mm0, mm7
326         punpckhbw mm1, mm7
327         movq      mm2, [eax+1]
328         movq      mm3, mm2
329         punpcklbw mm2, mm7
330         punpckhbw mm3, mm7
331         paddw     mm0, mm2
332         paddw     mm1, mm3
333         movq      mm2, [ebx]
334         movq      mm3, mm2
335         punpcklbw mm2, mm7
336         punpckhbw mm3, mm7
337         movq      mm4, [ebx+1]
338         movq      mm6, mm4
339         punpcklbw mm4, mm7
340         punpckhbw mm6, mm7
341         paddw     mm2, mm4
342         paddw     mm3, mm6
343         paddw     mm0, mm2
344         paddw     mm1, mm3
345         ;pxor         mm6, mm6    ; mm6 = 0
346         ;pcmpeqw          mm5, mm5    ; mm5 = -1
347         ;psubw        mm6, mm5    ; mm6 = 1
348         ;paddw        mm6, mm6    ; mm6 = 2
349         movq      mm6, [twos]
350         paddw     mm0, mm6    ; round mm0
351         paddw     mm1, mm6    ; round mm1
352         psrlw     mm0, 2
353         psrlw     mm1, 2
354
355         movq      mm2, [edx]
356         movq      mm3, mm2
357         punpcklbw mm2, mm7
358         punpckhbw mm3, mm7
359
360         psubw     mm0, mm2
361         psubw     mm1, mm3
362         pmaddwd   mm0, mm0
363         pmaddwd   mm1, mm1
364         paddd     mm0, mm1
365
366         movq      mm1, [eax+8]
367         movq      mm2, mm1
368         punpcklbw mm1, mm7
369         punpckhbw mm2, mm7
370         
371         movq      mm3, [eax+9]
372         movq      mm4, mm3
373         punpcklbw mm3, mm7
374         punpckhbw mm4, mm7
375         
376         paddw     mm1, mm3
377         paddw     mm2, mm4
378         
379         movq      mm3, [ebx+8]
380         movq      mm4, mm3
381         punpcklbw mm3, mm7
382         punpckhbw mm4, mm7
383         paddw     mm1, mm3
384         paddw     mm2, mm4 
385         
386         movq      mm3, [ebx+9]
387         movq      mm4, mm3
388         punpcklbw mm3, mm7
389         punpckhbw mm4, mm7
390
391         paddw     mm1, mm3
392         paddw     mm2, mm4
393
394         ;pxor     mm6, mm6    ; Zero mm6
395         ;pcmpeqw          mm5, mm5    ; mm5 = -1
396         ;psubw    mm6, mm5    ; mm6 = 1
397         ;paddw    mm6, mm6    ; mm6 = 2
398         ;paddw    mm1, mm6    ; round mm1 and mm2
399         ;paddw    mm2, mm6
400         movq      mm6, [twos]
401         paddw     mm1, mm6
402         paddw     mm2, mm6
403         
404         psrlw     mm1, 2
405         psrlw     mm2, 2
406
407         movq      mm3, [edx+8]
408         movq      mm4, mm3
409         punpcklbw mm3, mm7
410         punpckhbw mm4, mm7
411
412         psubw     mm1, mm3
413         psubw     mm2, mm4
414         pmaddwd   mm1, mm1
415         pmaddwd   mm2, mm2
416         paddd     mm1, mm2
417
418         paddd     mm0, mm1
419         
420         ;;
421         ;; Accumulate the result in "s" we use mm6 for the purpose...
422         ;movd     ecx, mm0
423     ;    add       s, ecx
424         ;psrlq    mm0, 32
425         ;movd     ecx, mm0
426         ;add      s, ecx
427         paddd     mm5, mm0
428
429         mov       eax, ebx    ; ahem ebx = eax at start of loop and wasn't changed...
430         add       ebx, esi   
431         add       edx, esi
432         dec       edi
433         jg        near d2top11
434
435
436 d2exit:
437         ;; Put the final sum in eax for return...
438         movd      eax, mm5
439         psrlq     mm5, 32
440         movd      ecx, mm5
441     add       eax, ecx
442
443         pop edi
444         pop esi
445         pop edx
446         pop ecx
447         pop ebx
448
449         pop ebp                 ; restore stack pointer
450
451         emms                    ; clear mmx registers
452         ret     
453
454
455 ; total squared difference between two (8*h) blocks
456 ; blk1,blk2: addresses of top left pels of both blocks
457 ; lx:        distance (in bytes) of vertically adjacent pels
458 ; h:         height of block (usually 4, or 8)
459 ; mmX version
460
461 global dist2_22_mmx
462 ; int dist2_22_mmx(unsigned char *blk1, unsigned char *blk2,
463 ;                 int lx, int h)
464
465 ; mm7 = 0
466
467 ; eax = pblk1 
468 ; ebx = pblk2
469 ; ecx = temp
470 ; edx = distance_sum
471 ; edi = h
472 ; esi = lx
473
474 align 32
475 dist2_22_mmx:
476         push ebp                        ; save frame pointer
477         mov ebp, esp            ; link
478         push ebx
479         push ecx
480         push edx
481         push esi     
482         push edi
483
484         mov             esi, [ebp+16] ; lx
485         mov     edi, [ebp+20] ; h
486
487     pxor      mm5, mm5      ; sum
488         test      edi, edi     ; h = 0?
489         jle       near d2exit
490
491         pxor      mm7, mm7     ; get zeros i mm7
492
493         mov       eax, [ebp+8]          ; blk1
494     mov       ebx, [ebp+12]             ; blk2
495         jmp      d2top22
496
497 align 32
498 d2top22:
499         movq      mm0, [eax]
500         movq      mm1, mm0
501         punpcklbw mm0, mm7
502         punpckhbw mm1, mm7
503
504         movq      mm2, [ebx]
505         movq      mm3, mm2
506         punpcklbw mm2, mm7
507         punpckhbw mm3, mm7
508
509         psubw     mm0, mm2
510         psubw     mm1, mm3
511         pmaddwd   mm0, mm0
512         pmaddwd   mm1, mm1
513         paddd     mm5, mm0
514                 paddd    mm5, mm1
515
516                         add       eax, esi
517         add       ebx, esi
518         dec       edi
519         jg        d2top22
520         jmp       d2exit
521
522
523 ; total squared difference between interpolation of two (8*h) blocks and
524 ; another 8*h block             
525 ; blk1,blk2: addresses of top left pels of both blocks
526 ; lx:        distance (in bytes) of vertically adjacent pels
527 ; h:         height of block (usually 4, or 8)
528 ; mmX version
529                 
530 global bdist2_22_mmx
531 ; int bdist2_22_mmx(unsigned char *blk1f, unsigned char*blk1b,
532 ;                                  unsigned char *blk2,
533 ;                 int lx, int h)
534
535 ; mm7 = 0
536
537 ; eax = pblk1f 
538 ; ebx = pblk2
539 ; ecx = pblk1b
540 ; edx = distance_sum
541 ; edi = h
542 ; esi = lx
543
544 align 32
545 bdist2_22_mmx:
546         push ebp                        ; save frame pointer
547         mov ebp, esp            ; link
548         push ebx
549         push ecx
550         push edx
551         push esi     
552         push edi
553
554         mov             esi, [ebp+20] ; lx
555         mov     edi, [ebp+24] ; h
556
557     pxor      mm5, mm5      ; sum
558         test      edi, edi     ; h = 0?
559         jle       near d2exit
560
561         pxor      mm7, mm7     ; get zeros i mm7
562
563         mov       eax, [ebp+8]          ; blk1f
564     mov       ebx, [ebp+12]             ; blk1b
565     mov       ecx, [ebp+16]             ; blk2          
566         jmp      bd2top22
567
568 align 32
569 bd2top22:
570         movq      mm0, [eax]
571         movq      mm1, mm0
572                 movq      mm4, [ebx]
573                 movq      mm6, mm4
574         punpcklbw mm0, mm7
575         punpckhbw mm1, mm7
576                 punpcklbw mm4, mm7
577                 punpckhbw mm6, mm7
578
579         movq      mm2, [ecx]
580         movq      mm3, mm2
581         punpcklbw mm2, mm7
582         punpckhbw mm3, mm7
583
584                 paddw     mm0, mm4
585                 psrlw     mm0, 1
586         psubw     mm0, mm2
587         pmaddwd   mm0, mm0
588                 paddw     mm1, mm6
589                 psrlw     mm1, 1
590         psubw     mm1, mm3
591         pmaddwd   mm1, mm1
592         paddd     mm5, mm0
593                 paddd    mm5, mm1
594
595                 add       eax, esi
596                 add       ebx, esi
597                 add               ecx, esi
598                 dec       edi
599                 jg        bd2top22
600                 jmp       d2exit
601