Skip to content

Commit

Permalink
cpu: completely remove PM fpu state
Browse files Browse the repository at this point in the history
Let back-ends to deal with save/restore.
  • Loading branch information
stsp committed Dec 13, 2022
1 parent 5241bf5 commit 7b31442
Show file tree
Hide file tree
Showing 11 changed files with 58 additions and 66 deletions.
21 changes: 10 additions & 11 deletions src/base/emu-i386/cpu.c
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ static unsigned int TRs[2] =
#endif

/* fpu_state needs to be paragraph aligned for fxrstor/fxsave */
fpregset_t vm86_fpu_state;
struct emu_fpstate vm86_fpu_state __attribute__((aligned(16)));
fenv_t dosemu_fenv;
static void fpu_reset(void);

Expand Down Expand Up @@ -242,13 +242,13 @@ static void fpu_init(void)
static void fpu_reset(void)
{
#ifdef __x86_64__
vm86_fpu_state->cwd = 0x0040;
vm86_fpu_state->swd = 0;
vm86_fpu_state->ftw = 0x5555; //bochs
vm86_fpu_state.cwd = 0x0040;
vm86_fpu_state.swd = 0;
vm86_fpu_state.ftw = 0x5555; //bochs
#else
vm86_fpu_state->cw = 0x40;
vm86_fpu_state->sw = 0;
vm86_fpu_state->tag = 0x5555; // bochs
vm86_fpu_state.cw = 0x40;
vm86_fpu_state.sw = 0;
vm86_fpu_state.tag = 0x5555; // bochs
#endif
}

Expand All @@ -263,9 +263,9 @@ static void fpu_io_write(ioport_t port, Bit8u val)
case 0xf0:
/* not sure about this */
#ifdef __x86_64__
vm86_fpu_state->swd &= ~0x8000;
vm86_fpu_state.swd &= ~0x8000;
#else
vm86_fpu_state->sw &= ~0x8000;
vm86_fpu_state.sw &= ~0x8000;
#endif
break;
case 0xf1:
Expand Down Expand Up @@ -300,8 +300,7 @@ void cpu_setup(void)
io_dev.handler_name = "Math Coprocessor";
port_register_handler(io_dev, 0);

vm86_fpu_state = aligned_alloc(16, sizeof(*vm86_fpu_state));
savefpstate(*vm86_fpu_state);
savefpstate(vm86_fpu_state);
#ifdef FE_NOMASK_ENV
feenableexcept(FE_DIVBYZERO | FE_OVERFLOW);
#endif
Expand Down
4 changes: 2 additions & 2 deletions src/base/emu-i386/do_vm86.c
Original file line number Diff line number Diff line change
Expand Up @@ -446,7 +446,7 @@ static int true_vm86(union vm86_union *x)
int ret;
uint32_t old_flags = REG(eflags);

loadfpstate(*vm86_fpu_state);
loadfpstate(vm86_fpu_state);
again:
#if 0
ret = vm86(&x->vm86ps);
Expand All @@ -464,7 +464,7 @@ static int true_vm86(union vm86_union *x)
* TODO: check kernel version */
REG(eflags) |= (old_flags & VIP);

