| 199 | |
| 200 | namespace Context { |
| 201 | void LoadStateFromWowContext(FEXCore::Core::InternalThreadState* Thread, uint64_t WowTEB, WOW64_CONTEXT* Context) { |
| 202 | auto& State = Thread->CurrentFrame->State; |
| 203 | |
| 204 | // General register state |
| 205 | |
| 206 | State.gregs[FEXCore::X86State::REG_RAX] = Context->Eax; |
| 207 | State.gregs[FEXCore::X86State::REG_RBX] = Context->Ebx; |
| 208 | State.gregs[FEXCore::X86State::REG_RCX] = Context->Ecx; |
| 209 | State.gregs[FEXCore::X86State::REG_RDX] = Context->Edx; |
| 210 | State.gregs[FEXCore::X86State::REG_RSI] = Context->Esi; |
| 211 | State.gregs[FEXCore::X86State::REG_RDI] = Context->Edi; |
| 212 | State.gregs[FEXCore::X86State::REG_RBP] = Context->Ebp; |
| 213 | State.gregs[FEXCore::X86State::REG_RSP] = Context->Esp; |
| 214 | |
| 215 | State.rip = Context->Eip; |
| 216 | CTX->SetFlagsFromCompactedEFLAGS(Thread, Context->EFlags); |
| 217 | |
| 218 | State.es_idx = Context->SegEs & 0xffff; |
| 219 | State.cs_idx = Context->SegCs & 0xffff; |
| 220 | State.ss_idx = Context->SegSs & 0xffff; |
| 221 | State.ds_idx = Context->SegDs & 0xffff; |
| 222 | State.fs_idx = Context->SegFs & 0xffff; |
| 223 | State.gs_idx = Context->SegGs & 0xffff; |
| 224 | |
| 225 | // The TEB is the only populated GDT entry by default |
| 226 | auto GDT = State.GetSegmentFromIndex(State, (Context->SegFs & 0xffff)); |
| 227 | State.SetGDTBase(GDT, WowTEB); |
| 228 | State.SetGDTLimit(GDT, 0xF'FFFFU); |
| 229 | State.fs_cached = WowTEB; |
| 230 | State.es_cached = 0; |
| 231 | State.cs_cached = 0; |
| 232 | State.ss_cached = 0; |
| 233 | State.ds_cached = 0; |
| 234 | |
| 235 | // Floating-point register state |
| 236 | const auto* XSave = reinterpret_cast<XSAVE_FORMAT*>(Context->ExtendedRegisters); |
| 237 | |
| 238 | CTX->SetXMMRegistersFromState(Thread, reinterpret_cast<const __uint128_t*>(XSave->XmmRegisters), nullptr); |
| 239 | memcpy(State.mm, XSave->FloatRegisters, sizeof(State.mm)); |
| 240 | |
| 241 | State.FCW = XSave->ControlWord; |
| 242 | State.flags[FEXCore::X86State::X87FLAG_IE_LOC] = XSave->StatusWord & 1; |
| 243 | State.flags[FEXCore::X86State::X87FLAG_C0_LOC] = (XSave->StatusWord >> 8) & 1; |
| 244 | State.flags[FEXCore::X86State::X87FLAG_C1_LOC] = (XSave->StatusWord >> 9) & 1; |
| 245 | State.flags[FEXCore::X86State::X87FLAG_C2_LOC] = (XSave->StatusWord >> 10) & 1; |
| 246 | State.flags[FEXCore::X86State::X87FLAG_C3_LOC] = (XSave->StatusWord >> 14) & 1; |
| 247 | State.flags[FEXCore::X86State::X87FLAG_TOP_LOC] = (XSave->StatusWord >> 11) & 0b111; |
| 248 | State.AbridgedFTW = XSave->TagWord; |
| 249 | } |
| 250 | |
| 251 | void StoreWowContextFromState(FEXCore::Core::InternalThreadState* Thread, WOW64_CONTEXT* Context) { |
| 252 | auto& State = Thread->CurrentFrame->State; |
no test coverage detected