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
#include "ki.h"
00027
00028 #define OPCODE_MASK 0x1EF00000000
00029
00030 #define LD_OP 0x08000000000
00031 #define LDS_OP 0x08100000000
00032 #define LDA_OP 0x08200000000
00033 #define LDSA_OP 0x08300000000
00034 #define LDBIAS_OP 0x08400000000
00035 #define LDACQ_OP 0x08500000000
00036 #define LDCCLR_OP 0x08800000000
00037 #define LDCNC_OP 0x08900000000
00038 #define LDCCLRACQ_OP 0x08A00000000
00039 #define ST_OP 0x08C00000000
00040 #define STREL_OP 0x08D00000000
00041
00042 #define LD_IMM_OP 0x0A000000000
00043 #define LDS_IMM_OP 0x0A100000000
00044 #define LDA_IMM_OP 0x0A200000000
00045 #define LDSA_IMM_OP 0x0A300000000
00046 #define LDBIAS_IMM_OP 0x0A400000000
00047 #define LDACQ_IMM_OP 0x0A500000000
00048 #define LDCCLR_IMM_OP 0x0A800000000
00049 #define LDCNC_IMM_OP 0x0A900000000
00050 #define LDCCLRACQ_IMM_OP 0x0AA00000000
00051 #define ST_IMM_OP 0x0AC00000000
00052 #define STREL_IMM_OP 0x0AD00000000
00053
00054 #define LDF_OP 0x0C000000000
00055 #define LDFS_OP 0x0C100000000
00056 #define LDFA_OP 0x0C200000000
00057 #define LDFSA_OP 0x0C300000000
00058 #define LDFCCLR_OP 0x0C800000000
00059 #define LDFCNC_OP 0x0C900000000
00060 #define STF_OP 0x0CC00000000
00061
00062 #define LDF_IMM_OP 0x0E000000000
00063 #define LDFS_IMM_OP 0x0E100000000
00064 #define LDFA_IMM_OP 0x0E200000000
00065 #define LDFSA_IMM_OP 0x0E300000000
00066 #define LDFCCLR_IMM_OP 0x0E800000000
00067 #define LDFCNC_IMM_OP 0x0E900000000
00068 #define STF_IMM_OP 0x0EC00000000
00069
00070 typedef struct _INST_FORMAT {
00071
union {
00072
struct {
00073 ULONGLONG
qp: 6;
00074 ULONGLONG
r1: 7;
00075 ULONGLONG
r2: 7;
00076 ULONGLONG
r3: 7;
00077 ULONGLONG
x: 1;
00078 ULONGLONG
hint: 2;
00079 ULONGLONG
x6: 6;
00080 ULONGLONG
m: 1;
00081 ULONGLONG
Op: 4;
00082 ULONGLONG
Rsv: 23;
00083 } i_field;
00084 ULONGLONG
Ulong64;
00085 } u;
00086 }
INST_FORMAT;
00087
00088
VOID
00089
KiEmulateLoad(
00090 IN PVOID UnalignedAddress,
00091 IN ULONG OperandSize,
00092 IN PVOID Data
00093 );
00094
00095
VOID
00096
KiEmulateStore(
00097 IN PVOID UnalignedAddress,
00098 IN ULONG OperandSize,
00099 IN PVOID Data
00100 );
00101
00102
VOID
00103
KiEmulateLoadFloat(
00104 IN PVOID UnalignedAddress,
00105 IN ULONG OperandSize,
00106 IN PVOID Data
00107 );
00108
00109
VOID
00110
KiEmulateStoreFloat(
00111 IN PVOID UnalignedAddress,
00112 IN ULONG OperandSize,
00113 IN PVOID Data
00114 );
00115
00116
VOID
00117
KiEmulateLoadFloat80(
00118 IN PVOID UnalignedAddress,
00119 OUT PVOID FloatData
00120 );
00121
00122
VOID
00123
KiEmulateLoadFloatInt(
00124 IN PVOID UnalignedAddress,
00125 OUT PVOID FloatData
00126 );
00127
00128
VOID
00129
KiEmulateLoadFloat32(
00130 IN PVOID UnalignedAddress,
00131 OUT PVOID FloatData
00132 );
00133
00134
VOID
00135
KiEmulateLoadFloat64(
00136 IN PVOID UnalignedAddress,
00137 OUT PVOID FloatData
00138 );
00139
00140
VOID
00141
KiEmulateStoreFloat80(
00142 IN PVOID UnalignedAddress,
00143 OUT PVOID FloatData
00144 );
00145
00146
VOID
00147
KiEmulateStoreFloatInt(
00148 IN PVOID UnalignedAddress,
00149 OUT PVOID FloatData
00150 );
00151
00152
VOID
00153
KiEmulateStoreFloat32(
00154 IN PVOID UnalignedAddress,
00155 OUT PVOID FloatData
00156 );
00157
00158
VOID
00159
KiEmulateStoreFloat64(
00160 IN PVOID UnalignedAddress,
00161 OUT PVOID FloatData
00162 );
00163
00164
00165 BOOLEAN
00166 KiEmulateReference (
00167 IN OUT PEXCEPTION_RECORD ExceptionRecord,
00168 IN OUT PKEXCEPTION_FRAME ExceptionFrame,
00169 IN OUT PKTRAP_FRAME TrapFrame
00170 )
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194 {
00195
00196 PVOID EffectiveAddress;
00197 PVOID ExceptionAddress;
00198 KIRQL OldIrql;
00199
00200
KPROCESSOR_MODE PreviousMode;
00201
INST_FORMAT FaultInstruction;
00202 ULONGLONG Opcode;
00203 ULONGLONG Reg2Value;
00204 ULONGLONG Reg3Value;
00205 ULONGLONG BundleLow;
00206 ULONGLONG BundleHigh;
00207 ULONGLONG Syllable;
00208 ULONGLONG Data = 0;
00209 FLOAT128 FloatData = {0, 0};
00210 ULONG OpSize;
00211 ULONG ImmValue;
00212 ULONG Length;
00213
00214
00215
00216
00217
00218
00219 KiFlushRse();
00220
00221
00222
00223
00224
00225
if (
KiProfileAlignmentFixup) {
00226
00227
if (++
KiProfileAlignmentFixupCount >=
KiProfileAlignmentFixupInterval) {
00228
00229
KeRaiseIrql(
PROFILE_LEVEL, &OldIrql);
00230
KiProfileAlignmentFixupCount = 0;
00231
KeProfileInterruptWithSource(TrapFrame, ProfileAlignmentFixup);
00232
KeLowerIrql(OldIrql);
00233
00234 }
00235 }
00236
00237
00238
00239
00240
00241
00242 EffectiveAddress = (PVOID) ExceptionRecord->ExceptionInformation[1];
00243 ExceptionAddress = (PVOID) TrapFrame->StIIP;
00244
00245
00246
00247
00248
00249 PreviousMode = (
KPROCESSOR_MODE) TrapFrame->PreviousMode;
00250
00251
00252
00253
00254
00255
00256
00257
00258
try {
00259
00260
00261 BundleLow = *((ULONGLONG *)ExceptionAddress);
00262 BundleHigh = *(((ULONGLONG *)ExceptionAddress) + 1);
00263
00264 Syllable = (TrapFrame->StIPSR >> PSR_RI) & 0x3;
00265
00266
switch (Syllable) {
00267
case 0:
00268 FaultInstruction.
u.Ulong64 = (BundleLow >> 5);
00269
break;
00270
case 1:
00271 FaultInstruction.
u.Ulong64 = (BundleLow >> 46) | (BundleHigh << 18);
00272
break;
00273
case 2:
00274 FaultInstruction.
u.Ulong64 = (BundleHigh >> 23);
00275
case 3:
00276
default:
00277
return FALSE;
00278 }
00279
00280 Opcode = FaultInstruction.
u.Ulong64 &
OPCODE_MASK;
00281 OpSize = (ULONG)FaultInstruction.
u.i_field.x6 & 0x3;
00282
00283
switch (Opcode) {
00284
00285
00286
00287
00288
00289
case LDS_OP:
00290
case LDSA_OP:
00291
case LDS_IMM_OP:
00292
case LDSA_IMM_OP:
00293
case LDFS_OP:
00294
case LDFSA_OP:
00295
case LDFS_IMM_OP:
00296
00297
00298
00299
00300
00301 TrapFrame->StIPSR |= (1i64 << PSR_ED);
00302
00303
return TRUE;
00304
00305
00306
00307
00308
00309
case LD_OP:
00310
case LDA_OP:
00311
case LDBIAS_OP:
00312
case LDCCLR_OP:
00313
case LDCNC_OP:
00314
case LDACQ_OP:
00315
case LDCCLRACQ_OP:
00316
00317
if (FaultInstruction.
u.i_field.x == 1) {
00318
00319
00320
00321
00322
00323
return FALSE;
00324 }
00325
00326
if( PreviousMode !=
KernelMode ){
00327
ProbeForRead( EffectiveAddress,
00328 1 << OpSize,
00329
sizeof(UCHAR) );
00330 }
00331
KiEmulateLoad(EffectiveAddress, OpSize, &Data);
00332
KiSetRegisterValue( (ULONG) FaultInstruction.
u.i_field.r1,
00333 Data,
00334 ExceptionFrame,
00335 TrapFrame );
00336
00337
if (FaultInstruction.
u.i_field.m == 1) {
00338
00339
00340
00341
00342
00343
00344 Reg2Value =
KiGetRegisterValue( (ULONG) FaultInstruction.
u.i_field.r2,
00345 ExceptionFrame,
00346 TrapFrame );
00347
00348 Reg3Value =
KiGetRegisterValue( (ULONG) FaultInstruction.
u.i_field.r3,
00349 ExceptionFrame,
00350 TrapFrame );
00351
00352
00353
00354
00355
00356 Reg3Value = Reg2Value + Reg3Value;
00357
00358
KiSetRegisterValue ((ULONG) FaultInstruction.
u.i_field.r3,
00359 Reg3Value,
00360 ExceptionFrame,
00361 TrapFrame);
00362 }
00363
00364
if ((Opcode ==
LDACQ_OP) || (Opcode ==
LDCCLRACQ_OP)) {
00365
00366
00367
00368
00369
00370 __mf();
00371 }
00372
00373
break;
00374
00375
00376
00377
00378
00379
00380
case LD_IMM_OP:
00381
case LDA_IMM_OP:
00382
case LDBIAS_IMM_OP:
00383
case LDCCLR_IMM_OP:
00384
case LDCNC_IMM_OP:
00385
case LDACQ_IMM_OP:
00386
case LDCCLRACQ_IMM_OP:
00387
00388
if( PreviousMode !=
KernelMode ){
00389
ProbeForRead( EffectiveAddress,
00390 1 << OpSize,
00391
sizeof(UCHAR) );
00392 }
00393
KiEmulateLoad(EffectiveAddress, OpSize, &Data);
00394
KiSetRegisterValue( (ULONG) FaultInstruction.
u.i_field.r1,
00395 Data,
00396 ExceptionFrame,
00397 TrapFrame );
00398
00399
00400
00401
00402
00403 Reg3Value =
KiGetRegisterValue( (ULONG) FaultInstruction.
u.i_field.r3,
00404 ExceptionFrame,
00405 TrapFrame );
00406
00407
00408
00409
00410
00411 ImmValue = (ULONG)(FaultInstruction.
u.i_field.r2
00412 + (FaultInstruction.
u.i_field.x << 7));
00413
00414
if (FaultInstruction.
u.i_field.m == 1) {
00415
00416 ImmValue = 0xFFFFFFFFFFFFFF00 | ImmValue;
00417
00418 }
00419
00420 Reg3Value = Reg3Value + ImmValue;
00421
00422
KiSetRegisterValue( (ULONG) FaultInstruction.
u.i_field.r3,
00423 Reg3Value,
00424 ExceptionFrame,
00425 TrapFrame );
00426
00427
if ((Opcode ==
LDACQ_IMM_OP) || (Opcode ==
LDCCLRACQ_IMM_OP)) {
00428
00429
00430
00431
00432
00433 __mf();
00434 }
00435
00436
break;
00437
00438
case LDF_OP:
00439
case LDFA_OP:
00440
case LDFCCLR_OP:
00441
case LDFCNC_OP:
00442
00443
if (FaultInstruction.
u.i_field.x == 1) {
00444
00445
00446
00447
00448
00449
if (FaultInstruction.
u.i_field.m == 1) {
00450
00451
00452
00453
00454
00455
return FALSE;
00456
00457 }
00458
00459
if( PreviousMode !=
KernelMode ){
00460
00461
switch (OpSize) {
00462
case 0:
return FALSE;
00463
case 1: Length = 8;
break;
00464
case 2: Length = 4;
break;
00465
case 3: Length = 8;
break;
00466
default:
00467
return FALSE;
00468 }
00469
00470
ProbeForRead( EffectiveAddress,
00471 Length << 1,
00472
sizeof(UCHAR) );
00473 }
00474
00475
00476
00477
00478
00479
KiEmulateLoadFloat(EffectiveAddress, OpSize, &FloatData);
00480
KiSetFloatRegisterValue( (ULONG) FaultInstruction.
u.i_field.r1,
00481 FloatData,
00482 ExceptionFrame,
00483 TrapFrame );
00484
00485
00486
00487
00488
00489 EffectiveAddress = (PVOID)((ULONG_PTR)EffectiveAddress + Length);
00490
00491
KiEmulateLoadFloat(EffectiveAddress, OpSize, &FloatData);
00492
KiSetFloatRegisterValue( (ULONG) FaultInstruction.
u.i_field.r2,
00493 FloatData,
00494 ExceptionFrame,
00495 TrapFrame );
00496
00497 }
else {
00498
00499
00500
00501
00502
00503
if( PreviousMode !=
KernelMode ){
00504
00505
switch (OpSize) {
00506
case 0: Length = 16;
break;
00507
case 1: Length = 8;
break;
00508
case 2: Length = 4;
break;
00509
case 3: Length = 8;
break;
00510
default:
00511
return FALSE;
00512 }
00513
00514
ProbeForRead( EffectiveAddress,
00515 Length,
00516
sizeof(UCHAR) );
00517 }
00518
00519
KiEmulateLoadFloat(EffectiveAddress, OpSize, &FloatData);
00520
KiSetFloatRegisterValue( (ULONG) FaultInstruction.
u.i_field.r1,
00521 FloatData,
00522 ExceptionFrame,
00523 TrapFrame );
00524
00525
if (FaultInstruction.
u.i_field.m == 1) {
00526
00527
00528
00529
00530
00531 Reg2Value =
KiGetRegisterValue( (ULONG) FaultInstruction.
u.i_field.r2,
00532 ExceptionFrame,
00533 TrapFrame );
00534
00535 Reg3Value =
KiGetRegisterValue( (ULONG) FaultInstruction.
u.i_field.r3,
00536 ExceptionFrame,
00537 TrapFrame );
00538
00539
00540
00541
00542 Reg3Value = Reg2Value + Reg3Value;
00543
00544
KiSetRegisterValue ((ULONG) FaultInstruction.
u.i_field.r3,
00545 Reg3Value,
00546 ExceptionFrame,
00547 TrapFrame);
00548 }
00549 }
00550
00551
break;
00552
00553
00554
00555
00556
00557
00558
case LDF_IMM_OP:
00559
case LDFA_IMM_OP:
00560
case LDFCCLR_IMM_OP:
00561
case LDFCNC_IMM_OP:
00562
00563
if (FaultInstruction.
u.i_field.x == 1) {
00564
00565
00566
00567
00568
00569
if (FaultInstruction.
u.i_field.m == 0) {
00570
00571
00572
00573
00574
00575
return FALSE;
00576
00577 }
00578
00579
if( PreviousMode !=
KernelMode ){
00580
00581
switch (OpSize) {
00582
case 0:
return FALSE;
00583
case 1: Length = 8;
break;
00584
case 2: Length = 8;
break;
00585
case 3: Length = 4;
break;
00586
default:
00587
return FALSE;
00588 }
00589
00590
ProbeForRead( EffectiveAddress,
00591 Length << 1,
00592
sizeof(UCHAR) );
00593 }
00594
00595
00596
00597
00598
00599
KiEmulateLoadFloat(EffectiveAddress, OpSize, &FloatData);
00600
KiSetFloatRegisterValue( (ULONG) FaultInstruction.
u.i_field.r1,
00601 FloatData,
00602 ExceptionFrame,
00603 TrapFrame );
00604
00605 EffectiveAddress = (PVOID)((ULONG_PTR)EffectiveAddress + Length);
00606
00607
00608
00609
00610
00611
KiEmulateLoadFloat(EffectiveAddress, OpSize, &FloatData);
00612
KiSetFloatRegisterValue( (ULONG) FaultInstruction.
u.i_field.r2,
00613 FloatData,
00614 ExceptionFrame,
00615 TrapFrame );
00616
00617
00618
00619
00620
00621 Reg3Value =
KiGetRegisterValue( (ULONG) FaultInstruction.
u.i_field.r3,
00622 ExceptionFrame,
00623 TrapFrame );
00624
00625
00626
00627
00628
00629 ImmValue = Length << 1;
00630
00631 Reg3Value = Reg3Value + ImmValue;
00632
00633
KiSetRegisterValue( (ULONG) FaultInstruction.
u.i_field.r3,
00634 Reg3Value,
00635 ExceptionFrame,
00636 TrapFrame );
00637
00638 }
else {
00639
00640
00641
00642
00643
00644
if( PreviousMode !=
KernelMode ){
00645
00646
switch (OpSize) {
00647
case 0: Length = 16;
break;
00648
case 1: Length = 8;
break;
00649
case 2: Length = 4;
break;
00650
case 3: Length = 8;
break;
00651
default:
00652
return FALSE;
00653 }
00654
00655
ProbeForRead( EffectiveAddress,
00656 Length,
00657
sizeof(UCHAR) );
00658 }
00659
KiEmulateLoadFloat(EffectiveAddress, OpSize, &FloatData);
00660
KiSetFloatRegisterValue( (ULONG) FaultInstruction.
u.i_field.r1,
00661 FloatData,
00662 ExceptionFrame,
00663 TrapFrame );
00664
00665
00666
00667
00668
00669 Reg3Value =
KiGetRegisterValue( (ULONG) FaultInstruction.
u.i_field.r3,
00670 ExceptionFrame,
00671 TrapFrame );
00672
00673
00674
00675
00676
00677 ImmValue = (ULONG)(FaultInstruction.
u.i_field.r2
00678 + (FaultInstruction.
u.i_field.x << 7));
00679
00680
if (FaultInstruction.
u.i_field.m == 1) {
00681
00682 ImmValue = 0xFFFFFFFFFFFFFF00 | ImmValue;
00683
00684 }
00685
00686 Reg3Value = Reg3Value + ImmValue;
00687
00688
KiSetRegisterValue( (ULONG) FaultInstruction.
u.i_field.r3,
00689 Reg3Value,
00690 ExceptionFrame,
00691 TrapFrame );
00692 }
00693
00694
break;
00695
00696
00697
case STREL_OP:
00698
00699 __mf();
00700
00701
case ST_OP:
00702
00703
if (FaultInstruction.
u.i_field.x == 1) {
00704
00705
00706
00707
00708
00709
return FALSE;
00710 }
00711
00712
if (FaultInstruction.
u.i_field.m == 1) {
00713
00714
00715
00716
00717
00718
return FALSE;
00719 }
00720
00721
if( PreviousMode !=
KernelMode ){
00722
ProbeForWrite( EffectiveAddress,
00723 1 << OpSize,
00724
sizeof(UCHAR) );
00725 }
00726 Data =
KiGetRegisterValue( (ULONG) FaultInstruction.
u.i_field.r2,
00727 ExceptionFrame,
00728 TrapFrame );
00729
00730
KiEmulateStore( EffectiveAddress, OpSize, &Data);
00731
00732
break;
00733
00734
case STREL_IMM_OP:
00735
00736 __mf();
00737
00738
case ST_IMM_OP:
00739
00740
if( PreviousMode !=
KernelMode ){
00741
ProbeForWrite( EffectiveAddress,
00742 1 << OpSize,
00743
sizeof(UCHAR) );
00744 }
00745 Data =
KiGetRegisterValue( (ULONG) FaultInstruction.
u.i_field.r2,
00746 ExceptionFrame,
00747 TrapFrame );
00748
00749
KiEmulateStore( EffectiveAddress, OpSize, &Data);
00750
00751
00752
00753
00754
00755 Reg3Value =
KiGetRegisterValue( (ULONG) FaultInstruction.
u.i_field.r3,
00756 ExceptionFrame,
00757 TrapFrame );
00758
00759
00760
00761
00762
00763 ImmValue = (ULONG)(FaultInstruction.
u.i_field.r1
00764 + (FaultInstruction.
u.i_field.x << 7));
00765
00766
if (FaultInstruction.
u.i_field.m == 1) {
00767
00768 ImmValue = 0xFFFFFFFFFFFFFF00 | ImmValue;
00769
00770 }
00771
00772 Reg3Value = Reg3Value + ImmValue;
00773
00774
KiSetRegisterValue( (ULONG) FaultInstruction.
u.i_field.r3,
00775 Reg3Value,
00776 ExceptionFrame,
00777 TrapFrame );
00778
00779
break;
00780
00781
00782
case STF_OP:
00783
00784
if (FaultInstruction.
u.i_field.x) {
00785
00786
00787
00788
00789
00790
return FALSE;
00791 }
00792
00793
if (FaultInstruction.
u.i_field.m) {
00794
00795
00796
00797
00798
00799
return FALSE;
00800 }
00801
00802
if( PreviousMode !=
KernelMode ){
00803
00804
switch (OpSize) {
00805
case 0: Length = 16;
break;
00806
case 1: Length = 8;
break;
00807
case 2: Length = 4;
break;
00808
case 3: Length = 8;
break;
00809
default:
00810
return FALSE;
00811 }
00812
00813
ProbeForWrite( EffectiveAddress,
00814 Length,
00815
sizeof(UCHAR) );
00816 }
00817 FloatData =
KiGetFloatRegisterValue( (ULONG) FaultInstruction.
u.i_field.r2,
00818 ExceptionFrame,
00819 TrapFrame );
00820
00821
KiEmulateStoreFloat( EffectiveAddress, OpSize, &FloatData);
00822
00823
break;
00824
00825
case STF_IMM_OP:
00826
00827
if( PreviousMode !=
KernelMode ){
00828
00829
switch (OpSize) {
00830
case 0: Length = 16;
break;
00831
case 1: Length = 8;
break;
00832
case 2: Length = 4;
break;
00833
case 3: Length = 8;
break;
00834
default:
00835
return FALSE;
00836 }
00837
00838
ProbeForWrite( EffectiveAddress,
00839 Length,
00840
sizeof(UCHAR) );
00841 }
00842 FloatData =
KiGetFloatRegisterValue( (ULONG) FaultInstruction.
u.i_field.r2,
00843 ExceptionFrame,
00844 TrapFrame );
00845
00846
KiEmulateStoreFloat( EffectiveAddress, OpSize, &FloatData);
00847
00848
00849
00850
00851
00852 Reg3Value =
KiGetRegisterValue( (ULONG) FaultInstruction.
u.i_field.r3,
00853 ExceptionFrame,
00854 TrapFrame );
00855
00856
00857
00858
00859 ImmValue = (ULONG)(FaultInstruction.
u.i_field.r1
00860 + (FaultInstruction.
u.i_field.x << 7));
00861
00862
if (FaultInstruction.
u.i_field.m == 1) {
00863
00864 ImmValue = 0xFFFFFFFFFFFFFF00 | ImmValue;
00865
00866 }
00867
00868 Reg3Value = Reg3Value + ImmValue;
00869
00870
KiSetRegisterValue( (ULONG) FaultInstruction.
u.i_field.r3,
00871 Reg3Value,
00872 ExceptionFrame,
00873 TrapFrame );
00874
00875
break;
00876
00877
default:
00878
00879
return FALSE;
00880
00881 }
00882
00883
00884
00885
00886
00887
KiAdvanceInstPointer(TrapFrame);
00888
00889
return TRUE;
00890
00891
00892
00893
00894
00895
00896 } except (
KiCopyInformation(ExceptionRecord,
00897 (GetExceptionInformation())->ExceptionRecord)) {
00898
00899
00900
00901
00902
00903 ExceptionRecord->ExceptionAddress = ExceptionAddress;
00904 }
00905
00906
00907
00908
00909
00910
return FALSE;
00911 }
00912
00913
00914
VOID
00915 KiEmulateLoad(
00916 IN PVOID UnalignedAddress,
00917 IN ULONG OperandSize,
00918 IN PVOID Data
00919 )
00920
00921
00922
00923
00924
00925
00926
00927
00928
00929
00930
00931
00932
00933
00934
00935
00936
00937
00938
00939
00940
00941
00942 {
00943 PUCHAR Source;
00944 PUCHAR Destination;
00945 ULONG i;
00946
00947 Source = (PUCHAR) UnalignedAddress;
00948 Destination = (PUCHAR) Data;
00949 OperandSize = 1 << OperandSize;
00950
00951
for (i = 0; i < OperandSize; i++) {
00952
00953 *Destination++ = *Source++;
00954
00955 }
00956
00957
return;
00958 }
00959
00960
00961
VOID
00962 KiEmulateStore(
00963 IN PVOID UnalignedAddress,
00964 IN ULONG OperandSize,
00965 IN PVOID Data
00966 )
00967
00968
00969
00970
00971
00972
00973
00974
00975
00976
00977
00978
00979
00980
00981
00982
00983
00984
00985
00986
00987 {
00988 PUCHAR Source;
00989 PUCHAR Destination;
00990 ULONG i;
00991
00992 Source = (PUCHAR) Data;
00993 Destination = (PUCHAR) UnalignedAddress;
00994 OperandSize = 1 << OperandSize;
00995
00996
for (i = 0; i < OperandSize; i++) {
00997
00998 *Destination++ = *Source++;
00999
01000 }
01001
01002
return;
01003 }
01004
01005
01006
VOID
01007 KiEmulateLoadFloat(
01008 IN PVOID UnalignedAddress,
01009 IN ULONG OperandSize,
01010 IN OUT PVOID Data
01011 )
01012
01013
01014
01015
01016
01017
01018
01019
01020
01021
01022
01023
01024
01025
01026
01027
01028
01029
01030
01031
01032
01033
01034 {
01035 FLOAT128 FloatData;
01036
01037 RtlMoveMemory(&FloatData, UnalignedAddress,
sizeof(FLOAT128));
01038
01039
switch (OperandSize) {
01040
01041
case 0:
01042
KiEmulateLoadFloat80(&FloatData, Data);
01043
return;
01044
01045
case 1:
01046
KiEmulateLoadFloatInt(&FloatData, Data);
01047
return;
01048
01049
case 2:
01050
KiEmulateLoadFloat32(&FloatData, Data);
01051
return;
01052
01053
case 3:
01054
KiEmulateLoadFloat64(&FloatData, Data);
01055
return;
01056
01057
default:
01058
return;
01059 }
01060 }
01061
01062
VOID
01063 KiEmulateStoreFloat(
01064 IN PVOID UnalignedAddress,
01065 IN ULONG OperandSize,
01066 IN PVOID Data
01067 )
01068
01069
01070
01071
01072
01073
01074
01075
01076
01077
01078
01079
01080
01081
01082
01083
01084
01085
01086
01087
01088
01089
01090 {
01091 FLOAT128 FloatData;
01092 ULONG Length;
01093
01094
switch (OperandSize) {
01095
01096
case 0:
01097
KiEmulateStoreFloat80(&FloatData, Data);
01098 Length = 16;
01099
break;
01100
01101
case 1:
01102
KiEmulateStoreFloatInt(&FloatData, Data);
01103 Length = 8;
01104
break;
01105
01106
case 2:
01107
KiEmulateStoreFloat32(&FloatData, Data);
01108 Length = 4;
01109
break;
01110
01111
case 3:
01112
KiEmulateStoreFloat64(&FloatData, Data);
01113 Length = 8;
01114
break;
01115
01116
default:
01117
return;
01118 }
01119
01120 RtlMoveMemory(UnalignedAddress, &FloatData, Length);
01121 }
01122