Revert "Rollback to previous package. evas_1.0.0.001+svn.62695slp2+build31"
[framework/uifw/evas.git] / src / lib / engines / common / evas_cpu.c
1 #include "evas_common.h"
2 #if defined BUILD_MMX || defined BUILD_SSE
3 #include "evas_mmx.h"
4 #endif
5
6 #if defined BUILD_SSE3
7 #include <immintrin.h>
8 #endif
9
10 #if defined (HAVE_STRUCT_SIGACTION) && defined (HAVE_SIGLONGJMP)
11 #include <signal.h>
12 #include <setjmp.h>
13 #include <errno.h>
14
15 static sigjmp_buf detect_buf;
16 #endif
17
18 static int cpu_feature_mask = 0;
19
20 #if defined (HAVE_STRUCT_SIGACTION) && defined (HAVE_SIGLONGJMP)
21 static void evas_common_cpu_catch_ill(int sig);
22 static void evas_common_cpu_catch_segv(int sig);
23
24 static void
25 evas_common_cpu_catch_ill(int sig __UNUSED__)
26 {
27    siglongjmp(detect_buf, 1);
28 }
29
30 static void
31 evas_common_cpu_catch_segv(int sig __UNUSED__)
32 {
33    siglongjmp(detect_buf, 1);
34 }
35 #endif
36
37 void
38 evas_common_cpu_mmx_test(void)
39 {
40 #ifdef BUILD_MMX
41    pxor_r2r(mm4, mm4);
42 #endif
43 }
44
45 void
46 evas_common_cpu_mmx2_test(void)
47 {
48 #ifdef BUILD_MMX
49    char data[16];
50
51    data[0] = 0;
52    mmx_r2m(movntq, mm0, data);
53    data[0] = 0;
54 #endif
55 }
56
57 void
58 evas_common_cpu_sse_test(void)
59 {
60 #ifdef BUILD_SSE
61    int blah[16];
62
63    movntq_r2m(mm0, blah);
64 #endif
65 }
66
67 void evas_common_op_sse3_test(void);
68
69 void
70 evas_common_cpu_sse3_test(void)
71 {
72 #ifdef BUILD_SSE3
73    evas_common_op_sse3_test();
74 #endif
75 }
76
77 void
78 evas_common_cpu_altivec_test(void)
79 {
80 #ifdef __POWERPC__
81 #ifdef __VEC__
82    vector unsigned int zero;
83
84    zero = vec_splat_u32(0);
85 #endif /* __VEC__ */
86 #endif /* __POWERPC__ */
87 }
88
89 void
90 evas_common_cpu_neon_test(void)
91 {
92 //#if defined(__ARM_ARCH__) && (__ARM_ARCH__ >= 70)
93 #ifdef BUILD_NEON
94    asm volatile (
95                 ".fpu neon           \n\t"
96                  "vqadd.u8 d0, d1, d0\n"
97                  : /* Out */
98                  : /* In */
99                  : /* Clobbered */
100                  "d0", "d1"
101                  );
102 #endif
103 //#endif
104 }
105
106 void
107 evas_common_cpu_vis_test(void)
108 {
109 #ifdef __SPARC__
110 #endif /* __SPARC__ */
111 }
112
113 int
114 evas_common_cpu_feature_test(void (*feature)(void))
115 {
116 #if defined (HAVE_STRUCT_SIGACTION) && defined (HAVE_SIGLONGJMP)
117    int enabled = 1;
118    struct sigaction act, oact, oact2;
119
120    act.sa_handler = evas_common_cpu_catch_ill;
121    act.sa_flags = SA_RESTART;
122    sigemptyset(&act.sa_mask);
123    sigaction(SIGILL, &act, &oact);
124
125    act.sa_handler = evas_common_cpu_catch_segv;
126    act.sa_flags = SA_RESTART;
127    sigemptyset(&act.sa_mask);
128    sigaction(SIGSEGV, &act, &oact2);
129
130    if (sigsetjmp(detect_buf, 1))
131      {
132         sigaction(SIGILL, &oact, NULL);
133         sigaction(SIGSEGV, &oact2, NULL);
134         return 0;
135      }
136
137    feature();
138
139    sigaction(SIGILL, &oact, NULL);
140    sigaction(SIGSEGV, &oact2, NULL);
141    return enabled;
142 #else
143    return 0;
144 #endif
145 }
146
147 EAPI void
148 evas_common_cpu_init(void)
149 {
150    static int called = 0;
151
152    if (called) return;
153    called = 1;
154 #ifdef BUILD_MMX
155    cpu_feature_mask |= CPU_FEATURE_MMX *
156      evas_common_cpu_feature_test(evas_common_cpu_mmx_test);
157    evas_common_cpu_end_opt();
158    if (getenv("EVAS_CPU_NO_MMX"))
159      cpu_feature_mask &= ~CPU_FEATURE_MMX;
160    cpu_feature_mask |= CPU_FEATURE_MMX2 *
161      evas_common_cpu_feature_test(evas_common_cpu_mmx2_test);
162    evas_common_cpu_end_opt();
163    if (getenv("EVAS_CPU_NO_MMX2"))
164      cpu_feature_mask &= ~CPU_FEATURE_MMX2;
165 #ifdef BUILD_SSE
166    cpu_feature_mask |= CPU_FEATURE_SSE *
167      evas_common_cpu_feature_test(evas_common_cpu_sse_test);
168    evas_common_cpu_end_opt();
169    if (getenv("EVAS_CPU_NO_SSE"))
170      cpu_feature_mask &= ~CPU_FEATURE_SSE;
171 #ifdef BUILD_SSE3
172    cpu_feature_mask |= CPU_FEATURE_SSE3 *
173      evas_common_cpu_feature_test(evas_common_cpu_sse3_test); 
174    evas_common_cpu_end_opt();
175    if (getenv("EVAS_CPU_NO_SSE3"))
176      cpu_feature_mask &= ~CPU_FEATURE_SSE3; 
177 #endif /* BUILD_SSE3 */
178 #endif /* BUILD_SSE */
179 #endif /* BUILD_MMX */
180 #ifdef __POWERPC__
181 #ifdef __VEC__
182    cpu_feature_mask |= CPU_FEATURE_ALTIVEC *
183      evas_common_cpu_feature_test(evas_common_cpu_altivec_test);
184    evas_common_cpu_end_opt();
185    if (getenv("EVAS_CPU_NO_ALTIVEC"))
186      cpu_feature_mask &= ~CPU_FEATURE_ALTIVEC;
187 #endif /* __VEC__ */
188 #endif /* __POWERPC__ */
189 #ifdef __SPARC__
190    cpu_feature_mask |= CPU_FEATURE_VIS *
191      evas_common_cpu_feature_test(evas_common_cpu_vis_test);
192    evas_common_cpu_end_opt();
193    if (getenv("EVAS_CPU_NO_VIS"))
194      cpu_feature_mask &= ~CPU_FEATURE_VIS;
195 #endif /* __SPARC__ */
196 #if defined(__ARM_ARCH__)
197 #ifdef BUILD_NEON
198    cpu_feature_mask |= CPU_FEATURE_NEON *
199      evas_common_cpu_feature_test(evas_common_cpu_neon_test);
200    evas_common_cpu_end_opt();
201    if (getenv("EVAS_CPU_NO_NEON"))
202      cpu_feature_mask &= ~CPU_FEATURE_NEON;
203 #endif
204 #endif
205 }
206
207 int
208 evas_common_cpu_has_feature(unsigned int feature)
209 {
210    return (cpu_feature_mask & feature);
211 }
212
213 int
214 evas_common_cpu_have_cpuid(void)
215 {
216    return 0;
217 /*
218 #ifdef BUILD_MMX
219    unsigned int have_cpu_id;
220
221    have_cpu_id = 0;
222    have_cpuid(have_cpu_id);
223    return have_cpu_id;
224 #else
225    return 0;
226 #endif
227  */
228 }
229
230 EAPI void
231 evas_common_cpu_can_do(int *mmx, int *sse, int *sse2)
232 {
233    static int do_mmx = 0, do_sse = 0, do_sse2 = 0, done = 0;
234
235    if (!done)
236      {
237 # ifdef HARD_CODED_P3
238         cpu_feature_mask |= CPU_FEATURE_MMX;
239         cpu_feature_mask |= CPU_FEATURE_SSE;
240 #endif
241 #ifdef HARD_CODED_P2
242         cpu_feature_mask |= CPU_FEATURE_MMX;
243 #endif
244         if (cpu_feature_mask & CPU_FEATURE_MMX) do_mmx = 1;
245         if (cpu_feature_mask & CPU_FEATURE_MMX2) do_sse = 1;
246         if (cpu_feature_mask & CPU_FEATURE_SSE) do_sse = 1;
247      }
248 //   INF("%i %i %i", do_mmx, do_sse, do_sse2);
249    *mmx = do_mmx;
250    *sse = do_sse;
251    *sse2 = do_sse2;
252    done = 1;
253 }
254
255 #ifdef BUILD_MMX
256 EAPI void
257 evas_common_cpu_end_opt(void)
258 {
259    if (cpu_feature_mask &
260        (CPU_FEATURE_MMX | CPU_FEATURE_MMX2))
261      {
262         emms();
263      }
264 }
265 #else
266 EAPI void
267 evas_common_cpu_end_opt(void)
268 {
269 }
270 #endif