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_BLOCKPFP_CONTEXT_BLOCK
typedef _FP_DOUBLE_OPERAND FP_DOUBLE_OPERAND
typedef _FP_DOUBLE_OPERANDPFP_DOUBLE_OPERAND
typedef _FP_SINGLE_OPERAND FP_SINGLE_OPERAND
typedef _FP_SINGLE_OPERANDPFP_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().


Generated on Sat May 15 19:43:41 2004 for test by doxygen 1.3.7