x86_64 FPU: Set 64-bit precision for fadd/fsub/fsqrt etc.
authorJohn Marino <netbsd@marino.st>
Thu, 12 Jul 2012 11:15:12 +0000 (13:15 +0200)
committerJohn Marino <draco@marino.st>
Thu, 12 Jul 2012 11:34:07 +0000 (13:34 +0200)
On AMD64, GCC and the ABI expects the x87 unit to be running in 80/64
mode rather than 64/53 mode seen on i386.  This corrects errors seen
in long double tests involving runtime calculations.  Previously, the
results of these runtime calculations would get rounded due to use
of 53-bit mantissas.

sys/platform/pc64/x86_64/machdep.c
sys/platform/pc64/x86_64/mp_machdep.c
sys/platform/pc64/x86_64/npx.c
sys/platform/vkernel64/x86_64/cpu_regs.c
sys/platform/vkernel64/x86_64/npx.c

index b4d66e7..176035d 100644 (file)
@@ -1113,7 +1113,7 @@ exec_setregs(u_long entry, u_long stack, u_long ps_strings)
        wrmsr(MSR_KGSBASE, 0);
 
        /* Initialize the npx (if any) for the current process. */
-       npxinit(__INITIAL_NPXCW__);
+       npxinit(__INITIAL_FPUCW__);
        crit_exit();
 
        pcb->pcb_ds = _udatasel;
index 74e21d8..ee0ac0c 100644 (file)
@@ -305,7 +305,7 @@ init_secondary(void)
        initializecpu();
 
        /* set up FPU state on the AP */
-       npxinit(__INITIAL_NPXCW__);
+       npxinit(__INITIAL_FPUCW__);
 
        /* disable the APIC, just to be SURE */
        lapic->svr &= ~APIC_SVR_ENABLE;
index 5920a75..e69c088 100644 (file)
@@ -331,7 +331,7 @@ npxdna(void)
        crit_enter();
        if ((td->td_flags & (TDF_USINGFP | TDF_KERNELFP)) == 0) {
                td->td_flags |= TDF_USINGFP;
-               npxinit(__INITIAL_NPXCW__);
+               npxinit(__INITIAL_FPUCW__);
                didinit = 1;
        }
 
index b0f7048..9a08a1c 100644 (file)
@@ -832,7 +832,7 @@ exec_setregs(u_long entry, u_long stack, u_long ps_strings)
        pcb->pcb_fsbase = 0;    /* Values loaded from PCB on switch */
        pcb->pcb_gsbase = 0;
        /* Initialize the npx (if any) for the current process. */
-       npxinit(__INITIAL_NPXCW__);
+       npxinit(__INITIAL_FPUCW__);
        crit_exit();
 
        /*
index 85bf69f..730577e 100644 (file)
@@ -113,7 +113,7 @@ SYSCTL_INT(_hw, OID_AUTO, instruction_sse, CTLFLAG_RD,
 int
 npx_attach(device_t dev)
 {
-       npxinit(__INITIAL_NPXCW__);
+       npxinit(__INITIAL_FPUCW__);
        return (0);
 }
 #endif
@@ -357,7 +357,7 @@ npxdna(struct trapframe *frame)
         */
        if ((curthread->td_flags & TDF_USINGFP) == 0) {
                curthread->td_flags |= TDF_USINGFP;
-               npxinit(__INITIAL_NPXCW__);
+               npxinit(__INITIAL_FPUCW__);
                didinit = 1;
        }