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
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
#include "ki.h"
00084
#pragma hdrstop
00085
#include "alphaops.h"
00086
00087
#if DBG
00088
00089
extern ULONG RtlDebugFlags;
00090
#define DBGPRINT ((RtlDebugFlags & 0x4) != 0) && DbgPrint
00091
#define DBGPRINT2 ((RtlDebugFlags & 0x8) != 0) && DbgPrint
00092
00093
#else
00094
00095 #define DBGPRINT 0 && DbgPrint
00096 #define DBGPRINT2 0 && DbgPrint
00097
00098
#endif
00099
00100 #define LOW_PART(Quad) ((ULONG)(Quad))
00101 #define HIGH_PART(Quad) ((ULONG)(Quad >> 32))
00102 #define MAKE_QUAD(Low, High) (((ULONGLONG)(High)) << 32 | ((ULONGLONG)(Low)))
00103
00104
00105
00106
00107
00108
00109 #define CVTST_FUNC_PROPER 0x00E
00110
00111
00112
00113
00114
00115
00116
00117
00118 #define DOUBLE_NAN_BIT_HIGH (1 << (53 - 32))
00119 #define SINGLE_NAN_BIT (1 << 24)
00120
00121 #define DoubleSignalNan(DoubleOperand) \
00122
(((DoubleOperand)->Nan != FALSE) && \
00123
(((DoubleOperand)->MantissaHigh & DOUBLE_NAN_BIT_HIGH) == 0))
00124
00125 #define DoubleQuietNan(DoubleOperand) \
00126
(((DoubleOperand)->Nan != FALSE) && \
00127
(((DoubleOperand)->MantissaHigh & DOUBLE_NAN_BIT_HIGH) != 0))
00128
00129 #define SingleSignalNan(SingleOperand) \
00130
(((SingleOperand)->Nan != FALSE) && \
00131
(((SingleOperand)->Mantissa & SINGLE_NAN_BIT) == 0))
00132
00133 #define SingleQuietNan(SingleOperand) \
00134
(((SingleOperand)->Nan != FALSE) && \
00135
(((SingleOperand)->Mantissa & SINGLE_NAN_BIT) != 0))
00136
00137
00138
00139
00140
00141 typedef struct _FP_CONTEXT_BLOCK {
00142 ULONG
Fc;
00143 PEXCEPTION_RECORD
ExceptionRecord;
00144 PKEXCEPTION_FRAME
ExceptionFrame;
00145 PKTRAP_FRAME
TrapFrame;
00146 PSW_FPCR
SoftwareFpcr;
00147 ULONG
Round;
00148 BOOLEAN
IeeeMode;
00149 BOOLEAN
UnderflowEnable;
00150 }
FP_CONTEXT_BLOCK, *
PFP_CONTEXT_BLOCK;
00151
00152
00153
00154
00155
00156 typedef struct _FP_DOUBLE_OPERAND {
00157 LONG
MantissaHigh;
00158 ULONG
MantissaLow;
00159 LONGLONG
Mantissa;
00160 LONG
Exponent;
00161 LONG
Sign;
00162 BOOLEAN
Infinity;
00163 BOOLEAN
Nan;
00164 BOOLEAN
Normal;
00165 }
FP_DOUBLE_OPERAND, *
PFP_DOUBLE_OPERAND;
00166
00167 typedef struct _FP_SINGLE_OPERAND {
00168 LONG
Mantissa;
00169 LONG
Exponent;
00170 LONG
Sign;
00171 BOOLEAN
Infinity;
00172 BOOLEAN
Nan;
00173 BOOLEAN
Normal;
00174 }
FP_SINGLE_OPERAND, *
PFP_SINGLE_OPERAND;
00175
00176
00177
00178
00179
00180 typedef struct _DOUBLE_FORMAT {
00181 ULONGLONG
Mantissa : 52;
00182 ULONGLONG
Exponent : 11;
00183 ULONGLONG
Sign : 1;
00184 }
DOUBLE_FORMAT, *
PDOUBLE_FORMAT;
00185
00186 typedef struct _SINGLE_FORMAT {
00187 ULONG
Mantissa : 23;
00188 ULONG
Exponent : 8;
00189 ULONG
Sign : 1;
00190 }
SINGLE_FORMAT, *
PSINGLE_FORMAT;
00191
00192
00193
00194
00195
00196 ULONGLONG
00197
KiConvertSingleOperandToRegister (
00198 IN ULONG SingleValue
00199 );
00200
00201 ULONG
00202
KiConvertRegisterToSingleOperand (
00203 IN ULONGLONG DoubleValue
00204 );
00205
00206 BOOLEAN
00207
KiConvertQuadwordToLongword (
00208 IN PFP_CONTEXT_BLOCK ContextBlock,
00209 IN LONGLONG Quadword
00210 );
00211
00212 BOOLEAN
00213
KiDivideByZeroDouble (
00214 IN PFP_CONTEXT_BLOCK ContextBlock,
00215 IN PFP_DOUBLE_OPERAND DoubleOperand1,
00216 IN PFP_DOUBLE_OPERAND DoubleOperand2
00217 );
00218
00219 BOOLEAN
00220
KiDivideByZeroSingle (
00221 IN PFP_CONTEXT_BLOCK ContextBlock,
00222 IN PFP_SINGLE_OPERAND SingleOperand1,
00223 IN PFP_SINGLE_OPERAND SingleOperand2
00224 );
00225
00226 PFP_IEEE_VALUE
00227
KiInitializeIeeeValue (
00228 IN PEXCEPTION_RECORD ExceptionRecord
00229 );
00230
00231 BOOLEAN
00232
KiInvalidCompareDouble (
00233 IN PFP_CONTEXT_BLOCK ContextBlock,
00234 IN BOOLEAN CheckForSignalNan,
00235 IN PFP_DOUBLE_OPERAND DoubleOperand1,
00236 IN PFP_DOUBLE_OPERAND DoubleOperand2
00237 );
00238
00239 BOOLEAN
00240
KiInvalidOperationDouble (
00241 IN PFP_CONTEXT_BLOCK ContextBlock,
00242 IN BOOLEAN CheckForSignalNan,
00243 IN PFP_DOUBLE_OPERAND DoubleOperand1,
00244 IN PFP_DOUBLE_OPERAND DoubleOperand2
00245 );
00246
00247 BOOLEAN
00248
KiInvalidOperationQuadword (
00249 IN PFP_CONTEXT_BLOCK ContextBlock,
00250 IN ULONGLONG ResultValue
00251 );
00252
00253 BOOLEAN
00254
KiInvalidOperationSingle (
00255 IN PFP_CONTEXT_BLOCK ContextBlock,
00256 IN BOOLEAN CheckForSignalNan,
00257 IN PFP_SINGLE_OPERAND SingleOperand1,
00258 IN PFP_SINGLE_OPERAND SingleOperand2
00259 );
00260
00261 BOOLEAN
00262
KiNormalizeDouble (
00263 IN PFP_CONTEXT_BLOCK ContextBlock,
00264 IN PFP_DOUBLE_OPERAND ResultOperand,
00265 IN ULONGLONG StickyBits
00266 );
00267
00268 BOOLEAN
00269
KiNormalizeQuadword (
00270 IN PFP_CONTEXT_BLOCK ContextBlock,
00271 IN PFP_DOUBLE_OPERAND ResultOperand
00272 );
00273
00274 BOOLEAN
00275
KiNormalizeSingle (
00276 IN PFP_CONTEXT_BLOCK ContextBlock,
00277 IN PFP_SINGLE_OPERAND ResultOperand,
00278 IN ULONG StickyBits
00279 );
00280
00281
VOID
00282
KiUnpackDouble (
00283 IN ULONG Source,
00284 IN PFP_CONTEXT_BLOCK ContextBlock,
00285 OUT PFP_DOUBLE_OPERAND DoubleOperand
00286 );
00287
00288
VOID
00289
KiUnpackSingle (
00290 IN ULONG Source,
00291 IN PFP_CONTEXT_BLOCK ContextBlock,
00292 OUT PFP_SINGLE_OPERAND SingleOperand
00293 );
00294
00295 BOOLEAN
00296 KiEmulateFloating (
00297 IN OUT PEXCEPTION_RECORD ExceptionRecord,
00298 IN OUT PKEXCEPTION_FRAME ExceptionFrame,
00299 IN OUT PKTRAP_FRAME TrapFrame,
00300 IN OUT PSW_FPCR SoftwareFpcr
00301 )
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330 {
00331
00332 ULARGE_INTEGER AhighBhigh;
00333 ULARGE_INTEGER AhighBlow;
00334 ULARGE_INTEGER AlowBhigh;
00335 ULARGE_INTEGER AlowBlow;
00336 ULONG Carry1;
00337 ULONG Carry2;
00338 BOOLEAN CompareEqual;
00339 BOOLEAN CompareLess;
00340 BOOLEAN CompareResult;
00341
FP_CONTEXT_BLOCK ContextBlock;
00342 LARGE_INTEGER DoubleDividend;
00343 LARGE_INTEGER DoubleDivisor;
00344 ULONG DoubleMantissaLow;
00345 LONG DoubleMantissaHigh;
00346
FP_DOUBLE_OPERAND DoubleOperand1;
00347
FP_DOUBLE_OPERAND DoubleOperand2;
00348
FP_DOUBLE_OPERAND DoubleOperand3;
00349 LARGE_INTEGER DoubleQuotient;
00350 PVOID ExceptionAddress;
00351 ULONG ExponentDifference;
00352 ULONG Fa;
00353 ULONG Fb;
00354 ULONG Function;
00355 ULONG
Index;
00356 ALPHA_INSTRUCTION Instruction;
00357 ULARGE_INTEGER LargeResult;
00358 LONG Negation;
00359 LONGLONG Quadword;
00360 LONG SingleMantissa;
00361
FP_SINGLE_OPERAND SingleOperand1;
00362
FP_SINGLE_OPERAND SingleOperand2;
00363
FP_SINGLE_OPERAND SingleOperand3;
00364 ULONG StickyBits;
00365 BOOLEAN ValidOperation;
00366
00367
00368
00369
00370
00371
00372 ExceptionAddress = ExceptionRecord->ExceptionAddress;
00373
00374
00375
00376
00377
00378
00379
00380
00381
try {
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393
00394 Instruction = *((PALPHA_INSTRUCTION)ExceptionRecord->ExceptionAddress);
00395
DBGPRINT(
"KiEmulateFloating: Instruction = %.8lx, Fpcr = %.16Lx\n",
00396 Instruction.Long, TrapFrame->Fpcr);
00397 Function = Instruction.FpOp.Function;
00398
00399 ValidOperation =
FALSE;
00400
if (Instruction.FpOp.Opcode == IEEEFP_OP) {
00401
00402
00403
00404
00405
00406
if (Function == CVTST_FUNC) {
00407 Function =
CVTST_FUNC_PROPER;
00408
00409 }
else if (Function == CVTST_S_FUNC) {
00410 Function =
CVTST_FUNC_PROPER | FP_TRAP_ENABLE_S;
00411 }
00412
00413
switch (Function & FP_FUNCTION_MASK) {
00414
case ADDS_FUNC :
00415
case SUBS_FUNC :
00416
case MULS_FUNC :
00417
case DIVS_FUNC :
00418
case ADDT_FUNC :
00419
case SUBT_FUNC :
00420
case MULT_FUNC :
00421
case DIVT_FUNC :
00422
case CVTTQ_FUNC :
00423
case CVTTS_FUNC :
00424
00425
switch (Function & FP_TRAP_ENABLE_MASK) {
00426
case FP_TRAP_ENABLE_NONE :
00427
case FP_TRAP_ENABLE_U :
00428
case FP_TRAP_ENABLE_SU :
00429
case FP_TRAP_ENABLE_SUI :
00430
00431 ValidOperation =
TRUE;
00432
break;
00433 }
00434
break;
00435
00436
case CVTQS_FUNC :
00437
case CVTQT_FUNC :
00438
00439
switch (Function & FP_TRAP_ENABLE_MASK) {
00440
case FP_TRAP_ENABLE_NONE :
00441
case FP_TRAP_ENABLE_SUI :
00442
00443 ValidOperation =
TRUE;
00444
break;
00445 }
00446
break;
00447
00448
case CVTST_FUNC_PROPER :
00449
00450
switch (Function & FP_TRAP_ENABLE_MASK) {
00451
case FP_TRAP_ENABLE_NONE :
00452
case FP_TRAP_ENABLE_S :
00453
00454 ValidOperation =
TRUE;
00455
break;
00456 }
00457
break;
00458
00459
case CMPTEQ_FUNC :
00460
case CMPTLE_FUNC :
00461
case CMPTLT_FUNC :
00462
case CMPTUN_FUNC :
00463
00464 ValidOperation =
TRUE;
00465
break;
00466 }
00467
00468 }
else if (Instruction.FpOp.Opcode == FPOP_OP) {
00469
switch (Function) {
00470
case CVTLQ_FUNC :
00471
case CVTQL_FUNC :
00472
case CVTQLV_FUNC :
00473
case CVTQLSV_FUNC :
00474
00475 ValidOperation =
TRUE;
00476
break;
00477 }
00478 }
00479
00480
if (ValidOperation ==
FALSE) {
00481
00482
00483
00484
00485
00486
00487
00488 ExceptionRecord->ExceptionCode = STATUS_ILLEGAL_INSTRUCTION;
00489
DBGPRINT(
"KiEmulateFloating: Invalid Function or Format\n");
00490
return FALSE;
00491 }
00492
00493
00494
00495
00496
00497
KeGetCurrentPrcb()->KeFloatingEmulationCount += 1;
00498
00499
00500
00501
00502
00503
00504
00505
00506
00507
00508 ContextBlock.
ExceptionRecord = ExceptionRecord;
00509 ContextBlock.
ExceptionFrame = ExceptionFrame;
00510 ContextBlock.
TrapFrame = TrapFrame;
00511 ContextBlock.
SoftwareFpcr = SoftwareFpcr;
00512
00513
00514
00515
00516
00517
00518
00519
00520
if ((Function & FP_TRAP_ENABLE_S) != 0) {
00521 ContextBlock.
IeeeMode =
TRUE;
00522
00523 }
else {
00524 ContextBlock.
IeeeMode =
FALSE;
00525 }
00526
00527
if ((Function & FP_TRAP_ENABLE_U) != 0) {
00528 ContextBlock.
UnderflowEnable =
TRUE;
00529
00530 }
else {
00531 ContextBlock.
UnderflowEnable =
FALSE;
00532 }
00533
00534
00535
00536
00537
00538
00539
00540
00541
00542 ContextBlock.
Fc = Instruction.FpOp.Fc;
00543 Fa = Instruction.FpOp.Fa;
00544 Fb = Instruction.FpOp.Fb;
00545
00546
if ((Function & FP_ROUND_MASK) == FP_ROUND_D) {
00547 ContextBlock.
Round = ((PFPCR)&TrapFrame->Fpcr)->DynamicRoundingMode;
00548
00549 }
else {
00550 ContextBlock.
Round = (Function & FP_ROUND_MASK) >> FP_ROUND_SHIFT;
00551 }
00552
00553 SoftwareFpcr->EmulationOccurred = 1;
00554
00555
00556
00557
00558
00559
switch (Function & FP_FUNCTION_MASK) {
00560
case ADDS_FUNC :
00561
case SUBS_FUNC :
00562
case MULS_FUNC :
00563
case DIVS_FUNC :
00564
00565
00566
00567
00568
00569
KiUnpackSingle(Fa, &ContextBlock, &SingleOperand1);
00570
KiUnpackSingle(Fb, &ContextBlock, &SingleOperand2);
00571
00572
00573
00574
00575
00576
00577
if ((ContextBlock.
IeeeMode ==
FALSE) &&
00578 ((SingleOperand1.
Normal ==
FALSE) ||
00579 (SingleOperand2.
Normal ==
FALSE))) {
00580 ExceptionRecord->ExceptionCode = STATUS_FLOAT_INVALID_OPERATION;
00581
return FALSE;
00582 }
00583
00584
if ((SingleOperand1.
Nan !=
FALSE) || (SingleOperand2.
Nan !=
FALSE)) {
00585
00586
00587
00588
00589
00590
00591
00592
00593
return KiInvalidOperationSingle(&ContextBlock,
00594
TRUE,
00595 &SingleOperand1,
00596 &SingleOperand2);
00597 }
00598
break;
00599
00600
case ADDT_FUNC :
00601
case SUBT_FUNC :
00602
case MULT_FUNC :
00603
case DIVT_FUNC :
00604
00605
00606
00607
00608
00609
KiUnpackDouble(Fa, &ContextBlock, &DoubleOperand1);
00610
KiUnpackDouble(Fb, &ContextBlock, &DoubleOperand2);
00611
00612
00613
00614
00615
00616
00617
if ((ContextBlock.
IeeeMode ==
FALSE) &&
00618 ((DoubleOperand1.
Normal ==
FALSE) ||
00619 (DoubleOperand2.
Normal ==
FALSE))) {
00620 ExceptionRecord->ExceptionCode = STATUS_FLOAT_INVALID_OPERATION;
00621
return FALSE;
00622 }
00623
if ((DoubleOperand1.
Nan !=
FALSE) || (DoubleOperand2.
Nan !=
FALSE)) {
00624
00625
00626
00627
00628
00629
00630
00631
00632
return KiInvalidOperationDouble(&ContextBlock,
00633
TRUE,
00634 &DoubleOperand1,
00635 &DoubleOperand2);
00636 }
00637
break;
00638
00639
case CMPTEQ_FUNC :
00640
case CMPTLE_FUNC :
00641
case CMPTLT_FUNC :
00642
case CMPTUN_FUNC :
00643
00644
00645
00646
00647
00648
KiUnpackDouble(Fa, &ContextBlock, &DoubleOperand1);
00649
KiUnpackDouble(Fb, &ContextBlock, &DoubleOperand2);
00650
00651
00652
00653
00654
00655
00656
if ((ContextBlock.
IeeeMode ==
FALSE) &&
00657 (((DoubleOperand1.
Normal ==
FALSE) &&
00658 (DoubleOperand1.
Infinity ==
FALSE)) ||
00659 ((DoubleOperand2.
Normal ==
FALSE) &&
00660 (DoubleOperand2.
Infinity ==
FALSE)))) {
00661 ExceptionRecord->ExceptionCode = STATUS_FLOAT_INVALID_OPERATION;
00662
return FALSE;
00663 }
00664
00665
00666
00667
00668
00669
00670
00671
00672
00673
00674
if ((DoubleOperand1.
Nan !=
FALSE) || (DoubleOperand2.
Nan !=
FALSE)) {
00675
00676
00677
00678
00679
00680
00681
00682
00683
00684
00685
00686
00687
00688
00689
00690
if ((Function & FP_FUNCTION_MASK) == CMPTUN_FUNC) {
00691
KiSetRegisterValue(ContextBlock.
Fc + 32,
00692 FP_COMPARE_TRUE,
00693 ExceptionFrame,
00694 TrapFrame);
00695
00696
return KiInvalidCompareDouble(&ContextBlock,
00697
TRUE,
00698 &DoubleOperand1,
00699 &DoubleOperand2);
00700
00701 }
else if ((Function & FP_FUNCTION_MASK) == CMPTEQ_FUNC) {
00702
KiSetRegisterValue(ContextBlock.
Fc + 32,
00703 FP_COMPARE_FALSE,
00704 ExceptionFrame,
00705 TrapFrame);
00706
00707
return KiInvalidCompareDouble(&ContextBlock,
00708
TRUE,
00709 &DoubleOperand1,
00710 &DoubleOperand2);
00711
00712 }
else {
00713
KiSetRegisterValue(ContextBlock.
Fc + 32,
00714 FP_COMPARE_FALSE,
00715 ExceptionFrame,
00716 TrapFrame);
00717
00718
return KiInvalidCompareDouble(&ContextBlock,
00719
FALSE,
00720 &DoubleOperand1,
00721 &DoubleOperand2);
00722 }
00723
00724 }
else {
00725
if ((Function & FP_FUNCTION_MASK) == CMPTUN_FUNC) {
00726
KiSetRegisterValue(ContextBlock.
Fc + 32,
00727 FP_COMPARE_FALSE,
00728 ExceptionFrame,
00729 TrapFrame);
00730
00731
return TRUE;
00732 }
00733 }
00734
break;
00735
00736
case CVTST_FUNC_PROPER :
00737
00738
00739
00740
00741
00742
00743
KiUnpackSingle(Fb, &ContextBlock, &SingleOperand1);
00744
00745
00746
00747
00748
00749
00750
if ((ContextBlock.
IeeeMode ==
FALSE) &&
00751 (SingleOperand1.
Normal ==
FALSE)) {
00752 ExceptionRecord->ExceptionCode = STATUS_FLOAT_INVALID_OPERATION;
00753
return FALSE;
00754 }
00755
break;
00756
00757
case CVTTQ_FUNC :
00758
case CVTTS_FUNC :
00759
00760
00761
00762
00763
00764
00765
KiUnpackDouble(Fb, &ContextBlock, &DoubleOperand1);
00766
00767
00768
00769
00770
00771
00772
if ((ContextBlock.
IeeeMode ==
FALSE) &&
00773 (DoubleOperand1.
Normal ==
FALSE)) {
00774 ExceptionRecord->ExceptionCode = STATUS_FLOAT_INVALID_OPERATION;
00775
return FALSE;
00776 }
00777
break;
00778
00779
case CVTLQ_FUNC :
00780
case CVTQL_FUNC :
00781
case CVTQS_FUNC :
00782
case CVTQT_FUNC :
00783
00784
00785
00786
00787
00788
00789 Quadword =
KiGetRegisterValue(Fb + 32,
00790 ContextBlock.
ExceptionFrame,
00791 ContextBlock.
TrapFrame);
00792
break;
00793 }
00794
00795
00796
00797
00798
00799 Negation = 0;
00800
switch (Function & FP_FUNCTION_MASK) {
00801
00802
00803
00804
00805
00806
00807
00808
00809
case SUBS_FUNC :
00810
DBGPRINT2(
"subs\n");
00811 Negation = 0x1;
00812
00813
00814
00815
00816
00817
00818
00819
00820
00821
00822
00823
00824
00825
00826
00827
00828
00829
00830
00831
00832
00833
00834
00835
00836
00837
00838
case ADDS_FUNC :
00839
DBGPRINT2(
"adds\n");
00840
00841
00842
00843
00844
00845
00846 SingleOperand2.
Sign ^= Negation;
00847
00848
00849
00850
00851
00852
00853
if (SingleOperand2.
Exponent > SingleOperand1.
Exponent) {
00854 SingleOperand3 = SingleOperand2;
00855 SingleOperand2 = SingleOperand1;
00856 SingleOperand1 = SingleOperand3;
00857 }
00858
00859
00860
00861
00862
00863
00864
00865
00866 ExponentDifference =
00867 SingleOperand1.
Exponent - SingleOperand2.
Exponent;
00868
00869
if (ExponentDifference > 26) {
00870 ExponentDifference = 26;
00871 }
00872
00873 StickyBits =
00874 SingleOperand2.
Mantissa & ((1 << ExponentDifference) - 1);
00875 SingleMantissa = SingleOperand2.
Mantissa >> ExponentDifference;
00876
00877
00878
00879
00880
00881
00882
00883
00884
if ((SingleOperand1.
Sign ^ SingleOperand2.
Sign) == 0) {
00885 SingleOperand1.
Mantissa += SingleMantissa;
00886
00887 }
else {
00888
if ((SingleOperand1.
Infinity !=
FALSE) &&
00889 (SingleOperand2.
Infinity !=
FALSE)) {
00890
return KiInvalidOperationSingle(&ContextBlock,
00891
FALSE,
00892 &SingleOperand1,
00893 &SingleOperand2);
00894
00895 }
else if (SingleOperand1.
Infinity ==
FALSE) {
00896
if (StickyBits != 0) {
00897 SingleOperand1.
Mantissa -= 1;
00898 }
00899
00900 SingleOperand1.
Mantissa -= SingleMantissa;
00901
if (SingleOperand1.
Mantissa < 0) {
00902 SingleOperand1.
Mantissa = -SingleOperand1.
Mantissa;
00903 SingleOperand1.
Sign ^= 0x1;
00904 }
00905
00906
00907
00908
00909
00910
00911
00912
if ((SingleOperand1.
Mantissa == 0) && (StickyBits == 0)) {
00913
if (ContextBlock.
Round == ROUND_TO_MINUS_INFINITY) {
00914 SingleOperand1.
Sign = 0x1;
00915
00916 }
else {
00917 SingleOperand1.
Sign = 0x0;
00918 }
00919 }
00920 }
00921 }
00922
00923
00924
00925
00926
00927
return KiNormalizeSingle(&ContextBlock,
00928 &SingleOperand1,
00929 StickyBits);
00930
00931
case SUBT_FUNC :
00932
DBGPRINT2(
"subt\n");
00933 Negation = 0x1;
00934
00935
case ADDT_FUNC :
00936
DBGPRINT2(
"addt\n");
00937
00938
00939
00940
00941
00942
00943 DoubleOperand2.
Sign ^= Negation;
00944
00945
00946
00947
00948
00949
00950
if (DoubleOperand2.
Exponent > DoubleOperand1.
Exponent) {
00951 DoubleOperand3 = DoubleOperand2;
00952 DoubleOperand2 = DoubleOperand1;
00953 DoubleOperand1 = DoubleOperand3;
00954 }
00955
00956
00957
00958
00959
00960
00961
00962
00963 ExponentDifference =
00964 DoubleOperand1.
Exponent - DoubleOperand2.
Exponent;
00965
00966
if (ExponentDifference > 55) {
00967 ExponentDifference = 55;
00968 }
00969
00970
if (ExponentDifference >= 32) {
00971 ExponentDifference -= 32;
00972 StickyBits = (DoubleOperand2.
MantissaLow) |
00973 (DoubleOperand2.
MantissaHigh & ((1 << ExponentDifference) - 1));
00974
00975 DoubleMantissaLow =
00976 DoubleOperand2.
MantissaHigh >> ExponentDifference;
00977
00978 DoubleMantissaHigh = 0;
00979
00980 }
else if (ExponentDifference > 0) {
00981 StickyBits =
00982 DoubleOperand2.
MantissaLow & ((1 << ExponentDifference) - 1);
00983
00984 DoubleMantissaLow =
00985 (DoubleOperand2.
MantissaLow >> ExponentDifference) |
00986 (DoubleOperand2.
MantissaHigh << (32 - ExponentDifference));
00987
00988 DoubleMantissaHigh =
00989 DoubleOperand2.
MantissaHigh >> ExponentDifference;
00990
00991 }
else {
00992 StickyBits = 0;
00993 DoubleMantissaLow = DoubleOperand2.
MantissaLow;
00994 DoubleMantissaHigh = DoubleOperand2.
MantissaHigh;
00995 }
00996
00997
00998
00999
01000
01001
01002
01003
01004
if ((DoubleOperand1.
Sign ^ DoubleOperand2.
Sign) == 0) {
01005 DoubleOperand1.
MantissaLow += DoubleMantissaLow;
01006 DoubleOperand1.
MantissaHigh += DoubleMantissaHigh;
01007
if (DoubleOperand1.
MantissaLow < DoubleMantissaLow) {
01008 DoubleOperand1.
MantissaHigh += 1;
01009 }
01010
01011 }
else {
01012
if ((DoubleOperand1.
Infinity !=
FALSE) &&
01013 (DoubleOperand2.
Infinity !=
FALSE)) {
01014
return KiInvalidOperationDouble(&ContextBlock,
01015
FALSE,
01016 &DoubleOperand1,
01017 &DoubleOperand2);
01018
01019 }
else if (DoubleOperand1.
Infinity ==
FALSE) {
01020
if (StickyBits != 0) {
01021
if (DoubleOperand1.
MantissaLow < 1) {
01022 DoubleOperand1.
MantissaHigh -= 1;
01023 }
01024
01025 DoubleOperand1.
MantissaLow -= 1;
01026 }
01027
01028
if (DoubleOperand1.
MantissaLow < DoubleMantissaLow) {
01029 DoubleOperand1.
MantissaHigh -= 1;
01030 }
01031
01032 DoubleOperand1.
MantissaLow -= DoubleMantissaLow;
01033 DoubleOperand1.
MantissaHigh -= DoubleMantissaHigh;
01034
if (DoubleOperand1.
MantissaHigh < 0) {
01035 DoubleOperand1.
MantissaLow = -(LONG)DoubleOperand1.
MantissaLow;
01036 DoubleOperand1.
MantissaHigh = -DoubleOperand1.
MantissaHigh;
01037
if (DoubleOperand1.
MantissaLow != 0) {
01038 DoubleOperand1.
MantissaHigh -= 1;
01039 }
01040 DoubleOperand1.
Sign ^= 0x1;
01041 }
01042
01043
01044
01045
01046
01047
01048
01049
if ((DoubleOperand1.
MantissaHigh == 0) &&
01050 (DoubleOperand1.
MantissaLow == 0) &&
01051 (StickyBits == 0)) {
01052
if (ContextBlock.
Round == ROUND_TO_MINUS_INFINITY) {
01053 DoubleOperand1.
Sign = 0x1;
01054
01055 }
else {
01056 DoubleOperand1.
Sign = 0x0;
01057 }
01058 }
01059 }
01060 }
01061
01062
01063
01064
01065
01066
return KiNormalizeDouble(&ContextBlock,
01067 &DoubleOperand1,
01068 StickyBits);
01069
01070
01071
01072
01073
01074
01075
01076
01077
01078
01079
01080
01081
case MULS_FUNC :
01082
DBGPRINT2(
"muls\n");
01083
01084
01085
01086
01087
01088
01089
if (SingleOperand2.
Exponent > SingleOperand1.
Exponent) {
01090 SingleOperand3 = SingleOperand2;
01091 SingleOperand2 = SingleOperand1;
01092 SingleOperand1 = SingleOperand3;
01093 }
01094
01095
01096
01097
01098
01099
01100
if ((SingleOperand1.
Infinity !=
FALSE) &&
01101 (SingleOperand2.
Infinity ==
FALSE) &&
01102 (SingleOperand2.
Mantissa == 0)) {
01103
return KiInvalidOperationSingle(&ContextBlock,
01104
FALSE,
01105 &SingleOperand1,
01106 &SingleOperand2);
01107 }
01108
01109
01110
01111
01112
01113
01114
01115
01116
01117
01118
01119
01120
01121
01122
01123
01124
01125
01126
01127
01128
01129 LargeResult.QuadPart = ((ULONGLONG)((ULONG)(SingleOperand1.
Mantissa << (32 - 26)))) *
01130 ((ULONGLONG)((ULONG)(SingleOperand2.
Mantissa << 1)));
01131
01132 SingleOperand1.
Mantissa = LargeResult.HighPart;
01133 StickyBits = LargeResult.LowPart;
01134
01135
01136
01137
01138
01139 SingleOperand1.
Sign ^= SingleOperand2.
Sign;
01140 SingleOperand1.
Exponent +=
01141 SingleOperand2.
Exponent - SINGLE_EXPONENT_BIAS;
01142
01143
01144
01145
01146
01147
return KiNormalizeSingle(&ContextBlock,
01148 &SingleOperand1,
01149 StickyBits);
01150
01151
case MULT_FUNC :
01152
DBGPRINT2(
"mult\n");
01153
01154
01155
01156
01157
01158
01159
if (DoubleOperand2.
Exponent > DoubleOperand1.
Exponent) {
01160 DoubleOperand3 = DoubleOperand2;
01161 DoubleOperand2 = DoubleOperand1;
01162 DoubleOperand1 = DoubleOperand3;
01163 }
01164
01165
01166
01167
01168
01169
01170
if ((DoubleOperand1.
Infinity !=
FALSE) &&
01171 (DoubleOperand2.
Infinity ==
FALSE) &&
01172 (DoubleOperand2.
MantissaHigh == 0)) {
01173
return KiInvalidOperationDouble(&ContextBlock,
01174
FALSE,
01175 &DoubleOperand1,
01176 &DoubleOperand2);
01177 }
01178
01179
01180
01181
01182
01183
01184
01185
01186
01187
01188
01189
01190
01191
01192
01193
01194
01195
01196
01197
01198
01199 DoubleOperand1.
MantissaHigh =
01200 (DoubleOperand1.
MantissaHigh << 1) |
01201 (DoubleOperand1.
MantissaLow >> 31);
01202
01203 DoubleOperand1.
MantissaLow <<= 1;
01204 DoubleOperand2.
MantissaHigh =
01205 (DoubleOperand2.
MantissaHigh << (64 - 55)) |
01206 (DoubleOperand2.
MantissaLow >> (32 - (64 - 55)));
01207
01208 DoubleOperand2.
MantissaLow <<= (64 - 55);
01209
01210
01211
01212
01213
01214
01215
01216
01217
01218
01219
01220
01221
01222
01223
01224 AhighBhigh.QuadPart = (ULONGLONG)(ULONG)DoubleOperand1.
MantissaHigh *
01225 (ULONGLONG)(ULONG)DoubleOperand2.
MantissaHigh;
01226
01227 AhighBlow.QuadPart = (ULONGLONG)(ULONG)DoubleOperand1.
MantissaHigh *
01228 (ULONGLONG)DoubleOperand2.
MantissaLow;
01229
01230 AlowBhigh.QuadPart = (ULONGLONG)DoubleOperand1.
MantissaLow *
01231 (ULONGLONG)(ULONG)DoubleOperand2.
MantissaHigh;
01232
01233 AlowBlow.QuadPart = (ULONGLONG)DoubleOperand1.
MantissaLow *
01234 (ULONGLONG)DoubleOperand2.
MantissaLow;
01235
01236 AlowBlow.HighPart += AhighBlow.LowPart;
01237
if (AlowBlow.HighPart < AhighBlow.LowPart) {
01238 Carry1 = 1;
01239
01240 }
else {
01241 Carry1 = 0;
01242 }
01243
01244 AlowBlow.HighPart += AlowBhigh.LowPart;
01245
if (AlowBlow.HighPart < AlowBhigh.LowPart) {
01246 Carry1 += 1;
01247 }
01248
01249 DoubleOperand1.
MantissaLow = AhighBlow.HighPart + Carry1;
01250
if (DoubleOperand1.
MantissaLow < Carry1) {
01251 Carry2 = 1;
01252
01253 }
else {
01254 Carry2 = 0;
01255 }
01256
01257 DoubleOperand1.
MantissaLow += AlowBhigh.HighPart;
01258
if (DoubleOperand1.
MantissaLow < AlowBhigh.HighPart) {
01259 Carry2 += 1;
01260 }
01261
01262 DoubleOperand1.
MantissaLow += AhighBhigh.LowPart;
01263
if (DoubleOperand1.
MantissaLow < AhighBhigh.LowPart) {
01264 Carry2 += 1;
01265 }
01266
01267 DoubleOperand1.
MantissaHigh = AhighBhigh.HighPart + Carry2;
01268 StickyBits = AlowBlow.HighPart | AlowBlow.LowPart;
01269
01270
01271
01272
01273
01274 DoubleOperand1.
Sign ^= DoubleOperand2.
Sign;
01275 DoubleOperand1.
Exponent +=
01276 DoubleOperand2.
Exponent - DOUBLE_EXPONENT_BIAS;
01277
01278
01279
01280
01281
01282
return KiNormalizeDouble(&ContextBlock,
01283 &DoubleOperand1,
01284 StickyBits);
01285
01286
01287
01288
01289
01290
01291
01292
01293
01294
01295
01296
01297
01298
case DIVS_FUNC :
01299
DBGPRINT2(
"divs\n");
01300
01301
01302
01303
01304
01305
01306
01307
if (((SingleOperand1.
Infinity !=
FALSE) &&
01308 (SingleOperand2.
Infinity !=
FALSE)) ||
01309 ((SingleOperand1.
Infinity ==
FALSE) &&
01310 (SingleOperand1.
Mantissa == 0) &&
01311 (SingleOperand2.
Infinity ==
FALSE) &&
01312 (SingleOperand2.
Mantissa == 0))) {
01313
return KiInvalidOperationSingle(&ContextBlock,
01314
FALSE,
01315 &SingleOperand1,
01316 &SingleOperand2);
01317 }
01318
01319
01320
01321
01322
01323
01324
if ((SingleOperand2.
Infinity ==
FALSE) &&
01325 (SingleOperand2.
Mantissa == 0)) {
01326
return KiDivideByZeroSingle(&ContextBlock,
01327 &SingleOperand1,
01328 &SingleOperand2);
01329 }
01330
01331
01332
01333
01334
01335
01336
01337
01338
if (SingleOperand1.
Infinity !=
FALSE) {
01339 SingleOperand1.
Sign ^= SingleOperand2.
Sign;
01340
return KiNormalizeSingle(&ContextBlock,
01341 &SingleOperand1,
01342 0);
01343
01344 }
else if (SingleOperand2.
Infinity !=
FALSE) {
01345 SingleOperand1.
Sign ^= SingleOperand2.
Sign;
01346 SingleOperand1.
Exponent = 0;
01347 SingleOperand1.
Mantissa = 0;
01348
return KiNormalizeSingle(&ContextBlock,
01349 &SingleOperand1,
01350 0);
01351 }
01352
01353
01354
01355
01356
01357
01358 SingleOperand3.
Mantissa = 0;
01359
for (
Index = 0;
Index < 26;
Index += 1) {
01360 SingleOperand3.
Mantissa <<= 1;
01361
if (SingleOperand1.
Mantissa >= SingleOperand2.
Mantissa) {
01362 SingleOperand1.
Mantissa -= SingleOperand2.
Mantissa;
01363 SingleOperand3.
Mantissa |= 1;
01364 }
01365
01366 SingleOperand1.
Mantissa <<= 1;
01367 }
01368
01369
01370
01371
01372
01373 SingleOperand3.
Sign = SingleOperand1.
Sign ^ SingleOperand2.
Sign;
01374 SingleOperand3.
Exponent = SingleOperand1.
Exponent -
01375 SingleOperand2.
Exponent + SINGLE_EXPONENT_BIAS;
01376
01377
01378
01379
01380
01381 SingleOperand3.
Infinity =
FALSE;
01382 SingleOperand3.
Nan =
FALSE;
01383
return KiNormalizeSingle(&ContextBlock,
01384 &SingleOperand3,
01385 SingleOperand1.
Mantissa);
01386
01387
case DIVT_FUNC :
01388
DBGPRINT2(
"divt\n");
01389
01390
01391
01392
01393
01394
01395
01396
if (((DoubleOperand1.
Infinity !=
FALSE) &&
01397 (DoubleOperand2.
Infinity !=
FALSE)) ||
01398 ((DoubleOperand1.
Infinity ==
FALSE) &&
01399 (DoubleOperand1.
MantissaHigh == 0) &&
01400 (DoubleOperand2.
Infinity ==
FALSE) &&
01401 (DoubleOperand2.
MantissaHigh == 0))) {
01402
return KiInvalidOperationDouble(&ContextBlock,
01403
FALSE,
01404 &DoubleOperand1,
01405 &DoubleOperand2);
01406 }
01407
01408
01409
01410
01411
01412
01413
if ((DoubleOperand2.
Infinity ==
FALSE) &&
01414 (DoubleOperand2.
MantissaHigh == 0)) {
01415
return KiDivideByZeroDouble(&ContextBlock,
01416 &DoubleOperand1,
01417 &DoubleOperand2);
01418 }
01419
01420
01421
01422
01423
01424
01425
01426
01427
if (DoubleOperand1.
Infinity !=
FALSE) {
01428 DoubleOperand1.
Sign ^= DoubleOperand2.
Sign;
01429
return KiNormalizeDouble(&ContextBlock,
01430 &DoubleOperand1,
01431 0);
01432
01433 }
else if (DoubleOperand2.
Infinity !=
FALSE) {
01434 DoubleOperand1.
Sign ^= DoubleOperand2.
Sign;
01435 DoubleOperand1.
Exponent = 0;
01436 DoubleOperand1.
MantissaHigh = 0;
01437 DoubleOperand1.
MantissaLow = 0;
01438
return KiNormalizeDouble(&ContextBlock,
01439 &DoubleOperand1,
01440 0);
01441 }
01442
01443
01444
01445
01446
01447
01448 DoubleDividend.LowPart = DoubleOperand1.
MantissaLow;
01449 DoubleDividend.HighPart = DoubleOperand1.
MantissaHigh;
01450 DoubleDivisor.LowPart = DoubleOperand2.
MantissaLow;
01451 DoubleDivisor.HighPart = DoubleOperand2.
MantissaHigh;
01452 DoubleQuotient.LowPart = 0;
01453 DoubleQuotient.HighPart = 0;
01454
for (
Index = 0;
Index < 55;
Index += 1) {
01455 DoubleQuotient.HighPart =
01456 (DoubleQuotient.HighPart << 1) |
01457 DoubleQuotient.LowPart >> 31;
01458
01459 DoubleQuotient.LowPart <<= 1;
01460
if (DoubleDividend.QuadPart >= DoubleDivisor.QuadPart) {
01461 DoubleDividend.QuadPart = DoubleDividend.QuadPart - DoubleDivisor.QuadPart;
01462 DoubleQuotient.LowPart |= 1;
01463 }
01464
01465 DoubleDividend.HighPart =
01466 (DoubleDividend.HighPart << 1) |
01467 DoubleDividend.LowPart >> 31;
01468
01469 DoubleDividend.LowPart <<= 1;
01470 }
01471
01472 DoubleOperand3.
MantissaLow = DoubleQuotient.LowPart;
01473 DoubleOperand3.
MantissaHigh = DoubleQuotient.HighPart;
01474
01475
01476
01477
01478
01479 DoubleOperand3.
Sign = DoubleOperand1.
Sign ^ DoubleOperand2.
Sign;
01480 DoubleOperand3.
Exponent = DoubleOperand1.
Exponent -
01481 DoubleOperand2.
Exponent + DOUBLE_EXPONENT_BIAS;
01482
01483
01484
01485
01486
01487 DoubleOperand3.
Infinity =
FALSE;
01488 DoubleOperand3.
Nan =
FALSE;
01489
return KiNormalizeDouble(&ContextBlock,
01490 &DoubleOperand3,
01491 DoubleDividend.LowPart | DoubleDividend.HighPart);
01492
01493
01494
01495
01496
01497
01498
01499
01500
01501
01502
01503
01504
01505
01506
case CMPTEQ_FUNC :
01507
case CMPTLE_FUNC :
01508
case CMPTLT_FUNC :
01509
01510
01511
01512
01513
01514
01515
01516
if ((DoubleOperand1.
Infinity ==
FALSE) &&
01517 (DoubleOperand1.
MantissaHigh == 0)) {
01518 DoubleOperand1.
Sign = 0;
01519 DoubleOperand1.
Exponent = -52;
01520 }
01521
01522
if ((DoubleOperand2.
Infinity ==
FALSE) &&
01523 (DoubleOperand2.
MantissaHigh == 0)) {
01524 DoubleOperand2.
Sign = 0;
01525 DoubleOperand2.
Exponent = -52;
01526 }
01527
01528
01529
01530
01531
01532
if (DoubleOperand1.
Sign < DoubleOperand2.
Sign) {
01533
01534
01535
01536
01537
01538 CompareEqual =
FALSE;
01539 CompareLess =
FALSE;
01540
01541 }
else if (DoubleOperand1.
Sign > DoubleOperand2.
Sign) {
01542
01543
01544
01545
01546
01547 CompareEqual =
FALSE;
01548 CompareLess =
TRUE;
01549
01550 }
else {
01551
01552
01553
01554
01555
01556
01557
01558
01559
if (DoubleOperand1.
Sign == 0) {
01560
01561
01562
01563
01564
01565
if (DoubleOperand1.
Exponent > DoubleOperand2.
Exponent) {
01566 CompareEqual =
FALSE;
01567 CompareLess =
FALSE;
01568
01569 }
else if (DoubleOperand1.
Exponent < DoubleOperand2.
Exponent) {
01570 CompareEqual =
FALSE;
01571 CompareLess =
TRUE;
01572
01573 }
else {
01574
if (DoubleOperand1.
MantissaHigh >
01575 DoubleOperand2.
MantissaHigh) {
01576 CompareEqual =
FALSE;
01577 CompareLess =
FALSE;
01578
01579 }
else if (DoubleOperand1.
MantissaHigh <
01580 DoubleOperand2.
MantissaHigh) {
01581 CompareEqual =
FALSE;
01582 CompareLess =
TRUE;
01583
01584 }
else {
01585
if (DoubleOperand1.
MantissaLow >
01586 DoubleOperand2.
MantissaLow) {
01587 CompareEqual =
FALSE;
01588 CompareLess =
FALSE;
01589
01590 }
else if (DoubleOperand1.
MantissaLow <
01591 DoubleOperand2.
MantissaLow) {
01592 CompareEqual =
FALSE;
01593 CompareLess =
TRUE;
01594
01595 }
else {
01596 CompareEqual =
TRUE;
01597 CompareLess =
FALSE;
01598 }
01599 }
01600 }
01601
01602 }
else {
01603
01604
01605
01606
01607
01608
if (DoubleOperand2.
Exponent > DoubleOperand1.
Exponent) {
01609 CompareEqual =
FALSE;
01610 CompareLess =
FALSE;
01611
01612 }
else if (DoubleOperand2.
Exponent < DoubleOperand1.
Exponent) {
01613 CompareEqual =
FALSE;
01614 CompareLess =
TRUE;
01615
01616 }
else {
01617
if (DoubleOperand2.
MantissaHigh >
01618 DoubleOperand1.
MantissaHigh) {
01619 CompareEqual =
FALSE;
01620 CompareLess =
FALSE;
01621
01622 }
else if (DoubleOperand2.
MantissaHigh <
01623 DoubleOperand1.
MantissaHigh) {
01624 CompareEqual =
FALSE;
01625 CompareLess =
TRUE;
01626
01627 }
else {
01628
if (DoubleOperand2.
MantissaLow >
01629 DoubleOperand1.
MantissaLow) {
01630 CompareEqual =
FALSE;
01631 CompareLess =
FALSE;
01632
01633 }
else if (DoubleOperand2.
MantissaLow <
01634 DoubleOperand1.
MantissaLow) {
01635 CompareEqual =
FALSE;
01636 CompareLess =
TRUE;
01637
01638 }
else {
01639 CompareEqual =
TRUE;
01640 CompareLess =
FALSE;
01641 }
01642 }
01643 }
01644 }
01645 }
01646
01647
01648
01649
01650
01651
01652
switch (Function & FP_FUNCTION_MASK) {
01653
case CMPTEQ_FUNC :
01654 CompareResult = CompareEqual;
01655
DBGPRINT2(
"cmpteq\n");
01656
break;
01657
01658
case CMPTLE_FUNC :
01659 CompareResult = (CompareLess | CompareEqual);
01660
DBGPRINT2(
"cmptle\n");
01661
break;
01662
01663
case CMPTLT_FUNC :
01664 CompareResult = CompareLess;
01665
DBGPRINT2(
"cmptlt\n");
01666
break;
01667 }
01668
01669
01670
01671
01672
01673
01674
if (CompareResult !=
FALSE) {
01675
KiSetRegisterValue(ContextBlock.
Fc + 32,
01676 FP_COMPARE_TRUE,
01677 ExceptionFrame,
01678 TrapFrame);
01679
01680 }
else {
01681
KiSetRegisterValue(ContextBlock.
Fc + 32,
01682 FP_COMPARE_FALSE,
01683 ExceptionFrame,
01684 TrapFrame);
01685 }
01686
return TRUE;
01687
01688
01689
01690
01691
01692
01693
01694
01695
01696
case CVTST_FUNC_PROPER :
01697
DBGPRINT2(
"cvtst\n");
01698
01699
01700
01701
01702
01703
01704
01705
01706
if (SingleOperand1.
Nan !=
FALSE) {
01707 DoubleOperand1.
MantissaHigh =
01708 SingleOperand1.
Mantissa >> (26 - (55 - 32));
01709 DoubleOperand1.
MantissaLow =
01710 SingleOperand1.
Mantissa << (32 - (26 - (55 - 32)));
01711 DoubleOperand1.
Exponent = DOUBLE_MAXIMUM_EXPONENT;
01712 DoubleOperand1.
Sign = SingleOperand1.
Sign;
01713 DoubleOperand1.
Infinity =
FALSE;
01714 DoubleOperand1.
Nan =
TRUE;
01715
return KiInvalidOperationDouble(&ContextBlock,
01716
TRUE,
01717 &DoubleOperand1,
01718 &DoubleOperand1);
01719 }
01720
01721
01722
01723
01724
01725 DoubleOperand1.
MantissaHigh =
01726 SingleOperand1.
Mantissa >> (26 - (55 - 32));
01727 DoubleOperand1.
MantissaLow =
01728 SingleOperand1.
Mantissa << (32 - (26 - (55 - 32)));
01729 DoubleOperand1.
Exponent = SingleOperand1.
Exponent +
01730 DOUBLE_EXPONENT_BIAS - SINGLE_EXPONENT_BIAS;
01731 DoubleOperand1.
Sign = SingleOperand1.
Sign;
01732 DoubleOperand1.
Infinity = SingleOperand1.
Infinity;
01733 DoubleOperand1.
Nan =
FALSE;
01734
01735
01736
01737
01738
01739
return KiNormalizeDouble(&ContextBlock,
01740 &DoubleOperand1,
01741 0);
01742
01743
01744
01745
01746
01747
01748
01749
01750
01751
case CVTTS_FUNC :
01752
DBGPRINT2(
"cvtts\n");
01753
01754
01755
01756
01757
01758
01759
01760
01761
if (DoubleOperand1.
Nan !=
FALSE) {
01762 SingleOperand1.
Mantissa =
01763 (DoubleOperand1.
MantissaHigh << (26 - (55 - 32))) |
01764 (DoubleOperand1.
MantissaLow >> (32 - (26 - (55 - 32))));
01765 SingleOperand1.
Exponent = SINGLE_MAXIMUM_EXPONENT;
01766 SingleOperand1.
Sign = DoubleOperand1.
Sign;
01767 SingleOperand1.
Infinity =
FALSE;
01768 SingleOperand1.
Nan =
TRUE;
01769
return KiInvalidOperationSingle(&ContextBlock,
01770
TRUE,
01771 &SingleOperand1,
01772 &SingleOperand1);
01773 }
01774
01775
01776
01777
01778
01779 SingleOperand1.
Mantissa =
01780 (DoubleOperand1.
MantissaHigh << (26 - (55 - 32))) |
01781 (DoubleOperand1.
MantissaLow >> (32 - (26 - (55 - 32))));
01782 StickyBits = DoubleOperand1.
MantissaLow << (26 - (55 - 32));
01783 SingleOperand1.
Exponent = DoubleOperand1.
Exponent +
01784 SINGLE_EXPONENT_BIAS - DOUBLE_EXPONENT_BIAS;
01785 SingleOperand1.
Sign = DoubleOperand1.
Sign;
01786 SingleOperand1.
Infinity = DoubleOperand1.
Infinity;
01787 SingleOperand1.
Nan =
FALSE;
01788
01789
01790
01791
01792
01793
return KiNormalizeSingle(&ContextBlock,
01794 &SingleOperand1,
01795 StickyBits);
01796
01797
01798
01799
01800
01801
01802
01803
01804
case CVTLQ_FUNC :
01805
DBGPRINT2(
"cvtlq\n");
01806
01807
01808
01809
01810
01811
01812
01813
01814 Quadword = ((Quadword >> 62) << 62) | ((ULONGLONG)(Quadword << 5) >> 2);
01815
KiSetRegisterValue(ContextBlock.
Fc + 32,
01816 Quadword >> 32,
01817 ExceptionFrame,
01818 TrapFrame);
01819
01820
return TRUE;
01821
01822
01823
01824
01825
01826
01827
01828
01829
01830
case CVTQL_FUNC :
01831
DBGPRINT2(
"cvtql\n");
01832
01833
return KiConvertQuadwordToLongword(&ContextBlock, Quadword);
01834
01835
01836
01837
01838
01839
01840
01841
01842
01843
case CVTQS_FUNC :
01844
DBGPRINT2(
"cvtqs\n");
01845
01846
01847
01848
01849
01850
if (Quadword < 0) {
01851 SingleOperand1.
Sign = 0x1;
01852 Quadword = -Quadword;
01853
01854 }
else {
01855 SingleOperand1.
Sign = 0;
01856 }
01857
01858
01859
01860
01861
01862 SingleOperand1.
Infinity =
FALSE;
01863 SingleOperand1.
Nan =
FALSE;
01864
01865
01866
01867
01868
01869
01870
if (Quadword != 0) {
01871 SingleOperand1.
Exponent = SINGLE_EXPONENT_BIAS + 63;
01872
while (Quadword > 0) {
01873 Quadword <<= 1;
01874 SingleOperand1.
Exponent -= 1;
01875 }
01876
01877 SingleOperand1.
Mantissa = (LONG)((ULONGLONG)Quadword >> (64 - 26));
01878
if (Quadword & (((ULONGLONG)1 << (64 - 26)) - 1)) {
01879 StickyBits = 1;
01880
01881 }
else {
01882 StickyBits = 0;
01883 }
01884
01885 }
else {
01886 SingleOperand1.
Exponent = 0;
01887 SingleOperand1.
Mantissa = 0;
01888 StickyBits = 0;
01889 }
01890
01891
01892
01893
01894
01895
return KiNormalizeSingle(&ContextBlock,
01896 &SingleOperand1,
01897 StickyBits);
01898
01899
01900
01901
01902
01903
01904
01905
01906
01907
case CVTQT_FUNC :
01908
DBGPRINT2(
"cvtqt\n");
01909
01910
01911
01912
01913
01914
if (Quadword < 0) {
01915 DoubleOperand1.
Sign = 0x1;
01916 Quadword = -Quadword;
01917
01918 }
else {
01919 DoubleOperand1.
Sign = 0;
01920 }
01921
01922
01923
01924
01925
01926 DoubleOperand1.
Infinity =
FALSE;
01927 DoubleOperand1.
Nan =
FALSE;
01928
01929
01930
01931
01932
01933
01934
if (Quadword != 0) {
01935 DoubleOperand1.
Exponent = DOUBLE_EXPONENT_BIAS + 63;
01936
while (Quadword > 0) {
01937 Quadword <<= 1;
01938 DoubleOperand1.
Exponent -= 1;
01939 }
01940
01941 DoubleOperand1.
MantissaHigh = (LONG)((ULONGLONG)Quadword >> ((64 - 55) + 32));
01942 DoubleOperand1.
MantissaLow = (LONG)((ULONGLONG)Quadword >> (64 - 55));
01943
if (Quadword & (((ULONGLONG)1 << (64 - 55)) - 1)) {
01944 StickyBits = 1;
01945
01946 }
else {
01947 StickyBits = 0;
01948 }
01949
01950 }
else {
01951 DoubleOperand1.
MantissaHigh = 0;
01952 DoubleOperand1.
MantissaLow = 0;
01953 DoubleOperand1.
Exponent = 0;
01954 StickyBits = 0;
01955 }
01956
01957
01958
01959
01960
01961
return KiNormalizeDouble(&ContextBlock,
01962 &DoubleOperand1,
01963 StickyBits);
01964
01965
01966
01967
01968
01969
01970
01971
01972
case CVTTQ_FUNC :
01973
DBGPRINT2(
"cvttq\n");
01974
01975
01976
01977
01978
01979
01980
01981
01982
if ((DoubleOperand1.
Infinity !=
FALSE) ||
01983 (DoubleOperand1.
Nan !=
FALSE)) {
01984
return KiInvalidOperationQuadword(&ContextBlock, 0);
01985 }
01986
01987
01988
01989
01990
01991
return KiNormalizeQuadword(&ContextBlock, &DoubleOperand1);
01992 }
01993
01994
01995
01996
01997
01998
01999 } except (
KiCopyInformation(ExceptionRecord,
02000 (GetExceptionInformation())->ExceptionRecord)) {
02001
02002
02003
02004
02005
02006 ExceptionRecord->ExceptionAddress = ExceptionAddress;
02007
DBGPRINT(
"KiEmulateFloating: Exception\n");
02008
return FALSE;
02009 }
02010
02011
DBGPRINT(
"KiEmulateFloating: Invalid Instruction\n");
02012
return FALSE;
02013 }
02014
02015 ULONGLONG
02016 KiConvertSingleOperandToRegister (
02017 IN ULONG SingleValue
02018 )
02019
02020
02021
02022
02023
02024
02025
02026
02027
02028
02029
02030
02031
02032
02033
02034
02035
02036
02037
02038
02039
02040 {
02041
PDOUBLE_FORMAT DoubleFormat;
02042 ULONGLONG Result;
02043
PSINGLE_FORMAT SingleFormat;
02044
02045 SingleFormat = (
PSINGLE_FORMAT)&SingleValue;
02046 DoubleFormat = (
PDOUBLE_FORMAT)&Result;
02047
02048 DoubleFormat->
Sign = SingleFormat->
Sign;
02049 DoubleFormat->
Mantissa = ((ULONGLONG)SingleFormat->
Mantissa) << (52 - 23);
02050
if (SingleFormat->
Exponent == SINGLE_MAXIMUM_EXPONENT) {
02051 DoubleFormat->
Exponent = DOUBLE_MAXIMUM_EXPONENT;
02052
02053 }
else if (SingleFormat->
Exponent == SINGLE_MINIMUM_EXPONENT) {
02054 DoubleFormat->
Exponent = DOUBLE_MINIMUM_EXPONENT;
02055
02056 }
else {
02057 DoubleFormat->
Exponent = SingleFormat->
Exponent - SINGLE_EXPONENT_BIAS +
02058 DOUBLE_EXPONENT_BIAS;
02059 }
02060
return Result;
02061 }
02062
02063 ULONG
02064 KiConvertRegisterToSingleOperand (
02065 IN ULONGLONG DoubleValue
02066 )
02067
02068
02069
02070
02071
02072
02073
02074
02075
02076
02077
02078
02079
02080
02081
02082
02083
02084
02085
02086
02087 {
02088
PDOUBLE_FORMAT DoubleFormat;
02089 ULONG Result;
02090
PSINGLE_FORMAT SingleFormat;
02091
02092 SingleFormat = (
PSINGLE_FORMAT)&Result;
02093 DoubleFormat = (
PDOUBLE_FORMAT)&DoubleValue;
02094
02095 SingleFormat->
Sign = (ULONG)DoubleFormat->
Sign;
02096 SingleFormat->
Mantissa = (ULONG)(DoubleFormat->
Mantissa >> (52 - 23));
02097
if (DoubleFormat->
Exponent == DOUBLE_MAXIMUM_EXPONENT) {
02098 SingleFormat->
Exponent = SINGLE_MAXIMUM_EXPONENT;
02099
02100 }
else if (DoubleFormat->
Exponent == DOUBLE_MINIMUM_EXPONENT) {
02101 SingleFormat->
Exponent = SINGLE_MINIMUM_EXPONENT;
02102
02103 }
else {
02104 SingleFormat->
Exponent = (ULONG)(DoubleFormat->
Exponent - DOUBLE_EXPONENT_BIAS +
02105 SINGLE_EXPONENT_BIAS);
02106 }
02107
return Result;
02108 }
02109
02110 BOOLEAN
02111 KiConvertQuadwordToLongword (
02112 IN PFP_CONTEXT_BLOCK ContextBlock,
02113 IN LONGLONG Quadword
02114 )
02115
02116
02117
02118
02119
02120
02121
02122
02123
02124
02125
02126
02127
02128
02129
02130
02131
02132
02133
02134
02135
02136
02137 {
02138 PEXCEPTION_RECORD ExceptionRecord;
02139 PFPCR Fpcr;
02140 PFP_IEEE_VALUE IeeeValue;
02141 ULONGLONG ResultValue;
02142 PSW_FPCR SoftwareFpcr;
02143
02144
02145
02146
02147
02148
02149 ResultValue = ((Quadword & (ULONGLONG)0xc0000000) << 32) |
02150 ((Quadword & (ULONGLONG)0x3fffffff) << 29);
02151
02152
02153
02154
02155
02156
02157
if ((Quadword < (LONG)0x80000000) || (Quadword > (LONG)0x7fffffff)) {
02158 Fpcr = (PFPCR)&ContextBlock->TrapFrame->Fpcr;
02159 Fpcr->InvalidOperation = 1;
02160 Fpcr->SummaryBit = 1;
02161
if (ContextBlock->IeeeMode ==
FALSE) {
02162 ExceptionRecord = ContextBlock->ExceptionRecord;
02163 ExceptionRecord->ExceptionCode = STATUS_FLOAT_INVALID_OPERATION;
02164
return FALSE;
02165 }
02166 SoftwareFpcr = ContextBlock->SoftwareFpcr;
02167 SoftwareFpcr->StatusInvalid = 1;
02168
if (SoftwareFpcr->EnableInvalid != 0) {
02169 ExceptionRecord = ContextBlock->ExceptionRecord;
02170 ExceptionRecord->ExceptionCode = STATUS_FLOAT_INVALID_OPERATION;
02171 IeeeValue =
KiInitializeIeeeValue(ExceptionRecord);
02172 IeeeValue->Value.U64Value.LowPart =
LOW_PART(ResultValue);
02173 IeeeValue->Value.U64Value.HighPart =
HIGH_PART(ResultValue);
02174
return FALSE;
02175 }
02176
02177 Fpcr->DisableInvalid = 1;
02178 }
02179
02180
02181
02182
02183
02184
KiSetRegisterValue(ContextBlock->Fc + 32,
02185 ResultValue,
02186 ContextBlock->ExceptionFrame,
02187 ContextBlock->TrapFrame);
02188
return TRUE;
02189 }
02190
02191 BOOLEAN
02192 KiDivideByZeroDouble (
02193 IN PFP_CONTEXT_BLOCK ContextBlock,
02194 IN PFP_DOUBLE_OPERAND DoubleOperand1,
02195 IN PFP_DOUBLE_OPERAND DoubleOperand2
02196 )
02197
02198
02199
02200
02201
02202
02203
02204
02205
02206
02207
02208
02209
02210
02211
02212
02213
02214
02215
02216
02217
02218
02219
02220
02221
02222
02223 {
02224
02225 PEXCEPTION_RECORD ExceptionRecord;
02226 PFPCR Fpcr;
02227 PFP_IEEE_VALUE IeeeValue;
02228 ULONG ResultSign;
02229 ULONG ResultValueHigh;
02230 ULONG ResultValueLow;
02231 PSW_FPCR SoftwareFpcr;
02232
02233
02234
02235
02236
02237 ResultSign = DoubleOperand1->Sign ^ DoubleOperand2->Sign;
02238 ResultValueHigh = DOUBLE_INFINITY_VALUE_HIGH | (ResultSign << 31);
02239 ResultValueLow = DOUBLE_INFINITY_VALUE_LOW;
02240
02241
02242
02243
02244
02245
02246
02247
02248
if (DoubleOperand1->Infinity ==
FALSE) {
02249
02250 Fpcr = (PFPCR)&ContextBlock->TrapFrame->Fpcr;
02251 Fpcr->DivisionByZero = 1;
02252 Fpcr->SummaryBit = 1;
02253
if (ContextBlock->IeeeMode ==
FALSE) {
02254 ExceptionRecord = ContextBlock->ExceptionRecord;
02255 ExceptionRecord->ExceptionCode = STATUS_FLOAT_DIVIDE_BY_ZERO;
02256
return FALSE;
02257 }
02258 SoftwareFpcr = ContextBlock->SoftwareFpcr;
02259 SoftwareFpcr->StatusDivisionByZero = 1;
02260
if (SoftwareFpcr->EnableDivisionByZero != 0) {
02261 ExceptionRecord = ContextBlock->ExceptionRecord;
02262 ExceptionRecord->ExceptionCode = STATUS_FLOAT_DIVIDE_BY_ZERO;
02263 IeeeValue =
KiInitializeIeeeValue(ExceptionRecord);
02264 IeeeValue->Value.Fp64Value.W[0] = ResultValueLow;
02265 IeeeValue->Value.Fp64Value.W[1] = ResultValueHigh;
02266
return FALSE;
02267 }
02268
02269 Fpcr->DisableDivisionByZero = 1;
02270 }
02271
02272
KiSetRegisterValue(ContextBlock->Fc + 32,
02273
MAKE_QUAD(ResultValueLow, ResultValueHigh),
02274 ContextBlock->ExceptionFrame,
02275 ContextBlock->TrapFrame);
02276
02277
return TRUE;
02278 }
02279
02280 BOOLEAN
02281 KiDivideByZeroSingle (
02282 IN PFP_CONTEXT_BLOCK ContextBlock,
02283 IN PFP_SINGLE_OPERAND SingleOperand1,
02284 IN PFP_SINGLE_OPERAND SingleOperand2
02285 )
02286
02287
02288
02289
02290
02291
02292
02293
02294
02295
02296
02297
02298
02299
02300
02301
02302
02303
02304
02305
02306
02307
02308
02309
02310
02311
02312 {
02313
02314 PEXCEPTION_RECORD ExceptionRecord;
02315 PFPCR Fpcr;
02316 PFP_IEEE_VALUE IeeeValue;
02317 ULONG ResultSign;
02318 ULONG ResultValue;
02319 PSW_FPCR SoftwareFpcr;
02320
02321
02322
02323
02324
02325 ResultSign = SingleOperand1->Sign ^ SingleOperand2->Sign;
02326 ResultValue = SINGLE_INFINITY_VALUE | (ResultSign << 31);
02327
02328
02329
02330
02331
02332
02333
02334
02335
if (SingleOperand1->Infinity ==
FALSE) {
02336
02337 Fpcr = (PFPCR)&ContextBlock->TrapFrame->Fpcr;
02338 Fpcr->DivisionByZero = 1;
02339 Fpcr->SummaryBit = 1;
02340
if (ContextBlock->IeeeMode ==
FALSE) {
02341 ExceptionRecord = ContextBlock->ExceptionRecord;
02342 ExceptionRecord->ExceptionCode = STATUS_FLOAT_DIVIDE_BY_ZERO;
02343
return FALSE;
02344 }
02345 SoftwareFpcr = ContextBlock->SoftwareFpcr;
02346 SoftwareFpcr->StatusDivisionByZero = 1;
02347
if (SoftwareFpcr->EnableDivisionByZero != 0) {
02348 ExceptionRecord = ContextBlock->ExceptionRecord;
02349 ExceptionRecord->ExceptionCode = STATUS_FLOAT_DIVIDE_BY_ZERO;
02350 IeeeValue =
KiInitializeIeeeValue(ExceptionRecord);
02351 IeeeValue->Value.Fp32Value.W[0] = ResultValue;
02352
return FALSE;
02353 }
02354
02355 Fpcr->DisableDivisionByZero = 1;
02356 }
02357
02358
KiSetRegisterValue(ContextBlock->Fc + 32,
02359
KiConvertSingleOperandToRegister(ResultValue),
02360 ContextBlock->ExceptionFrame,
02361 ContextBlock->TrapFrame);
02362
02363
return TRUE;
02364 }
02365
02366 PFP_IEEE_VALUE
02367 KiInitializeIeeeValue (
02368 IN PEXCEPTION_RECORD ExceptionRecord
02369 )
02370
02371
02372
02373
02374
02375
02376
02377
02378
02379
02380
02381
02382
02383
02384
02385
02386
02387
02388
02389
02390
02391
02392 {
02393
02394
02395
02396
02397
02398
02399
02400 ExceptionRecord->NumberParameters = 6;
02401 ExceptionRecord->ExceptionInformation[0] = 0;
02402 ExceptionRecord->ExceptionInformation[1] =
02403 ((ULONG_PTR)(ExceptionRecord)->ExceptionAddress) + 4;
02404 ExceptionRecord->ExceptionInformation[2] = 0;
02405 ExceptionRecord->ExceptionInformation[3] = 0;
02406 ExceptionRecord->ExceptionInformation[4] = 0;
02407 ExceptionRecord->ExceptionInformation[5] = 0;
02408
02409
02410
02411
02412
02413
return (PFP_IEEE_VALUE)&ExceptionRecord->ExceptionInformation[2];
02414 }
02415
02416 BOOLEAN
02417 KiInvalidCompareDouble (
02418 IN PFP_CONTEXT_BLOCK ContextBlock,
02419 IN BOOLEAN CheckForSignalNan,
02420 IN PFP_DOUBLE_OPERAND DoubleOperand1,
02421 IN PFP_DOUBLE_OPERAND DoubleOperand2
02422 )
02423
02424
02425
02426
02427
02428
02429
02430
02431
02432
02433
02434
02435
02436
02437
02438
02439
02440
02441
02442
02443
02444
02445
02446
02447
02448
02449
02450
02451 {
02452
02453 PEXCEPTION_RECORD ExceptionRecord;
02454 PFPCR Fpcr;
02455 PFP_IEEE_VALUE IeeeValue;
02456 PSW_FPCR SoftwareFpcr;
02457
02458
02459
02460
02461
02462
02463
02464
02465
02466
if ((CheckForSignalNan ==
FALSE) ||
02467 (
DoubleSignalNan(DoubleOperand1) !=
FALSE) ||
02468 (
DoubleSignalNan(DoubleOperand2) !=
FALSE)) {
02469
02470 Fpcr = (PFPCR)&ContextBlock->TrapFrame->Fpcr;
02471 Fpcr->InvalidOperation = 1;
02472 Fpcr->SummaryBit = 1;
02473
if (ContextBlock->IeeeMode ==
FALSE) {
02474 ExceptionRecord = ContextBlock->ExceptionRecord;
02475 ExceptionRecord->ExceptionCode = STATUS_FLOAT_INVALID_OPERATION;
02476
return FALSE;
02477 }
02478 SoftwareFpcr = ContextBlock->SoftwareFpcr;
02479 SoftwareFpcr->StatusInvalid = 1;
02480
if (SoftwareFpcr->EnableInvalid != 0) {
02481 ExceptionRecord = ContextBlock->ExceptionRecord;
02482 ExceptionRecord->ExceptionCode = STATUS_FLOAT_INVALID_OPERATION;
02483 IeeeValue =
KiInitializeIeeeValue(ExceptionRecord);
02484 IeeeValue->Value.CompareValue = FpCompareUnordered;
02485
return FALSE;
02486 }
02487
02488 Fpcr->DisableInvalid = 1;
02489 }
02490
02491
return TRUE;
02492 }
02493
02494 BOOLEAN
02495 KiInvalidOperationDouble (
02496 IN PFP_CONTEXT_BLOCK ContextBlock,
02497 IN BOOLEAN CheckForSignalNan,
02498 IN PFP_DOUBLE_OPERAND DoubleOperand1,
02499 IN PFP_DOUBLE_OPERAND DoubleOperand2
02500 )
02501
02502
02503
02504
02505
02506
02507
02508
02509
02510
02511
02512
02513
02514
02515
02516
02517
02518
02519
02520
02521
02522
02523
02524
02525
02526
02527
02528
02529 {
02530
02531 PEXCEPTION_RECORD ExceptionRecord;
02532 PFPCR Fpcr;
02533 PFP_IEEE_VALUE IeeeValue;
02534 ULONG ResultValueHigh;
02535 ULONG ResultValueLow;
02536 PSW_FPCR SoftwareFpcr;
02537
02538
02539
02540
02541
02542
02543
02544
02545
DBGPRINT(
"Operand1: Inf=%d NaN=%d Sign=%d Exponent=%d Mantissa=%.8x%.8x\n",
02546 DoubleOperand1->Infinity, DoubleOperand1->Nan,
02547 DoubleOperand1->Sign,
02548 DoubleOperand1->Exponent,
02549 DoubleOperand1->MantissaHigh, DoubleOperand1->MantissaLow);
02550
DBGPRINT(
"Operand2: Inf=%d NaN=%d Sign=%d Exponent=%d Mantissa=%.8x%.8x\n",
02551 DoubleOperand2->Infinity, DoubleOperand2->Nan,
02552 DoubleOperand2->Sign,
02553 DoubleOperand2->Exponent,
02554 DoubleOperand2->MantissaHigh, DoubleOperand2->MantissaLow);
02555
02556
if (DoubleOperand2->Nan !=
FALSE) {
02557 ResultValueLow = DoubleOperand2->MantissaLow >> 2;
02558 ResultValueLow |= DoubleOperand2->MantissaHigh << 30;
02559 ResultValueHigh = DoubleOperand2->MantissaHigh >> 2;
02560 ResultValueHigh |= DOUBLE_QUIET_NAN_PREFIX_HIGH;
02561 ResultValueHigh |= DoubleOperand2->Sign << 31;
02562
02563 }
else if (DoubleOperand1->Nan !=
FALSE) {
02564 ResultValueLow = DoubleOperand1->MantissaLow >> 2;
02565 ResultValueLow |= DoubleOperand1->MantissaHigh << 30;
02566 ResultValueHigh = DoubleOperand1->MantissaHigh >> 2;
02567 ResultValueHigh |= DOUBLE_QUIET_NAN_PREFIX_HIGH;
02568 ResultValueHigh |= DoubleOperand1->Sign << 31;
02569
02570 }
else {
02571 ResultValueLow = DOUBLE_QUIET_NAN_VALUE_LOW;
02572 ResultValueHigh = DOUBLE_QUIET_NAN_VALUE_HIGH;
02573 }
02574
02575
02576
02577
02578
02579
02580
02581
02582
02583
if ((CheckForSignalNan ==
FALSE) ||
02584 (
DoubleSignalNan(DoubleOperand1) !=
FALSE) ||
02585 (
DoubleSignalNan(DoubleOperand2) !=
FALSE)) {
02586
02587 Fpcr = (PFPCR)&ContextBlock->TrapFrame->Fpcr;
02588 Fpcr->InvalidOperation = 1;
02589 Fpcr->SummaryBit = 1;
02590
if (ContextBlock->IeeeMode ==
FALSE) {
02591 ExceptionRecord = ContextBlock->ExceptionRecord;
02592 ExceptionRecord->ExceptionCode = STATUS_FLOAT_INVALID_OPERATION;
02593
return FALSE;
02594 }
02595 SoftwareFpcr = ContextBlock->SoftwareFpcr;
02596 SoftwareFpcr->StatusInvalid = 1;
02597
if (SoftwareFpcr->EnableInvalid != 0) {
02598 ExceptionRecord = ContextBlock->ExceptionRecord;
02599 ExceptionRecord->ExceptionCode = STATUS_FLOAT_INVALID_OPERATION;
02600 IeeeValue =
KiInitializeIeeeValue(ExceptionRecord);
02601 IeeeValue->Value.Fp64Value.W[0] = ResultValueLow;
02602 IeeeValue->Value.Fp64Value.W[1] = ResultValueHigh;
02603
return FALSE;
02604 }
02605
02606 Fpcr->DisableInvalid = 1;
02607 }
02608
02609
KiSetRegisterValue(ContextBlock->Fc + 32,
02610
MAKE_QUAD(ResultValueLow, ResultValueHigh),
02611 ContextBlock->ExceptionFrame,
02612 ContextBlock->TrapFrame);
02613
02614
return TRUE;
02615 }
02616
02617 BOOLEAN
02618 KiInvalidOperationQuadword (
02619 IN PFP_CONTEXT_BLOCK ContextBlock,
02620 IN ULONGLONG ResultValue
02621 )
02622
02623
02624
02625
02626
02627
02628
02629
02630
02631
02632
02633
02634
02635
02636
02637
02638
02639
02640
02641
02642
02643
02644 {
02645
02646 PEXCEPTION_RECORD ExceptionRecord;
02647 PFPCR Fpcr;
02648 PFP_IEEE_VALUE IeeeValue;
02649 PSW_FPCR SoftwareFpcr;
02650
02651
02652
02653
02654
02655
02656
02657
02658 Fpcr = (PFPCR)&ContextBlock->TrapFrame->Fpcr;
02659 Fpcr->InvalidOperation = 1;
02660 Fpcr->SummaryBit = 1;
02661
if (ContextBlock->IeeeMode ==
FALSE) {
02662 ExceptionRecord = ContextBlock->ExceptionRecord;
02663 ExceptionRecord->ExceptionCode = STATUS_FLOAT_INVALID_OPERATION;
02664
return FALSE;
02665 }
02666 SoftwareFpcr = ContextBlock->SoftwareFpcr;
02667 SoftwareFpcr->StatusInvalid = 1;
02668
if (SoftwareFpcr->EnableInvalid != 0) {
02669 ExceptionRecord = ContextBlock->ExceptionRecord;
02670 ExceptionRecord->ExceptionCode = STATUS_FLOAT_INVALID_OPERATION;
02671 IeeeValue =
KiInitializeIeeeValue(ExceptionRecord);
02672 IeeeValue->Value.U64Value.LowPart =
LOW_PART(ResultValue);
02673 IeeeValue->Value.U64Value.HighPart =
HIGH_PART(ResultValue);
02674
return FALSE;
02675 }
02676
02677 Fpcr->DisableInvalid = 1;
02678
02679
KiSetRegisterValue(ContextBlock->Fc + 32,
02680 ResultValue,
02681 ContextBlock->ExceptionFrame,
02682 ContextBlock->TrapFrame);
02683
02684
return TRUE;
02685 }
02686
02687 BOOLEAN
02688 KiInvalidOperationSingle (
02689 IN PFP_CONTEXT_BLOCK ContextBlock,
02690 IN BOOLEAN CheckForSignalNan,
02691 IN PFP_SINGLE_OPERAND SingleOperand1,
02692 IN PFP_SINGLE_OPERAND SingleOperand2
02693 )
02694
02695
02696
02697
02698
02699
02700
02701
02702
02703
02704
02705
02706
02707
02708
02709
02710
02711
02712
02713
02714
02715
02716
02717
02718
02719
02720
02721
02722 {
02723
02724 PEXCEPTION_RECORD ExceptionRecord;
02725 PFPCR Fpcr;
02726 PFP_IEEE_VALUE IeeeValue;
02727 ULONG ResultValue;
02728 PSW_FPCR SoftwareFpcr;
02729
02730
02731
02732
02733
02734
02735
02736
02737
if (SingleOperand2->Nan !=
FALSE) {
02738 ResultValue = SingleOperand2->Mantissa >> 2;
02739 ResultValue |=
SINGLE_QUIET_NAN_PREFIX;
02740 ResultValue |= SingleOperand2->Sign << 31;
02741
02742 }
else if (SingleOperand1->Nan !=
FALSE) {
02743 ResultValue = SingleOperand1->Mantissa >> 2;
02744 ResultValue |=
SINGLE_QUIET_NAN_PREFIX;
02745 ResultValue |= SingleOperand1->Sign << 31;
02746
02747 }
else {
02748 ResultValue = SINGLE_QUIET_NAN_VALUE;
02749 }
02750
02751
02752
02753
02754
02755
02756
02757
02758
02759
if ((CheckForSignalNan ==
FALSE) ||
02760 (
SingleSignalNan(SingleOperand1) !=
FALSE) ||
02761 (
SingleSignalNan(SingleOperand2) !=
FALSE)) {
02762
02763 Fpcr = (PFPCR)&ContextBlock->TrapFrame->Fpcr;
02764 Fpcr->InvalidOperation = 1;
02765 Fpcr->SummaryBit = 1;
02766
if (ContextBlock->IeeeMode ==
FALSE) {
02767 ExceptionRecord = ContextBlock->ExceptionRecord;
02768 ExceptionRecord->ExceptionCode = STATUS_FLOAT_INVALID_OPERATION;
02769
return FALSE;
02770 }
02771 SoftwareFpcr = ContextBlock->SoftwareFpcr;
02772 SoftwareFpcr->StatusInvalid = 1;
02773
if (SoftwareFpcr->EnableInvalid != 0) {
02774 ExceptionRecord = ContextBlock->ExceptionRecord;
02775 ExceptionRecord->ExceptionCode = STATUS_FLOAT_INVALID_OPERATION;
02776 IeeeValue =
KiInitializeIeeeValue(ExceptionRecord);
02777 IeeeValue->Value.Fp32Value.W[0] = ResultValue;
02778
return FALSE;
02779 }
02780
02781 Fpcr->DisableInvalid = 1;
02782 }
02783
02784
KiSetRegisterValue(ContextBlock->Fc + 32,
02785
KiConvertSingleOperandToRegister(ResultValue),
02786 ContextBlock->ExceptionFrame,
02787 ContextBlock->TrapFrame);
02788
02789
return TRUE;
02790 }
02791
02792 BOOLEAN
02793 KiNormalizeDouble (
02794 IN PFP_CONTEXT_BLOCK ContextBlock,
02795 IN PFP_DOUBLE_OPERAND ResultOperand,
02796 IN ULONGLONG StickyBits
02797 )
02798
02799
02800
02801
02802
02803
02804
02805
02806
02807
02808
02809
02810
02811
02812
02813
02814
02815
02816
02817
02818
02819
02820
02821
02822
02823
02824
02825
02826
02827
02828
02829
02830
02831
02832
02833
02834
02835 {
02836
02837 ULONGLONG DenormalizeShift;
02838 PEXCEPTION_RECORD ExceptionRecord;
02839 ULONGLONG ExceptionResult;
02840 PFPCR Fpcr;
02841 PFP_IEEE_VALUE IeeeValue;
02842 BOOLEAN Inexact;
02843 ULONGLONG Mantissa;
02844 BOOLEAN Overflow;
02845 ULONGLONG ResultValue;
02846 ULONG RoundBit;
02847 PSW_FPCR SoftwareFpcr;
02848 BOOLEAN Underflow;
02849 ULONGLONG ResultStickyBits;
02850 ULONGLONG ResultMantissa;
02851 ULONG ResultRoundBit;
02852 LONG ResultExponent;
02853 BOOLEAN ReturnValue =
TRUE;
02854
02855
02856
02857
02858
02859
02860
02861
DBGPRINT(
"KiNormalizeDouble: Inf=%d NaN=%d Sign=%d Exponent=%d Mantissa=%.8x%.8x\n",
02862 ResultOperand->Infinity, ResultOperand->Nan, ResultOperand->Sign,
02863 ResultOperand->Exponent,
02864 ResultOperand->MantissaHigh, ResultOperand->MantissaLow);
02865
DBGPRINT(
"KiNormalizeDouble: StickyBits=%.16Lx\n", StickyBits);
02866
02867
if (ResultOperand->Infinity !=
FALSE) {
02868
KiSetRegisterValue(ContextBlock->Fc + 32,
02869
MAKE_QUAD(DOUBLE_INFINITY_VALUE_LOW,
02870 DOUBLE_INFINITY_VALUE_HIGH |
02871 (ResultOperand->Sign << 31)),
02872 ContextBlock->ExceptionFrame,
02873 ContextBlock->TrapFrame);
02874
02875
return TRUE;
02876 }
02877
02878 Mantissa =
MAKE_QUAD(ResultOperand->MantissaLow,
02879 ResultOperand->MantissaHigh);
02880 Fpcr = (PFPCR)&ContextBlock->TrapFrame->Fpcr;
02881 SoftwareFpcr = ContextBlock->SoftwareFpcr;
02882
02883
02884
02885
02886
02887
02888
02889
if ((Mantissa & ((ULONGLONG)1 << 55)) != 0) {
02890 StickyBits |= (Mantissa & 0x1);
02891 Mantissa >>= 1;
02892 ResultOperand->Exponent += 1;
02893 }
02894
02895
02896
02897
02898
02899
02900
if (Mantissa != 0) {
02901
while ((Mantissa & ((ULONGLONG)1 << 54)) == 0) {
02902 Mantissa <<= 1;
02903 ResultOperand->Exponent -= 1;
02904 }
02905 }
02906
02907
02908
02909
02910
02911
02912 StickyBits |= (Mantissa & 0x1);
02913 RoundBit = (ULONG)(Mantissa & 0x2);
02914 Mantissa >>= 2;
02915
02916
02917
02918
02919
02920
02921
02922
if (ResultOperand->Exponent <= DOUBLE_MINIMUM_EXPONENT && Mantissa != 0) {
02923
02924
02925
02926
02927
02928 ResultMantissa = Mantissa;
02929 ResultExponent = ResultOperand->Exponent;
02930 ResultStickyBits = StickyBits;
02931 ResultRoundBit = RoundBit;
02932
02933
02934
02935
02936
02937
02938 DenormalizeShift = 1 - ResultOperand->Exponent;
02939
02940
02941
02942
02943
02944
02945
if (DenormalizeShift > 54) {
02946 DenormalizeShift = 54;
02947 }
02948
02949
02950
02951
02952
02953
02954 StickyBits |= RoundBit;
02955 StickyBits |= (Mantissa << 1) << (64 - DenormalizeShift);
02956 RoundBit = (ULONG)(Mantissa >> (DenormalizeShift - 1)) & 1;
02957 Mantissa = Mantissa >> DenormalizeShift;
02958 ResultOperand->Exponent = DOUBLE_MINIMUM_EXPONENT;
02959 }
02960
02961
02962
02963
02964
02965
switch (ContextBlock->Round) {
02966
02967
02968
02969
02970
02971
case ROUND_TO_NEAREST:
02972
if (RoundBit != 0) {
02973
if ((StickyBits != 0) || ((Mantissa & 0x1) != 0)) {
02974 Mantissa += 1;
02975 }
02976 }
02977
break;
02978
02979
02980
02981
02982
02983
case ROUND_TO_ZERO:
02984
break;
02985
02986
02987
02988
02989
02990
case ROUND_TO_PLUS_INFINITY:
02991
if ((ResultOperand->Sign == 0) &&
02992 ((StickyBits != 0) || (RoundBit != 0))) {
02993 Mantissa += 1;
02994 }
02995
break;
02996
02997
02998
02999
03000
03001
case ROUND_TO_MINUS_INFINITY:
03002
if ((ResultOperand->Sign != 0) &&
03003 ((StickyBits != 0) || (RoundBit != 0))) {
03004 Mantissa += 1;
03005 }
03006
break;
03007 }
03008
03009
03010
03011
03012
03013
03014
if ((Mantissa & ((ULONGLONG)1 << 53)) != 0) {
03015 Mantissa >>= 1;
03016 ResultOperand->Exponent += 1;
03017 }
03018
03019
03020
03021
03022
03023
03024
if ((ResultOperand->Exponent == DOUBLE_MINIMUM_EXPONENT) &&
03025 (Mantissa & ((ULONGLONG)1 << 52)) != 0) {
03026 ResultOperand->Exponent += 1;
03027 }
03028
03029
03030
03031
03032
03033
03034
03035
03036
03037
03038
03039
03040
03041
03042
03043
03044
03045
03046
03047
03048
03049
if (ResultOperand->Exponent >= DOUBLE_MAXIMUM_EXPONENT) {
03050 Inexact =
TRUE;
03051 Overflow =
TRUE;
03052 Underflow =
FALSE;
03053
03054
03055
03056
03057
03058
switch (ContextBlock->Round) {
03059
03060
03061
03062
03063
03064
03065
03066
case ROUND_TO_NEAREST:
03067 ResultValue =
MAKE_QUAD(DOUBLE_INFINITY_VALUE_LOW,
03068 DOUBLE_INFINITY_VALUE_HIGH |
03069 (ResultOperand->Sign << 31));
03070
break;
03071
03072
03073
03074
03075
03076
03077
03078
case ROUND_TO_ZERO:
03079 ResultValue =
MAKE_QUAD(DOUBLE_MAXIMUM_VALUE_LOW,
03080 DOUBLE_MAXIMUM_VALUE_HIGH |
03081 (ResultOperand->Sign << 31));
03082
break;
03083
03084
03085
03086
03087
03088
03089
03090
03091
03092
case ROUND_TO_PLUS_INFINITY:
03093
if (ResultOperand->Sign == 0) {
03094 ResultValue =
MAKE_QUAD(DOUBLE_INFINITY_VALUE_LOW,
03095 DOUBLE_INFINITY_VALUE_HIGH);
03096
03097 }
else {
03098 ResultValue =
MAKE_QUAD(DOUBLE_MAXIMUM_VALUE_LOW,
03099 DOUBLE_MAXIMUM_VALUE_HIGH |
03100 (1 << 31));
03101 }
03102
break;
03103
03104
03105
03106
03107
03108
03109
03110
03111
03112
03113
case ROUND_TO_MINUS_INFINITY:
03114
if (ResultOperand->Sign != 0) {
03115 ResultValue =
MAKE_QUAD(DOUBLE_INFINITY_VALUE_LOW,
03116 DOUBLE_INFINITY_VALUE_HIGH |
03117 (1 << 31));
03118
03119 }
else {
03120 ResultValue =
MAKE_QUAD(DOUBLE_MAXIMUM_VALUE_LOW,
03121 DOUBLE_MAXIMUM_VALUE_HIGH);
03122 }
03123
break;
03124 }
03125
03126
03127
03128
03129
03130
03131 ExceptionResult = Mantissa & (((ULONGLONG)1 << 52) - 1);
03132 ExceptionResult |= (((ULONGLONG)ResultOperand->Exponent - 1536) << 52);
03133 ExceptionResult |= ((ULONGLONG)ResultOperand->Sign << 63);
03134
03135 }
else {
03136
03137
03138
03139
03140
03141
03142
03143
if ((ResultOperand->Exponent == DOUBLE_MINIMUM_EXPONENT) &&
03144 (Mantissa != 0 || RoundBit != 00 || StickyBits != 0)) {
03145
03146
03147
03148
03149
03150
03151
03152
if ((ContextBlock->IeeeMode ==
FALSE) ||
03153 (SoftwareFpcr->DenormalResultEnable == 0)) {
03154
DBGPRINT(
"SoftwareFpcr->DenormalResultEnable == 0\n");
03155 ResultValue = 0;
03156 Inexact =
FALSE;
03157 Overflow =
FALSE;
03158 Underflow =
FALSE;
03159
03160 }
else {
03161
03162 ResultValue = Mantissa;
03163 ResultValue |= (ULONGLONG)ResultOperand->Sign << 63;
03164
03165
03166
03167
03168
03169
03170
03171
03172
03173
03174
03175
switch (ContextBlock->Round) {
03176
03177
03178
03179
03180
03181
case ROUND_TO_NEAREST:
03182
if (ResultRoundBit != 0) {
03183
if ((ResultStickyBits != 0) || ((ResultMantissa & 0x1) != 0)) {
03184 ResultMantissa += 1;
03185 }
03186 }
03187
break;
03188
03189
03190
03191
03192
03193
case ROUND_TO_ZERO:
03194
break;
03195
03196
03197
03198
03199
03200
case ROUND_TO_PLUS_INFINITY:
03201
if ((ResultOperand->Sign == 0) &&
03202 ((ResultStickyBits != 0) || (ResultRoundBit != 0))) {
03203 ResultMantissa += 1;
03204 }
03205
break;
03206
03207
03208
03209
03210
03211
case ROUND_TO_MINUS_INFINITY:
03212
if ((ResultOperand->Sign != 0) &&
03213 ((ResultStickyBits != 0) || (ResultRoundBit != 0))) {
03214 ResultMantissa += 1;
03215 }
03216
break;
03217 }
03218
03219
03220
03221
03222
03223
03224
if ((ResultMantissa & ((ULONGLONG)1 << 53)) != 0) {
03225 ResultMantissa >>= 1;
03226 ResultExponent += 1;
03227 }
03228
03229
03230
03231
03232
03233 ExceptionResult = ResultMantissa & (((ULONGLONG)1 << 52) - 1);
03234 ExceptionResult |= (((ULONGLONG)ResultExponent + 1536) << 52);
03235 ExceptionResult |= ((ULONGLONG)ResultOperand->Sign << 63);
03236
03237
03238
03239
03240
03241
03242
03243 Overflow =
FALSE;
03244 Underflow =
TRUE;
03245
if ((StickyBits != 0) || (RoundBit != 0)) {
03246 Inexact =
TRUE;
03247
03248 }
else {
03249 Inexact =
FALSE;
03250 }
03251 }
03252
03253 }
else {
03254
03255
03256
03257
03258
03259
if (Mantissa == 0) {
03260 ResultOperand->Exponent = 0;
03261 }
03262
03263 ResultValue = Mantissa & (((ULONGLONG)1 << 52) - 1);
03264 ResultValue |= (ULONGLONG)ResultOperand->Exponent << 52;
03265 ResultValue |= (ULONGLONG)ResultOperand->Sign << 63;
03266
if ((StickyBits != 0) || (RoundBit != 0)) {
03267 Inexact =
TRUE;
03268
03269 }
else {
03270 Inexact =
FALSE;
03271 }
03272 Overflow =
FALSE;
03273 Underflow =
FALSE;
03274 }
03275 }
03276
03277
03278
03279
03280
03281 ExceptionRecord = ContextBlock->ExceptionRecord;
03282
03283
if (Overflow !=
FALSE) {
03284 Fpcr->Overflow = 1;
03285 Fpcr->InexactResult = 1;
03286 Fpcr->SummaryBit = 1;
03287
if (ContextBlock->IeeeMode ==
FALSE) {
03288 ExceptionRecord->ExceptionCode = STATUS_FLOAT_OVERFLOW;
03289
return FALSE;
03290 }
03291 IeeeValue =
KiInitializeIeeeValue(ExceptionRecord);
03292 SoftwareFpcr->StatusOverflow = 1;
03293 SoftwareFpcr->StatusInexact = 1;
03294
if (SoftwareFpcr->EnableOverflow != 0) {
03295 ExceptionRecord->ExceptionCode = STATUS_FLOAT_OVERFLOW;
03296 IeeeValue->Value.Fp64Value.W[0] =
LOW_PART(ExceptionResult);
03297 IeeeValue->Value.Fp64Value.W[1] =
HIGH_PART(ExceptionResult);
03298 ReturnValue =
FALSE;
03299 }
else if (SoftwareFpcr->EnableInexact != 0) {
03300 ExceptionRecord->ExceptionCode = STATUS_FLOAT_INEXACT_RESULT;
03301 IeeeValue->Value.Fp64Value.W[0] =
LOW_PART(ExceptionResult);
03302 IeeeValue->Value.Fp64Value.W[1] =
HIGH_PART(ExceptionResult);
03303 ReturnValue =
FALSE;
03304 }
else {
03305 Fpcr->DisableOverflow = 1;
03306 Fpcr->DisableInexact = 1;
03307 }
03308
03309 }
else if (Underflow !=
FALSE) {
03310
03311
03312
03313
03314
03315
if (ContextBlock->IeeeMode ==
FALSE) {
03316 Fpcr->Underflow = 1;
03317 Fpcr->SummaryBit = 1;
03318 Fpcr->InexactResult = 1;
03319
if (ContextBlock->UnderflowEnable !=
FALSE) {
03320 ExceptionRecord->ExceptionCode = STATUS_FLOAT_UNDERFLOW;
03321
return FALSE;
03322 }
03323
03324
03325
03326
03327
03328
03329 }
else {
03330 IeeeValue =
KiInitializeIeeeValue(ExceptionRecord);
03331
if (Inexact !=
FALSE) {
03332 Fpcr->Underflow = 1;
03333 Fpcr->SummaryBit = 1;
03334 Fpcr->InexactResult = 1;
03335 SoftwareFpcr->StatusUnderflow = 1;
03336 SoftwareFpcr->StatusInexact = 1;
03337 }
03338
if (SoftwareFpcr->EnableUnderflow != 0) {
03339 Fpcr->Underflow = 1;
03340 Fpcr->SummaryBit = 1;
03341 SoftwareFpcr->StatusUnderflow = 1;
03342 ExceptionRecord->ExceptionCode = STATUS_FLOAT_UNDERFLOW;
03343 IeeeValue->Value.Fp64Value.W[0] =
LOW_PART(ExceptionResult);
03344 IeeeValue->Value.Fp64Value.W[1] =
HIGH_PART(ExceptionResult);
03345 ReturnValue =
FALSE;
03346 }
else if (Inexact !=
FALSE && SoftwareFpcr->EnableInexact != 0) {
03347 ExceptionRecord->ExceptionCode = STATUS_FLOAT_INEXACT_RESULT;
03348 IeeeValue->Value.Fp64Value.W[0] =
LOW_PART(ExceptionResult);
03349 IeeeValue->Value.Fp64Value.W[1] =
HIGH_PART(ExceptionResult);
03350 ReturnValue =
FALSE;
03351 }
else if (Inexact !=
FALSE) {
03352 Fpcr->DisableUnderflow = 1;
03353 Fpcr->DisableInexact = 1;
03354 }
03355 }
03356
03357 }
else if (Inexact !=
FALSE) {
03358 Fpcr->InexactResult = 1;
03359 Fpcr->SummaryBit = 1;
03360
if (ContextBlock->IeeeMode !=
FALSE) {
03361 IeeeValue =
KiInitializeIeeeValue(ExceptionRecord);
03362 SoftwareFpcr->StatusInexact = 1;
03363
if (SoftwareFpcr->EnableInexact != 0) {
03364 ExceptionRecord->ExceptionCode = STATUS_FLOAT_INEXACT_RESULT;
03365 IeeeValue->Value.Fp64Value.W[0] =
LOW_PART(ResultValue);
03366 IeeeValue->Value.Fp64Value.W[1] =
HIGH_PART(ResultValue);
03367 ReturnValue =
FALSE;
03368 }
else {
03369 Fpcr->DisableInexact = 1;
03370 }
03371 }
03372 }
03373
03374
03375
03376
03377
03378
03379
KiSetRegisterValue(ContextBlock->Fc + 32,
03380 ResultValue,
03381 ContextBlock->ExceptionFrame,
03382 ContextBlock->TrapFrame);
03383
03384
03385
03386
03387
03388
return ReturnValue;
03389 }
03390
03391 BOOLEAN
03392 KiNormalizeQuadword (
03393 IN PFP_CONTEXT_BLOCK ContextBlock,
03394 IN PFP_DOUBLE_OPERAND ResultOperand
03395 )
03396
03397
03398
03399
03400
03401
03402
03403
03404
03405
03406
03407
03408
03409
03410
03411
03412
03413
03414
03415
03416
03417
03418
03419
03420
03421
03422
03423
03424
03425
03426
03427
03428
03429
03430
03431 {
03432
03433 PEXCEPTION_RECORD ExceptionRecord;
03434 LONGLONG ExponentShift;
03435 PFPCR Fpcr;
03436 PFP_IEEE_VALUE IeeeValue;
03437 ULONGLONG Mantissa;
03438 BOOLEAN Overflow;
03439 ULONGLONG ResultValue;
03440 ULONG RoundBit;
03441 ULONGLONG StickyBits;
03442 PSW_FPCR SoftwareFpcr;
03443
03444
03445
03446
03447
03448
03449 ExponentShift = ResultOperand->Exponent - DOUBLE_EXPONENT_BIAS;
03450
DBGPRINT(
"KiNormalizeQuadword: Inf=%d NaN=%d Sign=%d Exponent=%d Mantissa=%.8x%.8x\n",
03451 ResultOperand->Infinity, ResultOperand->Nan, ResultOperand->Sign,
03452 ResultOperand->Exponent,
03453 ResultOperand->MantissaHigh, ResultOperand->MantissaLow);
03454
DBGPRINT(
".. ExponentShift = %d\n", ExponentShift);
03455 Mantissa =
MAKE_QUAD(ResultOperand->MantissaLow,
03456 ResultOperand->MantissaHigh);
03457
03458
if (ExponentShift < 54) {
03459
03460
03461
03462
03463
03464
03465 ExponentShift = 54 - ExponentShift;
03466
if (ExponentShift < 64) {
03467 StickyBits = Mantissa << (64 - ExponentShift);
03468 ResultValue = Mantissa >> ExponentShift;
03469
03470 }
else {
03471 StickyBits = Mantissa;
03472 ResultValue = 0;
03473 }
03474 Overflow =
FALSE;
03475
03476 }
else if (ExponentShift > 54) {
03477 ExponentShift -= 54;
03478
03479
03480
03481
03482
03483
03484
03485
03486
if (ExponentShift < (64 - 54)) {
03487 StickyBits = Mantissa >> (64 - ExponentShift);
03488 ResultValue = Mantissa << ExponentShift;
03489 Overflow =
FALSE;
03490
03491 }
else {
03492 StickyBits = 0;
03493
if (ExponentShift < 64) {
03494 ResultValue = Mantissa << ExponentShift;
03495
03496 }
else {
03497 ResultValue = 0;
03498 }
03499 Overflow =
TRUE;
03500 }
03501
03502 }
else {
03503 StickyBits = 0;
03504 ResultValue = Mantissa;
03505 Overflow =
FALSE;
03506 }
03507
DBGPRINT(
".. ResultValue = %.16Lx, StickyBits = %.16Lx\n",
03508 ResultValue, StickyBits);
03509
03510
03511
03512
03513
03514
03515 RoundBit = (ULONG)(StickyBits >> 63);
03516 StickyBits <<= 1;
03517
DBGPRINT(
".. ResultValue = %.16Lx, StickyBits = %.16Lx, RoundBit = %lx\n",
03518 ResultValue, StickyBits, RoundBit);
03519
switch (ContextBlock->Round) {
03520
03521
03522
03523
03524
03525
case ROUND_TO_NEAREST:
03526
if (RoundBit != 0) {
03527
if ((StickyBits != 0) || ((ResultValue & 0x1) != 0)) {
03528 ResultValue += 1;
03529
if (ResultValue == 0) {
03530 Overflow =
TRUE;
03531 }
03532 }
03533 }
03534
break;
03535
03536
03537
03538
03539
03540
case ROUND_TO_ZERO:
03541
break;
03542
03543
03544
03545
03546
03547
case ROUND_TO_PLUS_INFINITY:
03548
if ((ResultOperand->Sign == 0) &&
03549 ((StickyBits != 0) || (RoundBit != 0))) {
03550 ResultValue += 1;
03551
if (ResultValue == 0) {
03552 Overflow =
TRUE;
03553 }
03554 }
03555
break;
03556
03557
03558
03559
03560
03561
case ROUND_TO_MINUS_INFINITY:
03562
if ((ResultOperand->Sign != 0) &&
03563 ((StickyBits != 0) || (RoundBit != 0))) {
03564 ResultValue += 1;
03565
if (ResultValue == 0) {
03566 Overflow =
TRUE;
03567 }
03568 }
03569
break;
03570 }
03571
03572
03573
03574
03575
03576
03577
03578
03579
if (ResultOperand->Sign == 0) {
03580
if ((LONGLONG)ResultValue < 0) {
03581 Overflow =
TRUE;
03582 }
03583
03584 }
else {
03585 ResultValue = -(LONGLONG)ResultValue;
03586
if ((LONGLONG)ResultValue > 0) {
03587 Overflow =
TRUE;
03588 }
03589 }
03590
DBGPRINT(
".. ResultValue = %.16Lx, StickyBits = %.16Lx\n",
03591 ResultValue, StickyBits);
03592
03593
03594
03595
03596
03597
03598
if (Overflow !=
FALSE) {
03599
return KiInvalidOperationQuadword(ContextBlock, ResultValue);
03600
03601 }
else if ((StickyBits | RoundBit) != 0) {
03602 Fpcr = (PFPCR)&ContextBlock->TrapFrame->Fpcr;
03603 Fpcr->InexactResult = 1;
03604 Fpcr->SummaryBit = 1;
03605
if (ContextBlock->IeeeMode !=
FALSE) {
03606 SoftwareFpcr = ContextBlock->SoftwareFpcr;
03607 SoftwareFpcr->StatusInexact = 1;
03608
if (SoftwareFpcr->EnableInexact != 0) {
03609 ExceptionRecord = ContextBlock->ExceptionRecord;
03610 ExceptionRecord->ExceptionCode = STATUS_FLOAT_INEXACT_RESULT;
03611 IeeeValue =
KiInitializeIeeeValue(ExceptionRecord);
03612 IeeeValue->Value.U64Value.LowPart =
LOW_PART(ResultValue);
03613 IeeeValue->Value.U64Value.HighPart =
HIGH_PART(ResultValue);
03614
return FALSE;
03615 }
03616
03617 Fpcr->DisableInexact = 1;
03618 }
03619 }
03620
03621
03622
03623
03624
03625
KiSetRegisterValue(ContextBlock->Fc + 32,
03626 ResultValue,
03627 ContextBlock->ExceptionFrame,
03628 ContextBlock->TrapFrame);
03629
03630
return TRUE;
03631 }
03632
03633 BOOLEAN
03634 KiNormalizeSingle (
03635 IN PFP_CONTEXT_BLOCK ContextBlock,
03636 IN PFP_SINGLE_OPERAND ResultOperand,
03637 IN ULONG StickyBits
03638 )
03639
03640
03641
03642
03643
03644
03645
03646
03647
03648
03649
03650
03651
03652
03653
03654
03655
03656
03657
03658
03659
03660
03661
03662
03663
03664
03665
03666
03667
03668
03669
03670
03671
03672
03673
03674
03675
03676 {
03677
03678 ULONG DenormalizeShift;
03679 PEXCEPTION_RECORD ExceptionRecord;
03680 ULONG ExceptionResult;
03681 PFPCR Fpcr;
03682 PFP_IEEE_VALUE IeeeValue;
03683 BOOLEAN Inexact;
03684 ULONG Mantissa;
03685 BOOLEAN Overflow;
03686 ULONG ResultValue;
03687 ULONG RoundBit;
03688 PSW_FPCR SoftwareFpcr;
03689 BOOLEAN Underflow;
03690 ULONG ResultStickyBits;
03691 ULONG ResultMantissa;
03692 ULONG ResultRoundBit;
03693 LONG ResultExponent;
03694 BOOLEAN ReturnValue =
TRUE;
03695
03696
03697
03698
03699
03700
03701
03702
DBGPRINT(
"KiNormalizeSingle: Inf=%d NaN=%d Sign=%d Exponent=%d Mantissa=%.8x\n",
03703 ResultOperand->Infinity, ResultOperand->Nan, ResultOperand->Sign,
03704 ResultOperand->Exponent, ResultOperand->Mantissa);
03705
DBGPRINT(
"KiNormalizeSingle: StickyBits=%.8lx\n", StickyBits);
03706
03707
if (ResultOperand->Infinity !=
FALSE) {
03708 ResultValue = SINGLE_INFINITY_VALUE | (ResultOperand->Sign << 31);
03709
KiSetRegisterValue(ContextBlock->Fc + 32,
03710
KiConvertSingleOperandToRegister(ResultValue),
03711 ContextBlock->ExceptionFrame,
03712 ContextBlock->TrapFrame);
03713
03714
return TRUE;
03715 }
03716
03717 Mantissa = ResultOperand->Mantissa;
03718 Fpcr = (PFPCR)&ContextBlock->TrapFrame->Fpcr;
03719 SoftwareFpcr = ContextBlock->SoftwareFpcr;
03720
03721
03722
03723
03724
03725
03726
03727
if ((Mantissa & (1 << 26)) != 0) {
03728 StickyBits |= (Mantissa & 0x1);
03729 Mantissa >>= 1;
03730 ResultOperand->Exponent += 1;
03731 }
03732
03733
03734
03735
03736
03737
03738
if (Mantissa != 0) {
03739
while ((Mantissa & (1 << 25)) == 0) {
03740 Mantissa <<= 1;
03741 ResultOperand->Exponent -= 1;
03742 }
03743 }
03744
03745
03746
03747
03748
03749
03750 StickyBits |= (Mantissa & 0x1);
03751 RoundBit = (Mantissa & 0x2);
03752 Mantissa >>= 2;
03753
03754
03755
03756
03757
03758
03759
03760
if (ResultOperand->Exponent <= SINGLE_MINIMUM_EXPONENT && Mantissa != 0) {
03761
03762
03763
03764
03765
03766 ResultMantissa = Mantissa;
03767 ResultExponent = ResultOperand->Exponent;
03768 ResultStickyBits = StickyBits;
03769 ResultRoundBit = RoundBit;
03770
03771
03772
03773
03774
03775
03776 DenormalizeShift = 1 - ResultOperand->Exponent;
03777
03778
03779
03780
03781
03782
03783
if (DenormalizeShift > 25) {
03784 DenormalizeShift = 25;
03785 }
03786
03787
03788
03789
03790
03791
03792 StickyBits |= RoundBit;
03793 StickyBits |= (Mantissa << 1) << (32 - DenormalizeShift);
03794 RoundBit = (Mantissa >> (DenormalizeShift - 1)) & 1;
03795 Mantissa = Mantissa >> DenormalizeShift;
03796 ResultOperand->Exponent = SINGLE_MINIMUM_EXPONENT;
03797 }
03798
03799
03800
03801
03802
03803
switch (ContextBlock->Round) {
03804
03805
03806
03807
03808
03809
case ROUND_TO_NEAREST:
03810
if (RoundBit != 0) {
03811
if ((StickyBits != 0) || ((Mantissa & 0x1) != 0)) {
03812 Mantissa += 1;
03813 }
03814 }
03815
break;
03816
03817
03818
03819
03820
03821
case ROUND_TO_ZERO:
03822
break;
03823
03824
03825
03826
03827
03828
case ROUND_TO_PLUS_INFINITY:
03829
if ((ResultOperand->Sign == 0) &&
03830 ((StickyBits != 0) || (RoundBit != 0))) {
03831 Mantissa += 1;
03832 }
03833
break;
03834
03835
03836
03837
03838
03839
case ROUND_TO_MINUS_INFINITY:
03840
if ((ResultOperand->Sign != 0) &&
03841 ((StickyBits != 0) || (RoundBit != 0))) {
03842 Mantissa += 1;
03843 }
03844
break;
03845 }
03846
03847
03848
03849
03850
03851
03852
if ((Mantissa & (1 << 24)) != 0) {
03853 Mantissa >>= 1;
03854 ResultOperand->Exponent += 1;
03855 }
03856
03857
03858
03859
03860
03861
03862
if ((ResultOperand->Exponent == SINGLE_MINIMUM_EXPONENT) &&
03863 (Mantissa & (1 << 23)) != 0) {
03864 ResultOperand->Exponent += 1;
03865 }
03866
03867
03868
03869
03870
03871
03872
03873
03874
03875
03876
03877
03878
03879
03880
03881
03882
03883
03884
03885
03886
03887
if (ResultOperand->Exponent >= SINGLE_MAXIMUM_EXPONENT) {
03888 Inexact =
TRUE;
03889 Overflow =
TRUE;
03890 Underflow =
FALSE;
03891
03892
03893
03894
03895
03896
switch (ContextBlock->Round) {
03897
03898
03899
03900
03901
03902
03903
03904
case ROUND_TO_NEAREST:
03905 ResultValue = SINGLE_INFINITY_VALUE | (ResultOperand->Sign << 31);
03906
break;
03907
03908
03909
03910
03911
03912
03913
03914
case ROUND_TO_ZERO:
03915 ResultValue = SINGLE_MAXIMUM_VALUE | (ResultOperand->Sign << 31);
03916
break;
03917
03918
03919
03920
03921
03922
03923
03924
03925
03926
case ROUND_TO_PLUS_INFINITY:
03927
if (ResultOperand->Sign == 0) {
03928 ResultValue = SINGLE_INFINITY_VALUE;
03929
03930 }
else {
03931 ResultValue = (ULONG)(SINGLE_MAXIMUM_VALUE | (1 << 31));
03932 }
03933
break;
03934
03935
03936
03937
03938
03939
03940
03941
03942
03943
case ROUND_TO_MINUS_INFINITY:
03944
if (ResultOperand->Sign != 0) {
03945 ResultValue = (ULONG)(SINGLE_INFINITY_VALUE | (1 << 31));
03946
03947 }
else {
03948 ResultValue = SINGLE_MAXIMUM_VALUE;
03949 }
03950
break;
03951 }
03952
03953
03954
03955
03956
03957
03958 ExceptionResult = Mantissa & ((1 << 23) - 1);
03959 ExceptionResult |= ((ResultOperand->Exponent - 192) << 23);
03960 ExceptionResult |= (ResultOperand->Sign << 31);
03961
03962 }
else {
03963
03964
03965
03966
03967
03968
03969
03970
if ((ResultOperand->Exponent == SINGLE_MINIMUM_EXPONENT) &&
03971 (Mantissa != 0 || RoundBit != 00 || StickyBits != 0)) {
03972
03973
03974
03975
03976
03977
03978
03979
if ((ContextBlock->IeeeMode ==
FALSE) ||
03980 (SoftwareFpcr->DenormalResultEnable == 0)) {
03981
DBGPRINT(
"SoftwareFpcr->DenormalResultEnable == 0\n");
03982 ResultValue = 0;
03983 Inexact =
FALSE;
03984 Overflow =
FALSE;
03985 Underflow =
FALSE;
03986
03987 }
else {
03988
03989 ResultValue = Mantissa;
03990 ResultValue |= ResultOperand->Sign << 31;
03991
03992
03993
03994
03995
03996
03997
03998
03999
04000
04001
04002
switch (ContextBlock->Round) {
04003
04004
04005
04006
04007
04008
case ROUND_TO_NEAREST:
04009
if (ResultRoundBit != 0) {
04010
if ((ResultStickyBits != 0) || ((ResultMantissa & 0x1) != 0)) {
04011 ResultMantissa += 1;
04012 }
04013 }
04014
break;
04015
04016
04017
04018
04019
04020
case ROUND_TO_ZERO:
04021
break;
04022
04023
04024
04025
04026
04027
case ROUND_TO_PLUS_INFINITY:
04028
if ((ResultOperand->Sign == 0) &&
04029 ((ResultStickyBits != 0) || (ResultRoundBit != 0))) {
04030 ResultMantissa += 1;
04031 }
04032
break;
04033
04034
04035
04036
04037
04038
case ROUND_TO_MINUS_INFINITY:
04039
if ((ResultOperand->Sign != 0) &&
04040 ((ResultStickyBits != 0) || (ResultRoundBit != 0))) {
04041 ResultMantissa += 1;
04042 }
04043
break;
04044 }
04045
04046
04047
04048
04049
04050
04051
if ((ResultMantissa & (1 << 24)) != 0) {
04052 ResultMantissa >>= 1;
04053 ResultExponent += 1;
04054 }
04055
04056
04057
04058
04059
04060
04061 ExceptionResult = ResultMantissa & ((1 << 23) - 1);
04062 ExceptionResult |= ((ResultExponent + 192) << 23);
04063 ExceptionResult |= (ResultOperand->Sign << 31);
04064
04065
04066
04067
04068
04069
04070
04071 Overflow =
FALSE;
04072 Underflow =
TRUE;
04073
if ((StickyBits != 0) || (RoundBit != 0)) {
04074 Inexact =
TRUE;
04075
04076 }
else {
04077 Inexact =
FALSE;
04078 }
04079 }
04080
04081 }
else {
04082
04083
04084
04085
04086
04087
if (Mantissa == 0) {
04088 ResultOperand->Exponent = 0;
04089 }
04090
04091 ResultValue = Mantissa & ((1 << 23) - 1);
04092 ResultValue |= (ResultOperand->Exponent << 23);
04093 ResultValue |= (ResultOperand->Sign << 31);
04094
if ((StickyBits != 0) || (RoundBit != 0)) {
04095 Inexact =
TRUE;
04096
04097 }
else {
04098 Inexact =
FALSE;
04099 }
04100 Overflow =
FALSE;
04101 Underflow =
FALSE;
04102 }
04103 }
04104
04105
04106
04107
04108
04109 ExceptionRecord = ContextBlock->ExceptionRecord;
04110
04111
if (Overflow !=
FALSE) {
04112 Fpcr->Overflow = 1;
04113 Fpcr->InexactResult = 1;
04114 Fpcr->SummaryBit = 1;
04115
if (ContextBlock->IeeeMode ==
FALSE) {
04116 ExceptionRecord->ExceptionCode = STATUS_FLOAT_OVERFLOW;
04117
return FALSE;
04118 }
04119 IeeeValue =
KiInitializeIeeeValue(ExceptionRecord);
04120 SoftwareFpcr->StatusOverflow = 1;
04121 SoftwareFpcr->StatusInexact = 1;
04122
if (SoftwareFpcr->EnableOverflow != 0) {
04123 ExceptionRecord->ExceptionCode = STATUS_FLOAT_OVERFLOW;
04124 IeeeValue->Value.Fp32Value.W[0] = ExceptionResult;
04125 ReturnValue =
FALSE;
04126 }
else if (SoftwareFpcr->EnableInexact != 0) {
04127 ExceptionRecord->ExceptionCode = STATUS_FLOAT_INEXACT_RESULT;
04128 IeeeValue->Value.Fp32Value.W[0] = ExceptionResult;
04129 ReturnValue =
FALSE;
04130 }
else {
04131 Fpcr->DisableOverflow = 1;
04132 Fpcr->DisableInexact = 1;
04133 }
04134
04135 }
else if (Underflow !=
FALSE) {
04136
04137
04138
04139
04140
04141
if (ContextBlock->IeeeMode ==
FALSE) {
04142 Fpcr->Underflow = 1;
04143 Fpcr->SummaryBit = 1;
04144 Fpcr->InexactResult = 1;
04145
if (ContextBlock->UnderflowEnable !=
FALSE) {
04146 ExceptionRecord->ExceptionCode = STATUS_FLOAT_UNDERFLOW;
04147
return FALSE;
04148 }
04149
04150
04151
04152
04153
04154
04155 }
else {
04156 IeeeValue =
KiInitializeIeeeValue(ExceptionRecord);
04157
if (Inexact !=
FALSE) {
04158 Fpcr->Underflow = 1;
04159 Fpcr->InexactResult = 1;
04160 Fpcr->SummaryBit = 1;
04161 SoftwareFpcr->StatusUnderflow = 1;
04162 SoftwareFpcr->StatusInexact = 1;
04163 }
04164
if (SoftwareFpcr->EnableUnderflow != 0) {
04165 Fpcr->Underflow = 1;
04166 Fpcr->SummaryBit = 1;
04167 SoftwareFpcr->StatusUnderflow = 1;
04168 ExceptionRecord->ExceptionCode = STATUS_FLOAT_UNDERFLOW;
04169 IeeeValue->Value.Fp32Value.W[0] = ExceptionResult;
04170 ReturnValue =
FALSE;
04171 }
else if (Inexact !=
FALSE && SoftwareFpcr->EnableInexact != 0) {
04172 ExceptionRecord->ExceptionCode = STATUS_FLOAT_INEXACT_RESULT;
04173 IeeeValue->Value.Fp32Value.W[0] = ExceptionResult;
04174 ReturnValue =
FALSE;
04175 }
else if (Inexact !=
FALSE) {
04176 Fpcr->DisableUnderflow = 1;
04177 Fpcr->DisableInexact = 1;
04178 }
04179 }
04180
04181 }
else if (Inexact !=
FALSE) {
04182 Fpcr->InexactResult = 1;
04183 Fpcr->SummaryBit = 1;
04184
if (ContextBlock->IeeeMode !=
FALSE) {
04185 IeeeValue =
KiInitializeIeeeValue(ExceptionRecord);
04186 SoftwareFpcr->StatusInexact = 1;
04187
if (SoftwareFpcr->EnableInexact != 0) {
04188 ExceptionRecord->ExceptionCode = STATUS_FLOAT_INEXACT_RESULT;
04189 IeeeValue->Value.Fp32Value.W[0] = ResultValue;
04190 ReturnValue =
FALSE;
04191 }
else {
04192 Fpcr->DisableInexact = 1;
04193 }
04194 }
04195 }
04196
04197
04198
04199
04200
04201
04202
KiSetRegisterValue(ContextBlock->Fc + 32,
04203
KiConvertSingleOperandToRegister(ResultValue),
04204 ContextBlock->ExceptionFrame,
04205 ContextBlock->TrapFrame);
04206
04207
04208
04209
04210
04211
return ReturnValue;
04212 }
04213
04214
VOID
04215 KiUnpackDouble (
04216 IN ULONG Source,
04217 IN PFP_CONTEXT_BLOCK ContextBlock,
04218 OUT PFP_DOUBLE_OPERAND DoubleOperand
04219 )
04220
04221
04222
04223
04224
04225
04226
04227
04228
04229
04230
04231
04232
04233
04234
04235
04236
04237
04238
04239
04240
04241
04242
04243
04244
04245
04246
04247
04248
04249
04250
04251
04252
04253 {
04254
04255 ULONGLONG Value;
04256 ULONG Value1;
04257 ULONG Value2;
04258
04259
04260
04261
04262
04263
04264 Value =
KiGetRegisterValue(Source + 32,
04265 ContextBlock->ExceptionFrame,
04266 ContextBlock->TrapFrame);
04267 Value1 = (ULONG)Value;
04268 Value2 = (ULONG)(Value >> 32);
04269
04270 DoubleOperand->Sign = Value2 >> 31;
04271 DoubleOperand->Exponent = (Value2 >> (52 - 32)) & 0x7ff;
04272 DoubleOperand->MantissaHigh = Value2 & 0xfffff;
04273 DoubleOperand->MantissaLow = Value1;
04274
04275
04276
04277
04278
04279
04280
04281
04282
if (DoubleOperand->Exponent == DOUBLE_MAXIMUM_EXPONENT) {
04283 DoubleOperand->Normal =
FALSE;
04284
if ((DoubleOperand->MantissaLow | DoubleOperand->MantissaHigh) != 0) {
04285 DoubleOperand->Infinity =
FALSE;
04286 DoubleOperand->Nan =
TRUE;
04287
04288 }
else {
04289 DoubleOperand->Infinity =
TRUE;
04290 DoubleOperand->Nan =
FALSE;
04291 }
04292
04293 }
else {
04294 DoubleOperand->Infinity =
FALSE;
04295 DoubleOperand->Nan =
FALSE;
04296 DoubleOperand->Normal =
TRUE;
04297
if (DoubleOperand->Exponent == DOUBLE_MINIMUM_EXPONENT) {
04298
if ((DoubleOperand->MantissaHigh | DoubleOperand->MantissaLow) != 0) {
04299
if (ContextBlock->SoftwareFpcr->DenormalOperandsEnable == 0) {
04300
DBGPRINT(
"SoftwareFpcr->DenormalOperandsEnable == 0\n");
04301 DoubleOperand->MantissaHigh = 0;
04302 DoubleOperand->MantissaLow = 0;
04303 DoubleOperand->Exponent = 0;
04304 }
else {
04305 DoubleOperand->Normal =
FALSE;
04306 DoubleOperand->Exponent += 1;
04307
while ((DoubleOperand->MantissaHigh & (1 << 20)) == 0) {
04308 DoubleOperand->MantissaHigh =
04309 (DoubleOperand->MantissaHigh << 1) |
04310 (DoubleOperand->MantissaLow >> 31);
04311 DoubleOperand->MantissaLow <<= 1;
04312 DoubleOperand->Exponent -= 1;
04313 }
04314 }
04315 }
04316
04317 }
else {
04318 DoubleOperand->MantissaHigh |= (1 << 20);
04319 }
04320 }
04321
04322
04323
04324
04325
04326
04327 DoubleOperand->MantissaHigh =
04328 (DoubleOperand->MantissaHigh << 2) | (DoubleOperand->MantissaLow >> 30);
04329 DoubleOperand->MantissaLow <<= 2;
04330
DBGPRINT(
"KiUnpackDouble: Inf=%d NaN=%d Sign=%d Exponent=%d Mantissa=%.8x%.8x\n",
04331 DoubleOperand->Infinity, DoubleOperand->Nan, DoubleOperand->Sign,
04332 DoubleOperand->Exponent,
04333 DoubleOperand->MantissaHigh, DoubleOperand->MantissaLow);
04334
04335
return;
04336 }
04337
04338
VOID
04339 KiUnpackSingle (
04340 IN ULONG Source,
04341 IN PFP_CONTEXT_BLOCK ContextBlock,
04342 OUT PFP_SINGLE_OPERAND SingleOperand
04343 )
04344
04345
04346
04347
04348
04349
04350
04351
04352
04353
04354
04355
04356
04357
04358
04359
04360
04361
04362
04363
04364
04365
04366
04367
04368
04369
04370
04371
04372
04373
04374
04375
04376
04377 {
04378
04379 ULONG Value;
04380
04381
04382
04383
04384
04385
04386 Value =
KiConvertRegisterToSingleOperand(
04387
KiGetRegisterValue(Source + 32,
04388 ContextBlock->ExceptionFrame,
04389 ContextBlock->TrapFrame));
04390
04391 SingleOperand->Sign = Value >> 31;
04392 SingleOperand->Exponent = (Value >> 23) & 0xff;
04393 SingleOperand->Mantissa = Value & 0x7fffff;
04394
04395
04396
04397
04398
04399
04400
04401
04402
if (SingleOperand->Exponent == SINGLE_MAXIMUM_EXPONENT) {
04403 SingleOperand->Normal =
FALSE;
04404
if (SingleOperand->Mantissa != 0) {
04405 SingleOperand->Infinity =
FALSE;
04406 SingleOperand->Nan =
TRUE;
04407
04408 }
else {
04409 SingleOperand->Infinity =
TRUE;
04410 SingleOperand->Nan =
FALSE;
04411 }
04412
04413 }
else {
04414 SingleOperand->Infinity =
FALSE;
04415 SingleOperand->Nan =
FALSE;
04416 SingleOperand->Normal =
TRUE;
04417
if (SingleOperand->Exponent == SINGLE_MINIMUM_EXPONENT) {
04418
if (SingleOperand->Mantissa != 0) {
04419
if (ContextBlock->SoftwareFpcr->DenormalOperandsEnable == 0) {
04420
DBGPRINT(
"SoftwareFpcr->DenormalOperandsEnable == 0\n");
04421 SingleOperand->Mantissa = 0;
04422 SingleOperand->Exponent = 0;
04423 }
else {
04424 SingleOperand->Normal =
FALSE;
04425 SingleOperand->Exponent += 1;
04426
while ((SingleOperand->Mantissa & (1 << 23)) == 0) {
04427 SingleOperand->Mantissa <<= 1;
04428 SingleOperand->Exponent -= 1;
04429 }
04430 }
04431 }
04432
04433 }
else {
04434 SingleOperand->Mantissa |= (1 << 23);
04435 }
04436 }
04437
04438
04439
04440
04441
04442
04443 SingleOperand->Mantissa <<= 2;
04444
DBGPRINT(
"KiUnpackSingle: Inf=%d NaN=%d Sign=%d Exponent=%d Mantissa=%.8x\n",
04445 SingleOperand->Infinity, SingleOperand->Nan, SingleOperand->Sign,
04446 SingleOperand->Exponent, SingleOperand->Mantissa);
04447
return;
04448 }