mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-03-01 07:13:36 +00:00
llvm: Implement trap instructions
This commit is contained in:
parent
2da52d0309
commit
082815f93e
@ -362,6 +362,17 @@ static void wrapped_fast_stop(PPUThread &CPU)
|
||||
CPU.fast_stop();
|
||||
}
|
||||
|
||||
static void wrapped_trap(PPUThread &CPU, u32) noexcept {
|
||||
try
|
||||
{
|
||||
throw EXCEPTION("trap");
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
CPU.pending_exception = std::current_exception();
|
||||
}
|
||||
}
|
||||
|
||||
std::pair<Executable, llvm::ExecutionEngine *> RecompilationEngine::compile(const std::string & name, u32 start_address, u32 instruction_count) {
|
||||
std::unique_ptr<llvm::Module> module = Compiler::create_module(m_llvm_context);
|
||||
|
||||
@ -375,6 +386,7 @@ std::pair<Executable, llvm::ExecutionEngine *> RecompilationEngine::compile(cons
|
||||
function_ptrs["get_timebased_time"] = reinterpret_cast<void*>(get_timebased_time);
|
||||
function_ptrs["wrappedExecutePPUFuncByIndex"] = reinterpret_cast<void*>(wrappedExecutePPUFuncByIndex);
|
||||
function_ptrs["wrappedDoSyscall"] = reinterpret_cast<void*>(wrappedDoSyscall);
|
||||
function_ptrs["trap"] = reinterpret_cast<void*>(wrapped_trap);
|
||||
|
||||
#define REGISTER_FUNCTION_PTR(name) \
|
||||
function_ptrs[#name] = reinterpret_cast<void*>(PPUInterpreter::name##_impl);
|
||||
|
@ -48,11 +48,67 @@ void Compiler::NOP() {
|
||||
}
|
||||
|
||||
void Compiler::TDI(u32 to, u32 ra, s32 simm16) {
|
||||
CompilationError("TDI");
|
||||
llvm::Value *gpr_a = GetGpr(ra);
|
||||
llvm::Value *cst_simm16 = m_ir_builder->getInt64(simm16);
|
||||
llvm::Value *trap_condition = m_ir_builder->getFalse();
|
||||
|
||||
if (to & 0x10)
|
||||
trap_condition = m_ir_builder->CreateOr(trap_condition,
|
||||
m_ir_builder->CreateICmpSLT(gpr_a, cst_simm16));
|
||||
if (to & 0x8)
|
||||
trap_condition = m_ir_builder->CreateOr(trap_condition,
|
||||
m_ir_builder->CreateICmpSGT(gpr_a, cst_simm16));
|
||||
if (to & 0x4)
|
||||
trap_condition = m_ir_builder->CreateOr(trap_condition,
|
||||
m_ir_builder->CreateICmpEQ(gpr_a, cst_simm16));
|
||||
if (to & 0x2)
|
||||
trap_condition = m_ir_builder->CreateOr(trap_condition,
|
||||
m_ir_builder->CreateICmpULT(gpr_a, cst_simm16));
|
||||
if (to & 0x1)
|
||||
trap_condition = m_ir_builder->CreateOr(trap_condition,
|
||||
m_ir_builder->CreateICmpUGT(gpr_a, cst_simm16));
|
||||
|
||||
llvm::BasicBlock *trap_block = GetBasicBlockFromAddress(m_state.current_instruction_address, "trap_block");
|
||||
llvm::BasicBlock *normal_execution = GetBasicBlockFromAddress(m_state.current_instruction_address, "normal_execution");
|
||||
m_ir_builder->CreateCondBr(trap_condition, trap_block, normal_execution);
|
||||
|
||||
m_ir_builder->SetInsertPoint(trap_block);
|
||||
Call<void>("trap");
|
||||
m_ir_builder->CreateRet(m_ir_builder->getInt32(ExecutionStatus::ExecutionStatusPropagateException));
|
||||
|
||||
m_ir_builder->SetInsertPoint(normal_execution);
|
||||
}
|
||||
|
||||
void Compiler::TWI(u32 to, u32 ra, s32 simm16) {
|
||||
CompilationError("TWI");
|
||||
llvm::Value *gpr_a = GetGpr(ra, 32);
|
||||
llvm::Value *cst_simm16 = m_ir_builder->getInt32(simm16);
|
||||
llvm::Value *trap_condition = m_ir_builder->getFalse();
|
||||
|
||||
if (to & 0x10)
|
||||
trap_condition = m_ir_builder->CreateOr(trap_condition,
|
||||
m_ir_builder->CreateICmpSLT(gpr_a, cst_simm16));
|
||||
if (to & 0x8)
|
||||
trap_condition = m_ir_builder->CreateOr(trap_condition,
|
||||
m_ir_builder->CreateICmpSGT(gpr_a, cst_simm16));
|
||||
if (to & 0x4)
|
||||
trap_condition = m_ir_builder->CreateOr(trap_condition,
|
||||
m_ir_builder->CreateICmpEQ(gpr_a, cst_simm16));
|
||||
if (to & 0x2)
|
||||
trap_condition = m_ir_builder->CreateOr(trap_condition,
|
||||
m_ir_builder->CreateICmpULT(gpr_a, cst_simm16));
|
||||
if (to & 0x1)
|
||||
trap_condition = m_ir_builder->CreateOr(trap_condition,
|
||||
m_ir_builder->CreateICmpUGT(gpr_a, cst_simm16));
|
||||
|
||||
llvm::BasicBlock *trap_block = GetBasicBlockFromAddress(m_state.current_instruction_address, "trap_block");
|
||||
llvm::BasicBlock *normal_execution = GetBasicBlockFromAddress(m_state.current_instruction_address, "normal_execution");
|
||||
m_ir_builder->CreateCondBr(trap_condition, trap_block, normal_execution);
|
||||
|
||||
m_ir_builder->SetInsertPoint(trap_block);
|
||||
Call<void>("trap");
|
||||
m_ir_builder->CreateRet(m_ir_builder->getInt32(ExecutionStatus::ExecutionStatusPropagateException));
|
||||
|
||||
m_ir_builder->SetInsertPoint(normal_execution);
|
||||
}
|
||||
|
||||
void Compiler::MFVSCR(u32 vd) {
|
||||
@ -2198,7 +2254,35 @@ void Compiler::CMP(u32 crfd, u32 l, u32 ra, u32 rb) {
|
||||
}
|
||||
|
||||
void Compiler::TW(u32 to, u32 ra, u32 rb) {
|
||||
CompilationError("TW");
|
||||
llvm::Value *gpr_a = GetGpr(ra, 32);
|
||||
llvm::Value *gpr_b = GetGpr(rb, 32);
|
||||
llvm::Value *trap_condition = m_ir_builder->getFalse();
|
||||
|
||||
if (to & 0x10)
|
||||
trap_condition = m_ir_builder->CreateOr(trap_condition,
|
||||
m_ir_builder->CreateICmpSLT(gpr_a, gpr_b));
|
||||
if (to & 0x8)
|
||||
trap_condition = m_ir_builder->CreateOr(trap_condition,
|
||||
m_ir_builder->CreateICmpSGT(gpr_a, gpr_b));
|
||||
if (to & 0x4)
|
||||
trap_condition = m_ir_builder->CreateOr(trap_condition,
|
||||
m_ir_builder->CreateICmpEQ(gpr_a, gpr_b));
|
||||
if (to & 0x2)
|
||||
trap_condition = m_ir_builder->CreateOr(trap_condition,
|
||||
m_ir_builder->CreateICmpULT(gpr_a, gpr_b));
|
||||
if (to & 0x1)
|
||||
trap_condition = m_ir_builder->CreateOr(trap_condition,
|
||||
m_ir_builder->CreateICmpUGT(gpr_a, gpr_b));
|
||||
|
||||
llvm::BasicBlock *trap_block = GetBasicBlockFromAddress(m_state.current_instruction_address, "trap_block");
|
||||
llvm::BasicBlock *normal_execution = GetBasicBlockFromAddress(m_state.current_instruction_address, "normal_execution");
|
||||
m_ir_builder->CreateCondBr(trap_condition, trap_block, normal_execution);
|
||||
|
||||
m_ir_builder->SetInsertPoint(trap_block);
|
||||
Call<void>("trap");
|
||||
m_ir_builder->CreateRet(m_ir_builder->getInt32(ExecutionStatus::ExecutionStatusPropagateException));
|
||||
|
||||
m_ir_builder->SetInsertPoint(normal_execution);
|
||||
}
|
||||
|
||||
void Compiler::LVSL(u32 vd, u32 ra, u32 rb) {
|
||||
@ -2555,7 +2639,8 @@ void Compiler::ANDC(u32 ra, u32 rs, u32 rb, u32 rc) {
|
||||
}
|
||||
|
||||
void Compiler::TD(u32 to, u32 ra, u32 rb) {
|
||||
CompilationError("TD");
|
||||
Call<void>("trap");
|
||||
m_ir_builder->CreateRet(m_ir_builder->getInt32(ExecutionStatus::ExecutionStatusPropagateException));
|
||||
}
|
||||
|
||||
void Compiler::LVEWX(u32 vd, u32 ra, u32 rb) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user