327 lines
9.2 KiB
NASM
327 lines
9.2 KiB
NASM
;*****************************************************************************
|
|
;* mc-a2.asm: h264 encoder library
|
|
;*****************************************************************************
|
|
;* Copyright (C) 2005 x264 project
|
|
;*
|
|
;* This program is CC_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., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
|
|
;*****************************************************************************
|
|
|
|
BITS 64
|
|
|
|
;=============================================================================
|
|
; Macros and other preprocessor constants
|
|
;=============================================================================
|
|
|
|
%include "amd64inc.asm"
|
|
|
|
;=============================================================================
|
|
; Read only data
|
|
;=============================================================================
|
|
|
|
SECTION .rodata align=16
|
|
|
|
ALIGN 16
|
|
pw_1: times 4 dw 1
|
|
pw_16: times 4 dw 16
|
|
pw_32: times 4 dw 32
|
|
|
|
;=============================================================================
|
|
; Macros
|
|
;=============================================================================
|
|
|
|
%macro LOAD_ADD 3
|
|
movd %1, %2
|
|
movd mm7, %3
|
|
punpcklbw %1, mm0
|
|
punpcklbw mm7, mm0
|
|
paddw %1, mm7
|
|
%endmacro
|
|
|
|
%macro FILT_V 0
|
|
psubw mm1, mm2 ; a-b
|
|
psubw mm4, mm5
|
|
psubw mm2, mm3 ; b-c
|
|
psubw mm5, mm6
|
|
psllw mm2, 2
|
|
psllw mm5, 2
|
|
psubw mm1, mm2 ; a-5*b+4*c
|
|
psubw mm4, mm5
|
|
psllw mm3, 4
|
|
psllw mm6, 4
|
|
paddw mm1, mm3 ; a-5*b+20*c
|
|
paddw mm4, mm6
|
|
%endmacro
|
|
|
|
%macro FILT_H 0
|
|
psubw mm1, mm2 ; a-b
|
|
psubw mm4, mm5
|
|
psraw mm1, 2 ; (a-b)/4
|
|
psraw mm4, 2
|
|
psubw mm1, mm2 ; (a-b)/4-b
|
|
psubw mm4, mm5
|
|
paddw mm1, mm3 ; (a-b)/4-b+c
|
|
paddw mm4, mm6
|
|
psraw mm1, 2 ; ((a-b)/4-b+c)/4
|
|
psraw mm4, 2
|
|
paddw mm1, mm3 ; ((a-b)/4-b+c)/4+c = (a-5*b+20*c)/16
|
|
paddw mm4, mm6
|
|
%endmacro
|
|
|
|
%macro FILT_PACK 1
|
|
paddw mm1, mm7
|
|
paddw mm4, mm7
|
|
psraw mm1, %1
|
|
psraw mm4, %1
|
|
packuswb mm1, mm4
|
|
%endmacro
|
|
|
|
|
|
;=============================================================================
|
|
; Code
|
|
;=============================================================================
|
|
|
|
SECTION .text
|
|
|
|
cglobal x264_hpel_filter_mmxext
|
|
cglobal x264_plane_copy_mmxext
|
|
|
|
;-----------------------------------------------------------------------------
|
|
; void x264_hpel_filter_mmxext( uint8_t *dsth, uint8_t *dstv, uint8_t *dstc, uint8_t *src,
|
|
; int i_stride, int i_width, int i_height );
|
|
;-----------------------------------------------------------------------------
|
|
|
|
ALIGN 16
|
|
x264_hpel_filter_mmxext :
|
|
|
|
%ifdef WIN64
|
|
push rdi
|
|
pushreg rdi
|
|
push rsi
|
|
pushreg rsi
|
|
%endif
|
|
push rbp
|
|
pushreg rbp
|
|
push rbx
|
|
pushreg rbx
|
|
mov rbp, rsp
|
|
setframe rbp, 0
|
|
endprolog
|
|
|
|
%ifdef WIN64
|
|
mov rdi, parm1q
|
|
mov rsi, parm2q
|
|
mov rdx, parm3q
|
|
mov rcx, parm4q
|
|
movsxd r8, dword [rbp+72]
|
|
movsxd r9, dword [rbp+80]
|
|
mov ebx, dword [rbp+88]
|
|
%else
|
|
mov ebx, dword [rbp+24]
|
|
%endif
|
|
%define dsth rdi
|
|
%define dstv rsi
|
|
%define dstc rdx
|
|
%define src rcx
|
|
%define stride r8
|
|
%define width r9
|
|
%define height ebx
|
|
%define stride3 r10
|
|
%define stride5 r11
|
|
%define x rax
|
|
%define tbuffer rsp + 8
|
|
|
|
lea stride3, [stride*3]
|
|
lea stride5, [stride*5]
|
|
sub src, stride
|
|
sub src, stride
|
|
|
|
lea rax, [stride*2 + 24]
|
|
sub rsp, rax
|
|
|
|
pxor mm0, mm0
|
|
|
|
.loopy:
|
|
|
|
xor x, x
|
|
ALIGN 16
|
|
.vertical_filter:
|
|
|
|
prefetchnta [src + stride5 + 32]
|
|
|
|
LOAD_ADD mm1, [src ], [src + stride5 ] ; a0
|
|
LOAD_ADD mm2, [src + stride ], [src + stride*4 ] ; b0
|
|
LOAD_ADD mm3, [src + stride*2 ], [src + stride3 ] ; c0
|
|
LOAD_ADD mm4, [src + 4], [src + stride5 + 4] ; a1
|
|
LOAD_ADD mm5, [src + stride + 4], [src + stride*4 + 4] ; b1
|
|
LOAD_ADD mm6, [src + stride*2 + 4], [src + stride3 + 4] ; c1
|
|
|
|
FILT_V
|
|
|
|
movq mm7, [pw_16 GLOBAL]
|
|
movq [tbuffer + x*2], mm1
|
|
movq [tbuffer + x*2 + 8], mm4
|
|
paddw mm1, mm7
|
|
paddw mm4, mm7
|
|
psraw mm1, 5
|
|
psraw mm4, 5
|
|
packuswb mm1, mm4
|
|
movntq [dstv + x], mm1
|
|
|
|
add x, 8
|
|
add src, 8
|
|
cmp x, width
|
|
jle .vertical_filter
|
|
|
|
pshufw mm2, [tbuffer], 0
|
|
movq [tbuffer - 8], mm2 ; pad left
|
|
; no need to pad right, since vertical_filter already did 4 extra pixels
|
|
|
|
sub src, x
|
|
xor x, x
|
|
movq mm7, [pw_32 GLOBAL]
|
|
.center_filter:
|
|
|
|
movq mm1, [tbuffer + x*2 - 4 ]
|
|
movq mm2, [tbuffer + x*2 - 2 ]
|
|
movq mm3, [tbuffer + x*2 ]
|
|
movq mm4, [tbuffer + x*2 + 4 ]
|
|
movq mm5, [tbuffer + x*2 + 6 ]
|
|
paddw mm3, [tbuffer + x*2 + 2 ] ; c0
|
|
paddw mm2, mm4 ; b0
|
|
paddw mm1, mm5 ; a0
|
|
movq mm6, [tbuffer + x*2 + 8 ]
|
|
paddw mm4, [tbuffer + x*2 + 14] ; a1
|
|
paddw mm5, [tbuffer + x*2 + 12] ; b1
|
|
paddw mm6, [tbuffer + x*2 + 10] ; c1
|
|
|
|
FILT_H
|
|
FILT_PACK 6
|
|
movntq [dstc + x], mm1
|
|
|
|
add x, 8
|
|
cmp x, width
|
|
jl .center_filter
|
|
|
|
lea src, [src + stride*2]
|
|
xor x, x
|
|
.horizontal_filter:
|
|
|
|
movd mm1, [src + x - 2]
|
|
movd mm2, [src + x - 1]
|
|
movd mm3, [src + x ]
|
|
movd mm6, [src + x + 1]
|
|
movd mm4, [src + x + 2]
|
|
movd mm5, [src + x + 3]
|
|
punpcklbw mm1, mm0
|
|
punpcklbw mm2, mm0
|
|
punpcklbw mm3, mm0
|
|
punpcklbw mm6, mm0
|
|
punpcklbw mm4, mm0
|
|
punpcklbw mm5, mm0
|
|
paddw mm3, mm6 ; c0
|
|
paddw mm2, mm4 ; b0
|
|
paddw mm1, mm5 ; a0
|
|
movd mm7, [src + x + 7]
|
|
movd mm6, [src + x + 6]
|
|
punpcklbw mm7, mm0
|
|
punpcklbw mm6, mm0
|
|
paddw mm4, mm7 ; c1
|
|
paddw mm5, mm6 ; b1
|
|
movd mm7, [src + x + 5]
|
|
movd mm6, [src + x + 4]
|
|
punpcklbw mm7, mm0
|
|
punpcklbw mm6, mm0
|
|
paddw mm6, mm7 ; a1
|
|
|
|
movq mm7, [pw_1 GLOBAL]
|
|
FILT_H
|
|
FILT_PACK 1
|
|
movntq [dsth + x], mm1
|
|
|
|
add x, 8
|
|
cmp x, width
|
|
jl .horizontal_filter
|
|
|
|
sub src, stride
|
|
add dsth, stride
|
|
add dstv, stride
|
|
add dstc, stride
|
|
dec height
|
|
jg .loopy
|
|
|
|
mov rsp, rbp
|
|
pop rbx
|
|
pop rbp
|
|
%ifdef WIN64
|
|
pop rsi
|
|
pop rdi
|
|
%endif
|
|
ret
|
|
|
|
|
|
|
|
;-----------------------------------------------------------------------------
|
|
; void x264_plane_copy_mmxext( uint8_t *dst, int i_dst,
|
|
; uint8_t *src, int i_src, int w, int h)
|
|
;-----------------------------------------------------------------------------
|
|
ALIGN 16
|
|
x264_plane_copy_mmxext:
|
|
movsxd parm2q, parm2d
|
|
movsxd parm4q, parm4d
|
|
add parm5d, 3
|
|
and parm5d, ~3
|
|
sub parm2q, parm5q
|
|
sub parm4q, parm5q
|
|
; shuffle regs because movsd needs dst=rdi, src=rsi, w=ecx
|
|
xchg rsi, rdx
|
|
mov rax, parm4q
|
|
.loopy:
|
|
mov ecx, parm5d
|
|
sub ecx, 64
|
|
jl .endx
|
|
.loopx:
|
|
prefetchnta [rsi+256]
|
|
movq mm0, [rsi ]
|
|
movq mm1, [rsi+ 8]
|
|
movq mm2, [rsi+16]
|
|
movq mm3, [rsi+24]
|
|
movq mm4, [rsi+32]
|
|
movq mm5, [rsi+40]
|
|
movq mm6, [rsi+48]
|
|
movq mm7, [rsi+56]
|
|
movntq [rdi ], mm0
|
|
movntq [rdi+ 8], mm1
|
|
movntq [rdi+16], mm2
|
|
movntq [rdi+24], mm3
|
|
movntq [rdi+32], mm4
|
|
movntq [rdi+40], mm5
|
|
movntq [rdi+48], mm6
|
|
movntq [rdi+56], mm7
|
|
add rsi, 64
|
|
add rdi, 64
|
|
sub ecx, 64
|
|
jge .loopx
|
|
.endx:
|
|
prefetchnta [rsi+256]
|
|
add ecx, 64
|
|
shr ecx, 2
|
|
rep movsd
|
|
add rdi, rdx
|
|
add rsi, rax
|
|
sub parm6d, 1
|
|
jg .loopy
|
|
emms
|
|
ret
|
|
|