;**************************************************************************
;* Copyright (C) 2007 Loren Merritt <lorenm@u.washington.edu>
;*
;* This program is free software; you can redistribute 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
;**************************************************************************

%include "amd64inc.asm"

section .text align=16

; void xlsc_mc_copy_16_mmx( uint8_t *dst, uint8_t *src, int strided, int strides, int height )
%macro MC_COPY 1
cglobal xlsc_mc_copy_%1_mmx
    lea    r10, [parm3q*3]
    lea    r11, [parm4q*3]
.loop:
    movq   mm0, [parm2q]
    movq   mm1, [parm2q+parm4q]
    movq   mm2, [parm2q+8]
    movq   mm3, [parm2q+8+parm4q]
%if %1 == 24
    movq   mm4, [parm2q+16]
    movq   mm5, [parm2q+16+parm4q]
%endif
    movq   [parm1q], mm0
    movq   [parm1q+parm3q], mm1
    movq   [parm1q+8], mm2
    movq   [parm1q+8+parm3q], mm3
%if %1 == 24
    movq   [parm1q+16], mm4
    movq   [parm1q+16+parm3q], mm5
%endif
    movq   mm0, [parm2q+2*parm4q]
    movq   mm1, [parm2q+r11]
    movq   mm2, [parm2q+8+2*parm4q]
    movq   mm3, [parm2q+8+r11]
%if %1 == 24
    movq   mm4, [parm2q+16+2*parm4q]
    movq   mm5, [parm2q+16+r11]
%endif
    movq   [parm1q+2*parm3q], mm0
    movq   [parm1q+r10], mm1
    movq   [parm1q+8+2*parm3q], mm2
    movq   [parm1q+8+r10], mm3
%if %1 == 24
    movq   [parm1q+16+2*parm3q], mm4
    movq   [parm1q+16+r10], mm5
%endif
    lea    parm2q, [parm2q+4*parm4q]
    lea    parm1q, [parm1q+4*parm3q]
    sub    parm5d, byte 4
    jg .loop
    rep ret
%endmacro

MC_COPY 16
MC_COPY 24

; void xlsc_mc_h_16_mmx2( uint8_t *dst, uint8_t *src, int strided, int strides, int height )
%macro MC_AVG 3
cglobal xlsc_mc_%2_%1_mmx2
.loop:
    movq   mm0, [parm2q]
    movq   mm1, [parm2q+8]
%if %1 == 24
    movq   mm2, [parm2q+16]
%endif
    pavgb  mm0, [parm2q+%3]
    pavgb  mm1, [parm2q+%3+8]
%if %1 == 24
    pavgb  mm2, [parm2q+%3+16]
%endif
    movq   [parm1q], mm0
    movq   [parm1q+8], mm1
%if %1 == 24
    movq   [parm1q+16], mm2
%endif
    add    parm1q, parm3q
    add    parm2q, parm4q
    sub    parm5d, 1
    jg .loop
    rep ret
%endmacro

MC_AVG 16, h, 1
MC_AVG 24, h, 1
MC_AVG 16, v, parm4q
MC_AVG 24, v, parm4q

; void xlsc_mc_hv_16_mmx2( uint8_t *dst, uint8_t *src, int strided, int strides, int height )
%macro MC_HV 1
cglobal xlsc_mc_hv_%1_mmx2
    movq   mm0, [parm2q]
    movq   mm1, [parm2q+8]
%if %1 == 24
    movq   mm2, [parm2q+16]
%endif
    pavgb  mm0, [parm2q+1]
    pavgb  mm1, [parm2q+9]
%if %1 == 24
    pavgb  mm2, [parm2q+17]
%endif
.loop:
    add    parm2q, parm4q
    movq   mm3, [parm2q]
    movq   mm4, [parm2q+8]
%if %1 == 24
    movq   mm5, [parm2q+16]
%endif
    pavgb  mm3, [parm2q+1]
    pavgb  mm4, [parm2q+9]
%if %1 == 24
    pavgb  mm5, [parm2q+17]
%endif
    pavgb  mm0, mm3
    pavgb  mm1, mm4
%if %1 == 24
    pavgb  mm2, mm5
%endif
    movq   [parm1q], mm0
    movq   [parm1q+8], mm1
%if %1 == 24
    movq   [parm1q+16], mm2
%endif
    movq   mm0, mm3
    movq   mm1, mm4
%if %1 == 24
    movq   mm2, mm5
%endif
    add    parm1q, parm3q
    sub    parm5d, 1
    jg .loop
    rep ret
%endmacro

MC_HV 16
MC_HV 24
