]> git.sesse.net Git - x264/blob - common/x86/util.h
Update source file headers
[x264] / common / x86 / util.h
1 /*****************************************************************************
2  * util.h: x86 inline asm
3  *****************************************************************************
4  * Copyright (C) 2008-2010 x264 Project
5  *
6  * Authors: Fiona Glaser <fiona@x264.com>
7  *          Loren Merritt <lorenm@u.washington.edu>
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02111, USA.
22  *
23  * This program is also available under a commercial proprietary license.
24  * For more information, contact us at licensing@x264.com.
25  *****************************************************************************/
26
27 #ifndef X264_X86_UTIL_H
28 #define X264_X86_UTIL_H
29
30 #ifdef __GNUC__
31
32 #ifdef __SSE__
33 #include <xmmintrin.h>
34 #endif
35
36 #define x264_median_mv x264_median_mv_mmxext
37 static ALWAYS_INLINE void x264_median_mv_mmxext( int16_t *dst, int16_t *a, int16_t *b, int16_t *c )
38 {
39     asm(
40         "movd   %1,    %%mm0 \n"
41         "movd   %2,    %%mm1 \n"
42         "movq   %%mm0, %%mm3 \n"
43         "movd   %3,    %%mm2 \n"
44         "pmaxsw %%mm1, %%mm0 \n"
45         "pminsw %%mm3, %%mm1 \n"
46         "pminsw %%mm2, %%mm0 \n"
47         "pmaxsw %%mm1, %%mm0 \n"
48         "movd   %%mm0, %0    \n"
49         :"=m"(*(x264_union32_t*)dst)
50         :"m"(M32( a )), "m"(M32( b )), "m"(M32( c ))
51     );
52 }
53
54 #define x264_predictor_difference x264_predictor_difference_mmxext
55 static ALWAYS_INLINE int x264_predictor_difference_mmxext( int16_t (*mvc)[2], intptr_t i_mvc )
56 {
57     int sum;
58     static const uint64_t pw_1 = 0x0001000100010001ULL;
59
60     asm(
61         "pxor    %%mm4, %%mm4 \n"
62         "test    $1, %1       \n"
63         "jnz 3f               \n"
64         "movd    -8(%2,%1,4), %%mm0 \n"
65         "movd    -4(%2,%1,4), %%mm3 \n"
66         "psubw   %%mm3, %%mm0 \n"
67         "jmp 2f               \n"
68         "3:                   \n"
69         "dec     %1           \n"
70         "1:                   \n"
71         "movq    -8(%2,%1,4), %%mm0 \n"
72         "psubw   -4(%2,%1,4), %%mm0 \n"
73         "2:                   \n"
74         "sub     $2,    %1    \n"
75         "pxor    %%mm2, %%mm2 \n"
76         "psubw   %%mm0, %%mm2 \n"
77         "pmaxsw  %%mm2, %%mm0 \n"
78         "paddusw %%mm0, %%mm4 \n"
79         "jg 1b                \n"
80         "pmaddwd %4, %%mm4    \n"
81         "pshufw $14, %%mm4, %%mm0 \n"
82         "paddd   %%mm0, %%mm4 \n"
83         "movd    %%mm4, %0    \n"
84         :"=r"(sum), "+r"(i_mvc)
85         :"r"(mvc), "m"(M64( mvc )), "m"(pw_1)
86     );
87     return sum;
88 }
89
90 #define x264_cabac_mvd_sum x264_cabac_mvd_sum_mmxext
91 static ALWAYS_INLINE uint16_t x264_cabac_mvd_sum_mmxext(uint8_t *mvdleft, uint8_t *mvdtop)
92 {
93     static const uint64_t pb_2    = 0x0202020202020202ULL;
94     static const uint64_t pb_32   = 0x2020202020202020ULL;
95     int amvd;
96     asm(
97         "movd         %1, %%mm0 \n"
98         "movd         %2, %%mm1 \n"
99         "paddb     %%mm1, %%mm0 \n"
100         "pxor      %%mm2, %%mm2 \n"
101         "movq      %%mm0, %%mm1 \n"
102         "pcmpgtb      %3, %%mm0 \n"
103         "pcmpgtb      %4, %%mm1 \n"
104         "psubb     %%mm0, %%mm2 \n"
105         "psubb     %%mm1, %%mm2 \n"
106         "movd      %%mm2, %0    \n"
107         :"=r"(amvd)
108         :"m"(M16( mvdleft )),"m"(M16( mvdtop )),
109          "m"(pb_2),"m"(pb_32)
110     );
111     return amvd;
112 }
113
114 #define x264_predictor_roundclip x264_predictor_roundclip_mmxext
115 static void ALWAYS_INLINE x264_predictor_roundclip_mmxext( int16_t (*dst)[2], int16_t (*mvc)[2], int i_mvc, int mv_x_min, int mv_x_max, int mv_y_min, int mv_y_max )
116 {
117     uint32_t mv_min = pack16to32_mask( mv_x_min, mv_y_min );
118     uint32_t mv_max = pack16to32_mask( mv_x_max, mv_y_max );
119     static const uint64_t pw_2 = 0x0002000200020002ULL;
120     intptr_t i = i_mvc;
121     asm(
122         "movd    %2, %%mm5       \n"
123         "movd    %3, %%mm6       \n"
124         "movq    %4, %%mm7       \n"
125         "punpckldq %%mm5, %%mm5  \n"
126         "punpckldq %%mm6, %%mm6  \n"
127         "test $1, %0             \n"
128         "jz 1f                   \n"
129         "movd -4(%6,%0,4), %%mm0 \n"
130         "paddw %%mm7, %%mm0      \n"
131         "psraw $2, %%mm0         \n"
132         "pmaxsw %%mm5, %%mm0     \n"
133         "pminsw %%mm6, %%mm0     \n"
134         "movd %%mm0, -4(%5,%0,4) \n"
135         "dec %0                  \n"
136         "jz 2f                   \n"
137         "1:                      \n"
138         "movq -8(%6,%0,4), %%mm0 \n"
139         "paddw %%mm7, %%mm0      \n"
140         "psraw $2, %%mm0         \n"
141         "pmaxsw %%mm5, %%mm0     \n"
142         "pminsw %%mm6, %%mm0     \n"
143         "movq %%mm0, -8(%5,%0,4) \n"
144         "sub $2, %0              \n"
145         "jnz 1b                  \n"
146         "2:                      \n"
147         :"+r"(i), "=m"(M64( dst ))
148         :"g"(mv_min), "g"(mv_max), "m"(pw_2), "r"(dst), "r"(mvc), "m"(M64( mvc ))
149     );
150 }
151
152 #ifdef __SSE__
153 #undef M128_ZERO
154 #define M128_ZERO ((__m128){0,0,0,0})
155 #define x264_union128_t x264_union128_sse_t
156 typedef union { __m128 i; uint64_t a[2]; uint32_t b[4]; uint16_t c[8]; uint8_t d[16]; } MAY_ALIAS x264_union128_sse_t;
157 #endif
158
159 #endif
160
161 #endif