MCPcopy Create free account
hub / github.com/FEX-Emu/FEX / BranchTargetInMultiblockRange

Method BranchTargetInMultiblockRange

FEXCore/Source/Interface/Core/Frontend.cpp:1068–1146  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

1066}
1067
1068void Decoder::BranchTargetInMultiblockRange() {
1069 if (!CTX->Config.Multiblock) {
1070 return;
1071 }
1072
1073 // If the RIP setting is conditional AND within our symbol range then it can be considered for multiblock
1074 uint64_t TargetRIP = 0;
1075 const auto GPRSize = GetGPROpSize();
1076 bool Conditional = true;
1077 const auto InstEnd = DecodeInst->PC + DecodeInst->InstSize;
1078
1079 if (DecodeInst->TableInfo->Flags & FEXCore::X86Tables::InstFlags::FLAGS_CALL) {
1080 if (ExecutableRangeWritable && CTX->AreMonoHacksActive()) {
1081 // Mono generated code often contains noreturn calls with garbage following them, and calls are always backpatched
1082 // after CIL compilation leading to n recompiles for a multiblock with n calls. Choose to minimize stutters over
1083 // raw performance and disable tracking past calls for mono generated code.
1084 return;
1085 }
1086
1087 AddBranchTarget(InstEnd);
1088 BlockInfo.EntryPoints.emplace(InstEnd);
1089 return;
1090 }
1091
1092 // Calls are handled above
1093 switch (DecodeInst->OP) {
1094 case 0x70 ... 0x7F: // Conditional JUMP
1095 case 0x80 ... 0x8F: { // More conditional
1096 // Source is a literal
1097 // auto RIPOffset = LoadSource(Op, Op->Src[0], Op->Flags);
1098 // auto RIPTargetConst = Constant(Op->PC + Op->InstSize);
1099 // Target offset is PC + InstSize + Literal
1100 TargetRIP = InstEnd + DecodeInst->Src[0].Literal();
1101 break;
1102 }
1103 case 0xE9:
1104 case 0xEB: // Both are unconditional JMP instructions
1105 TargetRIP = InstEnd + DecodeInst->Src[0].Literal();
1106 Conditional = false;
1107 break;
1108 case 0xC2: // RET imm
1109 case 0xC3: // RET
1110 default: return; break;
1111 }
1112
1113 if (GPRSize == IR::OpSize::i32Bit) {
1114 // If we are running a 32bit guest then wrap around addresses that go above 32bit
1115 TargetRIP &= 0xFFFFFFFFU;
1116 }
1117
1118 if (Conditional) {
1119 // If we are conditional then a target can be the instruction past the conditional instruction
1120 AddBranchTarget(InstEnd);
1121 }
1122
1123 // If the target RIP is x86 code within the symbol ranges then we are golden
1124 // Forbid distant branches to have the cost code better match the guest code layout, avoiding massive (range-wise) code
1125 // blocks in highly fragmented guest code. Such branches are often not-taken branches to garbage in obfuscated code.

Callers

nothing calls this directly

Calls 3

AreMonoHacksActiveMethod · 0.80
emplaceMethod · 0.80
LiteralMethod · 0.80

Tested by

no test coverage detected