mirror of
https://github.com/N64Recomp/N64Recomp.git
synced 2025-05-24 04:14:59 +00:00
Add LuajitGenerator class
This commit is contained in:
parent
46ab6f758d
commit
ef319b1aad
5 changed files with 189 additions and 2 deletions
|
@ -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
|
||||||
)
|
)
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
144
src/luajitgenerator.cpp
Normal 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);
|
||||||
|
}
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue