stack contains: Size of each member is 64-bit, 32-bit, or 16-bit depending on operating size RIP CS EFLAGS RSP SS */
| 187 | SS |
| 188 | */ |
| 189 | void OpDispatchBuilder::IRETOp(OpcodeArgs) { |
| 190 | // Operand Size override unsupported! |
| 191 | if ((Op->Flags & X86Tables::DecodeFlags::FLAG_OPERAND_SIZE) != 0) { |
| 192 | LogMan::Msg::EFmt("IRET only implemented for 64bit and 32bit sizes"); |
| 193 | DecodeFailure = true; |
| 194 | return; |
| 195 | } |
| 196 | |
| 197 | const auto GPRSize = GetGPROpSize(); |
| 198 | |
| 199 | Ref SP = _RMWHandle(LoadGPRRegister(X86State::REG_RSP)); |
| 200 | |
| 201 | // RIP (64/32/16 bits) |
| 202 | auto NewRIP = Pop(GPRSize, SP); |
| 203 | // CS (lower 16 used) |
| 204 | auto NewSegmentCS = Pop(GPRSize, SP); |
| 205 | _StoreContext(OpSize::i16Bit, GPRClass, NewSegmentCS, offsetof(FEXCore::Core::CPUState, cs_idx)); |
| 206 | UpdatePrefixFromSegment(NewSegmentCS, FEXCore::X86Tables::DecodeFlags::FLAG_CS_PREFIX); |
| 207 | |
| 208 | // eflags (lower 16 used) |
| 209 | SetPackedRFLAG(false, Pop(GPRSize, SP)); |
| 210 | |
| 211 | if (Is64BitMode) { |
| 212 | // RSP and SS only happen in 64-bit mode or if this is a CPL mode jump! |
| 213 | // FEX doesn't support a CPL mode switch, so don't need to worry about this on 32-bit |
| 214 | StoreGPRRegister(X86State::REG_RSP, Pop(GPRSize, SP)); |
| 215 | |
| 216 | // ss |
| 217 | auto NewSegmentSS = Pop(GPRSize, SP); |
| 218 | _StoreContext(OpSize::i16Bit, GPRClass, NewSegmentSS, offsetof(FEXCore::Core::CPUState, ss_idx)); |
| 219 | UpdatePrefixFromSegment(NewSegmentSS, FEXCore::X86Tables::DecodeFlags::FLAG_SS_PREFIX); |
| 220 | } else { |
| 221 | // Store the stack in 32-bit mode |
| 222 | StoreGPRRegister(X86State::REG_RSP, SP); |
| 223 | } |
| 224 | |
| 225 | ExitFunction(NewRIP); |
| 226 | BlockSetRIP = true; |
| 227 | } |
| 228 | |
| 229 | void OpDispatchBuilder::CallbackReturnOp(OpcodeArgs) { |
| 230 | const auto GPRSize = GetGPROpSize(); |