test: mips/floatem.c File Reference

Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

# floatem.c File Reference

`#include "ki.h"`

Go to the source code of this file.

## Classes

struct | _FP_CONTEXT_BLOCK
struct | _FP_DOUBLE_OPERAND
struct | _FP_SINGLE_OPERAND

## Defines

#define | DOUBLE_SIGNAL_NAN_MASK (1 << (53 - 32))
#define | SINGLE_SIGNAL_NAN_MASK (1 << 24)
#define | DOUBLE_QUIET_NAN_MASK (1 << (51 - 32))
#define | SINGLE_QUIET_NAN_MASK (1 << 22)
#define | DOUBLE_QUIET_NAN_PREFIX 0x7ff00000
#define | SINGLE_QUIET_NAN_PREFIX 0x7f800000
#define | COMPARE_UNORDERED_MASK (1 << 0)
#define | COMPARE_EQUAL_MASK (1 << 1)
#define | COMPARE_LESS_MASK (1 << 2)
#define | COMPARE_ORDERED_MASK (1 << 3)

## Typedefs

typedef _FP_CONTEXT_BLOCK | FP_CONTEXT_BLOCK
typedef _FP_CONTEXT_BLOCK * | PFP_CONTEXT_BLOCK
typedef _FP_DOUBLE_OPERAND | FP_DOUBLE_OPERAND
typedef _FP_DOUBLE_OPERAND * | PFP_DOUBLE_OPERAND
typedef _FP_SINGLE_OPERAND | FP_SINGLE_OPERAND
typedef _FP_SINGLE_OPERAND * | PFP_SINGLE_OPERAND

## Functions

BOOLEAN | KiDivideByZeroDouble (IN PFP_CONTEXT_BLOCK ContextBlock, IN PFP_DOUBLE_OPERAND DoubleOperand1, IN PFP_DOUBLE_OPERAND DoubleOperand2)
BOOLEAN | KiDivideByZeroSingle (IN PFP_CONTEXT_BLOCK ContextBlock, IN PFP_SINGLE_OPERAND SingleOperand1, IN PFP_SINGLE_OPERAND SingleOperand2)
BOOLEAN | KiInvalidCompareDouble (IN PFP_CONTEXT_BLOCK ContextBlock, IN BOOLEAN CheckForNan, IN PFP_DOUBLE_OPERAND DoubleOperand1, IN PFP_DOUBLE_OPERAND DoubleOperand2)
BOOLEAN | KiInvalidCompareSingle (IN PFP_CONTEXT_BLOCK ContextBlock, IN BOOLEAN CheckForNan, IN PFP_SINGLE_OPERAND SingleOperand1, IN PFP_SINGLE_OPERAND SingleOperand2)
BOOLEAN | KiInvalidOperationDouble (IN PFP_CONTEXT_BLOCK ContextBlock, IN BOOLEAN CheckForNan, IN PFP_DOUBLE_OPERAND DoubleOperand1, IN PFP_DOUBLE_OPERAND DoubleOperand2)
BOOLEAN | KiInvalidOperationLongword (IN PFP_CONTEXT_BLOCK ContextBlock, IN BOOLEAN Infinity, IN LONG Sign)
BOOLEAN | KiInvalidOperationQuadword (IN PFP_CONTEXT_BLOCK ContextBlock, IN BOOLEAN Infinity, IN LONG Sign)
BOOLEAN | KiInvalidOperationSingle (IN PFP_CONTEXT_BLOCK ContextBlock, IN BOOLEAN CheckForNan, IN PFP_SINGLE_OPERAND SingleOperand1, IN PFP_SINGLE_OPERAND SingleOperand2)
BOOLEAN | KiNormalizeDouble (IN PFP_CONTEXT_BLOCK ContextBlock, IN PFP_DOUBLE_OPERAND ResultOperand, IN ULONG StickyBits)
BOOLEAN | KiNormalizeLongword (IN PFP_CONTEXT_BLOCK ContextBlock, IN PFP_DOUBLE_OPERAND ResultOperand)
BOOLEAN | KiNormalizeQuadword (IN PFP_CONTEXT_BLOCK ContextBlock, IN PFP_DOUBLE_OPERAND ResultOperand)
BOOLEAN | KiNormalizeSingle (IN PFP_CONTEXT_BLOCK ContextBlock, IN PFP_SINGLE_OPERAND ResultOperand, IN ULONG StickyBits)
ULONG | KiSquareRootDouble (IN PULARGE_INTEGER DoubleValue)
ULONG | KiSquareRootSingle (IN PULONG SingleValue)
VOID | KiUnpackDouble (IN ULONG Source, IN PFP_CONTEXT_BLOCK ContextBlock, OUT PFP_DOUBLE_OPERAND DoubleOperand)
VOID | KiUnpackSingle (IN ULONG Source, IN PFP_CONTEXT_BLOCK ContextBlock, OUT PFP_SINGLE_OPERAND SingleOperand)
BOOLEAN | KiEmulateFloating (IN OUT PEXCEPTION_RECORD ExceptionRecord, IN OUT PKEXCEPTION_FRAME ExceptionFrame, IN OUT PKTRAP_FRAME TrapFrame)

## Define Documentation

#define COMPARE_EQUAL_MASK (1 << 1)

| Definition at line 91 of file mips/floatem.c. Referenced by KiEmulateFloating().

#define COMPARE_LESS_MASK (1 << 2)

| Definition at line 92 of file mips/floatem.c. Referenced by KiEmulateFloating().

#define COMPARE_ORDERED_MASK (1 << 3)

| Definition at line 93 of file mips/floatem.c. Referenced by KiEmulateFloating().

#define COMPARE_UNORDERED_MASK (1 << 0)

| Definition at line 90 of file mips/floatem.c. Referenced by KiEmulateFloating().

#define DOUBLE_QUIET_NAN_MASK (1 << (51 - 32))

| Definition at line 76 of file mips/floatem.c.

#define DOUBLE_QUIET_NAN_PREFIX 0x7ff00000

| Definition at line 83 of file mips/floatem.c.

#define DOUBLE_SIGNAL_NAN_MASK (1 << (53 - 32))

| Definition at line 69 of file mips/floatem.c.

#define SINGLE_QUIET_NAN_MASK (1 << 22)

| Definition at line 77 of file mips/floatem.c.

#define SINGLE_QUIET_NAN_PREFIX 0x7f800000

| Definition at line 84 of file mips/floatem.c. Referenced by KiInvalidOperationSingle().

#define SINGLE_SIGNAL_NAN_MASK (1 << 24)

| Definition at line 70 of file mips/floatem.c. Referenced by KiInvalidCompareSingle().

## Typedef Documentation

typedef struct _FP_CONTEXT_BLOCK FP_CONTEXT_BLOCK

typedef struct _FP_DOUBLE_OPERAND FP_DOUBLE_OPERAND

typedef struct _FP_SINGLE_OPERAND FP_SINGLE_OPERAND

typedef struct _FP_CONTEXT_BLOCK * PFP_CONTEXT_BLOCK

typedef struct _FP_DOUBLE_OPERAND * PFP_DOUBLE_OPERAND

typedef struct _FP_SINGLE_OPERAND * PFP_SINGLE_OPERAND

## Function Documentation

BOOLEAN KiDivideByZeroDouble | ( | IN PFP_CONTEXT_BLOCK | ContextBlock,
|  | IN PFP_DOUBLE_OPERAND | DoubleOperand1,
|  | IN PFP_DOUBLE_OPERAND | DoubleOperand2
| ) |

| Referenced by KiEmulateFloating().

BOOLEAN KiDivideByZeroSingle | ( | IN PFP_CONTEXT_BLOCK | ContextBlock,
|  | IN PFP_SINGLE_OPERAND | SingleOperand1,
|  | IN PFP_SINGLE_OPERAND | SingleOperand2
| ) |

| Referenced by KiEmulateFloating().

BOOLEAN KiEmulateFloating | ( | IN OUT PEXCEPTION_RECORD | ExceptionRecord,
|  | IN OUT PKEXCEPTION_FRAME | ExceptionFrame,
|  | IN OUT PKTRAP_FRAME | TrapFrame
| ) |

Definition at line 251 of file mips/floatem.c.

References _FP_CONTEXT_BLOCK::BranchAddress, COMPARE_EQUAL_MASK, COMPARE_LESS_MASK, COMPARE_ORDERED_MASK, COMPARE_UNORDERED_MASK, _FP_CONTEXT_BLOCK::ExceptionFrame, _FP_CONTEXT_BLOCK::ExceptionRecord, _FP_DOUBLE_OPERAND::Exponent, _FP_SINGLE_OPERAND::Exponent, FALSE, _FP_CONTEXT_BLOCK::Fd, Index, _FP_DOUBLE_OPERAND::Infinity, _FP_SINGLE_OPERAND::Infinity, KeGetCurrentPrcb, KiCopyInformation(), KiDivideByZeroDouble(), KiDivideByZeroSingle(), KiEmulateBranch(), KiGetRegisterValue(), KiInvalidCompareDouble(), KiInvalidCompareSingle(), KiInvalidOperationDouble(), KiInvalidOperationLongword(), KiInvalidOperationQuadword(), KiInvalidOperationSingle(), KiNormalizeDouble(), KiNormalizeLongword(), KiNormalizeQuadword(), KiNormalizeSingle(), KiSquareRootDouble(), KiSquareRootSingle(), KiUnpackDouble(), KiUnpackSingle(), _FP_DOUBLE_OPERAND::Mantissa, _FP_SINGLE_OPERAND::Mantissa, _FP_DOUBLE_OPERAND::MantissaHigh, _FP_DOUBLE_OPERAND::MantissaLow, _FP_DOUBLE_OPERAND::Nan, _FP_SINGLE_OPERAND::Nan, _FP_CONTEXT_BLOCK::Round, _FP_DOUBLE_OPERAND::Sign, _FP_SINGLE_OPERAND::Sign, _FP_CONTEXT_BLOCK::TrapFrame, and TRUE.

