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
00328
00329
00330
00331 ExceptionAddress = ExceptionRecord->ExceptionAddress;
00332
00333
00334
00335
00336
00337
00338
00339
00340
try {
00341
00342
00343
00344
00345
00346
00347
00348
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
00361
00362
00363
KeGetCurrentPrcb()->KeFloatingEmulationCount += 1;
00364
00365
00366
00367
00368
00369
00370
00371 ContextBlock.
ExceptionRecord = ExceptionRecord;
00372 ContextBlock.
ExceptionFrame = ExceptionFrame;
00373 ContextBlock.
TrapFrame = TrapFrame;
00374 ContextBlock.
Round = ((PFSR)&TrapFrame->Fsr)->RM;
00375
00376
00377
00378
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
00391
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
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
00414
00415
00416
if ((Function <= FLOAT_DIVIDE) || (Function >= FLOAT_COMPARE)) {
00417
00418
00419
00420
00421
00422
if (Format == FORMAT_SINGLE) {
00423
KiUnpackSingle(Fs, &ContextBlock, &SingleOperand1);
00424
KiUnpackSingle(Ft, &ContextBlock, &SingleOperand2);
00425
00426
00427
00428
00429
00430
00431
00432
if ((SingleOperand1.
Nan !=
FALSE) || (SingleOperand2.
Nan !=
FALSE)) {
00433
if (Function < FLOAT_COMPARE) {
00434
00435
00436
00437
00438
00439
00440
00441
00442
00443
00444
return KiInvalidOperationSingle(&ContextBlock,
00445 TRUE,
00446 &SingleOperand1,
00447 &SingleOperand2);
00448
00449 }
else {
00450
00451
00452
00453
00454
00455
00456
00457
00458
00459
00460
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
00496
00497
00498
00499
00500
if ((DoubleOperand1.
Nan !=
FALSE) || (DoubleOperand2.
Nan !=
FALSE)) {
00501
if (Function < FLOAT_COMPARE) {
00502
00503
00504
00505
00506
00507
00508
00509
00510
00511
00512
return KiInvalidOperationDouble(&ContextBlock,
00513 TRUE,
00514 &DoubleOperand1,
00515 &DoubleOperand2);
00516
00517 }
else {
00518
00519
00520
00521
00522
00523
00524
00525
00526
00527
00528
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
00566
00567
00568
if (Format == FORMAT_SINGLE) {
00569
KiUnpackSingle(Fs, &ContextBlock, &SingleOperand1);
00570
00571
00572
00573
00574
00575
00576
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
00596
00597
00598
00599
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
00636
00637
00638
switch (Function) {
00639
00640
00641
00642
00643
00644
00645
00646
00647
case FLOAT_SUBTRACT:
00648 Negation = 0x1;
00649
00650
00651
00652
00653
00654
00655
00656
00657
00658
00659
00660
00661
00662
00663
00664
00665
00666
00667
00668
00669
00670
00671
00672
00673
00674
00675
case FLOAT_ADD:
00676
if (Format == FORMAT_SINGLE) {
00677
00678
00679
00680
00681
00682
00683 SingleOperand2.
Sign ^= Negation;
00684
00685
00686
00687
00688
00689
if (SingleOperand2.
Exponent > SingleOperand1.
Exponent) {
00690 SingleOperand3 = SingleOperand2;
00691 SingleOperand2 = SingleOperand1;
00692 SingleOperand1 = SingleOperand3;
00693 }
00694
00695
00696
00697
00698
00699
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
00715
00716
00717
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
00746
00747
00748
return KiNormalizeSingle(&ContextBlock,
00749 &SingleOperand1,
00750 StickyBits);
00751
00752 }
else if (Format == FORMAT_DOUBLE) {
00753
00754
00755
00756
00757
00758
00759 DoubleOperand2.
Sign ^= Negation;
00760
00761
00762
00763
00764
00765
if (DoubleOperand2.
Exponent > DoubleOperand1.
Exponent) {
00766 DoubleOperand3 = DoubleOperand2;
00767 DoubleOperand2 = DoubleOperand1;
00768 DoubleOperand1 = DoubleOperand3;
00769 }
00770
00771
00772
00773
00774
00775
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
00814
00815
00816
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
00863
00864
00865
return KiNormalizeDouble(&ContextBlock,
00866 &DoubleOperand1,
00867 StickyBits);
00868
00869 }
else {
00870
break;
00871 }
00872
00873
00874
00875
00876
00877
00878
00879
00880
00881
00882
00883
00884
case FLOAT_MULTIPLY:
00885
if (Format == FORMAT_SINGLE) {
00886
00887
00888
00889
00890
00891
if (SingleOperand2.
Exponent > SingleOperand1.
Exponent) {
00892 SingleOperand3 = SingleOperand2;
00893 SingleOperand2 = SingleOperand1;
00894 SingleOperand1 = SingleOperand3;
00895 }
00896
00897
00898
00899
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
00914
00915
00916
00917
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
00928
00929
00930 SingleOperand1.
Sign ^= SingleOperand2.
Sign;
00931 SingleOperand1.
Exponent +=
00932 SingleOperand2.
Exponent - SINGLE_EXPONENT_BIAS;
00933
00934
00935
00936
00937
00938
return KiNormalizeSingle(&ContextBlock,
00939 &SingleOperand1,
00940 StickyBits);
00941
00942 }
else if (Format == FORMAT_DOUBLE) {
00943
00944
00945
00946
00947
00948
if (DoubleOperand2.
Exponent > DoubleOperand1.
Exponent) {
00949 DoubleOperand3 = DoubleOperand2;
00950 DoubleOperand2 = DoubleOperand1;
00951 DoubleOperand1 = DoubleOperand3;
00952 }
00953
00954
00955
00956
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
00971
00972
00973
00974
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
00990
00991
00992
00993
00994
00995
00996
00997
00998
00999
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
01050
01051
01052 DoubleOperand1.
Sign ^= DoubleOperand2.
Sign;
01053 DoubleOperand1.
Exponent +=
01054 DoubleOperand2.
Exponent - DOUBLE_EXPONENT_BIAS;
01055
01056
01057
01058
01059
01060
return KiNormalizeDouble(&ContextBlock,
01061 &DoubleOperand1,
01062 StickyBits);
01063
01064 }
else {
01065
break;
01066 }
01067
01068
01069
01070
01071
01072
01073
01074
01075
01076
01077
01078
01079
01080
case FLOAT_DIVIDE:
01081
if (Format == FORMAT_SINGLE) {
01082
01083
01084
01085
01086
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
01104
01105
01106
01107
if ((SingleOperand2.
Infinity ==
FALSE) &&
01108 (SingleOperand2.
Mantissa == 0)) {
01109
return KiDivideByZeroSingle(&ContextBlock,
01110 &SingleOperand1,
01111 &SingleOperand2);
01112 }
01113
01114
01115
01116
01117
01118
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
01139
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
01155
01156
01157 SingleOperand3.
Sign = SingleOperand1.
Sign ^ SingleOperand2.
Sign;
01158 SingleOperand3.
Exponent = SingleOperand1.
Exponent -
01159 SingleOperand2.
Exponent + SINGLE_EXPONENT_BIAS;
01160
01161
01162
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
01175
01176
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
01194
01195
01196
01197
if ((DoubleOperand2.
Infinity ==
FALSE) &&
01198 (DoubleOperand2.
MantissaHigh == 0)) {
01199
return KiDivideByZeroDouble(&ContextBlock,
01200 &DoubleOperand1,
01201 &DoubleOperand2);
01202 }
01203
01204
01205
01206
01207
01208
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
01230
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
01262
01263
01264 DoubleOperand3.
Sign = DoubleOperand1.
Sign ^ DoubleOperand2.
Sign;
01265 DoubleOperand3.
Exponent = DoubleOperand1.
Exponent -
01266 DoubleOperand2.
Exponent + DOUBLE_EXPONENT_BIAS;
01267
01268
01269
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
01284
01285
01286
case FLOAT_SQUARE_ROOT:
01287
if (Format == FORMAT_SINGLE) {
01288
01289
01290
01291
01292
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
01305
01306
01307
01308
if (SingleOperand1.
Sign != 0) {
01309
return KiInvalidOperationSingle(&ContextBlock,
01310 FALSE,
01311 &SingleOperand1,
01312 &SingleOperand1);
01313 }
01314
01315
01316
01317
01318
01319
01320
01321
01322
01323
01324
01325
01326
01327
01328
01329
01330
01331
01332
01333
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
01356
01357
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
01370
01371
01372
01373
if (DoubleOperand1.
Sign != 0) {
01374
return KiInvalidOperationDouble(&ContextBlock,
01375 FALSE,
01376 &DoubleOperand1,
01377 &DoubleOperand1);
01378 }
01379
01380
01381
01382
01383
01384
01385
01386
01387
01388
01389
01390
01391
01392
01393
01394
01395
01396
01397
01398
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
01428
01429
01430
01431
01432
01433
case FLOAT_ABSOLUTE:
01434
if (Format == FORMAT_SINGLE) {
01435
01436
01437
01438
01439
01440
01441 SingleOperand1.
Sign = 0;
01442
return KiNormalizeSingle(&ContextBlock,
01443 &SingleOperand1,
01444 0);
01445
01446 }
else if (Format == FORMAT_DOUBLE) {
01447
01448
01449
01450
01451
01452
01453 DoubleOperand1.
Sign = 0;
01454
return KiNormalizeDouble(&ContextBlock,
01455 &DoubleOperand1,
01456 0);
01457
01458 }
else {
01459
break;
01460 }
01461
01462
01463
01464
01465
01466
01467
01468
01469
case FLOAT_MOVE:
01470
if (Format == FORMAT_SINGLE) {
01471
01472
01473
01474
01475
01476
01477
return KiNormalizeSingle(&ContextBlock,
01478 &SingleOperand1,
01479 0);
01480
01481 }
else if (Format == FORMAT_DOUBLE) {
01482
01483
01484
01485
01486
01487
01488
return KiNormalizeDouble(&ContextBlock,
01489 &DoubleOperand1,
01490 0);
01491
01492 }
else {
01493
break;
01494 }
01495
01496
01497
01498
01499
01500
01501
01502
01503
case FLOAT_NEGATE:
01504
if (Format == FORMAT_SINGLE) {
01505
01506
01507
01508
01509
01510
01511 SingleOperand1.
Sign ^= 0x1;
01512
return KiNormalizeSingle(&ContextBlock,
01513 &SingleOperand1,
01514 0);
01515
01516 }
else if (Format == FORMAT_DOUBLE) {
01517
01518
01519
01520
01521
01522
01523 DoubleOperand1.
Sign ^= 0x1;
01524
return KiNormalizeDouble(&ContextBlock,
01525 &DoubleOperand1,
01526 0);
01527
01528 }
else {
01529
break;
01530 }
01531
01532
01533
01534
01535
01536
01537
01538
01539
01540
01541
01542
01543
01544
01545
case FLOAT_COMPARE_SINGLE:
01546
01547
01548
01549
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
01566
01567
01568
if (SingleOperand1.
Sign < SingleOperand2.
Sign) {
01569
01570
01571
01572
01573
01574 CompareEqual =
FALSE;
01575 CompareLess =
FALSE;
01576
01577 }
else if (SingleOperand1.
Sign > SingleOperand2.
Sign) {
01578
01579
01580
01581
01582
01583 CompareEqual =
FALSE;
01584 CompareLess =
TRUE;
01585
01586 }
else {
01587
01588
01589
01590
01591
01592
01593
01594
01595
if (SingleOperand1.
Sign == 0) {
01596
01597
01598
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
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
01657
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
01675
01676
01677
01678
01679
01680
01681
01682
01683
01684
01685
01686
case FLOAT_COMPARE_DOUBLE:
01687
01688
01689
01690
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
01707
01708
01709
if (DoubleOperand1.
Sign < DoubleOperand2.
Sign) {
01710
01711
01712
01713
01714
01715 CompareEqual =
FALSE;
01716 CompareLess =
FALSE;
01717
01718 }
else if (DoubleOperand1.
Sign > DoubleOperand2.
Sign) {
01719
01720
01721
01722
01723
01724 CompareEqual =
FALSE;
01725 CompareLess =
TRUE;
01726
01727 }
else {
01728
01729
01730
01731
01732
01733
01734
01735
01736
if (DoubleOperand1.
Sign == 0) {
01737
01738
01739
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
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
01826
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
01844
01845
01846
01847
01848
01849
01850
01851
01852
01853
01854
case FLOAT_CONVERT_SINGLE:
01855
if (Format == FORMAT_SINGLE) {
01856
break;
01857
01858 }
else if (Format == FORMAT_DOUBLE) {
01859
01860
01861
01862
01863
01864
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
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
01898
01899
01900
return KiNormalizeSingle(&ContextBlock,
01901 &SingleOperand1,
01902 StickyBits);
01903
01904 }
else if (Format == FORMAT_LONGWORD) {
01905
01906
01907
01908
01909
01910
if (Longword < 0) {
01911 SingleOperand1.
Sign = 0x1;
01912 Longword = -Longword;
01913
01914 }
else {
01915 SingleOperand1.
Sign = 0;
01916 }
01917
01918
01919
01920
01921
01922 SingleOperand1.
Infinity =
FALSE;
01923 SingleOperand1.
Nan =
FALSE;
01924
01925
01926
01927
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
01948
01949
01950
return KiNormalizeSingle(&ContextBlock,
01951 &SingleOperand1,
01952 StickyBits);
01953
01954 }
else if (Format == FORMAT_QUADWORD) {
01955
01956
01957
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
01970
01971
01972 SingleOperand1.
Infinity =
FALSE;
01973 SingleOperand1.
Nan =
FALSE;
01974
01975
01976
01977
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
01998
01999
02000
return KiNormalizeSingle(&ContextBlock,
02001 &SingleOperand1,
02002 StickyBits);
02003
02004 }
else {
02005
break;
02006 }
02007
02008
02009
02010
02011
02012
02013
02014
02015
02016
02017
02018
02019
02020
02021
case FLOAT_CONVERT_DOUBLE:
02022
if (Format == FORMAT_SINGLE) {
02023
02024
02025
02026
02027
02028
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
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
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
02076
02077
02078
if (Longword < 0) {
02079 DoubleOperand1.
Sign = 0x1;
02080 Longword = -Longword;
02081
02082 }
else {
02083 DoubleOperand1.
Sign = 0;
02084 }
02085
02086
02087
02088
02089
02090 DoubleOperand1.
Infinity =
FALSE;
02091 DoubleOperand1.
Nan =
FALSE;
02092
02093
02094
02095
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
02114
02115
02116
return KiNormalizeDouble(&ContextBlock,
02117 &DoubleOperand1,
02118 0);
02119
02120 }
else if (Format == FORMAT_QUADWORD) {
02121
02122
02123
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
02136
02137
02138 DoubleOperand1.
Infinity =
FALSE;
02139 DoubleOperand1.
Nan =
FALSE;
02140
02141
02142
02143
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
02164
02165
02166
return KiNormalizeDouble(&ContextBlock,
02167 &DoubleOperand1,
02168 StickyBits);
02169
02170 }
else {
02171
break;
02172 }
02173
02174
02175
02176
02177
02178
02179
02180
02181
02182
02183
02184
02185
02186
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
02211
02212
02213
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
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
02237
02238
02239
return KiNormalizeQuadword(&ContextBlock, &DoubleOperand1);
02240
02241 }
else if (Format == FORMAT_DOUBLE) {
02242
02243
02244
02245
02246
02247
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
02259
02260
02261
return KiNormalizeQuadword(&ContextBlock, &DoubleOperand1);
02262
02263 }
else {
02264
break;
02265 }
02266
02267
02268
02269
02270
02271
02272
02273
02274
02275
02276
02277
02278
02279
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
02304
02305
02306
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
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
02332
02333
02334
return KiNormalizeLongword(&ContextBlock, &DoubleOperand1);
02335
02336 }
else if (Format == FORMAT_DOUBLE) {
02337
02338
02339
02340
02341
02342
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
02354
02355
02356
return KiNormalizeLongword(&ContextBlock, &DoubleOperand1);
02357
02358 }
else {
02359
break;
02360 }
02361
02362
02363
02364
02365
02366
default :
02367
break;
02368 }
02369
02370
02371
02372
02373
02374
02375 ExceptionRecord->ExceptionCode = STATUS_ILLEGAL_INSTRUCTION;
02376
return FALSE;
02377
02378
02379
02380
02381
02382
02383 } except (
KiCopyInformation(ExceptionRecord,
02384 (GetExceptionInformation())->ExceptionRecord)) {
02385
02386
02387
02388
02389
02390 ExceptionRecord->ExceptionAddress = ExceptionAddress;
02391
return FALSE;
02392 }
02393 }