| ; |
| ; Copyright (c) 2016, Alliance for Open Media. All rights reserved |
| ; |
| ; This source code is subject to the terms of the BSD 2 Clause License and |
| ; the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License |
| ; was not distributed with this source code in the LICENSE file, you can |
| ; obtain it at www.aomedia.org/license/software. If the Alliance for Open |
| ; Media Patent License 1.0 was not distributed with this source code in the |
| ; PATENTS file, you can obtain it at www.aomedia.org/license/patent. |
| ; |
| |
| ; |
| |
| %include "aom_ports/x86_abi_support.asm" |
| |
| ; tabulate_ssim - sums sum_s,sum_r,sum_sq_s,sum_sq_r, sum_sxr |
| %macro TABULATE_SSIM 0 |
| paddusw xmm15, xmm3 ; sum_s |
| paddusw xmm14, xmm4 ; sum_r |
| movdqa xmm1, xmm3 |
| pmaddwd xmm1, xmm1 |
| paddd xmm13, xmm1 ; sum_sq_s |
| movdqa xmm2, xmm4 |
| pmaddwd xmm2, xmm2 |
| paddd xmm12, xmm2 ; sum_sq_r |
| pmaddwd xmm3, xmm4 |
| paddd xmm11, xmm3 ; sum_sxr |
| %endmacro |
| |
| ; Sum across the register %1 starting with q words |
| %macro SUM_ACROSS_Q 1 |
| movdqa xmm2,%1 |
| punpckldq %1,xmm0 |
| punpckhdq xmm2,xmm0 |
| paddq %1,xmm2 |
| movdqa xmm2,%1 |
| punpcklqdq %1,xmm0 |
| punpckhqdq xmm2,xmm0 |
| paddq %1,xmm2 |
| %endmacro |
| |
| ; Sum across the register %1 starting with q words |
| %macro SUM_ACROSS_W 1 |
| movdqa xmm1, %1 |
| punpcklwd %1,xmm0 |
| punpckhwd xmm1,xmm0 |
| paddd %1, xmm1 |
| SUM_ACROSS_Q %1 |
| %endmacro |
| |
| SECTION .text |
| |
| ;void ssim_parms_sse2( |
| ; unsigned char *s, |
| ; int sp, |
| ; unsigned char *r, |
| ; int rp |
| ; uint32_t *sum_s, |
| ; uint32_t *sum_r, |
| ; uint32_t *sum_sq_s, |
| ; uint32_t *sum_sq_r, |
| ; uint32_t *sum_sxr); |
| ; |
| ; TODO: Use parm passing through structure, probably don't need the pxors |
| ; ( calling app will initialize to 0 ) could easily fit everything in sse2 |
| ; without too much hastle, and can probably do better estimates with psadw |
| ; or pavgb At this point this is just meant to be first pass for calculating |
| ; all the parms needed for 16x16 ssim so we can play with dssim as distortion |
| ; in mode selection code. |
| global sym(aom_ssim_parms_16x16_sse2) PRIVATE |
| sym(aom_ssim_parms_16x16_sse2): |
| push rbp |
| mov rbp, rsp |
| SHADOW_ARGS_TO_STACK 9 |
| SAVE_XMM 15 |
| push rsi |
| push rdi |
| ; end prolog |
| |
| mov rsi, arg(0) ;s |
| mov rcx, arg(1) ;sp |
| mov rdi, arg(2) ;r |
| mov rax, arg(3) ;rp |
| |
| pxor xmm0, xmm0 |
| pxor xmm15,xmm15 ;sum_s |
| pxor xmm14,xmm14 ;sum_r |
| pxor xmm13,xmm13 ;sum_sq_s |
| pxor xmm12,xmm12 ;sum_sq_r |
| pxor xmm11,xmm11 ;sum_sxr |
| |
| mov rdx, 16 ;row counter |
| .NextRow: |
| |
| ;grab source and reference pixels |
| movdqu xmm5, [rsi] |
| movdqu xmm6, [rdi] |
| movdqa xmm3, xmm5 |
| movdqa xmm4, xmm6 |
| punpckhbw xmm3, xmm0 ; high_s |
| punpckhbw xmm4, xmm0 ; high_r |
| |
| TABULATE_SSIM |
| |
| movdqa xmm3, xmm5 |
| movdqa xmm4, xmm6 |
| punpcklbw xmm3, xmm0 ; low_s |
| punpcklbw xmm4, xmm0 ; low_r |
| |
| TABULATE_SSIM |
| |
| add rsi, rcx ; next s row |
| add rdi, rax ; next r row |
| |
| dec rdx ; counter |
| jnz .NextRow |
| |
| SUM_ACROSS_W xmm15 |
| SUM_ACROSS_W xmm14 |
| SUM_ACROSS_Q xmm13 |
| SUM_ACROSS_Q xmm12 |
| SUM_ACROSS_Q xmm11 |
| |
| mov rdi,arg(4) |
| movd [rdi], xmm15; |
| mov rdi,arg(5) |
| movd [rdi], xmm14; |
| mov rdi,arg(6) |
| movd [rdi], xmm13; |
| mov rdi,arg(7) |
| movd [rdi], xmm12; |
| mov rdi,arg(8) |
| movd [rdi], xmm11; |
| |
| ; begin epilog |
| pop rdi |
| pop rsi |
| RESTORE_XMM |
| UNSHADOW_ARGS |
| pop rbp |
| ret |
| |
| ;void ssim_parms_sse2( |
| ; unsigned char *s, |
| ; int sp, |
| ; unsigned char *r, |
| ; int rp |
| ; uint32_t *sum_s, |
| ; uint32_t *sum_r, |
| ; uint32_t *sum_sq_s, |
| ; uint32_t *sum_sq_r, |
| ; uint32_t *sum_sxr); |
| ; |
| ; TODO: Use parm passing through structure, probably don't need the pxors |
| ; ( calling app will initialize to 0 ) could easily fit everything in sse2 |
| ; without too much hastle, and can probably do better estimates with psadw |
| ; or pavgb At this point this is just meant to be first pass for calculating |
| ; all the parms needed for 16x16 ssim so we can play with dssim as distortion |
| ; in mode selection code. |
| global sym(aom_ssim_parms_8x8_sse2) PRIVATE |
| sym(aom_ssim_parms_8x8_sse2): |
| push rbp |
| mov rbp, rsp |
| SHADOW_ARGS_TO_STACK 9 |
| SAVE_XMM 15 |
| push rsi |
| push rdi |
| ; end prolog |
| |
| mov rsi, arg(0) ;s |
| mov rcx, arg(1) ;sp |
| mov rdi, arg(2) ;r |
| mov rax, arg(3) ;rp |
| |
| pxor xmm0, xmm0 |
| pxor xmm15,xmm15 ;sum_s |
| pxor xmm14,xmm14 ;sum_r |
| pxor xmm13,xmm13 ;sum_sq_s |
| pxor xmm12,xmm12 ;sum_sq_r |
| pxor xmm11,xmm11 ;sum_sxr |
| |
| mov rdx, 8 ;row counter |
| .NextRow: |
| |
| ;grab source and reference pixels |
| movq xmm3, [rsi] |
| movq xmm4, [rdi] |
| punpcklbw xmm3, xmm0 ; low_s |
| punpcklbw xmm4, xmm0 ; low_r |
| |
| TABULATE_SSIM |
| |
| add rsi, rcx ; next s row |
| add rdi, rax ; next r row |
| |
| dec rdx ; counter |
| jnz .NextRow |
| |
| SUM_ACROSS_W xmm15 |
| SUM_ACROSS_W xmm14 |
| SUM_ACROSS_Q xmm13 |
| SUM_ACROSS_Q xmm12 |
| SUM_ACROSS_Q xmm11 |
| |
| mov rdi,arg(4) |
| movd [rdi], xmm15; |
| mov rdi,arg(5) |
| movd [rdi], xmm14; |
| mov rdi,arg(6) |
| movd [rdi], xmm13; |
| mov rdi,arg(7) |
| movd [rdi], xmm12; |
| mov rdi,arg(8) |
| movd [rdi], xmm11; |
| |
| ; begin epilog |
| pop rdi |
| pop rsi |
| RESTORE_XMM |
| UNSHADOW_ARGS |
| pop rbp |
| ret |