initial import
[dosrtxon] / 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
9 #elif defined(__WATCOMC__)
10 #define INLINE __inline
11
12 #else
13 #define INLINE
14 #endif
15
16 /* fast conversion of double -> 32bit int
17  * for details see:
18  *  - http://chrishecker.com/images/f/fb/Gdmfp.pdf
19  *  - http://stereopsis.com/FPU.html#convert
20  */
21 static INLINE int32_t cround64(double val)
22 {
23         val += 6755399441055744.0;
24         return *(int32_t*)&val;
25 }
26
27 extern uint32_t perf_start_count, perf_interval_count;
28
29 #ifdef __WATCOMC__
30 void perf_start(void);
31 #pragma aux perf_start = \
32         "xor eax, eax" \
33         "cpuid" \
34         "rdtsc" \
35         "mov [perf_start_count], eax" \
36         modify[eax ebx ecx edx];
37
38 void perf_end(void);
39 #pragma aux perf_end = \
40         "xor eax, eax" \
41         "cpuid" \
42         "rdtsc" \
43         "sub eax, [perf_start_count]" \
44         "mov [perf_interval_count], eax" \
45         modify [eax ebx ecx edx];
46
47 void debug_break(void);
48 #pragma aux debug_break = "int 3";
49 #endif
50
51 #ifdef __GNUC__
52 #define perf_start()  asm volatile ( \
53         "xor %%eax, %%eax\n" \
54         "cpuid\n" \
55         "rdtsc\n" \
56         "mov %%eax, %0\n" \
57         : "=m"(perf_start_count) \
58         :: "%eax", "%ebx", "%ecx", "%edx")
59
60 #define perf_end() asm volatile ( \
61         "xor %%eax, %%eax\n" \
62         "cpuid\n" \
63         "rdtsc\n" \
64         "sub %1, %%eax\n" \
65         "mov %%eax, %0\n" \
66         : "=m"(perf_interval_count) \
67         : "m"(perf_start_count) \
68         : "%eax", "%ebx", "%ecx", "%edx")
69
70 #define debug_break() \
71         asm volatile ("int $3")
72 #endif
73
74 #ifdef _MSC_VER
75 #define perf_start() \
76         do { \
77                 __asm { \
78                         xor eax, eax \
79                         cpuid \
80                         rdtsc \
81                         mov [perf_start_count], eax \
82                 } \
83         } while(0)
84
85 #define perf_end() \
86         do { \
87                 __asm { \
88                         xor eax, eax \
89                         cpuid \
90                         rdtsc \
91                         sub eax, [perf_start_count] \
92                         mov [perf_interval_count], eax \
93                 } \
94         } while(0)
95
96 #define debug_break() \
97         do { \
98                 __asm { int 3 } \
99         } while(0)
100 #endif
101
102 #endif  /* UTIL_H_ */