b305d78697816a40303d98f012219d92750a2ddd
[dosdemo] / 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 void perf_start(void);
34 #pragma aux perf_start = \
35         "xor eax, eax" \
36         "cpuid" \
37         "rdtsc" \
38         "mov [perf_start_count], eax" \
39         modify[eax ebx ecx edx];
40
41 void perf_end(void);
42 #pragma aux perf_end = \
43         "xor eax, eax" \
44         "cpuid" \
45         "rdtsc" \
46         "sub eax, [perf_start_count]" \
47         "mov [perf_interval_count], eax" \
48         modify [eax ebx ecx edx];
49
50 void debug_break(void);
51 #pragma aux debug_break = "int 3";
52
53 void halt(void);
54 #pragma aux halt = "hlt";
55
56 void memset16(void *ptr, int val, int count);
57 #pragma aux memset16 = \
58         "rep stosw" \
59         parm[edi][eax][ecx];
60 #endif
61
62 #ifdef __GNUC__
63 #define perf_start()  asm volatile ( \
64         "xor %%eax, %%eax\n" \
65         "cpuid\n" \
66         "rdtsc\n" \
67         "mov %%eax, %0\n" \
68         : "=m"(perf_start_count) \
69         :: "%eax", "%ebx", "%ecx", "%edx")
70
71 #define perf_end() asm volatile ( \
72         "xor %%eax, %%eax\n" \
73         "cpuid\n" \
74         "rdtsc\n" \
75         "sub %1, %%eax\n" \
76         "mov %%eax, %0\n" \
77         : "=m"(perf_interval_count) \
78         : "m"(perf_start_count) \
79         : "%eax", "%ebx", "%ecx", "%edx")
80
81 #define debug_break() \
82         asm volatile ("int $3")
83
84 #define halt() \
85         asm volatile("hlt")
86
87 #define memset16(ptr, val, count) asm volatile ( \
88         "rep stosw\n\t" \
89         :: "D"(ptr), "a"(val), "c"(count))
90 #endif
91
92 #ifdef _MSC_VER
93 #define perf_start() \
94         do { \
95                 __asm { \
96                         xor eax, eax \
97                         cpuid \
98                         rdtsc \
99                         mov [perf_start_count], eax \
100                 } \
101         } while(0)
102
103 #define perf_end() \
104         do { \
105                 __asm { \
106                         xor eax, eax \
107                         cpuid \
108                         rdtsc \
109                         sub eax, [perf_start_count] \
110                         mov [perf_interval_count], eax \
111                 } \
112         } while(0)
113
114 #define debug_break() \
115         do { \
116                 __asm { int 3 } \
117         } while(0)
118
119 #define memset16(ptr, val, count) \
120         do { \
121                 __asm { \
122                         mov edi, ptr \
123                         mov ecx, count \
124                         mov eax, val \
125                         rep stosw \
126                 } \
127         } while(0)
128 #endif
129
130 #endif  /* UTIL_H_ */