MCPcopy Create free account
hub / github.com/FEX-Emu/FEX / StoreStateToPackedECContext

Function StoreStateToPackedECContext

Source/Windows/ARM64EC/Module.cpp:460–526  ·  view source on GitHub ↗

Reconstructs an x64 context from the input thread's state, packed into a regular ARM64 context following the ARM64EC register mapping

Source from the content-addressed store, hash-verified

458
459// Reconstructs an x64 context from the input thread's state, packed into a regular ARM64 context following the ARM64EC register mapping
460static ARM64_NT_CONTEXT StoreStateToPackedECContext(FEXCore::Core::InternalThreadState* Thread, uint32_t FPCR, uint32_t FPSR) {
461 ARM64_NT_CONTEXT ECContext {};
462
463 ECContext.ContextFlags = CONTEXT_ARM64_FULL;
464 if (CPUFeatures->IsFeaturePresent(PF_AVX2_INSTRUCTIONS_AVAILABLE)) {
465 // This is a FEX extension and requires corresponding wine-side patches to be of use, however it is harmless to set
466 // even if those patches are not used.
467 ECContext.ContextFlags |= CONTEXT_ARM64_FEX_YMMSTATE;
468 }
469
470 auto& State = Thread->CurrentFrame->State;
471
472 ECContext.X8 = State.gregs[FEXCore::X86State::REG_RAX];
473 ECContext.X0 = State.gregs[FEXCore::X86State::REG_RCX];
474 ECContext.X1 = State.gregs[FEXCore::X86State::REG_RDX];
475 ECContext.X27 = State.gregs[FEXCore::X86State::REG_RBX];
476 ECContext.Sp = State.gregs[FEXCore::X86State::REG_RSP];
477 ECContext.Fp = State.gregs[FEXCore::X86State::REG_RBP];
478 ECContext.X25 = State.gregs[FEXCore::X86State::REG_RSI];
479 ECContext.X26 = State.gregs[FEXCore::X86State::REG_RDI];
480 ECContext.X2 = State.gregs[FEXCore::X86State::REG_R8];
481 ECContext.X3 = State.gregs[FEXCore::X86State::REG_R9];
482 ECContext.X4 = State.gregs[FEXCore::X86State::REG_R10];
483 ECContext.X5 = State.gregs[FEXCore::X86State::REG_R11];
484 ECContext.X19 = State.gregs[FEXCore::X86State::REG_R12];
485 ECContext.X20 = State.gregs[FEXCore::X86State::REG_R13];
486 ECContext.X21 = State.gregs[FEXCore::X86State::REG_R14];
487 ECContext.X22 = State.gregs[FEXCore::X86State::REG_R15];
488
489 ECContext.Pc = State.rip;
490
491 CTX->ReconstructXMMRegisters(Thread, reinterpret_cast<__uint128_t*>(&ECContext.V[0]), reinterpret_cast<__uint128_t*>(&ECContext.V[16]));
492
493 ECContext.Lr = State.mm[0][0];
494 ECContext.X6 = State.mm[1][0];
495 ECContext.X7 = State.mm[2][0];
496 ECContext.X9 = State.mm[3][0];
497 ECContext.X16 = (State.mm[3][1] & 0xffff) << 48 | (State.mm[2][1] & 0xffff) << 32 | (State.mm[1][1] & 0xffff) << 16 | (State.mm[0][1] & 0xffff);
498 ECContext.X10 = State.mm[4][0];
499 ECContext.X11 = State.mm[5][0];
500 ECContext.X12 = State.mm[6][0];
501 ECContext.X15 = State.mm[7][0];
502 ECContext.X17 = (State.mm[7][1] & 0xffff) << 48 | (State.mm[6][1] & 0xffff) << 32 | (State.mm[5][1] & 0xffff) << 16 | (State.mm[4][1] & 0xffff);
503
504 // Zero all disallowed registers
505 ECContext.X13 = 0;
506 ECContext.X14 = 0;
507 ECContext.X18 = 0;
508 ECContext.X23 = 0;
509 ECContext.X24 = 0;
510 ECContext.X28 = 0;
511
512 // NZCV+SS will be converted into EFlags by ntdll, the rest are lost during exception handling.
513 // See HandleGuestException
514 uint32_t EFlags = CTX->ReconstructCompactedEFLAGS(Thread, false, nullptr, 0);
515 ECContext.Cpsr = 0;
516 ECContext.Cpsr |= (EFlags & (1U << FEXCore::X86State::RFLAG_TF_RAW_LOC)) ? (1U << 21) : 0;
517 ECContext.Cpsr |= (EFlags & (1U << FEXCore::X86State::RFLAG_OF_RAW_LOC)) ? (1U << 28) : 0;

Callers 3

RethrowGuestExceptionFunction · 0.85
HandleSyscallMethod · 0.85

Calls 3

IsFeaturePresentMethod · 0.80

Tested by

no test coverage detected