Referenced by KiDispatchException(), and KiFloatingException().

    00259                    :
    00260
    00261     This function is called to emulate a floating operation and convert the
    00262     exception status to the proper value. If the exception is an unimplemented
    00263     operation, then the operation is emulated. Otherwise, the status code is
    00264     just converted to its proper value.
    00265
    00266 Arguments:
    00267
    00268     ExceptionRecord - Supplies a pointer to an exception record.
    00269
    00270     ExceptionFrame - Supplies a pointer to an exception frame.
    00271
    00272     TrapFrame - Supplies a pointer to a trap frame.
    00273
    00274 Return Value:
    00275
    00276     A value of TRUE is returned if the floating exception is successfully
    00277     emulated. Otherwise, a value of FALSE is returned.
    00278
    00279 --*/
    00280
    00281 {
    00282
    00283     ULARGE_INTEGER AhighBhigh;
    00284     ULARGE_INTEGER AhighBlow;
    00285     ULARGE_INTEGER AlowBhigh;
    00286     ULARGE_INTEGER AlowBlow;
    00287     ULONG Carry1;
    00288     ULONG Carry2;
    00289     BOOLEAN CompareEqual;
    00290     ULONG CompareFunction;
    00291     BOOLEAN CompareLess;
    00292     FP_CONTEXT_BLOCK ContextBlock;
    00293     LARGE_INTEGER DoubleDividend;
    00294     LARGE_INTEGER DoubleDivisor;
    00295     ULARGE_INTEGER DoubleValue;
    00296     ULONG DoubleMantissaLow;
    00297     LONG DoubleMantissaHigh;
    00298     FP_DOUBLE_OPERAND DoubleOperand1;
    00299     FP_DOUBLE_OPERAND DoubleOperand2;
    00300     FP_DOUBLE_OPERAND DoubleOperand3;
    00301     LARGE_INTEGER DoubleQuotient;
    00302     PVOID ExceptionAddress;
    00303     ULONG ExponentDifference;
    00304     ULONG ExponentSum;
    00305     ULONG Format;
    00306     ULONG Fs;
    00307     ULONG Ft;
    00308     ULONG Function;
    00309     ULONG Index;
    00310     MIPS_INSTRUCTION Instruction;
    00311     ULARGE_INTEGER LargeResult;
    00312     LONG Longword;
    00313     LONG Negation;
    00314     union {
    00315         LONGLONG Quadword;
    00316         LARGE_INTEGER LargeValue;
    00317     }u;
    00318
    00319     LONG SingleMantissa;
    00320     FP_SINGLE_OPERAND SingleOperand1;
    00321     FP_SINGLE_OPERAND SingleOperand2;
    00322     FP_SINGLE_OPERAND SingleOperand3;
    00323     ULONG SingleValue;
    00324     ULONG StickyBits;
    00325
    00326     //
    00327     // Save the original exception address in case another exception
    00328     // occurs.
    00329     //
    00330
    00331     ExceptionAddress = ExceptionRecord->ExceptionAddress;
    00332
    00333     //
    00334     // Any exception that occurs during the attempted emulation of the
    00335     // floating operation causes the emulation to be aborted. The new
    00336     // exception code and information is copied to the original exception
    00337     // record and a value of FALSE is returned.
    00338     //
    00339
    00340     try {
    00341
    00342         //
    00343         // If the exception PC is equal to the fault instruction address
    00344         // plus four, then the floating exception occurred in the delay
    00345         // slot of a branch instruction and the continuation address must
    00346         // be computed by emulating the branch instruction. Note that it
    00347         // is possible for an exception to occur when the branch instruction
    00348         // is read from user memory.
    00349         //
    00350
    00351         if ((TrapFrame->Fir + 4) == (ULONG)ExceptionRecord->ExceptionAddress) {
    00352             ContextBlock.BranchAddress = KiEmulateBranch(ExceptionFrame,
    00353                                                          TrapFrame);
    00354
    00355         } else {
    00356             ContextBlock.BranchAddress = TrapFrame->Fir + 4;
    00357         }
    00358
    00359         //
    00360         // Increment the floating emulation count.
    00361         //
    00362
    00363         KeGetCurrentPrcb()->KeFloatingEmulationCount += 1;
    00364
    00365         //
    00366         // Initialize the address of the exception record, exception frame,
    00367         // and trap frame in the context block used during the emulation of
    00368         // the floating point operation.
    00369         //
    00370
    00371         ContextBlock.ExceptionRecord = ExceptionRecord;
    00372         ContextBlock.ExceptionFrame = ExceptionFrame;
    00373         ContextBlock.TrapFrame = TrapFrame;
    00374         ContextBlock.Round = ((PFSR)&TrapFrame->Fsr)->RM;
    00375
    00376         //
    00377         // Initialize the number of exception information parameters, set
    00378         // the branch address, and clear the IEEE exception value.
    00379         //
    00380
    00381         ExceptionRecord->NumberParameters = 6;
    00382         ExceptionRecord->ExceptionInformation[0] = 0;
    00383         ExceptionRecord->ExceptionInformation[1] = ContextBlock.BranchAddress;
    00384         ExceptionRecord->ExceptionInformation[2] = 0;
    00385         ExceptionRecord->ExceptionInformation[3] = 0;
    00386         ExceptionRecord->ExceptionInformation[4] = 0;
    00387         ExceptionRecord->ExceptionInformation[5] = 0;
    00388
    00389         //
    00390         // Clear all exception flags and emulate the floating point operation
    00391         // The return value is dependent on the results of the emulation.
    00392         //
    00393
    00394         TrapFrame->Fsr &= ~(0x3f << 12);
    00395         Instruction = *((PMIPS_INSTRUCTION)ExceptionRecord->ExceptionAddress);
    00396         Function = Instruction.c_format.Function;
    00397         ContextBlock.Fd = Instruction.c_format.Fd;
    00398         Fs = Instruction.c_format.Fs;
    00399         Ft = Instruction.c_format.Ft;
    00400         Format = Instruction.c_format.Format;
    00401         Negation = 0;
    00402
    00403         //
    00404         // Check for illegal register specification or format code.
    00405         //
    00406
    00407         if (((ContextBlock.Fd & 0x1) != 0) || ((Fs & 0x1) != 0) || ((Ft & 0x1) != 0) ||
    00408             ((Format != FORMAT_LONGWORD) && (Format != FORMAT_QUADWORD) && (Format > FORMAT_DOUBLE))) {
    00409             Function = FLOAT_ILLEGAL;
    00410         }
    00411
    00412         //
    00413         // Decode operand values and dispose with NaNs.
    00414         //
    00415
    00416         if ((Function <= FLOAT_DIVIDE) || (Function >= FLOAT_COMPARE)) {
    00417
    00418             //
    00419             // The function has two operand values.
    00420             //
    00421
    00422             if (Format == FORMAT_SINGLE) {
    00423                 KiUnpackSingle(Fs, &ContextBlock, &SingleOperand1);
    00424                 KiUnpackSingle(Ft, &ContextBlock, &SingleOperand2);
    00425
    00426                 //
    00427                 // If either operand is a NaN, then check to determine if a
    00428                 // compare instruction or other dyadic operation is being
    00429                 // performed.
    00430                 //
    00431
    00432                 if ((SingleOperand1.Nan != FALSE) || (SingleOperand2.Nan != FALSE)) {
    00433                     if (Function < FLOAT_COMPARE) {
    00434
    00435                         //
    00436                         // Dyadic operation.
    00437                         //
    00438                         // Store a quite Nan if the invalid operation trap
    00439                         // is disabled, or raise an exception if the invalid
    00440                         // operation trap is enabled and either of the NaNs
    00441                         // is a signally NaN.
    00442                         //
    00443
    00444                         return KiInvalidOperationSingle(&ContextBlock,
    00445                                                         TRUE,
    00446                                                         &SingleOperand1,
    00447                                                         &SingleOperand2);
    00448
    00449                     } else {
    00450
    00451                         //
    00452                         // Compare operation.
    00453                         //
    00454                         // Set the condition based on the predicate of
    00455                         // the floating comparison.
    00456                         //
    00457                         // If the compare is a signaling compare, then
    00458                         // raise an exception if the invalid operation
    00459                         // trap is enabled. Otherwise, raise an exception
    00460                         // if one of the operands is a signaling NaN.
    00461                         //
    00462
    00463                         if ((Function & COMPARE_UNORDERED_MASK) != 0) {
    00464                             ((PFSR)&TrapFrame->Fsr)->CC = 1;
    00465
    00466                         } else {
    00467                             ((PFSR)&TrapFrame->Fsr)->CC = 0;
    00468                         }
    00469
    00470                         if ((Function & COMPARE_ORDERED_MASK) != 0) {
    00471                             return KiInvalidCompareSingle(&ContextBlock,
    00472                                                           FALSE,
    00473                                                           &SingleOperand1,
    00474                                                           &SingleOperand2);
    00475
    00476                         } else {
    00477                             return KiInvalidCompareSingle(&ContextBlock,
    00478                                                           TRUE,
    00479                                                           &SingleOperand1,
    00480                                                           &SingleOperand2);
    00481
    00482                         }
    00483                     }
    00484
    00485                 } else if (Function >= FLOAT_COMPARE) {
    00486                     CompareFunction = Function;
    00487                     Function = FLOAT_COMPARE_SINGLE;
    00488                 }
    00489
    00490             } else if (Format == FORMAT_DOUBLE) {
    00491                 KiUnpackDouble(Fs, &ContextBlock, &DoubleOperand1);
    00492                 KiUnpackDouble(Ft, &ContextBlock, &DoubleOperand2);
    00493
    00494                 //
    00495                 // If either operand is a NaN, then check to determine if a
    00496                 // compare instruction or other dyadic operation is being
    00497                 // performed.
    00498                 //
    00499
    00500                 if ((DoubleOperand1.Nan != FALSE) || (DoubleOperand2.Nan != FALSE)) {
    00501                     if (Function < FLOAT_COMPARE) {
    00502
    00503                         //
    00504                         // Dyadic operation.
    00505                         //
    00506                         // Store a quite Nan if the invalid operation trap
    00507                         // is disabled, or raise an exception if the invalid
    00508                         // operation trap is enabled and either of the NaNs
    00509                         // is a signally NaN.
    00510                         //
    00511
    00512                         return KiInvalidOperationDouble(&ContextBlock,
    00513                                                         TRUE,
    00514                                                         &DoubleOperand1,
    00515                                                         &DoubleOperand2);
    00516
    00517                     } else {
    00518
    00519                         //
    00520                         // Compare operation.
    00521                         //
    00522                         // Set the condition based on the predicate of
    00523                         // the floating comparison.
    00524                         //
    00525                         // If the compare is a signaling compare, then
    00526                         // raise an exception if the invalid operation
    00527                         // trap is enabled. Othersie, raise an exception
    00528                         // if one of the operands is a signaling NaN.
    00529                         //
    00530
    00531                         if ((Function & COMPARE_UNORDERED_MASK) != 0) {
    00532                             ((PFSR)&TrapFrame->Fsr)->CC = 1;
    00533
    00534                         } else {
    00535                             ((PFSR)&TrapFrame->Fsr)->CC = 0;
    00536                         }
    00537
    00538                         if ((Function & COMPARE_ORDERED_MASK) != 0) {
    00539                             return KiInvalidCompareDouble(&ContextBlock,
    00540                                                           FALSE,
    00541                                                           &DoubleOperand1,
    00542                                                           &DoubleOperand2);
    00543
    00544                         } else {
    00545                             return KiInvalidCompareDouble(&ContextBlock,
    00546                                                           TRUE,
    00547                                                           &DoubleOperand1,
    00548                                                           &DoubleOperand2);
    00549
    00550                         }
    00551                     }
    00552
    00553                 } else if (Function >= FLOAT_COMPARE) {
    00554                     CompareFunction = Function;
    00555                     Function = FLOAT_COMPARE_DOUBLE;
    00556                 }
    00557
    00558             } else {
    00559                 Function = FLOAT_ILLEGAL;
    00560             }
    00561
    00562         } else {
    00563
    00564             //
    00565             // The function has one operand value.
    00566             //
    00567
    00568             if (Format == FORMAT_SINGLE) {
    00569                 KiUnpackSingle(Fs, &ContextBlock, &SingleOperand1);
    00570
    00571                 //
    00572                 // If the operand is a NaN and the function is not a convert
    00573                 // operation, then store a quiet NaN if the invalid operation
    00574                 // trap is disabled, or raise an exception if the invalid
    00575                 // operation trap is enabled and the operand is a signaling
    00576                 // NaN.
    00577                 //
    00578
    00579                 if ((SingleOperand1.Nan != FALSE) &&
    00580                     (Function < FLOAT_ROUND_QUADWORD) ||
    00581                     (Function > FLOAT_CONVERT_QUADWORD) ||
    00582                     ((Function > FLOAT_FLOOR_LONGWORD) &&
    00583                     (Function < FLOAT_CONVERT_SINGLE))) {
    00584                     return KiInvalidOperationSingle(&ContextBlock,
    00585                                                     TRUE,
    00586                                                     &SingleOperand1,
    00587                                                     &SingleOperand1);
    00588
    00589                 }
    00590
    00591             } else if (Format == FORMAT_DOUBLE) {
    00592                 KiUnpackDouble(Fs, &ContextBlock, &DoubleOperand1);
    00593
    00594                 //
    00595                 // If the operand is a NaN and the function is not a convert
    00596                 // operation, then store a quiet NaN if the invalid operation
    00597                 // trap is disabled, or raise an exception if the invalid
    00598                 // operation trap is enabled and the operand is a signaling
    00599                 // NaN.
    00600                 //
    00601
    00602                 if ((DoubleOperand1.Nan != FALSE) &&
    00603                     (Function < FLOAT_ROUND_QUADWORD) ||
    00604                     (Function > FLOAT_CONVERT_QUADWORD) ||
    00605                     ((Function > FLOAT_FLOOR_LONGWORD) &&
    00606                     (Function < FLOAT_CONVERT_SINGLE))) {
    00607                     return KiInvalidOperationDouble(&ContextBlock,
    00608                                                     TRUE,
    00609                                                     &DoubleOperand1,
    00610                                                     &DoubleOperand1);
    00611                 }
    00612
    00613             } else if ((Format == FORMAT_LONGWORD) &&
    00614                        (Function >= FLOAT_CONVERT_SINGLE)) {
    00615                 Longword = KiGetRegisterValue(Fs + 32,
    00616                                               ContextBlock.ExceptionFrame,
    00617                                               ContextBlock.TrapFrame);
    00618
    00619             } else if ((Format == FORMAT_QUADWORD) &&
    00620                        (Function >= FLOAT_CONVERT_SINGLE)) {
    00621                 u.LargeValue.LowPart = KiGetRegisterValue(Fs + 32,
    00622                                                           ContextBlock.ExceptionFrame,
    00623                                                           ContextBlock.TrapFrame);
    00624
    00625                 u.LargeValue.HighPart = KiGetRegisterValue(Fs + 33,
    00626                                                            ContextBlock.ExceptionFrame,
    00627                                                            ContextBlock.TrapFrame);
    00628
    00629             } else {
    00630                 Function = FLOAT_ILLEGAL;
    00631             }
    00632         }
    00633
    00634         //
    00635         // Case to the proper function routine to emulate the operation.
    00636         //
    00637
    00638         switch (Function) {
    00639
    00640             //
    00641             // Floating subtract operation.
    00642             //
    00643             // Floating subtract is accomplished by complementing the sign
    00644             // of the second operand and then performing an add operation.
    00645             //
    00646
    00647         case FLOAT_SUBTRACT:
    00648             Negation = 0x1;
    00649
    00650             //
    00651             // Floating add operation.
    00652             //
    00653             // Floating add is accomplished using signed magnitude addition.
    00654             //
    00655             // The exponent difference is calculated and the smaller number
    00656             // is right shifted by the specified amount, but no more than
    00657             // the width of the operand values (i.e., 26 for single and 55
    00658             // for double). The shifted out value is saved for rounding.
    00659             //
    00660             // If the signs of the two operands are the same, then they
    00661             // are added together after having performed the alignment
    00662             // shift.
    00663             //
    00664             // If the signs of the two operands are different, then the
    00665             // sign of the result is the sign of the larger operand and
    00666             // the smaller operand is subtracted from the larger operand.
    00667             // In order to avoid making a double level test (i.e., one on
    00668             // the exponents, and one on the mantissas if the exponents
    00669             // are equal), it is posible that the result of the subtract
    00670             // could be negative (if the exponents are equal). If this
    00671             // occurs, then the result sign and mantissa are complemented
    00672             // to obtain the correct result.
    00673             //
    00674
    00675         case FLOAT_ADD:
    00676             if (Format == FORMAT_SINGLE) {
    00677
    00678                 //
    00679                 // Complement the sign of the second operand if the operation
    00680                 // is subtraction.
    00681                 //
    00682
    00683                 SingleOperand2.Sign ^= Negation;
    00684
    00685                 //
    00686                 // Reorder then operands according to their exponent value.
    00687                 //
    00688
    00689                 if (SingleOperand2.Exponent > SingleOperand1.Exponent) {
    00690                     SingleOperand3 = SingleOperand2;
    00691                     SingleOperand2 = SingleOperand1;
    00692                     SingleOperand1 = SingleOperand3;
    00693                 }
    00694
    00695                 //
    00696                 // Compute the exponent difference and shift the smaller
    00697                 // mantissa right by the difference value or 26 which ever
    00698                 // is smaller. The bits shifted out are termed the sticky
    00699                 // bits and are used later in the rounding operation.
    00700                 //
    00701
    00702                 ExponentDifference =
    00703                             SingleOperand1.Exponent - SingleOperand2.Exponent;
    00704
    00705                 if (ExponentDifference > 26) {
    00706                     ExponentDifference = 26;
    00707                 }
    00708
    00709                 StickyBits =
    00710                         SingleOperand2.Mantissa & ((1 << ExponentDifference) - 1);
    00711                 SingleMantissa = SingleOperand2.Mantissa >> ExponentDifference;
    00712
    00713                 //
    00714                 // If the operands both have the same sign, then perform the
    00715                 // operation by adding the values together. Otherwise, perform
    00716                 // the operation by subtracting the second operand from the
    00717                 // first operand.
    00718                 //
    00719
    00720                 if ((SingleOperand1.Sign ^ SingleOperand2.Sign) == 0) {
    00721                     SingleOperand1.Mantissa += SingleMantissa;
    00722
    00723                 } else {
    00724                     if ((SingleOperand1.Infinity != FALSE) &&
    00725                         (SingleOperand2.Infinity != FALSE)) {
    00726                         return KiInvalidOperationSingle(&ContextBlock,
    00727                                                         FALSE,
    00728                                                         &SingleOperand1,
    00729                                                         &SingleOperand2);
    00730
    00731                     } else if (SingleOperand1.Infinity == FALSE) {
    00732                         if (StickyBits != 0) {
    00733                             SingleOperand1.Mantissa -= 1;
    00734                         }
    00735
    00736                         SingleOperand1.Mantissa -= SingleMantissa;
    00737                         if (SingleOperand1.Mantissa < 0) {
    00738                             SingleOperand1.Mantissa = -SingleOperand1.Mantissa;
    00739                             SingleOperand1.Sign ^= 0x1;
    00740                         }
    00741                     }
    00742                 }
    00743
    00744                 //
    00745                 // Normalize and store the result value.
    00746                 //
    00747
    00748                 return KiNormalizeSingle(&ContextBlock,
    00749                                          &SingleOperand1,
    00750                                          StickyBits);
    00751
    00752             } else if (Format == FORMAT_DOUBLE) {
    00753
    00754                 //
    00755                 // Complement the sign of the second operand if the operation
    00756                 // is subtraction.
    00757                 //
    00758
    00759                 DoubleOperand2.Sign ^= Negation;
    00760
    00761                 //
    00762                 // Reorder then operands according to their exponent value.
    00763                 //
    00764
    00765                 if (DoubleOperand2.Exponent > DoubleOperand1.Exponent) {
    00766                     DoubleOperand3 = DoubleOperand2;
    00767                     DoubleOperand2 = DoubleOperand1;
    00768                     DoubleOperand1 = DoubleOperand3;
    00769                 }
    00770
    00771                 //
    00772                 // Compute the exponent difference and shift the smaller
    00773                 // mantissa right by the difference value or 55 which ever
    00774                 // is smaller. The bits shifted out are termed the sticky
    00775                 // bits and are used later in the rounding operation.
    00776                 //
    00777
    00778                 ExponentDifference =
    00779                         DoubleOperand1.Exponent - DoubleOperand2.Exponent;
    00780
    00781                 if (ExponentDifference > 55) {
    00782                     ExponentDifference = 55;
    00783                 }
    00784
    00785                 if (ExponentDifference >= 32) {
    00786                     ExponentDifference -= 32;
    00787                     StickyBits = (DoubleOperand2.MantissaLow) |
    00788                         (DoubleOperand2.MantissaHigh & ((1 << ExponentDifference) - 1));
    00789
    00790                     DoubleMantissaLow =
    00791                         DoubleOperand2.MantissaHigh >> ExponentDifference;
    00792
    00793                     DoubleMantissaHigh = 0;
    00794
    00795                 } else if (ExponentDifference > 0) {
    00796                     StickyBits =
    00797                         DoubleOperand2.MantissaLow & ((1 << ExponentDifference) - 1);
    00798
    00799                     DoubleMantissaLow =
    00800                         (DoubleOperand2.MantissaLow >> ExponentDifference) |
    00801                         (DoubleOperand2.MantissaHigh << (32 - ExponentDifference));
    00802
    00803                     DoubleMantissaHigh =
    00804                         DoubleOperand2.MantissaHigh >> ExponentDifference;
    00805
    00806                 } else {
    00807                     StickyBits = 0;
    00808                     DoubleMantissaLow = DoubleOperand2.MantissaLow;
    00809                     DoubleMantissaHigh = DoubleOperand2.MantissaHigh;
    00810                 }
    00811
    00812                 //
    00813                 // If the operands both have the same sign, then perform the
    00814                 // operation by adding the values together. Otherwise, perform
    00815                 // the operation by subtracting the second operand from the
    00816                 // first operand.
    00817                 //
    00818
    00819                 if ((DoubleOperand1.Sign ^ DoubleOperand2.Sign) == 0) {
    00820                     DoubleOperand1.MantissaLow += DoubleMantissaLow;
    00821                     DoubleOperand1.MantissaHigh += DoubleMantissaHigh;
    00822                     if (DoubleOperand1.MantissaLow < DoubleMantissaLow) {
    00823                         DoubleOperand1.MantissaHigh += 1;
    00824                     }
    00825
    00826                 } else {
    00827                     if ((DoubleOperand1.Infinity != FALSE) &&
    00828                         (DoubleOperand2.Infinity != FALSE)) {
    00829                         return KiInvalidOperationDouble(&ContextBlock,
    00830                                                         FALSE,
    00831                                                         &DoubleOperand1,
    00832                                                         &DoubleOperand2);
    00833
    00834                     } else if (DoubleOperand1.Infinity == FALSE) {
    00835                         if (StickyBits != 0) {
    00836                             if (DoubleOperand1.MantissaLow < 1) {
    00837                                 DoubleOperand1.MantissaHigh -= 1;
    00838                             }
    00839
    00840                             DoubleOperand1.MantissaLow -= 1;
    00841                         }
    00842
    00843                         if (DoubleOperand1.MantissaLow < DoubleMantissaLow) {
    00844                             DoubleOperand1.MantissaHigh -= 1;
    00845                         }
    00846
    00847                         DoubleOperand1.MantissaLow -= DoubleMantissaLow;
    00848                         DoubleOperand1.MantissaHigh -= DoubleMantissaHigh;
    00849                         if (DoubleOperand1.MantissaHigh < 0) {
    00850                             DoubleOperand1.MantissaLow = ~DoubleOperand1.MantissaLow + 1;
    00851                             DoubleOperand1.MantissaHigh = -DoubleOperand1.MantissaHigh;
    00852                             if (DoubleOperand1.MantissaLow != 0) {
    00853                                 DoubleOperand1.MantissaHigh -= 1;
    00854                             }
    00855
    00856                             DoubleOperand1.Sign ^= 0x1;
    00857                         }
    00858                     }
    00859                 }
    00860
    00861                 //
    00862                 // Normalize and store the result value.
    00863                 //
    00864
    00865                 return KiNormalizeDouble(&ContextBlock,
    00866                                          &DoubleOperand1,
    00867                                          StickyBits);
    00868
    00869             } else {
    00870                 break;
    00871             }
    00872
    00873             //
    00874             // Floating multiply operation.
    00875             //
    00876             // Floating multiply is accomplished using unsigned multiplies
    00877             // of the mantissa values, and adding the parital results together
    00878             // to form the total product.
    00879             //
    00880             // The two mantissa values are preshifted such that the final
    00881             // result is properly aligned.
    00882             //
    00883
    00884         case FLOAT_MULTIPLY:
    00885             if (Format == FORMAT_SINGLE) {
    00886
    00887                 //
    00888                 // Reorder the operands according to their exponent value.
    00889                 //
    00890
    00891                 if (SingleOperand2.Exponent > SingleOperand1.Exponent) {
    00892                     SingleOperand3 = SingleOperand2;
    00893                     SingleOperand2 = SingleOperand1;
    00894                     SingleOperand1 = SingleOperand3;
    00895                 }
    00896
    00897                 //
    00898                 // If the first operand is infinite and the second operand is
    00899                 // zero, then an invalid operation is specified.
    00900                 //
    00901
    00902                 if ((SingleOperand1.Infinity != FALSE) &&
    00903                     (SingleOperand2.Infinity == FALSE) &&
    00904                     (SingleOperand2.Mantissa == 0)) {
    00905                     return KiInvalidOperationSingle(&ContextBlock,
    00906                                                     FALSE,
    00907                                                     &SingleOperand1,
    00908                                                     &SingleOperand2);
    00909
    00910                 }
    00911
    00912                 //
    00913                 // Preshift the operand mantissas so the result will be a
    00914                 // properly aligned 64-bit value and then unsigned multiply
    00915                 // the two mantissa values. The single result is the high part
    00916                 // of the 64-bit product and the sticky bits are the low part
    00917                 // of the 64-bit product.
    00918                 //
    00919
    00920                 LargeResult.QuadPart = UInt32x32To64(SingleOperand1.Mantissa << (32 - 26),
    00921                                                      SingleOperand2.Mantissa << 1);
    00922
    00923                 SingleOperand1.Mantissa = LargeResult.HighPart;
    00924                 StickyBits = LargeResult.LowPart;
    00925
    00926                 //
    00927                 // Compute the sign and exponent of the result.
    00928                 //
    00929
    00930                 SingleOperand1.Sign ^= SingleOperand2.Sign;
    00931                 SingleOperand1.Exponent +=
    00932                             SingleOperand2.Exponent - SINGLE_EXPONENT_BIAS;
    00933
    00934                 //
    00935                 // Normalize and store the result value.
    00936                 //
    00937
    00938                 return KiNormalizeSingle(&ContextBlock,
    00939                                          &SingleOperand1,
    00940                                          StickyBits);
    00941
    00942             } else if (Format == FORMAT_DOUBLE) {
    00943
    00944                 //
    00945                 // Reorder the operands according to their exponent value.
    00946                 //
    00947
    00948                 if (DoubleOperand2.Exponent > DoubleOperand1.Exponent) {
    00949                     DoubleOperand3 = DoubleOperand2;
    00950                     DoubleOperand2 = DoubleOperand1;
    00951                     DoubleOperand1 = DoubleOperand3;
    00952                 }
    00953
    00954                 //
    00955                 // If the first operand is infinite and the second operand is
    00956                 // zero, then an invalid operation is specified.
    00957                 //
    00958
    00959                 if ((DoubleOperand1.Infinity != FALSE) &&
    00960                     (DoubleOperand2.Infinity == FALSE) &&
    00961                     (DoubleOperand2.MantissaHigh == 0)) {
    00962                     return KiInvalidOperationDouble(&ContextBlock,
    00963                                                     FALSE,
    00964                                                     &DoubleOperand1,
    00965                                                     &DoubleOperand2);
    00966
    00967                 }
    00968
    00969                 //
    00970                 // Preshift the operand mantissas so the result will be a
    00971                 // properly aligned 128-bit value and then unsigned multiply
    00972                 // the two mantissa values. The double result is the high part
    00973                 // of the 128-bit product and the sticky bits are the low part
    00974                 // of the 128-bit product.
    00975                 //
    00976
    00977                 DoubleOperand1.MantissaHigh =
    00978                         (DoubleOperand1.MantissaHigh << 1) |
    00979                                 (DoubleOperand1.MantissaLow >> 31);
    00980
    00981                 DoubleOperand1.MantissaLow <<= 1;
    00982                 DoubleOperand2.MantissaHigh =
    00983                         (DoubleOperand2.MantissaHigh << (64 - 55)) |
    00984                                 (DoubleOperand2.MantissaLow >> (32 - (64 -55)));
    00985
    00986                 DoubleOperand2.MantissaLow <<= (64 - 55);
    00987
    00988                 //
    00989                 // The 128-bit product is formed by mutiplying and adding
    00990                 // all the cross product values.
    00991                 //
    00992                 // Consider the operands (A and B) as being composed of two
    00993                 // parts Ahigh, Alow, Bhigh, and Blow. The cross product sum
    00994                 // is then:
    00995                 //
    00996                 //       Ahigh * Bhigh * 2^64 +
    00997                 //              Ahigh * Blow * 2^32 +
    00998                 //              Alow * Bhigh * 2^32 +
    00999                 //                              Alow * Blow
    01000                 //
    01001
    01002                 AhighBhigh.QuadPart = UInt32x32To64(DoubleOperand1.MantissaHigh,
    01003                                                     DoubleOperand2.MantissaHigh);
    01004
    01005                 AhighBlow.QuadPart = UInt32x32To64(DoubleOperand1.MantissaHigh,
    01006                                                    DoubleOperand2.MantissaLow);
    01007
    01008                 AlowBhigh.QuadPart = UInt32x32To64(DoubleOperand1.MantissaLow,
    01009                                                    DoubleOperand2.MantissaHigh);
    01010
    01011                 AlowBlow.QuadPart = UInt32x32To64(DoubleOperand1.MantissaLow,
    01012                                                   DoubleOperand2.MantissaLow);
    01013
    01014                 AlowBlow.HighPart += AhighBlow.LowPart;
    01015                 if (AlowBlow.HighPart < AhighBlow.LowPart) {
    01016                     Carry1 = 1;
    01017
    01018                 } else {
    01019                     Carry1 = 0;
    01020                 }
    01021
    01022                 AlowBlow.HighPart += AlowBhigh.LowPart;
    01023                 if (AlowBlow.HighPart < AlowBhigh.LowPart) {
    01024                     Carry1 += 1;
    01025                 }
    01026
    01027                 DoubleOperand1.MantissaLow = AhighBlow.HighPart + Carry1;
    01028                 if (DoubleOperand1.MantissaLow < Carry1) {
    01029                     Carry2 = 1;
    01030
    01031                 } else {
    01032                     Carry2 = 0;
    01033                 }
    01034
    01035                 DoubleOperand1.MantissaLow += AlowBhigh.HighPart;
    01036                 if (DoubleOperand1.MantissaLow < AlowBhigh.HighPart) {
    01037                     Carry2 += 1;
    01038                 }
    01039
    01040                 DoubleOperand1.MantissaLow += AhighBhigh.LowPart;
    01041                 if (DoubleOperand1.MantissaLow < AhighBhigh.LowPart) {
    01042                     Carry2 += 1;
    01043                 }
    01044
    01045                 DoubleOperand1.MantissaHigh = AhighBhigh.HighPart + Carry2;
    01046                 StickyBits = AlowBlow.HighPart | AlowBlow.LowPart;
    01047
    01048                 //
    01049                 // Compute the sign and exponent of the result.
    01050                 //
    01051
    01052                 DoubleOperand1.Sign ^= DoubleOperand2.Sign;
    01053                 DoubleOperand1.Exponent +=
    01054                             DoubleOperand2.Exponent - DOUBLE_EXPONENT_BIAS;
    01055
    01056                 //
    01057                 // Normalize and store the result value.
    01058                 //
    01059
    01060                 return KiNormalizeDouble(&ContextBlock,
    01061                                          &DoubleOperand1,
    01062                                          StickyBits);
    01063
    01064             } else {
    01065                 break;
    01066             }
    01067
    01068             //
    01069             // Floating divide operation.
    01070             //
    01071             // Floating division is accomplished by repeated subtract using
    01072             // a single one-bit-at-a-time algorithm. The number of division
    01073             // steps performed is equal to the mantissa size plus one guard
    01074             // bit.
    01075             //
    01076             // The sticky bits are the remainder after the specified number
    01077             // of division steps.
    01078             //
    01079
    01080         case FLOAT_DIVIDE:
    01081             if (Format == FORMAT_SINGLE) {
    01082
    01083                 //
    01084                 // If the first operand is infinite and the second operand
    01085                 // is infinite, or both operands are zero, then an invalid
    01086                 // operation is specified.
    01087                 //
    01088
    01089                 if (((SingleOperand1.Infinity != FALSE) &&
    01090                     (SingleOperand2.Infinity != FALSE)) ||
    01091                     ((SingleOperand1.Infinity == FALSE) &&
    01092                     (SingleOperand1.Mantissa == 0) &&
    01093                     (SingleOperand2.Infinity == FALSE) &&
    01094                     (SingleOperand2.Mantissa == 0))) {
    01095                     return KiInvalidOperationSingle(&ContextBlock,
    01096                                                     FALSE,
    01097                                                     &SingleOperand1,
    01098                                                     &SingleOperand2);
    01099
    01100                 }
    01101
    01102                 //
    01103                 // If the second operand is zero, then a divide by zero
    01104                 // operation is specified.
    01105                 //
    01106
    01107                 if ((SingleOperand2.Infinity == FALSE) &&
    01108                     (SingleOperand2.Mantissa == 0)) {
    01109                     return KiDivideByZeroSingle(&ContextBlock,
    01110                                                 &SingleOperand1,
    01111                                                 &SingleOperand2);
    01112                 }
    01113
    01114                 //
    01115                 // If the first operand is infinite, then the result is
    01116                 // infinite. Otherwise, if the second operand is infinite,
    01117                 // then the result is zero (note that both operands cannot
    01118                 // be infinite).
    01119                 //
    01120
    01121                 if (SingleOperand1.Infinity != FALSE) {
    01122                     SingleOperand1.Sign ^= SingleOperand2.Sign;
    01123                     return KiNormalizeSingle(&ContextBlock,
    01124                                              &SingleOperand1,
    01125                                              0);
    01126
    01127                 } else if (SingleOperand2.Infinity != FALSE) {
    01128                     SingleOperand1.Sign ^= SingleOperand2.Sign;
    01129                     SingleOperand1.Exponent = 0;
    01130                     SingleOperand1.Mantissa = 0;
    01131                     return KiNormalizeSingle(&ContextBlock,
    01132                                              &SingleOperand1,
    01133                                              0);
    01134
    01135                 }
    01136
    01137                 //
    01138                 // Perform divide operation by repeating a single bit
    01139                 // divide step 26 iterations.
    01140                 //
    01141
    01142                 SingleOperand3.Mantissa = 0;
    01143                 for (Index = 0; Index < 26; Index += 1) {
    01144                     SingleOperand3.Mantissa <<=1;
    01145                     if (SingleOperand1.Mantissa >= SingleOperand2.Mantissa) {
    01146                         SingleOperand1.Mantissa -= SingleOperand2.Mantissa;
    01147                         SingleOperand3.Mantissa |= 1;
    01148                     }
    01149
    01150                     SingleOperand1.Mantissa <<= 1;
    01151                 }
    01152
    01153                 //
    01154                 // Compute the sign and exponent of the result.
    01155                 //
    01156
    01157                 SingleOperand3.Sign = SingleOperand1.Sign ^ SingleOperand2.Sign;
    01158                 SingleOperand3.Exponent = SingleOperand1.Exponent -
    01159                                 SingleOperand2.Exponent + SINGLE_EXPONENT_BIAS;
    01160
    01161                 //
    01162                 // Normalize and store the result value.
    01163                 //
    01164
    01165                 SingleOperand3.Infinity = FALSE;
    01166                 SingleOperand3.Nan = FALSE;
    01167                 return KiNormalizeSingle(&ContextBlock,
    01168                                          &SingleOperand3,
    01169                                          SingleOperand1.Mantissa);
    01170
    01171             } else if (Format == FORMAT_DOUBLE) {
    01172
    01173                 //
    01174                 // If the first operand is infinite and the second operand
    01175                 // is infinite, or both operands are zero, then an invalid
    01176                 // operation is specified.
    01177                 //
    01178
    01179                 if (((DoubleOperand1.Infinity != FALSE) &&
    01180                     (DoubleOperand2.Infinity != FALSE)) ||
    01181                     ((DoubleOperand1.Infinity == FALSE) &&
    01182                     (DoubleOperand1.MantissaHigh == 0) &&
    01183                     (DoubleOperand2.Infinity == FALSE) &&
    01184                     (DoubleOperand2.MantissaHigh == 0))) {
    01185                     return KiInvalidOperationDouble(&ContextBlock,
    01186                                                     FALSE,
    01187                                                     &DoubleOperand1,
    01188                                                     &DoubleOperand2);
    01189
    01190                 }
    01191
    01192                 //
    01193                 // If the second operand is zero, then a divide by zero
    01194                 // operation is specified.
    01195                 //
    01196
    01197                 if ((DoubleOperand2.Infinity == FALSE) &&
    01198                     (DoubleOperand2.MantissaHigh == 0)) {
    01199                     return KiDivideByZeroDouble(&ContextBlock,
    01200                                                 &DoubleOperand1,
    01201                                                 &DoubleOperand2);
    01202                 }
    01203
    01204                 //
    01205                 // If the first operand is infinite, then the result is
    01206                 // infinite. Otherwise, if the second operand is infinite,
    01207                 // then the result is zero (note that both operands cannot
    01208                 // be infinite).
    01209                 //
    01210
    01211                 if (DoubleOperand1.Infinity != FALSE) {
    01212                     DoubleOperand1.Sign ^= DoubleOperand2.Sign;
    01213                     return KiNormalizeDouble(&ContextBlock,
    01214                                              &DoubleOperand1,
    01215                                              0);
    01216
    01217                 } else if (DoubleOperand2.Infinity != FALSE) {
    01218                     DoubleOperand1.Sign ^= DoubleOperand2.Sign;
    01219                     DoubleOperand1.Exponent = 0;
    01220                     DoubleOperand1.MantissaHigh = 0;
    01221                     DoubleOperand1.MantissaLow = 0;
    01222                     return KiNormalizeDouble(&ContextBlock,
    01223                                              &DoubleOperand1,
    01224                                              0);
    01225
    01226                 }
    01227
    01228                 //
    01229                 // Perform divide operation by repeating a single bit
    01230                 // divide step 55 iterations.
    01231                 //
    01232
    01233                 DoubleDividend.LowPart = DoubleOperand1.MantissaLow;
    01234                 DoubleDividend.HighPart = DoubleOperand1.MantissaHigh;
    01235                 DoubleDivisor.LowPart = DoubleOperand2.MantissaLow;
    01236                 DoubleDivisor.HighPart = DoubleOperand2.MantissaHigh;
    01237                 DoubleQuotient.LowPart = 0;
    01238                 DoubleQuotient.HighPart = 0;
    01239                 for (Index = 0; Index < 55; Index += 1) {
    01240                     DoubleQuotient.HighPart =
    01241                                 (DoubleQuotient.HighPart << 1) |
    01242                                                 DoubleQuotient.LowPart >> 31;
    01243
    01244                     DoubleQuotient.LowPart <<= 1;
    01245                     if (DoubleDividend.QuadPart >= DoubleDivisor.QuadPart) {
    01246                         DoubleDividend.QuadPart -= DoubleDivisor.QuadPart;
    01247                         DoubleQuotient.LowPart |= 1;
    01248                     }
    01249
    01250                     DoubleDividend.HighPart =
    01251                                 (DoubleDividend.HighPart << 1) |
    01252                                                 DoubleDividend.LowPart >> 31;
    01253
    01254                     DoubleDividend.LowPart <<= 1;
    01255                 }
    01256
    01257                 DoubleOperand3.MantissaLow = DoubleQuotient.LowPart;
    01258                 DoubleOperand3.MantissaHigh = DoubleQuotient.HighPart;
    01259
    01260                 //
    01261                 // Compute the sign and exponent of the result.
    01262                 //
    01263
    01264                 DoubleOperand3.Sign = DoubleOperand1.Sign ^ DoubleOperand2.Sign;
    01265                 DoubleOperand3.Exponent = DoubleOperand1.Exponent -
    01266                                 DoubleOperand2.Exponent + DOUBLE_EXPONENT_BIAS;
    01267
    01268                 //
    01269                 // Normalize and store the result value.
    01270                 //
    01271
    01272                 DoubleOperand3.Infinity = FALSE;
    01273                 DoubleOperand3.Nan = FALSE;
    01274                 return KiNormalizeDouble(&ContextBlock,
    01275                                          &DoubleOperand3,
    01276                                          DoubleDividend.LowPart | DoubleDividend.HighPart);
    01277
    01278             } else {
    01279                 break;
    01280             }
    01281
    01282             //
    01283             // Floating square root.
    01284             //
    01285
    01286         case FLOAT_SQUARE_ROOT:
    01287             if (Format == FORMAT_SINGLE) {
    01288
    01289                 //
    01290                 // If the operand is plus infinity, then the result is
    01291                 // plus infinity, or if the operand is plus or minus
    01292                 // zero, then the result is plus or minus zero.
    01293                 //
    01294
    01295                 if (((SingleOperand1.Sign == 0) &&
    01296                    (SingleOperand1.Infinity != FALSE)) ||
    01297                    (SingleOperand1.Mantissa == 0)) {
    01298                     return KiNormalizeSingle(&ContextBlock,
    01299                                              &SingleOperand1,
    01300                                              0);
    01301                 }
    01302
    01303                 //
    01304                 // If the operand is negative, then the operation is
    01305                 // invalid.
    01306                 //
    01307
    01308                 if (SingleOperand1.Sign != 0) {
    01309                     return KiInvalidOperationSingle(&ContextBlock,
    01310                                                     FALSE,
    01311                                                     &SingleOperand1,
    01312                                                     &SingleOperand1);
    01313                 }
    01314
    01315                 //
    01316                 // The only case remaining that could cause an exception
    01317                 // is a denomalized source value. The square root of a
    01318                 // denormalized value is computed by:
    01319                 //
    01320                 //   1. Converting the value to a normalized value with
    01321                 //      an exponent equal to the denormalization shift count
    01322                 //      plus the bias of the exponent plus one.
    01323                 //
    01324                 //   2. Computing the square root of the value and unpacking
    01325                 //      the result.
    01326                 //
    01327                 //   3. Converting the shift count back to a normalization
    01328                 //      shift count.
    01329                 //
    01330                 //   4. Rounding and packing the resultant value.
    01331                 //
    01332                 // N.B. The square root of all denormalized number is a
    01333                 //      normalized number.
    01334                 //
    01335
    01336                 SingleOperand1.Exponent = (SINGLE_EXPONENT_BIAS + 1 +
    01337                                             SingleOperand1.Exponent) << 23;
    01338
    01339                 SingleValue = (SingleOperand1.Mantissa & ~(1 << 25)) >> 2;
    01340                 SingleValue |= SingleOperand1.Exponent;
    01341                 StickyBits = KiSquareRootSingle(&SingleValue);
    01342                 SingleOperand1.Exponent =  (SingleValue >> 23) -
    01343                                             ((SINGLE_EXPONENT_BIAS + 1) / 2);
    01344
    01345                 SingleOperand1.Mantissa = ((SingleValue &
    01346                                             0x7fffff) | 0x800000) << 2;
    01347
    01348                 return KiNormalizeSingle(&ContextBlock,
    01349                                          &SingleOperand1,
    01350                                          StickyBits);
    01351
    01352             } else if (Format == FORMAT_DOUBLE) {
    01353
    01354                 //
    01355                 // If the operand is plus infinity, then the result is
    01356                 // plus infinity, or if the operand is plus or minus
    01357                 // zero, then the result is plus or minus zero.
    01358                 //
    01359
    01360                 if (((DoubleOperand1.Sign == 0) &&
    01361                    (DoubleOperand1.Infinity != FALSE)) ||
    01362                    (DoubleOperand1.MantissaHigh == 0)) {
    01363                     return KiNormalizeDouble(&ContextBlock,
    01364                                              &DoubleOperand1,
    01365                                              0);
    01366                 }
    01367
    01368                 //
    01369                 // If the operand is negative, then the operation is
    01370                 // invalid.
    01371                 //
    01372
    01373                 if (DoubleOperand1.Sign != 0) {
    01374                     return KiInvalidOperationDouble(&ContextBlock,
    01375                                                     FALSE,
    01376                                                     &DoubleOperand1,
    01377                                                     &DoubleOperand1);
    01378                 }
    01379
    01380                 //
    01381                 // The only case remaining that could cause an exception
    01382                 // is a denomalized source value. The square root of a
    01383                 // denormalized value is computed by:
    01384                 //
    01385                 //   1. Converting the value to a normalized value with
    01386                 //      an exponent equal to the denormalization shift count
    01387                 //      plus the bias of the exponent plus one.
    01388                 //
    01389                 //   2. Computing the square root of the value and unpacking
    01390                 //      the result.
    01391                 //
    01392                 //   3. Converting the shift count back to a normalization
    01393                 //      shift count.
    01394                 //
    01395                 //   4. Rounding and packing the resultant value.
    01396                 //
    01397                 // N.B. The square root of all denormalized numbers is a
    01398                 //      normalized number.
    01399                 //
    01400
    01401                 DoubleOperand1.Exponent = (DOUBLE_EXPONENT_BIAS + 1 +
    01402                                             DoubleOperand1.Exponent) << 20;
    01403
    01404                 DoubleValue.HighPart = (DoubleOperand1.MantissaHigh & ~(1 << 22)) >> 2;
    01405                 DoubleValue.LowPart = (DoubleOperand1.MantissaHigh << 30) |
    01406                                             (DoubleOperand1.MantissaLow >> 2);
    01407
    01408                 DoubleValue.HighPart |= DoubleOperand1.Exponent;
    01409                 StickyBits = KiSquareRootDouble(&DoubleValue);
    01410                 DoubleOperand1.Exponent =  (DoubleValue.HighPart >> 20) -
    01411                                             ((DOUBLE_EXPONENT_BIAS + 1) / 2);
    01412
    01413                 DoubleOperand1.MantissaLow = DoubleValue.LowPart << 2;
    01414                 DoubleOperand1.MantissaHigh = ((DoubleValue.HighPart &
    01415                                             0xfffff) | 0x100000) << 2;
    01416
    01417                 DoubleOperand1.MantissaHigh |= (DoubleValue.LowPart >> 30);
    01418                 return KiNormalizeDouble(&ContextBlock,
    01419                                          &DoubleOperand1,
    01420                                          StickyBits);
    01421
    01422             } else {
    01423                 break;
    01424             }
    01425
    01426             //
    01427             // Floating absolute operation.
    01428             //
    01429             // Floating absolute is accomplished by clearing the sign
    01430             // of the floating value.
    01431             //
    01432
    01433         case FLOAT_ABSOLUTE:
    01434             if (Format == FORMAT_SINGLE) {
    01435
    01436                 //
    01437                 // Clear the sign, normalize the result, and store in the
    01438                 // destination register.
    01439                 //
    01440
    01441                 SingleOperand1.Sign = 0;
    01442                 return KiNormalizeSingle(&ContextBlock,
    01443                                          &SingleOperand1,
    01444                                          0);
    01445
    01446             } else if (Format == FORMAT_DOUBLE) {
    01447
    01448                 //
    01449                 // Clear the sign, normalize the result, and store in the
    01450                 // destination register.
    01451                 //
    01452
    01453                 DoubleOperand1.Sign = 0;
    01454                 return KiNormalizeDouble(&ContextBlock,
    01455                                          &DoubleOperand1,
    01456                                          0);
    01457
    01458             } else {
    01459                 break;
    01460             }
    01461
    01462             //
    01463             // Floating move operation.
    01464             //
    01465             // Floating move is accomplished by moving the source operand
    01466             // to the destination register.
    01467             //
    01468
    01469         case FLOAT_MOVE:
    01470             if (Format == FORMAT_SINGLE) {
    01471
    01472                 //
    01473                 // Normalize the result and store in the destination
    01474                 // register.
    01475                 //
    01476
    01477                 return KiNormalizeSingle(&ContextBlock,
    01478                                          &SingleOperand1,
    01479                                          0);
    01480
    01481             } else if (Format == FORMAT_DOUBLE) {
    01482
    01483                 //
    01484                 // Normalize the result and store in the destination
    01485                 // register.
    01486                 //
    01487
    01488                 return KiNormalizeDouble(&ContextBlock,
    01489                                          &DoubleOperand1,
    01490                                          0);
    01491
    01492             } else {
    01493                 break;
    01494             }
    01495
    01496             //
    01497             // Floating negate operation.
    01498             //
    01499             // Floating absolute is accomplished by complementing the sign
    01500             // of the floating value.
    01501             //
    01502
    01503         case FLOAT_NEGATE:
    01504             if (Format == FORMAT_SINGLE) {
    01505
    01506                 //
    01507                 // Complement the sign, normalize the result, and store in the
    01508                 // destination register.
    01509                 //
    01510
    01511                 SingleOperand1.Sign ^= 0x1;
    01512                 return KiNormalizeSingle(&ContextBlock,
    01513                                          &SingleOperand1,
    01514                                          0);
    01515
    01516             } else if (Format == FORMAT_DOUBLE) {
    01517
    01518                 //
    01519                 // Complement the sign, normalize the result, and store in the
    01520                 // destination register.
    01521                 //
    01522
    01523                 DoubleOperand1.Sign ^= 0x1;
    01524                 return KiNormalizeDouble(&ContextBlock,
    01525                                          &DoubleOperand1,
    01526                                          0);
    01527
    01528             } else {
    01529                 break;
    01530             }
    01531
    01532             //
    01533             // Floating compare single.
    01534             //
    01535             // This operation is performed after having separated out NaNs,
    01536             // and therefore the only comparison predicates left are equal
    01537             // and less.
    01538             //
    01539             // Floating compare single is accomplished by comparing signs,
    01540             // then exponents, and finally the mantissa if necessary.
    01541             //
    01542             // N.B. The sign of zero is ignorned.
    01543             //
    01544
    01545         case FLOAT_COMPARE_SINGLE:
    01546
    01547             //
    01548             // If either operand is zero, then set the sign of the operand
    01549             // positive.
    01550             //
    01551
    01552             if ((SingleOperand1.Infinity == FALSE) &&
    01553                 (SingleOperand1.Mantissa == 0)) {
    01554                 SingleOperand1.Sign = 0;
    01555                 SingleOperand1.Exponent = - 23;
    01556             }
    01557
    01558             if ((SingleOperand2.Infinity == FALSE)  &&
    01559                 (SingleOperand2.Mantissa == 0)) {
    01560                 SingleOperand2.Sign = 0;
    01561                 SingleOperand2.Exponent = - 23;
    01562             }
    01563
    01564             //
    01565             // Compare signs first.
    01566             //
    01567
    01568             if (SingleOperand1.Sign < SingleOperand2.Sign) {
    01569
    01570                 //
    01571                 // The first operand is greater than the second operand.
    01572                 //
    01573
    01574                 CompareEqual = FALSE;
    01575                 CompareLess = FALSE;
    01576
    01577             } else if (SingleOperand1.Sign > SingleOperand2.Sign) {
    01578
    01579                 //
    01580                 // The first operand is less than the second operand.
    01581                 //
    01582
    01583                 CompareEqual = FALSE;
    01584                 CompareLess = TRUE;
    01585
    01586             } else {
    01587
    01588                 //
    01589                 // The operand signs are equal.
    01590                 //
    01591                 // If the sign of the operand is negative, then the sense of
    01592                 // the comparison is reversed.
    01593                 //
    01594
    01595                 if (SingleOperand1.Sign == 0) {
    01596
    01597                     //
    01598                     // Compare positive operand with positive operand.
    01599                     //
    01600
    01601                     if (SingleOperand1.Exponent > SingleOperand2.Exponent) {
    01602                         CompareEqual = FALSE;
    01603                         CompareLess = FALSE;
    01604
    01605                     } else if (SingleOperand1.Exponent < SingleOperand2.Exponent) {
    01606                         CompareEqual = FALSE;
    01607                         CompareLess = TRUE;
    01608
    01609                     } else {
    01610                         if (SingleOperand1.Mantissa > SingleOperand2.Mantissa) {
    01611                             CompareEqual = FALSE;
    01612                             CompareLess = FALSE;
    01613
    01614                         } else if (SingleOperand1.Mantissa < SingleOperand2.Mantissa) {
    01615                             CompareEqual = FALSE;
    01616                             CompareLess = TRUE;
    01617
    01618                         } else {
    01619                             CompareEqual = TRUE;
    01620                             CompareLess = FALSE;
    01621                         }
    01622                     }
    01623
    01624                 } else {
    01625
    01626                     //
    01627                     // Compare negative operand with negative operand.
    01628                     //
    01629
    01630                     if (SingleOperand2.Exponent > SingleOperand1.Exponent) {
    01631                         CompareEqual = FALSE;
    01632                         CompareLess = FALSE;
    01633
    01634                     } else if (SingleOperand2.Exponent < SingleOperand1.Exponent) {
    01635                         CompareEqual = FALSE;
    01636                         CompareLess = TRUE;
    01637
    01638                     } else {
    01639                         if (SingleOperand2.Mantissa > SingleOperand1.Mantissa) {
    01640                             CompareEqual = FALSE;
    01641                             CompareLess = FALSE;
    01642
    01643                         } else if (SingleOperand2.Mantissa < SingleOperand1.Mantissa) {
    01644                             CompareEqual = FALSE;
    01645                             CompareLess = TRUE;
    01646
    01647                         } else {
    01648                             CompareEqual = TRUE;
    01649                             CompareLess = FALSE;
    01650                         }
    01651                     }
    01652                 }
    01653             }
    01654
    01655             //
    01656             // Form the condition code using the comparison information
    01657             // and the compare function predicate bits.
    01658             //
    01659
    01660             if (((CompareLess != FALSE) &&
    01661                 ((CompareFunction & COMPARE_LESS_MASK) != 0)) ||
    01662                 ((CompareEqual != FALSE) &&
    01663                 ((CompareFunction & COMPARE_EQUAL_MASK) != 0))) {
    01664                 ((PFSR)&TrapFrame->Fsr)->CC = 1;
    01665
    01666             } else {
    01667                 ((PFSR)&TrapFrame->Fsr)->CC = 0;
    01668             }
    01669
    01670             TrapFrame->Fir = ContextBlock.BranchAddress;
    01671             return TRUE;
    01672
    01673             //
    01674             // Floating compare double.
    01675             //
    01676             // This operation is performed after having separated out NaNs,
    01677             // and therefore the only comparison predicates left are equal
    01678             // and less.
    01679             //
    01680             // Floating compare double is accomplished by comparing signs,
    01681             // then exponents, and finally the mantissa if necessary.
    01682             //
    01683             // N.B. The sign of zero is ignorned.
    01684             //
    01685
    01686         case FLOAT_COMPARE_DOUBLE:
    01687
    01688             //
    01689             // If either operand is zero, then set the sign of the operand
    01690             // positive.
    01691             //
    01692
    01693             if ((DoubleOperand1.Infinity == FALSE) &&
    01694                 (DoubleOperand1.MantissaHigh == 0)) {
    01695                 DoubleOperand1.Sign = 0;
    01696                 DoubleOperand1.Exponent = - 52;
    01697             }
    01698
    01699             if ((DoubleOperand2.Infinity == FALSE) &&
    01700                 (DoubleOperand2.MantissaHigh == 0)) {
    01701                 DoubleOperand2.Sign = 0;
    01702                 DoubleOperand2.Exponent = - 52;
    01703             }
    01704
    01705             //
    01706             // Compare signs first.
    01707             //
    01708
    01709             if (DoubleOperand1.Sign < DoubleOperand2.Sign) {
    01710
    01711                 //
    01712                 // The first operand is greater than the second operand.
    01713                 //
    01714
    01715                 CompareEqual = FALSE;
    01716                 CompareLess = FALSE;
    01717
    01718             } else if (DoubleOperand1.Sign > DoubleOperand2.Sign) {
    01719
    01720                 //
    01721                 // The first operand is less than the second operand.
    01722                 //
    01723
    01724                 CompareEqual = FALSE;
    01725                 CompareLess = TRUE;
    01726
    01727             } else {
    01728
    01729                 //
    01730                 // The operand signs are equal.
    01731                 //
    01732                 // If the sign of the operand is negative, then the sense of
    01733                 // the comparison is reversed.
    01734                 //
    01735
    01736                 if (DoubleOperand1.Sign == 0) {
    01737
    01738                     //
    01739                     // Compare positive operand with positive operand.
    01740                     //
    01741
    01742                     if (DoubleOperand1.Exponent > DoubleOperand2.Exponent) {
    01743                         CompareEqual = FALSE;
    01744                         CompareLess = FALSE;
    01745
    01746                     } else if (DoubleOperand1.Exponent < DoubleOperand2.Exponent) {
    01747                         CompareEqual = FALSE;
    01748                         CompareLess = TRUE;
    01749
    01750                     } else {
    01751                         if (DoubleOperand1.MantissaHigh >
    01752                             DoubleOperand2.MantissaHigh) {
    01753                             CompareEqual = FALSE;
    01754                             CompareLess = FALSE;
    01755
    01756                         } else if (DoubleOperand1.MantissaHigh <
    01757                                    DoubleOperand2.MantissaHigh) {
    01758                             CompareEqual = FALSE;
    01759                             CompareLess = TRUE;
    01760
    01761                         } else {
    01762                             if (DoubleOperand1.MantissaLow >
    01763                                 DoubleOperand2.MantissaLow) {
    01764                                 CompareEqual = FALSE;
    01765                                 CompareLess = FALSE;
    01766
    01767                             } else if (DoubleOperand1.MantissaLow <
    01768                                        DoubleOperand2.MantissaLow) {
    01769                                 CompareEqual = FALSE;
    01770                                 CompareLess = TRUE;
    01771
    01772                             } else {
    01773                                 CompareEqual = TRUE;
    01774                                 CompareLess = FALSE;
    01775                             }
    01776                         }
    01777                     }
    01778
    01779                 } else {
    01780
    01781                     //
    01782                     // Compare negative operand with negative operand.
    01783                     //
    01784
    01785                     if (DoubleOperand2.Exponent > DoubleOperand1.Exponent) {
    01786                         CompareEqual = FALSE;
    01787                         CompareLess = FALSE;
    01788
    01789                     } else if (DoubleOperand2.Exponent < DoubleOperand1.Exponent) {
    01790                         CompareEqual = FALSE;
    01791                         CompareLess = TRUE;
    01792
    01793                     } else {
    01794                         if (DoubleOperand2.MantissaHigh >
    01795                             DoubleOperand1.MantissaHigh) {
    01796                             CompareEqual = FALSE;
    01797                             CompareLess = FALSE;
    01798
    01799                         } else if (DoubleOperand2.MantissaHigh <
    01800                                    DoubleOperand1.MantissaHigh) {
    01801                             CompareEqual = FALSE;
    01802                             CompareLess = TRUE;
    01803
    01804                         } else {
    01805                             if (DoubleOperand2.MantissaLow >
    01806                                 DoubleOperand1.MantissaLow) {
    01807                                 CompareEqual = FALSE;
    01808                                 CompareLess = FALSE;
    01809
    01810                             } else if (DoubleOperand2.MantissaLow <
    01811                                        DoubleOperand1.MantissaLow) {
    01812                                 CompareEqual = FALSE;
    01813                                 CompareLess = TRUE;
    01814
    01815                             } else {
    01816                                 CompareEqual = TRUE;
    01817                                 CompareLess = FALSE;
    01818                             }
    01819                         }
    01820                     }
    01821                 }
    01822             }
    01823
    01824             //
    01825             // Form the condition code using the comparison information
    01826             // and the compare function predicate bits.
    01827             //
    01828
    01829             if (((CompareLess != FALSE) &&
    01830                 ((CompareFunction & COMPARE_LESS_MASK) != 0)) ||
    01831                 ((CompareEqual != FALSE) &&
    01832                 ((CompareFunction & COMPARE_EQUAL_MASK) != 0))) {
    01833                 ((PFSR)&TrapFrame->Fsr)->CC = 1;
    01834
    01835             } else {
    01836                 ((PFSR)&TrapFrame->Fsr)->CC = 0;
    01837             }
    01838
    01839             TrapFrame->Fir = ContextBlock.BranchAddress;
    01840             return TRUE;
    01841
    01842             //
    01843             // Floating convert to single.
    01844             //
    01845             // This operation is only legal for conversion from quadword,
    01846             // longword, and double formats to single format. This operation
    01847             // can not be used to convert from a single format to a single format.
    01848             //
    01849             // Floating conversion to single is accompished by forming a
    01850             // single floating operand and then normalize and storing the
    01851             // result value.
    01852             //
    01853
    01854         case FLOAT_CONVERT_SINGLE:
    01855             if (Format == FORMAT_SINGLE) {
    01856                 break;
    01857
    01858             } else if (Format == FORMAT_DOUBLE) {
    01859
    01860                 //
    01861                 // If the operand is a NaN, then store a quiet NaN if the
    01862                 // invalid operation trap is disabled, or raise an exception
    01863                 // if the invalid operation trap is enabled and the operand
    01864                 // is a signaling NaN.
    01865                 //
    01866
    01867                 if (DoubleOperand1.Nan != FALSE) {
    01868                     SingleOperand1.Mantissa =
    01869                         (DoubleOperand1.MantissaHigh << (26 - (55 - 32))) |
    01870                         (DoubleOperand1.MantissaLow >> (32 - (26 - (55 - 32))));
    01871                     SingleOperand1.Exponent = SINGLE_MAXIMUM_EXPONENT;
    01872                     SingleOperand1.Sign = DoubleOperand1.Sign;
    01873                     SingleOperand1.Infinity = FALSE;
    01874                     SingleOperand1.Nan = TRUE;
    01875                     return KiInvalidOperationSingle(&ContextBlock,
    01876                                                     TRUE,
    01877                                                     &SingleOperand1,
    01878                                                     &SingleOperand1);
    01879
    01880                 }
    01881
    01882                 //
    01883                 // Transform the double operand to single format.
    01884                 //
    01885
    01886                 SingleOperand1.Mantissa =
    01887                     (DoubleOperand1.MantissaHigh << (26 - (55 - 32))) |
    01888                     (DoubleOperand1.MantissaLow >> (32 - (26 - (55 - 32))));
    01889                 StickyBits = DoubleOperand1.MantissaLow << (26 - (55 - 32));
    01890                 SingleOperand1.Exponent = DoubleOperand1.Exponent +
    01891                                     SINGLE_EXPONENT_BIAS - DOUBLE_EXPONENT_BIAS;
    01892                 SingleOperand1.Sign = DoubleOperand1.Sign;
    01893                 SingleOperand1.Infinity = DoubleOperand1.Infinity;
    01894                 SingleOperand1.Nan = FALSE;
    01895
    01896                 //
    01897                 // Normalize and store the result value.
    01898                 //
    01899
    01900                 return KiNormalizeSingle(&ContextBlock,
    01901                                          &SingleOperand1,
    01902                                          StickyBits);
    01903
    01904             } else if (Format == FORMAT_LONGWORD) {
    01905
    01906                 //
    01907                 // Compute the sign of the result.
    01908                 //
    01909
    01910                 if (Longword < 0) {
    01911                     SingleOperand1.Sign = 0x1;
    01912                     Longword = -Longword;
    01913
    01914                 } else {
    01915                     SingleOperand1.Sign = 0;
    01916                 }
    01917
    01918                 //
    01919                 // Initialize the infinity and NaN values.
    01920                 //
    01921
    01922                 SingleOperand1.Infinity = FALSE;
    01923                 SingleOperand1.Nan = FALSE;
    01924
    01925                 //
    01926                 // Compute the exponent value and normalize the longword
    01927                 // value.
    01928                 //
    01929
    01930                 if (Longword != 0) {
    01931                     SingleOperand1.Exponent = SINGLE_EXPONENT_BIAS + 31;
    01932                     while (Longword > 0) {
    01933                         Longword <<= 1;
    01934                         SingleOperand1.Exponent -= 1;
    01935                     }
    01936
    01937                     SingleOperand1.Mantissa = (ULONG)Longword >> (32 - 26);
    01938                     StickyBits = Longword << 26;
    01939
    01940                 } else {
    01941                     SingleOperand1.Mantissa = 0;
    01942                     StickyBits = 0;
    01943                     SingleOperand1.Exponent = 0;
    01944                 }
    01945
    01946                 //
    01947                 // Normalize and store the result value.
    01948                 //
    01949
    01950                 return KiNormalizeSingle(&ContextBlock,
    01951                                          &SingleOperand1,
    01952                                          StickyBits);
    01953
    01954             } else if (Format == FORMAT_QUADWORD) {
    01955
    01956                 //
    01957                 // Compute the sign of the result.
    01958                 //
    01959
    01960                 if (u.Quadword < 0) {
    01961                     SingleOperand1.Sign = 0x1;
    01962                     u.Quadword = -u.Quadword;
    01963
    01964                 } else {
    01965                     SingleOperand1.Sign = 0;
    01966                 }
    01967
    01968                 //
    01969                 // Initialize the infinity and NaN values.
    01970                 //
    01971
    01972                 SingleOperand1.Infinity = FALSE;
    01973                 SingleOperand1.Nan = FALSE;
    01974
    01975                 //
    01976                 // Compute the exponent value and normalize the quadword
    01977                 // value.
    01978                 //
    01979
    01980                 if (u.Quadword != 0) {
    01981                     SingleOperand1.Exponent = SINGLE_EXPONENT_BIAS + 63;
    01982                     while (u.Quadword > 0) {
    01983                         u.Quadword <<= 1;
    01984                         SingleOperand1.Exponent -= 1;
    01985                     }
    01986
    01987                     SingleOperand1.Mantissa = (LONG)((ULONGLONG)u.Quadword >> (64 - 26));
    01988                     StickyBits = (u.Quadword << 26) ? 1 : 0;
    01989
    01990                 } else {
    01991                     SingleOperand1.Mantissa = 0;
    01992                     StickyBits = 0;
    01993                     SingleOperand1.Exponent = 0;
    01994                 }
    01995
    01996                 //
    01997                 // Normalize and store the result value.
    01998                 //
    01999
    02000                 return KiNormalizeSingle(&ContextBlock,
    02001                                          &SingleOperand1,
    02002                                          StickyBits);
    02003
    02004             } else {
    02005                 break;
    02006             }
    02007
    02008             //
    02009             // Floating convert to double.
    02010             //
    02011             // This operation is only legal for conversion from quadword,
    02012             // longword, and single formats to double format. This operation
    02013             // cannot be used to convert from a double format to a double
    02014             // format.
    02015             //
    02016             // Floating conversion to double is accomplished by forming
    02017             // double floating operand and then normalizing and storing
    02018             // the result value.
    02019             //
    02020
    02021         case FLOAT_CONVERT_DOUBLE:
    02022             if (Format == FORMAT_SINGLE) {
    02023
    02024                 //
    02025                 // If the operand is a NaN, then store a quiet NaN if the
    02026                 // invalid operation trap is disabled, or raise an exception
    02027                 // if the invalid operation trap is enabled and the operand
    02028                 // is a signaling NaN.
    02029                 //
    02030
    02031                 if (SingleOperand1.Nan != FALSE) {
    02032                     DoubleOperand1.MantissaHigh =
    02033                             SingleOperand1.Mantissa >> (26 - (55 - 32));
    02034                     DoubleOperand1.MantissaLow = (0xffffffff >> (26 - 2 - (55 - 32))) |
    02035                             SingleOperand1.Mantissa << (32 - (26 - (55 - 32)));
    02036                     DoubleOperand1.Exponent = DOUBLE_MAXIMUM_EXPONENT;
    02037                     DoubleOperand1.Sign = SingleOperand1.Sign;
    02038                     DoubleOperand1.Infinity = FALSE;
    02039                     DoubleOperand1.Nan = TRUE;
    02040                     return KiInvalidOperationDouble(&ContextBlock,
    02041                                                     TRUE,
    02042                                                     &DoubleOperand1,
    02043                                                     &DoubleOperand1);
    02044
    02045                 }
    02046
    02047                 //
    02048                 // Transform the single operand to double format.
    02049                 //
    02050
    02051                 DoubleOperand1.MantissaHigh =
    02052                             SingleOperand1.Mantissa >> (26 - (55 - 32));
    02053                 DoubleOperand1.MantissaLow =
    02054                             SingleOperand1.Mantissa << (32 - (26 - (55 - 32)));
    02055                 DoubleOperand1.Exponent = SingleOperand1.Exponent +
    02056                                     DOUBLE_EXPONENT_BIAS - SINGLE_EXPONENT_BIAS;
    02057                 DoubleOperand1.Sign = SingleOperand1.Sign;
    02058                 DoubleOperand1.Infinity = SingleOperand1.Infinity;
    02059                 DoubleOperand1.Nan = FALSE;
    02060
    02061                 //
    02062                 // Normalize and store the result value.
    02063                 //
    02064
    02065                 return KiNormalizeDouble(&ContextBlock,
    02066                                          &DoubleOperand1,
    02067                                          0);
    02068
    02069             } else if (Format == FORMAT_DOUBLE) {
    02070                 break;
    02071
    02072             } else if (Format == FORMAT_LONGWORD) {
    02073
    02074                 //
    02075                 // Compute the sign of the result.
    02076                 //
    02077
    02078                 if (Longword < 0) {
    02079                     DoubleOperand1.Sign = 0x1;
    02080                     Longword = -Longword;
    02081
    02082                 } else {
    02083                     DoubleOperand1.Sign = 0;
    02084                 }
    02085
    02086                 //
    02087                 // Initialize the infinity and NaN values.
    02088                 //
    02089
    02090                 DoubleOperand1.Infinity = FALSE;
    02091                 DoubleOperand1.Nan = FALSE;
    02092
    02093                 //
    02094                 // Compute the exponent value and normalize the longword
    02095                 // value.
    02096                 //
    02097
    02098                 if (Longword != 0) {
    02099                     SingleOperand1.Exponent = DOUBLE_EXPONENT_BIAS + 31;
    02100                     while (Longword > 0) {
    02101                         Longword <<= 1;
    02102                         DoubleOperand1.Exponent -= 1;
    02103                     }
    02104
    02105                     DoubleOperand1.Mantissa = (ULONGLONG)Longword >> (64 - 55);
    02106
    02107                 } else {
    02108                     DoubleOperand1.Mantissa = 0;
    02109                     DoubleOperand1.Exponent = 0;
    02110                 }
    02111
    02112                 //
    02113                 // Normalize and store the result value.
    02114                 //
    02115
    02116                 return KiNormalizeDouble(&ContextBlock,
    02117                                          &DoubleOperand1,
    02118                                          0);
    02119
    02120             } else if (Format == FORMAT_QUADWORD) {
    02121
    02122                 //
    02123                 // Compute the sign of the result.
    02124                 //
    02125
    02126                 if (u.Quadword < 0) {
    02127                     DoubleOperand1.Sign = 0x1;
    02128                     u.Quadword = -u.Quadword;
    02129
    02130                 } else {
    02131                     DoubleOperand1.Sign = 0;
    02132                 }
    02133
    02134                 //
    02135                 // Initialize the infinity and NaN values.
    02136                 //
    02137
    02138                 DoubleOperand1.Infinity = FALSE;
    02139                 DoubleOperand1.Nan = FALSE;
    02140
    02141                 //
    02142                 // Compute the exponent value and normalize the quadword
    02143                 // value.
    02144                 //
    02145
    02146                 if (u.Quadword != 0) {
    02147                     DoubleOperand1.Exponent = DOUBLE_EXPONENT_BIAS + 63;
    02148                     while (u.Quadword > 0) {
    02149                         u.Quadword <<= 1;
    02150                         DoubleOperand1.Exponent -= 1;
    02151                     }
    02152
    02153                     DoubleOperand1.Mantissa = (ULONGLONG)u.Quadword >> (64 - 55);
    02154                     StickyBits = (u.Quadword << 55) ? 1 : 0;
    02155
    02156                 } else {
    02157                     DoubleOperand1.Mantissa = 0;
    02158                     StickyBits = 0;
    02159                     DoubleOperand1.Exponent = 0;
    02160                 }
    02161
    02162                 //
    02163                 // Normalize and store the result value.
    02164                 //
    02165
    02166                 return KiNormalizeDouble(&ContextBlock,
    02167                                          &DoubleOperand1,
    02168                                          StickyBits);
    02169
    02170             } else {
    02171                 break;
    02172             }
    02173
    02174             //
    02175             // Floating convert to quadword.
    02176             //
    02177             // This operation is only legal for conversion from double
    02178             // and single formats to quadword format. This operation
    02179             // cannot be used to convert from a quadword format to a
    02180             // longword or quadword format.
    02181             //
    02182             // Floating conversion to quadword is accomplished by forming
    02183             // a quadword value from a single or double floating value.
    02184             //
    02185             // There is one general conversion operation and four directed
    02186             // rounding operations.
    02187             //
    02188
    02189         case FLOAT_ROUND_QUADWORD:
    02190             ContextBlock.Round = ROUND_TO_NEAREST;
    02191             goto ConvertQuadword;
    02192
    02193         case FLOAT_TRUNC_QUADWORD:
    02194             ContextBlock.Round = ROUND_TO_ZERO;
    02195             goto ConvertQuadword;
    02196
    02197         case FLOAT_CEIL_QUADWORD:
    02198             ContextBlock.Round = ROUND_TO_PLUS_INFINITY;
    02199             goto ConvertQuadword;
    02200
    02201         case FLOAT_FLOOR_QUADWORD:
    02202             ContextBlock.Round = ROUND_TO_MINUS_INFINITY;
    02203             goto ConvertQuadword;
    02204
    02205         case FLOAT_CONVERT_QUADWORD:
    02206         ConvertQuadword:
    02207             if (Format == FORMAT_SINGLE) {
    02208
    02209                 //
    02210                 // If the operand is infinite or is a NaN, then store a
    02211                 // quiet NaN or an appropriate infinity if the invalid
    02212                 // operation trap is disabled, or raise an exception if
    02213                 // the invalid trap is enabled.
    02214                 //
    02215
    02216                 if ((SingleOperand1.Infinity != FALSE) ||
    02217                     (SingleOperand1.Nan != FALSE)) {
    02218                     return KiInvalidOperationQuadword(&ContextBlock,
    02219                                                       SingleOperand1.Infinity,
    02220                                                       SingleOperand1.Sign);
    02221                 }
    02222
    02223                 //
    02224                 // Transform the single operand to double format.
    02225                 //
    02226
    02227                 DoubleOperand1.Mantissa = (LONGLONG)SingleOperand1.Mantissa << (55 - 26);
    02228                 DoubleOperand1.Exponent = SingleOperand1.Exponent +
    02229                                     DOUBLE_EXPONENT_BIAS - SINGLE_EXPONENT_BIAS;
    02230
    02231                 DoubleOperand1.Sign = SingleOperand1.Sign;
    02232                 DoubleOperand1.Infinity = FALSE;
    02233                 DoubleOperand1.Nan = FALSE;
    02234
    02235                 //
    02236                 // Convert double to quadword and store the result value.
    02237                 //
    02238
    02239                 return KiNormalizeQuadword(&ContextBlock, &DoubleOperand1);
    02240
    02241             } else if (Format == FORMAT_DOUBLE) {
    02242
    02243                 //
    02244                 // If the operand is infinite or is a NaN, then store a
    02245                 // quiet NaN or an appropriate infinity if the invalid
    02246                 // operation trap is disabled, or raise an exception if
    02247                 // the invalid trap is enabled.
    02248                 //
    02249
    02250                 if ((DoubleOperand1.Infinity != FALSE) ||
    02251                     (DoubleOperand1.Nan != FALSE)) {
    02252                     return KiInvalidOperationQuadword(&ContextBlock,
    02253                                                       DoubleOperand1.Infinity,
    02254                                                       DoubleOperand1.Sign);
    02255                 }
    02256
    02257                 //
    02258                 // Convert double to quadword and store the result value.
    02259                 //
    02260
    02261                 return KiNormalizeQuadword(&ContextBlock, &DoubleOperand1);
    02262
    02263             } else {
    02264                 break;
    02265             }
    02266
    02267             //
    02268             // Floating convert to longword.
    02269             //
    02270             // This operation is only legal for conversion from double
    02271             // and single formats to longword format. This operation
    02272             // cannot be used to convert from a longword format to a
    02273             // longword format.
    02274             //
    02275             // Floating conversion to longword is accomplished by forming
    02276             // a longword value from a single or double floating value.
    02277             //
    02278             // There is one general conversion operation and four directed
    02279             // rounding operations.
    02280             //
    02281
    02282         case FLOAT_ROUND_LONGWORD:
    02283             ContextBlock.Round = ROUND_TO_NEAREST;
    02284             goto ConvertLongword;
    02285
    02286         case FLOAT_TRUNC_LONGWORD:
    02287             ContextBlock.Round = ROUND_TO_ZERO;
    02288             goto ConvertLongword;
    02289
    02290         case FLOAT_CEIL_LONGWORD:
    02291             ContextBlock.Round = ROUND_TO_PLUS_INFINITY;
    02292             goto ConvertLongword;
    02293
    02294         case FLOAT_FLOOR_LONGWORD:
    02295             ContextBlock.Round = ROUND_TO_MINUS_INFINITY;
    02296             goto ConvertLongword;
    02297
    02298         case FLOAT_CONVERT_LONGWORD:
    02299         ConvertLongword:
    02300             if (Format == FORMAT_SINGLE) {
    02301
    02302                 //
    02303                 // If the operand is infinite or is a NaN, then store a
    02304                 // quiet NaN or an appropriate infinity if the invalid
    02305                 // operation trap is disabled, or raise an exception if
    02306                 // the invalid trap is enabled.
    02307                 //
    02308
    02309                 if ((SingleOperand1.Infinity != FALSE) ||
    02310                     (SingleOperand1.Nan != FALSE)) {
    02311                     return KiInvalidOperationLongword(&ContextBlock,
    02312                                                       SingleOperand1.Infinity,
    02313                                                       SingleOperand1.Sign);
    02314                 }
    02315
    02316                 //
    02317                 // Transform the single operand to double format.
    02318                 //
    02319
    02320                 DoubleOperand1.MantissaHigh =
    02321                             SingleOperand1.Mantissa >> (26 - (55 - 32));
    02322                 DoubleOperand1.MantissaLow =
    02323                             SingleOperand1.Mantissa << (32 - (26 - (55 - 32)));
    02324                 DoubleOperand1.Exponent = SingleOperand1.Exponent +
    02325                                     DOUBLE_EXPONENT_BIAS - SINGLE_EXPONENT_BIAS;
    02326                 DoubleOperand1.Sign = SingleOperand1.Sign;
    02327                 DoubleOperand1.Infinity = FALSE;
    02328                 DoubleOperand1.Nan = FALSE;
    02329
    02330                 //
    02331                 // Convert double to longword and store the result value.
    02332                 //
    02333
    02334                 return KiNormalizeLongword(&ContextBlock, &DoubleOperand1);
    02335
    02336             } else if (Format == FORMAT_DOUBLE) {
    02337
    02338                 //
    02339                 // If the operand is infinite or is a NaN, then store a
    02340                 // quiet NaN or an appropriate infinity if the invalid
    02341                 // operation trap is disabled, or raise an exception if
    02342                 // the invalid trap is enabled.
    02343                 //
    02344
    02345                 if ((DoubleOperand1.Infinity != FALSE) ||
    02346                     (DoubleOperand1.Nan != FALSE)) {
    02347                     return KiInvalidOperationLongword(&ContextBlock,
    02348                                                       DoubleOperand1.Infinity,
    02349                                                       DoubleOperand1.Sign);
    02350                 }
    02351
    02352                 //
    02353                 // Convert double to longword and store the result value.
    02354                 //
    02355
    02356                 return KiNormalizeLongword(&ContextBlock, &DoubleOperand1);
    02357
    02358             } else {
    02359                 break;
    02360             }
    02361
    02362             //
    02363             // An illegal function, format value, or field value.
    02364             //
    02365
    02366         default :
    02367             break;
    02368         }
    02369
    02370         //
    02371         // An illegal function, format value, or field value was encoutnered.
    02372         // Generate and illegal instruction exception.
    02373         //
    02374
    02375         ExceptionRecord->ExceptionCode = STATUS_ILLEGAL_INSTRUCTION;
    02376         return FALSE;
    02377
    02378     //
    02379     // If an exception occurs, then copy the new exception information to the
    02380     // original exception record and handle the exception.
    02381     //
    02382
    02383     } except (KiCopyInformation(ExceptionRecord,
    02384                                (GetExceptionInformation())->ExceptionRecord)) {
    02385
    02386         //
    02387         // Preserve the original exception address and branch destination.
    02388         //
    02389
    02390         ExceptionRecord->ExceptionAddress = ExceptionAddress;
    02391         return FALSE;
    02392     }
    02393 }

