Merge commit 'fd9212f2edfe9b107c3c08ba2df5fd2cba5ab9e3'
[ffmpeg.git] / libavcodec / x86 / simple_idct10.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 ;* Copyright (c) 2015 Christophe Gisquet
8 ;*
9 ;* This file is part of FFmpeg.
10 ;*
11 ;* FFmpeg is free software; you can redistribute it and/or
12 ;* modify it under the terms of the GNU Lesser General Public
13 ;* License as published by the Free Software Foundation; either
14 ;* version 2.1 of the License, or (at your option) any later version.
15 ;*
16 ;* FFmpeg is distributed in the hope that it will be useful,
17 ;* but WITHOUT ANY WARRANTY; without even the implied warranty of
18 ;* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
19 ;* Lesser General Public License for more details.
20 ;*
21 ;* You should have received a copy of the GNU Lesser General Public
22 ;* License along with FFmpeg; if not, write to the Free Software
23 ;* 51, Inc., Foundation Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
24 ;******************************************************************************
25
26 %include "libavutil/x86/x86util.asm"
27
28 %if ARCH_X86_64
29
30 SECTION_RODATA
31
32 cextern pw_2
33 cextern pw_16
34 cextern pw_32
35 cextern pw_1023
36 cextern pw_4095
37 pd_round_11: times 4 dd 1<<(11-1)
38 pd_round_12: times 4 dd 1<<(12-1)
39 pd_round_15: times 4 dd 1<<(15-1)
40 pd_round_19: times 4 dd 1<<(19-1)
41 pd_round_20: times 4 dd 1<<(20-1)
42
43 %macro CONST_DEC  3
44 const %1
45 times 4 dw %2, %3
46 %endmacro
47
48 %define W1sh2 22725 ; W1 = 90901 = 22725<<2 + 1
49 %define W2sh2 21407 ; W2 = 85627 = 21407<<2 - 1
50 %define W3sh2 19265 ; W3 = 77062 = 19265<<2 + 2
51 %define W4sh2 16384 ; W4 = 65535 = 16384<<2 - 1
52 %define W3sh2_lo 19266
53 %define W4sh2_lo 16383
54 %define W5sh2 12873 ; W5 = 51491 = 12873<<2 - 1
55 %define W6sh2  8867 ; W6 = 35468 =  8867<<2
56 %define W7sh2  4520 ; W7 = 18081 =  4520<<2 + 1
57
58 CONST_DEC  w4_plus_w2_hi,   W4sh2, +W2sh2
59 CONST_DEC  w4_min_w2_hi,    W4sh2, -W2sh2
60 CONST_DEC  w4_plus_w6_hi,   W4sh2, +W6sh2
61 CONST_DEC  w4_min_w6_hi,    W4sh2, -W6sh2
62 CONST_DEC  w1_plus_w3_hi,   W1sh2, +W3sh2
63 CONST_DEC  w3_min_w1_hi,    W3sh2, -W1sh2
64 CONST_DEC  w7_plus_w3_hi,   W7sh2, +W3sh2
65 CONST_DEC  w3_min_w7_hi,    W3sh2, -W7sh2
66 CONST_DEC  w1_plus_w5,   W1sh2, +W5sh2
67 CONST_DEC  w5_min_w1,    W5sh2, -W1sh2
68 CONST_DEC  w5_plus_w7,   W5sh2, +W7sh2
69 CONST_DEC  w7_min_w5,    W7sh2, -W5sh2
70 CONST_DEC  w4_plus_w2_lo,   W4sh2_lo, +W2sh2
71 CONST_DEC  w4_min_w2_lo,    W4sh2_lo, -W2sh2
72 CONST_DEC  w4_plus_w6_lo,   W4sh2_lo, +W6sh2
73 CONST_DEC  w4_min_w6_lo,    W4sh2_lo, -W6sh2
74 CONST_DEC  w1_plus_w3_lo,   W1sh2,    +W3sh2_lo
75 CONST_DEC  w3_min_w1_lo,    W3sh2_lo, -W1sh2
76 CONST_DEC  w7_plus_w3_lo,   W7sh2,    +W3sh2_lo
77 CONST_DEC  w3_min_w7_lo,    W3sh2_lo, -W7sh2
78
79 %include "libavcodec/x86/simple_idct10_template.asm"
80
81 SECTION .text
82
83 %macro STORE_HI_LO 12
84     movq   %1, %9
85     movq   %3, %10
86     movq   %5, %11
87     movq   %7, %12
88     movhps %2, %9
89     movhps %4, %10
90     movhps %6, %11
91     movhps %8, %12
92 %endmacro
93
94 %macro LOAD_ZXBW_8 16
95     pmovzxbw %1, %9
96     pmovzxbw %2, %10
97     pmovzxbw %3, %11
98     pmovzxbw %4, %12
99     pmovzxbw %5, %13
100     pmovzxbw %6, %14
101     pmovzxbw %7, %15
102     pmovzxbw %8, %16
103 %endmacro
104
105 %macro LOAD_ZXBW_4 9
106     movh %1, %5
107     movh %2, %6
108     movh %3, %7
109     movh %4, %8
110     punpcklbw %1, %9
111     punpcklbw %2, %9
112     punpcklbw %3, %9
113     punpcklbw %4, %9
114 %endmacro
115
116 %define PASS4ROWS(base, stride, stride3) \
117     [base], [base + stride], [base + 2*stride], [base + stride3]
118
119 %macro idct_fn 0
120
121 define_constants _lo
122
123 cglobal simple_idct8, 1, 1, 16, 32, block
124     IDCT_FN    "", 11, pw_32, 20, "store"
125 RET
126
127 cglobal simple_idct8_put, 3, 4, 16, 32, pixels, lsize, block
128     IDCT_FN    "", 11, pw_32, 20
129     lea       r3, [3*lsizeq]
130     lea       r2, [pixelsq + r3]
131     packuswb  m8, m0
132     packuswb  m1, m2
133     packuswb  m4, m11
134     packuswb  m9, m10
135     STORE_HI_LO PASS8ROWS(pixelsq, r2, lsizeq, r3), m8, m1, m4, m9
136 RET
137
138 cglobal simple_idct8_add, 3, 4, 16, 32, pixels, lsize, block
139     IDCT_FN    "", 11, pw_32, 20
140     lea r2, [3*lsizeq]
141     %if cpuflag(sse4)
142         lea r3, [pixelsq + r2]
143         LOAD_ZXBW_8 m3, m5, m6, m7, m12, m13, m14, m15, PASS8ROWS(pixelsq, r3, lsizeq, r2)
144         paddsw m8, m3
145         paddsw m0, m5
146         paddsw m1, m6
147         paddsw m2, m7
148         paddsw m4, m12
149         paddsw m11, m13
150         paddsw m9, m14
151         paddsw m10, m15
152     %else
153         pxor m12, m12
154         LOAD_ZXBW_4 m3, m5, m6, m7, PASS4ROWS(pixelsq, lsizeq, r2), m12
155         paddsw m8, m3
156         paddsw m0, m5
157         paddsw m1, m6
158         paddsw m2, m7
159         lea r3, [pixelsq + 4*lsizeq]
160         LOAD_ZXBW_4 m3, m5, m6, m7, PASS4ROWS(r3, lsizeq, r2), m12
161         paddsw m4, m3
162         paddsw m11, m5
163         paddsw m9, m6
164         paddsw m10, m7
165         lea r3, [pixelsq + r2]
166     %endif
167     packuswb  m8, m0
168     packuswb  m1, m2
169     packuswb  m4, m11
170     packuswb  m9, m10
171     STORE_HI_LO PASS8ROWS(pixelsq, r3, lsizeq, r2), m8, m1, m4, m9
172 RET
173
174 define_constants _hi
175
176 cglobal simple_idct10, 1, 1, 16, block
177     IDCT_FN    "", 12, "", 19, "store"
178     RET
179
180 cglobal simple_idct10_put, 3, 3, 16, pixels, lsize, block
181     IDCT_FN    "", 12, "", 19, "put", 0, pw_1023
182     RET
183
184 cglobal simple_idct12, 1, 1, 16, block
185     ; coeffs are already 15bits, adding the offset would cause
186     ; overflow in the input
187     IDCT_FN    "", 15, pw_2, 16, "store"
188     RET
189
190 cglobal simple_idct12_put, 3, 3, 16, pixels, lsize, block
191     ; range isn't known, so the C simple_idct range is used
192     ; Also, using a bias on input overflows, so use the bias
193     ; on output of the first butterfly instead
194     IDCT_FN    "", 15, pw_2, 16, "put", 0, pw_4095
195     RET
196 %endmacro
197
198 INIT_XMM sse2
199 idct_fn
200 %if HAVE_AVX_EXTERNAL
201 INIT_XMM avx
202 idct_fn
203 %endif
204
205 %endif