savefpstate(*vm86_fpu_state);
savefpstate(vm86_fpu_state);
/* there is no real need to save and restore the FPU state of the
emulator itself: savefpstate (fnsave) also resets the current FPU
state using fninit; fesetenv then restores trapping of division by
Expand Down
4 changes: 3 additions & 1 deletion src/base/emu-i386/kvm.c
Original file line number Diff line number Diff line change
Expand Up @@ -1075,6 +1075,7 @@ int kvm_dpmi(cpuctx_t *scp)
}

if (_trapno == 0x10) {
#if 0
struct kvm_fpu fpu;
ioctl(vcpufd, KVM_GET_FPU, &fpu);
#ifdef __x86_64__
Expand All @@ -1095,9 +1096,10 @@ int kvm_dpmi(cpuctx_t *scp)
__fpstate->cssel = _cs;
__fpstate->dataoff = fpu.last_dp;
__fpstate->datasel = _ds;
#endif
print_exception_info(scp);
#endif
dbug_printf("coprocessor exception, calling IRQ13\n");
// print_exception_info(scp);
pic_untrigger(13);
pic_request(13);
ret = DPMI_RET_DOSEMU;
Expand Down
2 changes: 0 additions & 2 deletions src/base/emu-i386/simx86/codegen-x86.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,6 @@
#include "trees.h"
#include "vgaemu.h"

#define HOST_ARCH_X86

#define TAILSIZE 7
#define TAILFIX 1

Expand Down
29 changes: 15 additions & 14 deletions src/base/emu-i386/simx86/cpu-emu.c
Original file line number Diff line number Diff line change
Expand Up @@ -523,6 +523,8 @@ static void Reg2Cpu (int mode)
SetSegReal(SREG(gs),Ofs_GS);
trans_addr = LONG_CS + TheCPU.eip;

/* FPU state is loaded later on demand for JIT, not used for simulator */
TheCPU.fpstate = &vm86_fpu_state;
if (debug_level('e')>1) {
if (debug_level('e')==9) e_printf("Reg2Cpu< vm86=%08x dpm=%08x emu=%08x\n%s\n",
REG(eflags),get_FLAGS(TheCPU.eflags),TheCPU.eflags,
Expand Down Expand Up @@ -567,6 +569,14 @@ void Cpu2Reg (void)
clear_IF();
REG(eflags) |= EFLAGS_IF;

if (TheCPU.fpstate == NULL) {
if (!CONFIG_CPUSIM)
savefpstate(vm86_fpu_state);
#ifdef HOST_ARCH_X86
fesetenv(&dosemu_fenv);
#endif
}

if (debug_level('e')>1) e_printf("Cpu2Reg< vm86=%08x dpm=%08x emu=%08x\n",
REG(eflags),get_FLAGS(TheCPU.eflags),TheCPU.eflags);
}
Expand Down Expand Up @@ -600,9 +610,7 @@ static void Scp2Cpu (cpuctx_t *scp)
TheCPU.cr2 = _cr2;
TheCPU.df_increments = (TheCPU.eflags&DF)?0xfcfeff:0x040201;

/* __fpstate is loaded later on demand for JIT, not used for simulator */
TheCPU.fpstate = &TheCPU._fpstate;
TheCPU._fpstate = *__fpstate;
TheCPU.fpstate = &vm86_fpu_state;
}

/*
Expand Down Expand Up @@ -642,17 +650,17 @@ static void Cpu2Scp (cpuctx_t *scp, int trapno)
*/
if (!TheCPU.err) _err = 0; //???
if (TheCPU.fpstate == NULL) {
if (!CONFIG_CPUSIM) {
savefpstate(TheCPU._fpstate);
*get_fpstate(scp) = TheCPU._fpstate;
}
if (!CONFIG_CPUSIM)
savefpstate(vm86_fpu_state);
/* there is no real need to save and restore the FPU state of the
emulator itself: savefpstate (fnsave) also resets the current FPU
state using fninit; fesetenv then restores trapping of division by
zero and overflow which is good enough for calling FPU-using
routines.
*/
#ifdef HOST_ARCH_X86
fesetenv(&dosemu_fenv);
#endif
}

/* push running flags - same as eflags, RF is cosmetic */
Expand Down Expand Up @@ -966,8 +974,6 @@ int e_vm86(void)
e_sigpa_count = 0;
mode = ADDR16 | DATA16 | MREALA;
TheCPU.StackMask = 0x0000ffff;
/* FPU state is loaded later on demand for JIT, not used for simulator */
TheCPU.fpstate = vm86_fpu_state;
#ifdef SKIP_VM86_TRACE
demusav=debug_level('e'); if (debug_level('e')) set_debug_level('e', 1);
#endif
Expand Down Expand Up @@ -1053,11 +1059,6 @@ int e_vm86(void)
while (retval < 0);
/* ------ OUTER LOOP -- exit to user level ---------------------- */

if (TheCPU.fpstate == NULL) {
if (!CONFIG_CPUSIM) savefpstate(*vm86_fpu_state);
fesetenv(&dosemu_fenv);
}

if (debug_level('e')>1)
e_printf("EMU86: retval=%s\n", retdescs[retval&7]);

