fprem

Partial Remainder

FPREM

Computes remainder of ST(0) / ST(1).

Details

Computes the IEEE partial remainder of ST(0) divided by ST(1), storing the result in ST(0). This instruction performs an iterative reduction and may require multiple iterations to complete; the C2 flag indicates whether the result is incomplete (more iterations needed). The x87 status flags (C0, C1, C2, C3) encode the sign and partial quotient information.

Pseudocode Operation

quotient ← ST(0) ÷ ST(1);
remainder ← ST(0) - (rounded_quotient × ST(1));
ST(0) ← remainder;
C0, C1, C2, C3 ← encode_quotient_and_status(quotient, remainder);

Example

FPREM

Encoding

Binary Layout
D9
+0
F8
+1
 
Format Legacy
Opcode D9 F8
Extension x87 FPU

Operands

Reference (Intel® SDM)

Instruction Forms

Opcode Instruction Op/En 64/32-bit Mode CPUID Description
D9 F8 FPREM Valid Valid Replace ST(0) with the remainder obtained from dividing ST(0) by ST(1).

Description

Computes the remainder obtained from dividing the value in the ST(0) register (the dividend) by the value in the ST(1) register (the divisor or modulus), and stores the result in ST(0). The remainder represents the following value: Remainder := ST(0) − (Q ∗ ST(1)) Here, Q is an integer value that is obtained by truncating the floating-point number quotient of [ST(0) / ST(1)] toward zero. The sign of the remainder is the same as the sign of the dividend. The magnitude of the remainder is less than that of the modulus, unless a partial remainder was computed (as described below). This instruction produces an exact result; the inexact-result exception does not occur and the rounding control has no effect. The following table shows the results obtained when computing the remainder of various classes of numbers, assuming that underflow does not occur. Table 3-33. FPREM Results ST(1) -∞ -F -0 +0 +F +∞ NaN -∞ * * * * * * NaN ST(0) -F ST(0) -F or -0 * * -F or -0 ST(0) NaN -0 -0 -0 * * -0 -0 NaN +0 +0 +0 * * +0 +0 NaN +F ST(0) +F or +0 * * +F or +0 ST(0) NaN +∞ * * * * * * NaN NaN NaN NaN NaN NaN NaN NaN NaN

Operation

D := exponent(ST(0)) – exponent(ST(1));
IF D < 64
THEN
Q := Integer(TruncateTowardZero(ST(0) / ST(1)));
ST(0) := ST(0) – (ST(1) ∗ Q);
C2 := 0;
C0, C3, C1 := LeastSignificantBits(Q); (* Q2, Q1, Q0 *)
ELSE
C2 := 1;
N := An implementation-dependent number between 32 and 63;
QQ := Integer(TruncateTowardZero((ST(0)  / ST(1)) / 2(D − N)));
ST(0) := ST(0) – (ST(1) ∗ QQ ∗ 2(D − N));
FI;

Exceptions

Protected Mode Exceptions

#NM CR0.EM[bit 2] or CR0.TS[bit 3] = 1. #MF If there is a pending x87 FPU exception. #UD If the LOCK prefix is used.

Real-Address Mode Exceptions

Same exceptions as in protected mode.

Virtual-8086 Mode Exceptions

Same exceptions as in protected mode.

Compatibility Mode Exceptions

Same exceptions as in protected mode.

64-Bit Mode Exceptions

Same exceptions as in protected mode. FPREM—Partial Remainder Vol. 2A 3-367