Skip to content

[General]: FXTRACT treats a pseudo-denormal significand as signed #46

Description

@shuklaayush

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.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions