Partial Remainder
Hex  Mnemonic  Encoding  Long Mode  Legacy Mode  Description 

D9 F8  FPREM  None  Valid  Valid  Replace ST(0) with the remainder obtained from dividing ST(0) by ST(1). 
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 floatingpoint 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 inexactresult 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.
DEST  

SRC 

When the result is 0, its sign is the same as that of the dividend. When the modulus is ∞, the result is equal to the value in ST(0).
The FPREM instruction does not compute the remainder specified in IEEE Std 754. The IEEE specified remainder can be computed with the FPREM1 instruction. The FPREM instruction is provided for compatibility with the Intel 8087 and Intel287 math coprocessors.
The FPREM instruction gets its name "partial remainder" because of the way it computes the remainder. This instruction arrives at a remainder through iterative subtraction. It can, however, reduce the exponent of ST(0) by no more than 63 in one execution of the instruction. If the instruction succeeds in producing a remainder that is less than the modulus, the operation is complete and the C2 flag in the FPU status word is cleared. Otherwise, C2 is set, and the result in ST(0) is called the partial remainder. The exponent of the partial remainder will be less than the exponent of the original dividend by at least 32. Software can reexecute the instruction (using the partial remainder in ST(0) as the dividend) until C2 is cleared. (Note that while executing such a remaindercomputation loop, a higherpriority interrupting routine that needs the FPU can force a context switch inbetween the instructions in the loop.)
An important use of the FPREM instruction is to reduce the arguments of periodic functions. When reduction is complete, the instruction stores the three leastsignificant bits of the quotient in the C3, C1, and C0 flags of the FPU status word. This information is important in argument reduction for the tangent function (using a modulus of π/4), because it locates the original angle in the correct one of eight sectors of the unit circle.
This instruction's operation is the same in non64bit modes and 64bit mode.
D = exponent(ST(0))  exponent(ST(1)); IF D < 64 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 implementationdependent 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;
C0 Set to bit 2 (Q2) of the quotient. C1: Set to 0 if stack underflow occurred; otherwise, set to least significant bit of quotient (Q0). C2 Set to 0 if reduction complete; set to 1 if incomplete. C3 Set to bit 1 (Q1) of the quotient.
Exception  Description 

#U  Result is too small for destination format. 
#D  Source operand is a denormal value. 
#IA  Source operand is an SNaN value, modulus is 0, dividend is ∞, or unsupported format. 
#IS  Stack underflow occurred. 
Same exceptions as in protected mode.
Same exceptions as in protected mode.
Same exceptions as in protected mode.
Same exceptions as in protected mode.
Exception  Description 

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