00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
#include "ki.h"
00064
00065
00066
00067
00068
00069 #define DOUBLE_SIGNAL_NAN_MASK (1 << (53 - 32))
00070 #define SINGLE_SIGNAL_NAN_MASK (1 << 24)
00071
00072
00073
00074
00075
00076 #define DOUBLE_QUIET_NAN_MASK (1 << (51 - 32))
00077 #define SINGLE_QUIET_NAN_MASK (1 << 22)
00078
00079
00080
00081
00082
00083 #define DOUBLE_QUIET_NAN_PREFIX 0x7ff00000
00084 #define SINGLE_QUIET_NAN_PREFIX 0x7f800000
00085
00086
00087
00088
00089
00090 #define COMPARE_UNORDERED_MASK (1 << 0)
00091 #define COMPARE_EQUAL_MASK (1 << 1)
00092 #define COMPARE_LESS_MASK (1 << 2)
00093 #define COMPARE_ORDERED_MASK (1 << 3)
00094
00095
00096
00097
00098
00099
typedef struct _FP_CONTEXT_BLOCK {
00100 ULONG
Fd;
00101 ULONG
BranchAddress;
00102 PEXCEPTION_RECORD
ExceptionRecord;
00103 PKEXCEPTION_FRAME
ExceptionFrame;
00104 PKTRAP_FRAME
TrapFrame;
00105 ULONG
Round;
00106 }
FP_CONTEXT_BLOCK, *
PFP_CONTEXT_BLOCK;
00107
00108
00109
00110
00111
00112
typedef struct _FP_DOUBLE_OPERAND {
00113
union {
00114
struct {
00115 ULONG
MantissaLow;
00116 LONG
MantissaHigh;
00117 };
00118
00119 LONGLONG
Mantissa;
00120 };
00121
00122 LONG
Exponent;
00123 LONG
Sign;
00124 BOOLEAN
Infinity;
00125 BOOLEAN
Nan;
00126 }
FP_DOUBLE_OPERAND, *
PFP_DOUBLE_OPERAND;
00127
00128
typedef struct _FP_SINGLE_OPERAND {
00129 LONG
Mantissa;
00130 LONG
Exponent;
00131 LONG
Sign;
00132 BOOLEAN
Infinity;
00133 BOOLEAN
Nan;
00134 }
FP_SINGLE_OPERAND, *
PFP_SINGLE_OPERAND;
00135
00136
00137
00138
00139
00140 BOOLEAN
00141
KiDivideByZeroDouble (
00142 IN PFP_CONTEXT_BLOCK ContextBlock,
00143 IN PFP_DOUBLE_OPERAND DoubleOperand1,
00144 IN PFP_DOUBLE_OPERAND DoubleOperand2
00145 );
00146
00147 BOOLEAN
00148
KiDivideByZeroSingle (
00149 IN PFP_CONTEXT_BLOCK ContextBlock,
00150 IN PFP_SINGLE_OPERAND SingleOperand1,
00151 IN PFP_SINGLE_OPERAND SingleOperand2
00152 );
00153
00154 BOOLEAN
00155
KiInvalidCompareDouble (
00156 IN PFP_CONTEXT_BLOCK ContextBlock,
00157 IN BOOLEAN CheckForNan,
00158 IN PFP_DOUBLE_OPERAND DoubleOperand1,
00159 IN PFP_DOUBLE_OPERAND DoubleOperand2
00160 );
00161
00162 BOOLEAN
00163
KiInvalidCompareSingle (
00164 IN PFP_CONTEXT_BLOCK ContextBlock,
00165 IN BOOLEAN CheckForNan,
00166 IN PFP_SINGLE_OPERAND SingleOperand1,
00167 IN PFP_SINGLE_OPERAND SingleOperand2
00168 );
00169
00170 BOOLEAN
00171
KiInvalidOperationDouble (
00172 IN PFP_CONTEXT_BLOCK ContextBlock,
00173 IN BOOLEAN CheckForNan,
00174 IN PFP_DOUBLE_OPERAND DoubleOperand1,
00175 IN PFP_DOUBLE_OPERAND DoubleOperand2
00176 );
00177
00178 BOOLEAN
00179
KiInvalidOperationLongword (
00180 IN PFP_CONTEXT_BLOCK ContextBlock,
00181 IN BOOLEAN Infinity,
00182 IN LONG Sign
00183 );
00184
00185 BOOLEAN
00186
KiInvalidOperationQuadword (
00187 IN PFP_CONTEXT_BLOCK ContextBlock,
00188 IN BOOLEAN Infinity,
00189 IN LONG Sign
00190 );
00191
00192 BOOLEAN
00193
KiInvalidOperationSingle (
00194 IN PFP_CONTEXT_BLOCK ContextBlock,
00195 IN BOOLEAN CheckForNan,
00196 IN PFP_SINGLE_OPERAND SingleOperand1,
00197 IN PFP_SINGLE_OPERAND SingleOperand2
00198 );
00199
00200 BOOLEAN
00201
KiNormalizeDouble (
00202 IN PFP_CONTEXT_BLOCK ContextBlock,
00203 IN PFP_DOUBLE_OPERAND ResultOperand,
00204 IN ULONG StickyBits
00205 );
00206
00207 BOOLEAN
00208
KiNormalizeLongword (
00209 IN PFP_CONTEXT_BLOCK ContextBlock,
00210 IN PFP_DOUBLE_OPERAND ResultOperand
00211 );
00212
00213 BOOLEAN
00214
KiNormalizeQuadword (
00215 IN PFP_CONTEXT_BLOCK ContextBlock,
00216 IN PFP_DOUBLE_OPERAND ResultOperand
00217 );
00218
00219 BOOLEAN
00220
KiNormalizeSingle (
00221 IN PFP_CONTEXT_BLOCK ContextBlock,
00222 IN PFP_SINGLE_OPERAND ResultOperand,
00223 IN ULONG StickyBits
00224 );
00225
00226 ULONG
00227
KiSquareRootDouble (
00228 IN PULARGE_INTEGER DoubleValue
00229 );
00230
00231 ULONG
00232
KiSquareRootSingle (
00233 IN PULONG SingleValue
00234 );
00235
00236
VOID
00237
KiUnpackDouble (
00238 IN ULONG Source,
00239 IN PFP_CONTEXT_BLOCK ContextBlock,
00240 OUT PFP_DOUBLE_OPERAND DoubleOperand
00241 );
00242
00243
VOID
00244
KiUnpackSingle (
00245 IN ULONG Source,
00246 IN PFP_CONTEXT_BLOCK ContextBlock,
00247 OUT PFP_SINGLE_OPERAND SingleOperand
00248 );
00249
00250 BOOLEAN
00251 KiEmulateFloating (
00252 IN OUT PEXCEPTION_RECORD ExceptionRecord,
00253 IN OUT PKEXCEPTION_FRAME ExceptionFrame,
00254 IN OUT PKTRAP_FRAME TrapFrame
00255 )
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
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 }
02394
02395 BOOLEAN
02396
KiDivideByZeroDouble (
02397 IN PFP_CONTEXT_BLOCK ContextBlock,
02398 IN PFP_DOUBLE_OPERAND DoubleOperand1,
02399 IN PFP_DOUBLE_OPERAND DoubleOperand2
02400 )
02401
02402
02403
02404
02405
02406
02407
02408
02409
02410
02411
02412
02413
02414
02415
02416
02417
02418
02419
02420
02421
02422
02423
02424
02425
02426
02427 {
02428
02429 PEXCEPTION_RECORD ExceptionRecord;
02430 PFP_IEEE_VALUE IeeeValue;
02431 ULONG ResultSign;
02432 ULONG ResultValueHigh;
02433 ULONG ResultValueLow;
02434 PKTRAP_FRAME TrapFrame;
02435
02436
02437
02438
02439
02440 ResultSign = DoubleOperand1->Sign ^ DoubleOperand2->Sign;
02441 ResultValueHigh = DOUBLE_INFINITY_VALUE_HIGH | (ResultSign << 31);
02442 ResultValueLow = DOUBLE_INFINITY_VALUE_LOW;
02443
02444
02445
02446
02447
02448
02449
02450
02451 ExceptionRecord = ContextBlock->ExceptionRecord;
02452 TrapFrame = ContextBlock->TrapFrame;
02453
if (DoubleOperand1->Infinity ==
FALSE) {
02454 ((PFSR)&TrapFrame->Fsr)->SZ = 1;
02455
if (((PFSR)&TrapFrame->Fsr)->EZ != 0) {
02456 ExceptionRecord->ExceptionCode = STATUS_FLOAT_DIVIDE_BY_ZERO;
02457 ((PFSR)&TrapFrame->Fsr)->XZ = 1;
02458 IeeeValue = (PFP_IEEE_VALUE)&ExceptionRecord->ExceptionInformation[2];
02459 IeeeValue->Value.Fp64Value.W[0] = ResultValueLow;
02460 IeeeValue->Value.Fp64Value.W[1] = ResultValueHigh;
02461
return FALSE;
02462 }
02463 }
02464
02465
KiSetRegisterValue(ContextBlock->Fd + 32,
02466 ResultValueLow,
02467 ContextBlock->ExceptionFrame,
02468 ContextBlock->TrapFrame);
02469
02470
KiSetRegisterValue(ContextBlock->Fd + 32 + 1,
02471 ResultValueHigh,
02472 ContextBlock->ExceptionFrame,
02473 ContextBlock->TrapFrame);
02474
02475 TrapFrame->Fir = ContextBlock->BranchAddress;
02476
return TRUE;
02477 }
02478
02479 BOOLEAN
02480
KiDivideByZeroSingle (
02481 IN PFP_CONTEXT_BLOCK ContextBlock,
02482 IN PFP_SINGLE_OPERAND SingleOperand1,
02483 IN PFP_SINGLE_OPERAND SingleOperand2
02484 )
02485
02486
02487
02488
02489
02490
02491
02492
02493
02494
02495
02496
02497
02498
02499
02500
02501
02502
02503
02504
02505
02506
02507
02508
02509
02510
02511 {
02512
02513 PEXCEPTION_RECORD ExceptionRecord;
02514 PFP_IEEE_VALUE IeeeValue;
02515 ULONG ResultSign;
02516 ULONG ResultValue;
02517 PKTRAP_FRAME TrapFrame;
02518
02519
02520
02521
02522
02523 ResultSign = SingleOperand1->Sign ^ SingleOperand2->Sign;
02524 ResultValue = SINGLE_INFINITY_VALUE | (ResultSign << 31);
02525
02526
02527
02528
02529
02530
02531
02532
02533
02534 ExceptionRecord = ContextBlock->ExceptionRecord;
02535 TrapFrame = ContextBlock->TrapFrame;
02536
if (SingleOperand1->Infinity ==
FALSE) {
02537 ((PFSR)&TrapFrame->Fsr)->SZ = 1;
02538
if (((PFSR)&TrapFrame->Fsr)->EZ != 0) {
02539 ExceptionRecord->ExceptionCode = STATUS_FLOAT_DIVIDE_BY_ZERO;
02540 ((PFSR)&TrapFrame->Fsr)->XZ = 1;
02541 IeeeValue = (PFP_IEEE_VALUE)&ExceptionRecord->ExceptionInformation[2];
02542 IeeeValue->Value.Fp32Value.W[0] = ResultValue;
02543
return FALSE;
02544 }
02545 }
02546
02547
KiSetRegisterValue(ContextBlock->Fd + 32,
02548 ResultValue,
02549 ContextBlock->ExceptionFrame,
02550 ContextBlock->TrapFrame);
02551
02552 TrapFrame->Fir = ContextBlock->BranchAddress;
02553
return TRUE;
02554 }
02555
02556 BOOLEAN
02557
KiInvalidCompareDouble (
02558 IN PFP_CONTEXT_BLOCK ContextBlock,
02559 IN BOOLEAN CheckForNan,
02560 IN PFP_DOUBLE_OPERAND DoubleOperand1,
02561 IN PFP_DOUBLE_OPERAND DoubleOperand2
02562 )
02563
02564
02565
02566
02567
02568
02569
02570
02571
02572
02573
02574
02575
02576
02577
02578
02579
02580
02581
02582
02583
02584
02585
02586
02587
02588
02589
02590
02591 {
02592
02593 PEXCEPTION_RECORD ExceptionRecord;
02594 PFP_IEEE_VALUE IeeeValue;
02595 PKTRAP_FRAME TrapFrame;
02596
02597
02598
02599
02600
02601
02602
02603
02604
02605 ExceptionRecord = ContextBlock->ExceptionRecord;
02606 TrapFrame = ContextBlock->TrapFrame;
02607
if ((CheckForNan ==
FALSE) ||
02608 ((DoubleOperand1->Nan !=
FALSE) &&
02609 ((DoubleOperand1->MantissaHigh &
DOUBLE_SIGNAL_NAN_MASK) != 0)) ||
02610 ((DoubleOperand2->Nan !=
FALSE) &&
02611 ((DoubleOperand2->MantissaHigh &
DOUBLE_SIGNAL_NAN_MASK) != 0))) {
02612 ((PFSR)&TrapFrame->Fsr)->SV = 1;
02613
if (((PFSR)&TrapFrame->Fsr)->EV != 0) {
02614 ExceptionRecord->ExceptionCode = STATUS_FLOAT_INVALID_OPERATION;
02615 ((PFSR)&TrapFrame->Fsr)->XV = 1;
02616 IeeeValue = (PFP_IEEE_VALUE)&ExceptionRecord->ExceptionInformation[2];
02617 IeeeValue->Value.CompareValue = FpCompareUnordered;
02618
return FALSE;
02619 }
02620 }
02621
02622 TrapFrame->Fir = ContextBlock->BranchAddress;
02623
return TRUE;
02624 }
02625
02626 BOOLEAN
02627 KiInvalidCompareSingle (
02628 IN PFP_CONTEXT_BLOCK ContextBlock,
02629 IN BOOLEAN CheckForNan,
02630 IN PFP_SINGLE_OPERAND SingleOperand1,
02631 IN PFP_SINGLE_OPERAND SingleOperand2
02632 )
02633
02634
02635
02636
02637
02638
02639
02640
02641
02642
02643
02644
02645
02646
02647
02648
02649
02650
02651
02652
02653
02654
02655
02656
02657
02658
02659
02660
02661 {
02662
02663 PEXCEPTION_RECORD ExceptionRecord;
02664 PFP_IEEE_VALUE IeeeValue;
02665 PKTRAP_FRAME TrapFrame;
02666
02667
02668
02669
02670
02671
02672
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 }
02695
02696 BOOLEAN
02697
KiInvalidOperationDouble (
02698 IN PFP_CONTEXT_BLOCK ContextBlock,
02699 IN BOOLEAN CheckForNan,
02700 IN PFP_DOUBLE_OPERAND DoubleOperand1,
02701 IN PFP_DOUBLE_OPERAND DoubleOperand2
02702 )
02703
02704
02705
02706
02707
02708
02709
02710
02711
02712
02713
02714
02715
02716
02717
02718
02719
02720
02721
02722
02723
02724
02725
02726
02727
02728
02729
02730
02731 {
02732
02733 PEXCEPTION_RECORD ExceptionRecord;
02734 PFP_IEEE_VALUE IeeeValue;
02735 ULONG MantissaHigh;
02736 ULONG ResultValueHigh;
02737 ULONG ResultValueLow;
02738 PKTRAP_FRAME TrapFrame;
02739
02740
02741
02742
02743
02744
02745
02746
if (DoubleOperand1->Nan !=
FALSE) {
02747 MantissaHigh = DoubleOperand1->MantissaHigh & ~
DOUBLE_SIGNAL_NAN_MASK;
02748
if ((DoubleOperand1->MantissaLow | MantissaHigh) != 0) {
02749 ResultValueLow = DoubleOperand1->MantissaLow >> 2;
02750 ResultValueLow |= DoubleOperand1->MantissaHigh << 30;
02751 ResultValueHigh = DoubleOperand1->MantissaHigh >> 2;
02752 ResultValueHigh |=
DOUBLE_QUIET_NAN_PREFIX;
02753 ResultValueHigh &= ~
DOUBLE_QUIET_NAN_MASK;
02754
02755 }
else {
02756 ResultValueLow = DOUBLE_NAN_LOW;
02757 ResultValueHigh = DOUBLE_QUIET_NAN;
02758 }
02759
02760 }
else if (DoubleOperand2->Nan !=
FALSE) {
02761 MantissaHigh = DoubleOperand2->MantissaHigh & ~
DOUBLE_SIGNAL_NAN_MASK;
02762
if ((DoubleOperand2->MantissaLow | MantissaHigh) != 0) {
02763 ResultValueLow = DoubleOperand2->MantissaLow >> 2;
02764 ResultValueLow |= DoubleOperand2->MantissaHigh << 30;
02765 ResultValueHigh = DoubleOperand2->MantissaHigh >> 2;
02766 ResultValueHigh |=
DOUBLE_QUIET_NAN_PREFIX;
02767 ResultValueHigh &= ~
DOUBLE_QUIET_NAN_MASK;
02768
02769 }
else {
02770 ResultValueLow = DOUBLE_NAN_LOW;
02771 ResultValueHigh = DOUBLE_QUIET_NAN;
02772 }
02773
02774 }
else {
02775 ResultValueLow = DOUBLE_NAN_LOW;
02776 ResultValueHigh = DOUBLE_QUIET_NAN;
02777 }
02778
02779
02780
02781
02782
02783
02784
02785
02786
02787 ExceptionRecord = ContextBlock->ExceptionRecord;
02788 TrapFrame = ContextBlock->TrapFrame;
02789
if ((CheckForNan ==
FALSE) ||
02790 ((DoubleOperand1->Nan !=
FALSE) &&
02791 ((DoubleOperand1->MantissaHigh &
DOUBLE_SIGNAL_NAN_MASK) != 0)) ||
02792 ((DoubleOperand2->Nan !=
FALSE) &&
02793 ((DoubleOperand2->MantissaHigh &
DOUBLE_SIGNAL_NAN_MASK) != 0))) {
02794 ((PFSR)&TrapFrame->Fsr)->SV = 1;
02795
if (((PFSR)&TrapFrame->Fsr)->EV != 0) {
02796 ExceptionRecord->ExceptionCode = STATUS_FLOAT_INVALID_OPERATION;
02797 ((PFSR)&TrapFrame->Fsr)->XV = 1;
02798 IeeeValue = (PFP_IEEE_VALUE)&ExceptionRecord->ExceptionInformation[2];
02799 IeeeValue->Value.Fp64Value.W[0] = ResultValueLow;
02800 IeeeValue->Value.Fp64Value.W[1] = ResultValueHigh;
02801
return FALSE;
02802 }
02803 }
02804
02805
KiSetRegisterValue(ContextBlock->Fd + 32,
02806 ResultValueLow,
02807 ContextBlock->ExceptionFrame,
02808 ContextBlock->TrapFrame);
02809
02810
KiSetRegisterValue(ContextBlock->Fd + 32 + 1,
02811 ResultValueHigh,
02812 ContextBlock->ExceptionFrame,
02813 ContextBlock->TrapFrame);
02814
02815 TrapFrame->Fir = ContextBlock->BranchAddress;
02816
return TRUE;
02817 }
02818
02819 BOOLEAN
02820 KiInvalidOperationLongword (
02821 IN PFP_CONTEXT_BLOCK ContextBlock,
02822 IN BOOLEAN Infinity,
02823 IN LONG Sign
02824 )
02825
02826
02827
02828
02829
02830
02831
02832
02833
02834
02835
02836
02837
02838
02839
02840
02841
02842
02843
02844
02845
02846
02847
02848
02849
02850 {
02851
02852 PEXCEPTION_RECORD ExceptionRecord;
02853 PFP_IEEE_VALUE IeeeValue;
02854 ULONG ResultValue;
02855 PKTRAP_FRAME TrapFrame;
02856
02857
02858
02859
02860
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
02877
02878
02879
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 }
02903
02904 BOOLEAN
02905 KiInvalidOperationQuadword (
02906 IN PFP_CONTEXT_BLOCK ContextBlock,
02907 IN BOOLEAN Infinity,
02908 IN LONG Sign
02909 )
02910
02911
02912
02913
02914
02915
02916
02917
02918
02919
02920
02921
02922
02923
02924
02925
02926
02927
02928
02929
02930
02931
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
02948
02949
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
02966
02967
02968
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 }
02997
02998 BOOLEAN
02999
KiInvalidOperationSingle (
03000 IN PFP_CONTEXT_BLOCK ContextBlock,
03001 IN BOOLEAN CheckForNan,
03002 IN PFP_SINGLE_OPERAND SingleOperand1,
03003 IN PFP_SINGLE_OPERAND SingleOperand2
03004 )
03005
03006
03007
03008
03009
03010
03011
03012
03013
03014
03015
03016
03017
03018
03019
03020
03021
03022
03023
03024
03025
03026
03027
03028
03029
03030
03031
03032
03033 {
03034
03035 PEXCEPTION_RECORD ExceptionRecord;
03036 PFP_IEEE_VALUE IeeeValue;
03037 ULONG ResultValue;
03038 PKTRAP_FRAME TrapFrame;
03039
03040
03041
03042
03043
03044
03045
03046
if (SingleOperand1->Nan !=
FALSE) {
03047
if ((SingleOperand1->Mantissa & ~
SINGLE_SIGNAL_NAN_MASK) != 0) {
03048 ResultValue = SingleOperand1->Mantissa >> 2;
03049 ResultValue |=
SINGLE_QUIET_NAN_PREFIX;
03050 ResultValue &= ~
SINGLE_QUIET_NAN_MASK;
03051
03052 }
else {
03053 ResultValue = SINGLE_QUIET_NAN;
03054 }
03055
03056 }
else if (SingleOperand2->Nan !=
FALSE) {
03057
if ((SingleOperand2->Mantissa & ~
SINGLE_SIGNAL_NAN_MASK) != 0) {
03058 ResultValue = SingleOperand2->Mantissa >> 2;
03059 ResultValue |=
SINGLE_QUIET_NAN_PREFIX;
03060 ResultValue &= ~
SINGLE_QUIET_NAN_MASK;
03061
03062 }
else {
03063 ResultValue = SINGLE_QUIET_NAN;
03064 }
03065
03066 }
else {
03067 ResultValue = SINGLE_QUIET_NAN;
03068 }
03069
03070
03071
03072
03073
03074
03075
03076
03077
03078 ExceptionRecord = ContextBlock->ExceptionRecord;
03079 TrapFrame = ContextBlock->TrapFrame;
03080
if ((CheckForNan ==
FALSE) ||
03081 ((SingleOperand1->Nan !=
FALSE) &&
03082 ((SingleOperand1->Mantissa &
SINGLE_SIGNAL_NAN_MASK) != 0)) ||
03083 ((SingleOperand2->Nan !=
FALSE) &&
03084 ((SingleOperand2->Mantissa &
SINGLE_SIGNAL_NAN_MASK) != 0))) {
03085 ((PFSR)&TrapFrame->Fsr)->SV = 1;
03086
if (((PFSR)&TrapFrame->Fsr)->EV != 0) {
03087 ExceptionRecord->ExceptionCode = STATUS_FLOAT_INVALID_OPERATION;
03088 ((PFSR)&TrapFrame->Fsr)->XV = 1;
03089 IeeeValue = (PFP_IEEE_VALUE)&ExceptionRecord->ExceptionInformation[2];
03090 IeeeValue->Value.Fp32Value.W[0] = ResultValue;
03091
return FALSE;
03092 }
03093 }
03094
03095
KiSetRegisterValue(ContextBlock->Fd + 32,
03096 ResultValue,
03097 ContextBlock->ExceptionFrame,
03098 ContextBlock->TrapFrame);
03099
03100 TrapFrame->Fir = ContextBlock->BranchAddress;
03101
return TRUE;
03102 }
03103
03104 BOOLEAN
03105 KiNormalizeDouble (
03106 IN PFP_CONTEXT_BLOCK ContextBlock,
03107 IN PFP_DOUBLE_OPERAND ResultOperand,
03108 IN ULONG StickyBits
03109 )
03110
03111
03112
03113
03114
03115
03116
03117
03118
03119
03120
03121
03122
03123
03124
03125
03126
03127
03128
03129
03130
03131
03132
03133
03134
03135
03136
03137
03138
03139
03140
03141
03142
03143
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
03164
03165
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
03187
03188
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
03203
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
03219
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
03231
03232
03233 RoundBit = ResultOperand->MantissaLow & 0x1;
03234
switch (ContextBlock->Round) {
03235
03236
03237
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
03254
03255
03256
case ROUND_TO_ZERO:
03257
break;
03258
03259
03260
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
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
03292
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
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
03317
03318
03319
03320
03321
03322
03323
03324
03325
03326
03327
03328
03329
03330
03331
if (ResultOperand->Exponent >= DOUBLE_MAXIMUM_EXPONENT) {
03332 Inexact =
TRUE;
03333 Overflow =
TRUE;
03334 Underflow =
FALSE;
03335
03336
03337
03338
03339
03340
switch (ContextBlock->Round) {
03341
03342
03343
03344
03345
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
03357
03358
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
03369
03370
03371
03372
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
03389
03390
03391
03392
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
03411
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
03460
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
03499
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
03556
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 }
03572
03573 BOOLEAN
03574 KiNormalizeLongword (
03575 IN PFP_CONTEXT_BLOCK ContextBlock,
03576 IN PFP_DOUBLE_OPERAND ResultOperand
03577 )
03578
03579
03580
03581
03582
03583
03584
03585
03586
03587
03588
03589
03590
03591
03592
03593
03594
03595
03596
03597
03598
03599
03600
03601
03602
03603
03604
03605
03606
03607
03608
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
03626
03627
03628
03629 ExceptionRecord = ContextBlock->ExceptionRecord;
03630 TrapFrame = ContextBlock->TrapFrame;
03631 ExponentShift = ResultOperand->Exponent - DOUBLE_EXPONENT_BIAS;
03632
if (ExponentShift < 23) {
03633
03634
03635
03636
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
03655
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
03674
03675
03676 RoundBit = StickyBits >> 31;
03677 StickyBits <<= 1;
03678
switch (ContextBlock->Round) {
03679
03680
03681
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
03698
03699
03700
case ROUND_TO_ZERO:
03701
break;
03702
03703
03704
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
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
03734
03735
03736
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
03753
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
03775
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 }
03786
03787 BOOLEAN
03788
KiNormalizeQuadword (
03789 IN PFP_CONTEXT_BLOCK ContextBlock,
03790 IN PFP_DOUBLE_OPERAND ResultOperand
03791 )
03792
03793
03794
03795
03796
03797
03798
03799
03800
03801
03802
03803
03804
03805
03806
03807
03808
03809
03810
03811
03812
03813
03814
03815
03816
03817
03818
03819
03820
03821
03822
03823
03824
03825
03826 {
03827
03828 PEXCEPTION_RECORD ExceptionRecord;
03829 LONG ExponentShift;
03830 PFP_IEEE_VALUE IeeeValue;
03831 BOOLEAN Inexact;
03832 BOOLEAN Overflow;
03833
union {
03834 ULONGLONG ResultValue;
03835 ULARGE_INTEGER LargeValue;
03836 }u;
03837
03838 ULONG RoundBit;
03839 ULONG StickyBits;
03840 PKTRAP_FRAME TrapFrame;
03841
03842
03843
03844
03845
03846
03847 ExceptionRecord = ContextBlock->ExceptionRecord;
03848 TrapFrame = ContextBlock->TrapFrame;
03849 ExponentShift = ResultOperand->Exponent - DOUBLE_EXPONENT_BIAS;
03850
if (ExponentShift < 54) {
03851
03852
03853
03854
03855
03856
03857 ExponentShift = 54 - ExponentShift;
03858
if (ExponentShift > 54) {
03859 ExponentShift = 54;
03860 }
03861
03862 StickyBits = (ULONG)(ResultOperand->Mantissa << (32 - ExponentShift));
03863 u.ResultValue = ResultOperand->Mantissa >> ExponentShift;
03864 Overflow =
FALSE;
03865
03866 }
else {
03867
03868
03869
03870
03871
03872
03873 ExponentShift -= 54;
03874
if (ExponentShift <= (63 - 54)) {
03875 StickyBits = 0;
03876 u.ResultValue = ResultOperand->Mantissa << ExponentShift;
03877 Overflow =
FALSE;
03878
03879 }
else {
03880 Overflow =
TRUE;
03881 }
03882 }
03883
03884
03885
03886
03887
03888 RoundBit = StickyBits >> 31;
03889 StickyBits <<= 1;
03890
switch (ContextBlock->Round) {
03891
03892
03893
03894
03895
03896
case ROUND_TO_NEAREST:
03897
if (RoundBit != 0) {
03898
if ((StickyBits != 0) || ((u.ResultValue & 0x1) != 0)) {
03899 u.ResultValue += 1;
03900
if (u.ResultValue == 0) {
03901 Overflow =
TRUE;
03902 }
03903 }
03904 }
03905
03906
break;
03907
03908
03909
03910
03911
03912
case ROUND_TO_ZERO:
03913
break;
03914
03915
03916
03917
03918
03919
case ROUND_TO_PLUS_INFINITY:
03920
if ((ResultOperand->Sign == 0) && (StickyBits != 0)) {
03921 u.ResultValue += 1;
03922
if (u.ResultValue == 0) {
03923 Overflow =
TRUE;
03924 }
03925 }
03926
03927
break;
03928
03929
03930
03931
03932
03933
case ROUND_TO_MINUS_INFINITY:
03934
if ((ResultOperand->Sign != 0) && (StickyBits != 0)) {
03935 u.ResultValue += 1;
03936
if (u.ResultValue == 0) {
03937 Overflow =
TRUE;
03938 }
03939 }
03940
03941
break;
03942 }
03943
03944
03945
03946
03947
03948
03949
03950
03951
if (ResultOperand->Sign == 0) {
03952
if ((u.ResultValue >> 63) != 0) {
03953 Overflow =
TRUE;
03954 }
03955
03956 }
else {
03957 u.ResultValue = ~u.ResultValue + 1;
03958
if ((u.ResultValue >> 63) == 0) {
03959 Overflow =
TRUE;
03960 }
03961 }
03962
03963
03964
03965
03966
03967
03968
if (Overflow !=
FALSE) {
03969
return KiInvalidOperationQuadword(ContextBlock,
03970 FALSE,
03971 0);
03972
03973 }
else if ((StickyBits | RoundBit) != 0) {
03974 ((PFSR)&TrapFrame->Fsr)->SI = 1;
03975
if (((PFSR)&TrapFrame->Fsr)->EI != 0) {
03976 ExceptionRecord->ExceptionCode = STATUS_FLOAT_INEXACT_RESULT;
03977 ((PFSR)&TrapFrame->Fsr)->XI = 1;
03978 IeeeValue = (PFP_IEEE_VALUE)&ExceptionRecord->ExceptionInformation[2];
03979 IeeeValue->Value.U64Value.QuadPart = u.ResultValue;
03980
return FALSE;
03981 }
03982
03983 }
03984
03985
03986
03987
03988
03989
03990
KiSetRegisterValue(ContextBlock->Fd + 32,
03991 u.LargeValue.LowPart,
03992 ContextBlock->ExceptionFrame,
03993 ContextBlock->TrapFrame);
03994
03995
KiSetRegisterValue(ContextBlock->Fd + 33,
03996 u.LargeValue.HighPart,
03997 ContextBlock->ExceptionFrame,
03998 ContextBlock->TrapFrame);
03999
04000 TrapFrame->Fir = ContextBlock->BranchAddress;
04001
return TRUE;
04002 }
04003
04004 BOOLEAN
04005
KiNormalizeSingle (
04006 IN PFP_CONTEXT_BLOCK ContextBlock,
04007 IN PFP_SINGLE_OPERAND ResultOperand,
04008 IN ULONG StickyBits
04009 )
04010
04011
04012
04013
04014
04015
04016
04017
04018
04019
04020
04021
04022
04023
04024
04025
04026
04027
04028
04029
04030
04031
04032
04033
04034
04035
04036
04037
04038
04039
04040
04041
04042
04043
04044
04045
04046
04047 {
04048
04049 ULONG DenormalizeShift;
04050 PEXCEPTION_RECORD ExceptionRecord;
04051 ULONG ExceptionResult;
04052 PFP_IEEE_VALUE IeeeValue;
04053 BOOLEAN Inexact;
04054 BOOLEAN Overflow;
04055 ULONG ResultValue;
04056 ULONG RoundBit;
04057 PKTRAP_FRAME TrapFrame;
04058 BOOLEAN Underflow;
04059
04060
04061
04062
04063
04064
04065
04066 ExceptionRecord = ContextBlock->ExceptionRecord;
04067 TrapFrame = ContextBlock->TrapFrame;
04068
if (ResultOperand->Infinity !=
FALSE) {
04069
KiSetRegisterValue(ContextBlock->Fd + 32,
04070 SINGLE_INFINITY_VALUE | (ResultOperand->Sign << 31),
04071 ContextBlock->ExceptionFrame,
04072 ContextBlock->TrapFrame);
04073
04074 TrapFrame->Fir = ContextBlock->BranchAddress;
04075
return TRUE;
04076 }
04077
04078
04079
04080
04081
04082
04083
04084
if ((ResultOperand->Mantissa & (1 << 26)) != 0) {
04085 StickyBits |= (ResultOperand->Mantissa & 0x1);
04086 ResultOperand->Mantissa >>= 1;
04087 ResultOperand->Exponent += 1;
04088 }
04089
04090
04091
04092
04093
04094
04095
if (ResultOperand->Mantissa != 0) {
04096
while ((ResultOperand->Mantissa & (1 << 25)) == 0) {
04097 ResultOperand->Mantissa <<= 1;
04098 ResultOperand->Exponent -= 1;
04099 }
04100 }
04101
04102
04103
04104
04105
04106
04107 StickyBits |= (ResultOperand->Mantissa & 0x1);
04108 ResultOperand->Mantissa >>= 1;
04109
04110
04111
04112
04113
04114
04115 RoundBit = ResultOperand->Mantissa & 0x1;
04116
switch (ContextBlock->Round) {
04117
04118
04119
04120
04121
04122
case ROUND_TO_NEAREST:
04123
if (RoundBit != 0) {
04124
if ((StickyBits != 0) || ((ResultOperand->Mantissa & 0x2) != 0)) {
04125 ResultOperand->Mantissa += 2;
04126 }
04127 }
04128
04129
break;
04130
04131
04132
04133
04134
04135
case ROUND_TO_ZERO:
04136
break;
04137
04138
04139
04140
04141
04142
case ROUND_TO_PLUS_INFINITY:
04143
if ((ResultOperand->Sign == 0) &&
04144 ((StickyBits != 0) || (RoundBit != 0))) {
04145 ResultOperand->Mantissa += 2;
04146 }
04147
04148
break;
04149
04150
04151
04152
04153
04154
case ROUND_TO_MINUS_INFINITY:
04155
if ((ResultOperand->Sign != 0) &&
04156 ((StickyBits != 0) || (RoundBit != 0))) {
04157 ResultOperand->Mantissa += 2;
04158 }
04159
04160
break;
04161 }
04162
04163
04164
04165
04166
04167
04168
if ((ResultOperand->Mantissa & (1 << 25)) != 0) {
04169 ResultOperand->Mantissa >>= 1;
04170 ResultOperand->Exponent += 1;
04171 }
04172
04173
04174
04175
04176
04177 StickyBits |= RoundBit;
04178 ResultOperand->Mantissa >>= 1;
04179
04180
04181
04182
04183
04184
04185
04186
04187
04188
04189
04190
04191
04192
04193
04194
04195
04196
if (ResultOperand->Exponent >= SINGLE_MAXIMUM_EXPONENT) {
04197 Inexact =
TRUE;
04198 Overflow =
TRUE;
04199 Underflow =
FALSE;
04200
04201
04202
04203
04204
04205
switch (ContextBlock->Round) {
04206
04207
04208
04209
04210
04211
04212
04213
case ROUND_TO_NEAREST:
04214 ResultValue = SINGLE_INFINITY_VALUE | (ResultOperand->Sign << 31);
04215
break;
04216
04217
04218
04219
04220
04221
04222
04223
case ROUND_TO_ZERO:
04224 ResultValue = SINGLE_MAXIMUM_VALUE | (ResultOperand->Sign << 31);
04225
break;
04226
04227
04228
04229
04230
04231
04232
04233
04234
04235
case ROUND_TO_PLUS_INFINITY:
04236
if (ResultOperand->Sign == 0) {
04237 ResultValue = SINGLE_INFINITY_VALUE;
04238
04239 }
else {
04240 ResultValue = (ULONG)(SINGLE_MAXIMUM_VALUE | (1 << 31));
04241 }
04242
04243
break;
04244
04245
04246
04247
04248
04249
04250
04251
04252
04253
04254
case ROUND_TO_MINUS_INFINITY:
04255
if (ResultOperand->Sign != 0) {
04256 ResultValue = (ULONG)(SINGLE_INFINITY_VALUE | (1 << 31));
04257
04258 }
else {
04259 ResultValue = SINGLE_MAXIMUM_VALUE;
04260 }
04261
04262
break;
04263 }
04264
04265
04266
04267
04268
04269
04270 ExceptionResult = ResultOperand->Mantissa & ((1 << 23) - 1);
04271 ExceptionResult |= ((ResultOperand->Exponent - 192) << 23);
04272 ExceptionResult |= (ResultOperand->Sign << 31);
04273
04274 }
else {
04275
if ((ResultOperand->Exponent <= SINGLE_MINIMUM_EXPONENT) &&
04276 (ResultOperand->Mantissa != 0)) {
04277
if (((PFSR)&TrapFrame->Fsr)->FS == 0) {
04278 DenormalizeShift = 1 - ResultOperand->Exponent;
04279
if (DenormalizeShift >= 24) {
04280 DenormalizeShift = 24;
04281 }
04282
04283 ResultValue = ResultOperand->Mantissa >> DenormalizeShift;
04284 ResultValue |= (ResultOperand->Sign << 31);
04285
if ((StickyBits != 0) ||
04286 ((ResultOperand->Mantissa & ((1 << DenormalizeShift) - 1)) != 0)) {
04287 Inexact =
TRUE;
04288 Overflow =
FALSE;
04289 Underflow =
TRUE;
04290
04291
04292
04293
04294
04295
04296 ExceptionResult = ResultOperand->Mantissa & ((1 << 23) - 1);
04297 ExceptionResult |= ((ResultOperand->Exponent + 192) << 23);
04298 ExceptionResult |= (ResultOperand->Sign << 31);
04299
04300 }
else {
04301 Inexact =
FALSE;
04302 Overflow =
FALSE;
04303 Underflow =
FALSE;
04304 }
04305
04306 }
else {
04307 ResultValue = 0;
04308 Inexact =
FALSE;
04309 Overflow =
FALSE;
04310 Underflow =
FALSE;
04311 }
04312
04313 }
else {
04314
if (ResultOperand->Mantissa == 0) {
04315 ResultOperand->Exponent = 0;
04316 }
04317
04318 ResultValue = ResultOperand->Mantissa & ((1 << 23) - 1);
04319 ResultValue |= (ResultOperand->Exponent << 23);
04320 ResultValue |= (ResultOperand->Sign << 31);
04321 Inexact = StickyBits ?
TRUE :
FALSE;
04322 Overflow =
FALSE;
04323 Underflow =
FALSE;
04324 }
04325 }
04326
04327
04328
04329
04330
04331
04332
if (Overflow !=
FALSE) {
04333 ((PFSR)&TrapFrame->Fsr)->SI = 1;
04334 ((PFSR)&TrapFrame->Fsr)->SO = 1;
04335
if ((((PFSR)&TrapFrame->Fsr)->EO != 0) ||
04336 (((PFSR)&TrapFrame->Fsr)->EI != 0)) {
04337
if (((PFSR)&TrapFrame->Fsr)->EO != 0) {
04338 ExceptionRecord->ExceptionCode = STATUS_FLOAT_OVERFLOW;
04339
04340 }
else {
04341 ExceptionRecord->ExceptionCode = STATUS_FLOAT_INEXACT_RESULT;
04342 }
04343
04344 IeeeValue = (PFP_IEEE_VALUE)&ExceptionRecord->ExceptionInformation[2];
04345 IeeeValue->Value.Fp32Value.W[0] = ExceptionResult;
04346 ((PFSR)&TrapFrame->Fsr)->XI = 1;
04347 ((PFSR)&TrapFrame->Fsr)->XO = 1;
04348
return FALSE;
04349 }
04350
04351 }
else if (Underflow !=
FALSE) {
04352 ((PFSR)&TrapFrame->Fsr)->SI = 1;
04353 ((PFSR)&TrapFrame->Fsr)->SU = 1;
04354
if ((((PFSR)&TrapFrame->Fsr)->EU != 0) ||
04355 (((PFSR)&TrapFrame->Fsr)->EI != 0)) {
04356
if (((PFSR)&TrapFrame->Fsr)->EU != 0) {
04357 ExceptionRecord->ExceptionCode = STATUS_FLOAT_UNDERFLOW;
04358
04359 }
else {
04360 ExceptionRecord->ExceptionCode = STATUS_FLOAT_INEXACT_RESULT;
04361 }
04362
04363 IeeeValue = (PFP_IEEE_VALUE)&ExceptionRecord->ExceptionInformation[2];
04364 IeeeValue->Value.Fp32Value.W[0] = ExceptionResult;
04365 ((PFSR)&TrapFrame->Fsr)->XI = 1;
04366 ((PFSR)&TrapFrame->Fsr)->XU = 1;
04367
return FALSE;
04368 }
04369
04370 }
else if (Inexact !=
FALSE) {
04371 ((PFSR)&TrapFrame->Fsr)->SI = 1;
04372
if (((PFSR)&TrapFrame->Fsr)->EI != 0) {
04373 ExceptionRecord->ExceptionCode = STATUS_FLOAT_INEXACT_RESULT;
04374 ((PFSR)&TrapFrame->Fsr)->XI = 1;
04375 IeeeValue = (PFP_IEEE_VALUE)&ExceptionRecord->ExceptionInformation[2];
04376 IeeeValue->Value.Fp32Value.W[0] = ResultValue;
04377
return FALSE;
04378 }
04379
04380 }
04381
04382
04383
04384
04385
04386
04387
KiSetRegisterValue(ContextBlock->Fd + 32,
04388 ResultValue,
04389 ContextBlock->ExceptionFrame,
04390 ContextBlock->TrapFrame);
04391
04392 TrapFrame->Fir = ContextBlock->BranchAddress;
04393
return TRUE;
04394 }
04395
04396
VOID
04397
KiUnpackDouble (
04398 IN ULONG Source,
04399 IN PFP_CONTEXT_BLOCK ContextBlock,
04400 OUT PFP_DOUBLE_OPERAND DoubleOperand
04401 )
04402
04403
04404
04405
04406
04407
04408
04409
04410
04411
04412
04413
04414
04415
04416
04417
04418
04419
04420
04421
04422
04423
04424
04425
04426
04427
04428
04429
04430
04431
04432
04433
04434
04435 {
04436
04437 ULONG Value1;
04438 ULONG Value2;
04439
04440
04441
04442
04443
04444
04445 Value1 =
KiGetRegisterValue(Source + 32,
04446 ContextBlock->ExceptionFrame,
04447 ContextBlock->TrapFrame);
04448
04449 Value2 =
KiGetRegisterValue(Source + 32 + 1,
04450 ContextBlock->ExceptionFrame,
04451 ContextBlock->TrapFrame);
04452
04453 DoubleOperand->Sign = Value2 >> 31;
04454 DoubleOperand->Exponent = (Value2 >> (52 - 32)) & 0x7ff;
04455 DoubleOperand->MantissaHigh = Value2 & 0xfffff;
04456 DoubleOperand->MantissaLow = Value1;
04457
04458
04459
04460
04461
04462
04463
if (DoubleOperand->Exponent == DOUBLE_MAXIMUM_EXPONENT) {
04464
if ((DoubleOperand->MantissaLow | DoubleOperand->MantissaHigh) != 0) {
04465 DoubleOperand->Infinity =
FALSE;
04466 DoubleOperand->Nan =
TRUE;
04467
04468 }
else {
04469 DoubleOperand->Infinity =
TRUE;
04470 DoubleOperand->Nan =
FALSE;
04471 }
04472
04473 }
else {
04474 DoubleOperand->Infinity =
FALSE;
04475 DoubleOperand->Nan =
FALSE;
04476
if (DoubleOperand->Exponent == DOUBLE_MINIMUM_EXPONENT) {
04477
if ((DoubleOperand->MantissaHigh | DoubleOperand->MantissaLow) != 0) {
04478 DoubleOperand->Exponent += 1;
04479
while ((DoubleOperand->MantissaHigh & (1 << 20)) == 0) {
04480 DoubleOperand->MantissaHigh =
04481 (DoubleOperand->MantissaHigh << 1) |
04482 (DoubleOperand->MantissaLow >> 31);
04483 DoubleOperand->MantissaLow <<= 1;
04484 DoubleOperand->Exponent -= 1;
04485 }
04486 }
04487
04488 }
else {
04489 DoubleOperand->MantissaHigh |= (1 << 20);
04490 }
04491 }
04492
04493
04494
04495
04496
04497
04498 DoubleOperand->MantissaHigh =
04499 (DoubleOperand->MantissaHigh << 2) | (DoubleOperand->MantissaLow >> 30);
04500 DoubleOperand->MantissaLow <<= 2;
04501
return;
04502 }
04503
04504
VOID
04505
KiUnpackSingle (
04506 IN ULONG Source,
04507 IN PFP_CONTEXT_BLOCK ContextBlock,
04508 OUT PFP_SINGLE_OPERAND SingleOperand
04509 )
04510
04511
04512
04513
04514
04515
04516
04517
04518
04519
04520
04521
04522
04523
04524
04525
04526
04527
04528
04529
04530
04531
04532
04533
04534
04535
04536
04537
04538
04539
04540
04541
04542
04543 {
04544
04545 ULONG Value;
04546
04547
04548
04549
04550
04551
04552 Value =
KiGetRegisterValue(Source + 32,
04553 ContextBlock->ExceptionFrame,
04554 ContextBlock->TrapFrame);
04555
04556 SingleOperand->Sign = Value >> 31;
04557 SingleOperand->Exponent = (Value >> 23) & 0xff;
04558 SingleOperand->Mantissa = Value & 0x7fffff;
04559
04560
04561
04562
04563
04564
04565
if (SingleOperand->Exponent == SINGLE_MAXIMUM_EXPONENT) {
04566
if (SingleOperand->Mantissa != 0) {
04567 SingleOperand->Infinity =
FALSE;
04568 SingleOperand->Nan =
TRUE;
04569
04570 }
else {
04571 SingleOperand->Infinity =
TRUE;
04572 SingleOperand->Nan =
FALSE;
04573 }
04574
04575 }
else {
04576 SingleOperand->Infinity =
FALSE;
04577 SingleOperand->Nan =
FALSE;
04578
if (SingleOperand->Exponent == SINGLE_MINIMUM_EXPONENT) {
04579
if (SingleOperand->Mantissa != 0) {
04580 SingleOperand->Exponent += 1;
04581
while ((SingleOperand->Mantissa & (1 << 23)) == 0) {
04582 SingleOperand->Mantissa <<= 1;
04583 SingleOperand->Exponent -= 1;
04584 }
04585 }
04586
04587 }
else {
04588 SingleOperand->Mantissa |= (1 << 23);
04589 }
04590 }
04591
04592
04593
04594
04595
04596
04597 SingleOperand->Mantissa <<= 2;
04598
return;
04599 }