Revision 2ee73ac3
b/target-i386/cpu.h | ||
---|---|---|
143 | 143 |
#define CR0_MP_MASK (1 << 1) |
144 | 144 |
#define CR0_EM_MASK (1 << 2) |
145 | 145 |
#define CR0_TS_MASK (1 << 3) |
146 |
#define CR0_ET_MASK (1 << 4) |
|
146 | 147 |
#define CR0_NE_MASK (1 << 5) |
147 | 148 |
#define CR0_WP_MASK (1 << 16) |
148 | 149 |
#define CR0_AM_MASK (1 << 18) |
... | ... | |
373 | 374 |
int cpu_x86_exec(CPUX86State *s); |
374 | 375 |
void cpu_x86_close(CPUX86State *s); |
375 | 376 |
int cpu_get_pic_interrupt(CPUX86State *s); |
377 |
/* MSDOS compatibility mode FPU exception support */ |
|
378 |
void cpu_set_ferr(CPUX86State *s); |
|
376 | 379 |
|
377 | 380 |
/* this function must always be used to load data in the segment |
378 | 381 |
cache: it synchronizes the hflags with the segment cache values */ |
b/target-i386/exec.h | ||
---|---|---|
478 | 478 |
|
479 | 479 |
#endif /* USE_X86LDOUBLE */ |
480 | 480 |
|
481 |
#define FPUS_IE (1 << 0) |
|
482 |
#define FPUS_DE (1 << 1) |
|
483 |
#define FPUS_ZE (1 << 2) |
|
484 |
#define FPUS_OE (1 << 3) |
|
485 |
#define FPUS_UE (1 << 4) |
|
486 |
#define FPUS_PE (1 << 5) |
|
487 |
#define FPUS_SF (1 << 6) |
|
488 |
#define FPUS_SE (1 << 7) |
|
489 |
#define FPUS_B (1 << 15) |
|
490 |
|
|
491 |
#define FPUC_EM 0x3f |
|
492 |
|
|
481 | 493 |
const CPU86_LDouble f15rk[7]; |
482 | 494 |
|
483 | 495 |
void helper_fldt_ST0_A0(void); |
484 | 496 |
void helper_fstt_ST0_A0(void); |
497 |
void fpu_raise_exception(void); |
|
498 |
CPU86_LDouble helper_fdiv(CPU86_LDouble a, CPU86_LDouble b); |
|
485 | 499 |
void helper_fbld_ST0_A0(void); |
486 | 500 |
void helper_fbst_ST0_A0(void); |
487 | 501 |
void helper_f2xm1(void); |
b/target-i386/helper.c | ||
---|---|---|
24 | 24 |
#if 0 |
25 | 25 |
#define raise_exception_err(a, b)\ |
26 | 26 |
do {\ |
27 |
printf("raise_exception line=%d\n", __LINE__);\
|
|
27 |
fprintf(logfile, "raise_exception line=%d\n", __LINE__);\
|
|
28 | 28 |
(raise_exception_err)(a, b);\ |
29 | 29 |
} while (0) |
30 | 30 |
#endif |
... | ... | |
859 | 859 |
if (loglevel & (CPU_LOG_PCALL | CPU_LOG_INT)) { |
860 | 860 |
if ((env->cr[0] & CR0_PE_MASK)) { |
861 | 861 |
static int count; |
862 |
fprintf(logfile, "%6d: v=%02x e=%04x i=%d cpl=%d IP=%04x:%08x SP=%04x:%08x", |
|
862 |
fprintf(logfile, "%6d: v=%02x e=%04x i=%d cpl=%d IP=%04x:%08x pc=%08x SP=%04x:%08x",
|
|
863 | 863 |
count, intno, error_code, is_int, |
864 | 864 |
env->hflags & HF_CPL_MASK, |
865 | 865 |
env->segs[R_CS].selector, EIP, |
866 |
(int)env->segs[R_CS].base + EIP, |
|
866 | 867 |
env->segs[R_SS].selector, ESP); |
867 | 868 |
if (intno == 0x0e) { |
868 | 869 |
fprintf(logfile, " CR2=%08x", env->cr[2]); |
... | ... | |
1990 | 1991 |
helper_fstt(ST0, (uint8_t *)A0); |
1991 | 1992 |
} |
1992 | 1993 |
|
1994 |
void fpu_set_exception(int mask) |
|
1995 |
{ |
|
1996 |
env->fpus |= mask; |
|
1997 |
if (env->fpus & (~env->fpuc & FPUC_EM)) |
|
1998 |
env->fpus |= FPUS_SE | FPUS_B; |
|
1999 |
} |
|
2000 |
|
|
2001 |
CPU86_LDouble helper_fdiv(CPU86_LDouble a, CPU86_LDouble b) |
|
2002 |
{ |
|
2003 |
if (b == 0.0) |
|
2004 |
fpu_set_exception(FPUS_ZE); |
|
2005 |
return a / b; |
|
2006 |
} |
|
2007 |
|
|
2008 |
void fpu_raise_exception(void) |
|
2009 |
{ |
|
2010 |
if (env->cr[0] & CR0_NE_MASK) { |
|
2011 |
raise_exception(EXCP10_COPR); |
|
2012 |
} |
|
2013 |
#if !defined(CONFIG_USER_ONLY) |
|
2014 |
else { |
|
2015 |
cpu_set_ferr(env); |
|
2016 |
} |
|
2017 |
#endif |
|
2018 |
} |
|
2019 |
|
|
1993 | 2020 |
/* BCD ops */ |
1994 | 2021 |
|
1995 | 2022 |
void helper_fbld_ST0_A0(void) |
b/target-i386/op.c | ||
---|---|---|
1738 | 1738 |
|
1739 | 1739 |
void OPPROTO op_fdiv_ST0_FT0(void) |
1740 | 1740 |
{ |
1741 |
ST0 /= FT0;
|
|
1741 |
ST0 = helper_fdiv(ST0, FT0);
|
|
1742 | 1742 |
} |
1743 | 1743 |
|
1744 | 1744 |
void OPPROTO op_fdivr_ST0_FT0(void) |
1745 | 1745 |
{ |
1746 |
ST0 = FT0 / ST0;
|
|
1746 |
ST0 = helper_fdiv(FT0, ST0);
|
|
1747 | 1747 |
} |
1748 | 1748 |
|
1749 | 1749 |
/* fp operations between STN and ST0 */ |
... | ... | |
1772 | 1772 |
|
1773 | 1773 |
void OPPROTO op_fdiv_STN_ST0(void) |
1774 | 1774 |
{ |
1775 |
ST(PARAM1) /= ST0; |
|
1775 |
CPU86_LDouble *p; |
|
1776 |
p = &ST(PARAM1); |
|
1777 |
*p = helper_fdiv(*p, ST0); |
|
1776 | 1778 |
} |
1777 | 1779 |
|
1778 | 1780 |
void OPPROTO op_fdivr_STN_ST0(void) |
1779 | 1781 |
{ |
1780 | 1782 |
CPU86_LDouble *p; |
1781 | 1783 |
p = &ST(PARAM1); |
1782 |
*p = ST0 / *p;
|
|
1784 |
*p = helper_fdiv(ST0, *p);
|
|
1783 | 1785 |
} |
1784 | 1786 |
|
1785 | 1787 |
/* misc FPU operations */ |
... | ... | |
1959 | 1961 |
env->fpus &= 0x7f00; |
1960 | 1962 |
} |
1961 | 1963 |
|
1964 |
void OPPROTO op_fwait(void) |
|
1965 |
{ |
|
1966 |
if (env->fpus & FPUS_SE) |
|
1967 |
fpu_raise_exception(); |
|
1968 |
FORCE_RET(); |
|
1969 |
} |
|
1970 |
|
|
1962 | 1971 |
void OPPROTO op_fninit(void) |
1963 | 1972 |
{ |
1964 | 1973 |
env->fpus = 0; |
b/target-i386/translate.c | ||
---|---|---|
3761 | 3761 |
if ((s->flags & (HF_MP_MASK | HF_TS_MASK)) == |
3762 | 3762 |
(HF_MP_MASK | HF_TS_MASK)) { |
3763 | 3763 |
gen_exception(s, EXCP07_PREX, pc_start - s->cs_base); |
3764 |
} else { |
|
3765 |
if (s->cc_op != CC_OP_DYNAMIC) |
|
3766 |
gen_op_set_cc_op(s->cc_op); |
|
3767 |
gen_op_jmp_im(pc_start - s->cs_base); |
|
3768 |
gen_op_fwait(); |
|
3764 | 3769 |
} |
3765 | 3770 |
break; |
3766 | 3771 |
case 0xcc: /* int3 */ |
Also available in: Unified diff