mirror of
				https://github.com/N64Recomp/N64Recomp.git
				synced 2025-10-30 08:02:11 +00:00 
			
		
		
		
	Split Negate operation into NegateFloat and NegateDouble, added support for custom recompiler backends
This commit is contained in:
		
							parent
							
								
									c54855b05d
								
							
						
					
					
						commit
						485a9e14c9
					
				
					 6 changed files with 28 additions and 35 deletions
				
			
		|  | @ -517,8 +517,10 @@ namespace N64Recomp { | |||
|         } | ||||
|     }; | ||||
| 
 | ||||
|     bool recompile_function(const Context& context, const Function& func, std::ofstream& output_file, std::span<std::vector<uint32_t>> static_funcs, bool tag_reference_relocs); | ||||
|     bool recompile_function_luajit(const Context& context, const Function& func, std::ofstream& output_file, std::span<std::vector<uint32_t>> static_funcs, bool tag_reference_relocs); | ||||
|     class Generator; | ||||
|     bool recompile_function(const Context& context, const Function& func, std::ostream& output_file, std::span<std::vector<uint32_t>> static_funcs, bool tag_reference_relocs); | ||||
|     bool recompile_function_luajit(const Context& context, const Function& func, std::ostream& output_file, std::span<std::vector<uint32_t>> static_funcs, bool tag_reference_relocs); | ||||
|     bool recompile_function_custom(Generator& generator, const Context& context, const Function& func, std::ostream& output_file, std::span<std::vector<uint32_t>> static_funcs_out, bool tag_reference_relocs); | ||||
| 
 | ||||
