diff --git a/rpcs3/Emu/Cell/PPULLVMRecompiler.cpp b/rpcs3/Emu/Cell/PPULLVMRecompiler.cpp index 9828b6a0ce..3ab2ab6bd5 100644 --- a/rpcs3/Emu/Cell/PPULLVMRecompiler.cpp +++ b/rpcs3/Emu/Cell/PPULLVMRecompiler.cpp @@ -82,6 +82,8 @@ Compiler::Compiler(RecompilationEngine & recompilation_engine, const Executable InitRotateMask(); s_rotate_mask_inited = true; } + + RunAllTests(); } Compiler::~Compiler() { @@ -4727,10 +4729,13 @@ Value * Compiler::ReadMemory(Value * addr_i64, u32 bits, u32 alignment, bool bsw return val_ix; } else { + static u32 next_basic_block_id = 0; + + next_basic_block_id++; auto cmp_i1 = m_ir_builder->CreateICmpULT(addr_i64, m_ir_builder->getInt64(RAW_SPU_BASE_ADDR)); - auto then_bb = GetBasicBlockFromAddress(m_state.current_instruction_address, "then"); - auto else_bb = GetBasicBlockFromAddress(m_state.current_instruction_address, "else"); - auto merge_bb = GetBasicBlockFromAddress(m_state.current_instruction_address, "merge"); + auto then_bb = GetBasicBlockFromAddress(m_state.current_instruction_address, fmt::Format("then_%u", next_basic_block_id)); + auto else_bb = GetBasicBlockFromAddress(m_state.current_instruction_address, fmt::Format("else_%u", next_basic_block_id)); + auto merge_bb = GetBasicBlockFromAddress(m_state.current_instruction_address, fmt::Format("merge_%u", next_basic_block_id)); m_ir_builder->CreateCondBr(cmp_i1, then_bb, else_bb); m_ir_builder->SetInsertPoint(then_bb); @@ -4769,10 +4774,13 @@ void Compiler::WriteMemory(Value * addr_i64, Value * val_ix, u32 alignment, bool auto eaddr_ix_ptr = m_ir_builder->CreateIntToPtr(eaddr_i64, val_ix->getType()->getPointerTo()); m_ir_builder->CreateAlignedStore(val_ix, eaddr_ix_ptr, alignment); } else { + static u32 next_basic_block_id; + + next_basic_block_id++; auto cmp_i1 = m_ir_builder->CreateICmpULT(addr_i64, m_ir_builder->getInt64(RAW_SPU_BASE_ADDR)); - auto then_bb = GetBasicBlockFromAddress(m_state.current_instruction_address, "then"); - auto else_bb = GetBasicBlockFromAddress(m_state.current_instruction_address, "else"); - auto merge_bb = GetBasicBlockFromAddress(m_state.current_instruction_address, "merge"); + auto then_bb = GetBasicBlockFromAddress(m_state.current_instruction_address, fmt::Format("then_%u", next_basic_block_id)); + auto else_bb = GetBasicBlockFromAddress(m_state.current_instruction_address, fmt::Format("else_%u", next_basic_block_id)); + auto merge_bb = GetBasicBlockFromAddress(m_state.current_instruction_address, fmt::Format("merge_%u", next_basic_block_id)); m_ir_builder->CreateCondBr(cmp_i1, then_bb, else_bb); m_ir_builder->SetInsertPoint(then_bb); @@ -5118,7 +5126,7 @@ void RecompilationEngine::UpdateControlFlowGraph(ControlFlowGraph & cfg, const E void RecompilationEngine::CompileBlock(BlockEntry & block_entry) { #ifdef _DEBUG Log() << "Compile: " << block_entry.ToString() << "\n"; - Log() << "CFG: " << cfg->ToString() << "\n"; + Log() << "CFG: " << block_entry.cfg.ToString() << "\n"; #endif auto ordinal = AllocateOrdinal(block_entry.cfg.start_address, block_entry.IsFunction()); diff --git a/rpcs3/Emu/Cell/PPULLVMRecompiler.h b/rpcs3/Emu/Cell/PPULLVMRecompiler.h index 3731b345ea..fe1371f6d3 100644 --- a/rpcs3/Emu/Cell/PPULLVMRecompiler.h +++ b/rpcs3/Emu/Cell/PPULLVMRecompiler.h @@ -295,7 +295,7 @@ namespace ppu_recompiler_llvm { Stats GetStats(); /// Execute all tests - void RunAllTests(PPUThread * ppu_state, PPUInterpreter * interpreter); + void RunAllTests(); protected: void Decode(const u32 code) override; diff --git a/rpcs3/Emu/Cell/PPULLVMRecompilerTests.cpp b/rpcs3/Emu/Cell/PPULLVMRecompilerTests.cpp index 1a1ee9c68a..48e9f27641 100644 --- a/rpcs3/Emu/Cell/PPULLVMRecompilerTests.cpp +++ b/rpcs3/Emu/Cell/PPULLVMRecompilerTests.cpp @@ -222,8 +222,8 @@ void Compiler::VerifyInstructionAgainstInterpreter(const char * name, CompilerFn if (interp_output_state.ToString() != recomp_output_state.ToString()) { msg = std::string("Input state:\n") + input_state.ToString() + - std::string("\nOutput state:\n") + recomp_output_state.ToString() + - std::string("\nInterpreter output state:\n") + interp_output_state.ToString(); + std::string("\nOutput state:\n") + recomp_output_state.ToString() + + std::string("\nInterpreter output state:\n") + interp_output_state.ToString(); return false; } @@ -235,48 +235,49 @@ void Compiler::VerifyInstructionAgainstInterpreter(const char * name, CompilerFn void Compiler::RunTest(const char * name, std::function test_case, std::function input, std::function check_result) { #ifdef PPU_LLVM_RECOMPILER_UNIT_TESTS - // Create the unit test function - m_current_function = (Function *)m_module->getOrInsertFunction(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(); + // Create the function + m_state.function = (Function *)m_module->getOrInsertFunction(name, m_compiled_function_type); + m_state.function->setCallingConv(CallingConv::X86_64_Win64); + auto arg_i = m_state.function->arg_begin(); arg_i->setName("ppu_state"); - (++arg_i)->setName("base_address"); + m_state.args[CompileTaskState::Args::State] = arg_i; (++arg_i)->setName("interpreter"); + m_state.args[CompileTaskState::Args::Interpreter] = arg_i; + (++arg_i)->setName("context"); + m_state.args[CompileTaskState::Args::Context] = arg_i; + m_state.current_instruction_address = s_ppu_state->PC; - auto block = BasicBlock::Create(*m_llvm_context, "start", m_current_function); + auto block = BasicBlock::Create(*m_llvm_context, "start", m_state.function); m_ir_builder->SetInsertPoint(block); test_case(); - m_ir_builder->CreateRetVoid(); + m_ir_builder->CreateRet(m_ir_builder->getInt32(0)); // Print the IR std::string ir; raw_string_ostream ir_ostream(ir); - m_current_function->print(ir_ostream); + m_state.function->print(ir_ostream); LOG_NOTICE(PPU, "[UT %s] LLVM IR:%s", name, ir.c_str()); std::string verify; raw_string_ostream verify_ostream(verify); - if (verifyFunction(*m_current_function, &verify_ostream)) { + if (verifyFunction(*m_state.function, &verify_ostream)) { LOG_ERROR(PPU, "[UT %s] Verification Failed:%s", name, verify.c_str()); return; } // Optimize - m_fpm->run(*m_current_function); + m_fpm->run(*m_state.function); // Print the optimized IR ir = ""; - m_current_function->print(ir_ostream); + m_state.function->print(ir_ostream); LOG_NOTICE(PPU, "[UT %s] Optimized LLVM IR:%s", name, ir.c_str()); // Generate the function MachineCodeInfo mci; - m_execution_engine->runJITOnFunction(m_current_function, &mci); + m_execution_engine->runJITOnFunction(m_state.function, &mci); // Disassemble the generated function auto disassembler = LLVMCreateDisasm(sys::getProcessTriple().c_str(), nullptr, 0, nullptr, nullptr); @@ -294,10 +295,8 @@ void Compiler::RunTest(const char * name, std::function test_case, std:: // Run the test input(); - std::vector args; - args.push_back(GenericValue(s_ppu_state)); - args.push_back(GenericValue(s_interpreter)); - m_execution_engine->runFunction(m_current_function, args); + auto executable = (Executable)m_execution_engine->getPointerToFunction(m_state.function); + executable(s_ppu_state, s_interpreter, 0); // Verify results std::string msg; @@ -308,17 +307,17 @@ void Compiler::RunTest(const char * name, std::function test_case, std:: LOG_ERROR(PPU, "[UT %s] Test failed. %s", name, msg.c_str()); } - m_execution_engine->freeMachineCodeForFunction(m_current_function); + m_execution_engine->freeMachineCodeForFunction(m_state.function); #endif // PPU_LLVM_RECOMPILER_UNIT_TESTS } -void Compiler::RunAllTests(PPUThread * ppu_state, PPUInterpreter * interpreter) { +void Compiler::RunAllTests() { #ifdef PPU_LLVM_RECOMPILER_UNIT_TESTS - s_ppu_state = ppu_state; - s_interpreter = interpreter; + PPUThread ppu_state; + PPUInterpreter interpreter(ppu_state); - PPUState initial_state; - initial_state.Load(*ppu_state, 0x10000); + s_ppu_state = &ppu_state; + s_interpreter = &interpreter; LOG_NOTICE(PPU, "Running Unit Tests"); @@ -595,12 +594,14 @@ void Compiler::RunAllTests(PPUThread * ppu_state, PPUInterpreter * interpreter) VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(CNTLZW, 5, 5, 5, 6, 1); VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(CNTLZD, 0, 5, 5, 6, 0); VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(CNTLZD, 5, 5, 5, 6, 1); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(ANDC, 0, 5, 5, 6, 7, 0); + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(ANDC, 5, 5, 5, 6, 7, 1); VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(ISYNC, 0, 5); VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(EIEIO, 0, 5); VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(FSQRT, 0, 5, 0, 1, false); VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(FSQRTS, 0, 5, 0, 1, false); - + VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(FDIV, 0, 5, 0, 1, 2, false); VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(FSUB, 0, 5, 0, 1, 2, false); VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(FADD, 0, 5, 0, 1, 2, false); @@ -616,7 +617,7 @@ void Compiler::RunAllTests(PPUThread * ppu_state, PPUInterpreter * interpreter) VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(FCFID, 0, 5, 0, 1, false); VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(FCTID, 0, 5, 0, 1, false); VERIFY_INSTRUCTION_AGAINST_INTERPRETER_USING_RANDOM_INPUT(FCTIW, 0, 5, 0, 1, false); - + PPUState input; input.SetRandom(0x10000); input.GPR[14] = 10; @@ -766,7 +767,5 @@ void Compiler::RunAllTests(PPUThread * ppu_state, PPUInterpreter * interpreter) VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STSWI, 3, input, 5, 23, 25); VERIFY_INSTRUCTION_AGAINST_INTERPRETER(DCBZ, 0, input, 0, 23); VERIFY_INSTRUCTION_AGAINST_INTERPRETER(DCBZ, 1, input, 14, 23); - - initial_state.Store(*ppu_state); #endif // PPU_LLVM_RECOMPILER_UNIT_TESTS } diff --git a/rpcs3/emucore.vcxproj b/rpcs3/emucore.vcxproj index 2da63c0f47..913cfa065f 100644 --- a/rpcs3/emucore.vcxproj +++ b/rpcs3/emucore.vcxproj @@ -771,7 +771,7 @@ ..\llvm_build\Release\lib - LLVMJIT.lib;LLVMVectorize.lib;LLVMX86CodeGen.lib;LLVMX86Disassembler.lib;LLVMExecutionEngine.lib;LLVMAsmPrinter.lib;LLVMSelectionDAG.lib;LLVMCodeGen.lib;LLVMScalarOpts.lib;LLVMInstCombine.lib;LLVMTransformUtils.lib;LLVMipa.lib;LLVMAnalysis.lib;LLVMTarget.lib;LLVMX86Desc.lib;LLVMX86AsmPrinter.lib;LLVMObject.lib;LLVMMCParser.lib;LLVMBitReader.lib;LLVMCore.lib;LLVMX86Utils.lib;LLVMMC.lib;LLVMX86Info.lib;LLVMSupport.lib + LLVMJIT.lib;LLVMVectorize.lib;LLVMX86CodeGen.lib;LLVMX86Disassembler.lib;LLVMExecutionEngine.lib;LLVMAsmPrinter.lib;LLVMSelectionDAG.lib;LLVMCodeGen.lib;LLVMScalarOpts.lib;LLVMInstCombine.lib;LLVMTransformUtils.lib;LLVMipa.lib;LLVMAnalysis.lib;LLVMTarget.lib;LLVMX86Desc.lib;LLVMX86AsmPrinter.lib;LLVMObject.lib;LLVMMCParser.lib;LLVMBitReader.lib;LLVMCore.lib;LLVMX86Utils.lib;LLVMMC.lib;LLVMX86Info.lib;LLVMSupport.lib;LLVMMCDisassembler.lib