09202d8071
Change-Id: Ieebea089095d9073b3a94932791099f614ce120c
819 lines
26 KiB
NASM
819 lines
26 KiB
NASM
;
|
|
; Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
|
|
;
|
|
; Use of this source code is governed by a BSD-style license
|
|
; that can be found in the LICENSE file in the root of the source
|
|
; tree. An additional intellectual property rights grant can be found
|
|
; in the file PATENTS. All contributing project authors may
|
|
; be found in the AUTHORS file in the root of the source tree.
|
|
;
|
|
|
|
|
|
%include "vpx_ports/x86_abi_support.asm"
|
|
|
|
|
|
%define BLOCK_HEIGHT_WIDTH 4
|
|
%define vp8_filter_weight 128
|
|
%define VP8_FILTER_SHIFT 7
|
|
|
|
|
|
;void vp8_filter_block1d_h6_mmx
|
|
;(
|
|
; unsigned char *src_ptr,
|
|
; unsigned short *output_ptr,
|
|
; unsigned int src_pixels_per_line,
|
|
; unsigned int pixel_step,
|
|
; unsigned int output_height,
|
|
; unsigned int output_width,
|
|
; short * vp8_filter
|
|
;)
|
|
global sym(vp8_filter_block1d_h6_mmx)
|
|
sym(vp8_filter_block1d_h6_mmx):
|
|
push rbp
|
|
mov rbp, rsp
|
|
SHADOW_ARGS_TO_STACK 7
|
|
GET_GOT rbx
|
|
push rsi
|
|
push rdi
|
|
; end prolog
|
|
|
|
mov rdx, arg(6) ;vp8_filter
|
|
|
|
movq mm1, [rdx + 16] ; do both the negative taps first!!!
|
|
movq mm2, [rdx + 32] ;
|
|
movq mm6, [rdx + 48] ;
|
|
movq mm7, [rdx + 64] ;
|
|
|
|
mov rdi, arg(1) ;output_ptr
|
|
mov rsi, arg(0) ;src_ptr
|
|
movsxd rcx, dword ptr arg(4) ;output_height
|
|
movsxd rax, dword ptr arg(5) ;output_width ; destination pitch?
|
|
pxor mm0, mm0 ; mm0 = 00000000
|
|
|
|
nextrow:
|
|
movq mm3, [rsi-2] ; mm3 = p-2..p5
|
|
movq mm4, mm3 ; mm4 = p-2..p5
|
|
psrlq mm3, 8 ; mm3 = p-1..p5
|
|
punpcklbw mm3, mm0 ; mm3 = p-1..p2
|
|
pmullw mm3, mm1 ; mm3 *= kernel 1 modifiers.
|
|
|
|
movq mm5, mm4 ; mm5 = p-2..p5
|
|
punpckhbw mm4, mm0 ; mm5 = p2..p5
|
|
pmullw mm4, mm7 ; mm5 *= kernel 4 modifiers
|
|
paddsw mm3, mm4 ; mm3 += mm5
|
|
|
|
movq mm4, mm5 ; mm4 = p-2..p5;
|
|
psrlq mm5, 16 ; mm5 = p0..p5;
|
|
punpcklbw mm5, mm0 ; mm5 = p0..p3
|
|
pmullw mm5, mm2 ; mm5 *= kernel 2 modifiers
|
|
paddsw mm3, mm5 ; mm3 += mm5
|
|
|
|
movq mm5, mm4 ; mm5 = p-2..p5
|
|
psrlq mm4, 24 ; mm4 = p1..p5
|
|
punpcklbw mm4, mm0 ; mm4 = p1..p4
|
|
pmullw mm4, mm6 ; mm5 *= kernel 3 modifiers
|
|
paddsw mm3, mm4 ; mm3 += mm5
|
|
|
|
; do outer positive taps
|
|
movd mm4, [rsi+3]
|
|
punpcklbw mm4, mm0 ; mm5 = p3..p6
|
|
pmullw mm4, [rdx+80] ; mm5 *= kernel 0 modifiers
|
|
paddsw mm3, mm4 ; mm3 += mm5
|
|
|
|
punpcklbw mm5, mm0 ; mm5 = p-2..p1
|
|
pmullw mm5, [rdx] ; mm5 *= kernel 5 modifiers
|
|
paddsw mm3, mm5 ; mm3 += mm5
|
|
|
|
paddsw mm3, [rd GLOBAL] ; mm3 += round value
|
|
psraw mm3, VP8_FILTER_SHIFT ; mm3 /= 128
|
|
packuswb mm3, mm0 ; pack and unpack to saturate
|
|
punpcklbw mm3, mm0 ;
|
|
|
|
movq [rdi], mm3 ; store the results in the destination
|
|
|
|
%if ABI_IS_32BIT
|
|
add rsi, dword ptr arg(2) ;src_pixels_per_line ; next line
|
|
add rdi, rax;
|
|
%else
|
|
movsxd r8, dword ptr arg(2) ;src_pixels_per_line
|
|
add rdi, rax;
|
|
|
|
add rsi, r8 ; next line
|
|
%endif
|
|
|
|
dec rcx ; decrement count
|
|
jnz nextrow ; next row
|
|
|
|
; begin epilog
|
|
pop rdi
|
|
pop rsi
|
|
RESTORE_GOT
|
|
UNSHADOW_ARGS
|
|
pop rbp
|
|
ret
|
|
|
|
|
|
;
|
|
; THIS FUNCTION APPEARS TO BE UNUSED
|
|
;
|
|
;void vp8_filter_block1d_v6_mmx
|
|
;(
|
|
; short *src_ptr,
|
|
; unsigned char *output_ptr,
|
|
; unsigned int pixels_per_line,
|
|
; unsigned int pixel_step,
|
|
; unsigned int output_height,
|
|
; unsigned int output_width,
|
|
; short * vp8_filter
|
|
;)
|
|
global sym(vp8_filter_block1d_v6_mmx)
|
|
sym(vp8_filter_block1d_v6_mmx):
|
|
push rbp
|
|
mov rbp, rsp
|
|
SHADOW_ARGS_TO_STACK 7
|
|
GET_GOT rbx
|
|
push rsi
|
|
push rdi
|
|
; end prolog
|
|
|
|
movq mm5, [rd GLOBAL]
|
|
push rbx
|
|
mov rbx, arg(6) ;vp8_filter
|
|
movq mm1, [rbx + 16] ; do both the negative taps first!!!
|
|
movq mm2, [rbx + 32] ;
|
|
movq mm6, [rbx + 48] ;
|
|
movq mm7, [rbx + 64] ;
|
|
|
|
movsxd rdx, dword ptr arg(2) ;pixels_per_line
|
|
mov rdi, arg(1) ;output_ptr
|
|
mov rsi, arg(0) ;src_ptr
|
|
sub rsi, rdx
|
|
sub rsi, rdx
|
|
movsxd rcx, DWORD PTR arg(4) ;output_height
|
|
movsxd rax, DWORD PTR arg(5) ;output_width ; destination pitch?
|
|
pxor mm0, mm0 ; mm0 = 00000000
|
|
|
|
|
|
nextrow_v:
|
|
movq mm3, [rsi+rdx] ; mm3 = p0..p8 = row -1
|
|
pmullw mm3, mm1 ; mm3 *= kernel 1 modifiers.
|
|
|
|
|
|
movq mm4, [rsi + 4*rdx] ; mm4 = p0..p3 = row 2
|
|
pmullw mm4, mm7 ; mm4 *= kernel 4 modifiers.
|
|
paddsw mm3, mm4 ; mm3 += mm4
|
|
|
|
movq mm4, [rsi + 2*rdx] ; mm4 = p0..p3 = row 0
|
|
pmullw mm4, mm2 ; mm4 *= kernel 2 modifiers.
|
|
paddsw mm3, mm4 ; mm3 += mm4
|
|
|
|
movq mm4, [rsi] ; mm4 = p0..p3 = row -2
|
|
pmullw mm4, [rbx] ; mm4 *= kernel 0 modifiers.
|
|
paddsw mm3, mm4 ; mm3 += mm4
|
|
|
|
|
|
add rsi, rdx ; move source forward 1 line to avoid 3 * pitch
|
|
movq mm4, [rsi + 2*rdx] ; mm4 = p0..p3 = row 1
|
|
pmullw mm4, mm6 ; mm4 *= kernel 3 modifiers.
|
|
paddsw mm3, mm4 ; mm3 += mm4
|
|
|
|
movq mm4, [rsi + 4*rdx] ; mm4 = p0..p3 = row 3
|
|
pmullw mm4, [rbx +80] ; mm4 *= kernel 3 modifiers.
|
|
paddsw mm3, mm4 ; mm3 += mm4
|
|
|
|
|
|
paddsw mm3, mm5 ; mm3 += round value
|
|
psraw mm3, VP8_FILTER_SHIFT ; mm3 /= 128
|
|
packuswb mm3, mm0 ; pack and saturate
|
|
|
|
movd [rdi],mm3 ; store the results in the destination
|
|
|
|
add rdi,rax;
|
|
|
|
dec rcx ; decrement count
|
|
jnz nextrow_v ; next row
|
|
|
|
pop rbx
|
|
|
|
; begin epilog
|
|
pop rdi
|
|
pop rsi
|
|
RESTORE_GOT
|
|
UNSHADOW_ARGS
|
|
pop rbp
|
|
ret
|
|
|
|
|
|
;void vp8_filter_block1dc_v6_mmx
|
|
;(
|
|
; short *src_ptr,
|
|
; unsigned char *output_ptr,
|
|
; int output_pitch,
|
|
; unsigned int pixels_per_line,
|
|
; unsigned int pixel_step,
|
|
; unsigned int output_height,
|
|
; unsigned int output_width,
|
|
; short * vp8_filter
|
|
;)
|
|
global sym(vp8_filter_block1dc_v6_mmx)
|
|
sym(vp8_filter_block1dc_v6_mmx):
|
|
push rbp
|
|
mov rbp, rsp
|
|
SHADOW_ARGS_TO_STACK 8
|
|
GET_GOT rbx
|
|
push rsi
|
|
push rdi
|
|
; end prolog
|
|
|
|
movq mm5, [rd GLOBAL]
|
|
push rbx
|
|
mov rbx, arg(7) ;vp8_filter
|
|
movq mm1, [rbx + 16] ; do both the negative taps first!!!
|
|
movq mm2, [rbx + 32] ;
|
|
movq mm6, [rbx + 48] ;
|
|
movq mm7, [rbx + 64] ;
|
|
|
|
movsxd rdx, dword ptr arg(3) ;pixels_per_line
|
|
mov rdi, arg(1) ;output_ptr
|
|
mov rsi, arg(0) ;src_ptr
|
|
sub rsi, rdx
|
|
sub rsi, rdx
|
|
movsxd rcx, DWORD PTR arg(5) ;output_height
|
|
movsxd rax, DWORD PTR arg(2) ;output_pitch ; destination pitch?
|
|
pxor mm0, mm0 ; mm0 = 00000000
|
|
|
|
|
|
nextrow_cv:
|
|
movq mm3, [rsi+rdx] ; mm3 = p0..p8 = row -1
|
|
pmullw mm3, mm1 ; mm3 *= kernel 1 modifiers.
|
|
|
|
|
|
movq mm4, [rsi + 4*rdx] ; mm4 = p0..p3 = row 2
|
|
pmullw mm4, mm7 ; mm4 *= kernel 4 modifiers.
|
|
paddsw mm3, mm4 ; mm3 += mm4
|
|
|
|
movq mm4, [rsi + 2*rdx] ; mm4 = p0..p3 = row 0
|
|
pmullw mm4, mm2 ; mm4 *= kernel 2 modifiers.
|
|
paddsw mm3, mm4 ; mm3 += mm4
|
|
|
|
movq mm4, [rsi] ; mm4 = p0..p3 = row -2
|
|
pmullw mm4, [rbx] ; mm4 *= kernel 0 modifiers.
|
|
paddsw mm3, mm4 ; mm3 += mm4
|
|
|
|
|
|
add rsi, rdx ; move source forward 1 line to avoid 3 * pitch
|
|
movq mm4, [rsi + 2*rdx] ; mm4 = p0..p3 = row 1
|
|
pmullw mm4, mm6 ; mm4 *= kernel 3 modifiers.
|
|
paddsw mm3, mm4 ; mm3 += mm4
|
|
|
|
movq mm4, [rsi + 4*rdx] ; mm4 = p0..p3 = row 3
|
|
pmullw mm4, [rbx +80] ; mm4 *= kernel 3 modifiers.
|
|
paddsw mm3, mm4 ; mm3 += mm4
|
|
|
|
|
|
paddsw mm3, mm5 ; mm3 += round value
|
|
psraw mm3, VP8_FILTER_SHIFT ; mm3 /= 128
|
|
packuswb mm3, mm0 ; pack and saturate
|
|
|
|
movd [rdi],mm3 ; store the results in the destination
|
|
; the subsequent iterations repeat 3 out of 4 of these reads. Since the
|
|
; recon block should be in cache this shouldn't cost much. Its obviously
|
|
; avoidable!!!.
|
|
lea rdi, [rdi+rax] ;
|
|
dec rcx ; decrement count
|
|
jnz nextrow_cv ; next row
|
|
|
|
pop rbx
|
|
|
|
; begin epilog
|
|
pop rdi
|
|
pop rsi
|
|
RESTORE_GOT
|
|
UNSHADOW_ARGS
|
|
pop rbp
|
|
ret
|
|
|
|
|
|
;void bilinear_predict8x8_mmx
|
|
;(
|
|
; unsigned char *src_ptr,
|
|
; int src_pixels_per_line,
|
|
; int xoffset,
|
|
; int yoffset,
|
|
; unsigned char *dst_ptr,
|
|
; int dst_pitch
|
|
;)
|
|
global sym(vp8_bilinear_predict8x8_mmx)
|
|
sym(vp8_bilinear_predict8x8_mmx):
|
|
push rbp
|
|
mov rbp, rsp
|
|
SHADOW_ARGS_TO_STACK 6
|
|
GET_GOT rbx
|
|
push rsi
|
|
push rdi
|
|
; end prolog
|
|
|
|
;const short *HFilter = bilinear_filters_mmx[xoffset];
|
|
;const short *VFilter = bilinear_filters_mmx[yoffset];
|
|
|
|
movsxd rax, dword ptr arg(2) ;xoffset
|
|
mov rdi, arg(4) ;dst_ptr ;
|
|
|
|
shl rax, 5 ; offset * 32
|
|
lea rcx, [sym(vp8_bilinear_filters_mmx) GLOBAL]
|
|
|
|
add rax, rcx ; HFilter
|
|
mov rsi, arg(0) ;src_ptr ;
|
|
|
|
movsxd rdx, dword ptr arg(5) ;dst_pitch
|
|
movq mm1, [rax] ;
|
|
|
|
movq mm2, [rax+16] ;
|
|
movsxd rax, dword ptr arg(3) ;yoffset
|
|
|
|
pxor mm0, mm0 ;
|
|
|
|
shl rax, 5 ; offset*32
|
|
add rax, rcx ; VFilter
|
|
|
|
lea rcx, [rdi+rdx*8] ;
|
|
movsxd rdx, dword ptr arg(1) ;src_pixels_per_line ;
|
|
|
|
|
|
|
|
; get the first horizontal line done ;
|
|
movq mm3, [rsi] ; xx 00 01 02 03 04 05 06 07 08 09 10 11 12 13 14
|
|
movq mm4, mm3 ; make a copy of current line
|
|
|
|
punpcklbw mm3, mm0 ; xx 00 01 02 03 04 05 06
|
|
punpckhbw mm4, mm0 ;
|
|
|
|
pmullw mm3, mm1 ;
|
|
pmullw mm4, mm1 ;
|
|
|
|
movq mm5, [rsi+1] ;
|
|
movq mm6, mm5 ;
|
|
|
|
punpcklbw mm5, mm0 ;
|
|
punpckhbw mm6, mm0 ;
|
|
|
|
pmullw mm5, mm2 ;
|
|
pmullw mm6, mm2 ;
|
|
|
|
paddw mm3, mm5 ;
|
|
paddw mm4, mm6 ;
|
|
|
|
paddw mm3, [rd GLOBAL] ; xmm3 += round value
|
|
psraw mm3, VP8_FILTER_SHIFT ; xmm3 /= 128
|
|
|
|
paddw mm4, [rd GLOBAL] ;
|
|
psraw mm4, VP8_FILTER_SHIFT ;
|
|
|
|
movq mm7, mm3 ;
|
|
packuswb mm7, mm4 ;
|
|
|
|
add rsi, rdx ; next line
|
|
next_row_8x8:
|
|
movq mm3, [rsi] ; xx 00 01 02 03 04 05 06 07 08 09 10 11 12 13 14
|
|
movq mm4, mm3 ; make a copy of current line
|
|
|
|
punpcklbw mm3, mm0 ; xx 00 01 02 03 04 05 06
|
|
punpckhbw mm4, mm0 ;
|
|
|
|
pmullw mm3, mm1 ;
|
|
pmullw mm4, mm1 ;
|
|
|
|
movq mm5, [rsi+1] ;
|
|
movq mm6, mm5 ;
|
|
|
|
punpcklbw mm5, mm0 ;
|
|
punpckhbw mm6, mm0 ;
|
|
|
|
pmullw mm5, mm2 ;
|
|
pmullw mm6, mm2 ;
|
|
|
|
paddw mm3, mm5 ;
|
|
paddw mm4, mm6 ;
|
|
|
|
movq mm5, mm7 ;
|
|
movq mm6, mm7 ;
|
|
|
|
punpcklbw mm5, mm0 ;
|
|
punpckhbw mm6, mm0
|
|
|
|
pmullw mm5, [rax] ;
|
|
pmullw mm6, [rax] ;
|
|
|
|
paddw mm3, [rd GLOBAL] ; xmm3 += round value
|
|
psraw mm3, VP8_FILTER_SHIFT ; xmm3 /= 128
|
|
|
|
paddw mm4, [rd GLOBAL] ;
|
|
psraw mm4, VP8_FILTER_SHIFT ;
|
|
|
|
movq mm7, mm3 ;
|
|
packuswb mm7, mm4 ;
|
|
|
|
|
|
pmullw mm3, [rax+16] ;
|
|
pmullw mm4, [rax+16] ;
|
|
|
|
paddw mm3, mm5 ;
|
|
paddw mm4, mm6 ;
|
|
|
|
|
|
paddw mm3, [rd GLOBAL] ; xmm3 += round value
|
|
psraw mm3, VP8_FILTER_SHIFT ; xmm3 /= 128
|
|
|
|
paddw mm4, [rd GLOBAL] ;
|
|
psraw mm4, VP8_FILTER_SHIFT ;
|
|
|
|
packuswb mm3, mm4
|
|
|
|
movq [rdi], mm3 ; store the results in the destination
|
|
|
|
%if ABI_IS_32BIT
|
|
add rsi, rdx ; next line
|
|
add rdi, dword ptr arg(5) ;dst_pitch ;
|
|
%else
|
|
movsxd r8, dword ptr arg(5) ;dst_pitch
|
|
add rsi, rdx ; next line
|
|
add rdi, r8 ;dst_pitch
|
|
%endif
|
|
cmp rdi, rcx ;
|
|
jne next_row_8x8
|
|
|
|
; begin epilog
|
|
pop rdi
|
|
pop rsi
|
|
RESTORE_GOT
|
|
UNSHADOW_ARGS
|
|
pop rbp
|
|
ret
|
|
|
|
|
|
;void bilinear_predict8x4_mmx
|
|
;(
|
|
; unsigned char *src_ptr,
|
|
; int src_pixels_per_line,
|
|
; int xoffset,
|
|
; int yoffset,
|
|
; unsigned char *dst_ptr,
|
|
; int dst_pitch
|
|
;)
|
|
global sym(vp8_bilinear_predict8x4_mmx)
|
|
sym(vp8_bilinear_predict8x4_mmx):
|
|
push rbp
|
|
mov rbp, rsp
|
|
SHADOW_ARGS_TO_STACK 6
|
|
GET_GOT rbx
|
|
push rsi
|
|
push rdi
|
|
; end prolog
|
|
|
|
;const short *HFilter = bilinear_filters_mmx[xoffset];
|
|
;const short *VFilter = bilinear_filters_mmx[yoffset];
|
|
|
|
movsxd rax, dword ptr arg(2) ;xoffset
|
|
mov rdi, arg(4) ;dst_ptr ;
|
|
|
|
lea rcx, [sym(vp8_bilinear_filters_mmx) GLOBAL]
|
|
shl rax, 5
|
|
|
|
mov rsi, arg(0) ;src_ptr ;
|
|
add rax, rcx
|
|
|
|
movsxd rdx, dword ptr arg(5) ;dst_pitch
|
|
movq mm1, [rax] ;
|
|
|
|
movq mm2, [rax+16] ;
|
|
movsxd rax, dword ptr arg(3) ;yoffset
|
|
|
|
pxor mm0, mm0 ;
|
|
shl rax, 5
|
|
|
|
add rax, rcx
|
|
lea rcx, [rdi+rdx*4] ;
|
|
|
|
movsxd rdx, dword ptr arg(1) ;src_pixels_per_line ;
|
|
|
|
; get the first horizontal line done ;
|
|
movq mm3, [rsi] ; xx 00 01 02 03 04 05 06 07 08 09 10 11 12 13 14
|
|
movq mm4, mm3 ; make a copy of current line
|
|
|
|
punpcklbw mm3, mm0 ; xx 00 01 02 03 04 05 06
|
|
punpckhbw mm4, mm0 ;
|
|
|
|
pmullw mm3, mm1 ;
|
|
pmullw mm4, mm1 ;
|
|
|
|
movq mm5, [rsi+1] ;
|
|
movq mm6, mm5 ;
|
|
|
|
punpcklbw mm5, mm0 ;
|
|
punpckhbw mm6, mm0 ;
|
|
|
|
pmullw mm5, mm2 ;
|
|
pmullw mm6, mm2 ;
|
|
|
|
paddw mm3, mm5 ;
|
|
paddw mm4, mm6 ;
|
|
|
|
paddw mm3, [rd GLOBAL] ; xmm3 += round value
|
|
psraw mm3, VP8_FILTER_SHIFT ; xmm3 /= 128
|
|
|
|
paddw mm4, [rd GLOBAL] ;
|
|
psraw mm4, VP8_FILTER_SHIFT ;
|
|
|
|
movq mm7, mm3 ;
|
|
packuswb mm7, mm4 ;
|
|
|
|
add rsi, rdx ; next line
|
|
next_row_8x4:
|
|
movq mm3, [rsi] ; xx 00 01 02 03 04 05 06 07 08 09 10 11 12 13 14
|
|
movq mm4, mm3 ; make a copy of current line
|
|
|
|
punpcklbw mm3, mm0 ; xx 00 01 02 03 04 05 06
|
|
punpckhbw mm4, mm0 ;
|
|
|
|
pmullw mm3, mm1 ;
|
|
pmullw mm4, mm1 ;
|
|
|
|
movq mm5, [rsi+1] ;
|
|
movq mm6, mm5 ;
|
|
|
|
punpcklbw mm5, mm0 ;
|
|
punpckhbw mm6, mm0 ;
|
|
|
|
pmullw mm5, mm2 ;
|
|
pmullw mm6, mm2 ;
|
|
|
|
paddw mm3, mm5 ;
|
|
paddw mm4, mm6 ;
|
|
|
|
movq mm5, mm7 ;
|
|
movq mm6, mm7 ;
|
|
|
|
punpcklbw mm5, mm0 ;
|
|
punpckhbw mm6, mm0
|
|
|
|
pmullw mm5, [rax] ;
|
|
pmullw mm6, [rax] ;
|
|
|
|
paddw mm3, [rd GLOBAL] ; xmm3 += round value
|
|
psraw mm3, VP8_FILTER_SHIFT ; xmm3 /= 128
|
|
|
|
paddw mm4, [rd GLOBAL] ;
|
|
psraw mm4, VP8_FILTER_SHIFT ;
|
|
|
|
movq mm7, mm3 ;
|
|
packuswb mm7, mm4 ;
|
|
|
|
|
|
pmullw mm3, [rax+16] ;
|
|
pmullw mm4, [rax+16] ;
|
|
|
|
paddw mm3, mm5 ;
|
|
paddw mm4, mm6 ;
|
|
|
|
|
|
paddw mm3, [rd GLOBAL] ; xmm3 += round value
|
|
psraw mm3, VP8_FILTER_SHIFT ; xmm3 /= 128
|
|
|
|
paddw mm4, [rd GLOBAL] ;
|
|
psraw mm4, VP8_FILTER_SHIFT ;
|
|
|
|
packuswb mm3, mm4
|
|
|
|
movq [rdi], mm3 ; store the results in the destination
|
|
|
|
%if ABI_IS_32BIT
|
|
add rsi, rdx ; next line
|
|
add rdi, dword ptr arg(5) ;dst_pitch ;
|
|
%else
|
|
movsxd r8, dword ptr arg(5) ;dst_pitch
|
|
add rsi, rdx ; next line
|
|
add rdi, r8
|
|
%endif
|
|
cmp rdi, rcx ;
|
|
jne next_row_8x4
|
|
|
|
; begin epilog
|
|
pop rdi
|
|
pop rsi
|
|
RESTORE_GOT
|
|
UNSHADOW_ARGS
|
|
pop rbp
|
|
ret
|
|
|
|
|
|
;void bilinear_predict4x4_mmx
|
|
;(
|
|
; unsigned char *src_ptr,
|
|
; int src_pixels_per_line,
|
|
; int xoffset,
|
|
; int yoffset,
|
|
; unsigned char *dst_ptr,
|
|
; int dst_pitch
|
|
;)
|
|
global sym(vp8_bilinear_predict4x4_mmx)
|
|
sym(vp8_bilinear_predict4x4_mmx):
|
|
push rbp
|
|
mov rbp, rsp
|
|
SHADOW_ARGS_TO_STACK 6
|
|
GET_GOT rbx
|
|
push rsi
|
|
push rdi
|
|
; end prolog
|
|
|
|
;const short *HFilter = bilinear_filters_mmx[xoffset];
|
|
;const short *VFilter = bilinear_filters_mmx[yoffset];
|
|
|
|
movsxd rax, dword ptr arg(2) ;xoffset
|
|
mov rdi, arg(4) ;dst_ptr ;
|
|
|
|
lea rcx, [sym(vp8_bilinear_filters_mmx) GLOBAL]
|
|
shl rax, 5
|
|
|
|
add rax, rcx ; HFilter
|
|
mov rsi, arg(0) ;src_ptr ;
|
|
|
|
movsxd rdx, dword ptr arg(5) ;ldst_pitch
|
|
movq mm1, [rax] ;
|
|
|
|
movq mm2, [rax+16] ;
|
|
movsxd rax, dword ptr arg(3) ;yoffset
|
|
|
|
pxor mm0, mm0 ;
|
|
shl rax, 5
|
|
|
|
add rax, rcx
|
|
lea rcx, [rdi+rdx*4] ;
|
|
|
|
movsxd rdx, dword ptr arg(1) ;src_pixels_per_line ;
|
|
|
|
; get the first horizontal line done ;
|
|
movd mm3, [rsi] ; xx 00 01 02 03 04 05 06 07 08 09 10 11 12 13 14
|
|
punpcklbw mm3, mm0 ; xx 00 01 02 03 04 05 06
|
|
|
|
pmullw mm3, mm1 ;
|
|
movd mm5, [rsi+1] ;
|
|
|
|
punpcklbw mm5, mm0 ;
|
|
pmullw mm5, mm2 ;
|
|
|
|
paddw mm3, mm5 ;
|
|
paddw mm3, [rd GLOBAL] ; xmm3 += round value
|
|
|
|
psraw mm3, VP8_FILTER_SHIFT ; xmm3 /= 128
|
|
|
|
movq mm7, mm3 ;
|
|
packuswb mm7, mm0 ;
|
|
|
|
add rsi, rdx ; next line
|
|
next_row_4x4:
|
|
movd mm3, [rsi] ; xx 00 01 02 03 04 05 06 07 08 09 10 11 12 13 14
|
|
punpcklbw mm3, mm0 ; xx 00 01 02 03 04 05 06
|
|
|
|
pmullw mm3, mm1 ;
|
|
movd mm5, [rsi+1] ;
|
|
|
|
punpcklbw mm5, mm0 ;
|
|
pmullw mm5, mm2 ;
|
|
|
|
paddw mm3, mm5 ;
|
|
|
|
movq mm5, mm7 ;
|
|
punpcklbw mm5, mm0 ;
|
|
|
|
pmullw mm5, [rax] ;
|
|
paddw mm3, [rd GLOBAL] ; xmm3 += round value
|
|
|
|
psraw mm3, VP8_FILTER_SHIFT ; xmm3 /= 128
|
|
movq mm7, mm3 ;
|
|
|
|
packuswb mm7, mm0 ;
|
|
|
|
pmullw mm3, [rax+16] ;
|
|
paddw mm3, mm5 ;
|
|
|
|
|
|
paddw mm3, [rd GLOBAL] ; xmm3 += round value
|
|
psraw mm3, VP8_FILTER_SHIFT ; xmm3 /= 128
|
|
|
|
packuswb mm3, mm0
|
|
movd [rdi], mm3 ; store the results in the destination
|
|
|
|
%if ABI_IS_32BIT
|
|
add rsi, rdx ; next line
|
|
add rdi, dword ptr arg(5) ;dst_pitch ;
|
|
%else
|
|
movsxd r8, dword ptr arg(5) ;dst_pitch ;
|
|
add rsi, rdx ; next line
|
|
add rdi, r8
|
|
%endif
|
|
|
|
cmp rdi, rcx ;
|
|
jne next_row_4x4
|
|
|
|
; begin epilog
|
|
pop rdi
|
|
pop rsi
|
|
RESTORE_GOT
|
|
UNSHADOW_ARGS
|
|
pop rbp
|
|
ret
|
|
|
|
|
|
|
|
SECTION_RODATA
|
|
align 16
|
|
rd:
|
|
times 4 dw 0x40
|
|
|
|
align 16
|
|
global sym(vp8_six_tap_mmx)
|
|
sym(vp8_six_tap_mmx):
|
|
times 8 dw 0
|
|
times 8 dw 0
|
|
times 8 dw 128
|
|
times 8 dw 0
|
|
times 8 dw 0
|
|
times 8 dw 0
|
|
|
|
times 8 dw 0
|
|
times 8 dw -6
|
|
times 8 dw 123
|
|
times 8 dw 12
|
|
times 8 dw -1
|
|
times 8 dw 0
|
|
|
|
times 8 dw 2
|
|
times 8 dw -11
|
|
times 8 dw 108
|
|
times 8 dw 36
|
|
times 8 dw -8
|
|
times 8 dw 1
|
|
|
|
times 8 dw 0
|
|
times 8 dw -9
|
|
times 8 dw 93
|
|
times 8 dw 50
|
|
times 8 dw -6
|
|
times 8 dw 0
|
|
|
|
times 8 dw 3
|
|
times 8 dw -16
|
|
times 8 dw 77
|
|
times 8 dw 77
|
|
times 8 dw -16
|
|
times 8 dw 3
|
|
|
|
times 8 dw 0
|
|
times 8 dw -6
|
|
times 8 dw 50
|
|
times 8 dw 93
|
|
times 8 dw -9
|
|
times 8 dw 0
|
|
|
|
times 8 dw 1
|
|
times 8 dw -8
|
|
times 8 dw 36
|
|
times 8 dw 108
|
|
times 8 dw -11
|
|
times 8 dw 2
|
|
|
|
times 8 dw 0
|
|
times 8 dw -1
|
|
times 8 dw 12
|
|
times 8 dw 123
|
|
times 8 dw -6
|
|
times 8 dw 0
|
|
|
|
|
|
align 16
|
|
global sym(vp8_bilinear_filters_mmx)
|
|
sym(vp8_bilinear_filters_mmx):
|
|
times 8 dw 128
|
|
times 8 dw 0
|
|
|
|
times 8 dw 112
|
|
times 8 dw 16
|
|
|
|
times 8 dw 96
|
|
times 8 dw 32
|
|
|
|
times 8 dw 80
|
|
times 8 dw 48
|
|
|
|
times 8 dw 64
|
|
times 8 dw 64
|
|
|
|
times 8 dw 48
|
|
times 8 dw 80
|
|
|
|
times 8 dw 32
|
|
times 8 dw 96
|
|
|
|
times 8 dw 16
|
|
times 8 dw 112
|