243 |
unsigned int next_eip); |
unsigned int next_eip); |
244 |
void raise_exception_err(int exception_index, int error_code); |
void raise_exception_err(int exception_index, int error_code); |
245 |
void raise_exception(int exception_index); |
void raise_exception(int exception_index); |
246 |
|
void helper_divl_EAX_T0(uint32_t eip); |
247 |
|
void helper_idivl_EAX_T0(uint32_t eip); |
248 |
|
void helper_cmpxchg8b(void); |
249 |
void helper_cpuid(void); |
void helper_cpuid(void); |
250 |
|
void helper_rdtsc(void); |
251 |
void helper_lsl(void); |
void helper_lsl(void); |
252 |
void helper_lar(void); |
void helper_lar(void); |
253 |
|
|
|
|
|
254 |
#ifdef USE_X86LDOUBLE |
#ifdef USE_X86LDOUBLE |
255 |
/* use long double functions */ |
/* use long double functions */ |
256 |
#define lrint lrintl |
#define lrint lrintl |
290 |
|
|
291 |
#define MAXTAN 9223372036854775808.0 |
#define MAXTAN 9223372036854775808.0 |
292 |
|
|
293 |
|
#ifdef __arm__ |
294 |
|
/* we have no way to do correct rounding - a FPU emulator is needed */ |
295 |
|
#define FE_DOWNWARD FE_TONEAREST |
296 |
|
#define FE_UPWARD FE_TONEAREST |
297 |
|
#define FE_TOWARDZERO FE_TONEAREST |
298 |
|
#endif |
299 |
|
|
300 |
#ifdef USE_X86LDOUBLE |
#ifdef USE_X86LDOUBLE |
301 |
|
|
302 |
/* only for x86 */ |
/* only for x86 */ |
318 |
|
|
319 |
#else |
#else |
320 |
|
|
321 |
|
/* NOTE: arm is horrible as double 32 bit words are stored in big endian ! */ |
322 |
typedef union { |
typedef union { |
323 |
double d; |
double d; |
324 |
#ifndef WORDS_BIGENDIAN |
#if !defined(WORDS_BIGENDIAN) && !defined(__arm__) |
325 |
struct { |
struct { |
326 |
uint32_t lower; |
uint32_t lower; |
327 |
int32_t upper; |
int32_t upper; |
332 |
uint32_t lower; |
uint32_t lower; |
333 |
} l; |
} l; |
334 |
#endif |
#endif |
335 |
|
#ifndef __arm__ |
336 |
int64_t ll; |
int64_t ll; |
337 |
|
#endif |
338 |
} CPU86_LDoubleU; |
} CPU86_LDoubleU; |
339 |
|
|
340 |
/* the following deal with IEEE double-precision numbers */ |
/* the following deal with IEEE double-precision numbers */ |
342 |
#define EXPBIAS 1023 |
#define EXPBIAS 1023 |
343 |
#define EXPD(fp) (((fp.l.upper) >> 20) & 0x7FF) |
#define EXPD(fp) (((fp.l.upper) >> 20) & 0x7FF) |
344 |
#define SIGND(fp) ((fp.l.upper) & 0x80000000) |
#define SIGND(fp) ((fp.l.upper) & 0x80000000) |
345 |
|
#ifdef __arm__ |
346 |
|
#define MANTD(fp) (fp.l.lower | ((uint64_t)(fp.l.upper & ((1 << 20) - 1)) << 32)) |
347 |
|
#else |
348 |
#define MANTD(fp) (fp.ll & ((1LL << 52) - 1)) |
#define MANTD(fp) (fp.ll & ((1LL << 52) - 1)) |
349 |
|
#endif |
350 |
#define BIASEXPONENT(fp) fp.l.upper = (fp.l.upper & ~(0x7ff << 20)) | (EXPBIAS << 20) |
#define BIASEXPONENT(fp) fp.l.upper = (fp.l.upper & ~(0x7ff << 20)) | (EXPBIAS << 20) |
351 |
#endif |
#endif |
352 |
|
|
367 |
{ |
{ |
368 |
CPU86_LDoubleU temp; |
CPU86_LDoubleU temp; |
369 |
int upper, e; |
int upper, e; |
370 |
|
uint64_t ll; |
371 |
|
|
372 |
/* mantissa */ |
/* mantissa */ |
373 |
upper = lduw(ptr + 8); |
upper = lduw(ptr + 8); |
374 |
/* XXX: handle overflow ? */ |
/* XXX: handle overflow ? */ |
375 |
e = (upper & 0x7fff) - 16383 + EXPBIAS; /* exponent */ |
e = (upper & 0x7fff) - 16383 + EXPBIAS; /* exponent */ |
376 |
e |= (upper >> 4) & 0x800; /* sign */ |
e |= (upper >> 4) & 0x800; /* sign */ |
377 |
temp.ll = ((ldq(ptr) >> 11) & ((1LL << 52) - 1)) | ((uint64_t)e << 52); |
ll = (ldq(ptr) >> 11) & ((1LL << 52) - 1); |
378 |
|
#ifdef __arm__ |
379 |
|
temp.l.upper = (e << 20) | (ll >> 32); |
380 |
|
temp.l.lower = ll; |
381 |
|
#else |
382 |
|
temp.ll = ll | ((uint64_t)e << 52); |
383 |
|
#endif |
384 |
return temp.d; |
return temp.d; |
385 |
} |
} |
386 |
|
|
388 |
{ |
{ |
389 |
CPU86_LDoubleU temp; |
CPU86_LDoubleU temp; |
390 |
int e; |
int e; |
391 |
|
|
392 |
temp.d = f; |
temp.d = f; |
393 |
/* mantissa */ |
/* mantissa */ |
394 |
stq(ptr, (MANTD(temp) << 11) | (1LL << 63)); |
stq(ptr, (MANTD(temp) << 11) | (1LL << 63)); |
399 |
} |
} |
400 |
#endif |
#endif |
401 |
|
|
402 |
|
const CPU86_LDouble f15rk[7]; |
403 |
|
|
404 |
void helper_fldt_ST0_A0(void); |
void helper_fldt_ST0_A0(void); |
405 |
void helper_fstt_ST0_A0(void); |
void helper_fstt_ST0_A0(void); |
406 |
void helper_fbld_ST0_A0(void); |
void helper_fbld_ST0_A0(void); |