BOOLEAN KiInvalidCompareDouble | ( | IN PFP_CONTEXT_BLOCK | ContextBlock,
|  | IN BOOLEAN | CheckForNan,
|  | IN PFP_DOUBLE_OPERAND | DoubleOperand1,
|  | IN PFP_DOUBLE_OPERAND | DoubleOperand2
| ) |

| Referenced by KiEmulateFloating().

BOOLEAN KiInvalidCompareSingle | ( | IN PFP_CONTEXT_BLOCK | ContextBlock,
|  | IN BOOLEAN | CheckForNan,
|  | IN PFP_SINGLE_OPERAND | SingleOperand1,
|  | IN PFP_SINGLE_OPERAND | SingleOperand2
| ) |

Definition at line 2627 of file mips/floatem.c.

References FALSE, SINGLE_SIGNAL_NAN_MASK, and TRUE.

Referenced by KiEmulateFloating().

    02636                    :
    02637
    02638     This function is called to determine whether an invalid operation
    02639     exception should be raised for a single compare operation.
    02640
    02641 Arguments:
    02642
    02643     ContextBlock - Supplies a pointer to the emulation context block.
    02644
    02645     CheckForNan - Supplies a boolean value that detetermines whether the
    02646         operand values should be checked for a signaling NaN.
    02647
    02648     SingleOperand1 - Supplies a pointer to the first operand value.
    02649
    02650     SingleOperand2 - Supplies a pointer ot the second operand value.
    02651
    02652 Return Value:
    02653
    02654     If the invalid operation trap is enabled and either the operation is
    02655     invalid or one of the operands in a signaling NaN, then a value of
    02656     FALSE is returned. Otherwise, no operation is performed and a value
    02657     of TRUE is returned.
    02658
    02659 --*/
    02660
    02661 {
    02662
    02663     PEXCEPTION_RECORD ExceptionRecord;
    02664     PFP_IEEE_VALUE IeeeValue;
    02665     PKTRAP_FRAME TrapFrame;
    02666
    02667     //
    02668     // If an invalid operation is specified or one of the operands is a
    02669     // signaling NaN and the invalid operation trap is enabled, then
    02670     // store the proper exception code and exception flags and return
    02671     // a value of FALSE. Otherwise, perform no operation and return a
    02672     // value of TRUE.
    02673     //
    02674
    02675     ExceptionRecord = ContextBlock->ExceptionRecord;
    02676     TrapFrame = ContextBlock->TrapFrame;
    02677     if ((CheckForNan == FALSE) ||
    02678         ((SingleOperand1->Nan != FALSE) &&
    02679         ((SingleOperand1->Mantissa & SINGLE_SIGNAL_NAN_MASK) != 0)) ||
    02680         ((SingleOperand2->Nan != FALSE) &&
    02681         ((SingleOperand2->Mantissa & SINGLE_SIGNAL_NAN_MASK) != 0))) {
    02682         ((PFSR)&TrapFrame->Fsr)->SV = 1;
    02683         if (((PFSR)&TrapFrame->Fsr)->EV != 0) {
    02684             ExceptionRecord->ExceptionCode = STATUS_FLOAT_INVALID_OPERATION;
    02685             ((PFSR)&TrapFrame->Fsr)->XV = 1;
    02686             IeeeValue = (PFP_IEEE_VALUE)&ExceptionRecord->ExceptionInformation[2];
    02687             IeeeValue->Value.CompareValue = FpCompareUnordered;
    02688             return FALSE;
    02689         }
    02690     }
    02691
    02692     TrapFrame->Fir = ContextBlock->BranchAddress;
    02693     return TRUE;
    02694 }

