michael@0: ; michael@0: ; Copyright (c) 2010 The WebM project authors. All Rights Reserved. michael@0: ; michael@0: ; Use of this source code is governed by a BSD-style license michael@0: ; that can be found in the LICENSE file in the root of the source michael@0: ; tree. An additional intellectual property rights grant can be found michael@0: ; in the file PATENTS. All contributing project authors may michael@0: ; be found in the AUTHORS file in the root of the source tree. michael@0: ; michael@0: michael@0: michael@0: %include "vpx_ports/x86_abi_support.asm" michael@0: michael@0: ;void copy_mem16x16_sse2( michael@0: ; unsigned char *src, michael@0: ; int src_stride, michael@0: ; unsigned char *dst, michael@0: ; int dst_stride michael@0: ; ) michael@0: global sym(vp8_copy_mem16x16_sse2) PRIVATE michael@0: sym(vp8_copy_mem16x16_sse2): michael@0: push rbp michael@0: mov rbp, rsp michael@0: SHADOW_ARGS_TO_STACK 4 michael@0: push rsi michael@0: push rdi michael@0: ; end prolog michael@0: michael@0: mov rsi, arg(0) ;src; michael@0: movdqu xmm0, [rsi] michael@0: michael@0: movsxd rax, dword ptr arg(1) ;src_stride; michael@0: mov rdi, arg(2) ;dst; michael@0: michael@0: movdqu xmm1, [rsi+rax] michael@0: movdqu xmm2, [rsi+rax*2] michael@0: michael@0: movsxd rcx, dword ptr arg(3) ;dst_stride michael@0: lea rsi, [rsi+rax*2] michael@0: michael@0: movdqa [rdi], xmm0 michael@0: add rsi, rax michael@0: michael@0: movdqa [rdi+rcx], xmm1 michael@0: movdqa [rdi+rcx*2],xmm2 michael@0: michael@0: lea rdi, [rdi+rcx*2] michael@0: movdqu xmm3, [rsi] michael@0: michael@0: add rdi, rcx michael@0: movdqu xmm4, [rsi+rax] michael@0: michael@0: movdqu xmm5, [rsi+rax*2] michael@0: lea rsi, [rsi+rax*2] michael@0: michael@0: movdqa [rdi], xmm3 michael@0: add rsi, rax michael@0: michael@0: movdqa [rdi+rcx], xmm4 michael@0: movdqa [rdi+rcx*2],xmm5 michael@0: michael@0: lea rdi, [rdi+rcx*2] michael@0: movdqu xmm0, [rsi] michael@0: michael@0: add rdi, rcx michael@0: movdqu xmm1, [rsi+rax] michael@0: michael@0: movdqu xmm2, [rsi+rax*2] michael@0: lea rsi, [rsi+rax*2] michael@0: michael@0: movdqa [rdi], xmm0 michael@0: add rsi, rax michael@0: michael@0: movdqa [rdi+rcx], xmm1 michael@0: michael@0: movdqa [rdi+rcx*2], xmm2 michael@0: movdqu xmm3, [rsi] michael@0: michael@0: movdqu xmm4, [rsi+rax] michael@0: lea rdi, [rdi+rcx*2] michael@0: michael@0: add rdi, rcx michael@0: movdqu xmm5, [rsi+rax*2] michael@0: michael@0: lea rsi, [rsi+rax*2] michael@0: movdqa [rdi], xmm3 michael@0: michael@0: add rsi, rax michael@0: movdqa [rdi+rcx], xmm4 michael@0: michael@0: movdqa [rdi+rcx*2],xmm5 michael@0: movdqu xmm0, [rsi] michael@0: michael@0: lea rdi, [rdi+rcx*2] michael@0: movdqu xmm1, [rsi+rax] michael@0: michael@0: add rdi, rcx michael@0: movdqu xmm2, [rsi+rax*2] michael@0: michael@0: lea rsi, [rsi+rax*2] michael@0: movdqa [rdi], xmm0 michael@0: michael@0: movdqa [rdi+rcx], xmm1 michael@0: movdqa [rdi+rcx*2],xmm2 michael@0: michael@0: movdqu xmm3, [rsi+rax] michael@0: lea rdi, [rdi+rcx*2] michael@0: michael@0: movdqa [rdi+rcx], xmm3 michael@0: michael@0: ; begin epilog michael@0: pop rdi michael@0: pop rsi michael@0: UNSHADOW_ARGS michael@0: pop rbp michael@0: ret michael@0: michael@0: michael@0: ;void vp8_intra_pred_uv_dc_mmx2( michael@0: ; unsigned char *dst, michael@0: ; int dst_stride michael@0: ; unsigned char *above, michael@0: ; unsigned char *left, michael@0: ; int left_stride, michael@0: ; ) michael@0: global sym(vp8_intra_pred_uv_dc_mmx2) PRIVATE michael@0: sym(vp8_intra_pred_uv_dc_mmx2): michael@0: push rbp michael@0: mov rbp, rsp michael@0: SHADOW_ARGS_TO_STACK 5 michael@0: push rsi michael@0: push rdi michael@0: ; end prolog michael@0: michael@0: ; from top michael@0: mov rdi, arg(2) ;above; michael@0: mov rsi, arg(3) ;left; michael@0: movsxd rax, dword ptr arg(4) ;left_stride; michael@0: pxor mm0, mm0 michael@0: movq mm1, [rdi] michael@0: lea rdi, [rax*3] michael@0: psadbw mm1, mm0 michael@0: ; from left michael@0: movzx ecx, byte [rsi] michael@0: movzx edx, byte [rsi+rax*1] michael@0: add ecx, edx michael@0: movzx edx, byte [rsi+rax*2] michael@0: add ecx, edx michael@0: michael@0: movzx edx, byte [rsi+rdi] michael@0: lea rsi, [rsi+rax*4] michael@0: add ecx, edx michael@0: movzx edx, byte [rsi] michael@0: add ecx, edx michael@0: movzx edx, byte [rsi+rax] michael@0: add ecx, edx michael@0: movzx edx, byte [rsi+rax*2] michael@0: add ecx, edx michael@0: movzx edx, byte [rsi+rdi] michael@0: add ecx, edx michael@0: michael@0: ; add up michael@0: pextrw edx, mm1, 0x0 michael@0: lea edx, [edx+ecx+8] michael@0: sar edx, 4 michael@0: movd mm1, edx michael@0: movsxd rcx, dword ptr arg(1) ;dst_stride michael@0: pshufw mm1, mm1, 0x0 michael@0: mov rdi, arg(0) ;dst; michael@0: packuswb mm1, mm1 michael@0: michael@0: ; write out michael@0: lea rax, [rcx*3] michael@0: lea rdx, [rdi+rcx*4] michael@0: michael@0: movq [rdi ], mm1 michael@0: movq [rdi+rcx ], mm1 michael@0: movq [rdi+rcx*2], mm1 michael@0: movq [rdi+rax ], mm1 michael@0: movq [rdx ], mm1 michael@0: movq [rdx+rcx ], mm1 michael@0: movq [rdx+rcx*2], mm1 michael@0: movq [rdx+rax ], mm1 michael@0: michael@0: ; begin epilog michael@0: pop rdi michael@0: pop rsi michael@0: UNSHADOW_ARGS michael@0: pop rbp michael@0: ret michael@0: michael@0: ;void vp8_intra_pred_uv_dctop_mmx2( michael@0: ; unsigned char *dst, michael@0: ; int dst_stride michael@0: ; unsigned char *above, michael@0: ; unsigned char *left, michael@0: ; int left_stride, michael@0: ; ) michael@0: global sym(vp8_intra_pred_uv_dctop_mmx2) PRIVATE michael@0: sym(vp8_intra_pred_uv_dctop_mmx2): michael@0: push rbp michael@0: mov rbp, rsp michael@0: SHADOW_ARGS_TO_STACK 5 michael@0: GET_GOT rbx michael@0: push rsi michael@0: push rdi michael@0: ; end prolog michael@0: michael@0: ;arg(3), arg(4) not used michael@0: michael@0: ; from top michael@0: mov rsi, arg(2) ;above; michael@0: pxor mm0, mm0 michael@0: movq mm1, [rsi] michael@0: psadbw mm1, mm0 michael@0: michael@0: ; add up michael@0: paddw mm1, [GLOBAL(dc_4)] michael@0: psraw mm1, 3 michael@0: pshufw mm1, mm1, 0x0 michael@0: packuswb mm1, mm1 michael@0: michael@0: ; write out michael@0: mov rdi, arg(0) ;dst; michael@0: movsxd rcx, dword ptr arg(1) ;dst_stride michael@0: lea rax, [rcx*3] michael@0: michael@0: movq [rdi ], mm1 michael@0: movq [rdi+rcx ], mm1 michael@0: movq [rdi+rcx*2], mm1 michael@0: movq [rdi+rax ], mm1 michael@0: lea rdi, [rdi+rcx*4] michael@0: movq [rdi ], mm1 michael@0: movq [rdi+rcx ], mm1 michael@0: movq [rdi+rcx*2], mm1 michael@0: movq [rdi+rax ], mm1 michael@0: michael@0: ; begin epilog michael@0: pop rdi michael@0: pop rsi michael@0: RESTORE_GOT michael@0: UNSHADOW_ARGS michael@0: pop rbp michael@0: ret michael@0: michael@0: ;void vp8_intra_pred_uv_dcleft_mmx2( michael@0: ; unsigned char *dst, michael@0: ; int dst_stride michael@0: ; unsigned char *above, michael@0: ; unsigned char *left, michael@0: ; int left_stride, michael@0: ; ) michael@0: global sym(vp8_intra_pred_uv_dcleft_mmx2) PRIVATE michael@0: sym(vp8_intra_pred_uv_dcleft_mmx2): michael@0: push rbp michael@0: mov rbp, rsp michael@0: SHADOW_ARGS_TO_STACK 5 michael@0: push rsi michael@0: push rdi michael@0: ; end prolog michael@0: michael@0: ;arg(2) not used michael@0: michael@0: ; from left michael@0: mov rsi, arg(3) ;left; michael@0: movsxd rax, dword ptr arg(4) ;left_stride; michael@0: lea rdi, [rax*3] michael@0: movzx ecx, byte [rsi] michael@0: movzx edx, byte [rsi+rax] michael@0: add ecx, edx michael@0: movzx edx, byte [rsi+rax*2] michael@0: add ecx, edx michael@0: movzx edx, byte [rsi+rdi] michael@0: add ecx, edx michael@0: lea rsi, [rsi+rax*4] michael@0: movzx edx, byte [rsi] michael@0: add ecx, edx michael@0: movzx edx, byte [rsi+rax] michael@0: add ecx, edx michael@0: movzx edx, byte [rsi+rax*2] michael@0: add ecx, edx michael@0: movzx edx, byte [rsi+rdi] michael@0: lea edx, [ecx+edx+4] michael@0: michael@0: ; add up michael@0: shr edx, 3 michael@0: movd mm1, edx michael@0: pshufw mm1, mm1, 0x0 michael@0: packuswb mm1, mm1 michael@0: michael@0: ; write out michael@0: mov rdi, arg(0) ;dst; michael@0: movsxd rcx, dword ptr arg(1) ;dst_stride michael@0: lea rax, [rcx*3] michael@0: michael@0: movq [rdi ], mm1 michael@0: movq [rdi+rcx ], mm1 michael@0: movq [rdi+rcx*2], mm1 michael@0: movq [rdi+rax ], mm1 michael@0: lea rdi, [rdi+rcx*4] michael@0: movq [rdi ], mm1 michael@0: movq [rdi+rcx ], mm1 michael@0: movq [rdi+rcx*2], mm1 michael@0: movq [rdi+rax ], mm1 michael@0: michael@0: ; begin epilog michael@0: pop rdi michael@0: pop rsi michael@0: UNSHADOW_ARGS michael@0: pop rbp michael@0: ret michael@0: michael@0: ;void vp8_intra_pred_uv_dc128_mmx( michael@0: ; unsigned char *dst, michael@0: ; int dst_stride michael@0: ; unsigned char *above, michael@0: ; unsigned char *left, michael@0: ; int left_stride, michael@0: ; ) michael@0: global sym(vp8_intra_pred_uv_dc128_mmx) PRIVATE michael@0: sym(vp8_intra_pred_uv_dc128_mmx): michael@0: push rbp michael@0: mov rbp, rsp michael@0: SHADOW_ARGS_TO_STACK 5 michael@0: GET_GOT rbx michael@0: ; end prolog michael@0: michael@0: ;arg(2), arg(3), arg(4) not used michael@0: michael@0: ; write out michael@0: movq mm1, [GLOBAL(dc_128)] michael@0: mov rax, arg(0) ;dst; michael@0: movsxd rdx, dword ptr arg(1) ;dst_stride michael@0: lea rcx, [rdx*3] michael@0: michael@0: movq [rax ], mm1 michael@0: movq [rax+rdx ], mm1 michael@0: movq [rax+rdx*2], mm1 michael@0: movq [rax+rcx ], mm1 michael@0: lea rax, [rax+rdx*4] michael@0: movq [rax ], mm1 michael@0: movq [rax+rdx ], mm1 michael@0: movq [rax+rdx*2], mm1 michael@0: movq [rax+rcx ], mm1 michael@0: michael@0: ; begin epilog michael@0: RESTORE_GOT michael@0: UNSHADOW_ARGS michael@0: pop rbp michael@0: ret michael@0: michael@0: ;void vp8_intra_pred_uv_tm_sse2( michael@0: ; unsigned char *dst, michael@0: ; int dst_stride michael@0: ; unsigned char *above, michael@0: ; unsigned char *left, michael@0: ; int left_stride, michael@0: ; ) michael@0: %macro vp8_intra_pred_uv_tm 1 michael@0: global sym(vp8_intra_pred_uv_tm_%1) PRIVATE michael@0: sym(vp8_intra_pred_uv_tm_%1): michael@0: push rbp michael@0: mov rbp, rsp michael@0: SHADOW_ARGS_TO_STACK 5 michael@0: GET_GOT rbx michael@0: push rsi michael@0: push rdi michael@0: ; end prolog michael@0: michael@0: ; read top row michael@0: mov edx, 4 michael@0: mov rsi, arg(2) ;above michael@0: movsxd rax, dword ptr arg(4) ;left_stride; michael@0: pxor xmm0, xmm0 michael@0: %ifidn %1, ssse3 michael@0: movdqa xmm2, [GLOBAL(dc_1024)] michael@0: %endif michael@0: movq xmm1, [rsi] michael@0: punpcklbw xmm1, xmm0 michael@0: michael@0: ; set up left ptrs ans subtract topleft michael@0: movd xmm3, [rsi-1] michael@0: mov rsi, arg(3) ;left; michael@0: %ifidn %1, sse2 michael@0: punpcklbw xmm3, xmm0 michael@0: pshuflw xmm3, xmm3, 0x0 michael@0: punpcklqdq xmm3, xmm3 michael@0: %else michael@0: pshufb xmm3, xmm2 michael@0: %endif michael@0: psubw xmm1, xmm3 michael@0: michael@0: ; set up dest ptrs michael@0: mov rdi, arg(0) ;dst; michael@0: movsxd rcx, dword ptr arg(1) ;dst_stride michael@0: michael@0: .vp8_intra_pred_uv_tm_%1_loop: michael@0: movd xmm3, [rsi] michael@0: movd xmm5, [rsi+rax] michael@0: %ifidn %1, sse2 michael@0: punpcklbw xmm3, xmm0 michael@0: punpcklbw xmm5, xmm0 michael@0: pshuflw xmm3, xmm3, 0x0 michael@0: pshuflw xmm5, xmm5, 0x0 michael@0: punpcklqdq xmm3, xmm3 michael@0: punpcklqdq xmm5, xmm5 michael@0: %else michael@0: pshufb xmm3, xmm2 michael@0: pshufb xmm5, xmm2 michael@0: %endif michael@0: paddw xmm3, xmm1 michael@0: paddw xmm5, xmm1 michael@0: packuswb xmm3, xmm5 michael@0: movq [rdi ], xmm3 michael@0: movhps[rdi+rcx], xmm3 michael@0: lea rsi, [rsi+rax*2] michael@0: lea rdi, [rdi+rcx*2] michael@0: dec edx michael@0: jnz .vp8_intra_pred_uv_tm_%1_loop michael@0: michael@0: ; begin epilog michael@0: pop rdi michael@0: pop rsi michael@0: RESTORE_GOT michael@0: UNSHADOW_ARGS michael@0: pop rbp michael@0: ret michael@0: %endmacro michael@0: michael@0: vp8_intra_pred_uv_tm sse2 michael@0: vp8_intra_pred_uv_tm ssse3 michael@0: michael@0: ;void vp8_intra_pred_uv_ve_mmx( michael@0: ; unsigned char *dst, michael@0: ; int dst_stride michael@0: ; unsigned char *above, michael@0: ; unsigned char *left, michael@0: ; int left_stride, michael@0: ; ) michael@0: global sym(vp8_intra_pred_uv_ve_mmx) PRIVATE michael@0: sym(vp8_intra_pred_uv_ve_mmx): michael@0: push rbp michael@0: mov rbp, rsp michael@0: SHADOW_ARGS_TO_STACK 5 michael@0: ; end prolog michael@0: michael@0: ; arg(3), arg(4) not used michael@0: michael@0: ; read from top michael@0: mov rax, arg(2) ;src; michael@0: michael@0: movq mm1, [rax] michael@0: michael@0: ; write out michael@0: mov rax, arg(0) ;dst; michael@0: movsxd rdx, dword ptr arg(1) ;dst_stride michael@0: lea rcx, [rdx*3] michael@0: michael@0: movq [rax ], mm1 michael@0: movq [rax+rdx ], mm1 michael@0: movq [rax+rdx*2], mm1 michael@0: movq [rax+rcx ], mm1 michael@0: lea rax, [rax+rdx*4] michael@0: movq [rax ], mm1 michael@0: movq [rax+rdx ], mm1 michael@0: movq [rax+rdx*2], mm1 michael@0: movq [rax+rcx ], mm1 michael@0: michael@0: ; begin epilog michael@0: UNSHADOW_ARGS michael@0: pop rbp michael@0: ret michael@0: michael@0: ;void vp8_intra_pred_uv_ho_mmx2( michael@0: ; unsigned char *dst, michael@0: ; int dst_stride michael@0: ; unsigned char *above, michael@0: ; unsigned char *left, michael@0: ; int left_stride michael@0: ; ) michael@0: %macro vp8_intra_pred_uv_ho 1 michael@0: global sym(vp8_intra_pred_uv_ho_%1) PRIVATE michael@0: sym(vp8_intra_pred_uv_ho_%1): michael@0: push rbp michael@0: mov rbp, rsp michael@0: SHADOW_ARGS_TO_STACK 5 michael@0: push rsi michael@0: push rdi michael@0: %ifidn %1, ssse3 michael@0: %ifndef GET_GOT_SAVE_ARG michael@0: push rbx michael@0: %endif michael@0: GET_GOT rbx michael@0: %endif michael@0: ; end prolog michael@0: michael@0: ;arg(2) not used michael@0: michael@0: ; read from left and write out michael@0: %ifidn %1, mmx2 michael@0: mov edx, 4 michael@0: %endif michael@0: mov rsi, arg(3) ;left michael@0: movsxd rax, dword ptr arg(4) ;left_stride; michael@0: mov rdi, arg(0) ;dst; michael@0: movsxd rcx, dword ptr arg(1) ;dst_stride michael@0: %ifidn %1, ssse3 michael@0: lea rdx, [rcx*3] michael@0: movdqa xmm2, [GLOBAL(dc_00001111)] michael@0: lea rbx, [rax*3] michael@0: %endif michael@0: michael@0: %ifidn %1, mmx2 michael@0: .vp8_intra_pred_uv_ho_%1_loop: michael@0: movd mm0, [rsi] michael@0: movd mm1, [rsi+rax] michael@0: punpcklbw mm0, mm0 michael@0: punpcklbw mm1, mm1 michael@0: pshufw mm0, mm0, 0x0 michael@0: pshufw mm1, mm1, 0x0 michael@0: movq [rdi ], mm0 michael@0: movq [rdi+rcx], mm1 michael@0: lea rsi, [rsi+rax*2] michael@0: lea rdi, [rdi+rcx*2] michael@0: dec edx michael@0: jnz .vp8_intra_pred_uv_ho_%1_loop michael@0: %else michael@0: movd xmm0, [rsi] michael@0: movd xmm3, [rsi+rax] michael@0: movd xmm1, [rsi+rax*2] michael@0: movd xmm4, [rsi+rbx] michael@0: punpcklbw xmm0, xmm3 michael@0: punpcklbw xmm1, xmm4 michael@0: pshufb xmm0, xmm2 michael@0: pshufb xmm1, xmm2 michael@0: movq [rdi ], xmm0 michael@0: movhps [rdi+rcx], xmm0 michael@0: movq [rdi+rcx*2], xmm1 michael@0: movhps [rdi+rdx], xmm1 michael@0: lea rsi, [rsi+rax*4] michael@0: lea rdi, [rdi+rcx*4] michael@0: movd xmm0, [rsi] michael@0: movd xmm3, [rsi+rax] michael@0: movd xmm1, [rsi+rax*2] michael@0: movd xmm4, [rsi+rbx] michael@0: punpcklbw xmm0, xmm3 michael@0: punpcklbw xmm1, xmm4 michael@0: pshufb xmm0, xmm2 michael@0: pshufb xmm1, xmm2 michael@0: movq [rdi ], xmm0 michael@0: movhps [rdi+rcx], xmm0 michael@0: movq [rdi+rcx*2], xmm1 michael@0: movhps [rdi+rdx], xmm1 michael@0: %endif michael@0: michael@0: ; begin epilog michael@0: %ifidn %1, ssse3 michael@0: RESTORE_GOT michael@0: %ifndef GET_GOT_SAVE_ARG michael@0: pop rbx michael@0: %endif michael@0: %endif michael@0: pop rdi michael@0: pop rsi michael@0: UNSHADOW_ARGS michael@0: pop rbp michael@0: ret michael@0: %endmacro michael@0: michael@0: vp8_intra_pred_uv_ho mmx2 michael@0: vp8_intra_pred_uv_ho ssse3 michael@0: michael@0: ;void vp8_intra_pred_y_dc_sse2( michael@0: ; unsigned char *dst, michael@0: ; int dst_stride michael@0: ; unsigned char *above, michael@0: ; unsigned char *left, michael@0: ; int left_stride michael@0: ; ) michael@0: global sym(vp8_intra_pred_y_dc_sse2) PRIVATE michael@0: sym(vp8_intra_pred_y_dc_sse2): michael@0: push rbp michael@0: mov rbp, rsp michael@0: SHADOW_ARGS_TO_STACK 5 michael@0: push rsi michael@0: push rdi michael@0: ; end prolog michael@0: michael@0: ; from top michael@0: mov rdi, arg(2) ;above michael@0: mov rsi, arg(3) ;left michael@0: movsxd rax, dword ptr arg(4) ;left_stride; michael@0: michael@0: pxor xmm0, xmm0 michael@0: movdqa xmm1, [rdi] michael@0: psadbw xmm1, xmm0 michael@0: movq xmm2, xmm1 michael@0: punpckhqdq xmm1, xmm1 michael@0: paddw xmm1, xmm2 michael@0: michael@0: ; from left michael@0: lea rdi, [rax*3] michael@0: michael@0: movzx ecx, byte [rsi] michael@0: movzx edx, byte [rsi+rax] michael@0: add ecx, edx michael@0: movzx edx, byte [rsi+rax*2] michael@0: add ecx, edx michael@0: movzx edx, byte [rsi+rdi] michael@0: add ecx, edx michael@0: lea rsi, [rsi+rax*4] michael@0: michael@0: movzx edx, byte [rsi] michael@0: add ecx, edx michael@0: movzx edx, byte [rsi+rax] michael@0: add ecx, edx michael@0: movzx edx, byte [rsi+rax*2] michael@0: add ecx, edx michael@0: movzx edx, byte [rsi+rdi] michael@0: add ecx, edx michael@0: lea rsi, [rsi+rax*4] michael@0: michael@0: movzx edx, byte [rsi] michael@0: add ecx, edx michael@0: movzx edx, byte [rsi+rax] michael@0: add ecx, edx michael@0: movzx edx, byte [rsi+rax*2] michael@0: add ecx, edx michael@0: movzx edx, byte [rsi+rdi] michael@0: add ecx, edx michael@0: lea rsi, [rsi+rax*4] michael@0: michael@0: movzx edx, byte [rsi] michael@0: add ecx, edx michael@0: movzx edx, byte [rsi+rax] michael@0: add ecx, edx michael@0: movzx edx, byte [rsi+rax*2] michael@0: add ecx, edx michael@0: movzx edx, byte [rsi+rdi] michael@0: add ecx, edx michael@0: michael@0: ; add up michael@0: pextrw edx, xmm1, 0x0 michael@0: lea edx, [edx+ecx+16] michael@0: sar edx, 5 michael@0: movd xmm1, edx michael@0: ; FIXME use pshufb for ssse3 version michael@0: pshuflw xmm1, xmm1, 0x0 michael@0: punpcklqdq xmm1, xmm1 michael@0: packuswb xmm1, xmm1 michael@0: michael@0: ; write out michael@0: mov rsi, 2 michael@0: mov rdi, arg(0) ;dst; michael@0: movsxd rcx, dword ptr arg(1) ;dst_stride michael@0: lea rax, [rcx*3] michael@0: michael@0: .label michael@0: movdqa [rdi ], xmm1 michael@0: movdqa [rdi+rcx ], xmm1 michael@0: movdqa [rdi+rcx*2], xmm1 michael@0: movdqa [rdi+rax ], xmm1 michael@0: lea rdi, [rdi+rcx*4] michael@0: movdqa [rdi ], xmm1 michael@0: movdqa [rdi+rcx ], xmm1 michael@0: movdqa [rdi+rcx*2], xmm1 michael@0: movdqa [rdi+rax ], xmm1 michael@0: lea rdi, [rdi+rcx*4] michael@0: dec rsi michael@0: jnz .label michael@0: michael@0: ; begin epilog michael@0: pop rdi michael@0: pop rsi michael@0: UNSHADOW_ARGS michael@0: pop rbp michael@0: ret michael@0: michael@0: ;void vp8_intra_pred_y_dctop_sse2( michael@0: ; unsigned char *dst, michael@0: ; int dst_stride michael@0: ; unsigned char *above, michael@0: ; unsigned char *left, michael@0: ; int left_stride michael@0: ; ) michael@0: global sym(vp8_intra_pred_y_dctop_sse2) PRIVATE michael@0: sym(vp8_intra_pred_y_dctop_sse2): michael@0: push rbp michael@0: mov rbp, rsp michael@0: SHADOW_ARGS_TO_STACK 5 michael@0: push rsi michael@0: GET_GOT rbx michael@0: ; end prolog michael@0: michael@0: ;arg(3), arg(4) not used michael@0: michael@0: ; from top michael@0: mov rcx, arg(2) ;above; michael@0: pxor xmm0, xmm0 michael@0: movdqa xmm1, [rcx] michael@0: psadbw xmm1, xmm0 michael@0: movdqa xmm2, xmm1 michael@0: punpckhqdq xmm1, xmm1 michael@0: paddw xmm1, xmm2 michael@0: michael@0: ; add up michael@0: paddw xmm1, [GLOBAL(dc_8)] michael@0: psraw xmm1, 4 michael@0: ; FIXME use pshufb for ssse3 version michael@0: pshuflw xmm1, xmm1, 0x0 michael@0: punpcklqdq xmm1, xmm1 michael@0: packuswb xmm1, xmm1 michael@0: michael@0: ; write out michael@0: mov rsi, 2 michael@0: mov rdx, arg(0) ;dst; michael@0: movsxd rcx, dword ptr arg(1) ;dst_stride michael@0: lea rax, [rcx*3] michael@0: michael@0: .label michael@0: movdqa [rdx ], xmm1 michael@0: movdqa [rdx+rcx ], xmm1 michael@0: movdqa [rdx+rcx*2], xmm1 michael@0: movdqa [rdx+rax ], xmm1 michael@0: lea rdx, [rdx+rcx*4] michael@0: movdqa [rdx ], xmm1 michael@0: movdqa [rdx+rcx ], xmm1 michael@0: movdqa [rdx+rcx*2], xmm1 michael@0: movdqa [rdx+rax ], xmm1 michael@0: lea rdx, [rdx+rcx*4] michael@0: dec rsi michael@0: jnz .label michael@0: michael@0: ; begin epilog michael@0: RESTORE_GOT michael@0: pop rsi michael@0: UNSHADOW_ARGS michael@0: pop rbp michael@0: ret michael@0: michael@0: ;void vp8_intra_pred_y_dcleft_sse2( michael@0: ; unsigned char *dst, michael@0: ; int dst_stride michael@0: ; unsigned char *above, michael@0: ; unsigned char *left, michael@0: ; int left_stride michael@0: ; ) michael@0: global sym(vp8_intra_pred_y_dcleft_sse2) PRIVATE michael@0: sym(vp8_intra_pred_y_dcleft_sse2): michael@0: push rbp michael@0: mov rbp, rsp michael@0: SHADOW_ARGS_TO_STACK 5 michael@0: push rsi michael@0: push rdi michael@0: ; end prolog michael@0: michael@0: ;arg(2) not used michael@0: michael@0: ; from left michael@0: mov rsi, arg(3) ;left; michael@0: movsxd rax, dword ptr arg(4) ;left_stride; michael@0: michael@0: lea rdi, [rax*3] michael@0: movzx ecx, byte [rsi] michael@0: movzx edx, byte [rsi+rax] michael@0: add ecx, edx michael@0: movzx edx, byte [rsi+rax*2] michael@0: add ecx, edx michael@0: movzx edx, byte [rsi+rdi] michael@0: add ecx, edx michael@0: lea rsi, [rsi+rax*4] michael@0: movzx edx, byte [rsi] michael@0: add ecx, edx michael@0: movzx edx, byte [rsi+rax] michael@0: add ecx, edx michael@0: movzx edx, byte [rsi+rax*2] michael@0: add ecx, edx michael@0: movzx edx, byte [rsi+rdi] michael@0: add ecx, edx michael@0: lea rsi, [rsi+rax*4] michael@0: movzx edx, byte [rsi] michael@0: add ecx, edx michael@0: movzx edx, byte [rsi+rax] michael@0: add ecx, edx michael@0: movzx edx, byte [rsi+rax*2] michael@0: add ecx, edx michael@0: movzx edx, byte [rsi+rdi] michael@0: add ecx, edx michael@0: lea rsi, [rsi+rax*4] michael@0: movzx edx, byte [rsi] michael@0: add ecx, edx michael@0: movzx edx, byte [rsi+rax] michael@0: add ecx, edx michael@0: movzx edx, byte [rsi+rax*2] michael@0: add ecx, edx michael@0: movzx edx, byte [rsi+rdi] michael@0: lea edx, [ecx+edx+8] michael@0: michael@0: ; add up michael@0: shr edx, 4 michael@0: movd xmm1, edx michael@0: ; FIXME use pshufb for ssse3 version michael@0: pshuflw xmm1, xmm1, 0x0 michael@0: punpcklqdq xmm1, xmm1 michael@0: packuswb xmm1, xmm1 michael@0: michael@0: ; write out michael@0: mov rsi, 2 michael@0: mov rdi, arg(0) ;dst; michael@0: movsxd rcx, dword ptr arg(1) ;dst_stride michael@0: lea rax, [rcx*3] michael@0: michael@0: .label michael@0: movdqa [rdi ], xmm1 michael@0: movdqa [rdi+rcx ], xmm1 michael@0: movdqa [rdi+rcx*2], xmm1 michael@0: movdqa [rdi+rax ], xmm1 michael@0: lea rdi, [rdi+rcx*4] michael@0: movdqa [rdi ], xmm1 michael@0: movdqa [rdi+rcx ], xmm1 michael@0: movdqa [rdi+rcx*2], xmm1 michael@0: movdqa [rdi+rax ], xmm1 michael@0: lea rdi, [rdi+rcx*4] michael@0: dec rsi michael@0: jnz .label michael@0: michael@0: ; begin epilog michael@0: pop rdi michael@0: pop rsi michael@0: UNSHADOW_ARGS michael@0: pop rbp michael@0: ret michael@0: michael@0: ;void vp8_intra_pred_y_dc128_sse2( michael@0: ; unsigned char *dst, michael@0: ; int dst_stride michael@0: ; unsigned char *above, michael@0: ; unsigned char *left, michael@0: ; int left_stride michael@0: ; ) michael@0: global sym(vp8_intra_pred_y_dc128_sse2) PRIVATE michael@0: sym(vp8_intra_pred_y_dc128_sse2): michael@0: push rbp michael@0: mov rbp, rsp michael@0: SHADOW_ARGS_TO_STACK 5 michael@0: push rsi michael@0: GET_GOT rbx michael@0: ; end prolog michael@0: michael@0: ;arg(2), arg(3), arg(4) not used michael@0: michael@0: ; write out michael@0: mov rsi, 2 michael@0: movdqa xmm1, [GLOBAL(dc_128)] michael@0: mov rax, arg(0) ;dst; michael@0: movsxd rdx, dword ptr arg(1) ;dst_stride michael@0: lea rcx, [rdx*3] michael@0: michael@0: .label michael@0: movdqa [rax ], xmm1 michael@0: movdqa [rax+rdx ], xmm1 michael@0: movdqa [rax+rdx*2], xmm1 michael@0: movdqa [rax+rcx ], xmm1 michael@0: lea rax, [rax+rdx*4] michael@0: movdqa [rax ], xmm1 michael@0: movdqa [rax+rdx ], xmm1 michael@0: movdqa [rax+rdx*2], xmm1 michael@0: movdqa [rax+rcx ], xmm1 michael@0: lea rax, [rax+rdx*4] michael@0: dec rsi michael@0: jnz .label michael@0: michael@0: ; begin epilog michael@0: RESTORE_GOT michael@0: pop rsi michael@0: UNSHADOW_ARGS michael@0: pop rbp michael@0: ret michael@0: michael@0: ;void vp8_intra_pred_y_tm_sse2( michael@0: ; unsigned char *dst, michael@0: ; int dst_stride michael@0: ; unsigned char *above, michael@0: ; unsigned char *left, michael@0: ; int left_stride michael@0: ; ) michael@0: %macro vp8_intra_pred_y_tm 1 michael@0: global sym(vp8_intra_pred_y_tm_%1) PRIVATE michael@0: sym(vp8_intra_pred_y_tm_%1): michael@0: push rbp michael@0: mov rbp, rsp michael@0: SHADOW_ARGS_TO_STACK 5 michael@0: SAVE_XMM 7 michael@0: push rsi michael@0: push rdi michael@0: GET_GOT rbx michael@0: ; end prolog michael@0: michael@0: ; read top row michael@0: mov edx, 8 michael@0: mov rsi, arg(2) ;above michael@0: movsxd rax, dword ptr arg(4) ;left_stride; michael@0: pxor xmm0, xmm0 michael@0: %ifidn %1, ssse3 michael@0: movdqa xmm3, [GLOBAL(dc_1024)] michael@0: %endif michael@0: movdqa xmm1, [rsi] michael@0: movdqa xmm2, xmm1 michael@0: punpcklbw xmm1, xmm0 michael@0: punpckhbw xmm2, xmm0 michael@0: michael@0: ; set up left ptrs ans subtract topleft michael@0: movd xmm4, [rsi-1] michael@0: mov rsi, arg(3) ;left michael@0: %ifidn %1, sse2 michael@0: punpcklbw xmm4, xmm0 michael@0: pshuflw xmm4, xmm4, 0x0 michael@0: punpcklqdq xmm4, xmm4 michael@0: %else michael@0: pshufb xmm4, xmm3 michael@0: %endif michael@0: psubw xmm1, xmm4 michael@0: psubw xmm2, xmm4 michael@0: michael@0: ; set up dest ptrs michael@0: mov rdi, arg(0) ;dst; michael@0: movsxd rcx, dword ptr arg(1) ;dst_stride michael@0: vp8_intra_pred_y_tm_%1_loop: michael@0: movd xmm4, [rsi] michael@0: movd xmm5, [rsi+rax] michael@0: %ifidn %1, sse2 michael@0: punpcklbw xmm4, xmm0 michael@0: punpcklbw xmm5, xmm0 michael@0: pshuflw xmm4, xmm4, 0x0 michael@0: pshuflw xmm5, xmm5, 0x0 michael@0: punpcklqdq xmm4, xmm4 michael@0: punpcklqdq xmm5, xmm5 michael@0: %else michael@0: pshufb xmm4, xmm3 michael@0: pshufb xmm5, xmm3 michael@0: %endif michael@0: movdqa xmm6, xmm4 michael@0: movdqa xmm7, xmm5 michael@0: paddw xmm4, xmm1 michael@0: paddw xmm6, xmm2 michael@0: paddw xmm5, xmm1 michael@0: paddw xmm7, xmm2 michael@0: packuswb xmm4, xmm6 michael@0: packuswb xmm5, xmm7 michael@0: movdqa [rdi ], xmm4 michael@0: movdqa [rdi+rcx], xmm5 michael@0: lea rsi, [rsi+rax*2] michael@0: lea rdi, [rdi+rcx*2] michael@0: dec edx michael@0: jnz vp8_intra_pred_y_tm_%1_loop michael@0: michael@0: ; begin epilog michael@0: RESTORE_GOT michael@0: pop rdi michael@0: pop rsi michael@0: RESTORE_XMM michael@0: UNSHADOW_ARGS michael@0: pop rbp michael@0: ret michael@0: %endmacro michael@0: michael@0: vp8_intra_pred_y_tm sse2 michael@0: vp8_intra_pred_y_tm ssse3 michael@0: michael@0: ;void vp8_intra_pred_y_ve_sse2( michael@0: ; unsigned char *dst, michael@0: ; int dst_stride michael@0: ; unsigned char *above, michael@0: ; unsigned char *left, michael@0: ; int left_stride michael@0: ; ) michael@0: global sym(vp8_intra_pred_y_ve_sse2) PRIVATE michael@0: sym(vp8_intra_pred_y_ve_sse2): michael@0: push rbp michael@0: mov rbp, rsp michael@0: SHADOW_ARGS_TO_STACK 5 michael@0: push rsi michael@0: ; end prolog michael@0: michael@0: ;arg(3), arg(4) not used michael@0: michael@0: mov rax, arg(2) ;above; michael@0: mov rsi, 2 michael@0: movsxd rdx, dword ptr arg(1) ;dst_stride michael@0: michael@0: ; read from top michael@0: movdqa xmm1, [rax] michael@0: michael@0: ; write out michael@0: mov rax, arg(0) ;dst; michael@0: lea rcx, [rdx*3] michael@0: michael@0: .label michael@0: movdqa [rax ], xmm1 michael@0: movdqa [rax+rdx ], xmm1 michael@0: movdqa [rax+rdx*2], xmm1 michael@0: movdqa [rax+rcx ], xmm1 michael@0: lea rax, [rax+rdx*4] michael@0: movdqa [rax ], xmm1 michael@0: movdqa [rax+rdx ], xmm1 michael@0: movdqa [rax+rdx*2], xmm1 michael@0: movdqa [rax+rcx ], xmm1 michael@0: lea rax, [rax+rdx*4] michael@0: dec rsi michael@0: jnz .label michael@0: michael@0: ; begin epilog michael@0: pop rsi michael@0: UNSHADOW_ARGS michael@0: pop rbp michael@0: ret michael@0: michael@0: ;void vp8_intra_pred_y_ho_sse2( michael@0: ; unsigned char *dst, michael@0: ; int dst_stride michael@0: ; unsigned char *above, michael@0: ; unsigned char *left, michael@0: ; int left_stride, michael@0: ; ) michael@0: global sym(vp8_intra_pred_y_ho_sse2) PRIVATE michael@0: sym(vp8_intra_pred_y_ho_sse2): michael@0: push rbp michael@0: mov rbp, rsp michael@0: SHADOW_ARGS_TO_STACK 5 michael@0: push rsi michael@0: push rdi michael@0: ; end prolog michael@0: michael@0: ;arg(2) not used michael@0: michael@0: ; read from left and write out michael@0: mov edx, 8 michael@0: mov rsi, arg(3) ;left; michael@0: movsxd rax, dword ptr arg(4) ;left_stride; michael@0: mov rdi, arg(0) ;dst; michael@0: movsxd rcx, dword ptr arg(1) ;dst_stride michael@0: michael@0: vp8_intra_pred_y_ho_sse2_loop: michael@0: movd xmm0, [rsi] michael@0: movd xmm1, [rsi+rax] michael@0: ; FIXME use pshufb for ssse3 version michael@0: punpcklbw xmm0, xmm0 michael@0: punpcklbw xmm1, xmm1 michael@0: pshuflw xmm0, xmm0, 0x0 michael@0: pshuflw xmm1, xmm1, 0x0 michael@0: punpcklqdq xmm0, xmm0 michael@0: punpcklqdq xmm1, xmm1 michael@0: movdqa [rdi ], xmm0 michael@0: movdqa [rdi+rcx], xmm1 michael@0: lea rsi, [rsi+rax*2] michael@0: lea rdi, [rdi+rcx*2] michael@0: dec edx michael@0: jnz vp8_intra_pred_y_ho_sse2_loop michael@0: michael@0: ; begin epilog michael@0: pop rdi michael@0: pop rsi michael@0: UNSHADOW_ARGS michael@0: pop rbp michael@0: ret michael@0: michael@0: SECTION_RODATA michael@0: align 16 michael@0: dc_128: michael@0: times 16 db 128 michael@0: dc_4: michael@0: times 4 dw 4 michael@0: align 16 michael@0: dc_8: michael@0: times 8 dw 8 michael@0: align 16 michael@0: dc_1024: michael@0: times 8 dw 0x400 michael@0: align 16 michael@0: dc_00001111: michael@0: times 8 db 0 michael@0: times 8 db 1