Problem
FXTRACT separates an x87 floating-point value into its exponent and its significand, the
part containing its significant digits. The 80-bit x87 format also permits a
representation called a pseudo-denormal: its stored exponent is zero, but its explicit
leading significand bit is 1. The manual says to treat it as the corresponding value
with stored exponent 1.
The source helper instead passes the significand bits through a signed-integer
conversion. Because the top bit is 1, that conversion treats the input as negative and
changes its magnitude. Restoring the original floating-point sign afterward does not
undo that change.
For the example below, the extracted significand should be 1.5, but the source produces
1.0. The code responsible is:
result1 := FP87::Convert_From_Integer(x.Mantissa);
result1.Exponent := f80_bias;
result1.Sign := x.Sign;
Reproducing case
Use 64-bit mode with x87 enabled: CR0.EM=0 and CR0.TS=0 allow these instructions to
execute with x87 enabled. ST(0) is the top x87 register and
ST(1) is the next. The control word selects rounding and which exceptions are masked.
“Masked” means the instruction uses the defined fallback behavior for that exception.
Use FXRSTOR, the instruction that restores saved floating-point state, to install raw
80-bit value 0000c000000000000000 directly as ST(0), with ST(0) nonempty, ST(7) empty
so that the instruction has room to push its second result, control word 0x037f, and
no pending exceptions. Execute FXTRACT (D9 F4).
The source helper returns significand 1.0.
Each 20-digit hexadecimal input specifies the exact 80-bit x87 register contents.
Source checked: Intel SDM executable specification revision
d307f89f742765865b87c5d4d23f552b3c72e871.
Separate hardware test
A separate hardware test on an AMD EPYC-Milan processor returned significand 1.5.
The source and hardware results have the same exponent.
Manual reference
References use Intel SDM 325462-089US, October 2025.
Intel SDM Volume 1, section 8.2.2, page 8-14 (PDF page 222)
says pseudo-denormals are handled by “considering the biased exponent as 1”
and “treated as denormals and a denormal exception is generated.” Volume 2A,
FXTRACT, page 3-413 (PDF page 1109) says the extracted value retains the source
sign and significand.
Proposed fix
Use the existing FP87::Normalize(x) helper to form the significand, then set its
exponent to 0x3fff and retain x.Sign. The existing exponent calculation and denormal
exception remain in place.
AI disclosure
Assisted-by: Codex
Codex assisted with source analysis, test review, and drafting this report.
Source links
Current helper pages:
FP87::Extract.
Problem
FXTRACT separates an x87 floating-point value into its exponent and its significand, the
part containing its significant digits. The 80-bit x87 format also permits a
representation called a pseudo-denormal: its stored exponent is zero, but its explicit
leading significand bit is 1. The manual says to treat it as the corresponding value
with stored exponent 1.
The source helper instead passes the significand bits through a signed-integer
conversion. Because the top bit is 1, that conversion treats the input as negative and
changes its magnitude. Restoring the original floating-point sign afterward does not
undo that change.
For the example below, the extracted significand should be 1.5, but the source produces
1.0. The code responsible is:
Reproducing case
Use 64-bit mode with x87 enabled: CR0.EM=0 and CR0.TS=0 allow these instructions to
execute with x87 enabled. ST(0) is the top x87 register and
ST(1) is the next. The control word selects rounding and which exceptions are masked.
“Masked” means the instruction uses the defined fallback behavior for that exception.
Use FXRSTOR, the instruction that restores saved floating-point state, to install raw
80-bit value
0000c000000000000000directly as ST(0), with ST(0) nonempty, ST(7) emptyso that the instruction has room to push its second result, control word
0x037f, andno pending exceptions. Execute FXTRACT (
D9 F4).The source helper returns significand 1.0.
Each 20-digit hexadecimal input specifies the exact 80-bit x87 register contents.
Source checked: Intel SDM executable specification revision
d307f89f742765865b87c5d4d23f552b3c72e871.Separate hardware test
A separate hardware test on an AMD EPYC-Milan processor returned significand 1.5.
The source and hardware results have the same exponent.
Manual reference
References use Intel SDM 325462-089US, October 2025.
Intel SDM Volume 1, section 8.2.2, page 8-14 (PDF page 222)
says pseudo-denormals are handled by “considering the biased exponent as 1”
and “treated as denormals and a denormal exception is generated.” Volume 2A,
FXTRACT, page 3-413 (PDF page 1109) says the extracted value retains the source
sign and significand.
Proposed fix
Use the existing
FP87::Normalize(x)helper to form the significand, then set itsexponent to
0x3fffand retainx.Sign. The existing exponent calculation and denormalexception remain in place.
AI disclosure
Assisted-by: Codex
Codex assisted with source analysis, test review, and drafting this report.
Source links
Current helper pages:
FP87::Extract.