Skip to content

Commit 3280a7c

Browse files
Add support for placing midasm hooks after instructions.
1 parent 87e3509 commit 3280a7c

3 files changed

Lines changed: 73 additions & 62 deletions

File tree

XenonRecomp/recompiler.cpp

Lines changed: 69 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -333,84 +333,88 @@ bool Recompiler::Recompile(
333333
};
334334

335335
auto midAsmHook = config.midAsmHooks.find(base);
336-
if (midAsmHook != config.midAsmHooks.end())
337-
{
338-
bool returnsBool = midAsmHook->second.returnOnFalse || midAsmHook->second.returnOnTrue ||
339-
midAsmHook->second.jumpAddressOnFalse != NULL || midAsmHook->second.jumpAddressOnTrue != NULL;
340-
341-
print("\t");
342-
if (returnsBool)
343-
print("if (");
344336

345-
print("{}(", midAsmHook->second.name);
346-
for (auto& reg : midAsmHook->second.registers)
337+
auto printMidAsmHook = [&]()
347338
{
348-
if (out.back() != '(')
349-
out += ", ";
339+
bool returnsBool = midAsmHook->second.returnOnFalse || midAsmHook->second.returnOnTrue ||
340+
midAsmHook->second.jumpAddressOnFalse != NULL || midAsmHook->second.jumpAddressOnTrue != NULL;
350341

351-
switch (reg[0])
342+
print("\t");
343+
if (returnsBool)
344+
print("if (");
345+
346+
print("{}(", midAsmHook->second.name);
347+
for (auto& reg : midAsmHook->second.registers)
352348
{
353-
case 'c':
354-
if (reg == "ctr")
355-
out += ctr();
356-
else
357-
out += cr(std::atoi(reg.c_str() + 2));
358-
break;
349+
if (out.back() != '(')
350+
out += ", ";
351+
352+
switch (reg[0])
353+
{
354+
case 'c':
355+
if (reg == "ctr")
356+
out += ctr();
357+
else
358+
out += cr(std::atoi(reg.c_str() + 2));
359+
break;
359360

360-
case 'x':
361-
out += xer();
362-
break;
361+
case 'x':
362+
out += xer();
363+
break;
363364

364-
case 'r':
365-
if (reg == "reserved")
366-
out += reserved();
367-
else
368-
out += r(std::atoi(reg.c_str() + 1));
369-
break;
365+
case 'r':
366+
if (reg == "reserved")
367+
out += reserved();
368+
else
369+
out += r(std::atoi(reg.c_str() + 1));
370+
break;
370371

371-
case 'f':
372-
if (reg == "fpscr")
373-
out += "ctx.fpscr";
374-
else
375-
out += f(std::atoi(reg.c_str() + 1));
376-
break;
372+
case 'f':
373+
if (reg == "fpscr")
374+
out += "ctx.fpscr";
375+
else
376+
out += f(std::atoi(reg.c_str() + 1));
377+
break;
377378

378-
case 'v':
379-
out += v(std::atoi(reg.c_str() + 1));
380-
break;
379+
case 'v':
380+
out += v(std::atoi(reg.c_str() + 1));
381+
break;
382+
}
381383
}
382-
}
383384

384-
if (returnsBool)
385-
{
386-
println(")) {{");
385+
if (returnsBool)
386+
{
387+
println(")) {{");
387388

388-
if (midAsmHook->second.returnOnTrue)
389-
println("\t\treturn;");
390-
else if (midAsmHook->second.jumpAddressOnTrue != NULL)
391-
println("\t\tgoto loc_{:X};", midAsmHook->second.jumpAddressOnTrue);
389+
if (midAsmHook->second.returnOnTrue)
390+
println("\t\treturn;");
391+
else if (midAsmHook->second.jumpAddressOnTrue != NULL)
392+
println("\t\tgoto loc_{:X};", midAsmHook->second.jumpAddressOnTrue);
392393

393-
println("\t}}");
394+
println("\t}}");
394395

395-
println("\telse {{");
396+
println("\telse {{");
396397

397-
if (midAsmHook->second.returnOnFalse)
398-
println("\t\treturn;");
399-
else if (midAsmHook->second.jumpAddressOnFalse != NULL)
400-
println("\t\tgoto loc_{:X};", midAsmHook->second.jumpAddressOnFalse);
398+
if (midAsmHook->second.returnOnFalse)
399+
println("\t\treturn;");
400+
else if (midAsmHook->second.jumpAddressOnFalse != NULL)
401+
println("\t\tgoto loc_{:X};", midAsmHook->second.jumpAddressOnFalse);
401402

402-
println("\t}}");
403-
}
404-
else
405-
{
406-
println(");");
403+
println("\t}}");
404+
}
405+
else
406+
{
407+
println(");");
407408

408-
if (midAsmHook->second.ret)
409-
println("\treturn;");
410-
else if (midAsmHook->second.jumpAddress != NULL)
411-
println("\tgoto loc_{:X};", midAsmHook->second.jumpAddress);
412-
}
413-
}
409+
if (midAsmHook->second.ret)
410+
println("\treturn;");
411+
else if (midAsmHook->second.jumpAddress != NULL)
412+
println("\tgoto loc_{:X};", midAsmHook->second.jumpAddress);
413+
}
414+
};
415+
416+
if (midAsmHook != config.midAsmHooks.end() && !midAsmHook->second.afterInstruction)
417+
printMidAsmHook();
414418

415419
int id = insn.opcode->id;
416420

@@ -2148,6 +2152,9 @@ bool Recompiler::Recompile(
21482152
fmt::println("{} at {:X} has RC bit enabled but no comparison was generated", insn.opcode->name, base);
21492153
}
21502154
#endif
2155+
2156+
if (midAsmHook != config.midAsmHooks.end() && midAsmHook->second.afterInstruction)
2157+
printMidAsmHook();
21512158

21522159
return true;
21532160
}

XenonRecomp/recompiler_config.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,8 @@ void RecompilerConfig::Load(const std::string_view& configFilePath)
118118
fmt::println("{}: can't mix direct and conditional return/jump", midAsmHook.name);
119119
}
120120

121+
midAsmHook.afterInstruction = table["after_instruction"].value_or(false);
122+
121123
midAsmHooks.emplace(*table["address"].value<uint32_t>(), std::move(midAsmHook));
122124
}
123125
}

XenonRecomp/recompiler_config.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ struct RecompilerMidAsmHook
1818
uint32_t jumpAddress = 0;
1919
uint32_t jumpAddressOnTrue = 0;
2020
uint32_t jumpAddressOnFalse = 0;
21+
22+
bool afterInstruction = false;
2123
};
2224

2325
struct RecompilerConfig

0 commit comments

Comments
 (0)