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) asm volatile ( \
123 "shl $16, %%eax\n\t" \
127 :: "D"(dest), "a"((uint16_t)(val)), "c"(count) \
130 static void INLINE memset16(void *dest, uint16_t val, int count)
132 uint16_t *ptr = dest;
133 while(count--) *ptr++ = val;
138 #define memcpy64(dest, src, count) asm volatile ( \
140 "movq (%1), %%mm0\n\t" \
141 "movq %%mm0, (%0)\n\t" \
147 :: "r"(dest), "r"(src), "r"(count) \
150 #define memcpy64(dest, src, count) memcpy(dest, src, (count) << 3)
153 #define perf_start() asm volatile ( \
154 "xor %%eax, %%eax\n" \
158 : "=m"(perf_start_count) \
159 :: "%eax", "%ebx", "%ecx", "%edx")
161 #define perf_end() asm volatile ( \
162 "xor %%eax, %%eax\n" \
167 : "=m"(perf_interval_count) \
168 : "m"(perf_start_count) \
169 : "%eax", "%ebx", "%ecx", "%edx")
171 #define debug_break() \
172 asm volatile("int $3")
179 static void __inline memset16(void *dest, uint16_t val, int count)
200 #define perf_start() \
206 mov [perf_start_count], eax \
216 sub eax, [perf_start_count] \
217 mov [perf_interval_count], eax \
221 #define debug_break() \
226 static unsigned int __inline get_cs(void)
238 unsigned int get_cs(void);
239 #define get_cpl() ((int)(get_cs() & 3))
241 void get_msr(uint32_t msr, uint32_t *low, uint32_t *high);
242 void set_msr(uint32_t msr, uint32_t low, uint32_t high);
245 /* Non-failing versions of malloc/calloc/realloc. They never return 0, they call
246 * demo_abort on failure. Use the macros, don't call the *_impl functions.
248 #define malloc_nf(sz) malloc_nf_impl(sz, __FILE__, __LINE__)
249 void *malloc_nf_impl(size_t sz, const char *file, int line);
250 #define calloc_nf(n, sz) calloc_nf_impl(n, sz, __FILE__, __LINE__)
251 void *calloc_nf_impl(size_t num, size_t sz, const char *file, int line);
252 #define realloc_nf(p, sz) realloc_nf_impl(p, sz, __FILE__, __LINE__)
253 void *realloc_nf_impl(void *p, size_t sz, const char *file, int line);