BOOLEAN KiInvalidOperationDouble | ( | IN PFP_CONTEXT_BLOCK | ContextBlock,
|  | IN BOOLEAN | CheckForNan,
|  | IN PFP_DOUBLE_OPERAND | DoubleOperand1,
|  | IN PFP_DOUBLE_OPERAND | DoubleOperand2
| ) |

| Referenced by KiEmulateFloating().

BOOLEAN KiInvalidOperationLongword | ( | IN PFP_CONTEXT_BLOCK | ContextBlock,
|  | IN BOOLEAN | Infinity,
|  | IN LONG | Sign
| ) |

Definition at line 2820 of file mips/floatem.c.

References FALSE, KiSetRegisterValue(), and TRUE.

Referenced by KiEmulateFloating(), and KiNormalizeLongword().

    02828                    :
    02829
    02830     This function is called to either raise and exception or store a
    02831     quiet NaN for an invalid conversion to longword.
    02832
    02833 Arguments:
    02834
    02835     ContextBlock - Supplies a pointer to the emulation context block.
    02836
    02837     Infinity - Suuplies a boolean variable that specifies whether the
    02838         invalid operand is infinite.
    02839
    02840     Sign - Supplies the infinity sign if the invalid operand is infinite.
    02841
    02842 Return Value:
    02843
    02844     If the invalid operation trap is enabled, then a value of FALSE is
    02845     returned. Otherwise, an appropriate longword value is stored as the
    02846     destination result and a value of TRUE is returned.
    02847
    02848 --*/
    02849
    02850 {
    02851
    02852     PEXCEPTION_RECORD ExceptionRecord;
    02853     PFP_IEEE_VALUE IeeeValue;
    02854     ULONG ResultValue;
    02855     PKTRAP_FRAME TrapFrame;
    02856
    02857     //
    02858     // If the value is infinite, then the result is a properly signed value
    02859     // whose magnitude is the largest that will fit in 32-bits. Otherwise,
    02860     // the result is an integer NaN.
    02861     //
    02862
    02863     if (Infinity != FALSE) {
    02864         if (Sign == 0) {
    02865             ResultValue = 0x7fffffff;
    02866
    02867         } else {
    02868             ResultValue = 0x80000000;
    02869         }
    02870
    02871     } else {
    02872         ResultValue = SINGLE_INTEGER_NAN;
    02873     }
    02874
    02875     //
    02876     // If the invalid operation trap is enabled then store the proper
    02877     // exception code and exception flags and return a value of FALSE.
    02878     // Otherwise, store a quiet NaN as the destination result and return
    02879     // a value of TRUE.
    02880     //
    02881
    02882     ExceptionRecord = ContextBlock->ExceptionRecord;
    02883     TrapFrame = ContextBlock->TrapFrame;
    02884     ((PFSR)&TrapFrame->Fsr)->SV = 1;
    02885     if (((PFSR)&TrapFrame->Fsr)->EV != 0) {
    02886         ExceptionRecord->ExceptionCode = STATUS_FLOAT_INVALID_OPERATION;
    02887         ((PFSR)&TrapFrame->Fsr)->XV = 1;
    02888         IeeeValue = (PFP_IEEE_VALUE)&ExceptionRecord->ExceptionInformation[2];
    02889         IeeeValue->Value.U32Value = ResultValue;
    02890         return FALSE;
    02891
    02892     } else {
    02893
    02894         KiSetRegisterValue(ContextBlock->Fd + 32,
    02895                            ResultValue,
    02896                            ContextBlock->ExceptionFrame,
    02897                            ContextBlock->TrapFrame);
    02898
    02899         TrapFrame->Fir = ContextBlock->BranchAddress;
    02900         return TRUE;
    02901     }
    02902 }

