rv40dsp x86: use only one register, for both increment and loop counter
[ffmpeg.git] / libavcodec / x86 / rv40dsp.asm
1 ;******************************************************************************
2 ;* MMX/SSE2-optimized functions for the RV40 decoder
3 ;* Copyright (C) 2012 Christophe Gisquet <christophe.gisquet@gmail.com>
4 ;*
5 ;* This file is part of Libav.
6 ;*
7 ;* Libav is free software; you can redistribute it and/or
8 ;* modify it under the terms of the GNU Lesser General Public
9 ;* License as published by the Free Software Foundation; either
10 ;* version 2.1 of the License, or (at your option) any later version.
11 ;*
12 ;* Libav is distributed in the hope that it will be useful,
13 ;* but WITHOUT ANY WARRANTY; without even the implied warranty of
14 ;* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15 ;* Lesser General Public License for more details.
16 ;*
17 ;* You should have received a copy of the GNU Lesser General Public
18 ;* License along with Libav; if not, write to the Free Software
19 ;* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 ;******************************************************************************
21
22 %include "x86inc.asm"
23 %include "x86util.asm"
24
25 SECTION_RODATA
26
27 align 16
28 shift_round:   times 8 dw 1 << (16 - 6)
29 cextern pw_16
30
31 SECTION .text
32
33 ; %1=5bits weights?, %2=dst %3=src1 %4=src3 %5=stride if sse2
34 %macro RV40_WCORE  4-5
35     movh       m4, [%3 + r6 + 0]
36     movh       m5, [%4 + r6 + 0]
37 %if %0 == 4
38 %define OFFSET r6 + mmsize / 2
39 %else
40     ; 8x8 block and sse2, stride was provided
41 %define OFFSET r6
42     add        r6, r5
43 %endif
44     movh       m6, [%3 + OFFSET]
45     movh       m7, [%4 + OFFSET]
46
47 %if %1 == 0
48     ; 14bits weights
49     punpcklbw  m4, m0
50     punpcklbw  m5, m0
51     punpcklbw  m6, m0
52     punpcklbw  m7, m0
53
54     psllw      m4, 7
55     psllw      m5, 7
56     psllw      m6, 7
57     psllw      m7, 7
58     pmulhw     m4, m3
59     pmulhw     m5, m2
60     pmulhw     m6, m3
61     pmulhw     m7, m2
62
63     paddw      m4, m5
64     paddw      m6, m7
65 %else
66     ; 5bits weights
67 %if cpuflag(ssse3)
68     punpcklbw  m4, m5
69     punpcklbw  m6, m7
70
71     pmaddubsw  m4, m3
72     pmaddubsw  m6, m3
73 %else
74     punpcklbw  m4, m0
75     punpcklbw  m5, m0
76     punpcklbw  m6, m0
77     punpcklbw  m7, m0
78
79     pmullw     m4, m3
80     pmullw     m5, m2
81     pmullw     m6, m3
82     pmullw     m7, m2
83     paddw      m4, m5
84     paddw      m6, m7
85 %endif
86
87 %endif
88
89     ; bias and shift down
90 %if cpuflag(ssse3)
91     pmulhrsw   m4, m1
92     pmulhrsw   m6, m1
93 %else
94     paddw      m4, m1
95     paddw      m6, m1
96     psrlw      m4, 5
97     psrlw      m6, 5
98 %endif
99
100     packuswb   m4, m6
101 %if %0 == 5
102     ; Only called for 8x8 blocks and sse2
103     sub        r6, r5
104     movh       [%2 + r6], m4
105     add        r6, r5
106     movhps     [%2 + r6], m4
107 %else
108     mova       [%2 + r6], m4
109 %endif
110 %endmacro
111
112
113 %macro MAIN_LOOP   2
114 %if mmsize == 8
115     RV40_WCORE %2, r0, r1, r2
116 %if %1 == 16
117     RV40_WCORE %2, r0 + 8, r1 + 8, r2 + 8
118 %endif
119
120     ; Prepare for next loop
121     add        r6, r5
122 %else
123 %ifidn %1, 8
124     RV40_WCORE %2, r0, r1, r2, r5
125     ; Prepare 2 next lines
126     add        r6, r5
127 %else
128     RV40_WCORE %2, r0, r1, r2
129     ; Prepare single next line
130     add        r6, r5
131 %endif
132 %endif
133
134 %endmacro
135
136 ; rv40_weight_func_%1(uint8_t *dst, uint8_t *src1, uint8_t *src2, int w1, int w2, int stride)
137 ; %1=size  %2=num of xmm regs
138 ; The weights are FP0.14 notation of fractions depending on pts.
139 ; For timebases without rounding error (i.e. PAL), the fractions
140 ; can be simplified, and several operations can be avoided.
141 ; Therefore, we check here whether they are multiples of 2^9 for
142 ; those simplifications to occur.
143 %macro RV40_WEIGHT  3
144 cglobal rv40_weight_func_%1_%2, 6, 7, 8
145 %if cpuflag(ssse3)
146     mova       m1, [shift_round]
147 %else
148     mova       m1, [pw_16]
149 %endif
150     pxor       m0, m0
151     ; Set loop counter and increments
152     mov        r6, r5
153     shl        r6, %3
154     add        r0, r6
155     add        r1, r6
156     add        r2, r6
157     neg        r6
158
159     movd       m2, r3
160     movd       m3, r4
161 %ifidn %1,rnd
162 %define  RND   0
163     SPLATW     m2, m2
164 %else
165 %define  RND   1
166 %if cpuflag(ssse3)
167     punpcklbw  m3, m2
168 %else
169     SPLATW     m2, m2
170 %endif
171 %endif
172     SPLATW     m3, m3
173
174 .loop:
175     MAIN_LOOP  %2, RND
176     jnz        .loop
177     REP_RET
178 %endmacro
179
180 INIT_MMX mmx
181 RV40_WEIGHT   rnd,    8, 3
182 RV40_WEIGHT   rnd,   16, 4
183 RV40_WEIGHT   nornd,  8, 3
184 RV40_WEIGHT   nornd, 16, 4
185
186 INIT_XMM sse2
187 RV40_WEIGHT   rnd,    8, 3
188 RV40_WEIGHT   rnd,   16, 4
189 RV40_WEIGHT   nornd,  8, 3
190 RV40_WEIGHT   nornd, 16, 4
191
192 INIT_XMM ssse3
193 RV40_WEIGHT   rnd,    8, 3
194 RV40_WEIGHT   rnd,   16, 4
195 RV40_WEIGHT   nornd,  8, 3
196 RV40_WEIGHT   nornd, 16, 4