diff --git a/XenonRecomp/recompiler.cpp b/XenonRecomp/recompiler.cpp index b42c6ce..04d8dae 100644 --- a/XenonRecomp/recompiler.cpp +++ b/XenonRecomp/recompiler.cpp @@ -333,84 +333,88 @@ bool Recompiler::Recompile( }; auto midAsmHook = config.midAsmHooks.find(base); - if (midAsmHook != config.midAsmHooks.end()) - { - bool returnsBool = midAsmHook->second.returnOnFalse || midAsmHook->second.returnOnTrue || - midAsmHook->second.jumpAddressOnFalse != NULL || midAsmHook->second.jumpAddressOnTrue != NULL; - print("\t"); - if (returnsBool) - print("if ("); - - print("{}(", midAsmHook->second.name); - for (auto& reg : midAsmHook->second.registers) + auto printMidAsmHook = [&]() { - if (out.back() != '(') - out += ", "; + bool returnsBool = midAsmHook->second.returnOnFalse || midAsmHook->second.returnOnTrue || + midAsmHook->second.jumpAddressOnFalse != NULL || midAsmHook->second.jumpAddressOnTrue != NULL; - switch (reg[0]) + print("\t"); + if (returnsBool) + print("if ("); + + print("{}(", midAsmHook->second.name); + for (auto& reg : midAsmHook->second.registers) { - case 'c': - if (reg == "ctr") - out += ctr(); - else - out += cr(std::atoi(reg.c_str() + 2)); - break; + if (out.back() != '(') + out += ", "; - case 'x': - out += xer(); - break; + switch (reg[0]) + { + case 'c': + if (reg == "ctr") + out += ctr(); + else + out += cr(std::atoi(reg.c_str() + 2)); + break; - case 'r': - if (reg == "reserved") - out += reserved(); - else - out += r(std::atoi(reg.c_str() + 1)); - break; + case 'x': + out += xer(); + break; - case 'f': - if (reg == "fpscr") - out += "ctx.fpscr"; - else - out += f(std::atoi(reg.c_str() + 1)); - break; + case 'r': + if (reg == "reserved") + out += reserved(); + else + out += r(std::atoi(reg.c_str() + 1)); + break; - case 'v': - out += v(std::atoi(reg.c_str() + 1)); - break; + case 'f': + if (reg == "fpscr") + out += "ctx.fpscr"; + else + out += f(std::atoi(reg.c_str() + 1)); + break; + + case 'v': + out += v(std::atoi(reg.c_str() + 1)); + break; + } } - } - if (returnsBool) - { - println(")) {{"); + if (returnsBool) + { + println(")) {{"); - if (midAsmHook->second.returnOnTrue) - println("\t\treturn;"); - else if (midAsmHook->second.jumpAddressOnTrue != NULL) - println("\t\tgoto loc_{:X};", midAsmHook->second.jumpAddressOnTrue); + if (midAsmHook->second.returnOnTrue) + println("\t\treturn;"); + else if (midAsmHook->second.jumpAddressOnTrue != NULL) + println("\t\tgoto loc_{:X};", midAsmHook->second.jumpAddressOnTrue); - println("\t}}"); + println("\t}}"); - println("\telse {{"); + println("\telse {{"); - if (midAsmHook->second.returnOnFalse) - println("\t\treturn;"); - else if (midAsmHook->second.jumpAddressOnFalse != NULL) - println("\t\tgoto loc_{:X};", midAsmHook->second.jumpAddressOnFalse); + if (midAsmHook->second.returnOnFalse) + println("\t\treturn;"); + else if (midAsmHook->second.jumpAddressOnFalse != NULL) + println("\t\tgoto loc_{:X};", midAsmHook->second.jumpAddressOnFalse); - println("\t}}"); - } - else - { - println(");"); + println("\t}}"); + } + else + { + println(");"); - if (midAsmHook->second.ret) - println("\treturn;"); - else if (midAsmHook->second.jumpAddress != NULL) - println("\tgoto loc_{:X};", midAsmHook->second.jumpAddress); - } - } + if (midAsmHook->second.ret) + println("\treturn;"); + else if (midAsmHook->second.jumpAddress != NULL) + println("\tgoto loc_{:X};", midAsmHook->second.jumpAddress); + } + }; + + if (midAsmHook != config.midAsmHooks.end() && !midAsmHook->second.afterInstruction) + printMidAsmHook(); int id = insn.opcode->id; @@ -2148,6 +2152,9 @@ bool Recompiler::Recompile( fmt::println("{} at {:X} has RC bit enabled but no comparison was generated", insn.opcode->name, base); } #endif + + if (midAsmHook != config.midAsmHooks.end() && midAsmHook->second.afterInstruction) + printMidAsmHook(); return true; } diff --git a/XenonRecomp/recompiler_config.cpp b/XenonRecomp/recompiler_config.cpp index 31f6a8d..e558f29 100644 --- a/XenonRecomp/recompiler_config.cpp +++ b/XenonRecomp/recompiler_config.cpp @@ -118,6 +118,8 @@ void RecompilerConfig::Load(const std::string_view& configFilePath) fmt::println("{}: can't mix direct and conditional return/jump", midAsmHook.name); } + midAsmHook.afterInstruction = table["after_instruction"].value_or(false); + midAsmHooks.emplace(*table["address"].value(), std::move(midAsmHook)); } } diff --git a/XenonRecomp/recompiler_config.h b/XenonRecomp/recompiler_config.h index e20936e..ee61ed9 100644 --- a/XenonRecomp/recompiler_config.h +++ b/XenonRecomp/recompiler_config.h @@ -18,6 +18,8 @@ struct RecompilerMidAsmHook uint32_t jumpAddress = 0; uint32_t jumpAddressOnTrue = 0; uint32_t jumpAddressOnFalse = 0; + + bool afterInstruction = false; }; struct RecompilerConfig