moving on
[eradicate] / src / util.h
1 #ifndef UTIL_H_
2 #define UTIL_H_
3
4 #include "inttypes.h"
5
6 #ifdef __GNUC__
7 #define INLINE __inline
8 #define PACKED __attribute__((packed))
9
10 #elif defined(__WATCOMC__)
11 #define INLINE __inline
12 #define PACKED
13
14 #else
15 #define INLINE
16 #define PACKED
17 #endif
18
19 /* fast conversion of double -> 32bit int
20  * for details see:
21  *  - http://chrishecker.com/images/f/fb/Gdmfp.pdf
22  *  - http://stereopsis.com/FPU.html#convert
23  */
24 static INLINE int32_t cround64(double val)
25 {
26         val += 6755399441055744.0;
27         return *(int32_t*)&val;
28 }
29
30 extern uint32_t perf_start_count, perf_interval_count;
31
32 #ifdef __WATCOMC__
33 #ifdef USE_MMX
34 void memcpy64(void *dest, void *src, int count);
35 #pragma aux memcpy64 = \
36         "cploop:" \
37         "movq mm0, [edx]" \
38         "movq [ebx], mm0" \
39         "add edx, 8" \
40         "add ebx, 8" \
41         "dec ecx" \
42         "jnz cploop" \
43         "emms" \
44         parm[ebx][edx][ecx] \
45         modify[8087];
46 #else
47 #define memcpy64(dest, src, count)      memcpy(dest, src, (count) << 3)
48 #endif
49
50 void perf_start(void);
51 #pragma aux perf_start = \
52         "xor eax, eax" \
53         "cpuid" \
54         "rdtsc" \
55         "mov [perf_start_count], eax" \
56         modify[eax ebx ecx edx];
57
58 void perf_end(void);
59 #pragma aux perf_end = \
60         "xor eax, eax" \
61         "cpuid" \
62         "rdtsc" \
63         "sub eax, [perf_start_count]" \
64         "mov [perf_interval_count], eax" \
65         modify [eax ebx ecx edx];
66
67 void debug_break(void);
68 #pragma aux debug_break = "int 3";
69 #endif
70
71 #ifdef __GNUC__
72 #ifdef USE_MMX
73 #define memcpy64(dest, src, count) asm volatile ( \
74         "0:\n\t" \
75         "movq (%1), %%mm0\n\t" \
76         "movq %%mm0, (%0)\n\t" \
77         "add $8, %1\n\t" \
78         "add $8, %0\n\t" \
79         "dec %2\n\t" \
80         "jnz 0b\n\t" \
81         "emms\n\t" \
82         :: "r"(dest), "r"(src), "r"(count) \
83         : "%mm0")
84 #else
85 #define memcpy64(dest, src, count)      memcpy(dest, src, (count) << 3)
86 #endif
87
88 #define perf_start()  asm volatile ( \
89         "xor %%eax, %%eax\n" \
90         "cpuid\n" \
91         "rdtsc\n" \
92         "mov %%eax, %0\n" \
93         : "=m"(perf_start_count) \
94         :: "%eax", "%ebx", "%ecx", "%edx")
95
96 #define perf_end() asm volatile ( \
97         "xor %%eax, %%eax\n" \
98         "cpuid\n" \
99         "rdtsc\n" \
100         "sub %1, %%eax\n" \
101         "mov %%eax, %0\n" \
102         : "=m"(perf_interval_count) \
103         : "m"(perf_start_count) \
104         : "%eax", "%ebx", "%ecx", "%edx")
105
106 #define debug_break() \
107         asm volatile ("int $3")
108 #endif
109
110 #ifdef _MSC_VER
111 #define perf_start() \
112         do { \
113                 __asm { \
114                         xor eax, eax \
115                         cpuid \
116                         rdtsc \
117                         mov [perf_start_count], eax \
118                 } \
119         } while(0)
120
121 #define perf_end() \
122         do { \
123                 __asm { \
124                         xor eax, eax \
125                         cpuid \
126                         rdtsc \
127                         sub eax, [perf_start_count] \
128                         mov [perf_interval_count], eax \
129                 } \
130         } while(0)
131
132 #define debug_break() \
133         do { \
134                 __asm { int 3 } \
135         } while(0)
136 #endif
137
138 #endif  /* UTIL_H_ */