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