mirror of
https://github.com/ran-j/PS2Recomp.git
synced 2026-10-02 02:31:51 -04:00
migrate from private cloud
This commit is contained in:
@@ -0,0 +1,38 @@
|
||||
#ifndef PS2RECOMP_CODE_GENERATOR_H
|
||||
#define PS2RECOMP_CODE_GENERATOR_H
|
||||
|
||||
#include "ps2recomp/types.h"
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace ps2recomp
|
||||
{
|
||||
|
||||
class CodeGenerator
|
||||
{
|
||||
public:
|
||||
CodeGenerator(const std::vector<Symbol> &symbols);
|
||||
~CodeGenerator();
|
||||
|
||||
std::string generateFunction(const Function &function, const std::vector<Instruction> &instructions);
|
||||
std::string generateMacroHeader();
|
||||
std::string handleBranchDelaySlots(const Instruction &branchInst, const Instruction &delaySlot);
|
||||
|
||||
private:
|
||||
std::vector<Symbol> m_symbols;
|
||||
|
||||
std::string translateInstruction(const Instruction &inst);
|
||||
std::string translateMMIInstruction(const Instruction &inst);
|
||||
std::string translateVUInstruction(const Instruction &inst);
|
||||
std::string translateFPUInstruction(const Instruction& inst);
|
||||
std::string translateCOP0Instruction(const Instruction& inst);
|
||||
|
||||
std::string generateJumpTableSwitch(const Instruction &inst, uint32_t tableAddress,
|
||||
const std::vector<JumpTableEntry> &entries);
|
||||
|
||||
Symbol *findSymbolByAddress(uint32_t address);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // PS2RECOMP_CODE_GENERATOR_H
|
||||
@@ -0,0 +1,25 @@
|
||||
#ifndef PS2RECOMP_CONFIG_MANAGER_H
|
||||
#define PS2RECOMP_CONFIG_MANAGER_H
|
||||
|
||||
#include "ps2recomp/types.h"
|
||||
#include <string>
|
||||
|
||||
namespace ps2recomp
|
||||
{
|
||||
|
||||
class ConfigManager
|
||||
{
|
||||
public:
|
||||
ConfigManager(const std::string &configPath);
|
||||
~ConfigManager();
|
||||
|
||||
RecompilerConfig loadConfig();
|
||||
void saveConfig(const RecompilerConfig &config);
|
||||
|
||||
private:
|
||||
std::string m_configPath;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // PS2RECOMP_CONFIG_MANAGER_H
|
||||
@@ -0,0 +1,50 @@
|
||||
#ifndef PS2RECOMP_ELF_PARSER_H
|
||||
#define PS2RECOMP_ELF_PARSER_H
|
||||
|
||||
#include "ps2recomp/types.h"
|
||||
#include <elfio/elfio.hpp>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
|
||||
namespace ps2recomp
|
||||
{
|
||||
|
||||
class ElfParser
|
||||
{
|
||||
public:
|
||||
ElfParser(const std::string &filePath);
|
||||
~ElfParser();
|
||||
|
||||
bool parse();
|
||||
|
||||
std::vector<Function> extractFunctions();
|
||||
std::vector<Symbol> extractSymbols();
|
||||
std::vector<Section> getSections();
|
||||
std::vector<Relocation> getRelocations();
|
||||
|
||||
// Helper methods
|
||||
bool isValidAddress(uint32_t address) const;
|
||||
uint32_t readWord(uint32_t address) const;
|
||||
uint8_t *getSectionData(const std::string §ionName);
|
||||
uint32_t getSectionAddress(const std::string §ionName);
|
||||
uint32_t getSectionSize(const std::string §ionName);
|
||||
|
||||
private:
|
||||
std::string m_filePath;
|
||||
std::unique_ptr<ELFIO::elfio> m_elf;
|
||||
|
||||
std::vector<Section> m_sections;
|
||||
std::vector<Symbol> m_symbols;
|
||||
std::vector<Relocation> m_relocations;
|
||||
|
||||
void loadSections();
|
||||
void loadSymbols();
|
||||
void loadRelocations();
|
||||
bool isExecutableSection(const ELFIO::section *section) const;
|
||||
bool isDataSection(const ELFIO::section *section) const;
|
||||
};
|
||||
|
||||
} // namespace ps2recomp
|
||||
|
||||
#endif // PS2RECOMP_ELF_PARSER_H
|
||||
@@ -0,0 +1,376 @@
|
||||
#ifndef PS2RECOMP_INSTRUCTIONS_H
|
||||
#define PS2RECOMP_INSTRUCTIONS_H
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
namespace ps2recomp
|
||||
{
|
||||
// Basic MIPS opcodes (shared with R4300i)
|
||||
enum MipsOpcodes
|
||||
{
|
||||
OPCODE_SPECIAL = 0x00,
|
||||
OPCODE_REGIMM = 0x01,
|
||||
OPCODE_J = 0x02,
|
||||
OPCODE_JAL = 0x03,
|
||||
OPCODE_BEQ = 0x04,
|
||||
OPCODE_BNE = 0x05,
|
||||
OPCODE_BLEZ = 0x06,
|
||||
OPCODE_BGTZ = 0x07,
|
||||
OPCODE_ADDI = 0x08,
|
||||
OPCODE_ADDIU = 0x09,
|
||||
OPCODE_SLTI = 0x0A,
|
||||
OPCODE_SLTIU = 0x0B,
|
||||
OPCODE_ANDI = 0x0C,
|
||||
OPCODE_ORI = 0x0D,
|
||||
OPCODE_XORI = 0x0E,
|
||||
OPCODE_LUI = 0x0F,
|
||||
OPCODE_COP0 = 0x10,
|
||||
OPCODE_COP1 = 0x11,
|
||||
OPCODE_COP2 = 0x12, // VU0 macro instructions
|
||||
OPCODE_COP3 = 0x13, // Unused on PS2
|
||||
OPCODE_BEQL = 0x14,
|
||||
OPCODE_BNEL = 0x15,
|
||||
OPCODE_BLEZL = 0x16,
|
||||
OPCODE_BGTZL = 0x17,
|
||||
OPCODE_DADDI = 0x18,
|
||||
OPCODE_DADDIU = 0x19,
|
||||
OPCODE_LDL = 0x1A,
|
||||
OPCODE_LDR = 0x1B,
|
||||
OPCODE_MMI = 0x1C, // PS2 specific multimedia instructions
|
||||
OPCODE_LQ = 0x1E, // PS2 specific 128-bit load
|
||||
OPCODE_SQ = 0x1F, // PS2 specific 128-bit store
|
||||
OPCODE_LB = 0x20,
|
||||
OPCODE_LH = 0x21,
|
||||
OPCODE_LWL = 0x22,
|
||||
OPCODE_LW = 0x23,
|
||||
OPCODE_LBU = 0x24,
|
||||
OPCODE_LHU = 0x25,
|
||||
OPCODE_LWR = 0x26,
|
||||
OPCODE_LWU = 0x27,
|
||||
OPCODE_SB = 0x28,
|
||||
OPCODE_SH = 0x29,
|
||||
OPCODE_SWL = 0x2A,
|
||||
OPCODE_SW = 0x2B,
|
||||
OPCODE_SDL = 0x2C,
|
||||
OPCODE_SDR = 0x2D,
|
||||
OPCODE_SWR = 0x2E,
|
||||
OPCODE_CACHE = 0x2F,
|
||||
OPCODE_LL = 0x30,
|
||||
OPCODE_LWC1 = 0x31,
|
||||
OPCODE_LWC2 = 0x32,
|
||||
OPCODE_PREF = 0x33,
|
||||
OPCODE_LLD = 0x34,
|
||||
OPCODE_LDC1 = 0x35,
|
||||
OPCODE_LDC2 = 0x36,
|
||||
OPCODE_LD = 0x37,
|
||||
OPCODE_SC = 0x38,
|
||||
OPCODE_SWC1 = 0x39,
|
||||
OPCODE_SWC2 = 0x3A,
|
||||
OPCODE_SCD = 0x3C,
|
||||
OPCODE_SDC1 = 0x3D,
|
||||
OPCODE_SDC2 = 0x3E,
|
||||
OPCODE_SD = 0x3F
|
||||
};
|
||||
|
||||
// SPECIAL function codes
|
||||
enum SpecialFunctions
|
||||
{
|
||||
SPECIAL_SLL = 0x00,
|
||||
SPECIAL_SRL = 0x02,
|
||||
SPECIAL_SRA = 0x03,
|
||||
SPECIAL_SLLV = 0x04,
|
||||
SPECIAL_SRLV = 0x06,
|
||||
SPECIAL_SRAV = 0x07,
|
||||
SPECIAL_JR = 0x08,
|
||||
SPECIAL_JALR = 0x09,
|
||||
SPECIAL_MOVZ = 0x0A,
|
||||
SPECIAL_MOVN = 0x0B,
|
||||
SPECIAL_SYSCALL = 0x0C,
|
||||
SPECIAL_BREAK = 0x0D,
|
||||
SPECIAL_SYNC = 0x0F,
|
||||
SPECIAL_MFHI = 0x10,
|
||||
SPECIAL_MTHI = 0x11,
|
||||
SPECIAL_MFLO = 0x12,
|
||||
SPECIAL_MTLO = 0x13,
|
||||
SPECIAL_DSLLV = 0x14,
|
||||
SPECIAL_DSRLV = 0x16,
|
||||
SPECIAL_DSRAV = 0x17,
|
||||
SPECIAL_MULT = 0x18,
|
||||
SPECIAL_MULTU = 0x19,
|
||||
SPECIAL_DIV = 0x1A,
|
||||
SPECIAL_DIVU = 0x1B,
|
||||
SPECIAL_ADD = 0x20,
|
||||
SPECIAL_ADDU = 0x21,
|
||||
SPECIAL_SUB = 0x22,
|
||||
SPECIAL_SUBU = 0x23,
|
||||
SPECIAL_AND = 0x24,
|
||||
SPECIAL_OR = 0x25,
|
||||
SPECIAL_XOR = 0x26,
|
||||
SPECIAL_NOR = 0x27,
|
||||
SPECIAL_MFSA = 0x28,
|
||||
SPECIAL_MTSA = 0x29,
|
||||
SPECIAL_SLT = 0x2A,
|
||||
SPECIAL_SLTU = 0x2B,
|
||||
SPECIAL_DADD = 0x2C,
|
||||
SPECIAL_DADDU = 0x2D,
|
||||
SPECIAL_DSUB = 0x2E,
|
||||
SPECIAL_DSUBU = 0x2F,
|
||||
SPECIAL_TGE = 0x30,
|
||||
SPECIAL_TGEU = 0x31,
|
||||
SPECIAL_TLT = 0x32,
|
||||
SPECIAL_TLTU = 0x33,
|
||||
SPECIAL_TEQ = 0x34,
|
||||
SPECIAL_TNE = 0x36,
|
||||
SPECIAL_DSLL = 0x38,
|
||||
SPECIAL_DSRL = 0x3A,
|
||||
SPECIAL_DSRA = 0x3B,
|
||||
SPECIAL_DSLL32 = 0x3C,
|
||||
SPECIAL_DSRL32 = 0x3E,
|
||||
SPECIAL_DSRA32 = 0x3F
|
||||
};
|
||||
|
||||
// REGIMM function codes
|
||||
enum RegimmFunctions
|
||||
{
|
||||
REGIMM_BLTZ = 0x00,
|
||||
REGIMM_BGEZ = 0x01,
|
||||
REGIMM_BLTZL = 0x02,
|
||||
REGIMM_BGEZL = 0x03,
|
||||
REGIMM_TGEI = 0x08,
|
||||
REGIMM_TGEIU = 0x09,
|
||||
REGIMM_TLTI = 0x0A,
|
||||
REGIMM_TLTIU = 0x0B,
|
||||
REGIMM_TEQI = 0x0C,
|
||||
REGIMM_TNEI = 0x0E,
|
||||
REGIMM_BLTZAL = 0x10,
|
||||
REGIMM_BGEZAL = 0x11,
|
||||
REGIMM_BLTZALL = 0x12,
|
||||
REGIMM_BGEZALL = 0x13,
|
||||
REGIMM_MTSAB = 0x18,
|
||||
REGIMM_MTSAH = 0x19
|
||||
};
|
||||
|
||||
// PS2-specific MMI function codes
|
||||
enum MMIFunctions
|
||||
{
|
||||
MMI_MADD = 0x00,
|
||||
MMI_MADDU = 0x01,
|
||||
MMI_PLZCW = 0x04,
|
||||
MMI_MMI0 = 0x08,
|
||||
MMI_MMI2 = 0x09,
|
||||
MMI_MFHI1 = 0x10,
|
||||
MMI_MTHI1 = 0x11,
|
||||
MMI_MFLO1 = 0x12,
|
||||
MMI_MTLO1 = 0x13,
|
||||
MMI_MULT1 = 0x18,
|
||||
MMI_MULTU1 = 0x19,
|
||||
MMI_DIV1 = 0x1A,
|
||||
MMI_DIVU1 = 0x1B,
|
||||
MMI_MADD1 = 0x20,
|
||||
MMI_MADDU1 = 0x21,
|
||||
MMI_MMI1 = 0x28,
|
||||
MMI_MMI3 = 0x29,
|
||||
MMI_PMFHL = 0x30,
|
||||
MMI_PMTHL = 0x31,
|
||||
MMI_PSLLH = 0x34,
|
||||
MMI_PSRLH = 0x36,
|
||||
MMI_PSRAH = 0x37,
|
||||
MMI_PSLLW = 0x3C,
|
||||
MMI_PSRLW = 0x3E,
|
||||
MMI_PSRAW = 0x3F,
|
||||
MMI_MSUB = 0x02,
|
||||
MMI_MSUBU = 0x03
|
||||
};
|
||||
|
||||
// PS2-specific MMI0 function codes
|
||||
enum MMI0Functions
|
||||
{
|
||||
MMI0_PADDW = 0x00,
|
||||
MMI0_PSUBW = 0x01,
|
||||
MMI0_PCGTW = 0x02,
|
||||
MMI0_PMAXW = 0x03,
|
||||
MMI0_PADDH = 0x04,
|
||||
MMI0_PSUBH = 0x05,
|
||||
MMI0_PCGTH = 0x06,
|
||||
MMI0_PMAXH = 0x07,
|
||||
MMI0_PADDB = 0x08,
|
||||
MMI0_PSUBB = 0x09,
|
||||
MMI0_PCGTB = 0x0A,
|
||||
MMI0_PADDSW = 0x10,
|
||||
MMI0_PSUBSW = 0x11,
|
||||
MMI0_PEXTLW = 0x12,
|
||||
MMI0_PPACW = 0x13,
|
||||
MMI0_PADDSH = 0x14,
|
||||
MMI0_PSUBSH = 0x15,
|
||||
MMI0_PEXTLH = 0x16,
|
||||
MMI0_PPACH = 0x17,
|
||||
MMI0_PADDSB = 0x18,
|
||||
MMI0_PSUBSB = 0x19,
|
||||
MMI0_PEXTLB = 0x1A,
|
||||
MMI0_PPACB = 0x1B,
|
||||
MMI0_PEXT5 = 0x1E,
|
||||
MMI0_PPAC5 = 0x1F
|
||||
};
|
||||
|
||||
// PS2-specific MMI1 function codes
|
||||
enum MMI1Functions
|
||||
{
|
||||
MMI1_PABSW = 0x01,
|
||||
MMI1_PCEQW = 0x02,
|
||||
MMI1_PMINW = 0x03,
|
||||
MMI1_PADSBH = 0x04,
|
||||
MMI1_PABSH = 0x05,
|
||||
MMI1_PCEQH = 0x06,
|
||||
MMI1_PMINH = 0x07,
|
||||
MMI1_PCEQB = 0x0A,
|
||||
MMI1_PADDUW = 0x10,
|
||||
MMI1_PSUBUW = 0x11,
|
||||
MMI1_PEXTUW = 0x12,
|
||||
MMI1_PADDUH = 0x14,
|
||||
MMI1_PSUBUH = 0x15,
|
||||
MMI1_PEXTUH = 0x16,
|
||||
MMI1_PADDUB = 0x18,
|
||||
MMI1_PSUBUB = 0x19,
|
||||
MMI1_PEXTUB = 0x1A,
|
||||
MMI1_QFSRV = 0x1B
|
||||
};
|
||||
|
||||
// PS2-specific MMI2 function codes
|
||||
enum MMI2Functions
|
||||
{
|
||||
MMI2_PMADDW = 0x00,
|
||||
MMI2_PSLLVW = 0x02,
|
||||
MMI2_PSRLVW = 0x03,
|
||||
MMI2_PMSUBW = 0x04,
|
||||
MMI2_PMFHI = 0x08,
|
||||
MMI2_PMFLO = 0x09,
|
||||
MMI2_PINTH = 0x0A,
|
||||
MMI2_PMULTW = 0x0C,
|
||||
MMI2_PDIVW = 0x0D,
|
||||
MMI2_PCPYLD = 0x0E,
|
||||
MMI2_PAND = 0x12,
|
||||
MMI2_PXOR = 0x13,
|
||||
MMI2_PMADDH = 0x14,
|
||||
MMI2_PHMADH = 0x15,
|
||||
MMI2_PAND_ = 0x16,
|
||||
MMI2_PXOR_ = 0x17,
|
||||
MMI2_PMSUBH = 0x18,
|
||||
MMI2_PHMSBH = 0x19,
|
||||
MMI2_PEXEH = 0x1A,
|
||||
MMI2_PREVH = 0x1B,
|
||||
MMI2_PMULTH = 0x1C,
|
||||
MMI2_PDIVBW = 0x1D,
|
||||
MMI2_PEXEW = 0x1E,
|
||||
MMI2_PROT3W = 0x1F
|
||||
};
|
||||
|
||||
// PS2-specific MMI3 function codes
|
||||
enum MMI3Functions
|
||||
{
|
||||
MMI3_PMADDUW = 0x00,
|
||||
MMI3_PSRAVW = 0x03,
|
||||
MMI3_PINTEH = 0x0A,
|
||||
MMI3_PMULTUW = 0x0C,
|
||||
MMI3_PDIVUW = 0x0D,
|
||||
MMI3_PCPYUD = 0x0E,
|
||||
MMI3_POR = 0x12,
|
||||
MMI3_PNOR = 0x13,
|
||||
MMI3_PEXCH = 0x1A,
|
||||
MMI3_PCPYH = 0x1B,
|
||||
MMI3_PEXCW = 0x1E,
|
||||
};
|
||||
|
||||
// COP0 (System Control) function codes
|
||||
enum Cop0Functions
|
||||
{
|
||||
COP0_MF = 0x00,
|
||||
COP0_MT = 0x04,
|
||||
COP0_CO = 0x10 // COProcessor commands
|
||||
};
|
||||
|
||||
// COP0 CO (COProcessor) function codes
|
||||
enum Cop0CoFunctions
|
||||
{
|
||||
COP0_CO_TLBR = 0x01,
|
||||
COP0_CO_TLBWI = 0x02,
|
||||
COP0_CO_TLBWR = 0x06,
|
||||
COP0_CO_TLBP = 0x08,
|
||||
COP0_CO_ERET = 0x18,
|
||||
COP0_CO_EI = 0x38,
|
||||
COP0_CO_DI = 0x39
|
||||
};
|
||||
|
||||
// COP1 (FPU) function codes
|
||||
enum Cop1Functions
|
||||
{
|
||||
COP1_MF = 0x00,
|
||||
COP1_CF = 0x02,
|
||||
COP1_MT = 0x04,
|
||||
COP1_CT = 0x06,
|
||||
COP1_BC = 0x08,
|
||||
COP1_S = 0x10,
|
||||
COP1_W = 0x14,
|
||||
COP1_BC_BCF = 0x00,
|
||||
COP1_BC_BCT = 0x01
|
||||
};
|
||||
|
||||
// COP2 (VU0 macro) function codes
|
||||
enum Cop2Functions
|
||||
{
|
||||
COP2_QMFC2 = 0x00, // Move From Coprocessor 2 (128-bit)
|
||||
COP2_CFC2 = 0x02, // Move Control From Coprocessor 2
|
||||
COP2_QMTC2 = 0x04, // Move To Coprocessor 2 (128-bit)
|
||||
COP2_CTC2 = 0x06, // Move Control To Coprocessor 2
|
||||
COP2_BC2 = 0x08, // Branch On Coprocessor 2 Condition
|
||||
COP2_CO = 0x10, // COProcessor instructions (VU0 macro)
|
||||
COP2_BCF = 0x00,
|
||||
COP2_BCT = 0x01,
|
||||
COP2_MFC2 = 0x02,
|
||||
COP2_MTC2 = 0x0A
|
||||
};
|
||||
|
||||
// VU0 macro instruction function codes (subset - there are many more)
|
||||
enum VU0MacroFunctions
|
||||
{
|
||||
VU0_VADD = 0x00,
|
||||
VU0_VSUB = 0x01,
|
||||
VU0_VMUL = 0x02,
|
||||
VU0_VDIV = 0x03,
|
||||
VU0_VSQRT = 0x04,
|
||||
VU0_VRSQRT = 0x05,
|
||||
VU0_VMULQ = 0x06,
|
||||
VU0_VIADD = 0x10,
|
||||
VU0_VISUB = 0x11,
|
||||
VU0_VIADDI = 0x12,
|
||||
VU0_VIAND = 0x13,
|
||||
VU0_VIOR = 0x14,
|
||||
VU0_VILWR = 0x15,
|
||||
VU0_VISWR = 0x16,
|
||||
VU0_VCALLMS = 0x20,
|
||||
VU0_VCALLMSR = 0x21
|
||||
};
|
||||
|
||||
// PMFHL functions (sa field)
|
||||
enum PMFHLFunctions
|
||||
{
|
||||
PMFHL_LW = 0x00,
|
||||
PMFHL_UW = 0x01,
|
||||
PMFHL_SLW = 0x02,
|
||||
PMFHL_LH = 0x03,
|
||||
PMFHL_SH = 0x04
|
||||
};
|
||||
|
||||
// Instruction decoding helper macros
|
||||
#define OPCODE(inst) ((inst >> 26) & 0x3F)
|
||||
#define RS(inst) ((inst >> 21) & 0x1F)
|
||||
#define RT(inst) ((inst >> 16) & 0x1F)
|
||||
#define RD(inst) ((inst >> 11) & 0x1F)
|
||||
#define SA(inst) ((inst >> 6) & 0x1F)
|
||||
#define FUNCTION(inst) ((inst) & 0x3F)
|
||||
#define IMMEDIATE(inst) ((inst) & 0xFFFF)
|
||||
#define SIMMEDIATE(inst) ((int16_t)((inst) & 0xFFFF))
|
||||
#define TARGET(inst) ((inst) & 0x3FFFFFF)
|
||||
|
||||
} // namespace ps2recomp
|
||||
|
||||
#endif // PS2RECOMP_INSTRUCTIONS_H
|
||||
@@ -0,0 +1,55 @@
|
||||
#ifndef PS2RECOMP_PS2_RECOMPILER_H
|
||||
#define PS2RECOMP_PS2_RECOMPILER_H
|
||||
|
||||
#include "ps2recomp/types.h"
|
||||
#include "ps2recomp/elf_parser.h"
|
||||
#include "ps2recomp/r5900_decoder.h"
|
||||
#include "ps2recomp/code_generator.h"
|
||||
#include "ps2recomp/config_manager.h"
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <unordered_map>
|
||||
#include <filesystem>
|
||||
|
||||
namespace ps2recomp
|
||||
{
|
||||
|
||||
class PS2Recompiler
|
||||
{
|
||||
public:
|
||||
PS2Recompiler(const std::string &configPath);
|
||||
~PS2Recompiler() = default;
|
||||
|
||||
bool initialize();
|
||||
bool recompile();
|
||||
void generateOutput();
|
||||
|
||||
private:
|
||||
ConfigManager m_configManager;
|
||||
std::unique_ptr<ElfParser> m_elfParser;
|
||||
std::unique_ptr<R5900Decoder> m_decoder;
|
||||
std::unique_ptr<CodeGenerator> m_codeGenerator;
|
||||
RecompilerConfig m_config;
|
||||
|
||||
std::vector<Function> m_functions;
|
||||
std::vector<Symbol> m_symbols;
|
||||
std::vector<Section> m_sections;
|
||||
std::vector<Relocation> m_relocations;
|
||||
|
||||
std::unordered_map<uint32_t, std::vector<Instruction>> m_decodedFunctions;
|
||||
std::unordered_map<std::string, bool> m_stubFunctions;
|
||||
std::unordered_map<std::string, bool> m_skipFunctions;
|
||||
std::map<uint32_t, std::string> m_generatedStubs;
|
||||
|
||||
bool decodeFunction(Function &function);
|
||||
bool shouldStubFunction(const std::string &name) const;
|
||||
bool shouldSkipFunction(const std::string &name) const;
|
||||
std::string generateRuntimeHeader();
|
||||
std::string generateStubFunction(const Function& function);
|
||||
bool writeToFile(const std::string &path, const std::string &content);
|
||||
std::filesystem::path getOutputPath(const Function &function) const;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,52 @@
|
||||
#ifndef PS2RECOMP_R5900_DECODER_H
|
||||
#define PS2RECOMP_R5900_DECODER_H
|
||||
|
||||
#include "ps2recomp/types.h"
|
||||
#include "ps2recomp/instructions.h"
|
||||
#include <cstdint>
|
||||
|
||||
namespace ps2recomp
|
||||
{
|
||||
|
||||
class R5900Decoder
|
||||
{
|
||||
public:
|
||||
R5900Decoder();
|
||||
~R5900Decoder();
|
||||
|
||||
Instruction decodeInstruction(uint32_t address, uint32_t rawInstruction);
|
||||
|
||||
bool isBranchInstruction(const Instruction &inst) const;
|
||||
bool isJumpInstruction(const Instruction &inst) const;
|
||||
bool isCallInstruction(const Instruction &inst) const;
|
||||
bool isReturnInstruction(const Instruction &inst) const;
|
||||
bool isMMIInstruction(const Instruction &inst) const;
|
||||
bool isVUInstruction(const Instruction &inst) const;
|
||||
bool isStore(const Instruction &inst) const;
|
||||
bool isLoad(const Instruction &inst) const;
|
||||
bool hasDelaySlot(const Instruction &inst) const;
|
||||
|
||||
uint32_t getBranchTarget(const Instruction &inst) const;
|
||||
uint32_t getJumpTarget(const Instruction &inst) const;
|
||||
|
||||
private:
|
||||
void decodeRType(Instruction &inst) const;
|
||||
void decodeIType(Instruction &inst) const;
|
||||
void decodeJType(Instruction &inst) const;
|
||||
|
||||
void decodeSpecial(Instruction &inst) const;
|
||||
void decodeRegimm(Instruction &inst) const;
|
||||
void decodeMMI(Instruction &inst) const;
|
||||
void decodeCOP0(Instruction& inst) const;
|
||||
void decodeCOP1(Instruction &inst) const;
|
||||
void decodeCOP2(Instruction &inst) const;
|
||||
void decodeMMI0(Instruction &inst) const;
|
||||
void decodeMMI1(Instruction &inst) const;
|
||||
void decodeMMI2(Instruction &inst) const;
|
||||
void decodeMMI3(Instruction &inst) const;
|
||||
void decodePMFHL(Instruction &inst) const;
|
||||
};
|
||||
|
||||
} // namespace ps2recomp
|
||||
|
||||
#endif // PS2RECOMP_R5900_DECODER_H
|
||||
@@ -0,0 +1,139 @@
|
||||
#ifndef PS2RECOMP_TYPES_H
|
||||
#define PS2RECOMP_TYPES_H
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <cstdint>
|
||||
#include <unordered_map>
|
||||
#include <map>
|
||||
|
||||
namespace ps2recomp
|
||||
{
|
||||
|
||||
// Instruction representation
|
||||
struct Instruction
|
||||
{
|
||||
uint32_t address;
|
||||
uint32_t opcode;
|
||||
uint32_t rs; // Source register
|
||||
uint32_t rt; // Target register
|
||||
uint32_t rd; // Destination register
|
||||
uint32_t sa; // Shift amount
|
||||
uint32_t function; // Function code for R-type instructions
|
||||
uint32_t immediate; // Immediate value for I-type instructions
|
||||
uint32_t target; // Jump target for J-type instructions
|
||||
uint32_t raw; // Raw instruction value
|
||||
bool isMMI; // Is MMI instruction (PS2 specific)
|
||||
bool isVU; // Is VU instruction (PS2 specific)
|
||||
bool isBranch; // Is branch instruction
|
||||
bool isJump; // Is jump instruction
|
||||
bool isCall; // Is function call
|
||||
bool isReturn; // Is return instruction
|
||||
bool hasDelaySlot; // Has delay slot
|
||||
bool isMultimedia; // PS2-specific multimedia operations
|
||||
bool isStore;
|
||||
bool isLoad;
|
||||
uint8_t pmfhlVariation;
|
||||
};
|
||||
|
||||
// Function information
|
||||
struct Function
|
||||
{
|
||||
std::string name;
|
||||
uint32_t start;
|
||||
uint32_t end;
|
||||
std::vector<Instruction> instructions;
|
||||
std::vector<uint32_t> callers;
|
||||
std::vector<uint32_t> callees;
|
||||
bool isRecompiled;
|
||||
bool isStub;
|
||||
};
|
||||
|
||||
// Symbol information
|
||||
struct Symbol
|
||||
{
|
||||
std::string name;
|
||||
uint32_t address;
|
||||
uint32_t size;
|
||||
bool isFunction;
|
||||
bool isImported;
|
||||
bool isExported;
|
||||
};
|
||||
|
||||
// Section information
|
||||
struct Section
|
||||
{
|
||||
std::string name;
|
||||
uint32_t address;
|
||||
uint32_t size;
|
||||
uint32_t offset;
|
||||
bool isCode;
|
||||
bool isData;
|
||||
bool isBSS;
|
||||
bool isReadOnly;
|
||||
uint8_t *data;
|
||||
};
|
||||
|
||||
// Relocation information
|
||||
struct Relocation
|
||||
{
|
||||
uint32_t offset;
|
||||
uint32_t info;
|
||||
uint32_t symbol;
|
||||
uint32_t type;
|
||||
int32_t addend;
|
||||
};
|
||||
|
||||
// Jump table entry
|
||||
struct JumpTableEntry
|
||||
{
|
||||
uint32_t index;
|
||||
uint32_t target;
|
||||
};
|
||||
|
||||
// Jump table
|
||||
struct JumpTable
|
||||
{
|
||||
uint32_t address;
|
||||
uint32_t baseRegister;
|
||||
std::vector<JumpTableEntry> entries;
|
||||
};
|
||||
|
||||
// Control flow graph
|
||||
struct CFGNode
|
||||
{
|
||||
uint32_t startAddress;
|
||||
uint32_t endAddress;
|
||||
std::vector<Instruction> instructions;
|
||||
std::vector<uint32_t> predecessors;
|
||||
std::vector<uint32_t> successors;
|
||||
bool isJumpTarget;
|
||||
bool hasJumpTable;
|
||||
JumpTable jumpTable;
|
||||
};
|
||||
|
||||
using CFG = std::unordered_map<uint32_t, CFGNode>;
|
||||
|
||||
// Function call
|
||||
struct FunctionCall
|
||||
{
|
||||
uint32_t callerAddress;
|
||||
uint32_t calleeAddress;
|
||||
std::string calleeName;
|
||||
};
|
||||
|
||||
// Recompiler configuration
|
||||
struct RecompilerConfig
|
||||
{
|
||||
std::string inputPath;
|
||||
std::string outputPath;
|
||||
bool singleFileOutput;
|
||||
std::vector<std::string> stubFunctions;
|
||||
std::vector<std::string> skipFunctions;
|
||||
std::unordered_map<uint32_t, std::string> patches;
|
||||
std::map<std::string, std::string> stubImplementations;
|
||||
};
|
||||
|
||||
} // namespace ps2recomp
|
||||
|
||||
#endif // PS2RECOMP_TYPES_H
|
||||
Reference in New Issue
Block a user