2014-04-05 18:30:08 +02:00
|
|
|
#pragma once
|
|
|
|
|
|
2018-05-04 23:01:27 +02:00
|
|
|
#include "Utilities/File.h"
|
2018-04-09 16:45:37 +02:00
|
|
|
#include "SPUThread.h"
|
2018-05-04 23:01:27 +02:00
|
|
|
#include <vector>
|
2018-04-30 18:44:01 +02:00
|
|
|
#include <bitset>
|
2018-05-04 23:01:27 +02:00
|
|
|
#include <memory>
|
2018-05-10 18:38:07 +02:00
|
|
|
#include <string>
|
2018-05-04 23:01:27 +02:00
|
|
|
|
|
|
|
|
// Helper class
|
|
|
|
|
class spu_cache
|
|
|
|
|
{
|
|
|
|
|
fs::file m_file;
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
spu_cache(const std::string& loc);
|
|
|
|
|
|
|
|
|
|
~spu_cache();
|
|
|
|
|
|
|
|
|
|
operator bool() const
|
|
|
|
|
{
|
|
|
|
|
return m_file.operator bool();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::vector<std::vector<u32>> get();
|
|
|
|
|
|
|
|
|
|
void add(const std::vector<u32>& func);
|
|
|
|
|
|
|
|
|
|
static void initialize();
|
|
|
|
|
};
|
2014-04-05 18:30:08 +02:00
|
|
|
|
2018-04-09 16:45:37 +02:00
|
|
|
// SPU Recompiler instance base class
|
2016-04-14 01:09:41 +02:00
|
|
|
class spu_recompiler_base
|
2014-04-05 18:30:08 +02:00
|
|
|
{
|
2015-08-26 04:54:06 +02:00
|
|
|
protected:
|
2018-04-09 16:45:37 +02:00
|
|
|
u32 m_pos;
|
2018-05-02 20:49:19 +02:00
|
|
|
u32 m_size;
|
2014-04-05 18:30:08 +02:00
|
|
|
|
2018-05-10 18:38:07 +02:00
|
|
|
// Bit indicating start of the block
|
2018-04-30 18:44:01 +02:00
|
|
|
std::bitset<0x10000> m_block_info;
|
|
|
|
|
|
2018-05-10 18:38:07 +02:00
|
|
|
// GPR modified by the instruction (-1 = not set)
|
|
|
|
|
std::array<u8, 0x10000> m_regmod;
|
|
|
|
|
|
|
|
|
|
// List of possible targets for the instruction ({} = next instruction, {-1} = no targets)
|
|
|
|
|
std::unordered_map<u32, std::basic_string<u32>, value_hash<u32, 2>> m_targets;
|
|
|
|
|
|
2018-05-04 23:01:27 +02:00
|
|
|
std::shared_ptr<spu_cache> m_cache;
|
|
|
|
|
|
2015-08-26 04:54:06 +02:00
|
|
|
public:
|
2018-05-03 14:55:45 +02:00
|
|
|
spu_recompiler_base();
|
2018-04-09 16:45:37 +02:00
|
|
|
|
2017-01-25 00:22:19 +01:00
|
|
|
virtual ~spu_recompiler_base();
|
2014-04-05 18:30:08 +02:00
|
|
|
|
2018-05-04 23:01:27 +02:00
|
|
|
// Initialize
|
|
|
|
|
virtual void init() = 0;
|
|
|
|
|
|
2018-04-16 17:27:57 +02:00
|
|
|
// Get pointer to the trampoline at given position
|
|
|
|
|
virtual spu_function_t get(u32 lsa) = 0;
|
|
|
|
|
|
2018-04-09 16:45:37 +02:00
|
|
|
// Compile function
|
2018-05-04 23:01:27 +02:00
|
|
|
virtual spu_function_t compile(std::vector<u32>&&) = 0;
|
2018-04-09 16:45:37 +02:00
|
|
|
|
2018-05-03 14:55:45 +02:00
|
|
|
// Default dispatch function fallback (second arg is unused)
|
|
|
|
|
static void dispatch(SPUThread&, void*, u8* rip);
|
2018-04-09 16:45:37 +02:00
|
|
|
|
2018-05-03 14:55:45 +02:00
|
|
|
// Target for the unresolved patch point (second arg is unused)
|
|
|
|
|
static void branch(SPUThread&, void*, u8* rip);
|
2018-04-09 16:45:37 +02:00
|
|
|
|
|
|
|
|
// Get the block at specified address
|
2018-05-04 23:01:27 +02:00
|
|
|
std::vector<u32> block(const be_t<u32>* ls, u32 lsa);
|
2015-05-27 05:11:59 +02:00
|
|
|
|
2018-04-09 16:45:37 +02:00
|
|
|
// Create recompiler instance (ASMJIT)
|
2018-05-03 14:55:45 +02:00
|
|
|
static std::unique_ptr<spu_recompiler_base> make_asmjit_recompiler();
|
2018-05-02 20:49:19 +02:00
|
|
|
|
|
|
|
|
// Create recompiler instance (LLVM)
|
2018-05-03 14:55:45 +02:00
|
|
|
static std::unique_ptr<spu_recompiler_base> make_llvm_recompiler();
|
2014-04-08 17:10:07 +02:00
|
|
|
};
|