Merge commit '3fd22538bc0e0de84b31335266b4b1577d3d609e'
[ffmpeg.git] / libavcodec / x86 / simple_idct10_template.asm
1 ;******************************************************************************
2 ;* x86-SIMD-optimized IDCT for prores
3 ;* this is identical to "simple" IDCT written by Michael Niedermayer
4 ;* except for the clip range
5 ;*
6 ;* Copyright (c) 2011 Ronald S. Bultje <rsbultje@gmail.com>
7 ;*
8 ;* This file is part of FFmpeg.
9 ;*
10 ;* FFmpeg is free software; you can redistribute it and/or
11 ;* modify it under the terms of the GNU Lesser General Public
12 ;* License as published by the Free Software Foundation; either
13 ;* version 2.1 of the License, or (at your option) any later version.
14 ;*
15 ;* FFmpeg is distributed in the hope that it will be useful,
16 ;* but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18 ;* Lesser General Public License for more details.
19 ;*
20 ;* You should have received a copy of the GNU Lesser General Public
21 ;* License along with FFmpeg; if not, write to the Free Software
22 ;* 51, Inc., Foundation Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
23 ;******************************************************************************
24
25 ; add SECTION_RODATA and proper include before including this file!
26
27 %if ARCH_X86_64
28
29 ; interleave data while maintaining source
30 ; %1=type, %2=dstlo, %3=dsthi, %4=src, %5=interleave
31 %macro SBUTTERFLY3 5
32     punpckl%1   m%2, m%4, m%5
33     punpckh%1   m%3, m%4, m%5
34 %endmacro
35
36 ; %1/%2=src1/dst1, %3/%4=dst2, %5/%6=src2, %7=shift
37 ; action: %3/%4 = %1/%2 - %5/%6; %1/%2 += %5/%6
38 ;         %1/%2/%3/%4 >>= %7; dword -> word (in %1/%3)
39 %macro SUMSUB_SHPK 7
40     psubd       %3,  %1,  %5       ; { a0 - b0 }[0-3]
41     psubd       %4,  %2,  %6       ; { a0 - b0 }[4-7]
42     paddd       %1,  %5            ; { a0 + b0 }[0-3]
43     paddd       %2,  %6            ; { a0 + b0 }[4-7]
44     psrad       %1,  %7
45     psrad       %2,  %7
46     psrad       %3,  %7
47     psrad       %4,  %7
48     packssdw    %1,  %2            ; row[0]
49     packssdw    %3,  %4            ; row[7]
50 %endmacro
51
52 ; %1 = initial bias ("" if nop)
53 ; %2 = number of bits to shift at the end
54 ; %3 = qmat (for prores)
55 %macro IDCT_1D 2-3
56     ; a0 = (W4 * row[0]) + (1 << (15 - 1));
57     ; a1 = a0;
58     ; a2 = a0;
59     ; a3 = a0;
60     ; a0 += W2 * row[2];
61     ; a1 += W6 * row[2];
62     ; a2 -= W6 * row[2];
63     ; a3 -= W2 * row[2];
64 %ifstr %1
65     mova        m15, [pd_round_ %+ %2]
66 %else
67     paddw       m10, [%1]
68 %endif
69     SBUTTERFLY3 wd,  0,  1, 10,  8 ; { row[0], row[2] }[0-3]/[4-7]
70     pmaddwd     m2,  m0, [w4_plus_w6]
71     pmaddwd     m3,  m1, [w4_plus_w6]
72     pmaddwd     m4,  m0, [w4_min_w6]
73     pmaddwd     m5,  m1, [w4_min_w6]
74     pmaddwd     m6,  m0, [w4_min_w2]
75     pmaddwd     m7,  m1, [w4_min_w2]
76     pmaddwd     m0, [w4_plus_w2]
77     pmaddwd     m1, [w4_plus_w2]
78 %ifstr %1
79     ; Adding 1<<(%2-1) for >=15 bits values
80     paddd       m2, m15
81     paddd       m3, m15
82     paddd       m4, m15
83     paddd       m5, m15
84     paddd       m6, m15
85     paddd       m7, m15
86     paddd       m0, m15
87     paddd       m1, m15
88 %endif
89
90     ; a0: -1*row[0]-1*row[2]
91     ; a1: -1*row[0]
92     ; a2: -1*row[0]
93     ; a3: -1*row[0]+1*row[2]
94
95     ; a0 +=   W4*row[4] + W6*row[6]; i.e. -1*row[4]
96     ; a1 -=   W4*row[4] + W2*row[6]; i.e. -1*row[4]-1*row[6]
97     ; a2 -=   W4*row[4] - W2*row[6]; i.e. -1*row[4]+1*row[6]
98     ; a3 +=   W4*row[4] - W6*row[6]; i.e. -1*row[4]
99     SBUTTERFLY3 wd,  8,  9, 13, 12 ; { row[4], row[6] }[0-3]/[4-7]
100     pmaddwd     m10, m8, [w4_plus_w6]
101     pmaddwd     m11, m9, [w4_plus_w6]
102     paddd       m0,  m10            ; a0[0-3]
103     paddd       m1,  m11            ; a0[4-7]
104     pmaddwd     m10, m8, [w4_min_w6]
105     pmaddwd     m11, m9, [w4_min_w6]
106     paddd       m6,  m10           ; a3[0-3]
107     paddd       m7,  m11           ; a3[4-7]
108     pmaddwd     m10, m8, [w4_min_w2]
109     pmaddwd     m11, m9, [w4_min_w2]
110     pmaddwd     m8, [w4_plus_w2]
111     pmaddwd     m9, [w4_plus_w2]
112     psubd       m4,  m10           ; a2[0-3] intermediate
113     psubd       m5,  m11           ; a2[4-7] intermediate
114     psubd       m2,  m8            ; a1[0-3] intermediate
115     psubd       m3,  m9            ; a1[4-7] intermediate
116
117     ; load/store
118     mova   [COEFFS+  0], m0
119     mova   [COEFFS+ 32], m2
120     mova   [COEFFS+ 64], m4
121     mova   [COEFFS+ 96], m6
122     mova        m10,[COEFFS+ 16]       ; { row[1] }[0-7]
123     mova        m8, [COEFFS+ 48]       ; { row[3] }[0-7]
124     mova        m13,[COEFFS+ 80]       ; { row[5] }[0-7]
125     mova        m14,[COEFFS+112]       ; { row[7] }[0-7]
126     mova   [COEFFS+ 16], m1
127     mova   [COEFFS+ 48], m3
128     mova   [COEFFS+ 80], m5
129     mova   [COEFFS+112], m7
130 %if %0 == 3
131     pmullw      m10,[%3+ 16]
132     pmullw      m8, [%3+ 48]
133     pmullw      m13,[%3+ 80]
134     pmullw      m14,[%3+112]
135 %endif
136
137     ; b0 = MUL(W1, row[1]);
138     ; MAC(b0, W3, row[3]);
139     ; b1 = MUL(W3, row[1]);
140     ; MAC(b1, -W7, row[3]);
141     ; b2 = MUL(W5, row[1]);
142     ; MAC(b2, -W1, row[3]);
143     ; b3 = MUL(W7, row[1]);
144     ; MAC(b3, -W5, row[3]);
145     SBUTTERFLY3 wd,  0,  1, 10, 8  ; { row[1], row[3] }[0-3]/[4-7]
146     pmaddwd     m2,  m0, [w3_min_w7]
147     pmaddwd     m3,  m1, [w3_min_w7]
148     pmaddwd     m4,  m0, [w5_min_w1]
149     pmaddwd     m5,  m1, [w5_min_w1]
150     pmaddwd     m6,  m0, [w7_min_w5]
151     pmaddwd     m7,  m1, [w7_min_w5]
152     pmaddwd     m0, [w1_plus_w3]
153     pmaddwd     m1, [w1_plus_w3]
154
155     ; b0: +1*row[1]+2*row[3]
156     ; b1: +2*row[1]-1*row[3]
157     ; b2: -1*row[1]-1*row[3]
158     ; b3: +1*row[1]+1*row[3]
159
160     ; MAC(b0,  W5, row[5]);
161     ; MAC(b0,  W7, row[7]);
162     ; MAC(b1, -W1, row[5]);
163     ; MAC(b1, -W5, row[7]);
164     ; MAC(b2,  W7, row[5]);
165     ; MAC(b2,  W3, row[7]);
166     ; MAC(b3,  W3, row[5]);
167     ; MAC(b3, -W1, row[7]);
168     SBUTTERFLY3 wd,  8,  9, 13, 14 ; { row[5], row[7] }[0-3]/[4-7]
169
170     ; b0: -1*row[5]+1*row[7]
171     ; b1: -1*row[5]+1*row[7]
172     ; b2: +1*row[5]+2*row[7]
173     ; b3: +2*row[5]-1*row[7]
174
175     pmaddwd     m10, m8, [w1_plus_w5]
176     pmaddwd     m11, m9, [w1_plus_w5]
177     pmaddwd     m12, m8, [w5_plus_w7]
178     pmaddwd     m13, m9, [w5_plus_w7]
179     psubd       m2,  m10           ; b1[0-3]
180     psubd       m3,  m11           ; b1[4-7]
181     paddd       m0,  m12            ; b0[0-3]
182     paddd       m1,  m13            ; b0[4-7]
183     pmaddwd     m12, m8, [w7_plus_w3]
184     pmaddwd     m13, m9, [w7_plus_w3]
185     pmaddwd     m8, [w3_min_w1]
186     pmaddwd     m9, [w3_min_w1]
187     paddd       m4,  m12           ; b2[0-3]
188     paddd       m5,  m13           ; b2[4-7]
189     paddd       m6,  m8            ; b3[0-3]
190     paddd       m7,  m9            ; b3[4-7]
191
192     ; row[0] = (a0 + b0) >> 15;
193     ; row[7] = (a0 - b0) >> 15;
194     ; row[1] = (a1 + b1) >> 15;
195     ; row[6] = (a1 - b1) >> 15;
196     ; row[2] = (a2 + b2) >> 15;
197     ; row[5] = (a2 - b2) >> 15;
198     ; row[3] = (a3 + b3) >> 15;
199     ; row[4] = (a3 - b3) >> 15;
200     mova        m8, [COEFFS+ 0]        ; a0[0-3]
201     mova        m9, [COEFFS+16]        ; a0[4-7]
202     SUMSUB_SHPK m8,  m9,  m10, m11, m0,  m1,  %2
203     mova        m0, [COEFFS+32]        ; a1[0-3]
204     mova        m1, [COEFFS+48]        ; a1[4-7]
205     SUMSUB_SHPK m0,  m1,  m9,  m11, m2,  m3,  %2
206     mova        m1, [COEFFS+64]        ; a2[0-3]
207     mova        m2, [COEFFS+80]        ; a2[4-7]
208     SUMSUB_SHPK m1,  m2,  m11, m3,  m4,  m5,  %2
209     mova        m2, [COEFFS+96]        ; a3[0-3]
210     mova        m3, [COEFFS+112]       ; a3[4-7]
211     SUMSUB_SHPK m2,  m3,  m4,  m5,  m6,  m7,  %2
212 %endmacro
213
214 ; void ff_prores_idct_put_10_<opt>(uint8_t *pixels, ptrdiff_t stride,
215 ;                                  int16_t *block, const int16_t *qmat);
216
217 ; %1 = row shift
218 ; %2 = row bias macro
219 ; %3 = column shift
220 ; %4 = column bias macro
221 ; %5 = min pixel value
222 ; %6 = max pixel value
223 ; %7 = qmat (for prores)
224
225 %macro IDCT_FN 4-7
226 %if %0 == 4
227     ; No clamping, means pure idct
228 %xdefine COEFFS r0
229 %else
230     movsxd      r1,  r1d
231 %xdefine COEFFS r2
232 %endif
233
234     ; for (i = 0; i < 8; i++)
235     ;     idctRowCondDC(block + i*8);
236     mova        m10,[COEFFS+ 0]        ; { row[0] }[0-7]
237     mova        m8, [COEFFS+32]        ; { row[2] }[0-7]
238     mova        m13,[COEFFS+64]        ; { row[4] }[0-7]
239     mova        m12,[COEFFS+96]        ; { row[6] }[0-7]
240
241 %if %0 == 7
242     pmullw      m10,[%7+ 0]
243     pmullw      m8, [%7+32]
244     pmullw      m13,[%7+64]
245     pmullw      m12,[%7+96]
246
247     IDCT_1D     %1, %2, %7
248 %else
249     IDCT_1D     %1, %2
250 %endif
251
252     ; transpose for second part of IDCT
253     TRANSPOSE8x8W 8, 0, 1, 2, 4, 11, 9, 10, 3
254     mova   [COEFFS+ 16], m0
255     mova   [COEFFS+ 48], m2
256     mova   [COEFFS+ 80], m11
257     mova   [COEFFS+112], m10
258     SWAP         8,  10
259     SWAP         1,   8
260     SWAP         4,  13
261     SWAP         9,  12
262
263     ; for (i = 0; i < 8; i++)
264     ;     idctSparseColAdd(dest + i, line_size, block + i);
265     IDCT_1D     %3, %4
266
267     ; clip/store
268 %if %0 == 4
269     ; No clamping, means pure idct
270     mova  [r0+  0], m8
271     mova  [r0+ 16], m0
272     mova  [r0+ 32], m1
273     mova  [r0+ 48], m2
274     mova  [r0+ 64], m4
275     mova  [r0+ 80], m11
276     mova  [r0+ 96], m9
277     mova  [r0+112], m10
278 %else
279 %ifidn %5, 0
280     pxor        m3, m3
281 %else
282     mova        m3, [%5]
283 %endif
284     mova        m5, [%6]
285     pmaxsw      m8,  m3
286     pmaxsw      m0,  m3
287     pmaxsw      m1,  m3
288     pmaxsw      m2,  m3
289     pmaxsw      m4,  m3
290     pmaxsw      m11, m3
291     pmaxsw      m9,  m3
292     pmaxsw      m10, m3
293     pminsw      m8,  m5
294     pminsw      m0,  m5
295     pminsw      m1,  m5
296     pminsw      m2,  m5
297     pminsw      m4,  m5
298     pminsw      m11, m5
299     pminsw      m9,  m5
300     pminsw      m10, m5
301
302     lea         r2, [r1*3]
303     mova  [r0     ], m8
304     mova  [r0+r1  ], m0
305     mova  [r0+r1*2], m1
306     mova  [r0+r2  ], m2
307     lea         r0, [r0+r1*4]
308     mova  [r0     ], m4
309     mova  [r0+r1  ], m11
310     mova  [r0+r1*2], m9
311     mova  [r0+r2  ], m10
312 %endif
313 %endmacro
314
315 %endif