Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F139435033
D26856.id78519.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
3 KB
Referenced Files
None
Subscribers
None
D26856.id78519.diff
View Options
Index: sys/amd64/ia32/ia32_reg.c
===================================================================
--- sys/amd64/ia32/ia32_reg.c
+++ sys/amd64/ia32/ia32_reg.c
@@ -145,7 +145,11 @@
struct save87 *sv_87;
struct env87 *penv_87;
struct envxmm *penv_xmm;
- int i;
+ struct fpacc87 *fx_reg;
+ int i, st;
+ uint64_t mantissa;
+ uint16_t tw, exp;
+ uint8_t ab_tw;
bzero(regs, sizeof(*regs));
sv_87 = (struct save87 *)regs;
@@ -171,13 +175,39 @@
/* Entry into the kernel always sets TF_HASSEGS */
penv_87->en_fos = td->td_frame->tf_ds;
- /* FPU registers and tags */
- penv_87->en_tw = 0xffff;
- for (i = 0; i < 8; ++i) {
- sv_87->sv_ac[i] = sv_fpu->sv_fp[i].fp_acc;
- if ((penv_xmm->en_tw & (1 << i)) != 0)
- penv_87->en_tw &= ~(3 << i * 2);
+ /*
+ * FPU registers and tags.
+ * For ST(i), i = fpu_reg - top; we start with fpu_reg=7.
+ */
+ st = 7 - ((penv_xmm->en_sw >> 11) & 7);
+ ab_tw = penv_xmm->en_tw;
+ tw = 0;
+ for (i = 0x80; i != 0; i >>= 1) {
+ sv_87->sv_ac[st] = sv_fpu->sv_fp[st].fp_acc;
+ tw <<= 2;
+ if ((ab_tw & i) != 0) {
+ /* Non-empty - we need to check ST(i) */
+ fx_reg = &sv_fpu->sv_fp[st].fp_acc;
+ /* The first 64 bits contain the mantissa. */
+ mantissa = *((uint64_t *)fx_reg->fp_bytes);
+ /*
+ * The final 16 bits contain the sign bit and the exponent.
+ * Mask the sign bit since it is of no consequence to these
+ * tests.
+ */
+ exp = *((uint16_t *)&fx_reg->fp_bytes[8]) & 0x7fff;
+ if (exp == 0) {
+ if (mantissa == 0)
+ tw |= 1; /* Zero */
+ else
+ tw |= 2; /* Denormal */
+ } else if (exp == 0x7fff)
+ tw |= 2; /* Infinity or NaN */
+ } else
+ tw |= 3; /* Empty */
+ st = (st - 1) & 7;
}
+ penv_87->en_tw = tw;
return (0);
}
Index: sys/i386/i386/npx.c
===================================================================
--- sys/i386/i386/npx.c
+++ sys/i386/i386/npx.c
@@ -1154,7 +1154,11 @@
{
struct env87 *penv_87;
struct envxmm *penv_xmm;
- int i;
+ struct fpacc87 *fx_reg;
+ int i, st;
+ uint64_t mantissa;
+ uint16_t tw, exp;
+ uint8_t ab_tw;
penv_87 = &sv_87->sv_env;
penv_xmm = &sv_xmm->sv_env;
@@ -1168,14 +1172,39 @@
penv_87->en_foo = penv_xmm->en_foo;
penv_87->en_fos = penv_xmm->en_fos;
- /* FPU registers and tags */
- penv_87->en_tw = 0xffff;
- for (i = 0; i < 8; ++i) {
- sv_87->sv_ac[i] = sv_xmm->sv_fp[i].fp_acc;
- if ((penv_xmm->en_tw & (1 << i)) != 0)
- /* zero and special are set as valid */
- penv_87->en_tw &= ~(3 << i * 2);
+ /*
+ * FPU registers and tags.
+ * For ST(i), i = fpu_reg - top; we start with fpu_reg=7.
+ */
+ st = 7 - ((penv_xmm->en_sw >> 11) & 7);
+ ab_tw = penv_xmm->en_tw;
+ tw = 0;
+ for (i = 0x80; i != 0; i >>= 1) {
+ sv_87->sv_ac[st] = sv_xmm->sv_fp[st].fp_acc;
+ tw <<= 2;
+ if (ab_tw & i) {
+ /* Non-empty - we need to check ST(i) */
+ fx_reg = &sv_xmm->sv_fp[st].fp_acc;
+ /* The first 64 bits contain the mantissa. */
+ mantissa = *((uint64_t *)fx_reg->fp_bytes);
+ /*
+ * The final 16 bits contain the sign bit and the exponent.
+ * Mask the sign bit since it is of no consequence to these
+ * tests.
+ */
+ exp = *((uint16_t *)&fx_reg->fp_bytes[8]) & 0x7fff;
+ if (exp == 0) {
+ if (mantissa == 0)
+ tw |= 1; /* Zero */
+ else
+ tw |= 2; /* Denormal */
+ } else if (exp == 0x7fff)
+ tw |= 2; /* Infinity or NaN */
+ } else
+ tw |= 3; /* Empty */
+ st = (st - 1) & 7;
}
+ penv_87->en_tw = tw;
}
void
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sat, Dec 13, 1:32 AM (9 h, 35 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
26917483
Default Alt Text
D26856.id78519.diff (3 KB)
Attached To
Mode
D26856: Improve FPU Tag Word reconstruction on i386 to indicate register states
Attached
Detach File
Event Timeline
Log In to Comment