|     enum class ModSymbolsError { | ||||
|         Good, | ||||
|  |  | |||
|  | @ -28,13 +28,12 @@ namespace N64Recomp { | |||
|         ToU32, | ||||
|         ToS64, | ||||
|         ToU64, | ||||
|         NegateS32, | ||||
|         NegateS64, | ||||
|         Lui, | ||||
|         Mask5, // Mask to 5 bits
 | ||||
|         Mask6, // Mask to 5 bits
 | ||||
|         ToInt32, // Functionally equivalent to ToS32, only exists for parity with old codegen
 | ||||
|         Negate, | ||||
|         NegateFloat, | ||||
|         NegateDouble, | ||||
|         AbsFloat, | ||||
|         AbsDouble, | ||||
|         SqrtFloat, | ||||
|  |  | |||
|  | @ -223,12 +223,6 @@ void N64Recomp::CGenerator::get_operand_string(Operand operand, UnaryOpType oper | |||
|         case UnaryOpType::ToU64: | ||||
|             // Nothing to do here, they're already U64
 | ||||
|             break; | ||||
|         case UnaryOpType::NegateS32: | ||||
|             assert(false); | ||||
|             break; | ||||
|         case UnaryOpType::NegateS64: | ||||
|             assert(false); | ||||
|             break; | ||||
|         case UnaryOpType::Lui: | ||||
|             operand_string = "S32(" + operand_string + " << 16)";  | ||||
|             break; | ||||
|  | @ -241,7 +235,10 @@ void N64Recomp::CGenerator::get_operand_string(Operand operand, UnaryOpType oper | |||
|         case UnaryOpType::ToInt32: | ||||
|             operand_string = "(int32_t)" + operand_string;  | ||||
|             break; | ||||
|         case UnaryOpType::Negate: | ||||
|         case UnaryOpType::NegateFloat: | ||||
|             operand_string = "-" + operand_string; | ||||
|             break; | ||||
|         case UnaryOpType::NegateDouble: | ||||
|             operand_string = "-" + operand_string; | ||||
|             break; | ||||
|         case UnaryOpType::AbsFloat: | ||||
|  |  | |||
|  | @ -224,12 +224,6 @@ void N64Recomp::LuajitGenerator::get_operand_string(Operand operand, UnaryOpType | |||
|         case UnaryOpType::ToU64: | ||||
|             // Nothing to do here, they're already U64
 | ||||
|             break; | ||||
|         case UnaryOpType::NegateS32: | ||||
|             assert(false); | ||||
|             break; | ||||
|         case UnaryOpType::NegateS64: | ||||
|             assert(false); | ||||
|             break; | ||||
|         case UnaryOpType::Lui: | ||||
|             operand_string = "S32(bit.lshift(" + operand_string + "), 16ULL)";  | ||||
|             break; | ||||
|  | @ -239,7 +233,10 @@ void N64Recomp::LuajitGenerator::get_operand_string(Operand operand, UnaryOpType | |||
|         case UnaryOpType::Mask6: | ||||
|             operand_string = "(bit.band(" + operand_string + "), 63ULL)"; | ||||
|             break; | ||||
|         case UnaryOpType::Negate: | ||||
|         case UnaryOpType::NegateFloat: | ||||
|             operand_string = "-" + operand_string; | ||||
|             break; | ||||
|         case UnaryOpType::NegateDouble: | ||||
|             operand_string = "-" + operand_string; | ||||
|             break; | ||||
|         case UnaryOpType::AbsFloat: | ||||
|  |  | |||
|  | @ -12,8 +12,8 @@ namespace N64Recomp { | |||
|         // Float operations
 | ||||
|         { InstrId::cpu_mov_s,     { UnaryOpType::None,           Operand::Fd,       Operand::Fs,       true } }, | ||||
|         { InstrId::cpu_mov_d,     { UnaryOpType::None,           Operand::FdDouble, Operand::FsDouble, true } }, | ||||
|         { InstrId::cpu_neg_s,     { UnaryOpType::Negate,         Operand::Fd,       Operand::Fs,       true, true } }, | ||||
|         { InstrId::cpu_neg_d,     { UnaryOpType::Negate,         Operand::FdDouble, Operand::FsDouble, true, true } }, | ||||
|         { InstrId::cpu_neg_s,     { UnaryOpType::NegateFloat,    Operand::Fd,       Operand::Fs,       true, true } }, | ||||
|         { InstrId::cpu_neg_d,     { UnaryOpType::NegateDouble,   Operand::FdDouble, Operand::FsDouble, true, true } }, | ||||
|         { InstrId::cpu_abs_s,     { UnaryOpType::AbsFloat,       Operand::Fd,       Operand::Fs,       true, true } }, | ||||
|         { InstrId::cpu_abs_d,     { UnaryOpType::AbsDouble,      Operand::FdDouble, Operand::FsDouble, true, true } }, | ||||
|         { InstrId::cpu_sqrt_s,    { UnaryOpType::SqrtFloat,      Operand::Fd,       Operand::Fs,       true, true } }, | ||||
|  |  | |||
|  | @ -110,7 +110,7 @@ std::string_view ctx_gpr_prefix(int reg) { | |||
| } | ||||
| 
 | ||||
| template <typename GeneratorType> | ||||
| bool process_instruction(GeneratorType& generator, const N64Recomp::Context& context, const N64Recomp::Function& func, const N64Recomp::FunctionStats& stats, const std::unordered_set<uint32_t>& skipped_insns, size_t instr_index, const std::vector<rabbitizer::InstructionCpu>& instructions, std::ofstream& output_file, bool indent, bool emit_link_branch, int link_branch_index, size_t reloc_index, bool& needs_link_branch, bool& is_branch_likely, bool tag_reference_relocs, std::span<std::vector<uint32_t>> static_funcs_out) { | ||||
| bool process_instruction(GeneratorType& generator, const N64Recomp::Context& context, const N64Recomp::Function& func, const N64Recomp::FunctionStats& stats, const std::unordered_set<uint32_t>& skipped_insns, size_t instr_index, const std::vector<rabbitizer::InstructionCpu>& instructions, std::ostream& output_file, bool indent, bool emit_link_branch, int link_branch_index, size_t reloc_index, bool& needs_link_branch, bool& is_branch_likely, bool tag_reference_relocs, std::span<std::vector<uint32_t>> static_funcs_out) { | ||||
|     using namespace N64Recomp; | ||||
| 
 | ||||
|     const auto& section = context.sections[func.section_index]; | ||||
|  | @ -260,16 +260,6 @@ bool process_instruction(GeneratorType& generator, const N64Recomp::Context& con | |||
|         return true; | ||||
|     }; | ||||
| 
 | ||||
|     auto print_func_call_lookup = [&](uint32_t target_vram) { | ||||
|         if (!process_delay_slot(false)) { | ||||
|             return false; | ||||
|         } | ||||
|         print_indent(); | ||||
|         generator.emit_function_call_lookup(target_vram); | ||||
|         print_link_branch(); | ||||
|         return true; | ||||
|     }; | ||||
| 
 | ||||
|     auto print_func_call_by_address = [&generator, reloc_target_section_offset, reloc_section, reloc_reference_symbol, reloc_type, &context, §ion, &func, &static_funcs_out, &needs_link_branch, &print_indent, &process_delay_slot, &output_file, &print_link_branch] | ||||
|         (uint32_t target_func_vram, bool tail_call = false, bool indent = false) | ||||
|     { | ||||
|  | @ -364,6 +354,7 @@ bool process_instruction(GeneratorType& generator, const N64Recomp::Context& con | |||
|                 } | ||||
|                 print_indent(); | ||||
|                 generator.emit_return(); | ||||
|                 // TODO check if this branch close should exist.
 | ||||
|                 print_indent(); | ||||
|                 generator.emit_branch_close(); | ||||
|                 return true; | ||||
|  | @ -379,6 +370,7 @@ bool process_instruction(GeneratorType& generator, const N64Recomp::Context& con | |||
|         print_indent(); | ||||
|         print_indent(); | ||||
|         generator.emit_goto(fmt::format("L_{:08X}", branch_target)); | ||||
|         // TODO check if this link branch ever exists.
 | ||||
|         if (needs_link_branch) { | ||||
|             print_indent(); | ||||
|             print_indent(); | ||||
|  | @ -704,6 +696,8 @@ bool process_instruction(GeneratorType& generator, const N64Recomp::Context& con | |||
|     auto find_conditional_branch_it = conditional_branch_ops.find(instr.getUniqueId()); | ||||
|     if (find_conditional_branch_it != conditional_branch_ops.end()) { | ||||
|         print_indent(); | ||||
|         // TODO combining the branch condition and branch target into one generator call would allow better optimization in the runtime's JIT generator.
 | ||||
|         // This would require splitting into a conditional jump method and conditional function call method.
 | ||||
|         generator.emit_branch_condition(find_conditional_branch_it->second, instruction_context); | ||||
| 
 | ||||
|         print_indent(); | ||||
|  | @ -753,7 +747,7 @@ bool process_instruction(GeneratorType& generator, const N64Recomp::Context& con | |||
| } | ||||
| 
 | ||||
| template <typename GeneratorType> | ||||
| bool recompile_function_impl(GeneratorType& generator, const N64Recomp::Context& context, const N64Recomp::Function& func, std::ofstream& output_file, std::span<std::vector<uint32_t>> static_funcs_out, bool tag_reference_relocs) { | ||||
| bool recompile_function_impl(GeneratorType& generator, const N64Recomp::Context& context, const N64Recomp::Function& func, std::ostream& output_file, std::span<std::vector<uint32_t>> static_funcs_out, bool tag_reference_relocs) { | ||||
|     //fmt::print("Recompiling {}\n", func.name);
 | ||||
|     std::vector<rabbitizer::InstructionCpu> instructions; | ||||
| 
 | ||||
|  | @ -859,12 +853,16 @@ bool recompile_function_impl(GeneratorType& generator, const N64Recomp::Context& | |||
| } | ||||
| 
 | ||||
| // Wrap the templated function with CGenerator as the template parameter.
 | ||||
| bool N64Recomp::recompile_function(const N64Recomp::Context& context, const N64Recomp::Function& func, std::ofstream& output_file, std::span<std::vector<uint32_t>> static_funcs_out, bool tag_reference_relocs) { | ||||
| bool N64Recomp::recompile_function(const N64Recomp::Context& context, const N64Recomp::Function& func, std::ostream& output_file, std::span<std::vector<uint32_t>> static_funcs_out, bool tag_reference_relocs) { | ||||
|     CGenerator generator{output_file}; | ||||
|     return recompile_function_impl(generator, context, func, output_file, static_funcs_out, tag_reference_relocs); | ||||
| } | ||||
| 
 | ||||
| bool N64Recomp::recompile_function_luajit(const N64Recomp::Context& context, const N64Recomp::Function& func, std::ofstream& output_file, std::span<std::vector<uint32_t>> static_funcs_out, bool tag_reference_relocs) { | ||||
| bool N64Recomp::recompile_function_luajit(const N64Recomp::Context& context, const N64Recomp::Function& func, std::ostream& output_file, std::span<std::vector<uint32_t>> static_funcs_out, bool tag_reference_relocs) { | ||||
|     LuajitGenerator generator{output_file}; | ||||
|     return recompile_function_impl(generator, context, func, output_file, static_funcs_out, tag_reference_relocs); | ||||
| } | ||||
| 
 | ||||
| bool N64Recomp::recompile_function_custom(Generator& generator, const Context& context, const Function& func, std::ostream& output_file, std::span<std::vector<uint32_t>> static_funcs_out, bool tag_reference_relocs) { | ||||
|     return recompile_function_impl(generator, context, func, output_file, static_funcs_out, tag_reference_relocs); | ||||
| } | ||||
|  |  | |||
		Loading…
	
	Add table
		
		Reference in a new issue
	
	 Mr-Wiseguy
						Mr-Wiseguy