8 #define INLINE __inline
9 #define PACKED __attribute__((packed))
11 #elif defined(__WATCOMC__)
12 #define INLINE __inline
20 #define BSWAP16(x) ((((x) >> 8) & 0xff) | (((x) & 0xff) << 8))
22 ((((x) >> 24) & 0xff) | \
23 (((x) >> 8) & 0xff00) | \
24 (((x) << 8) & 0xff0000) | \
27 #if defined(__i386__) || defined(__x86_64__) || defined(__386__) || defined(MSDOS)
28 /* fast conversion of double -> 32bit int
30 * - http://chrishecker.com/images/f/fb/Gdmfp.pdf
31 * - http://stereopsis.com/FPU.html#convert
33 static INLINE int32_t cround64(double val)
35 val += 6755399441055744.0;
36 return *(int32_t*)&val;
39 #define cround64(x) ((int32_t)(x))
42 static INLINE float rsqrt(float x)
44 float xhalf = x * 0.5f;
45 int32_t i = *(int32_t*)&x;
46 i = 0x5f3759df - (i >> 1);
48 x = x * (1.5f - xhalf * x * x);
52 extern uint32_t perf_start_count, perf_interval_count;
55 void memset16(void *dest, uint16_t val, int count);
56 #pragma aux memset16 = \
59 "jz memset16_dwords" \
72 void memcpy64(void *dest, void *src, int count);
73 #pragma aux memcpy64 = \
85 #define memcpy64(dest, src, count) memcpy(dest, src, (count) << 3)
88 void perf_start(void);
89 #pragma aux perf_start = \
93 "mov [perf_start_count], eax" \
94 modify[eax ebx ecx edx];
97 #pragma aux perf_end = \
101 "sub eax, [perf_start_count]" \
102 "mov [perf_interval_count], eax" \
103 modify [eax ebx ecx edx];
105 void debug_break(void);
106 #pragma aux debug_break = "int 3";
109 #pragma aux halt = "hlt";
113 #if defined(__i386__) || defined(__x86_64__)
114 #define memset16(dest, val, count) \
116 uint32_t dummy1, dummy2; \
119 "test $1, %%ecx\n\t" \
124 "shr $1, %%ecx\n\t" \
126 "shl $16, %%eax\n\t" \
130 : "=D"(dummy1), "=c"(dummy2) \
131 : "0"(dest), "a"((uint16_t)(val)), "1"(count) \
132 : "flags", "memory"); \
135 static void INLINE memset16(void *dest, uint16_t val, int count)
137 uint16_t *ptr = dest;
138 while(count--) *ptr++ = val;
143 #define memcpy64(dest, src, count) asm volatile ( \
145 "movq (%1), %%mm0\n\t" \
146 "movq %%mm0, (%0)\n\t" \
152 :: "r"(dest), "r"(src), "r"(count) \
155 #define memcpy64(dest, src, count) memcpy(dest, src, (count) << 3)
158 #define perf_start() asm volatile ( \
159 "xor %%eax, %%eax\n" \
163 : "=m"(perf_start_count) \
164 :: "%eax", "%ebx", "%ecx", "%edx")
166 #define perf_end() asm volatile ( \
167 "xor %%eax, %%eax\n" \
172 : "=m"(perf_interval_count) \
173 : "m"(perf_start_count) \
174 : "%eax", "%ebx", "%ecx", "%edx")
176 #define debug_break() \
177 asm volatile("int $3")
184 static void __inline memset16(void *dest, uint16_t val, int count)
205 #define perf_start() \
211 mov [perf_start_count], eax \
221 sub eax, [perf_start_count] \
222 mov [perf_interval_count], eax \
226 #define debug_break() \
231 static unsigned int __inline get_cs(void)
243 unsigned int get_cs(void);
244 #define get_cpl() ((int)(get_cs() & 3))
246 void get_msr(uint32_t msr, uint32_t *low, uint32_t *high);
247 void set_msr(uint32_t msr, uint32_t low, uint32_t high);
250 /* Non-failing versions of malloc/calloc/realloc. They never return 0, they call
251 * demo_abort on failure. Use the macros, don't call the *_impl functions.
253 #define malloc_nf(sz) malloc_nf_impl(sz, __FILE__, __LINE__)
254 void *malloc_nf_impl(size_t sz, const char *file, int line);
255 #define calloc_nf(n, sz) calloc_nf_impl(n, sz, __FILE__, __LINE__)
256 void *calloc_nf_impl(size_t num, size_t sz, const char *file, int line);
257 #define realloc_nf(p, sz) realloc_nf_impl(p, sz, __FILE__, __LINE__)
258 void *realloc_nf_impl(void *p, size_t sz, const char *file, int line);