Add LuajitGenerator class

This commit is contained in:
Mr-Wiseguy 2024-09-29 01:02:46 -04:00
parent 46ab6f758d
commit ef319b1aad
5 changed files with 189 additions and 2 deletions

View file

@ -82,6 +82,7 @@ target_sources(N64Recomp PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}/src/analysis.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/analysis.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/operations.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/operations.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/cgenerator.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/cgenerator.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/luajitgenerator.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/recompilation.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/recompilation.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/mod_symbols.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/mod_symbols.cpp
) )

View file

@ -97,6 +97,42 @@ namespace N64Recomp {
void get_binary_expr_string(BinaryOpType type, const BinaryOperands& operands, const InstructionContext& ctx, const std::string& output, std::string& expr_string) const; void get_binary_expr_string(BinaryOpType type, const BinaryOperands& operands, const InstructionContext& ctx, const std::string& output, std::string& expr_string) const;
void get_notation(BinaryOpType op_type, std::string& func_string, std::string& infix_string) const; void get_notation(BinaryOpType op_type, std::string& func_string, std::string& infix_string) const;
}; };
class LuajitGenerator final : Generator {
public:
LuajitGenerator() = default;
void process_binary_op(std::ostream& output_file, const BinaryOp& op, const InstructionContext& ctx) const final;
void process_unary_op(std::ostream& output_file, const UnaryOp& op, const InstructionContext& ctx) const final;
void process_store_op(std::ostream& output_file, const StoreOp& op, const InstructionContext& ctx) const final;
void emit_function_start(std::ostream& output_file, const std::string& function_name) const final;
void emit_function_end(std::ostream& output_file) const final;
void emit_function_call_lookup(std::ostream& output_file, uint32_t addr) const final;
void emit_function_call_by_register(std::ostream& output_file, int reg) const final;
void emit_function_call_by_name(std::ostream& output_file, const std::string& func_name) const final;
void emit_goto(std::ostream& output_file, const std::string& target) const final;
void emit_label(std::ostream& output_file, const std::string& label_name) const final;
void emit_variable_declaration(std::ostream& output_file, const std::string& var_name, int reg) const final;
void emit_branch_condition(std::ostream& output_file, const ConditionalBranchOp& op, const InstructionContext& ctx) const final;
void emit_branch_close(std::ostream& output_file) const final;
void emit_switch(std::ostream& output_file, const std::string& jump_variable, int shift_amount) const final;
void emit_case(std::ostream& output_file, int case_index, const std::string& target_label) const final;
void emit_switch_error(std::ostream& output_file, uint32_t instr_vram, uint32_t jtbl_vram) const final;
void emit_switch_close(std::ostream& output_file) const final;
void emit_return(std::ostream& output_file) const final;
void emit_check_fr(std::ostream& output_file, int fpr) const final;
void emit_check_nan(std::ostream& output_file, int fpr, bool is_double) const final;
void emit_cop0_status_read(std::ostream& output_file, int reg) const final;
void emit_cop0_status_write(std::ostream& output_file, int reg) const final;
void emit_cop1_cs_read(std::ostream& output_file, int reg) const final;
void emit_cop1_cs_write(std::ostream& output_file, int reg) const final;
void emit_muldiv(std::ostream& output_file, InstrId instr_id, int reg1, int reg2) const final;
void emit_syscall(std::ostream& output_file, uint32_t instr_vram) const final;
void emit_do_break(std::ostream& output_file, uint32_t instr_vram) const final;
void emit_pause_self(std::ostream& output_file) const final;
void emit_trigger_event(std::ostream& output_file, size_t event_index) const final;
void emit_comment(std::ostream& output_file, const std::string& comment) const final;
private:
};
} }
#endif #endif

View file

