- Timestamp:
- Feb 15, 2012 4:40:03 PM (13 years ago)
- svn:sync-xref-src-repo-rev:
- 76289
- Location:
- trunk/src/VBox/VMM
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMAll/IEMAllAImpl.asm
r40093 r40138 1278 1278 1279 1279 1280 ;;1281 ; The state saved by FXSAVE.1282 ; @todo move to x86.mac.1283 ;1284 struc X86FXSTATE1285 .FCW resw 11286 .FSW resw 11287 .FTW resw 11288 .FOP resw 11289 .FPUIP resd 11290 .CS resw 11291 .Rsrvd1 resw 11292 .FPUDP resd 11293 .DS resw 11294 .Rsrvd2 resw 11295 .MXCSR resd 11296 .MXCSR_MASK resd 11297 .r0 resd 41298 .r1 resd 41299 .r2 resd 41300 .r3 resd 41301 .r4 resd 41302 .r5 resd 41303 .r6 resd 41304 .r7 resd 41305 .xmm0 resd 41306 .xmm1 resd 41307 .xmm2 resd 41308 .xmm3 resd 41309 .xmm4 resd 41310 .xmm5 resd 41311 .xmm6 resd 41312 .xmm7 resd 41313 .xmm8 resd 41314 .xmm9 resd 41315 .xmm10 resd 41316 .xmm11 resd 41317 .xmm12 resd 41318 .xmm13 resd 41319 .xmm14 resd 41320 .xmm15 resd 41321 .au32RsrvdRest resd 241322 endstruc1323 1324 1280 %macro FPU_SAFE_INIT 1 1325 1281 fninit -
trunk/src/VBox/VMM/testcase/tstX86-1.cpp
r40082 r40138 72 72 DECLASM(int32_t) x861_Test5(void); 73 73 DECLASM(int32_t) x861_Test6(void); 74 DECLASM(int32_t) x861_TestFPUInstr1(void); 74 75 75 76 … … 179 180 180 181 182 181 183 int main() 182 184 { … … 239 241 if (rc != 0) 240 242 RTTestFailed(hTest, "x861_Test4 -> %d", rc); 241 #endif242 243 243 244 RTTestSub(hTest, "Odd floating point encodings"); … … 250 251 if (rc != 0) 251 252 RTTestFailed(hTest, "x861_Test6 -> %d", rc); 253 #endif 254 255 rc = x861_TestFPUInstr1(); 256 if (rc != 0) 257 RTTestFailed(hTest, "x861_TestFPUInstr1 -> %d", rc); 252 258 } 253 259 -
trunk/src/VBox/VMM/testcase/tstX86-1A.asm
r40090 r40138 33 33 34 34 35 %ifdef RT_ARCH_AMD64 36 %define arch_fxsave o64 fxsave 37 %define arch_fxrstor o64 fxrstor 38 %else 39 %define arch_fxsave fxsave 40 %define arch_fxrstor fxrstor 41 %endif 42 35 43 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 36 44 ; Global Variables ; … … 45 53 %define g_cchAlpha (g_szAlpha_end - NAME(g_szAlpha)) 46 54 db 0, 0, 0, 55 56 ;; @name Floating point constants. 57 ; @{ 58 g_r32_0dot1: dd 0.1 59 g_r32_3dot2: dd 3.2 60 g_r32_Zero: dd 0.0 61 g_r32_One: dd 1.0 62 g_r32_Two: dd 2.0 63 g_r32_Three: dd 3.0 64 g_r32_Ten: dd 10.0 65 g_r32_Eleven: dd 11.0 66 g_r32_ThirtyTwo:dd 32.0 67 g_r32_Min: dd 000800000h 68 g_r32_Max: dd 07f7fffffh 69 g_r32_Inf: dd 07f800000h 70 g_r32_SNaN: dd 07f800001h 71 g_r32_SNaNMax: dd 07fbfffffh 72 g_r32_QNaN: dd 07fc00000h 73 g_r32_QNaNMax: dd 07fffffffh 74 75 g_r64_0dot1: dq 0.1 76 g_r64_6dot9: dq 6.9 77 g_r64_Zero: dq 0.0 78 g_r64_One: dq 1.0 79 g_r64_Two: dq 2.0 80 g_r64_Three: dq 3.0 81 g_r64_Ten: dq 10.0 82 g_r64_Eleven: dq 11.0 83 g_r64_ThirtyTwo:dq 32.0 84 g_r64_Min: dq 00010000000000000h 85 g_r64_Max: dq 07fefffffffffffffh 86 g_r64_Inf: dq 07ff0000000000000h 87 g_r64_SNaN: dq 07ff0000000000001h 88 g_r64_SNaNMax: dq 07ff7ffffffffffffh 89 g_r64_QNaN: dq 07ff8000000000000h 90 g_r64_QNaNMax: dq 07fffffffffffffffh 91 g_r64_DnMin: dq 00000000000000001h 92 g_r64_DnMax: dq 0000fffffffffffffh 93 94 95 g_r80_0dot1: dt 0.1 96 g_r80_3dot2: dt 3.2 97 g_r80_Zero: dt 0.0 98 g_r80_One: dt 1.0 99 g_r80_Two: dt 2.0 100 g_r80_Three: dt 3.0 101 g_r80_Ten: dt 10.0 102 g_r80_Eleven: dt 11.0 103 g_r80_ThirtyTwo:dt 32.0 104 g_r80_Min: dt 000018000000000000000h 105 g_r80_Max: dt 07ffeffffffffffffffffh 106 g_r80_Inf: dt 07fff8000000000000000h 107 108 g_r32V1: dd 3.2 109 g_r32V2: dd -1.9 110 g_r64V1: dq 6.4 111 g_r80V1: dt 8.0 112 113 ; Denormal numbers. 114 g_r32D0: dd 000200000h 115 ;; @} 116 117 ;; @name Upconverted Floating point constants 118 ; @{ 119 ;g_r80_r32_0dot1: dt 0.1 120 g_r80_r32_3dot2: dt 04000cccccd0000000000h 121 ;g_r80_r32_Zero: dt 0.0 122 ;g_r80_r32_One: dt 1.0 123 ;g_r80_r32_Two: dt 2.0 124 ;g_r80_r32_Three: dt 3.0 125 ;g_r80_r32_Ten: dt 10.0 126 ;g_r80_r32_Eleven: dt 11.0 127 ;g_r80_r32_ThirtyTwo: dt 32.0 128 ;; @} 129 130 ;; @name Decimal constants. 131 ; @{ 132 g_u64Zero: dd 0 133 g_u32Zero: dw 0 134 g_u64Two: dd 2 135 g_u32Two: dw 2 136 ;; @} 137 47 138 48 139 ;; … … 63 154 ;; Reference a variable 64 155 %ifdef RT_ARCH_AMD64 65 %define REF(a_Name) [a_Name wrt rip]156 %define REF(a_Name) a_Name wrt rip 66 157 %else 67 %define REF(a_Name) [a_Name]158 %define REF(a_Name) a_Name 68 159 %endif 69 160 70 161 ;; Reference a global variable 71 162 %ifdef RT_ARCH_AMD64 72 %define REF_ GLOBAL(a_Name) [NAME(a_Name) wrt rip]163 %define REF_EXTERN(a_Name) NAME(a_Name) wrt rip 73 164 %else 74 %define REF_ GLOBAL(a_Name) [NAME(a_Name)]165 %define REF_EXTERN(a_Name) NAME(a_Name) 75 166 %endif 76 167 … … 125 216 BEGINCODE 126 217 %%resume: 127 FpuCheckFSW ((%1) | X86_FSW_ B | X86_FSW_ES), %2218 FpuCheckFSW ((%1) | X86_FSW_ES | X86_FSW_B), %2 128 219 fnclex 129 220 %endmacro 130 221 131 222 ;; 132 ; Macro for recording a FPU instruction trapping on a following fwait.223 ; Macro for recording checking the FSW value. 133 224 ; 134 225 ; Uses stack. … … 148 239 jmp .return 149 240 %%ok: 150 fnstsw ax151 241 %endmacro 152 242 … … 172 262 %endmacro 173 263 174 175 ;; 176 ; Function prologue saving all registers except EAX. 264 ;; Checks that ST0 contains QNaN. 265 %define CheckSt0Value_QNaN CheckSt0Value 0x00000000, 0xc0000000, 0xffff 266 ;; Checks that ST0 contains +Inf. 267 %define CheckSt0Value_PlusInf CheckSt0Value 0x00000000, 0x80000000, 0x7fff 268 ;; Checks that ST0 contains 3 & 1/3. 269 %define CheckSt0Value_3_and_a_3rd CheckSt0Value 0x55555555, 0xd5555555, 0x4000 270 ;; Checks that ST0 contains 3 & 1/3. 271 %define CheckSt0Value_3_and_two_3rds CheckSt0Value 0xaaaaaaab, 0xeaaaaaaa, 0x4000 272 273 274 ;; 275 ; Macro for recording checking the FSW value of a FXSAVE image. 276 ; 277 ; Uses stack. 278 ; 279 ; @param 1 Address expression for the FXSAVE image. 280 ; @param 2 The status flags that are expected to be set afterwards. 281 ; @param 3 C0..C3 to mask out in case undefined. 282 ; @uses eax 283 ; @sa FpuCheckFSW 284 ; 285 %macro FxSaveCheckFSW 3 286 %%resume: 287 movzx eax, word [%1 + X86FXSTATE.FSW] 288 and eax, ~X86_FSW_TOP_MASK & ~(%3) 289 cmp eax, (%2) 290 je %%ok 291 mov eax, 10000000 + __LINE__ 292 jmp .return 293 %%ok: 294 %endmacro 295 296 297 ;; 298 ; Checks that ST0 is empty in an FXSAVE image. 299 ; 300 ; @uses eax 301 ; @param 1 Address expression for the FXSAVE image. 302 ; 303 %macro FxSaveCheckSt0Empty 1 304 movzx eax, word [%1 + X86FXSTATE.FSW] 305 and eax, X86_FSW_TOP_MASK 306 shr eax, X86_FSW_TOP_SHIFT 307 bt [%1 + X86FXSTATE.FTW], eax 308 jnc %%ok 309 mov eax, 20000000 + __LINE__ 310 jmp .return 311 %%ok: 312 %endmacro 313 314 315 ;; 316 ; Checks that ST0 is not-empty in an FXSAVE image. 317 ; 318 ; @uses eax 319 ; @param 1 Address expression for the FXSAVE image. 320 ; 321 %macro FxSaveCheckSt0NonEmpty 1 322 movzx eax, word [%1 + X86FXSTATE.FSW] 323 and eax, X86_FSW_TOP_MASK 324 shr eax, X86_FSW_TOP_SHIFT 325 bt [%1 + X86FXSTATE.FTW], eax 326 jc %%ok 327 mov eax, 30000000 + __LINE__ 328 jmp .return 329 %%ok: 330 %endmacro 331 332 ;; 333 ; Checks that ST0 in a FXSAVE image has a certain value (empty or not 334 ; is ignored). 335 ; 336 ; @uses eax 337 ; @param 1 Address expression for the FXSAVE image. 338 ; @param 2 First dword of value. 339 ; @param 3 Second dword of value. 340 ; @param 4 Final word of value. 341 ; 342 %macro FxSaveCheckSt0ValueEx 4 343 cmp dword [%1 + X86FXSTATE.st0], %2 344 je %%ok1 345 %%bad: 346 mov eax, 40000000 + __LINE__ 347 jmp .return 348 %%ok1: 349 cmp dword [%1 + X86FXSTATE.st0 + 4], %3 350 jne %%bad 351 cmp word [%1 + X86FXSTATE.st0 + 8], %4 352 jne %%bad 353 %endmacro 354 355 356 ;; 357 ; Checks if ST0 in a FXSAVE image has the same value as the specified 358 ; floating point (80-bit) constant. 359 ; 360 ; @uses eax, xDX 361 ; @param 1 Address expression for the FXSAVE image. 362 ; @param 2 The address expression of the constant. 363 ; 364 %macro FxSaveCheckSt0ValueConstEx 2 365 mov eax, [%2] 366 cmp dword [%1 + X86FXSTATE.st0], eax 367 je %%ok1 368 %%bad: 369 mov eax, 40000000 + __LINE__ 370 jmp .return 371 %%ok1: 372 mov eax, [4 + %2] 373 cmp dword [%1 + X86FXSTATE.st0 + 4], eax 374 jne %%bad 375 mov ax, [8 + %2] 376 cmp word [%1 + X86FXSTATE.st0 + 8], ax 377 jne %%bad 378 %endmacro 379 380 381 ;; 382 ; Checks that ST0 in a FXSAVE image has a certain value. 383 ; 384 ; @uses eax 385 ; @param 1 Address expression for the FXSAVE image. 386 ; @param 2 First dword of value. 387 ; @param 3 Second dword of value. 388 ; @param 4 Final word of value. 389 ; 390 %macro FxSaveCheckSt0Value 4 391 FxSaveCheckSt0NonEmpty %1 392 FxSaveCheckSt0ValueEx %1, %2, %3, %4 393 %endmacro 394 395 396 ;; 397 ; Checks that ST0 in a FXSAVE image is empty and that the value stored is the 398 ; init value set by FpuInitWithCW. 399 ; 400 ; @uses eax 401 ; @param 1 Address expression for the FXSAVE image. 402 ; 403 %macro FxSaveCheckSt0EmptyInitValue 1 404 FxSaveCheckSt0Empty %1 405 FxSaveCheckSt0ValueEx %1, 0x40404040, 0x40404040, 0xffff 406 %endmacro 407 408 ;; 409 ; Checks that ST0 in a FXSAVE image is non-empty and has the same value as the 410 ; specified constant (80-bit). 411 ; 412 ; @uses eax, xDX 413 ; @param 1 Address expression for the FXSAVE image. 414 ; @param 2 The address expression of the constant. 415 %macro FxSaveCheckSt0ValueConst 2 416 FxSaveCheckSt0NonEmpty %1 417 FxSaveCheckSt0ValueConstEx %1, %2 418 %endmacro 419 420 ;; Checks that ST0 contains QNaN. 421 %define FxSaveCheckSt0Value_QNaN(p) FxSaveCheckSt0Value p, 0x00000000, 0xc0000000, 0xffff 422 ;; Checks that ST0 contains +Inf. 423 %define FxSaveCheckSt0Value_PlusInf(p) FxSaveCheckSt0Value p, 0x00000000, 0x80000000, 0x7fff 424 ;; Checks that ST0 contains 3 & 1/3. 425 %define FxSaveCheckSt0Value_3_and_a_3rd(p) FxSaveCheckSt0Value p, 0x55555555, 0xd5555555, 0x4000 426 ;; Checks that ST0 contains 3 & 1/3. 427 %define FxSaveCheckSt0Value_3_and_two_3rds(p) FxSaveCheckSt0Value p, 0xaaaaaaab, 0xeaaaaaaa, 0x4000 428 429 430 ;; 431 ; Function prologue saving all registers except EAX and aligns the stack 432 ; on a 16-byte boundrary. 177 433 ; 178 434 %macro SAVE_ALL_PROLOGUE 0 … … 195 451 push r15 196 452 %endif 453 and xSP, ~0fh; 197 454 %endmacro 198 455 … … 203 460 %macro SAVE_ALL_EPILOGUE 0 204 461 %ifdef RT_ARCH_AMD64 462 lea rsp, [rbp - 14 * 8] 205 463 pop r15 206 464 pop r14 … … 211 469 pop r9 212 470 pop r8 471 %else 472 lea esp, [ebp - 6 * 4] 213 473 %endif 214 474 pop xDI … … 285 545 ; 286 546 x861_LoadUniqueRegValuesSSE: 287 movq mm0, REF(._mm0) 288 movq mm1, REF(._mm1) 289 movq mm2, REF(._mm2) 290 movq mm3, REF(._mm3) 291 movq mm4, REF(._mm4) 292 movq mm5, REF(._mm5) 293 movq mm6, REF(._mm6) 294 movq mm7, REF(._mm7) 295 movdqu xmm0, REF(._xmm0) 296 movdqu xmm1, REF(._xmm1) 297 movdqu xmm2, REF(._xmm2) 298 movdqu xmm3, REF(._xmm3) 299 movdqu xmm4, REF(._xmm4) 300 movdqu xmm5, REF(._xmm5) 301 movdqu xmm6, REF(._xmm6) 302 movdqu xmm7, REF(._xmm7) 547 fninit 548 movq mm0, [REF(._mm0)] 549 movq mm1, [REF(._mm1)] 550 movq mm2, [REF(._mm2)] 551 movq mm3, [REF(._mm3)] 552 movq mm4, [REF(._mm4)] 553 movq mm5, [REF(._mm5)] 554 movq mm6, [REF(._mm6)] 555 movq mm7, [REF(._mm7)] 556 movdqu xmm0, [REF(._xmm0)] 557 movdqu xmm1, [REF(._xmm1)] 558 movdqu xmm2, [REF(._xmm2)] 559 movdqu xmm3, [REF(._xmm3)] 560 movdqu xmm4, [REF(._xmm4)] 561 movdqu xmm5, [REF(._xmm5)] 562 movdqu xmm6, [REF(._xmm6)] 563 movdqu xmm7, [REF(._xmm7)] 303 564 %ifdef RT_ARCH_AMD64 304 movdqu xmm8, REF(._xmm8)305 movdqu xmm9, REF(._xmm9)306 movdqu xmm10, REF(._xmm10)307 movdqu xmm11, REF(._xmm11)308 movdqu xmm12, REF(._xmm12)309 movdqu xmm13, REF(._xmm13)310 movdqu xmm14, REF(._xmm14)311 movdqu xmm15, REF(._xmm15)565 movdqu xmm8, [REF(._xmm8)] 566 movdqu xmm9, [REF(._xmm9)] 567 movdqu xmm10, [REF(._xmm10)] 568 movdqu xmm11, [REF(._xmm11)] 569 movdqu xmm12, [REF(._xmm12)] 570 movdqu xmm13, [REF(._xmm13)] 571 movdqu xmm14, [REF(._xmm14)] 572 movdqu xmm15, [REF(._xmm15)] 312 573 %endif 313 574 call x861_LoadUniqueRegValues … … 343 604 344 605 ;; 345 ; Clears all general, MMX and SSE registers except xBP and xSP.606 ; Clears all MMX and SSE registers. 346 607 ; 347 608 x861_ClearRegistersSSE: 348 call x861_ClearRegisters349 movq mm0, REF(.zero)350 movq mm1, REF(.zero)351 movq mm2, REF(.zero)352 movq mm3, REF(.zero)353 movq mm4, REF(.zero)354 movq mm5, REF(.zero)355 movq mm6, REF(.zero)356 movq mm7, REF(.zero)357 movdqu xmm0, REF(.zero)358 movdqu xmm1, REF(.zero)359 movdqu xmm2, REF(.zero)360 movdqu xmm3, REF(.zero)361 movdqu xmm4, REF(.zero)362 movdqu xmm5, REF(.zero)363 movdqu xmm6, REF(.zero)364 movdqu xmm7, REF(.zero)609 fninit 610 movq mm0, [REF(.zero)] 611 movq mm1, [REF(.zero)] 612 movq mm2, [REF(.zero)] 613 movq mm3, [REF(.zero)] 614 movq mm4, [REF(.zero)] 615 movq mm5, [REF(.zero)] 616 movq mm6, [REF(.zero)] 617 movq mm7, [REF(.zero)] 618 movdqu xmm0, [REF(.zero)] 619 movdqu xmm1, [REF(.zero)] 620 movdqu xmm2, [REF(.zero)] 621 movdqu xmm3, [REF(.zero)] 622 movdqu xmm4, [REF(.zero)] 623 movdqu xmm5, [REF(.zero)] 624 movdqu xmm6, [REF(.zero)] 625 movdqu xmm7, [REF(.zero)] 365 626 %ifdef RT_ARCH_AMD64 366 movdqu xmm8, REF(.zero)367 movdqu xmm9, REF(.zero)368 movdqu xmm10, REF(.zero)369 movdqu xmm11, REF(.zero)370 movdqu xmm12, REF(.zero)371 movdqu xmm13, REF(.zero)372 movdqu xmm14, REF(.zero)373 movdqu xmm15, REF(.zero)627 movdqu xmm8, [REF(.zero)] 628 movdqu xmm9, [REF(.zero)] 629 movdqu xmm10, [REF(.zero)] 630 movdqu xmm11, [REF(.zero)] 631 movdqu xmm12, [REF(.zero)] 632 movdqu xmm13, [REF(.zero)] 633 movdqu xmm14, [REF(.zero)] 634 movdqu xmm15, [REF(.zero)] 374 635 %endif 375 call x861_LoadUniqueRegValues376 636 ret 377 637 … … 380 640 ; x861_ClearRegistersSSE 381 641 642 643 ;; 644 ; Loads all general, MMX and SSE registers except xBP and xSP with unique values. 645 ; 646 x861_LoadUniqueRegValuesSSEAndGRegs: 647 call x861_LoadUniqueRegValuesSSE 648 call x861_LoadUniqueRegValues 649 ret 650 651 ;; 652 ; Clears all general, MMX and SSE registers except xBP and xSP. 653 ; 654 x861_ClearRegistersSSEAndGRegs: 655 call x861_ClearRegistersSSE 656 call x861_ClearRegisters 657 ret 382 658 383 659 BEGINPROC x861_Test1 … … 544 820 ; Loading is always a word access. 545 821 mov eax, __LINE__ 546 mov xDI, REF_GLOBAL(g_pbEfPage)822 mov xDI, [REF_EXTERN(g_pbEfPage)] 547 823 lea xDI, [xDI + 0x1000 - 2] 548 824 mov xDX, es … … 552 828 ; Saving is always a word access. 553 829 mov eax, __LINE__ 554 mov xDI, REF_GLOBAL(g_pbEfPage)830 mov xDI, [REF_EXTERN(g_pbEfPage)] 555 831 mov dword [xDI + 0x1000 - 4], -1 556 832 mov [xDI + 0x1000 - 2], ss ; Should not crash. … … 564 840 call x861_ClearRegisters 565 841 mov eax, __LINE__ 566 mov xDI, REF_GLOBAL(g_pbEfPage)842 mov xDI, [REF_EXTERN(g_pbEfPage)] 567 843 mov dword [xDI + 0x1000 - 4], -1 568 844 db 04ah … … 583 859 584 860 ; check that repne scasb (al=0) behaves like expected. 585 lea xDI, REF_GLOBAL(g_szAlpha)861 lea xDI, [REF(g_szAlpha)] 586 862 xor eax, eax ; find the end 587 863 mov ecx, g_cchAlpha + 1 … … 592 868 593 869 ; check that repe scasb (al=0) behaves like expected. 594 lea xDI, REF_GLOBAL(g_szAlpha)870 lea xDI, [REF(g_szAlpha)] 595 871 xor eax, eax ; find the end 596 872 mov ecx, g_cchAlpha + 1 … … 601 877 602 878 ; repne is last, it wins. 603 lea xDI, REF_GLOBAL(g_szAlpha)879 lea xDI, [REF(g_szAlpha)] 604 880 xor eax, eax ; find the end 605 881 mov ecx, g_cchAlpha + 1 … … 612 888 613 889 ; repe is last, it wins. 614 lea xDI, REF_GLOBAL(g_szAlpha)890 lea xDI, [REF(g_szAlpha)] 615 891 xor eax, eax ; find the end 616 892 mov ecx, g_cchAlpha + 1 … … 628 904 mov dx, ds 629 905 mov es, dx 630 mov xDI, REF_GLOBAL(g_pbEfPage)906 mov xDI, [REF_EXTERN(g_pbEfPage)] 631 907 xor eax, eax 632 908 mov ecx, 01000h 633 909 rep stosb 634 910 635 mov xDI, REF_GLOBAL(g_pbEfPage)911 mov xDI, [REF_EXTERN(g_pbEfPage)] 636 912 mov ecx, 4 637 913 mov eax, 0ffh … … 642 918 jne .failed 643 919 mov eax, __LINE__ 644 mov xDI, REF_GLOBAL(g_pbEfPage)920 mov xDI, [REF_EXTERN(g_pbEfPage)] 645 921 cmp dword [xDI], 0ffffffffh 646 922 jne .failed … … 648 924 jne .failed 649 925 650 mov xDI, REF_GLOBAL(g_pbEfPage)926 mov xDI, [REF_EXTERN(g_pbEfPage)] 651 927 mov ecx, 4 652 928 mov eax, 0feh … … 657 933 jne .failed 658 934 mov eax, __LINE__ 659 mov xDI, REF_GLOBAL(g_pbEfPage)935 mov xDI, [REF_EXTERN(g_pbEfPage)] 660 936 cmp dword [xDI], 0fefefefeh 661 937 jne .failed … … 670 946 mov dx, ds 671 947 mov es, dx 672 mov xDI, REF_GLOBAL(g_pbEfPage)948 mov xDI, [REF_EXTERN(g_pbEfPage)] 673 949 xor xCX, xCX 674 950 rep stosb ; no trap … … 702 978 ; 703 979 mov eax, __LINE__ 704 mov xDI, REF_GLOBAL(g_pbEfExecPage)980 mov xDI, [REF_EXTERN(g_pbEfExecPage)] 705 981 add xDI, 1000h - 8h 706 982 mov byte [xDI+0], 0f0h … … 712 988 713 989 mov eax, __LINE__ 714 mov xDI, REF_GLOBAL(g_pbEfExecPage)990 mov xDI, [REF_EXTERN(g_pbEfExecPage)] 715 991 add xDI, 1000h - 7h 716 992 mov byte [xDI+0], 0f0h … … 721 997 722 998 mov eax, __LINE__ 723 mov xDI, REF_GLOBAL(g_pbEfExecPage)999 mov xDI, [REF_EXTERN(g_pbEfExecPage)] 724 1000 add xDI, 1000h - 4h 725 1001 mov byte [xDI+0], 0f0h … … 730 1006 731 1007 mov eax, __LINE__ 732 mov xDI, REF_GLOBAL(g_pbEfExecPage)1008 mov xDI, [REF_EXTERN(g_pbEfExecPage)] 733 1009 add xDI, 1000h - 6h 734 1010 mov byte [xDI+0], 0f0h … … 741 1017 742 1018 mov eax, __LINE__ 743 mov xDI, REF_GLOBAL(g_pbEfExecPage)1019 mov xDI, [REF_EXTERN(g_pbEfExecPage)] 744 1020 add xDI, 1000h - 5h 745 1021 mov byte [xDI+0], 0f0h … … 751 1027 752 1028 mov eax, __LINE__ 753 mov xDI, REF_GLOBAL(g_pbEfExecPage)1029 mov xDI, [REF_EXTERN(g_pbEfExecPage)] 754 1030 add xDI, 1000h - 4h 755 1031 mov byte [xDI+0], 0f0h … … 760 1036 761 1037 mov eax, __LINE__ 762 mov xDI, REF_GLOBAL(g_pbEfExecPage)1038 mov xDI, [REF_EXTERN(g_pbEfExecPage)] 763 1039 add xDI, 1000h - 3h 764 1040 mov byte [xDI+0], 0f0h … … 768 1044 769 1045 mov eax, __LINE__ 770 mov xDI, REF_GLOBAL(g_pbEfExecPage)1046 mov xDI, [REF_EXTERN(g_pbEfExecPage)] 771 1047 add xDI, 1000h - 2h 772 1048 mov byte [xDI+0], 0f0h … … 775 1051 776 1052 mov eax, __LINE__ 777 mov xDI, REF_GLOBAL(g_pbEfExecPage)1053 mov xDI, [REF_EXTERN(g_pbEfExecPage)] 778 1054 add xDI, 1000h - 1h 779 1055 mov byte [xDI+0], 0f0h … … 819 1095 820 1096 ; Check testcase preconditions. 821 call x861_LoadUniqueRegValuesSSE 1097 call x861_LoadUniqueRegValuesSSEAndGRegs 822 1098 mov eax, __LINE__ 823 1099 db 00Fh, 073h, 0D0h, 080h ; psrlq mm0, 128 824 1100 call .check_mm0_zero_and_xmm0_nz 825 1101 826 call x861_LoadUniqueRegValuesSSE 1102 call x861_LoadUniqueRegValuesSSEAndGRegs 827 1103 mov eax, __LINE__ 828 1104 db 066h, 00Fh, 073h, 0D0h, 080h ; psrlq xmm0, 128 … … 836 1112 837 1113 ; General checks that order does not matter, etc. 838 call x861_LoadUniqueRegValuesSSE 1114 call x861_LoadUniqueRegValuesSSEAndGRegs 839 1115 mov eax, __LINE__ 840 1116 db 026h, 066h, 00Fh, 073h, 0D0h, 080h 841 1117 call .check_xmm0_zero_and_mm0_nz 842 1118 843 call x861_LoadUniqueRegValuesSSE 1119 call x861_LoadUniqueRegValuesSSEAndGRegs 844 1120 mov eax, __LINE__ 845 1121 db 066h, 026h, 00Fh, 073h, 0D0h, 080h 846 1122 call .check_xmm0_zero_and_mm0_nz 847 1123 848 call x861_LoadUniqueRegValuesSSE 1124 call x861_LoadUniqueRegValuesSSEAndGRegs 849 1125 mov eax, __LINE__ 850 1126 db 066h, 067h, 00Fh, 073h, 0D0h, 080h 851 1127 call .check_xmm0_zero_and_mm0_nz 852 1128 853 call x861_LoadUniqueRegValuesSSE 1129 call x861_LoadUniqueRegValuesSSEAndGRegs 854 1130 mov eax, __LINE__ 855 1131 db 067h, 066h, 00Fh, 073h, 0D0h, 080h 856 1132 call .check_xmm0_zero_and_mm0_nz 857 1133 858 call x861_LoadUniqueRegValuesSSE 1134 call x861_LoadUniqueRegValuesSSEAndGRegs 859 1135 mov eax, __LINE__ 860 1136 db 067h, 066h, 065h, 00Fh, 073h, 0D0h, 080h … … 862 1138 863 1139 %ifdef RT_ARCH_AMD64 864 call x861_LoadUniqueRegValuesSSE 1140 call x861_LoadUniqueRegValuesSSEAndGRegs 865 1141 mov eax, __LINE__ 866 1142 db 048h, 066h, 00Fh, 073h, 0D0h, 080h ; REX.W 867 1143 call .check_xmm0_zero_and_mm0_nz 868 1144 869 call x861_LoadUniqueRegValuesSSE 1145 call x861_LoadUniqueRegValuesSSEAndGRegs 870 1146 mov eax, __LINE__ 871 1147 db 044h, 066h, 00Fh, 073h, 0D0h, 080h ; REX.R 872 1148 call .check_xmm0_zero_and_mm0_nz 873 1149 874 call x861_LoadUniqueRegValuesSSE 1150 call x861_LoadUniqueRegValuesSSEAndGRegs 875 1151 mov eax, __LINE__ 876 1152 db 042h, 066h, 00Fh, 073h, 0D0h, 080h ; REX.X … … 878 1154 879 1155 ; Actually for REX, order does matter if the prefix is used. 880 call x861_LoadUniqueRegValuesSSE 1156 call x861_LoadUniqueRegValuesSSEAndGRegs 881 1157 mov eax, __LINE__ 882 1158 db 041h, 066h, 00Fh, 073h, 0D0h, 080h ; REX.B 883 1159 call .check_xmm0_zero_and_mm0_nz 884 1160 885 call x861_LoadUniqueRegValuesSSE 1161 call x861_LoadUniqueRegValuesSSEAndGRegs 886 1162 mov eax, __LINE__ 887 1163 db 066h, 041h, 00Fh, 073h, 0D0h, 080h ; REX.B … … 890 1166 891 1167 ; Check all ignored prefixes (repeates some of the above). 892 call x861_LoadUniqueRegValuesSSE 1168 call x861_LoadUniqueRegValuesSSEAndGRegs 893 1169 mov eax, __LINE__ 894 1170 db 066h, 026h, 00Fh, 073h, 0D0h, 080h ; es 895 1171 call .check_xmm0_zero_and_mm0_nz 896 1172 897 call x861_LoadUniqueRegValuesSSE 1173 call x861_LoadUniqueRegValuesSSEAndGRegs 898 1174 mov eax, __LINE__ 899 1175 db 066h, 065h, 00Fh, 073h, 0D0h, 080h ; gs 900 1176 call .check_xmm0_zero_and_mm0_nz 901 1177 902 call x861_LoadUniqueRegValuesSSE 1178 call x861_LoadUniqueRegValuesSSEAndGRegs 903 1179 mov eax, __LINE__ 904 1180 db 066h, 064h, 00Fh, 073h, 0D0h, 080h ; fs 905 1181 call .check_xmm0_zero_and_mm0_nz 906 1182 907 call x861_LoadUniqueRegValuesSSE 1183 call x861_LoadUniqueRegValuesSSEAndGRegs 908 1184 mov eax, __LINE__ 909 1185 db 066h, 02eh, 00Fh, 073h, 0D0h, 080h ; cs 910 1186 call .check_xmm0_zero_and_mm0_nz 911 1187 912 call x861_LoadUniqueRegValuesSSE 1188 call x861_LoadUniqueRegValuesSSEAndGRegs 913 1189 mov eax, __LINE__ 914 1190 db 066h, 036h, 00Fh, 073h, 0D0h, 080h ; ss 915 1191 call .check_xmm0_zero_and_mm0_nz 916 1192 917 call x861_LoadUniqueRegValuesSSE 1193 call x861_LoadUniqueRegValuesSSEAndGRegs 918 1194 mov eax, __LINE__ 919 1195 db 066h, 03eh, 00Fh, 073h, 0D0h, 080h ; ds 920 1196 call .check_xmm0_zero_and_mm0_nz 921 1197 922 call x861_LoadUniqueRegValuesSSE 1198 call x861_LoadUniqueRegValuesSSEAndGRegs 923 1199 mov eax, __LINE__ 924 1200 db 066h, 067h, 00Fh, 073h, 0D0h, 080h ; addr size … … 926 1202 927 1203 %ifdef RT_ARCH_AMD64 928 call x861_LoadUniqueRegValuesSSE 1204 call x861_LoadUniqueRegValuesSSEAndGRegs 929 1205 mov eax, __LINE__ 930 1206 db 066h, 048h, 00Fh, 073h, 0D0h, 080h ; REX.W 931 1207 call .check_xmm0_zero_and_mm0_nz 932 1208 933 call x861_LoadUniqueRegValuesSSE 1209 call x861_LoadUniqueRegValuesSSEAndGRegs 934 1210 mov eax, __LINE__ 935 1211 db 066h, 044h, 00Fh, 073h, 0D0h, 080h ; REX.R 936 1212 call .check_xmm0_zero_and_mm0_nz 937 1213 938 call x861_LoadUniqueRegValuesSSE 1214 call x861_LoadUniqueRegValuesSSEAndGRegs 939 1215 mov eax, __LINE__ 940 1216 db 066h, 042h, 00Fh, 073h, 0D0h, 080h ; REX.X 941 1217 call .check_xmm0_zero_and_mm0_nz 942 1218 943 call x861_LoadUniqueRegValuesSSE 1219 call x861_LoadUniqueRegValuesSSEAndGRegs 944 1220 mov eax, __LINE__ 945 1221 db 066h, 041h, 00Fh, 073h, 0D0h, 080h ; REX.B - has actual effect on the instruction. … … 948 1224 949 1225 ; Repeated prefix until we hit the max opcode limit. 950 call x861_LoadUniqueRegValuesSSE 1226 call x861_LoadUniqueRegValuesSSEAndGRegs 951 1227 mov eax, __LINE__ 952 1228 db 066h, 066h, 00Fh, 073h, 0D0h, 080h 953 1229 call .check_xmm0_zero_and_mm0_nz 954 1230 955 call x861_LoadUniqueRegValuesSSE 1231 call x861_LoadUniqueRegValuesSSEAndGRegs 956 1232 mov eax, __LINE__ 957 1233 db 066h, 066h, 066h, 00Fh, 073h, 0D0h, 080h 958 1234 call .check_xmm0_zero_and_mm0_nz 959 1235 960 call x861_LoadUniqueRegValuesSSE 1236 call x861_LoadUniqueRegValuesSSEAndGRegs 961 1237 mov eax, __LINE__ 962 1238 db 066h, 066h, 066h, 066h, 066h, 066h, 066h, 066h, 00Fh, 073h, 0D0h, 080h 963 1239 call .check_xmm0_zero_and_mm0_nz 964 1240 965 call x861_LoadUniqueRegValuesSSE 1241 call x861_LoadUniqueRegValuesSSEAndGRegs 966 1242 mov eax, __LINE__ 967 1243 db 066h, 066h, 066h, 066h, 066h, 066h, 066h, 066h, 066h, 066h, 066h, 00Fh, 073h, 0D0h, 080h … … 972 1248 %ifdef RT_ARCH_AMD64 973 1249 ; Repeated REX is parsed, but only the last byte matters. 974 call x861_LoadUniqueRegValuesSSE 1250 call x861_LoadUniqueRegValuesSSEAndGRegs 975 1251 mov eax, __LINE__ 976 1252 db 066h, 041h, 048h, 00Fh, 073h, 0D0h, 080h ; REX.B, REX.W 977 1253 call .check_xmm0_zero_and_mm0_nz 978 1254 979 call x861_LoadUniqueRegValuesSSE 1255 call x861_LoadUniqueRegValuesSSEAndGRegs 980 1256 mov eax, __LINE__ 981 1257 db 066h, 048h, 041h, 00Fh, 073h, 0D0h, 080h ; REX.B, REX.W 982 1258 call .check_xmm8_zero_and_xmm0_nz 983 1259 984 call x861_LoadUniqueRegValuesSSE 1260 call x861_LoadUniqueRegValuesSSEAndGRegs 985 1261 mov eax, __LINE__ 986 1262 db 066h, 048h, 044h, 042h, 048h, 044h, 042h, 048h, 044h, 042h, 041h, 00Fh, 073h, 0D0h, 080h 987 1263 call .check_xmm8_zero_and_xmm0_nz 988 1264 989 call x861_LoadUniqueRegValuesSSE 1265 call x861_LoadUniqueRegValuesSSEAndGRegs 990 1266 mov eax, __LINE__ 991 1267 db 066h, 041h, 041h, 041h, 041h, 041h, 041h, 041h, 041h, 041h, 04eh, 00Fh, 073h, 0D0h, 080h … … 1093 1369 BEGINPROC x861_Test3 1094 1370 SAVE_ALL_PROLOGUE 1095 call x861_LoadUniqueRegValuesSSE 1096 mov xDI, REF_GLOBAL(g_pbEfExecPage)1371 call x861_LoadUniqueRegValuesSSEAndGRegs 1372 mov xDI, [REF_EXTERN(g_pbEfExecPage)] 1097 1373 1098 1374 ; Check testcase preconditions. 1099 fxsave [xDI]1100 fxrstor [xDI]1375 fxsave [xDI] 1376 fxrstor [xDI] 1101 1377 1102 1378 add xDI, PAGE_SIZE - 512 … … 1126 1402 1127 1403 ; Check that a save + restore + save cycle yield the same results. 1128 mov xBX, REF_GLOBAL(g_pbEfExecPage)1404 mov xBX, [REF_EXTERN(g_pbEfExecPage)] 1129 1405 mov xDI, xBX 1130 1406 mov eax, 066778899h … … 1134 1410 fxsave [xBX] 1135 1411 1136 call x861_ClearRegistersSSE 1137 mov xBX, REF_GLOBAL(g_pbEfExecPage)1412 call x861_ClearRegistersSSEAndGRegs 1413 mov xBX, [REF_EXTERN(g_pbEfExecPage)] 1138 1414 fxrstor [xBX] 1139 1415 … … 1150 1426 ; 464:511 are available to software use. Let see how carefully access 1151 1427 ; to the full 512 bytes are checked... 1152 call x861_LoadUniqueRegValuesSSE 1153 mov xDI, REF_GLOBAL(g_pbEfExecPage)1428 call x861_LoadUniqueRegValuesSSEAndGRegs 1429 mov xDI, [REF_EXTERN(g_pbEfExecPage)] 1154 1430 add xDI, PAGE_SIZE - 512 1155 1431 ShouldTrap X86_XCPT_PF, fxsave [xDI + 16] … … 1227 1503 mov ebx, 16 1228 1504 .fxsave_pf_effect_loop: 1229 mov xDI, REF_GLOBAL(g_pbEfExecPage)1505 mov xDI, [REF_EXTERN(g_pbEfExecPage)] 1230 1506 add xDI, PAGE_SIZE - 512 * 2 1231 1507 mov xSI, xDI … … 1249 1525 1250 1526 ; Lets check that a FP in fxrstor does not have any effect on the FPU or SSE state. 1251 mov xDI, REF_GLOBAL(g_pbEfExecPage)1527 mov xDI, [REF_EXTERN(g_pbEfExecPage)] 1252 1528 mov ecx, PAGE_SIZE / 4 1253 1529 mov eax, 0ffaa33cch … … 1255 1531 rep stosd 1256 1532 1257 call x861_LoadUniqueRegValuesSSE 1258 mov xDI, REF_GLOBAL(g_pbEfExecPage)1533 call x861_LoadUniqueRegValuesSSEAndGRegs 1534 mov xDI, [REF_EXTERN(g_pbEfExecPage)] 1259 1535 fxsave [xDI] 1260 1536 1261 call x861_ClearRegistersSSE 1262 mov xDI, REF_GLOBAL(g_pbEfExecPage)1537 call x861_ClearRegistersSSEAndGRegs 1538 mov xDI, [REF_EXTERN(g_pbEfExecPage)] 1263 1539 fxsave [xDI + 512] 1264 1540 1265 1541 mov ebx, 16 1266 1542 .fxrstor_pf_effect_loop: 1267 mov xDI, REF_GLOBAL(g_pbEfExecPage)1543 mov xDI, [REF_EXTERN(g_pbEfExecPage)] 1268 1544 mov xSI, xDI 1269 1545 lea xDI, [xDI + PAGE_SIZE - 512 + xBX] … … 1274 1550 1275 1551 push xBX 1276 call x861_ClearRegistersSSE 1552 call x861_ClearRegistersSSEAndGRegs 1277 1553 pop xBX 1278 mov xDI, REF_GLOBAL(g_pbEfExecPage)1554 mov xDI, [REF_EXTERN(g_pbEfExecPage)] 1279 1555 ShouldTrap X86_XCPT_PF, fxrstor [xDI + PAGE_SIZE - 512 + xBX] ; try load unique state 1280 1556 1281 mov xDI, REF_GLOBAL(g_pbEfExecPage)1557 mov xDI, [REF_EXTERN(g_pbEfExecPage)] 1282 1558 lea xSI, [xDI + 512] ; point it to the clean state, which is what we expect. 1283 1559 lea xDI, [xDI + 1024] … … 1389 1665 sub xSP, 2048 1390 1666 and xSP, ~0fh 1391 fxsave[xSP + 1024]1667 arch_fxsave [xSP + 1024] 1392 1668 %1 1393 1669 call SaveFPUAndGRegsToStack 1394 1670 1395 fxrstor [xSP + 1024]1671 arch_fxrstor [xSP + 1024] 1396 1672 %2 1397 1673 call CompareFPUAndGRegsOnStack 1398 ; fxrstor [xSP + 1024]1674 ;arch_fxrstor [xSP + 1024] 1399 1675 leave 1400 1676 … … 1433 1709 1434 1710 ; Save the FPU state. 1435 fxsave[xSP + xS]1711 arch_fxsave [xSP + xS] 1436 1712 1437 1713 ; Save GRegs (80h bytes). … … 1515 1791 lea xDI, [xSI + 1024] 1516 1792 1517 mov dword [xSI + 0x8], 0 ; ignore FPUIP 1518 mov dword [xDI + 0x8], 0 ; ignore FPUIP 1793 mov word [xSI + X86FXSTATE.FOP], 0 ; ignore 1794 mov dword [xSI + X86FXSTATE.FPUIP], 0 ; ignore 1795 mov dword [xDI + X86FXSTATE.FPUDP], 0 ; ignore 1519 1796 1520 1797 cld … … 1522 1799 je .ok 1523 1800 1524 int31801 ;int3 1525 1802 lea xAX, [xSP + xS*3] 1526 1803 xchg xAX, xSI … … 1559 1836 1560 1837 ; standard stuff... 1561 fld dword REF(.r32V1)1562 fld qword REF(.r64V1)1563 fld tword REF(.r80V1)1564 fld qword REF(.r64V1)1565 fld dword REF(.r32V2)1566 fld dword REF(.r32V1)1838 fld dword [REF(g_r32V1)] 1839 fld qword [REF(g_r64V1)] 1840 fld tword [REF(g_r80V1)] 1841 fld qword [REF(g_r64V1)] 1842 fld dword [REF(g_r32V2)] 1843 fld dword [REF(g_r32V1)] 1567 1844 1568 1845 ; Test the nop check. … … 1767 2044 ret 1768 2045 1769 .r32V1: dd 3.21770 .r32V2: dd -1.91771 .r64V1: dq 6.41772 .r80V1: dt 8.01773 1774 ; Denormal numbers.1775 .r32D0: dd 0200000h1776 1777 2046 ENDPROC x861_Test5 1778 2047 … … 1788 2057 1789 2058 ; Load some pointers. 1790 lea xSI, REF(.r32V1)1791 mov xDI, REF_GLOBAL(g_pbEfExecPage)2059 lea xSI, [REF(g_r32V1)] 2060 mov xDI, [REF_EXTERN(g_pbEfExecPage)] 1792 2061 add xDI, PAGE_SIZE ; invalid page. 1793 2062 … … 1799 2068 mov dword [xSP], X86_FCW_PC_64 | X86_FCW_RC_NEAREST 1800 2069 fldcw [xSP] 1801 FpuShouldTrap X86_FSW_DE, 0, fld dword REF(.r32D0)2070 FpuShouldTrap X86_FSW_DE, 0, fld dword [REF(g_r32D0)] 1802 2071 CheckSt0Value 0x00000000, 0x80000000, 0x3f7f 1803 2072 1804 2073 mov dword [xSP], X86_FCW_PC_64 | X86_FCW_RC_NEAREST | X86_FCW_DM 1805 2074 fldcw [xSP] 1806 fld dword REF(.r32D0)2075 fld dword [REF(g_r32D0)] 1807 2076 fwait 1808 2077 FpuCheckFSW X86_FSW_DE, 0 … … 1815 2084 mov dword [xSP], X86_FCW_PC_64 | X86_FCW_RC_NEAREST 1816 2085 fldcw [xSP] 1817 fld qword REF(.r64V1)2086 fld qword [REF(g_r64V1)] 1818 2087 fld dword [xSI] 1819 2088 fld dword [xSI] … … 1822 2091 fld dword [xSI] 1823 2092 fld dword [xSI] 1824 fld tword REF(.r80V1)2093 fld tword [REF(g_r80V1)] 1825 2094 fwait 1826 2095 … … 1854 2123 CheckSt0Value 0x00000000, 0xc0000000, 0xffff 1855 2124 1856 fld qword REF(.r64V1)2125 fld qword [REF(g_r64V1)] 1857 2126 FpuCheckFSW X86_FSW_IE | X86_FSW_SF | X86_FSW_C1, X86_FSW_C0 | X86_FSW_C2 | X86_FSW_C3 1858 2127 fnclex … … 1860 2129 1861 2130 ; This is includes denormal values. 1862 fld dword REF(.r32D0)2131 fld dword [REF(g_r32D0)] 1863 2132 fwait 1864 2133 FpuCheckFSW X86_FSW_IE | X86_FSW_SF | X86_FSW_C1, X86_FSW_C0 | X86_FSW_C2 | X86_FSW_C3 … … 1872 2141 mov dword [xSP], X86_FCW_PC_64 | X86_FCW_RC_NEAREST 1873 2142 fldcw [xSP] 1874 fld qword REF(.r64V1)2143 fld qword [REF(g_r64V1)] 1875 2144 ShouldTrap X86_XCPT_MF, fld dword [xDI] 1876 2145 fnclex … … 1900 2169 SAVE_ALL_EPILOGUE 1901 2170 ret 1902 1903 .r32V1: dd 3.21904 .r64V1: dq 6.41905 .r80V1: dt 8.01906 1907 ; Denormal numbers.1908 .r32D0: dd 0200000h1909 1910 2171 ENDPROC x861_Test6 2172 2173 2174 extern NAME(RTTestISub) 2175 2176 ;; 2177 ; Sets the current subtest. 2178 %macro SetSubTest 1 2179 %ifdef RT_ARCH_AMD64 2180 %ifdef ASM_CALL64_GCC 2181 lea rdi, [%%s_szName wrt rip] 2182 %else 2183 lea rcx, [%%s_szName wrt rip] 2184 %endif 2185 call NAME(RTTestISub) 2186 %else 2187 push %%s_szName 2188 call NAME(RTTestISub) 2189 add esp, 4 2190 %endif 2191 jmp %%done 2192 %%s_szName: 2193 db %1, 0 2194 %%done: 2195 %endmacro 2196 2197 2198 ;; 2199 ; Checks the opcode and CS:IP FPU. 2200 ; 2201 ; @returns ZF=1 on success, ZF=0 on failure. 2202 ; @param xSP + xS fxsave image followed by fnstenv. 2203 ; @param xCX Opcode address (no prefixes). 2204 ; 2205 CheckOpcodeCsIp: 2206 push xBP 2207 mov xBP, xSP 2208 push xAX 2209 2210 ; Check the IP. 2211 %ifdef RT_ARCH_AMD64 2212 cmp rcx, [xBP + xS*2 + X86FXSTATE.FPUIP] 2213 %else 2214 cmp ecx, [xBP + xS*2 + X86FXSTATE.FPUIP] 2215 %endif 2216 jne .failure1 2217 2218 mov ax, cs 2219 cmp ax, [xBP + xS*2 + 512 + X86FSTENV32P.FPUCS] 2220 jne .failure2 2221 2222 ; Check the opcode. This may be disabled. 2223 cmp word [xBP + xS*2 + X86FXSTATE.FOP], 0 2224 je .success 2225 2226 mov ah, [xCX] 2227 mov al, [xCX + 1] 2228 and ax, 07ffh 2229 cmp ax, [xBP + xS*2 + X86FXSTATE.FOP] 2230 jne .failure3 2231 2232 .success: 2233 xor eax, eax ; clear Z 2234 .return: 2235 pop xAX 2236 leave 2237 ret 2238 2239 .failure1: 2240 mov eax, 10000000 2241 jmp .failure 2242 .failure2: 2243 mov eax, 20000000 2244 jmp .failure 2245 .failure3: 2246 mov eax, 30000000 2247 jmp .failure 2248 .failure: 2249 or eax, eax 2250 leave 2251 ret 2252 2253 2254 2255 2256 2257 ;; 2258 ; Checks the opcode, CS:IP and DS:DP of the FPU. 2259 ; 2260 ; @returns ZF=1 on success, ZF=0+EAX on failure. 2261 ; @param xSP + xS fxsave image followed by fnstenv. 2262 ; @param xCX Opcode address (no prefixes). 2263 ; @param xDX Memory address (DS relative). 2264 ; 2265 CheckOpcodeCsIpDsDp: 2266 push xBP 2267 mov xBP, xSP 2268 push xAX 2269 2270 ; Check the memory operand. 2271 %ifdef RT_ARCH_AMD64 2272 cmp rdx, [xBP + xS*2 + X86FXSTATE.FPUDP] 2273 %else 2274 cmp edx, [xBP + xS*2 + X86FXSTATE.FPUDP] 2275 %endif 2276 jne .failure1 2277 2278 mov ax, ds 2279 cmp ax, [xBP + xS*2 + 512 + X86FSTENV32P.FPUDS] 2280 jne .failure2 2281 2282 .success: 2283 pop xAX 2284 leave 2285 ; Let CheckOpcodeCsIp to the rest. 2286 jmp CheckOpcodeCsIp 2287 2288 .failure1: 2289 mov eax, 60000000 2290 jmp .failure 2291 .failure2: 2292 mov eax, 80000000 2293 .failure: 2294 or eax, eax 2295 leave 2296 ret 2297 2298 2299 ;; 2300 ; Checks a FPU instruction taking a memory operand. 2301 ; 2302 ; @uses xCX, xDX, xAX, Stack. 2303 ; 2304 %macro FpuCheckOpcodeCsIpDsDp 2 2305 %%instruction: 2306 %1 2307 arch_fxsave [xSP] 2308 fnstenv [xSP + 512] ; for the selectors (64-bit) 2309 arch_fxrstor [xSP] ; fnstenv screws up the ES bit. 2310 lea xDX, %2 2311 lea xCX, [REF(%%instruction)] 2312 call CheckOpcodeCsIpDsDp 2313 jz %%ok 2314 or eax, __LINE__ 2315 jmp .return 2316 %%ok: 2317 %endmacro 2318 2319 2320 ;; 2321 ; Checks a trapping FPU instruction taking a memory operand. 2322 ; 2323 ; Upon return, there is are two FXSAVE image on the stack at xSP. 2324 ; 2325 ; @uses xCX, xDX, xAX, Stack. 2326 ; 2327 ; @param %1 The instruction. 2328 ; @param %2 Operand memory address (DS relative). 2329 ; 2330 %macro FpuTrapOpcodeCsIpDsDp 2 2331 %%instruction: 2332 %1 2333 fxsave [xSP + 1024 +512] ; FPUDS and FPUCS for 64-bit hosts. 2334 ; WEIRD: When saved after FWAIT they are ZEROed! (64-bit Intel) 2335 %%trap: 2336 fwait 2337 %%trap_end: 2338 mov eax, __LINE__ 2339 jmp .return 2340 BEGINDATA 2341 %%trapinfo: istruc TRAPINFO 2342 at TRAPINFO.uTrapPC, RTCCPTR_DEF %%trap 2343 at TRAPINFO.uResumePC, RTCCPTR_DEF %%resume 2344 at TRAPINFO.u8TrapNo, db X86_XCPT_MF 2345 at TRAPINFO.cbInstr, db (%%trap_end - %%trap) 2346 iend 2347 BEGINCODE 2348 %%resume: 2349 arch_fxsave [xSP] 2350 lea xDX, %2 2351 lea xCX, [REF(%%instruction)] 2352 call CheckOpcodeCsIpDsDp 2353 jz %%ok 2354 or eax, __LINE__ 2355 jmp .return 2356 %%ok: 2357 %endmacro 2358 2359 2360 ;; 2361 ; Initialize the FPU and set CW to %1. 2362 ; 2363 ; @uses dword at [xSP]. 2364 ; 2365 %macro FpuInitWithCW 1 2366 call x861_LoadUniqueRegValuesSSE 2367 fninit 2368 mov dword [xSP], %1 2369 fldcw [xSP] 2370 %endmacro 2371 2372 2373 ;; 2374 ; First bunch of FPU instruction tests. 2375 ; 2376 ; 2377 BEGINPROC x861_TestFPUInstr1 2378 SAVE_ALL_PROLOGUE 2379 sub xSP, 2048 2380 2381 ; Make xBX (preserved accross calls) point to the invalid page. 2382 mov xBX, [REF_EXTERN(g_pbEfExecPage)] 2383 add xBX, PAGE_SIZE 2384 2385 ; 2386 ; FDIV with 64-bit floating point memory operand. 2387 ; 2388 SetSubTest "FDIV m64r" 2389 2390 ; ## Normal operation. ## 2391 fninit 2392 FpuCheckOpcodeCsIpDsDp { fld dword [REF(g_r32_3dot2)] }, [REF(g_r32_3dot2)] 2393 CheckSt0Value 0x00000000, 0xcccccd00, 0x4000 2394 FpuCheckOpcodeCsIpDsDp { fdiv qword [REF(g_r64_One)] }, [REF(g_r64_One)] 2395 FpuCheckFSW 0, X86_FSW_C0 | X86_FSW_C2 | X86_FSW_C3 2396 CheckSt0Value 0x00000000, 0xcccccd00, 0x4000 2397 2398 2399 ; ## Masked exceptions. ## 2400 ; Masked stack underflow. 2401 fninit 2402 FpuCheckOpcodeCsIpDsDp { fdiv qword [REF(g_r64_One)] }, [REF(g_r64_One)] 2403 FpuCheckFSW X86_FSW_IE | X86_FSW_SF, X86_FSW_C0 | X86_FSW_C2 | X86_FSW_C3 2404 CheckSt0Value_QNaN 2405 2406 ; Masked zero divide. 2407 fninit 2408 FpuCheckOpcodeCsIpDsDp { fld dword [REF(g_r32_3dot2)] }, [REF(g_r32_3dot2)] 2409 FpuCheckOpcodeCsIpDsDp { fdiv qword [REF(g_r64_Zero)] }, [REF(g_r64_Zero)] 2410 FpuCheckFSW X86_FSW_ZE, X86_FSW_C0 | X86_FSW_C2 | X86_FSW_C3 2411 CheckSt0Value_PlusInf 2412 2413 ; Masked Inf/Inf. 2414 fninit 2415 FpuCheckOpcodeCsIpDsDp { fld dword [REF(g_r32_Inf)] }, [REF(g_r32_Inf)] 2416 FpuCheckOpcodeCsIpDsDp { fdiv qword [REF(g_r64_Inf)] }, [REF(g_r64_Inf)] 2417 FpuCheckFSW X86_FSW_IE, X86_FSW_C0 | X86_FSW_C2 | X86_FSW_C3 2418 CheckSt0Value_QNaN 2419 2420 ; Masked 0/0. 2421 fninit 2422 FpuCheckOpcodeCsIpDsDp { fld dword [REF(g_r32_Zero)] }, [REF(g_r32_Zero)] 2423 FpuCheckOpcodeCsIpDsDp { fdiv qword [REF(g_r64_Zero)] }, [REF(g_r64_Zero)] 2424 FpuCheckFSW X86_FSW_IE, X86_FSW_C0 | X86_FSW_C2 | X86_FSW_C3 2425 CheckSt0Value_QNaN 2426 2427 ; Masked precision exception, rounded down. 2428 fninit 2429 FpuCheckOpcodeCsIpDsDp { fld dword [REF(g_r32_Ten)] }, [REF(g_r32_Ten)] 2430 FpuCheckOpcodeCsIpDsDp { fdiv qword [REF(g_r64_Three)] }, [REF(g_r64_Three)] 2431 FpuCheckFSW X86_FSW_PE, X86_FSW_C0 | X86_FSW_C2 | X86_FSW_C3 2432 CheckSt0Value_3_and_a_3rd 2433 2434 ; Masked precision exception, rounded up. 2435 fninit 2436 FpuCheckOpcodeCsIpDsDp { fld dword [REF(g_r32_Eleven)] }, [REF(g_r32_Eleven)] 2437 FpuCheckOpcodeCsIpDsDp { fdiv qword [REF(g_r64_Three)] }, [REF(g_r64_Three)] 2438 FpuCheckFSW X86_FSW_PE | X86_FSW_C1, X86_FSW_C0 | X86_FSW_C2 | X86_FSW_C3 2439 CheckSt0Value_3_and_two_3rds 2440 2441 ; Masked overflow exception. 2442 fninit 2443 FpuCheckOpcodeCsIpDsDp { fld tword [REF(g_r80_Max)] }, [REF(g_r80_Max)] 2444 FpuCheckOpcodeCsIpDsDp { fdiv qword [REF(g_r64_0dot1)] }, [REF(g_r64_0dot1)] 2445 FpuCheckFSW X86_FSW_PE | X86_FSW_OE | X86_FSW_C1, X86_FSW_C0 | X86_FSW_C2 | X86_FSW_C3 2446 CheckSt0Value_PlusInf 2447 2448 ; Masked underflow exception. 2449 fninit 2450 FpuCheckOpcodeCsIpDsDp { fld tword [REF(g_r80_Min)] }, [REF(g_r80_Min)] 2451 FpuCheckOpcodeCsIpDsDp { fdiv qword [REF(g_r64_Ten)] }, [REF(g_r64_Ten)] 2452 FpuCheckFSW X86_FSW_PE | X86_FSW_UE | X86_FSW_C1, X86_FSW_C0 | X86_FSW_C2 | X86_FSW_C3 2453 CheckSt0Value 0xcccccccd, 0x0ccccccc, 0x0000 2454 2455 ; Denormal operand. 2456 fninit 2457 FpuCheckOpcodeCsIpDsDp { fld tword [REF(g_r80_One)] }, [REF(g_r80_One)] 2458 FpuCheckOpcodeCsIpDsDp { fdiv qword [REF(g_r64_DnMax)] }, [REF(g_r64_DnMax)] 2459 FxSaveCheckFSW xSP, X86_FSW_DE | X86_FSW_PE, X86_FSW_C0 | X86_FSW_C2 | X86_FSW_C3 2460 FxSaveCheckSt0Value xSP, 0x00000800, 0x80000000, 0x43fd 2461 2462 ; ## Unmasked exceptions. ## 2463 %if 1 2464 ; Stack underflow - TOP and ST0 unmodified. 2465 FpuInitWithCW X86_FCW_PC_64 | X86_FCW_RC_NEAREST 2466 FpuTrapOpcodeCsIpDsDp { fdiv qword [REF(g_r64_One)] }, [REF(g_r64_One)] 2467 FxSaveCheckFSW xSP, X86_FSW_IE | X86_FSW_SF | X86_FSW_B | X86_FSW_ES, X86_FSW_C0 | X86_FSW_C2 | X86_FSW_C3 2468 FxSaveCheckSt0EmptyInitValue xSP 2469 2470 ; Zero divide - Unmodified ST0. 2471 FpuInitWithCW X86_FCW_PC_64 | X86_FCW_RC_NEAREST 2472 FpuCheckOpcodeCsIpDsDp { fld dword [REF(g_r32_3dot2)] }, [REF(g_r32_3dot2)] 2473 FpuTrapOpcodeCsIpDsDp { fdiv qword [REF(g_r64_Zero)] }, [REF(g_r64_Zero)] 2474 FxSaveCheckFSW xSP, X86_FSW_ZE | X86_FSW_ES | X86_FSW_B, X86_FSW_C0 | X86_FSW_C2 | X86_FSW_C3 2475 FxSaveCheckSt0ValueConst xSP, REF(g_r80_r32_3dot2) 2476 2477 ; Invalid Operand (Inf/Inf) - Unmodified ST0. 2478 FpuInitWithCW X86_FCW_PC_64 | X86_FCW_RC_NEAREST 2479 FpuCheckOpcodeCsIpDsDp { fld dword [REF(g_r32_Inf)] }, [REF(g_r32_Inf)] 2480 FpuTrapOpcodeCsIpDsDp { fdiv qword [REF(g_r64_Inf)] }, [REF(g_r64_Inf)] 2481 FpuCheckFSW X86_FSW_IE | X86_FSW_ES | X86_FSW_B, X86_FSW_C0 | X86_FSW_C2 | X86_FSW_C3 2482 FxSaveCheckSt0ValueConst xSP, REF(g_r80_Inf) 2483 2484 ; Invalid Operand (0/0) - Unmodified ST0. 2485 FpuInitWithCW X86_FCW_PC_64 | X86_FCW_RC_NEAREST 2486 FpuCheckOpcodeCsIpDsDp { fld dword [REF(g_r32_Zero)] }, [REF(g_r32_Zero)] 2487 FpuTrapOpcodeCsIpDsDp { fdiv qword [REF(g_r64_Zero)] }, [REF(g_r64_Zero)] 2488 FxSaveCheckFSW xSP, X86_FSW_IE | X86_FSW_ES | X86_FSW_B, X86_FSW_C0 | X86_FSW_C2 | X86_FSW_C3 2489 FxSaveCheckSt0ValueConst xSP, REF(g_r80_Zero) 2490 2491 ; Precision exception, rounded down. 2492 FpuInitWithCW X86_FCW_PC_64 | X86_FCW_RC_NEAREST 2493 FpuCheckOpcodeCsIpDsDp { fld dword [REF(g_r32_Ten)] }, [REF(g_r32_Ten)] 2494 FpuTrapOpcodeCsIpDsDp { fdiv qword [REF(g_r64_Three)] }, [REF(g_r64_Three)] 2495 FxSaveCheckFSW xSP, X86_FSW_PE | X86_FSW_ES | X86_FSW_B, X86_FSW_C0 | X86_FSW_C2 | X86_FSW_C3 2496 FxSaveCheckSt0Value_3_and_a_3rd(xSP) 2497 2498 ; Precision exception, rounded up. 2499 FpuInitWithCW X86_FCW_PC_64 | X86_FCW_RC_NEAREST 2500 FpuCheckOpcodeCsIpDsDp { fld dword [REF(g_r32_Eleven)] }, [REF(g_r32_Eleven)] 2501 FpuTrapOpcodeCsIpDsDp { fdiv qword [REF(g_r64_Three)] }, [REF(g_r64_Three)] 2502 FxSaveCheckFSW xSP, X86_FSW_PE | X86_FSW_C1 | X86_FSW_ES | X86_FSW_B, X86_FSW_C0 | X86_FSW_C2 | X86_FSW_C3 2503 FxSaveCheckSt0Value_3_and_two_3rds(xSP) 2504 2505 ; Overflow exception. 2506 FpuInitWithCW X86_FCW_PC_64 | X86_FCW_RC_NEAREST 2507 FpuCheckOpcodeCsIpDsDp { fld tword [REF(g_r80_Max)] }, [REF(g_r80_Max)] 2508 FpuTrapOpcodeCsIpDsDp { fdiv qword [REF(g_r64_0dot1)] }, [REF(g_r64_0dot1)] 2509 FxSaveCheckFSW xSP, X86_FSW_PE | X86_FSW_OE | X86_FSW_ES | X86_FSW_B, X86_FSW_C0 | X86_FSW_C2 | X86_FSW_C3 2510 FxSaveCheckSt0Value xSP, 0xfffffd7f, 0x9fffffff, 0x2002 2511 2512 ; Underflow exception. 2513 FpuInitWithCW X86_FCW_PC_64 | X86_FCW_RC_NEAREST 2514 FpuCheckOpcodeCsIpDsDp { fld tword [REF(g_r80_Min)] }, [REF(g_r80_Min)] 2515 FpuTrapOpcodeCsIpDsDp { fdiv qword [REF(g_r64_Ten)] }, [REF(g_r64_Ten)] 2516 FxSaveCheckFSW xSP, X86_FSW_PE | X86_FSW_UE | X86_FSW_C1 | X86_FSW_ES | X86_FSW_B, X86_FSW_C0 | X86_FSW_C2 | X86_FSW_C3 2517 FxSaveCheckSt0Value xSP, 0xcccccccd, 0xcccccccc, 0x5ffd 2518 2519 ; Denormal operand - Unmodified ST0. 2520 FpuInitWithCW X86_FCW_PC_64 | X86_FCW_RC_NEAREST 2521 FpuCheckOpcodeCsIpDsDp { fld tword [REF(g_r80_One)] }, [REF(g_r80_One)] 2522 FpuTrapOpcodeCsIpDsDp { fdiv qword [REF(g_r64_DnMax)] }, [REF(g_r64_DnMax)] 2523 FxSaveCheckFSW xSP, X86_FSW_DE | X86_FSW_ES | X86_FSW_B, X86_FSW_C0 | X86_FSW_C2 | X86_FSW_C3 2524 FxSaveCheckSt0ValueConst xSP, REF(g_r80_One) 2525 %endif 2526 2527 2528 ; ## A couple of variations on the #PF theme. ## 2529 2530 .success: 2531 xor eax, eax 2532 .return: 2533 add xSP, 2048 2534 SAVE_ALL_EPILOGUE 2535 ret 2536 2537 ENDPROC x861_TestFPUInstr1 2538 2539 1911 2540 1912 2541
Note:
See TracChangeset
for help on using the changeset viewer.