| 960 | } |
| 961 | |
| 962 | void OpDispatchBuilder::CALLFARIndirectOp(OpcodeArgs) { |
| 963 | const auto SrcSize = Op->Flags & FEXCore::X86Tables::DecodeFlags::FLAG_REX_WIDENING ? OpSize::i64Bit : OpSize::i32Bit; |
| 964 | |
| 965 | // Calculate flags early. |
| 966 | CalculateDeferredFlags(); |
| 967 | |
| 968 | BlockSetRIP = true; |
| 969 | |
| 970 | Ref Src = MakeSegmentAddress(Op, Op->Dest); |
| 971 | AddressMode SrcCS = {.Base = Src, .Offset = 4, .AddrSize = OpSize::i64Bit}; |
| 972 | auto RIPOffset = _LoadMemAutoTSO(GPRClass, OpSize::i32Bit, Src, OpSize::i8Bit); |
| 973 | auto NewSegmentCS = _LoadMemAutoTSO(GPRClass, OpSize::i16Bit, SrcCS, OpSize::i8Bit); |
| 974 | auto CurrentCS = _LoadContext(OpSize::i16Bit, GPRClass, offsetof(FEXCore::Core::CPUState, cs_idx)); |
| 975 | |
| 976 | auto NewRIP = GetRelocatedPC(Op); |
| 977 | |
| 978 | // Push the current CS |
| 979 | Push(SrcSize, CurrentCS); |
| 980 | |
| 981 | // Push the return address. |
| 982 | Push(SrcSize, NewRIP); |
| 983 | |
| 984 | // Set up the new CSSegment. |
| 985 | _StoreContext(OpSize::i16Bit, GPRClass, NewSegmentCS, offsetof(FEXCore::Core::CPUState, cs_idx)); |
| 986 | UpdatePrefixFromSegment(NewSegmentCS, FEXCore::X86Tables::DecodeFlags::FLAG_CS_PREFIX); |
| 987 | |
| 988 | // Store the new RIP |
| 989 | ExitFunction(RIPOffset); |
| 990 | } |
| 991 | |
| 992 | void OpDispatchBuilder::RETFARIndirectOp(OpcodeArgs) { |
| 993 | const auto GPRSize = GetGPROpSize(); |
nothing calls this directly
no outgoing calls
no test coverage detected