@ -521,6 +521,7 @@ 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(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);
enum class ModSymbolsError { enum class ModSymbolsError {
Good, Good,

144
src/luajitgenerator.cpp Normal file
View file

@ -0,0 +1,144 @@
#include <cassert>
#include <fstream>
#include "fmt/format.h"
#include "fmt/ostream.h"
#include "generator.h"
void N64Recomp::LuajitGenerator::process_binary_op(std::ostream& output_file, const BinaryOp& op, const InstructionContext& ctx) const {
// TODO
fmt::print(output_file, "\n");
}
void N64Recomp::LuajitGenerator::process_unary_op(std::ostream& output_file, const UnaryOp& op, const InstructionContext& ctx) const {
// TODO
fmt::print(output_file, "\n");
}
void N64Recomp::LuajitGenerator::process_store_op(std::ostream& output_file, const StoreOp& op, const InstructionContext& ctx) const {
// TODO
fmt::print(output_file, "\n");
}
void N64Recomp::LuajitGenerator::emit_function_start(std::ostream& output_file, const std::string& function_name) const {
fmt::print(output_file, "function {}(rdram, ctx)\n", function_name);
}
void N64Recomp::LuajitGenerator::emit_function_end(std::ostream& output_file) const {
fmt::print(output_file, "end\n");
}
void N64Recomp::LuajitGenerator::emit_function_call_lookup(std::ostream& output_file, uint32_t addr) const {
// TODO
fmt::print(output_file, "\n");
}
void N64Recomp::LuajitGenerator::emit_function_call_by_register(std::ostream& output_file, int reg) const {
// TODO
fmt::print(output_file, "\n");
}
void N64Recomp::LuajitGenerator::emit_function_call_by_name(std::ostream& output_file, const std::string& func_name) const {
// TODO
fmt::print(output_file, "\n");
}
void N64Recomp::LuajitGenerator::emit_goto(std::ostream& output_file, const std::string& target) const {
fmt::print(output_file, "goto {}\n", target);
}
void N64Recomp::LuajitGenerator::emit_label(std::ostream& output_file, const std::string& label_name) const {
fmt::print(output_file, "::{}::\n", label_name);
}
void N64Recomp::LuajitGenerator::emit_variable_declaration(std::ostream& output_file, const std::string& var_name, int reg) const {
// TODO
fmt::print(output_file, "{} = 0\n", var_name);
}
void N64Recomp::LuajitGenerator::emit_branch_condition(std::ostream& output_file, const ConditionalBranchOp& op, const InstructionContext& ctx) const {
// TODO
fmt::print(output_file, "if (true) then\n");
}
void N64Recomp::LuajitGenerator::emit_branch_close(std::ostream& output_file) const {
fmt::print(output_file, "end\n");
}
void N64Recomp::LuajitGenerator::emit_switch(std::ostream& output_file, const std::string& jump_variable, int shift_amount) const {
fmt::print(output_file, "do local case_index = bit.rshift({}, {}ULL)\n", jump_variable, shift_amount);
}
void N64Recomp::LuajitGenerator::emit_case(std::ostream& output_file, int case_index, const std::string& target_label) const {
fmt::print(output_file, "if case_index == {} then goto {} end\n", case_index, target_label);
}
void N64Recomp::LuajitGenerator::emit_switch_error(std::ostream& output_file, uint32_t instr_vram, uint32_t jtbl_vram) const {
fmt::print(output_file, "switch_error(\'lua\', {:08X}, {:08X})\n", instr_vram, jtbl_vram);
}
void N64Recomp::LuajitGenerator::emit_switch_close(std::ostream& output_file) const {
fmt::print(output_file, "end\n");
}
void N64Recomp::LuajitGenerator::emit_return(std::ostream& output_file) const {
fmt::print(output_file, "return\n");
}
void N64Recomp::LuajitGenerator::emit_check_fr(std::ostream& output_file, int fpr) const {
// Not used
}
void N64Recomp::LuajitGenerator::emit_check_nan(std::ostream& output_file, int fpr, bool is_double) const {
// Not used
}
void N64Recomp::LuajitGenerator::emit_cop0_status_read(std::ostream& output_file, int reg) const {
// TODO
fmt::print(output_file, "\n");
}
void N64Recomp::LuajitGenerator::emit_cop0_status_write(std::ostream& output_file, int reg) const {
// TODO
fmt::print(output_file, "\n");
}
void N64Recomp::LuajitGenerator::emit_cop1_cs_read(std::ostream& output_file, int reg) const {
// TODO
fmt::print(output_file, "\n");
}
void N64Recomp::LuajitGenerator::emit_cop1_cs_write(std::ostream& output_file, int reg) const {
// TODO
fmt::print(output_file, "\n");
}
void N64Recomp::LuajitGenerator::emit_muldiv(std::ostream& output_file, InstrId instr_id, int reg1, int reg2) const {
// TODO
fmt::print(output_file, "\n");
}
void N64Recomp::LuajitGenerator::emit_syscall(std::ostream& output_file, uint32_t instr_vram) const {
// TODO
fmt::print(output_file, "\n");
}
void N64Recomp::LuajitGenerator::emit_do_break(std::ostream& output_file, uint32_t instr_vram) const {
// TODO
fmt::print(output_file, "\n");
}
void N64Recomp::LuajitGenerator::emit_pause_self(std::ostream& output_file) const {
// TODO
fmt::print(output_file, "\n");
}
void N64Recomp::LuajitGenerator::emit_trigger_event(std::ostream& output_file, size_t event_index) const {
// TODO
fmt::print(output_file, "\n");
}
void N64Recomp::LuajitGenerator::emit_comment(std::ostream& output_file, const std::string& comment) const {
fmt::print(output_file, "-- {}\n", comment);
}

View file

@ -604,7 +604,7 @@ bool process_instruction(GeneratorType& generator, const N64Recomp::Context& con
instruction_context.reloc_section_index = reloc_section; instruction_context.reloc_section_index = reloc_section;
instruction_context.reloc_target_section_offset = reloc_target_section_offset; instruction_context.reloc_target_section_offset = reloc_target_section_offset;
auto do_check_fr = [](std::ostream& output_file, const CGenerator& generator, const InstructionContext& ctx, Operand operand) { auto do_check_fr = [](std::ostream& output_file, const GeneratorType& generator, const InstructionContext& ctx, Operand operand) {
switch (operand) { switch (operand) {
case Operand::Fd: case Operand::Fd:
case Operand::FdDouble: case Operand::FdDouble:
@ -633,7 +633,7 @@ bool process_instruction(GeneratorType& generator, const N64Recomp::Context& con
} }
}; };
auto do_check_nan = [](std::ostream& output_file, const CGenerator& generator, const InstructionContext& ctx, Operand operand) { auto do_check_nan = [](std::ostream& output_file, const GeneratorType& generator, const InstructionContext& ctx, Operand operand) {
switch (operand) { switch (operand) {
case Operand::Fd: case Operand::Fd:
generator.emit_check_nan(output_file, ctx.fd, false); generator.emit_check_nan(output_file, ctx.fd, false);
@ -869,3 +869,8 @@ bool N64Recomp::recompile_function(const N64Recomp::Context& context, const N64R
CGenerator generator{}; CGenerator generator{};
return recompile_function_impl(generator, context, func, output_file, static_funcs_out, tag_reference_relocs); 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) {
LuajitGenerator generator{};
return recompile_function_impl(generator, context, func, output_file, static_funcs_out, tag_reference_relocs);
}