Expand Down
2 changes: 2 additions & 0 deletions src/base/emu-i386/simx86/interp.c
Original file line number Diff line number Diff line change
Expand Up @@ -2725,6 +2725,7 @@ intop3b: { int op = ArOpsFR[D_MO(opc)];
}
}
b &= 7;
#ifdef HOST_ARCH_X86
if (TheCPU.fpstate) {
/* For simulator, only need to mask all
exceptions; for JIT, load emulated FPU state
Expand All @@ -2735,6 +2736,7 @@ intop3b: { int op = ArOpsFR[D_MO(opc)];
loadfpstate(*TheCPU.fpstate);
TheCPU.fpstate = NULL;
}
#endif
if (sim) {
if (Fp87_op(exop,b)) { TheCPU.err = -96; return P0; }
}
Expand Down
11 changes: 5 additions & 6 deletions src/base/emu-i386/simx86/syncpu.h
Original file line number Diff line number Diff line change
Expand Up @@ -147,18 +147,17 @@ typedef struct {
unsigned short TR_SEL;
DTR TR;

/* if not NULL, points to emulated FPU state
if NULL, emulator uses FPU instructions, so flags that
dosemu needs to restore its own FPU environment. */
fpregset_t fpstate;

void (*stub_read_8)(void);
void (*stub_read_16)(void);
void (*stub_read_32)(void);

/* should be moved to TSS once implemented */
struct revectored_struct int_revectored;
struct _libc_fpstate _fpstate __attribute__((aligned(16)));

/* if not NULL, points to emulated FPU state
if NULL, emulator uses FPU instructions, so flags that
dosemu needs to restore its own FPU environment. */
emu_fpregset_t fpstate;
} SynCPU;

union _SynCPU {
Expand Down
2 changes: 1 addition & 1 deletion src/base/init/config.c
Original file line number Diff line number Diff line change
Expand Up @@ -728,7 +728,7 @@ static void read_cpu_info(void)
#endif
#ifdef __i386__
if (cpuflags && (strstr(cpuflags, "fxsr")) &&
sizeof(*vm86_fpu_state) == (112+512)) {
sizeof(vm86_fpu_state) == (112+512)) {
config.cpufxsr = 1;
if (cpuflags && strstr(cpuflags, "sse"))
config.cpusse = 1;
Expand Down
12 changes: 8 additions & 4 deletions src/dosext/dpmi/dnative.c
Original file line number Diff line number Diff line change
Expand Up @@ -85,8 +85,9 @@ static void copy_to_dpmi(sigcontext_t *scp, cpuctx_t *s)
_C(trapno);
_C(err);
_C(cr2);
if (scp->fpstate)
memcpy(scp->fpstate, get_fpstate(s), sizeof(struct _fpstate));
static_assert(sizeof(struct _fpstate) == sizeof(vm86_fpu_state),
"size mismatch");
scp->fpstate = (struct _fpstate *)&vm86_fpu_state;
}

static void copy_to_emu(cpuctx_t *d, sigcontext_t *scp)
Expand All @@ -111,8 +112,11 @@ static void copy_to_emu(cpuctx_t *d, sigcontext_t *scp)
_D(trapno);
_D(err);
_D(cr2);
if (scp->fpstate)
memcpy(get_fpstate(d), _scp_fpstate, sizeof(*get_fpstate(d)));
if (scp->fpstate && scp->fpstate != (struct _fpstate *)&vm86_fpu_state) {
static_assert(sizeof(struct _fpstate) == sizeof(vm86_fpu_state),
"size mismatch");
memcpy(&vm86_fpu_state, scp->fpstate, sizeof(struct _fpstate));
}
}

#if WANT_SIGRETURN_WA
Expand Down
6 changes: 0 additions & 6 deletions src/dosext/dpmi/dpmi.c
Original file line number Diff line number Diff line change
Expand Up @@ -3997,11 +3997,6 @@ void dpmi_init(void)
_es = ES;
_fs = 0;
_gs = 0;
#ifdef __linux__
/* fpu_state needs to be paragraph aligned for fxrstor/fxsave */
// __fpstate = aligned_alloc(16, sizeof(*__fpstate));
*__fpstate = *vm86_fpu_state;
#endif
NOCARRY;
rm_to_pm_regs(&DPMI_CLIENT.stack_frame, ~0);
/* on cpu-emu we work with IOPL=3 to avoid doom work-around */
Expand Down Expand Up @@ -4611,7 +4606,6 @@ static void do_dpmi_hlt(cpuctx_t *scp, uint8_t *lina, void *sp)
DPMI_CLIENT.in_dpmi_pm_stack);

