diff --git a/rpcs3/Emu/Cell/PPUInterpreter.h b/rpcs3/Emu/Cell/PPUInterpreter.h index e3fa46ac82..ee11db1d5a 100644 --- a/rpcs3/Emu/Cell/PPUInterpreter.h +++ b/rpcs3/Emu/Cell/PPUInterpreter.h @@ -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 #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; diff --git a/rpcs3/Emu/Cell/PPULLVMRecompiler.cpp b/rpcs3/Emu/Cell/PPULLVMRecompiler.cpp index 262dadafb3..a728748064 100644 --- a/rpcs3/Emu/Cell/PPULLVMRecompiler.cpp +++ b/rpcs3/Emu/Cell/PPULLVMRecompiler.cpp @@ -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(0))); + auto addr_i8_ptr = m_ir_builder->CreateIntToPtr(addr_i64, m_ir_builder->getInt8PtrTy()); + + std::vector 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(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(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(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(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 { diff --git a/rpcs3/Emu/Cell/PPULLVMRecompiler.h b/rpcs3/Emu/Cell/PPULLVMRecompiler.h index 35cec9a6e8..0c7b3e2102 100644 --- a/rpcs3/Emu/Cell/PPULLVMRecompiler.h +++ b/rpcs3/Emu/Cell/PPULLVMRecompiler.h @@ -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(); diff --git a/rpcs3/Emu/Cell/PPULLVMRecompilerTests.cpp b/rpcs3/Emu/Cell/PPULLVMRecompilerTests.cpp index d244ef6cfc..5ed6a6791d 100644 --- a/rpcs3/Emu/Cell/PPULLVMRecompilerTests.cpp +++ b/rpcs3/Emu/Cell/PPULLVMRecompilerTests.cpp @@ -158,7 +158,6 @@ struct PPURegState { }; static PPUThread * s_ppu_state = nullptr; -static u64 s_base_address = 0; static PPUInterpreter * s_interpreter = nullptr; template @@ -222,6 +221,9 @@ void PPULLVMRecompiler::RunTest(const char * name, std::function 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 test_ca input(); std::vector 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 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); } diff --git a/rpcs3/Emu/Cell/PPUThread.h b/rpcs3/Emu/Cell/PPUThread.h index 34021a2d6a..1f408210b9 100644 --- a/rpcs3/Emu/Cell/PPUThread.h +++ b/rpcs3/Emu/Cell/PPUThread.h @@ -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();