Merge remote-tracking branch 'qatar/master'
[ffmpeg.git] / libavcodec / x86 / hpeldsp_rnd_template.c
1 /*
2  * DSP utils mmx functions are compiled twice for rnd/no_rnd
3  * Copyright (c) 2000, 2001 Fabrice Bellard
4  * Copyright (c) 2003-2004 Michael Niedermayer <michaelni@gmx.at>
5  *
6  * MMX optimization by Nick Kurshev <nickols_k@mail.ru>
7  * mostly rewritten by Michael Niedermayer <michaelni@gmx.at>
8  * and improved by Zdenek Kabelac <kabi@users.sf.net>
9  *
10  * This file is part of FFmpeg.
11  *
12  * FFmpeg is free software; you can redistribute it and/or
13  * modify it under the terms of the GNU Lesser General Public
14  * License as published by the Free Software Foundation; either
15  * version 2.1 of the License, or (at your option) any later version.
16  *
17  * FFmpeg is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
20  * Lesser General Public License for more details.
21  *
22  * You should have received a copy of the GNU Lesser General Public
23  * License along with FFmpeg; if not, write to the Free Software
24  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
25  */
26
27 #include "rnd_template.c"
28
29 // put_pixels
30 static void DEF(put, pixels8_x2)(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h)
31 {
32     MOVQ_BFE(mm6);
33     __asm__ volatile(
34         "lea    (%3, %3), %%"REG_a"     \n\t"
35         ".p2align 3                     \n\t"
36         "1:                             \n\t"
37         "movq   (%1), %%mm0             \n\t"
38         "movq   1(%1), %%mm1            \n\t"
39         "movq   (%1, %3), %%mm2         \n\t"
40         "movq   1(%1, %3), %%mm3        \n\t"
41         PAVGBP(%%mm0, %%mm1, %%mm4,   %%mm2, %%mm3, %%mm5)
42         "movq   %%mm4, (%2)             \n\t"
43         "movq   %%mm5, (%2, %3)         \n\t"
44         "add    %%"REG_a", %1           \n\t"
45         "add    %%"REG_a", %2           \n\t"
46         "movq   (%1), %%mm0             \n\t"
47         "movq   1(%1), %%mm1            \n\t"
48         "movq   (%1, %3), %%mm2         \n\t"
49         "movq   1(%1, %3), %%mm3        \n\t"
50         PAVGBP(%%mm0, %%mm1, %%mm4,   %%mm2, %%mm3, %%mm5)
51         "movq   %%mm4, (%2)             \n\t"
52         "movq   %%mm5, (%2, %3)         \n\t"
53         "add    %%"REG_a", %1           \n\t"
54         "add    %%"REG_a", %2           \n\t"
55         "subl   $4, %0                  \n\t"
56         "jnz    1b                      \n\t"
57         :"+g"(h), "+S"(pixels), "+D"(block)
58         :"r"((x86_reg)line_size)
59         :REG_a, "memory");
60 }
61
62 static void DEF(put, pixels16_x2)(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h)
63 {
64     MOVQ_BFE(mm6);
65     __asm__ volatile(
66         "lea        (%3, %3), %%"REG_a" \n\t"
67         ".p2align 3                     \n\t"
68         "1:                             \n\t"
69         "movq   (%1), %%mm0             \n\t"
70         "movq   1(%1), %%mm1            \n\t"
71         "movq   (%1, %3), %%mm2         \n\t"
72         "movq   1(%1, %3), %%mm3        \n\t"
73         PAVGBP(%%mm0, %%mm1, %%mm4,   %%mm2, %%mm3, %%mm5)
74         "movq   %%mm4, (%2)             \n\t"
75         "movq   %%mm5, (%2, %3)         \n\t"
76         "movq   8(%1), %%mm0            \n\t"
77         "movq   9(%1), %%mm1            \n\t"
78         "movq   8(%1, %3), %%mm2        \n\t"
79         "movq   9(%1, %3), %%mm3        \n\t"
80         PAVGBP(%%mm0, %%mm1, %%mm4,   %%mm2, %%mm3, %%mm5)
81         "movq   %%mm4, 8(%2)            \n\t"
82         "movq   %%mm5, 8(%2, %3)        \n\t"
83         "add    %%"REG_a", %1           \n\t"
84         "add    %%"REG_a", %2           \n\t"
85         "movq   (%1), %%mm0             \n\t"
86         "movq   1(%1), %%mm1            \n\t"
87         "movq   (%1, %3), %%mm2         \n\t"
88         "movq   1(%1, %3), %%mm3        \n\t"
89         PAVGBP(%%mm0, %%mm1, %%mm4,   %%mm2, %%mm3, %%mm5)
90         "movq   %%mm4, (%2)             \n\t"
91         "movq   %%mm5, (%2, %3)         \n\t"
92         "movq   8(%1), %%mm0            \n\t"
93         "movq   9(%1), %%mm1            \n\t"
94         "movq   8(%1, %3), %%mm2        \n\t"
95         "movq   9(%1, %3), %%mm3        \n\t"
96         PAVGBP(%%mm0, %%mm1, %%mm4,   %%mm2, %%mm3, %%mm5)
97         "movq   %%mm4, 8(%2)            \n\t"
98         "movq   %%mm5, 8(%2, %3)        \n\t"
99         "add    %%"REG_a", %1           \n\t"
100         "add    %%"REG_a", %2           \n\t"
101         "subl   $4, %0                  \n\t"
102         "jnz    1b                      \n\t"
103         :"+g"(h), "+S"(pixels), "+D"(block)
104         :"r"((x86_reg)line_size)
105         :REG_a, "memory");
106 }
107
108 static void DEF(put, pixels8_y2)(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h)
109 {
110     MOVQ_BFE(mm6);
111     __asm__ volatile(
112         "lea (%3, %3), %%"REG_a"        \n\t"
113         "movq (%1), %%mm0               \n\t"
114         ".p2align 3                     \n\t"
115         "1:                             \n\t"
116         "movq   (%1, %3), %%mm1         \n\t"
117         "movq   (%1, %%"REG_a"),%%mm2   \n\t"
118         PAVGBP(%%mm1, %%mm0, %%mm4,   %%mm2, %%mm1, %%mm5)
119         "movq   %%mm4, (%2)             \n\t"
120         "movq   %%mm5, (%2, %3)         \n\t"
121         "add    %%"REG_a", %1           \n\t"
122         "add    %%"REG_a", %2           \n\t"
123         "movq   (%1, %3), %%mm1         \n\t"
124         "movq   (%1, %%"REG_a"),%%mm0   \n\t"
125         PAVGBP(%%mm1, %%mm2, %%mm4,   %%mm0, %%mm1, %%mm5)
126         "movq   %%mm4, (%2)             \n\t"
127         "movq   %%mm5, (%2, %3)         \n\t"
128         "add    %%"REG_a", %1           \n\t"
129         "add    %%"REG_a", %2           \n\t"
130         "subl   $4, %0                  \n\t"
131         "jnz    1b                      \n\t"
132         :"+g"(h), "+S"(pixels), "+D"(block)
133         :"r"((x86_reg)line_size)
134         :REG_a, "memory");
135 }
136
137 #ifndef NO_RND
138 static void DEF(avg, pixels8_x2)(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h)
139 {
140     MOVQ_BFE(mm6);
141     JUMPALIGN();
142     do {
143         __asm__ volatile(
144             "movq  %1, %%mm0            \n\t"
145             "movq  1%1, %%mm1           \n\t"
146             "movq  %0, %%mm3            \n\t"
147             PAVGB(%%mm0, %%mm1, %%mm2, %%mm6)
148             OP_AVG(%%mm3, %%mm2, %%mm0, %%mm6)
149             "movq  %%mm0, %0            \n\t"
150             :"+m"(*block)
151             :"m"(*pixels)
152             :"memory");
153         pixels += line_size;
154         block += line_size;
155     } while (--h);
156 }
157 #endif // NO_RND
158
159 static void DEF(avg, pixels16_x2)(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h)
160 {
161     MOVQ_BFE(mm6);
162     JUMPALIGN();
163     do {
164         __asm__ volatile(
165             "movq  %1, %%mm0            \n\t"
166             "movq  1%1, %%mm1           \n\t"
167             "movq  %0, %%mm3            \n\t"
168             PAVGB(%%mm0, %%mm1, %%mm2, %%mm6)
169             OP_AVG(%%mm3, %%mm2, %%mm0, %%mm6)
170             "movq  %%mm0, %0            \n\t"
171             "movq  8%1, %%mm0           \n\t"
172             "movq  9%1, %%mm1           \n\t"
173             "movq  8%0, %%mm3           \n\t"
174             PAVGB(%%mm0, %%mm1, %%mm2, %%mm6)
175             OP_AVG(%%mm3, %%mm2, %%mm0, %%mm6)
176             "movq  %%mm0, 8%0           \n\t"
177             :"+m"(*block)
178             :"m"(*pixels)
179             :"memory");
180         pixels += line_size;
181         block += line_size;
182     } while (--h);
183 }
184
185 static void DEF(avg, pixels8_y2)(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h)
186 {
187     MOVQ_BFE(mm6);
188     __asm__ volatile(
189         "lea    (%3, %3), %%"REG_a"     \n\t"
190         "movq   (%1), %%mm0             \n\t"
191         ".p2align 3                     \n\t"
192         "1:                             \n\t"
193         "movq   (%1, %3), %%mm1         \n\t"
194         "movq   (%1, %%"REG_a"), %%mm2  \n\t"
195         PAVGBP(%%mm1, %%mm0, %%mm4,   %%mm2, %%mm1, %%mm5)
196         "movq   (%2), %%mm3             \n\t"
197         OP_AVG(%%mm3, %%mm4, %%mm0, %%mm6)
198         "movq   (%2, %3), %%mm3         \n\t"
199         OP_AVG(%%mm3, %%mm5, %%mm1, %%mm6)
200         "movq   %%mm0, (%2)             \n\t"
201         "movq   %%mm1, (%2, %3)         \n\t"
202         "add    %%"REG_a", %1           \n\t"
203         "add    %%"REG_a", %2           \n\t"
204
205         "movq   (%1, %3), %%mm1         \n\t"
206         "movq   (%1, %%"REG_a"), %%mm0  \n\t"
207         PAVGBP(%%mm1, %%mm2, %%mm4,   %%mm0, %%mm1, %%mm5)
208         "movq   (%2), %%mm3             \n\t"
209         OP_AVG(%%mm3, %%mm4, %%mm2, %%mm6)
210         "movq   (%2, %3), %%mm3         \n\t"
211         OP_AVG(%%mm3, %%mm5, %%mm1, %%mm6)
212         "movq   %%mm2, (%2)             \n\t"
213         "movq   %%mm1, (%2, %3)         \n\t"
214         "add    %%"REG_a", %1           \n\t"
215         "add    %%"REG_a", %2           \n\t"
216
217         "subl   $4, %0                  \n\t"
218         "jnz    1b                      \n\t"
219         :"+g"(h), "+S"(pixels), "+D"(block)
220         :"r"((x86_reg)line_size)
221         :REG_a, "memory");
222 }
223
224 //FIXME optimize
225 static void DEF(put, pixels16_y2)(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h){
226     DEF(put, pixels8_y2)(block  , pixels  , line_size, h);
227     DEF(put, pixels8_y2)(block+8, pixels+8, line_size, h);
228 }
229
230 static void DEF(avg, pixels16_y2)(uint8_t *block, const uint8_t *pixels, ptrdiff_t line_size, int h){
231     DEF(avg, pixels8_y2)(block  , pixels  , line_size, h);
232     DEF(avg, pixels8_y2)(block+8, pixels+8, line_size, h);
233 }