avcodec/hevc: new idct + asm
[ffmpeg.git] / 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
24 max_pixels_10:          times 8  dw ((1 << 10)-1)
25 dc_add_10:              times 4 dd ((1 << 14-10) + 1)
26
27
28 SECTION .text
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, %1
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_OP 4
45     %1                m2, [%2     ]
46     %1                m3, [%2+%3  ]
47     %1                m4, [%2+%3*2]
48     %1                m5, [%2+%4  ]
49     paddusb           m2, m0
50     paddusb           m3, m0
51     paddusb           m4, m0
52     paddusb           m5, m0
53     psubusb           m2, m1
54     psubusb           m3, m1
55     psubusb           m4, m1
56     psubusb           m5, m1
57     %1         [%2     ], m2
58     %1         [%2+%3  ], m3
59     %1         [%2+%3*2], m4
60     %1         [%2+%4  ], m5
61 %endmacro
62
63 INIT_MMX mmxext
64 ; void ff_hevc_idct_dc_add_8_mmxext(uint8_t *dst, int16_t *coeffs, ptrdiff_t stride)
65 %if ARCH_X86_64
66 cglobal hevc_idct4_dc_add_8, 3, 4, 0
67     movsx             r3, word [r1]
68     DC_ADD_INIT       r3, r2
69     DC_ADD_OP       movh, r0, r2, r3
70     RET
71
72 ; void ff_hevc_idct8_dc_add_8_mmxext(uint8_t *dst, int16_t *coeffs, ptrdiff_t stride)
73 cglobal hevc_idct8_dc_add_8, 3, 4, 0
74     movsx             r3, word [r1]
75     DC_ADD_INIT       r3, r2
76     DC_ADD_OP       mova, r0, r2, r3
77     lea               r0, [r0+r2*4]
78     DC_ADD_OP       mova, r0, r2, r3
79     RET
80 %else
81 ; void ff_hevc_idct_dc_add_8_mmxext(uint8_t *dst, int16_t *coeffs, ptrdiff_t stride)
82 cglobal hevc_idct4_dc_add_8, 2, 3, 0
83     movsx             r2, word [r1]
84     mov               r1, r2m
85     DC_ADD_INIT       r2, r1
86     DC_ADD_OP       movh, r0, r1, r2
87     RET
88
89 ; void ff_hevc_idct8_dc_add_8_mmxext(uint8_t *dst, int16_t *coeffs, ptrdiff_t stride)
90 cglobal hevc_idct8_dc_add_8, 2, 3, 0
91     movsx             r2, word [r1]
92     mov               r1, r2m
93     DC_ADD_INIT       r2, r1
94     DC_ADD_OP       mova, r0, r1, r2
95     lea               r0, [r0+r1*4]
96     DC_ADD_OP       mova, r0, r1, r2
97     RET
98 %endif
99
100
101 INIT_XMM sse2
102 ; void ff_hevc_idct16_dc_add_8_mmxext(uint8_t *dst, int16_t *coeffs, ptrdiff_t stride)
103 cglobal hevc_idct16_dc_add_8, 3, 4, 0
104     movsx             r3, word [r1]
105     DC_ADD_INIT       r3, r2
106     DC_ADD_OP       mova, r0, r2, r3
107     lea               r0, [r0+r2*4]
108     DC_ADD_OP       mova, r0, r2, r3
109     lea               r0, [r0+r2*4]
110     DC_ADD_OP       mova, r0, r2, r3
111     lea               r0, [r0+r2*4]
112     DC_ADD_OP       mova, r0, r2, r3
113     RET
114
115 ;-----------------------------------------------------------------------------
116 ; void ff_hevc_idct_dc_add_10(pixel *dst, int16_t *block, int stride)
117 ;-----------------------------------------------------------------------------
118 %macro IDCT_DC_ADD_OP_10 3
119     pxor              m5, m5
120 %if avx_enabled
121     paddw             m1, m0, [%1+0   ]
122     paddw             m2, m0, [%1+%2  ]
123     paddw             m3, m0, [%1+%2*2]
124     paddw             m4, m0, [%1+%3  ]
125 %else
126     mova              m1, [%1+0   ]
127     mova              m2, [%1+%2  ]
128     mova              m3, [%1+%2*2]
129     mova              m4, [%1+%3  ]
130     paddw             m1, m0
131     paddw             m2, m0
132     paddw             m3, m0
133     paddw             m4, m0
134 %endif
135     CLIPW             m1, m5, m6
136     CLIPW             m2, m5, m6
137     CLIPW             m3, m5, m6
138     CLIPW             m4, m5, m6
139     mova       [%1+0   ], m1
140     mova       [%1+%2  ], m2
141     mova       [%1+%2*2], m3
142     mova       [%1+%3  ], m4
143 %endmacro
144
145 INIT_MMX mmxext
146 cglobal hevc_idct4_dc_add_10,3,3
147     mov              r1w, [r1]
148     add              r1w, ((1 << 4) + 1)
149     sar              r1w, 5
150     movd              m0, r1d
151     lea               r1, [r2*3]
152     SPLATW            m0, m0, 0
153     mova              m6, [max_pixels_10]
154     IDCT_DC_ADD_OP_10 r0, r2, r1
155     RET
156
157 ;-----------------------------------------------------------------------------
158 ; void ff_hevc_idct8_dc_add_10(pixel *dst, int16_t *block, int stride)
159 ;-----------------------------------------------------------------------------
160 %macro IDCT8_DC_ADD 0
161 cglobal hevc_idct8_dc_add_10,3,4,7
162     mov              r1w, [r1]
163     add              r1w, ((1 << 4) + 1)
164     sar              r1w, 5
165     movd              m0, r1d
166     lea               r1, [r2*3]
167     SPLATW            m0, m0, 0
168     mova              m6, [max_pixels_10]
169     IDCT_DC_ADD_OP_10 r0, r2, r1
170     lea               r0, [r0+r2*4]
171     IDCT_DC_ADD_OP_10 r0, r2, r1
172     RET
173 %endmacro
174
175 INIT_XMM sse2
176 IDCT8_DC_ADD
177 %if HAVE_AVX_EXTERNAL
178 INIT_XMM avx
179 IDCT8_DC_ADD
180 %endif