mirror of
				https://github.com/hedge-dev/XenonRecomp.git
				synced 2025-11-04 06:47:09 +00:00 
			
		
		
		
	Add support for placing midasm hooks after instructions.
This commit is contained in:
		@@ -333,84 +333,88 @@ bool Recompiler::Recompile(
 | 
				
			|||||||
        };
 | 
					        };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    auto midAsmHook = config.midAsmHooks.find(base);
 | 
					    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");
 | 
					    auto printMidAsmHook = [&]()
 | 
				
			||||||
        if (returnsBool)
 | 
					 | 
				
			||||||
            print("if (");
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        print("{}(", midAsmHook->second.name);
 | 
					 | 
				
			||||||
        for (auto& reg : midAsmHook->second.registers)
 | 
					 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            if (out.back() != '(')
 | 
					            bool returnsBool = midAsmHook->second.returnOnFalse || midAsmHook->second.returnOnTrue ||
 | 
				
			||||||
                out += ", ";
 | 
					                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 (out.back() != '(')
 | 
				
			||||||
                if (reg == "ctr")
 | 
					                    out += ", ";
 | 
				
			||||||
                    out += ctr();
 | 
					 | 
				
			||||||
                else
 | 
					 | 
				
			||||||
                    out += cr(std::atoi(reg.c_str() + 2));
 | 
					 | 
				
			||||||
                break;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
            case 'x':
 | 
					                switch (reg[0])
 | 
				
			||||||
                out += xer();
 | 
					                {
 | 
				
			||||||
                break;
 | 
					                case 'c':
 | 
				
			||||||
 | 
					                    if (reg == "ctr")
 | 
				
			||||||
 | 
					                        out += ctr();
 | 
				
			||||||
 | 
					                    else
 | 
				
			||||||
 | 
					                        out += cr(std::atoi(reg.c_str() + 2));
 | 
				
			||||||
 | 
					                    break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            case 'r':
 | 
					                case 'x':
 | 
				
			||||||
                if (reg == "reserved")
 | 
					                    out += xer();
 | 
				
			||||||
                    out += reserved();
 | 
					                    break;
 | 
				
			||||||
                else
 | 
					 | 
				
			||||||
                    out += r(std::atoi(reg.c_str() + 1));
 | 
					 | 
				
			||||||
                break;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
            case 'f':
 | 
					                case 'r':
 | 
				
			||||||
                if (reg == "fpscr")
 | 
					                    if (reg == "reserved")
 | 
				
			||||||
                    out += "ctx.fpscr";
 | 
					                        out += reserved();
 | 
				
			||||||
                else
 | 
					                    else
 | 
				
			||||||
                    out += f(std::atoi(reg.c_str() + 1));
 | 
					                        out += r(std::atoi(reg.c_str() + 1));
 | 
				
			||||||
                break;
 | 
					                    break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            case 'v':
 | 
					                case 'f':
 | 
				
			||||||
                out += v(std::atoi(reg.c_str() + 1));
 | 
					                    if (reg == "fpscr")
 | 
				
			||||||
                break;
 | 
					                        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)
 | 
					            if (returnsBool)
 | 
				
			||||||
        {
 | 
					            {
 | 
				
			||||||
            println(")) {{");
 | 
					                println(")) {{");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if (midAsmHook->second.returnOnTrue)
 | 
					                if (midAsmHook->second.returnOnTrue)
 | 
				
			||||||
                println("\t\treturn;");
 | 
					                    println("\t\treturn;");
 | 
				
			||||||
            else if (midAsmHook->second.jumpAddressOnTrue != NULL)
 | 
					                else if (midAsmHook->second.jumpAddressOnTrue != NULL)
 | 
				
			||||||
                println("\t\tgoto loc_{:X};", midAsmHook->second.jumpAddressOnTrue);
 | 
					                    println("\t\tgoto loc_{:X};", midAsmHook->second.jumpAddressOnTrue);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            println("\t}}");
 | 
					                println("\t}}");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            println("\telse {{");
 | 
					                println("\telse {{");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if (midAsmHook->second.returnOnFalse)
 | 
					                if (midAsmHook->second.returnOnFalse)
 | 
				
			||||||
                println("\t\treturn;");
 | 
					                    println("\t\treturn;");
 | 
				
			||||||
            else if (midAsmHook->second.jumpAddressOnFalse != NULL)
 | 
					                else if (midAsmHook->second.jumpAddressOnFalse != NULL)
 | 
				
			||||||
                println("\t\tgoto loc_{:X};", midAsmHook->second.jumpAddressOnFalse);
 | 
					                    println("\t\tgoto loc_{:X};", midAsmHook->second.jumpAddressOnFalse);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            println("\t}}");
 | 
					                println("\t}}");
 | 
				
			||||||
        }
 | 
					            }
 | 
				
			||||||
        else
 | 
					            else
 | 
				
			||||||
        {
 | 
					            {
 | 
				
			||||||
            println(");");
 | 
					                println(");");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if (midAsmHook->second.ret)
 | 
					                if (midAsmHook->second.ret)
 | 
				
			||||||
                println("\treturn;");
 | 
					                    println("\treturn;");
 | 
				
			||||||
            else if (midAsmHook->second.jumpAddress != NULL)
 | 
					                else if (midAsmHook->second.jumpAddress != NULL)
 | 
				
			||||||
                println("\tgoto loc_{:X};", midAsmHook->second.jumpAddress);
 | 
					                    println("\tgoto loc_{:X};", midAsmHook->second.jumpAddress);
 | 
				
			||||||
        }
 | 
					            }
 | 
				
			||||||
    }
 | 
					        };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (midAsmHook != config.midAsmHooks.end() && !midAsmHook->second.afterInstruction)
 | 
				
			||||||
 | 
					        printMidAsmHook();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    int id = insn.opcode->id;
 | 
					    int id = insn.opcode->id;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -2149,6 +2153,9 @@ bool Recompiler::Recompile(
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (midAsmHook != config.midAsmHooks.end() && midAsmHook->second.afterInstruction)
 | 
				
			||||||
 | 
					        printMidAsmHook();
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
    return true;
 | 
					    return true;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -118,6 +118,8 @@ void RecompilerConfig::Load(const std::string_view& configFilePath)
 | 
				
			|||||||
                fmt::println("{}: can't mix direct and conditional return/jump", midAsmHook.name);
 | 
					                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<uint32_t>(), std::move(midAsmHook));
 | 
					            midAsmHooks.emplace(*table["address"].value<uint32_t>(), std::move(midAsmHook));
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -18,6 +18,8 @@ struct RecompilerMidAsmHook
 | 
				
			|||||||
    uint32_t jumpAddress = 0;
 | 
					    uint32_t jumpAddress = 0;
 | 
				
			||||||
    uint32_t jumpAddressOnTrue = 0;
 | 
					    uint32_t jumpAddressOnTrue = 0;
 | 
				
			||||||
    uint32_t jumpAddressOnFalse = 0;
 | 
					    uint32_t jumpAddressOnFalse = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    bool afterInstruction = false;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct RecompilerConfig
 | 
					struct RecompilerConfig
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user