mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-04-22 12:35:21 +00:00
Support more instructions
This commit is contained in:
parent
b95cddb0c7
commit
35a0e0c625
5 changed files with 209 additions and 67 deletions
|
@ -7,6 +7,7 @@
|
|||
#include "Emu/SysCalls/Static.h"
|
||||
#include "Emu/SysCalls/Modules.h"
|
||||
#include "Emu/Memory/Memory.h"
|
||||
#include "Emu/SysCalls/lv2/sys_time.h"
|
||||
|
||||
#include <stdint.h>
|
||||
#ifdef _MSC_VER
|
||||
|
@ -2809,6 +2810,7 @@ private:
|
|||
{
|
||||
const u32 n = (spr >> 5) | ((spr & 0x1f) << 5);
|
||||
|
||||
CPU.TB = get_time();
|
||||
switch(n)
|
||||
{
|
||||
case 0x10C: CPU.GPR[rd] = CPU.TB; break;
|
||||
|
|
|
@ -1586,11 +1586,55 @@ void PPULLVMRecompiler::TW(u32 to, u32 ra, u32 rb) {
|
|||
}
|
||||
|
||||
void PPULLVMRecompiler::LVSL(u32 vd, u32 ra, u32 rb) {
|
||||
InterpreterCall("LVSL", &PPUInterpreter::LVSL, vd, ra, rb);
|
||||
static const u128 s_lvsl_values[] = {
|
||||
{0x08090A0B0C0D0E0F, 0x0001020304050607},
|
||||
{0x090A0B0C0D0E0F10, 0x0102030405060708},
|
||||
{0x0A0B0C0D0E0F1011, 0x0203040506070809},
|
||||
{0x0B0C0D0E0F101112, 0x030405060708090A},
|
||||
{0x0C0D0E0F10111213, 0x0405060708090A0B},
|
||||
{0x0D0E0F1011121314, 0x05060708090A0B0C},
|
||||
{0x0E0F101112131415, 0x060708090A0B0C0D},
|
||||
{0x0F10111213141516, 0x0708090A0B0C0D0E},
|
||||
{0x1011121314151617, 0x08090A0B0C0D0E0F},
|
||||
{0x1112131415161718, 0x090A0B0C0D0E0F10},
|
||||
{0x1213141516171819, 0x0A0B0C0D0E0F1011},
|
||||
{0x131415161718191A, 0x0B0C0D0E0F101112},
|
||||
{0x1415161718191A1B, 0x0C0D0E0F10111213},
|
||||
{0x15161718191A1B1C, 0x0D0E0F1011121314},
|
||||
{0x161718191A1B1C1D, 0x0E0F101112131415},
|
||||
{0x1718191A1B1C1D1E, 0x0F10111213141516},
|
||||
};
|
||||
|
||||
auto addr_i64 = GetGpr(rb);
|
||||
if (ra) {
|
||||
auto ra_i64 = GetGpr(ra);
|
||||
addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64);
|
||||
}
|
||||
|
||||
auto index_i64 = m_ir_builder->CreateAnd(addr_i64, 0xF);
|
||||
auto lvsl_values_i28_ptr = m_ir_builder->CreateIntToPtr(m_ir_builder->getInt64((u64)s_lvsl_values), m_ir_builder->getIntNTy(128)->getPointerTo());
|
||||
lvsl_values_i28_ptr = m_ir_builder->CreateGEP(lvsl_values_i28_ptr, index_i64);
|
||||
auto val_i128 = m_ir_builder->CreateLoad(lvsl_values_i28_ptr);
|
||||
SetVr(vd, val_i128);
|
||||
|
||||
//InterpreterCall("LVSL", &PPUInterpreter::LVSL, vd, ra, rb);
|
||||
}
|
||||
|
||||
void PPULLVMRecompiler::LVEBX(u32 vd, u32 ra, u32 rb) {
|
||||
InterpreterCall("LVEBX", &PPUInterpreter::LVEBX, vd, ra, rb);
|
||||
auto addr_i64 = GetGpr(rb);
|
||||
if (ra) {
|
||||
auto ra_i64 = GetGpr(ra);
|
||||
addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64);
|
||||
}
|
||||
|
||||
auto val_i8 = ReadMemory(addr_i64, 8);
|
||||
auto index_i64 = m_ir_builder->CreateAnd(addr_i64, 0xf);
|
||||
index_i64 = m_ir_builder->CreateSub(m_ir_builder->getInt64(15), index_i64);
|
||||
auto vd_v16i8 = GetVrAsIntVec(vd, 8);
|
||||
vd_v16i8 = m_ir_builder->CreateInsertElement(vd_v16i8, val_i8, index_i64);
|
||||
SetVr(vd, vd_v16i8);
|
||||
|
||||
//InterpreterCall("LVEBX", &PPUInterpreter::LVEBX, vd, ra, rb);
|
||||
}
|
||||
|
||||
void PPULLVMRecompiler::SUBFC(u32 rd, u32 ra, u32 rb, u32 oe, bool rc) {
|
||||
|
@ -1602,20 +1646,19 @@ void PPULLVMRecompiler::ADDC(u32 rd, u32 ra, u32 rb, u32 oe, bool rc) {
|
|||
}
|
||||
|
||||
void PPULLVMRecompiler::MULHDU(u32 rd, u32 ra, u32 rb, bool rc) {
|
||||
auto ra_i64 = GetGpr(ra);
|
||||
auto rb_i64 = GetGpr(rb);
|
||||
auto ra_i128 = m_ir_builder->CreateZExt(ra_i64, m_ir_builder->getIntNTy(128));
|
||||
auto rb_i128 = m_ir_builder->CreateZExt(rb_i64, m_ir_builder->getIntNTy(128));
|
||||
auto prod_i128 = m_ir_builder->CreateMul(ra_i128, rb_i128);
|
||||
auto prod_v2i64 = m_ir_builder->CreateBitCast(prod_i128, VectorType::get(m_ir_builder->getInt64Ty(), 2));
|
||||
auto prod_i64 = m_ir_builder->CreateExtractElement(prod_v2i64, m_ir_builder->getInt32(1));
|
||||
auto ra_i64 = GetGpr(ra);
|
||||
auto rb_i64 = GetGpr(rb);
|
||||
auto ra_i128 = m_ir_builder->CreateZExt(ra_i64, m_ir_builder->getIntNTy(128));
|
||||
auto rb_i128 = m_ir_builder->CreateZExt(rb_i64, m_ir_builder->getIntNTy(128));
|
||||
auto prod_i128 = m_ir_builder->CreateMul(ra_i128, rb_i128);
|
||||
prod_i128 = m_ir_builder->CreateLShr(prod_i128, 64);
|
||||
auto prod_i64 = m_ir_builder->CreateTrunc(prod_i128, m_ir_builder->getInt64Ty());
|
||||
SetGpr(rd, prod_i64);
|
||||
|
||||
if (rc) {
|
||||
SetCrFieldSignedCmp(0, prod_i64, m_ir_builder->getInt64(0));
|
||||
}
|
||||
|
||||
// TODO: Check what code this generates
|
||||
//InterpreterCall("MULHDU", &PPUInterpreter::MULHDU, rd, ra, rb, rc);
|
||||
}
|
||||
|
||||
|
@ -1746,11 +1789,57 @@ void PPULLVMRecompiler::CMPL(u32 crfd, u32 l, u32 ra, u32 rb) {
|
|||
}
|
||||
|
||||
void PPULLVMRecompiler::LVSR(u32 vd, u32 ra, u32 rb) {
|
||||
InterpreterCall("LVSR", &PPUInterpreter::LVSR, vd, ra, rb);
|
||||
static const u128 s_lvsr_values[] = {
|
||||
{0x18191A1B1C1D1E1F, 0x1011121314151617},
|
||||
{0x1718191A1B1C1D1E, 0x0F10111213141516},
|
||||
{0x161718191A1B1C1D, 0x0E0F101112131415},
|
||||
{0x15161718191A1B1C, 0x0D0E0F1011121314},
|
||||
{0x1415161718191A1B, 0x0C0D0E0F10111213},
|
||||
{0x131415161718191A, 0x0B0C0D0E0F101112},
|
||||
{0x1213141516171819, 0x0A0B0C0D0E0F1011},
|
||||
{0x1112131415161718, 0x090A0B0C0D0E0F10},
|
||||
{0x1011121314151617, 0x08090A0B0C0D0E0F},
|
||||
{0x0F10111213141516, 0x0708090A0B0C0D0E},
|
||||
{0x0E0F101112131415, 0x060708090A0B0C0D},
|
||||
{0x0D0E0F1011121314, 0x05060708090A0B0C},
|
||||
{0x0C0D0E0F10111213, 0x0405060708090A0B},
|
||||
{0x0B0C0D0E0F101112, 0x030405060708090A},
|
||||
{0x0A0B0C0D0E0F1011, 0x0203040506070809},
|
||||
{0x090A0B0C0D0E0F10, 0x0102030405060708},
|
||||
};
|
||||
|
||||
auto addr_i64 = GetGpr(rb);
|
||||
if (ra) {
|
||||
auto ra_i64 = GetGpr(ra);
|
||||
addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64);
|
||||
}
|
||||
|
||||
auto index_i64 = m_ir_builder->CreateAnd(addr_i64, 0xF);
|
||||
auto lvsr_values_i28_ptr = m_ir_builder->CreateIntToPtr(m_ir_builder->getInt64((u64)s_lvsr_values), m_ir_builder->getIntNTy(128)->getPointerTo());
|
||||
lvsr_values_i28_ptr = m_ir_builder->CreateGEP(lvsr_values_i28_ptr, index_i64);
|
||||
auto val_i128 = m_ir_builder->CreateLoad(lvsr_values_i28_ptr);
|
||||
SetVr(vd, val_i128);
|
||||
|
||||
//InterpreterCall("LVSR", &PPUInterpreter::LVSR, vd, ra, rb);
|
||||
}
|
||||
|
||||
void PPULLVMRecompiler::LVEHX(u32 vd, u32 ra, u32 rb) {
|
||||
InterpreterCall("LVEHX", &PPUInterpreter::LVEHX, vd, ra, rb);
|
||||
auto addr_i64 = GetGpr(rb);
|
||||
if (ra) {
|
||||
auto ra_i64 = GetGpr(ra);
|
||||
addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64);
|
||||
}
|
||||
|
||||
addr_i64 = m_ir_builder->CreateAnd(addr_i64, 0xFFFFFFFFFFFFFFFEULL);
|
||||
auto val_i16 = ReadMemory(addr_i64, 16);
|
||||
auto index_i64 = m_ir_builder->CreateAnd(addr_i64, 0xf);
|
||||
index_i64 = m_ir_builder->CreateLShr(index_i64, 1);
|
||||
index_i64 = m_ir_builder->CreateSub(m_ir_builder->getInt64(7), index_i64);
|
||||
auto vd_v8i16 = GetVrAsIntVec(vd, 16);
|
||||
vd_v8i16 = m_ir_builder->CreateInsertElement(vd_v8i16, val_i16, index_i64);
|
||||
SetVr(vd, vd_v8i16);
|
||||
|
||||
//InterpreterCall("LVEHX", &PPUInterpreter::LVEHX, vd, ra, rb);
|
||||
}
|
||||
|
||||
void PPULLVMRecompiler::SUBF(u32 rd, u32 ra, u32 rb, u32 oe, bool rc) {
|
||||
|
@ -1781,7 +1870,8 @@ void PPULLVMRecompiler::LDUX(u32 rd, u32 ra, u32 rb) {
|
|||
}
|
||||
|
||||
void PPULLVMRecompiler::DCBST(u32 ra, u32 rb) {
|
||||
InterpreterCall("DCBST", &PPUInterpreter::DCBST, ra, rb);
|
||||
// TODO: Implement this
|
||||
//InterpreterCall("DCBST", &PPUInterpreter::DCBST, ra, rb);
|
||||
}
|
||||
|
||||
void PPULLVMRecompiler::LWZUX(u32 rd, u32 ra, u32 rb) {
|
||||
|
@ -1817,24 +1907,38 @@ void PPULLVMRecompiler::TD(u32 to, u32 ra, u32 rb) {
|
|||
}
|
||||
|
||||
void PPULLVMRecompiler::LVEWX(u32 vd, u32 ra, u32 rb) {
|
||||
InterpreterCall("LVEWX", &PPUInterpreter::LVEWX, vd, ra, rb);
|
||||
auto addr_i64 = GetGpr(rb);
|
||||
if (ra) {
|
||||
auto ra_i64 = GetGpr(ra);
|
||||
addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64);
|
||||
}
|
||||
|
||||
addr_i64 = m_ir_builder->CreateAnd(addr_i64, 0xFFFFFFFFFFFFFFFCULL);
|
||||
auto val_i32 = ReadMemory(addr_i64, 32);
|
||||
auto index_i64 = m_ir_builder->CreateAnd(addr_i64, 0xf);
|
||||
index_i64 = m_ir_builder->CreateLShr(index_i64, 2);
|
||||
index_i64 = m_ir_builder->CreateSub(m_ir_builder->getInt64(3), index_i64);
|
||||
auto vd_v4i32 = GetVrAsIntVec(vd, 32);
|
||||
vd_v4i32 = m_ir_builder->CreateInsertElement(vd_v4i32, val_i32, index_i64);
|
||||
SetVr(vd, vd_v4i32);
|
||||
|
||||
//InterpreterCall("LVEWX", &PPUInterpreter::LVEWX, vd, ra, rb);
|
||||
}
|
||||
|
||||
void PPULLVMRecompiler::MULHD(u32 rd, u32 ra, u32 rb, bool rc) {
|
||||
auto ra_i64 = GetGpr(ra);
|
||||
auto rb_i64 = GetGpr(rb);
|
||||
auto ra_i128 = m_ir_builder->CreateSExt(ra_i64, m_ir_builder->getIntNTy(128));
|
||||
auto rb_i128 = m_ir_builder->CreateSExt(rb_i64, m_ir_builder->getIntNTy(128));
|
||||
auto prod_i128 = m_ir_builder->CreateMul(ra_i128, rb_i128);
|
||||
auto prod_v2i64 = m_ir_builder->CreateBitCast(prod_i128, VectorType::get(m_ir_builder->getInt64Ty(), 2));
|
||||
auto prod_i64 = m_ir_builder->CreateExtractElement(prod_v2i64, m_ir_builder->getInt32(1));
|
||||
auto ra_i64 = GetGpr(ra);
|
||||
auto rb_i64 = GetGpr(rb);
|
||||
auto ra_i128 = m_ir_builder->CreateSExt(ra_i64, m_ir_builder->getIntNTy(128));
|
||||
auto rb_i128 = m_ir_builder->CreateSExt(rb_i64, m_ir_builder->getIntNTy(128));
|
||||
auto prod_i128 = m_ir_builder->CreateMul(ra_i128, rb_i128);
|
||||
prod_i128 = m_ir_builder->CreateLShr(prod_i128, 64);
|
||||
auto prod_i64 = m_ir_builder->CreateTrunc(prod_i128, m_ir_builder->getInt64Ty());
|
||||
SetGpr(rd, prod_i64);
|
||||
|
||||
if (rc) {
|
||||
SetCrFieldSignedCmp(0, prod_i64, m_ir_builder->getInt64(0));
|
||||
}
|
||||
|
||||
// TODO: Check what code this generates
|
||||
//InterpreterCall("MULHD", &PPUInterpreter::MULHD, rd, ra, rb, rc);
|
||||
}
|
||||
|
||||
|
@ -1858,7 +1962,8 @@ void PPULLVMRecompiler::LDARX(u32 rd, u32 ra, u32 rb) {
|
|||
}
|
||||
|
||||
void PPULLVMRecompiler::DCBF(u32 ra, u32 rb) {
|
||||
InterpreterCall("DCBF", &PPUInterpreter::DCBF, ra, rb);
|
||||
// TODO: Implement this
|
||||
//InterpreterCall("DCBF", &PPUInterpreter::DCBF, ra, rb);
|
||||
}
|
||||
|
||||
void PPULLVMRecompiler::LBZX(u32 rd, u32 ra, u32 rb) {
|
||||
|
@ -2099,7 +2204,8 @@ void PPULLVMRecompiler::MULLW(u32 rd, u32 ra, u32 rb, u32 oe, bool rc) {
|
|||
}
|
||||
|
||||
void PPULLVMRecompiler::DCBTST(u32 ra, u32 rb, u32 th) {
|
||||
InterpreterCall("DCBTST", &PPUInterpreter::DCBTST, ra, rb, th);
|
||||
// TODO: Implement this
|
||||
//InterpreterCall("DCBTST", &PPUInterpreter::DCBTST, ra, rb, th);
|
||||
}
|
||||
|
||||
void PPULLVMRecompiler::STBUX(u32 rs, u32 ra, u32 rb) {
|
||||
|
@ -2129,7 +2235,8 @@ void PPULLVMRecompiler::ADD(u32 rd, u32 ra, u32 rb, u32 oe, bool rc) {
|
|||
}
|
||||
|
||||
void PPULLVMRecompiler::DCBT(u32 ra, u32 rb, u32 th) {
|
||||
InterpreterCall("DCBT", &PPUInterpreter::DCBT, ra, rb, th);
|
||||
// TODO: Implement this using prefetch
|
||||
//InterpreterCall("DCBT", &PPUInterpreter::DCBT, ra, rb, th);
|
||||
}
|
||||
|
||||
void PPULLVMRecompiler::LHZX(u32 rd, u32 ra, u32 rb) {
|
||||
|
@ -2239,7 +2346,22 @@ void PPULLVMRecompiler::LVXL(u32 vd, u32 ra, u32 rb) {
|
|||
}
|
||||
|
||||
void PPULLVMRecompiler::MFTB(u32 rd, u32 spr) {
|
||||
InterpreterCall("MFTB", &PPUInterpreter::MFTB, rd, spr);
|
||||
static Function * s_get_time_fn = nullptr;
|
||||
|
||||
if (s_get_time_fn == nullptr) {
|
||||
s_get_time_fn = (Function *)m_module->getOrInsertFunction("get_time", m_ir_builder->getInt64Ty(), nullptr);
|
||||
s_get_time_fn->setCallingConv(CallingConv::X86_64_Win64);
|
||||
m_execution_engine->addGlobalMapping(s_get_time_fn, (void *)get_time);
|
||||
}
|
||||
|
||||
auto tb_i64 = (Value *)m_ir_builder->CreateCall(s_get_time_fn);
|
||||
|
||||
u32 n = (spr >> 5) | ((spr & 0x1f) << 5);
|
||||
if (n == 0x10D) {
|
||||
tb_i64 = m_ir_builder->CreateLShr(tb_i64, 32);
|
||||
}
|
||||
|
||||
SetGpr(rd, tb_i64);
|
||||
}
|
||||
|
||||
void PPULLVMRecompiler::LWAUX(u32 rd, u32 ra, u32 rb) {
|
||||
|
@ -2408,7 +2530,20 @@ void PPULLVMRecompiler::DIVW(u32 rd, u32 ra, u32 rb, u32 oe, bool rc) {
|
|||
}
|
||||
|
||||
void PPULLVMRecompiler::LVLX(u32 vd, u32 ra, u32 rb) {
|
||||
InterpreterCall("LVLX", &PPUInterpreter::LVLX, vd, ra, rb);
|
||||
auto addr_i64 = GetGpr(rb);
|
||||
if (ra) {
|
||||
auto ra_i64 = GetGpr(ra);
|
||||
addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64);
|
||||
}
|
||||
|
||||
auto eb_i64 = m_ir_builder->CreateAnd(addr_i64, 0xF);
|
||||
eb_i64 = m_ir_builder->CreateShl(eb_i64, 3);
|
||||
auto eb_i128 = m_ir_builder->CreateZExt(eb_i64, m_ir_builder->getIntNTy(128));
|
||||
addr_i64 = m_ir_builder->CreateAnd(addr_i64, 0xFFFFFFFFFFFFFFF0ULL);
|
||||
auto mem_i128 = ReadMemory(addr_i64, 128);
|
||||
mem_i128 = m_ir_builder->CreateShl(mem_i128, eb_i128);
|
||||
SetVr(vd, mem_i128);
|
||||
//InterpreterCall("LVLX", &PPUInterpreter::LVLX, vd, ra, rb);
|
||||
}
|
||||
|
||||
void PPULLVMRecompiler::LDBRX(u32 rd, u32 ra, u32 rb) {
|
||||
|
@ -2504,7 +2639,8 @@ void PPULLVMRecompiler::LFSUX(u32 frd, u32 ra, u32 rb) {
|
|||
}
|
||||
|
||||
void PPULLVMRecompiler::SYNC(u32 l) {
|
||||
InterpreterCall("SYNC", &PPUInterpreter::SYNC, l);
|
||||
m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::x86_sse2_mfence));
|
||||
//InterpreterCall("SYNC", &PPUInterpreter::SYNC, l);
|
||||
}
|
||||
|
||||
void PPULLVMRecompiler::LFDX(u32 frd, u32 ra, u32 rb) {
|
||||
|
@ -2799,7 +2935,20 @@ void PPULLVMRecompiler::ICBI(u32 ra, u32 rs) {
|
|||
}
|
||||
|
||||
void PPULLVMRecompiler::DCBZ(u32 ra, u32 rb) {
|
||||
InterpreterCall("DCBZ", &PPUInterpreter::DCBZ, ra, rb);
|
||||
auto addr_i64 = GetGpr(rb);
|
||||
if (ra) {
|
||||
auto ra_i64 = GetGpr(ra);
|
||||
addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64);
|
||||
}
|
||||
|
||||
addr_i64 = m_ir_builder->CreateAnd(addr_i64, ~(127ULL));
|
||||
addr_i64 = m_ir_builder->CreateAdd(addr_i64, m_ir_builder->getInt64((u64)vm::get_ptr<u8>(0)));
|
||||
auto addr_i8_ptr = m_ir_builder->CreateIntToPtr(addr_i64, m_ir_builder->getInt8PtrTy());
|
||||
|
||||
std::vector<Type *> types = {(Type *)m_ir_builder->getInt8PtrTy(), (Type *)m_ir_builder->getInt32Ty()};
|
||||
m_ir_builder->CreateCall5(Intrinsic::getDeclaration(m_module, Intrinsic::memset, types),
|
||||
addr_i8_ptr, m_ir_builder->getInt8(0), m_ir_builder->getInt32(128), m_ir_builder->getInt32(128), m_ir_builder->getInt1(true));
|
||||
//InterpreterCall("DCBZ", &PPUInterpreter::DCBZ, ra, rb);L
|
||||
}
|
||||
|
||||
void PPULLVMRecompiler::LWZ(u32 rd, u32 ra, s32 d) {
|
||||
|
@ -3466,12 +3615,10 @@ void PPULLVMRecompiler::Compile(u32 address) {
|
|||
auto function_name = fmt::Format("fn_0x%X_%u", address, revision);
|
||||
m_current_function = (Function *)m_module->getOrInsertFunction(function_name, m_ir_builder->getVoidTy(),
|
||||
m_ir_builder->getInt8PtrTy() /*ppu_state*/,
|
||||
m_ir_builder->getInt64Ty() /*base_addres*/,
|
||||
m_ir_builder->getInt8PtrTy() /*interpreter*/, nullptr);
|
||||
m_current_function->setCallingConv(CallingConv::X86_64_Win64);
|
||||
auto arg_i = m_current_function->arg_begin();
|
||||
arg_i->setName("ppu_state");
|
||||
(++arg_i)->setName("base_address");
|
||||
(++arg_i)->setName("interpreter");
|
||||
|
||||
// Add an entry block that branches to the first instruction
|
||||
|
@ -3607,16 +3754,9 @@ Value * PPULLVMRecompiler::GetPPUState() {
|
|||
return m_current_function->arg_begin();
|
||||
}
|
||||
|
||||
Value * PPULLVMRecompiler::GetBaseAddress() {
|
||||
auto i = m_current_function->arg_begin();
|
||||
i++;
|
||||
return i;
|
||||
}
|
||||
|
||||
Value * PPULLVMRecompiler::GetInterpreter() {
|
||||
auto i = m_current_function->arg_begin();
|
||||
i++;
|
||||
i++;
|
||||
return i;
|
||||
}
|
||||
|
||||
|
@ -4073,7 +4213,7 @@ void PPULLVMRecompiler::CreateBranch(llvm::Value * cmp_i1, llvm::Value * target_
|
|||
|
||||
Value * PPULLVMRecompiler::ReadMemory(Value * addr_i64, u32 bits, bool bswap) {
|
||||
if (bits != 32) {
|
||||
auto eaddr_i64 = m_ir_builder->CreateAdd(addr_i64, GetBaseAddress());
|
||||
auto eaddr_i64 = m_ir_builder->CreateAdd(addr_i64, m_ir_builder->getInt64((u64)vm::get_ptr<u8>(0)));
|
||||
auto eaddr_ix_ptr = m_ir_builder->CreateIntToPtr(eaddr_i64, m_ir_builder->getIntNTy(bits)->getPointerTo());
|
||||
auto val_ix = (Value *)m_ir_builder->CreateLoad(eaddr_ix_ptr);
|
||||
if (bits > 8 && bswap) {
|
||||
|
@ -4101,7 +4241,7 @@ Value * PPULLVMRecompiler::ReadMemory(Value * addr_i64, u32 bits, bool bswap) {
|
|||
m_ir_builder->CreateCondBr(cmp_i1, then_bb, else_bb);
|
||||
|
||||
m_ir_builder->SetInsertPoint(then_bb);
|
||||
auto eaddr_i64 = m_ir_builder->CreateAdd(addr_i64, GetBaseAddress());
|
||||
auto eaddr_i64 = m_ir_builder->CreateAdd(addr_i64, m_ir_builder->getInt64((u64)vm::get_ptr<u8>(0)));
|
||||
auto eaddr_i32_ptr = m_ir_builder->CreateIntToPtr(eaddr_i64, m_ir_builder->getInt32Ty()->getPointerTo());
|
||||
auto val_then_i32 = (Value *)m_ir_builder->CreateLoad(eaddr_i32_ptr);
|
||||
if (bswap) {
|
||||
|
@ -4132,7 +4272,7 @@ void PPULLVMRecompiler::WriteMemory(Value * addr_i64, Value * val_ix, bool bswap
|
|||
val_ix = m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::bswap, {val_ix->getType()}), val_ix);
|
||||
}
|
||||
|
||||
auto eaddr_i64 = m_ir_builder->CreateAdd(addr_i64, GetBaseAddress());
|
||||
auto eaddr_i64 = m_ir_builder->CreateAdd(addr_i64, m_ir_builder->getInt64((u64)vm::get_ptr<u8>(0)));
|
||||
auto eaddr_ix_ptr = m_ir_builder->CreateIntToPtr(eaddr_i64, val_ix->getType()->getPointerTo());
|
||||
m_ir_builder->CreateStore(val_ix, eaddr_ix_ptr);
|
||||
} else {
|
||||
|
@ -4160,7 +4300,7 @@ void PPULLVMRecompiler::WriteMemory(Value * addr_i64, Value * val_ix, bool bswap
|
|||
val_then_i32 = m_ir_builder->CreateCall(Intrinsic::getDeclaration(m_module, Intrinsic::bswap, {m_ir_builder->getInt32Ty()}), val_then_i32);
|
||||
}
|
||||
|
||||
auto eaddr_i64 = m_ir_builder->CreateAdd(addr_i64, GetBaseAddress());
|
||||
auto eaddr_i64 = m_ir_builder->CreateAdd(addr_i64, m_ir_builder->getInt64((u64)vm::get_ptr<u8>(0)));
|
||||
auto eaddr_i32_ptr = m_ir_builder->CreateIntToPtr(eaddr_i64, m_ir_builder->getInt32Ty()->getPointerTo());
|
||||
m_ir_builder->CreateStore(val_then_i32, eaddr_i32_ptr);
|
||||
m_ir_builder->CreateBr(merge_bb);
|
||||
|
@ -4255,7 +4395,7 @@ PPULLVMEmulator::PPULLVMEmulator(PPUThread & ppu)
|
|||
s_num_instances++;
|
||||
if (!s_recompiler) {
|
||||
s_recompiler = new PPULLVMRecompiler();
|
||||
//s_recompiler->RunAllTests(&m_ppu, (u64)Memory.GetBaseAddr(), m_interpreter);
|
||||
//s_recompiler->RunAllTests(&m_ppu, m_interpreter);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4327,7 +4467,7 @@ u8 PPULLVMEmulator::DecodeMemory(const u32 address) {
|
|||
|
||||
u8 ret = 0;
|
||||
if (address_to_executable_iter != m_address_to_executable.end()) {
|
||||
address_to_executable_iter->second.executable(&m_ppu, (u64)Memory.GetBaseAddr(), m_interpreter);
|
||||
address_to_executable_iter->second.executable(&m_ppu, m_interpreter);
|
||||
address_to_executable_iter->second.num_hits++;
|
||||
m_last_instr_was_branch = true;
|
||||
} else {
|
||||
|
|
|
@ -16,7 +16,7 @@ struct PPURegState;
|
|||
/// PPU recompiler that uses LLVM for code generation and optimization
|
||||
class PPULLVMRecompiler : public ThreadBase, protected PPUOpcodes, protected PPCDecoder {
|
||||
public:
|
||||
typedef void(*Executable)(PPUThread * ppu_state, u64 base_address, PPUInterpreter * interpreter);
|
||||
typedef void(*Executable)(PPUThread * ppu_state, PPUInterpreter * interpreter);
|
||||
|
||||
PPULLVMRecompiler();
|
||||
|
||||
|
@ -41,7 +41,7 @@ public:
|
|||
u32 GetCurrentRevision();
|
||||
|
||||
/// Execute all tests
|
||||
void RunAllTests(PPUThread * ppu_state, u64 base_address, PPUInterpreter * interpreter);
|
||||
void RunAllTests(PPUThread * ppu_state, PPUInterpreter * interpreter);
|
||||
|
||||
void Task() override;
|
||||
|
||||
|
@ -560,9 +560,6 @@ private:
|
|||
/// Get PPU state pointer
|
||||
llvm::Value * GetPPUState();
|
||||
|
||||
/// Get base address
|
||||
llvm::Value * GetBaseAddress();
|
||||
|
||||
/// Get interpreter pointer
|
||||
llvm::Value * GetInterpreter();
|
||||
|
||||
|
|
|
@ -158,7 +158,6 @@ struct PPURegState {
|
|||
};
|
||||
|
||||
static PPUThread * s_ppu_state = nullptr;
|
||||
static u64 s_base_address = 0;
|
||||
static PPUInterpreter * s_interpreter = nullptr;
|
||||
|
||||
template <class PPULLVMRecompilerFn, class PPUInterpreterFn, class... Args>
|
||||
|
@ -222,6 +221,9 @@ void PPULLVMRecompiler::RunTest(const char * name, std::function<void()> test_ca
|
|||
return;
|
||||
}
|
||||
|
||||
// Optimize
|
||||
m_fpm->run(*m_current_function);
|
||||
|
||||
// Generate the function
|
||||
MachineCodeInfo mci;
|
||||
m_execution_engine->runJITOnFunction(m_current_function, &mci);
|
||||
|
@ -244,9 +246,6 @@ void PPULLVMRecompiler::RunTest(const char * name, std::function<void()> test_ca
|
|||
input();
|
||||
std::vector<GenericValue> args;
|
||||
args.push_back(GenericValue(s_ppu_state));
|
||||
GenericValue base_address;
|
||||
base_address.IntVal = APInt(64, s_base_address);
|
||||
args.push_back(base_address);
|
||||
args.push_back(GenericValue(s_interpreter));
|
||||
m_execution_engine->runFunction(m_current_function, args);
|
||||
|
||||
|
@ -262,10 +261,9 @@ void PPULLVMRecompiler::RunTest(const char * name, std::function<void()> test_ca
|
|||
m_execution_engine->freeMachineCodeForFunction(m_current_function);
|
||||
}
|
||||
|
||||
void PPULLVMRecompiler::RunAllTests(PPUThread * ppu_state, u64 base_address, PPUInterpreter * interpreter) {
|
||||
s_ppu_state = ppu_state;
|
||||
s_base_address = base_address;
|
||||
s_interpreter = interpreter;
|
||||
void PPULLVMRecompiler::RunAllTests(PPUThread * ppu_state, PPUInterpreter * interpreter) {
|
||||
s_ppu_state = ppu_state;
|
||||
s_interpreter = interpreter;
|
||||
|
||||
PPURegState initial_state;
|
||||
initial_state.Load(*ppu_state);
|
||||
|
@ -492,7 +490,7 @@ void PPULLVMRecompiler::RunAllTests(PPUThread * ppu_state, u64 base_address, PPU
|
|||
input.GPR[14] = 10;
|
||||
input.GPR[23] = 0x10000;
|
||||
for (int i = 0; i < 1000; i++) {
|
||||
((u8*)base_address)[i + 0x10000] = (u8)i;
|
||||
vm::write8(i + 0x10000, i);
|
||||
}
|
||||
|
||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LBZ, 0, input, 5, 0, 0x10000);
|
||||
|
@ -549,6 +547,18 @@ void PPULLVMRecompiler::RunAllTests(PPUThread * ppu_state, u64 base_address, PPU
|
|||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LVX, 1, input, 5, 14, 23);
|
||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LVXL, 0, input, 5, 0, 23);
|
||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LVXL, 1, input, 5, 14, 23);
|
||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LVLX, 0, input, 5, 0, 23);
|
||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LVLX, 1, input, 5, 14, 23);
|
||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LVSL, 0, input, 5, 0, 23);
|
||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LVSL, 1, input, 5, 14, 23);
|
||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LVSR, 0, input, 5, 0, 23);
|
||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LVSR, 1, input, 5, 14, 23);
|
||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LVEBX, 0, input, 5, 0, 23);
|
||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LVEBX, 1, input, 5, 14, 23);
|
||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LVEHX, 0, input, 5, 0, 23);
|
||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LVEHX, 1, input, 5, 14, 23);
|
||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LVEWX, 0, input, 5, 0, 23);
|
||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LVEWX, 1, input, 5, 14, 23);
|
||||
|
||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STB, 0, input, 3, 0, 0x10000);
|
||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STB, 1, input, 3, 14, 0x10000);
|
||||
|
@ -593,6 +603,8 @@ void PPULLVMRecompiler::RunAllTests(PPUThread * ppu_state, u64 base_address, PPU
|
|||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STVX, 1, input, 5, 14, 23);
|
||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STVXL, 0, input, 5, 0, 23);
|
||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STVXL, 1, input, 5, 14, 23);
|
||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER(DCBZ, 0, input, 0, 23);
|
||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER(DCBZ, 1, input, 14, 23);
|
||||
|
||||
initial_state.Store(*ppu_state);
|
||||
}
|
||||
|
|
|
@ -796,15 +796,6 @@ protected:
|
|||
virtual void DoPause() override;
|
||||
virtual void DoResume() override;
|
||||
virtual void DoStop() override;
|
||||
|
||||
virtual void Step() override
|
||||
{
|
||||
//if(++cycle > 20)
|
||||
{
|
||||
TB++;
|
||||
//cycle = 0;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
PPUThread& GetCurrentPPUThread();
|
||||
|
|
Loading…
Add table
Reference in a new issue