pm_to_rm_regs(scp, ~0);
old_ctx.fpregs = scp->fpregs;
restore_pm_regs(&old_ctx);
curscp = scp;
scp = &old_ctx;
Expand Down
31 changes: 12 additions & 19 deletions src/include/cpu.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,22 +61,20 @@ union word {
struct { Bit8u l, h; } b;
} MAY_ALIAS;

#ifndef __linux__
#define __ctx(fld) fld
#ifdef __x86_64__
/* taken from glibc, don't blame me :) */
typedef long long int greg_t;
struct _libc_fpxreg
struct __fpxreg
{
unsigned short int __ctx(significand)[4];
unsigned short int __ctx(exponent);
unsigned short int __glibc_reserved1[3];
};
struct _libc_xmmreg
struct __xmmreg
{
__uint32_t __ctx(element)[4];
};
struct _libc_fpstate
struct emu_fpstate
{
/* 64-bit FXSAVE format. */
uint16_t __ctx(cwd);
Expand All @@ -87,20 +85,17 @@ struct _libc_fpstate
uint64_t __ctx(rdp);
uint32_t __ctx(mxcsr);
uint32_t __ctx(mxcr_mask);
struct _libc_fpxreg _st[8];
struct _libc_xmmreg _xmm[16];
struct __fpxreg _st[8];
struct __xmmreg _xmm[16];
uint32_t __glibc_reserved1[24];
};
/* Structure to describe FPU registers. */
typedef struct _libc_fpstate *fpregset_t;
#else
typedef int greg_t;
struct _libc_fpreg
struct __fpreg
{
unsigned short int __ctx(significand)[4];
unsigned short int __ctx(exponent);
};
struct _libc_fpstate
struct emu_fpstate
{
unsigned long int __ctx(cw);
unsigned long int __ctx(sw);
Expand All @@ -109,11 +104,12 @@ struct _libc_fpstate
unsigned long int __ctx(cssel);
unsigned long int __ctx(dataoff);
unsigned long int __ctx(datasel);
struct _libc_fpreg _st[8];
struct __fpreg _st[8];
unsigned long int __ctx(status);
};
#endif
#endif
/* Structure to describe FPU registers. */
typedef struct emu_fpstate *emu_fpregset_t;

union g_reg {
greg_t reg;
Expand Down Expand Up @@ -245,7 +241,7 @@ static inline dosaddr_t FAR2ADDR(far_t ptr) {

#define peek(seg, off) (READ_WORD(SEGOFF2LINEAR(seg, off)))

extern fpregset_t vm86_fpu_state;
extern struct emu_fpstate vm86_fpu_state;
extern fenv_t dosemu_fenv;

/*
Expand Down Expand Up @@ -490,10 +486,9 @@ struct pm_regs {
unsigned trapno;
unsigned err;
unsigned long cr2;
struct _libc_fpstate fpregs;
};
typedef struct pm_regs cpuctx_t;
#define REGS_SIZE offsetof(struct pm_regs, fpregs)
#define REGS_SIZE offsetof(struct pm_regs, trapno)

#define _es (scp->es)
#define _ds (scp->ds)
Expand All @@ -518,7 +513,6 @@ typedef struct pm_regs cpuctx_t;
#define get_trapno(s) ((s)->trapno)
#define get_err(s) ((s)->err)
#define get_cr2(s) ((s)->cr2)
#define get_fpstate(s) (&(s)->fpregs)
#define _edi get_edi(scp)
#define _esi get_esi(scp)
#define _ebp get_ebp(scp)
Expand Down Expand Up @@ -547,7 +541,6 @@ typedef struct pm_regs cpuctx_t;
#define _eflags_ (scp->eflags)
#define _cr2 (scp->cr2)
#define _trapno (scp->trapno)
#define __fpstate (&scp->fpregs)
/* compatibility */
#define _rdi _edi
#define _rsi _esi
Expand Down

0 comments on commit 7b31442

Please sign in to comment.