blob: 2cffb1e669aa6a793642a68d690aac991788ec42 [file] [log] [blame]
;
; Copyright (c) 2021, Alliance for Open Media. All rights reserved
;
; This source code is subject to the terms of the BSD 3-Clause Clear License and the
; Alliance for Open Media Patent License 1.0. If the BSD 3-Clause Clear License was
; not distributed with this source code in the LICENSE file, you can obtain it
; at aomedia.org/license/software-license/bsd-3-c-c/. 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 aomedia.org/license/patent-license/.
;
;
; Increment %1 by sizeof() tran_low_t * %2.
%macro INCREMENT_ELEMENTS_TRAN_LOW 2
lea %1, [%1 + %2 * 4]
%endmacro
; Load %2 + %3 into m%1.
; %3 is the offset in elements, not bytes.
; If tran_low_t is 16 bits (low bit depth configuration) then load the value
; directly. If tran_low_t is 32 bits (high bit depth configuration) then pack
; the values down to 16 bits.
%macro LOAD_TRAN_LOW 3
mova m%1, [%2 + (%3) * 4]
packssdw m%1, [%2 + (%3) * 4 + 16]
%endmacro
%define private_prefix av1
%include "third_party/x86inc/x86inc.asm"
SECTION .text
; int64_t av1_block_error(int16_t *coeff, int16_t *dqcoeff, intptr_t block_size,
; int64_t *ssz)
INIT_XMM sse2
cglobal block_error, 3, 3, 8, uqc, dqc, size, ssz
pxor m4, m4 ; sse accumulator
pxor m6, m6 ; ssz accumulator
pxor m5, m5 ; dedicated zero register
.loop:
LOAD_TRAN_LOW 2, uqcq, 0
LOAD_TRAN_LOW 0, dqcq, 0
LOAD_TRAN_LOW 3, uqcq, 8
LOAD_TRAN_LOW 1, dqcq, 8
INCREMENT_ELEMENTS_TRAN_LOW uqcq, 16
INCREMENT_ELEMENTS_TRAN_LOW dqcq, 16
sub sizeq, 16
psubw m0, m2
psubw m1, m3
; individual errors are max. 15bit+sign, so squares are 30bit, and
; thus the sum of 2 should fit in a 31bit integer (+ unused sign bit)
pmaddwd m0, m0
pmaddwd m1, m1
pmaddwd m2, m2
pmaddwd m3, m3
; the sum of 2 31bit integers will fit in a 32bit unsigned integer
paddd m0, m1
paddd m2, m3
; accumulate in 64bit
punpckldq m7, m0, m5
punpckhdq m0, m5
paddq m4, m7
punpckldq m7, m2, m5
paddq m4, m0
punpckhdq m2, m5
paddq m6, m7
paddq m6, m2
jg .loop
; accumulate horizontally and store in return value
movhlps m5, m4
movhlps m7, m6
paddq m4, m5
paddq m6, m7
%if ARCH_X86_64
movq rax, m4
movq [sszq], m6
%else
mov eax, sszm
pshufd m5, m4, 0x1
movq [eax], m6
movd eax, m4
movd edx, m5
%endif
RET