BOOLEAN KiInvalidOperationQuadword | ( | IN PFP_CONTEXT_BLOCK | ContextBlock,
|  | IN BOOLEAN | Infinity,
|  | IN LONG | Sign
| ) |

Definition at line 2905 of file mips/floatem.c.

References FALSE, KiSetRegisterValue(), and TRUE.

Referenced by KiEmulateFloating(), and KiNormalizeQuadword().

    02913                    :
    02914
    02915     This function is called to either raise and exception or store a
    02916     quiet NaN for an invalid conversion to quadword.
    02917
    02918 Arguments:
    02919
    02920     ContextBlock - Supplies a pointer to the emulation context block.
    02921
    02922     Infinity - Suuplies a boolean variable that specifies whether the
    02923         invalid operand is infinite.
    02924
    02925     Sign - Supplies the infinity sign if the invalid operand is infinite.
    02926
    02927 Return Value:
    02928
    02929     If the invalid operation trap is enabled, then a value of FALSE is
    02930     returned. Otherwise, an appropriate longword value is stored as the
    02931     destination result and a value of TRUE is returned.
    02932
    02933 --*/
    02934
    02935 {
    02936
    02937     PEXCEPTION_RECORD ExceptionRecord;
    02938     PFP_IEEE_VALUE IeeeValue;
    02939     union {
    02940         ULONGLONG ResultValue;
    02941         ULARGE_INTEGER LargeValue;
    02942     }u;
    02943
    02944     PKTRAP_FRAME TrapFrame;
    02945
    02946     //
    02947     // If the value is infinite, then the result is a properly signed value
    02948     // whose magnitude is the largest that will fit in 64-bits. Otherwise,
    02949     // the result is an integer NaN.
    02950     //
    02951
    02952     if (Infinity != FALSE) {
    02953         if (Sign == 0) {
    02954             u.ResultValue = 0x7fffffffffffffff;
    02955
    02956         } else {
    02957             u.ResultValue = 0x8000000000000000;
    02958         }
    02959
    02960     } else {
    02961         u.ResultValue = DOUBLE_INTEGER_NAN;
    02962     }
    02963
    02964     //
    02965     // If the invalid operation trap is enabled then store the proper
    02966     // exception code and exception flags and return a value of FALSE.
    02967     // Otherwise, store a quiet NaN as the destination result and return
    02968     // a value of TRUE.
    02969     //
    02970
    02971     ExceptionRecord = ContextBlock->ExceptionRecord;
    02972     TrapFrame = ContextBlock->TrapFrame;
    02973     ((PFSR)&TrapFrame->Fsr)->SV = 1;
    02974     if (((PFSR)&TrapFrame->Fsr)->EV != 0) {
    02975         ExceptionRecord->ExceptionCode = STATUS_FLOAT_INVALID_OPERATION;
    02976         ((PFSR)&TrapFrame->Fsr)->XV = 1;
    02977         IeeeValue = (PFP_IEEE_VALUE)&ExceptionRecord->ExceptionInformation[2];
    02978         IeeeValue->Value.U64Value.QuadPart = u.ResultValue;
    02979         return FALSE;
    02980
    02981     } else {
    02982
    02983         KiSetRegisterValue(ContextBlock->Fd + 32,
    02984                            u.LargeValue.LowPart,
    02985                            ContextBlock->ExceptionFrame,
    02986                            ContextBlock->TrapFrame);
    02987
    02988         KiSetRegisterValue(ContextBlock->Fd + 33,
    02989                            u.LargeValue.HighPart,
    02990                            ContextBlock->ExceptionFrame,
    02991                            ContextBlock->TrapFrame);
    02992
    02993         TrapFrame->Fir = ContextBlock->BranchAddress;
    02994         return TRUE;
    02995     }
    02996 }

