I'm seeing core=dynamic fail here with the same Scale and transcendental tests. x86_64 Linux.
DOSBox-X still uses the old dynamic core for 32-bit, is that what you are compiling?
I do not have a 32-bit Linux system handy at this time.
/* From fpu_control.h: 387 through the control word register
*
* 11-10 9-8 5 4 3 2 1 0
* | RC | PC | | PM | UM | OM | ZM | DM | IM
*
* IM: Invalid operation mask 0x1
* DM: Denormalized operand mask 0x2
* ZM: Zero-divide mask 0x4
* OM: Overflow mask 0x8
* UM: Underflow mask 0x10
* PM: Precision (inexact result) mask 0x20
*
* Mask bit is 1 means no interrupt.
*
* PC: Precision control
* 11 - round to extended precision 0x300
* 10 - round to double precision 0x200
* 00 - round to single precision
*
* RC: Rounding control
* 00 - rounding to nearest
* 01 - rounding down (toward - infinity) 0x400
* 10 - rounding up (toward + infinity) 0x800
* 11 - rounding toward zero 0xC00
*
* The hardware default is 0x037f which we use.
*/
hail-to-the-ryzen wrote:I think the normal cpu core and long double fpu core are not fully compatible in a Windows 95 dos box. I don't know yet whether it is related to the page fault system. Running Quake led to a SIGFPE arithmetic exception in the emulator. It seems related to use of the assembly instruction fldcw.
diff -rupN dosbox-Orig//src/fpu/fpu_instructions_longdouble.h dosbox/src/fpu/fpu_instructions_longdouble.h
--- dosbox-Orig//src/fpu/fpu_instructions_longdouble.h
+++ dosbox/src/fpu/fpu_instructions_longdouble.h
@@ -26,6 +26,7 @@
# include <fpu_control.h>
# endif
static inline void FPU_SyncCW(void) {
+ fpu.cw = fpu.cw | 0x3f;
_FPU_SETCW(fpu.cw);
}
#else
@@ -528,6 +529,7 @@ static void FPU_FLDENV(PhysPt addr){
tag = static_cast<Bit16u>(tagbig);
}
FPU_SetTag(tag);
+ cw = cw | 0x3f;
FPU_SetCW(cw);
FPU_SyncCW();
TOP = FPU_GET_TOP();
@@ -26,6 +26,7 @@
# include <fpu_control.h>
# endif
static inline void FPU_SyncCW(void) {
+ fpu.cw |= 0x3f;
_FPU_SETCW(fpu.cw);
}
#else
@@ -528,7 +529,7 @@ static void FPU_FLDENV(PhysPt addr){
tag = static_cast<Bit16u>(tagbig);
}
FPU_SetTag(tag);
- FPU_SetCW(cw);
+ FPU_SetCW(cw | 0x3f);
FPU_SyncCW();
TOP = FPU_GET_TOP();
}
hail-to-the-ryzen wrote:Confirmed the negative result on 35 SCALE tests in the FPU test software MCPDIAG. Used the 32 bit dynarec with the x86 fpu code.
diff -rupN dosbox-Orig//src/fpu/fpu_instructions_x86.h dosbox/src/fpu/fpu_instructions_x86.h
--- dosbox-Orig//src/fpu/fpu_instructions_x86.h
+++ dosbox/src/fpu/fpu_instructions_x86.h
@@ -802,17 +802,20 @@
// handles fprem,fprem1,fscale
#define FPUD_REMAINDER(op) \
- Bit16u new_sw; \
+ Bit16u new_sw,save_sw; \
__asm__ volatile ( \
+ "fnstcw %1 \n" \
+ "fldcw %4 \n" \
+ "fldt %3 \n" \
"fldt %2 \n" \
- "fldt %1 \n" \
"fclex \n" \
#op" \n" \
"fnstsw %0 \n" \
- "fstpt %1 \n" \
- "fstp %%st(0) " \
- : "=&am" (new_sw), "+m" (fpu.p_regs[TOP]) \
- : "m" (fpu.p_regs[(TOP+1)&7]) \
+ "fstpt %2 \n" \
+ "fstp %%st(0) \n" \
+ "fldcw %1 " \
+ : "=&am" (new_sw), "=m" (save_sw), "+m" (fpu.p_regs[TOP]) \
+ : "m" (fpu.p_regs[(TOP+1)&7]), "m" (fpu.cw_mask_all) \
); \
fpu.sw=(new_sw&0xffbf)|(fpu.sw&0x80ff);
Users browsing this forum: No registered users and 0 guests