]> git.sesse.net Git - ffmpeg/blob - libavcodec/x86/hevc_idct.asm
Merge commit 'eac77fcd56fc2a3391f0d86faf54302afb368ff7'
[ffmpeg] / libavcodec / x86 / hevc_idct.asm
1 ; /*
2 ; * Provide SSE & MMX idct functions for HEVC decoding
3 ; * Copyright (c) 2014 Pierre-Edouard LEPERE
4 ; *
5 ; * This file is part of FFmpeg.
6 ; *
7 ; * FFmpeg 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 ; * FFmpeg 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 FFmpeg; if not, write to the Free Software
19 ; * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 ; */
21 %include "libavutil/x86/x86util.asm"
22
23 SECTION_RODATA 32
24 max_pixels_10:          times 16  dw ((1 << 10)-1)
25 dc_add_10:              times 4 dd ((1 << 14-10) + 1)
26
27
28 SECTION_TEXT 32
29
30 ;the idct_dc_add macros and functions were largely inspired by x264 project's code in the h264_idct.asm file
31
32 %macro DC_ADD_INIT 2
33     add              %1w, ((1 << 14-8) + 1)
34     sar              %1w, (15-8)
35     movd              m0, %1d
36     lea               %1, [%2*3]
37     SPLATW            m0, m0, 0
38     pxor              m1, m1
39     psubw             m1, m0
40     packuswb          m0, m0
41     packuswb          m1, m1
42 %endmacro
43
44 %macro DC_ADD_INIT_AVX2 2
45     add              %1w, ((1 << 14-8) + 1)
46     sar              %1w, (15-8)
47     movd             xm0, %1d
48     vpbroadcastw      m0, xm0    ;SPLATW
49     lea               %1, [%2*3]
50     pxor              m1, m1
51     psubw             m1, m0
52     packuswb          m0, m0
53     packuswb          m1, m1
54 %endmacro
55
56 %macro DC_ADD_OP 4
57     %1                m2, [%2     ]
58     %1                m3, [%2+%3  ]
59     %1                m4, [%2+%3*2]
60     %1                m5, [%2+%4  ]
61     paddusb           m2, m0
62     paddusb           m3, m0
63     paddusb           m4, m0
64     paddusb           m5, m0
65     psubusb           m2, m1
66     psubusb           m3, m1
67     psubusb           m4, m1
68     psubusb           m5, m1
69     %1         [%2     ], m2
70     %1         [%2+%3  ], m3
71     %1         [%2+%3*2], m4
72     %1         [%2+%4  ], m5
73 %endmacro
74
75 INIT_MMX mmxext
76 ; void ff_hevc_idct_dc_add_8_mmxext(uint8_t *dst, int16_t *coeffs, ptrdiff_t stride)
77 %if ARCH_X86_64
78 cglobal hevc_idct4_dc_add_8, 3, 4, 0
79     movsx             r3, word [r1]
80     DC_ADD_INIT       r3, r2
81     DC_ADD_OP       movh, r0, r2, r3
82     RET
83
84 ; void ff_hevc_idct8_dc_add_8_mmxext(uint8_t *dst, int16_t *coeffs, ptrdiff_t stride)
85 cglobal hevc_idct8_dc_add_8, 3, 4, 0
86     movsx             r3, word [r1]
87     DC_ADD_INIT       r3, r2
88     DC_ADD_OP       mova, r0, r2, r3
89     lea               r0, [r0+r2*4]
90     DC_ADD_OP       mova, r0, r2, r3
91     RET
92 %else
93 ; void ff_hevc_idct_dc_add_8_mmxext(uint8_t *dst, int16_t *coeffs, ptrdiff_t stride)
94 cglobal hevc_idct4_dc_add_8, 2, 3, 0
95     movsx             r2, word [r1]
96     mov               r1, r2m
97     DC_ADD_INIT       r2, r1
98     DC_ADD_OP       movh, r0, r1, r2
99     RET
100
101 ; void ff_hevc_idct8_dc_add_8_mmxext(uint8_t *dst, int16_t *coeffs, ptrdiff_t stride)
102 cglobal hevc_idct8_dc_add_8, 2, 3, 0
103     movsx             r2, word [r1]
104     mov               r1, r2m
105     DC_ADD_INIT       r2, r1
106     DC_ADD_OP       mova, r0, r1, r2
107     lea               r0, [r0+r1*4]
108     DC_ADD_OP       mova, r0, r1, r2
109     RET
110 %endif
111
112
113 INIT_XMM sse2
114 ; void ff_hevc_idct16_dc_add_8_sse2(uint8_t *dst, int16_t *coeffs, ptrdiff_t stride)
115 cglobal hevc_idct16_dc_add_8, 3, 4, 6
116     movsx             r3, word [r1]
117     DC_ADD_INIT       r3, r2
118     DC_ADD_OP       mova, r0, r2, r3
119     lea               r0, [r0+r2*4]
120     DC_ADD_OP       mova, r0, r2, r3
121     lea               r0, [r0+r2*4]
122     DC_ADD_OP       mova, r0, r2, r3
123     lea               r0, [r0+r2*4]
124     DC_ADD_OP       mova, r0, r2, r3
125     RET
126
127 %if HAVE_AVX2_EXTERNAL
128 INIT_YMM avx2
129 ; void ff_hevc_idct32_dc_add_8_avx2(uint8_t *dst, int16_t *coeffs, ptrdiff_t stride)
130 cglobal hevc_idct32_dc_add_8, 3, 4, 6
131     movsx             r3, word [r1]
132     DC_ADD_INIT_AVX2  r3, r2
133     DC_ADD_OP       mova, r0, r2, r3,
134  %rep 7
135     lea               r0, [r0+r2*4]
136     DC_ADD_OP       mova, r0, r2, r3
137 %endrep
138     RET
139 %endif ;HAVE_AVX2_EXTERNAL
140 ;-----------------------------------------------------------------------------
141 ; void ff_hevc_idct_dc_add_10(pixel *dst, int16_t *block, int stride)
142 ;-----------------------------------------------------------------------------
143 %macro IDCT_DC_ADD_OP_10 3
144     pxor              m5, m5
145 %if avx_enabled
146     paddw             m1, m0, [%1+0   ]
147     paddw             m2, m0, [%1+%2  ]
148     paddw             m3, m0, [%1+%2*2]
149     paddw             m4, m0, [%1+%3  ]
150 %else
151     mova              m1, [%1+0   ]
152     mova              m2, [%1+%2  ]
153     mova              m3, [%1+%2*2]
154     mova              m4, [%1+%3  ]
155     paddw             m1, m0
156     paddw             m2, m0
157     paddw             m3, m0
158     paddw             m4, m0
159 %endif
160     CLIPW             m1, m5, m6
161     CLIPW             m2, m5, m6
162     CLIPW             m3, m5, m6
163     CLIPW             m4, m5, m6
164     mova       [%1+0   ], m1
165     mova       [%1+%2  ], m2
166     mova       [%1+%2*2], m3
167     mova       [%1+%3  ], m4
168 %endmacro
169
170 INIT_MMX mmxext
171 cglobal hevc_idct4_dc_add_10,3,3
172     mov              r1w, [r1]
173     add              r1w, ((1 << 4) + 1)
174     sar              r1w, 5
175     movd              m0, r1d
176     lea               r1, [r2*3]
177     SPLATW            m0, m0, 0
178     mova              m6, [max_pixels_10]
179     IDCT_DC_ADD_OP_10 r0, r2, r1
180     RET
181
182 ;-----------------------------------------------------------------------------
183 ; void ff_hevc_idct8_dc_add_10(pixel *dst, int16_t *block, int stride)
184 ;-----------------------------------------------------------------------------
185 %macro IDCT8_DC_ADD 0
186 cglobal hevc_idct8_dc_add_10,3,4,7
187     mov              r1w, [r1]
188     add              r1w, ((1 << 4) + 1)
189     sar              r1w, 5
190     movd              m0, r1d
191     lea               r1, [r2*3]
192     SPLATW            m0, m0, 0
193     mova              m6, [max_pixels_10]
194     IDCT_DC_ADD_OP_10 r0, r2, r1
195     lea               r0, [r0+r2*4]
196     IDCT_DC_ADD_OP_10 r0, r2, r1
197     RET
198 %endmacro
199
200 INIT_XMM sse2
201 IDCT8_DC_ADD
202 %if HAVE_AVX_EXTERNAL
203 INIT_XMM avx
204 IDCT8_DC_ADD
205 %endif
206
207 %if HAVE_AVX2_EXTERNAL
208 INIT_YMM avx2
209 cglobal hevc_idct16_dc_add_10,3,4,7
210     mov              r1w, [r1]
211     add              r1w, ((1 << 4) + 1)
212     sar              r1w, 5
213     movd             xm0, r1d
214     lea               r1, [r2*3]
215     vpbroadcastw      m0, xm0    ;SPLATW
216     mova              m6, [max_pixels_10]
217     IDCT_DC_ADD_OP_10 r0, r2, r1
218     lea               r0, [r0+r2*4]
219     IDCT_DC_ADD_OP_10 r0, r2, r1
220     lea               r0, [r0+r2*4]
221     IDCT_DC_ADD_OP_10 r0, r2, r1
222     lea               r0, [r0+r2*4]
223     IDCT_DC_ADD_OP_10 r0, r2, r1
224     RET
225 %endif ;HAVE_AVX_EXTERNAL