Merge CV, ver=5.1; ops/methods from HV, and interface from CV where possible
[goodguy/history.git] / cinelerra-5.1 / mpeg2enc / bdist2_mmx.s
diff --git a/cinelerra-5.1/mpeg2enc/bdist2_mmx.s b/cinelerra-5.1/mpeg2enc/bdist2_mmx.s
new file mode 100644 (file)
index 0000000..be1c352
--- /dev/null
@@ -0,0 +1,327 @@
+;
+;  bdist2_mmx.s:  MMX optimized bidirectional squared distance sum
+;
+;  Original believed to be Copyright (C) 2000 Brent Byeler
+;
+;  This program is free software; you can reaxstribute it and/or
+;  modify it under the terms of the GNU General Public License
+;  as published by the Free Software Foundation; either version 2
+;  of the License, or (at your option) any later version.
+;
+;  This program is distributed in the hope that it will be useful,
+;  but WITHOUT ANY WARRANTY; without even the implied warranty of
+;  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;  GNU General Public License for more details.
+;
+;  You should have received a copy of the GNU General Public License
+;  along with this program; if not, write to the Free Software
+;  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+;
+
+;/*
+; * squared error between a (16*h) block and a bidirectional
+; * prediction
+; *
+; * p2: address of top left pel of block
+; * pf,hxf,hyf: address and half pel flags of forward ref. block
+; * pb,hxb,hyb: address and half pel flags of backward ref. block
+; * h: height of block
+; * lx: distance (in bytes) of vertically adjacent pels in p2,pf,pb
+; * mmX version
+; */
+
+;int bdist2_mmx(
+;unsigned char *pf, unsigned char *pb, unsigned char *p2,
+;int lx, int hxf, int hyf, int hxb, int hyb, int h)
+;{
+;  unsigned char *pfa,*pfb,*pfc,*pba,*pbb,*pbc;
+;  int s;
+
+; Handy macros for readbility
+
+%define pf [ebp+8]
+%define pb [ebp+12]
+%define p2 [ebp+16]
+%define lx [ebp+20]
+%define hxf [ebp+24]
+%define hyf [ebp+28]
+%define hxb [ebp+32]
+%define hyb [ebp+36]
+%define h   [ebp+40]
+
+
+%define pfa [esp+4]
+%define pfb [esp+8]
+%define pfc [esp+12]
+%define pba [esp+16]
+%define pbb [esp+20]
+%define pbc [esp+24]
+
+SECTION .text
+global bdist2_mmx
+
+align 32
+bdist2_mmx:
+       push ebp                        ; save frame pointer
+       mov ebp, esp            ; link
+       push ebx
+       push ecx
+       push edx
+       push esi     
+       push edi
+
+       ;;
+       ;; Make space for local variables on stack
+       sub       esp, 32
+       
+       mov       edx, hxb
+       mov       eax, hxf
+       mov       esi, lx
+
+       mov       ecx, pf
+       add       ecx, eax
+       mov       pfa, ecx
+       mov       ecx, esi
+       imul      ecx, hyf
+       mov       ebx, pf
+       add       ecx, ebx
+       mov       pfb, ecx
+       add       eax, ecx
+       mov       pfc, eax
+       mov       eax, pb
+       add       eax, edx
+       mov       pba, eax
+       mov       eax, esi
+       imul      eax, hyb
+       mov       ecx, pb
+       add       eax, ecx
+       mov       pbb, eax
+       add       edx, eax
+       mov       pbc, edx
+       xor       esi, esi      ; esi = s (accumulated sym)
+       mov       eax, esi
+
+       mov       edi, h
+       test      edi, edi  ; h = 0?
+       jle       near bdist2exit
+
+       pxor      mm7, mm7
+       pxor      mm6, mm6
+       pcmpeqw   mm5, mm5
+       psubw     mm6, mm5
+       psllw     mm6, 1
+
+bdist2top:
+       mov       eax, pf
+       mov       ebx, pfa
+       mov       ecx, pfb
+       mov       edx, pfc
+       movq      mm0, [eax]
+       movq      mm1, mm0
+       punpcklbw mm0, mm7
+       punpckhbw mm1, mm7
+       movq      mm2, [ebx]
+       movq      mm3, mm2
+       punpcklbw mm2, mm7
+       punpckhbw mm3, mm7
+       paddw     mm0, mm2
+       paddw     mm1, mm3
+       movq      mm2, [ecx]
+       movq      mm3, mm2
+       punpcklbw mm2, mm7
+       punpckhbw mm3, mm7
+       paddw     mm0, mm2
+       paddw     mm1, mm3
+       movq      mm2, [edx]
+       movq      mm3, mm2
+       punpcklbw mm2, mm7
+       punpckhbw mm3, mm7
+       paddw     mm0, mm2
+       paddw     mm1, mm3
+       paddw     mm0, mm6
+       paddw     mm1, mm6
+       psrlw     mm0, 2
+       psrlw     mm1, 2
+
+       mov       eax, pb
+       mov       ebx, pba
+       mov       ecx, pbb
+       mov       edx, pbc
+       movq      mm2, [eax]
+       movq      mm3, mm2
+       punpcklbw mm2, mm7
+       punpckhbw mm3, mm7
+       movq      mm4, [ebx]
+       movq      mm5, mm4
+       punpcklbw mm4, mm7
+       punpckhbw mm5, mm7
+       paddw     mm2, mm4
+       paddw     mm3, mm5
+       movq      mm4, [ecx]
+       movq      mm5, mm4
+       punpcklbw mm4, mm7
+       punpckhbw mm5, mm7
+       paddw     mm2, mm4
+       paddw     mm3, mm5
+       movq      mm4, [edx]
+       movq      mm5, mm4
+       punpcklbw mm4, mm7
+       punpckhbw mm5, mm7
+       paddw     mm2, mm4
+       paddw     mm3, mm5
+
+       paddw     mm2, mm6
+       paddw     mm3, mm6
+       psrlw     mm2, 2
+       psrlw     mm3, 2
+
+       paddw     mm0, mm2
+       paddw     mm1, mm3
+       psrlw     mm6, 1
+       paddw     mm0, mm6
+       paddw     mm1, mm6
+       psllw     mm6, 1
+       psrlw     mm0, 1
+       psrlw     mm1, 1
+
+       mov       eax, p2
+       movq      mm2, [eax]
+       movq      mm3, mm2
+        punpcklbw mm2, mm7
+        punpckhbw mm3, mm7
+
+        psubw     mm0, mm2
+        psubw     mm1, mm3
+        pmaddwd   mm0, mm0
+        pmaddwd   mm1, mm1
+        paddd     mm0, mm1
+
+       movd      eax, mm0
+       psrlq     mm0, 32
+       movd      ebx, mm0
+       add       esi, eax
+       add       esi, ebx
+
+       mov       eax, pf
+       mov       ebx, pfa
+       mov       ecx, pfb
+       mov       edx, pfc
+       movq      mm0, [eax+8]
+       movq      mm1, mm0
+       punpcklbw mm0, mm7
+       punpckhbw mm1, mm7
+       movq      mm2, [ebx+8]
+       movq      mm3, mm2
+       punpcklbw mm2, mm7
+       punpckhbw mm3, mm7
+       paddw     mm0, mm2
+       paddw     mm1, mm3
+       movq      mm2, [ecx+8]
+       movq      mm3, mm2
+       punpcklbw mm2, mm7
+       punpckhbw mm3, mm7
+       paddw     mm0, mm2
+       paddw     mm1, mm3
+       movq      mm2, [edx+8]
+       movq      mm3, mm2
+       punpcklbw mm2, mm7
+       punpckhbw mm3, mm7
+       paddw     mm0, mm2
+       paddw     mm1, mm3
+       paddw     mm0, mm6
+       paddw     mm1, mm6
+       psrlw     mm0, 2
+       psrlw     mm1, 2
+
+       mov       eax, pb
+       mov       ebx, pba
+       mov       ecx, pbb
+       mov       edx, pbc
+       movq      mm2, [eax+8]
+       movq      mm3, mm2
+       punpcklbw mm2, mm7
+       punpckhbw mm3, mm7
+       movq      mm4, [ebx+8]
+       movq      mm5, mm4
+       punpcklbw mm4, mm7
+       punpckhbw mm5, mm7
+       paddw     mm2, mm4
+       paddw     mm3, mm5
+       movq      mm4, [ecx+8]
+       movq      mm5, mm4
+       punpcklbw mm4, mm7
+       punpckhbw mm5, mm7
+       paddw     mm2, mm4
+       paddw     mm3, mm5
+       movq      mm4, [edx+8]
+       movq      mm5, mm4
+       punpcklbw mm4, mm7
+       punpckhbw mm5, mm7
+       paddw     mm2, mm4
+       paddw     mm3, mm5
+       paddw     mm2, mm6
+       paddw     mm3, mm6
+       psrlw     mm2, 2
+       psrlw     mm3, 2
+
+       paddw     mm0, mm2
+       paddw     mm1, mm3
+       psrlw     mm6, 1
+       paddW     mm0, mm6
+       paddw     mm1, mm6
+       psllw     mm6, 1
+       psrlw     mm0, 1
+       psrlw     mm1, 1
+
+       mov       eax, p2
+       movq      mm2, [eax+8]
+       movq      mm3, mm2
+        punpcklbw mm2, mm7
+        punpckhbw mm3, mm7
+
+        psubw     mm0, mm2
+        psubw     mm1, mm3
+        pmaddwd   mm0, mm0
+        pmaddwd   mm1, mm1
+        paddd     mm0, mm1
+
+       movd      eax, mm0
+       psrlq     mm0, 32
+       movd      ebx, mm0
+       add       esi, eax
+       add       esi, ebx
+
+    mov       eax, lx
+       add       p2, eax
+       add       pf, eax
+       add       pfa, eax
+       add       pfb, eax
+       add       pfc, eax
+       add       pb, eax
+       add       pba, eax
+       add       pbb, eax
+       add       pbc, eax
+
+       dec       edi
+       jg        near bdist2top
+    mov       eax, esi
+
+bdist2exit:
+       
+       ;;
+       ;; Get rid of local variables
+       add esp, 32
+       
+       ;; Retore (callee saves convention...)
+       ;;
+       pop edi
+       pop esi
+       pop edx
+       pop ecx
+       pop ebx
+
+       pop ebp                 ; restore stack pointer
+
+       emms                    ; clear mmx registers
+       ret     
+