| 249 | } |
| 250 | |
| 251 | void StoreWowContextFromState(FEXCore::Core::InternalThreadState* Thread, WOW64_CONTEXT* Context) { |
| 252 | auto& State = Thread->CurrentFrame->State; |
| 253 | |
| 254 | // General register state |
| 255 | |
| 256 | Context->Eax = State.gregs[FEXCore::X86State::REG_RAX]; |
| 257 | Context->Ebx = State.gregs[FEXCore::X86State::REG_RBX]; |
| 258 | Context->Ecx = State.gregs[FEXCore::X86State::REG_RCX]; |
| 259 | Context->Edx = State.gregs[FEXCore::X86State::REG_RDX]; |
| 260 | Context->Esi = State.gregs[FEXCore::X86State::REG_RSI]; |
| 261 | Context->Edi = State.gregs[FEXCore::X86State::REG_RDI]; |
| 262 | Context->Ebp = State.gregs[FEXCore::X86State::REG_RBP]; |
| 263 | Context->Esp = State.gregs[FEXCore::X86State::REG_RSP]; |
| 264 | |
| 265 | Context->Eip = State.rip; |
| 266 | Context->EFlags = CTX->ReconstructCompactedEFLAGS(Thread, false, nullptr, 0); |
| 267 | |
| 268 | Context->SegEs = State.es_idx; |
| 269 | Context->SegCs = State.cs_idx; |
| 270 | Context->SegSs = State.ss_idx; |
| 271 | Context->SegDs = State.ds_idx; |
| 272 | Context->SegFs = State.fs_idx; |
| 273 | Context->SegGs = State.gs_idx; |
| 274 | |
| 275 | // Floating-point register state |
| 276 | |
| 277 | auto* XSave = reinterpret_cast<XSAVE_FORMAT*>(Context->ExtendedRegisters); |
| 278 | |
| 279 | CTX->ReconstructXMMRegisters(Thread, reinterpret_cast<__uint128_t*>(XSave->XmmRegisters), nullptr); |
| 280 | memcpy(XSave->FloatRegisters, State.mm, sizeof(State.mm)); |
| 281 | |
| 282 | XSave->ControlWord = State.FCW; |
| 283 | XSave->StatusWord = (State.flags[FEXCore::X86State::X87FLAG_TOP_LOC] << 11) | (State.flags[FEXCore::X86State::X87FLAG_C0_LOC] << 8) | |
| 284 | (State.flags[FEXCore::X86State::X87FLAG_C1_LOC] << 9) | (State.flags[FEXCore::X86State::X87FLAG_C2_LOC] << 10) | |
| 285 | (State.flags[FEXCore::X86State::X87FLAG_C3_LOC] << 14) | State.flags[FEXCore::X86State::X87FLAG_IE_LOC]; |
| 286 | XSave->TagWord = State.AbridgedFTW; |
| 287 | |
| 288 | Context->FloatSave.ControlWord = XSave->ControlWord; |
| 289 | Context->FloatSave.StatusWord = XSave->StatusWord; |
| 290 | Context->FloatSave.TagWord = FEXCore::FPState::ConvertFromAbridgedFTW(XSave->StatusWord, State.mm, XSave->TagWord); |
| 291 | Context->FloatSave.ErrorOffset = XSave->ErrorOffset; |
| 292 | Context->FloatSave.ErrorSelector = XSave->ErrorSelector | (XSave->ErrorOpcode << 16); |
| 293 | Context->FloatSave.DataOffset = XSave->DataOffset; |
| 294 | Context->FloatSave.DataSelector = XSave->DataSelector; |
| 295 | Context->FloatSave.Cr0NpxState = XSave->StatusWord | 0xffff0000; |
| 296 | } |
| 297 | |
| 298 | NTSTATUS FlushThreadStateContext(HANDLE Thread) { |
| 299 | const auto [Err, TLS] = GetThreadTLS(Thread); |
no test coverage detected