BOOLEAN KiInvalidOperationSingle | ( | IN PFP_CONTEXT_BLOCK | ContextBlock,
|  | IN BOOLEAN | CheckForNan,
|  | IN PFP_SINGLE_OPERAND | SingleOperand1,
|  | IN PFP_SINGLE_OPERAND | SingleOperand2
| ) |

| Referenced by KiEmulateFloating().

BOOLEAN KiNormalizeDouble | ( | IN PFP_CONTEXT_BLOCK | ContextBlock,
|  | IN PFP_DOUBLE_OPERAND | ResultOperand,
|  | IN ULONG | StickyBits
| ) |

Definition at line 3105 of file mips/floatem.c.

References FALSE, KiSetRegisterValue(), and TRUE.

Referenced by KiEmulateFloating().

    03113                    :
    03114
    03115     This function is called to normalize a double floating result.
    03116
    03117     N.B. The result value is specified with a guard bit on the right,
    03118         the hidden bit (if appropriate), and a possible overflow bit.
    03119         The result format is:
    03120
    03121         <63:56> - zero
    03122         <55> - overflow bit
    03123         <54> - hidden bit
    03124         <53:2> - mantissa
    03125         <1> - guard bit
    03126         <0> - round bit
    03127
    03128         The sticky bits specify bits that were lost during the computable.
    03129
    03130 Arguments:
    03131
    03132     ContextBlock - Supplies a pointer to the emulation context block.
    03133
    03134     ResultOperand - Supplies a pointer to the result operand value.
    03135
    03136     StickyBits - Supplies the value of the sticky bits.
    03137
    03138 Return Value:
    03139
    03140     If there is not an exception, or the exception is handled, then a proper
    03141     result is stored in the destination result, the continuation address is
    03142     set, and a value of TRUE is returned. Otherwise, no value is stored and
    03143     a value of FALSE is returned.
    03144
    03145 --*/
    03146
    03147 {
    03148
    03149     ULONG DenormalizeShift;
    03150     PEXCEPTION_RECORD ExceptionRecord;
    03151     ULONG ExceptionResultHigh;
    03152     ULONG ExceptionResultLow;
    03153     PFP_IEEE_VALUE IeeeValue;
    03154     BOOLEAN Inexact;
    03155     BOOLEAN Overflow;
    03156     ULONG ResultValueHigh;
    03157     ULONG ResultValueLow;
    03158     ULONG RoundBit;
    03159     PKTRAP_FRAME TrapFrame;
    03160     BOOLEAN Underflow;
    03161
    03162     //
    03163     // If the result is infinite, then store a properly signed infinity
    03164     // in the destination register and return a value of TRUE. Otherwise,
    03165     // round and normalize the result and check for overflow and underflow.
    03166     //
    03167
    03168     ExceptionRecord = ContextBlock->ExceptionRecord;
    03169     TrapFrame = ContextBlock->TrapFrame;
    03170     if (ResultOperand->Infinity != FALSE) {
    03171         KiSetRegisterValue(ContextBlock->Fd + 32,
    03172                            DOUBLE_INFINITY_VALUE_LOW,
    03173                            ContextBlock->ExceptionFrame,
    03174                            ContextBlock->TrapFrame);
    03175
    03176         KiSetRegisterValue(ContextBlock->Fd + 32 + 1,
    03177                            DOUBLE_INFINITY_VALUE_HIGH | (ResultOperand->Sign << 31),
    03178                            ContextBlock->ExceptionFrame,
    03179                            ContextBlock->TrapFrame);
    03180
    03181         TrapFrame->Fir = ContextBlock->BranchAddress;
    03182         return TRUE;
    03183     }
    03184
    03185     //
    03186     // If the overflow bit is set, then right shift the mantissa one bit,
    03187     // accumlate the lost bit with the sticky bits, and adjust the exponent
    03188     // value.
    03189     //
    03190
    03191     if ((ResultOperand->MantissaHigh & (1 << (55 - 32))) != 0) {
    03192         StickyBits |= (ResultOperand->MantissaLow & 0x1);
    03193         ResultOperand->MantissaLow =
    03194                         (ResultOperand->MantissaLow >> 1) |
    03195                                             (ResultOperand->MantissaHigh << 31);
    03196
    03197         ResultOperand->MantissaHigh >>= 1;
    03198         ResultOperand->Exponent += 1;
    03199     }
    03200
    03201     //
    03202     // If the mantissa is not zero, then normalize the mantissa by left
    03203     // shifting one bit at a time until there is a one bit in bit 54.
    03204     //
    03205
    03206     if ((ResultOperand->MantissaLow != 0) || (ResultOperand->MantissaHigh != 0)) {
    03207         while ((ResultOperand->MantissaHigh & (1 << (54 - 32))) == 0) {
    03208             ResultOperand->MantissaHigh =
    03209                         (ResultOperand->MantissaHigh << 1) |
    03210                                             (ResultOperand->MantissaLow >> 31);
    03211
    03212             ResultOperand->MantissaLow <<= 1;
    03213             ResultOperand->Exponent -= 1;
    03214         }
    03215     }
    03216
    03217     //
    03218     // Right shift the mantissa one bit and accumlate the lost bit with the
    03219     // sticky bits.
    03220     //
    03221
    03222     StickyBits |= (ResultOperand->MantissaLow & 0x1);
    03223     ResultOperand->MantissaLow =
    03224                         (ResultOperand->MantissaLow >> 1) |
    03225                                             (ResultOperand->MantissaHigh << 31);
    03226
    03227     ResultOperand->MantissaHigh >>= 1;
    03228
    03229     //
    03230     // Round the result value using the mantissa and the sticky bits,
    03231     //
    03232
    03233     RoundBit = ResultOperand->MantissaLow & 0x1;
    03234     switch (ContextBlock->Round) {
    03235
    03236         //
    03237         // Round to nearest representable number.
    03238         //
    03239
    03240     case ROUND_TO_NEAREST:
    03241         if (RoundBit != 0) {
    03242             if ((StickyBits != 0) || ((ResultOperand->MantissaLow & 0x2) != 0)) {
    03243                 ResultOperand->MantissaLow += 2;
    03244                 if (ResultOperand->MantissaLow < 2) {
    03245                     ResultOperand->MantissaHigh += 1;
    03246                 }
    03247             }
    03248         }
    03249
    03250         break;
    03251
    03252         //
    03253         // Round toward zero.
    03254         //
    03255
    03256     case ROUND_TO_ZERO:
    03257         break;
    03258
    03259         //
    03260         // Round toward plus infinity.
    03261         //
    03262
    03263     case ROUND_TO_PLUS_INFINITY:
    03264         if ((ResultOperand->Sign == 0) &&
    03265             ((StickyBits != 0) || (RoundBit != 0))) {
    03266             ResultOperand->MantissaLow += 2;
    03267             if (ResultOperand->MantissaLow < 2) {
    03268                 ResultOperand->MantissaHigh += 1;
    03269             }
    03270         }
    03271
    03272         break;
    03273
    03274         //
    03275         // Round toward minus infinity.
    03276         //
    03277
    03278     case ROUND_TO_MINUS_INFINITY:
    03279         if ((ResultOperand->Sign != 0) &&
    03280             ((StickyBits != 0) || (RoundBit != 0))) {
    03281             ResultOperand->MantissaLow += 2;
    03282             if (ResultOperand->MantissaLow < 2) {
    03283                 ResultOperand->MantissaHigh += 1;
    03284             }
    03285         }
    03286
    03287         break;
    03288     }
    03289
    03290     //
    03291     // If rounding resulted in a carry into bit 54, then right shift the
    03292     // mantissa one bit and adjust the exponent.
    03293     //
    03294
    03295     if ((ResultOperand->MantissaHigh & (1 << (54 - 32))) != 0) {
    03296         ResultOperand->MantissaLow =
    03297                         (ResultOperand->MantissaLow >> 1) |
    03298                                             (ResultOperand->MantissaHigh << 31);
    03299
    03300         ResultOperand->MantissaHigh >>= 1;
    03301         ResultOperand->Exponent += 1;
    03302     }
    03303
    03304     //
    03305     // Right shift the mantissa one bit to normalize the final result.
    03306     //
    03307
    03308     StickyBits |= ResultOperand->MantissaLow & 0x1;
    03309     ResultOperand->MantissaLow =
    03310                         (ResultOperand->MantissaLow >> 1) |
    03311                                             (ResultOperand->MantissaHigh << 31);
    03312
    03313     ResultOperand->MantissaHigh >>= 1;
    03314
    03315     //
    03316     // If the exponent value is greater than or equal to the maximum
    03317     // exponent value, then overflow has occurred. This results in both
    03318     // the inexact and overflow sticky bits being set in FSR.
    03319     //
    03320     // If the exponent value is less than or equal to the minimum exponent
    03321     // value, the mantissa is nonzero, and the result is inexact or the
    03322     // denormalized result causes loss of accuracy, then underflow has
    03323     // occurred. If denormals are being flushed to zero, then a result of
    03324     // zero is returned. Otherwise, both the inexact and underflow sticky
    03325     // bits are set in FSR.
    03326     //
    03327     // Otherwise, a normal result can be delivered, but it may be inexact.
    03328     // If the result is inexact, then the inexact sticky bit is set in FSR.
    03329     //
    03330
    03331     if (ResultOperand->Exponent >= DOUBLE_MAXIMUM_EXPONENT) {
    03332         Inexact = TRUE;
    03333         Overflow = TRUE;
    03334         Underflow = FALSE;
    03335
    03336         //
    03337         // The overflow value is dependent on the rounding mode.
    03338         //
    03339
    03340         switch (ContextBlock->Round) {
    03341
    03342             //
    03343             // Round to nearest representable number.
    03344             //
    03345             // The result value is infinity with the sign of the result.
    03346             //
    03347
    03348         case ROUND_TO_NEAREST:
    03349             ResultValueLow = DOUBLE_INFINITY_VALUE_LOW;
    03350             ResultValueHigh =
    03351                         DOUBLE_INFINITY_VALUE_HIGH | (ResultOperand->Sign << 31);
    03352
    03353             break;
    03354
    03355             //
    03356             // Round toward zero.
    03357             //
    03358             // The result is the maximum number with the sign of the result.
    03359             //
    03360
    03361         case ROUND_TO_ZERO:
    03362             ResultValueLow = DOUBLE_MAXIMUM_VALUE_LOW;
    03363             ResultValueHigh =
    03364                         DOUBLE_MAXIMUM_VALUE_HIGH | (ResultOperand->Sign << 31);
    03365             break;
    03366
    03367             //
    03368             // Round toward plus infinity.
    03369             //
    03370             // If the sign of the result is positive, then the result is
    03371             // plus infinity. Otherwise, the result is the maximum negative
    03372             // number.
    03373             //
    03374
    03375         case ROUND_TO_PLUS_INFINITY:
    03376             if (ResultOperand->Sign == 0) {
    03377                 ResultValueLow = DOUBLE_INFINITY_VALUE_LOW;
    03378                 ResultValueHigh = DOUBLE_INFINITY_VALUE_HIGH;
    03379
    03380             } else {
    03381                 ResultValueLow = DOUBLE_MAXIMUM_VALUE_LOW;
    03382                 ResultValueHigh = (ULONG)(DOUBLE_MAXIMUM_VALUE_HIGH | (1 << 31));
    03383             }
    03384
    03385             break;
    03386
    03387             //
    03388             // Round toward minus infinity.
    03389             //
    03390             // If the sign of the result is negative, then the result is
    03391             // negative infinity. Otherwise, the result is the maximum
    03392             // positive number.
    03393             //
    03394
    03395
    03396         case ROUND_TO_MINUS_INFINITY:
    03397             if (ResultOperand->Sign != 0) {
    03398                 ResultValueLow = DOUBLE_INFINITY_VALUE_LOW;
    03399                 ResultValueHigh = (ULONG)(DOUBLE_INFINITY_VALUE_HIGH | (1 << 31));
    03400
    03401             } else {
    03402                 ResultValueLow = DOUBLE_MAXIMUM_VALUE_LOW;
    03403                 ResultValueHigh = DOUBLE_MAXIMUM_VALUE_HIGH;
    03404             }
    03405
    03406             break;
    03407         }
    03408
    03409         //
    03410         // Compute the overflow exception result value by subtracting 1536
    03411         // from the exponent.
    03412         //
    03413
    03414         ExceptionResultLow = ResultOperand->MantissaLow;
    03415         ExceptionResultHigh = ResultOperand->MantissaHigh & ((1 << (52 - 32)) - 1);
    03416         ExceptionResultHigh |= ((ResultOperand->Exponent - 1536) << (52 - 32));
    03417         ExceptionResultHigh |= (ResultOperand->Sign << 31);
    03418
    03419     } else {
    03420         if ((ResultOperand->Exponent <= DOUBLE_MINIMUM_EXPONENT) &&
    03421             (ResultOperand->MantissaHigh != 0)) {
    03422             if (((PFSR)&TrapFrame->Fsr)->FS == 0) {
    03423                 DenormalizeShift = 1 - ResultOperand->Exponent;
    03424                 if (DenormalizeShift >= 53) {
    03425                     DenormalizeShift = 53;
    03426                 }
    03427
    03428                 if (DenormalizeShift >= 32) {
    03429                     DenormalizeShift -= 32;
    03430                     StickyBits |= ResultOperand->MantissaLow |
    03431                         (ResultOperand->MantissaHigh & ((1 << DenormalizeShift) - 1));
    03432
    03433                     ResultValueLow = ResultOperand->MantissaHigh >> DenormalizeShift;
    03434                     ResultValueHigh = 0;
    03435
    03436                 } else if (DenormalizeShift > 0) {
    03437                     StickyBits |=
    03438                         ResultOperand->MantissaLow & ((1 << DenormalizeShift) - 1);
    03439
    03440                     ResultValueLow =
    03441                         (ResultOperand->MantissaLow >> DenormalizeShift) |
    03442                         (ResultOperand->MantissaHigh << (32 - DenormalizeShift));
    03443
    03444                     ResultValueHigh =
    03445                             (ResultOperand->MantissaHigh >> DenormalizeShift);
    03446
    03447                 } else {
    03448                     ResultValueLow = ResultOperand->MantissaLow;
    03449                     ResultValueHigh = ResultOperand->MantissaHigh;
    03450                 }
    03451
    03452                 ResultValueHigh |= (ResultOperand->Sign << 31);
    03453                 if (StickyBits != 0) {
    03454                     Inexact = TRUE;
    03455                     Overflow = FALSE;
    03456                     Underflow = TRUE;
    03457
    03458                     //
    03459                     // Compute the underflow exception result value by adding
    03460                     // 1536 to the exponent.
    03461                     //
    03462
    03463                     ExceptionResultLow = ResultOperand->MantissaLow;
    03464                     ExceptionResultHigh = ResultOperand->MantissaHigh & ((1 << (52 - 32)) - 1);
    03465                     ExceptionResultHigh |= ((ResultOperand->Exponent + 1536) << (52 - 32));
    03466                     ExceptionResultHigh |= (ResultOperand->Sign << 31);
    03467
    03468                 } else {
    03469                     Inexact = FALSE;
    03470                     Overflow = FALSE;
    03471                     Underflow = FALSE;
    03472                 }
    03473
    03474             } else {
    03475                 ResultValueLow = 0;
    03476                 ResultValueHigh = 0;
    03477                 Inexact = FALSE;
    03478                 Overflow = FALSE;
    03479                 Underflow = FALSE;
    03480             }
    03481
    03482         } else {
    03483             if (ResultOperand->MantissaHigh == 0) {
    03484                 ResultOperand->Exponent = 0;
    03485             }
    03486
    03487             ResultValueLow = ResultOperand->MantissaLow;
    03488             ResultValueHigh = ResultOperand->MantissaHigh & ((1 << (52 - 32)) - 1);
    03489             ResultValueHigh |= (ResultOperand->Exponent << (52 - 32));
    03490             ResultValueHigh |= (ResultOperand->Sign << 31);
    03491             Inexact = StickyBits ? TRUE : FALSE;
    03492             Overflow = FALSE;
    03493             Underflow = FALSE;
    03494         }
    03495     }
    03496
    03497     //
    03498     // Check to determine if an exception should be delivered or the result
    03499     // should be written to the destination register.
    03500     //
    03501
    03502     if (Overflow != FALSE) {
    03503         ((PFSR)&TrapFrame->Fsr)->SI = 1;
    03504         ((PFSR)&TrapFrame->Fsr)->SO = 1;
    03505         if ((((PFSR)&TrapFrame->Fsr)->EO != 0) ||
    03506             (((PFSR)&TrapFrame->Fsr)->EI != 0)) {
    03507             if (((PFSR)&TrapFrame->Fsr)->EO != 0) {
    03508                 ExceptionRecord->ExceptionCode = STATUS_FLOAT_OVERFLOW;
    03509
    03510             } else {
    03511                 ExceptionRecord->ExceptionCode = STATUS_FLOAT_INEXACT_RESULT;
    03512             }
    03513
    03514             IeeeValue = (PFP_IEEE_VALUE)&ExceptionRecord->ExceptionInformation[2];
    03515             IeeeValue->Value.Fp64Value.W[0] = ExceptionResultLow;
    03516             IeeeValue->Value.Fp64Value.W[1] = ExceptionResultHigh;
    03517             ((PFSR)&TrapFrame->Fsr)->XI = 1;
    03518             ((PFSR)&TrapFrame->Fsr)->XO = 1;
    03519             return FALSE;
    03520         }
    03521
    03522     } else if (Underflow != FALSE) {
    03523         ((PFSR)&TrapFrame->Fsr)->SI = 1;
    03524         ((PFSR)&TrapFrame->Fsr)->SU = 1;
    03525         if ((((PFSR)&TrapFrame->Fsr)->EU != 0) ||
    03526             (((PFSR)&TrapFrame->Fsr)->EI != 0)) {
    03527             if (((PFSR)&TrapFrame->Fsr)->EU != 0) {
    03528                 ExceptionRecord->ExceptionCode = STATUS_FLOAT_UNDERFLOW;
    03529
    03530             } else {
    03531                 ExceptionRecord->ExceptionCode = STATUS_FLOAT_INEXACT_RESULT;
    03532             }
    03533
    03534             IeeeValue = (PFP_IEEE_VALUE)&ExceptionRecord->ExceptionInformation[2];
    03535             IeeeValue->Value.Fp64Value.W[0] = ExceptionResultLow;
    03536             IeeeValue->Value.Fp64Value.W[1] = ExceptionResultHigh;
    03537             ((PFSR)&TrapFrame->Fsr)->XI = 1;
    03538             ((PFSR)&TrapFrame->Fsr)->XU = 1;
    03539             return FALSE;
    03540         }
    03541
    03542     } else if (Inexact != FALSE) {
    03543         ((PFSR)&TrapFrame->Fsr)->SI = 1;
    03544         if (((PFSR)&TrapFrame->Fsr)->EI != 0) {
    03545             ExceptionRecord->ExceptionCode = STATUS_FLOAT_INEXACT_RESULT;
    03546             ((PFSR)&TrapFrame->Fsr)->XI = 1;
    03547             IeeeValue = (PFP_IEEE_VALUE)&ExceptionRecord->ExceptionInformation[2];
    03548             IeeeValue->Value.Fp64Value.W[0] = ResultValueLow;
    03549             IeeeValue->Value.Fp64Value.W[1] = ResultValueHigh;
    03550             return FALSE;
    03551         }
    03552     }
    03553
    03554     //
    03555     // Set the destination register value, update the return address,
    03556     // and return a value of TRUE.
    03557     //
    03558
    03559     KiSetRegisterValue(ContextBlock->Fd + 32,
    03560                        ResultValueLow,
    03561                        ContextBlock->ExceptionFrame,
    03562                        ContextBlock->TrapFrame);
    03563
    03564     KiSetRegisterValue(ContextBlock->Fd + 32 + 1,
    03565                        ResultValueHigh,
    03566                        ContextBlock->ExceptionFrame,
    03567                        ContextBlock->TrapFrame);
    03568
    03569     TrapFrame->Fir = ContextBlock->BranchAddress;
    03570     return TRUE;
    03571 }

