| 939 | } |
| 940 | |
| 941 | void OpDispatchBuilder::JUMPFARIndirectOp(OpcodeArgs) { |
| 942 | // Calculate flags early. |
| 943 | CalculateDeferredFlags(); |
| 944 | |
| 945 | BlockSetRIP = true; |
| 946 | // This is just an unconditional jump |
| 947 | // This uses ModRM to determine its location |
| 948 | // No way to use this effectively in multiblock |
| 949 | Ref Src = MakeSegmentAddress(Op, Op->Dest); |
| 950 | AddressMode SrcCS = {.Base = Src, .Offset = 4, .AddrSize = OpSize::i64Bit}; |
| 951 | auto RIPOffset = _LoadMemAutoTSO(GPRClass, OpSize::i32Bit, Src, OpSize::i8Bit); |
| 952 | auto NewSegmentCS = _LoadMemAutoTSO(GPRClass, OpSize::i16Bit, SrcCS, OpSize::i8Bit); |
| 953 | |
| 954 | // Set up the new CSSegment. |
| 955 | _StoreContext(OpSize::i16Bit, GPRClass, NewSegmentCS, offsetof(FEXCore::Core::CPUState, cs_idx)); |
| 956 | UpdatePrefixFromSegment(NewSegmentCS, FEXCore::X86Tables::DecodeFlags::FLAG_CS_PREFIX); |
| 957 | |
| 958 | // Store the new RIP |
| 959 | ExitFunction(RIPOffset); |
| 960 | } |
| 961 | |
| 962 | void OpDispatchBuilder::CALLFARIndirectOp(OpcodeArgs) { |
| 963 | const auto SrcSize = Op->Flags & FEXCore::X86Tables::DecodeFlags::FLAG_REX_WIDENING ? OpSize::i64Bit : OpSize::i32Bit; |
nothing calls this directly
no outgoing calls
no test coverage detected