d721ebda6bcb48b3012c806fddead38c6d01be49
[ffmpeg.git] / libavcodec / x86 / apedsp.asm
1 ;******************************************************************************
2 ;* Copyright (c) 2008 Loren Merritt
3 ;*
4 ;* This file is part of Libav.
5 ;*
6 ;* Libav is free software; you can redistribute it and/or
7 ;* modify it under the terms of the GNU Lesser General Public
8 ;* License as published by the Free Software Foundation; either
9 ;* version 2.1 of the License, or (at your option) any later version.
10 ;*
11 ;* Libav is distributed in the hope that it will be useful,
12 ;* but WITHOUT ANY WARRANTY; without even the implied warranty of
13 ;* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 ;* Lesser General Public License for more details.
15 ;*
16 ;* You should have received a copy of the GNU Lesser General Public
17 ;* License along with Libav; if not, write to the Free Software
18 ;* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 ;******************************************************************************
20
21 %include "libavutil/x86/x86util.asm"
22
23 SECTION_TEXT
24
25 %macro SCALARPRODUCT 0
26 ; int ff_scalarproduct_and_madd_int16(int16_t *v1, int16_t *v2, int16_t *v3,
27 ;                                     int order, int mul)
28 cglobal scalarproduct_and_madd_int16, 4,4,8, v1, v2, v3, order, mul
29     shl orderq, 1
30     movd    m7, mulm
31 %if mmsize == 16
32     pshuflw m7, m7, 0
33     punpcklqdq m7, m7
34 %else
35     pshufw  m7, m7, 0
36 %endif
37     pxor    m6, m6
38     add v1q, orderq
39     add v2q, orderq
40     add v3q, orderq
41     neg orderq
42 .loop:
43     movu    m0, [v2q + orderq]
44     movu    m1, [v2q + orderq + mmsize]
45     mova    m4, [v1q + orderq]
46     mova    m5, [v1q + orderq + mmsize]
47     movu    m2, [v3q + orderq]
48     movu    m3, [v3q + orderq + mmsize]
49     pmaddwd m0, m4
50     pmaddwd m1, m5
51     pmullw  m2, m7
52     pmullw  m3, m7
53     paddd   m6, m0
54     paddd   m6, m1
55     paddw   m2, m4
56     paddw   m3, m5
57     mova    [v1q + orderq], m2
58     mova    [v1q + orderq + mmsize], m3
59     add     orderq, mmsize*2
60     jl .loop
61 %if mmsize == 16
62     movhlps m0, m6
63     paddd   m6, m0
64     pshuflw m0, m6, 0x4e
65 %else
66     pshufw  m0, m6, 0x4e
67 %endif
68     paddd   m6, m0
69     movd   eax, m6
70     RET
71 %endmacro
72
73 INIT_MMX mmxext
74 SCALARPRODUCT
75 INIT_XMM sse2
76 SCALARPRODUCT
77
78 %macro SCALARPRODUCT_LOOP 1
79 align 16
80 .loop%1:
81     sub     orderq, mmsize*2
82 %if %1
83     mova    m1, m4
84     mova    m4, [v2q + orderq]
85     mova    m0, [v2q + orderq + mmsize]
86     palignr m1, m0, %1
87     palignr m0, m4, %1
88     mova    m3, m5
89     mova    m5, [v3q + orderq]
90     mova    m2, [v3q + orderq + mmsize]
91     palignr m3, m2, %1
92     palignr m2, m5, %1
93 %else
94     mova    m0, [v2q + orderq]
95     mova    m1, [v2q + orderq + mmsize]
96     mova    m2, [v3q + orderq]
97     mova    m3, [v3q + orderq + mmsize]
98 %endif
99     %define t0  [v1q + orderq]
100     %define t1  [v1q + orderq + mmsize]
101 %if ARCH_X86_64
102     mova    m8, t0
103     mova    m9, t1
104     %define t0  m8
105     %define t1  m9
106 %endif
107     pmaddwd m0, t0
108     pmaddwd m1, t1
109     pmullw  m2, m7
110     pmullw  m3, m7
111     paddw   m2, t0
112     paddw   m3, t1
113     paddd   m6, m0
114     paddd   m6, m1
115     mova    [v1q + orderq], m2
116     mova    [v1q + orderq + mmsize], m3
117     jg .loop%1
118 %if %1
119     jmp .end
120 %endif
121 %endmacro
122
123 ; int ff_scalarproduct_and_madd_int16(int16_t *v1, int16_t *v2, int16_t *v3,
124 ;                                     int order, int mul)
125 INIT_XMM ssse3
126 cglobal scalarproduct_and_madd_int16, 4,5,10, v1, v2, v3, order, mul
127     shl orderq, 1
128     movd    m7, mulm
129     pshuflw m7, m7, 0
130     punpcklqdq m7, m7
131     pxor    m6, m6
132     mov    r4d, v2d
133     and    r4d, 15
134     and    v2q, ~15
135     and    v3q, ~15
136     mova    m4, [v2q + orderq]
137     mova    m5, [v3q + orderq]
138     ; linear is faster than branch tree or jump table, because the branches taken are cyclic (i.e. predictable)
139     cmp    r4d, 0
140     je .loop0
141     cmp    r4d, 2
142     je .loop2
143     cmp    r4d, 4
144     je .loop4
145     cmp    r4d, 6
146     je .loop6
147     cmp    r4d, 8
148     je .loop8
149     cmp    r4d, 10
150     je .loop10
151     cmp    r4d, 12
152     je .loop12
153 SCALARPRODUCT_LOOP 14
154 SCALARPRODUCT_LOOP 12
155 SCALARPRODUCT_LOOP 10
156 SCALARPRODUCT_LOOP 8
157 SCALARPRODUCT_LOOP 6
158 SCALARPRODUCT_LOOP 4
159 SCALARPRODUCT_LOOP 2
160 SCALARPRODUCT_LOOP 0
161 .end:
162     movhlps m0, m6
163     paddd   m6, m0
164     pshuflw m0, m6, 0x4e
165     paddd   m6, m0
166     movd   eax, m6
167     RET