tech-userlevel archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: Default value of x87 registers' reserved bits



Attached find output from both a Intel Core-i7 and AMD Phenom II Quad-core

On Fri, 28 May 2010, Stathis Kamperis wrote:

Greetings everyone,

I've been working on floating-point exception support for x86_64 (as
part of this year's gsoc). It's basically done, just one subtlety
remaining. POSIX specs say that we must provide the constant
FE_DFL_ENV, which represents the default floating-point environment.

Here's the deal.

Control, status, etc x87 registers (which are part of the fp
environment) are 16 bit wide. In protected mode though, they are
accessed as 32 bit. The upper bits, 31-16, are marked as `reserved'
and are ought to be ignored. Their default value is _not_ mentioned in
the CPU specs. At the same time though, when we write to these
registers we must not tamper with the reserved bits.

So, I wrote this snippet to extract the default value of the reserved bits:

#include <inttypes.h>
#include <stdio.h>
#include <string.h>

/* Store x87 FPU state */
#define __fnstenv(__env)        __asm__ __volatile__ \
       ("fnstenv %0" : "=m" (*(__env)))

struct fenv {
       uint32_t fe_cw;         /* Control word register */
       uint32_t fe_sw;         /* Status word register */
       uint32_t fe_tw;         /* Tag word register */

       uint32_t fe_unused[5];
};

int
main(void)
{
       struct fenv f;

       memset(&f, 0, sizeof f);
       __fnstenv(&f);

       printf("Control word: 0x%x\n", f.fe_cw);
       printf(" Status word: 0x%x\n", f.fe_sw);
       printf("    Tag word: 0x%x\n", f.fe_tw);

       printf("Instruct Ptr: 0x%x 0x%x\n",
           f.fe_unused[0],
           f.fe_unused[1]);
       printf(" Operand Ptr: 0x%x 0x%x\n",
           f.fe_unused[2],
           f.fe_unused[3]);

       return 0;
}

Here is the output I get in an Intel cpu:

stathis:~% gcc dumpfenv.c -o dumpfenv -Wall -W -ansi -pedantic
stathis:~% ./dumpfenv
Control word: 0xffff037f
Status word: 0xffff0000
   Tag word: 0xffffffff
Instruct Ptr: 0x0 0x0
Operand Ptr: 0x0 0xffff0000
stathis:~%

So all of the reserved bits seem to be set to 1. Is it fine to assume
that this is true in all cases ? Could someone please confirm it with
an AMD processor ?
So that when I define FE_DFL_ENV, I do something like:

struct fenv fe_dfl_env = {
   0xffff0000 | 0x037f,         /* or just 0xffff037f */
   ...
};

#define FE_DFL_ENV (&fe_dfl_env)

I hope I made myself clear.
Thank you all for considering.

Cheers,
Stathis


-------------------------------------------------------------------------
| Paul Goyette     | PGP Key fingerprint:     | E-mail addresses:       |
| Customer Service | FA29 0E3B 35AF E8AE 6651 | paul at whooppee.com    |
| Network Engineer | 0786 F758 55DE 53BA 7731 | pgoyette at juniper.net |
| Kernel Developer |                          | pgoyette at netbsd.org  |
-------------------------------------------------------------------------
cpu0: AMD Unknown AMD64 CPU (686-class), 3013.98 MHz, id 0x100f42
cpu0: features  0x178bfbff<FPU,VME,DE,PSE,TSC,MSR,PAE,MCE,CX8,APIC,SEP,MTRR>
cpu0: features  0x178bfbff<PGE,MCA,CMOV,PAT,PSE36,CFLUSH,MMX,FXSR,SSE,SSE2>
cpu0: features  0x178bfbff<HTT>
cpu0: features2 0x802009<SSE3,MONITOR,CX16,POPCNT>
cpu0: features3 0xefd3fbff<SYSCALL/SYSRET,NOX,MXX,FFXSR,P1GB,RDTSCP,LONG>
cpu0: features3 0xefd3fbff<3DNOW2,3DNOW>
cpu0: features4 0x37ff<LAHF,CMPLEGACY,SVM,EAPIC,ALTMOVCR0,LZCNT,SSE4A>
cpu0: features4 0x37ff<MISALIGNSSE,3DNOWPREFETCH,OSVW,IBS,SKINIT,WDT>
cpu0: "AMD Processor model unknown"
cpu0: I-cache 64KB 64B/line 2-way, D-cache 64KB 64B/line 2-way
cpu0: L2 cache 512KB 64B/line 16-way
cpu0: ITLB 32 4KB entries fully associative, 16 4MB entries fully associative
cpu0: DTLB 48 4KB entries fully associative, 48 4MB entries fully associative
cpu0: L3 cache 6MB 64B/line 48-way
cpu0: Initial APIC ID 0
cpu0: AMD Power Management features: 0x1f9<TS,TTP,HTC,STC,100,HWP,TSC>
cpu0: SVM Rev. 1
cpu0: SVM NASID 64
cpu0: SVM features 0xf<NP,LbrVirt,SVML,NRIPS>
cpu0: family 0f model 04 extfamily 01 extmodel 00
Control word: 0xffff127f
 Status word: 0xffff0000
    Tag word: 0xffffffff
Instruct Ptr: 0x0 0x0
 Operand Ptr: 0x0 0xffff0000
Cannot bind to target CPU.  Output may not accurately describe the target.
Run as root to allow binding.

cpu0: Intel Core 2 (686-class), 2400.18 MHz, id 0x6fb
cpu0: features  0xbfebfbff<FPU,VME,DE,PSE,TSC,MSR,PAE,MCE,CX8,APIC,SEP,MTRR>
cpu0: features  0xbfebfbff<PGE,MCA,CMOV,PAT,PSE36,CFLUSH,DS,ACPI,MMX,FXSR>
cpu0: features  0xbfebfbff<SSE,SSE2,SS,HTT,TM,SBF>
cpu0: features2 0xe3bd<SSE3,DTES64,MONITOR,DS-CPL,VMX,EST,TM2,SSSE3,CX16>
cpu0: features2 0xe3bd<xTPR,PDCM>
cpu0: features3 0x20100800<SYSCALL/SYSRET,XD,EM64T>
cpu0: features4 0x1<LAHF>
cpu0: "Intel(R) Core(TM)2 Quad CPU    Q6600  @ 2.40GHz"
cpu0: I-cache 32KB 64B/line 8-way, D-cache 32KB 64B/line 8-way
cpu0: L2 cache 4MB 64B/line 16-way
cpu0: ITLB 128 4KB entries 4-way
cpu0: DTLB 256 4KB entries 4-way, 16 4MB entries 4-way
cpu0: Initial APIC ID 1
cpu0: Cluster/Package ID 0
cpu0: Core ID 1
cpu0: family 06 model 0f extfamily 00 extmodel 00
Control word: 0xffff127f
 Status word: 0xffff0000
    Tag word: 0xffffffff
Instruct Ptr: 0x0 0x0
 Operand Ptr: 0x0 0xffff0000


Home | Main Index | Thread Index | Old Index