BOOLEAN KiNormalizeLongword | ( | IN PFP_CONTEXT_BLOCK | ContextBlock,
|  | IN PFP_DOUBLE_OPERAND | ResultOperand
| ) |

Definition at line 3574 of file mips/floatem.c.

References FALSE, KiInvalidOperationLongword(), KiSetRegisterValue(), and TRUE.

Referenced by KiEmulateFloating().

    03581                    :
    03582
    03583     This function is called to convert a result value to a longword result.
    03584
    03585     N.B. The result value is specified with a guard bit on the right,
    03586         the hidden bit (if appropriate), and an overlfow bit of zero.
    03587         The result format is:
    03588
    03589         <63:55> - zero
    03590         <54 - hidden bit
    03591         <53:2> - mantissa
    03592         <1> - guard bit
    03593         <0> - round bit
    03594
    03595         There are no sticky bits.
    03596
    03597 Arguments:
    03598
    03599     ContextBlock - Supplies a pointer to the emulation context block.
    03600
    03601     ResultOperand - Supplies a pointer to the result operand value.
    03602
    03603 Return Value:
    03604
    03605     If there is not an exception, or the exception is handled, then a proper
    03606     result is stored in the destination result, the continuation address is
    03607     set, and a value of TRUE is returned. Otherwise, no value is stored and
    03608     a value of FALSE is returned.
    03609
    03610 --*/
    03611
    03612 {
    03613
    03614     PEXCEPTION_RECORD ExceptionRecord;
    03615     LONG ExponentShift;
    03616     PFP_IEEE_VALUE IeeeValue;
    03617     BOOLEAN Inexact;
    03618     BOOLEAN Overflow;
    03619     ULONG ResultValue;
    03620     ULONG RoundBit;
    03621     ULONG StickyBits;
    03622     PKTRAP_FRAME TrapFrame;
    03623
    03624     //
    03625     // Subtract out the exponent bias and divide the cases into right
    03626     // and left shifts.
    03627     //
    03628
    03629     ExceptionRecord = ContextBlock->ExceptionRecord;
    03630     TrapFrame = ContextBlock->TrapFrame;
    03631     ExponentShift = ResultOperand->Exponent - DOUBLE_EXPONENT_BIAS;
    03632     if (ExponentShift < 23) {
    03633
    03634         //
    03635         // The integer value is less than 2**23 and a right shift must
    03636         // be performed.
    03637         //
    03638
    03639         ExponentShift = 22 - ExponentShift;
    03640         if (ExponentShift > 24) {
    03641             ExponentShift = 24;
    03642         }
    03643
    03644         StickyBits =
    03645                 (ResultOperand->MantissaLow >> 2) |
    03646                 (ResultOperand->MantissaHigh << (32 - ExponentShift));
    03647
    03648         ResultValue = ResultOperand->MantissaHigh >> ExponentShift;
    03649         Overflow = FALSE;
    03650
    03651     } else {
    03652
    03653         //
    03654         // The integer value is two or greater and a left shift must be
    03655         // performed.
    03656         //
    03657
    03658         ExponentShift -= 22;
    03659         if (ExponentShift <= (31 - 22)) {
    03660             StickyBits = ResultOperand->MantissaLow << ExponentShift;
    03661             ResultValue =
    03662                 (ResultOperand->MantissaHigh << ExponentShift) |
    03663                 (ResultOperand->MantissaLow >> (32 - ExponentShift));
    03664
    03665             Overflow = FALSE;
    03666
    03667         } else {
    03668             Overflow = TRUE;
    03669         }
    03670     }
    03671
    03672     //
    03673     // Round the result value using the mantissa and the sticky bits,
    03674     //
    03675
    03676     RoundBit = StickyBits >> 31;
    03677     StickyBits <<= 1;
    03678     switch (ContextBlock->Round) {
    03679
    03680         //
    03681         // Round to nearest representable number.
    03682         //
    03683
    03684     case ROUND_TO_NEAREST:
    03685         if (RoundBit != 0) {
    03686             if ((StickyBits != 0) || ((ResultValue & 0x1) != 0)) {
    03687                 ResultValue += 1;
    03688                 if (ResultValue == 0) {
    03689                     Overflow = TRUE;
    03690                 }
    03691             }
    03692         }
    03693
    03694         break;
    03695
    03696         //
    03697         // Round toward zero.
    03698         //
    03699
    03700     case ROUND_TO_ZERO:
    03701         break;
    03702
    03703         //
    03704         // Round toward plus infinity.
    03705         //
    03706
    03707     case ROUND_TO_PLUS_INFINITY:
    03708         if ((ResultOperand->Sign == 0) && (StickyBits != 0)) {
    03709             ResultValue += 1;
    03710             if (ResultValue == 0) {
    03711                 Overflow = TRUE;
    03712             }
    03713         }
    03714
    03715         break;
    03716
    03717         //
    03718         // Round toward minus infinity.
    03719         //
    03720
    03721     case ROUND_TO_MINUS_INFINITY:
    03722         if ((ResultOperand->Sign != 0) && (StickyBits != 0)) {
    03723             ResultValue += 1;
    03724             if (ResultValue == 0) {
    03725                 Overflow = TRUE;
    03726             }
    03727         }
    03728
    03729         break;
    03730     }
    03731
    03732     //
    03733     // If the result value is positive and the result is negative, then
    03734     // overflow has occurred. Otherwise, negate the result value and
    03735     // check if the result is negative. If the result is positive, then
    03736     // overflow has occurred.
    03737     //
    03738
    03739     if (ResultOperand->Sign == 0) {
    03740         if ((ResultValue >> 31) != 0) {
    03741             Overflow = TRUE;
    03742         }
    03743
    03744     } else {
    03745         ResultValue = ~ResultValue + 1;
    03746         if ((ResultValue >> 31) == 0) {
    03747             Overflow = TRUE;
    03748         }
    03749     }
    03750
    03751     //
    03752     // Check to determine if an exception should be delivered or the result
    03753     // should be written to the destination register.
    03754     //
    03755
    03756     if (Overflow != FALSE) {
    03757         return KiInvalidOperationLongword(ContextBlock,
    03758                                           FALSE,
    03759                                           0);
    03760
    03761     } else if ((StickyBits | RoundBit) != 0) {
    03762         ((PFSR)&TrapFrame->Fsr)->SI = 1;
    03763         if (((PFSR)&TrapFrame->Fsr)->EI != 0) {
    03764             ExceptionRecord->ExceptionCode = STATUS_FLOAT_INEXACT_RESULT;
    03765             ((PFSR)&TrapFrame->Fsr)->XI = 1;
    03766             IeeeValue = (PFP_IEEE_VALUE)&ExceptionRecord->ExceptionInformation[2];
    03767             IeeeValue->Value.U32Value = ResultValue;
    03768             return FALSE;
    03769         }
    03770
    03771     }
    03772
    03773     //
    03774     // Set the destination register value, update the return address,
    03775     // and return a value of TRUE.
    03776     //
    03777
    03778     KiSetRegisterValue(ContextBlock->Fd + 32,
    03779                        ResultValue,
    03780                        ContextBlock->ExceptionFrame,
    03781                        ContextBlock->TrapFrame);
    03782
    03783     TrapFrame->Fir = ContextBlock->BranchAddress;
    03784     return TRUE;
    03785 }

BOOLEAN KiNormalizeQuadword | ( | IN PFP_CONTEXT_BLOCK | ContextBlock,
|  | IN PFP_DOUBLE_OPERAND | ResultOperand
| ) |

| Referenced by KiEmulateFloating().

BOOLEAN KiNormalizeSingle | ( | IN PFP_CONTEXT_BLOCK | ContextBlock,
|  | IN PFP_SINGLE_OPERAND | ResultOperand,
|  | IN ULONG | StickyBits
| ) |

| Referenced by KiEmulateFloating().

ULONG KiSquareRootDouble | ( | IN PULARGE_INTEGER | DoubleValue | ) |

| Referenced by KiEmulateFloating().

ULONG KiSquareRootSingle | ( | IN PULONG | SingleValue | ) |

| Referenced by KiEmulateFloating().

VOID KiUnpackDouble | ( | IN ULONG | Source,
|  | IN PFP_CONTEXT_BLOCK | ContextBlock,
|  | OUT PFP_DOUBLE_OPERAND | DoubleOperand
| ) |

| Referenced by KiEmulateFloating().

VOID KiUnpackSingle | ( | IN ULONG | Source,
|  | IN PFP_CONTEXT_BLOCK | ContextBlock,
|  | OUT PFP_SINGLE_OPERAND | SingleOperand
| ) |

| Referenced by KiEmulateFloating().