mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-07-09 00:11:24 +12:00
PPU LLVM recompiler: Implement more instructions
This commit is contained in:
parent
631675fdd6
commit
205e1d88b3
2 changed files with 62 additions and 34 deletions
|
@ -1778,7 +1778,21 @@ void Compiler::BC(u32 bo, u32 bi, s32 bd, u32 aa, u32 lk) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Compiler::SC(u32 sc_code) {
|
void Compiler::SC(u32 sc_code) {
|
||||||
InterpreterCall("SC", &PPUInterpreter::SC, sc_code);
|
switch (sc_code) {
|
||||||
|
case 2:
|
||||||
|
Call<void>("SysCalls.DoSyscall", SysCalls::DoSyscall, m_state.args[CompileTaskState::Args::State], GetGpr(11));
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
Call<void>("StaticFuncManager.StaticExecute", &StaticFuncManager::StaticExecute,
|
||||||
|
m_ir_builder->getInt64((u64)&Emu.GetSFuncManager()), m_state.args[CompileTaskState::Args::State], GetGpr(11, 32));
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
Call<void>("PPUThread.FastStop", &PPUThread::FastStop, m_state.args[CompileTaskState::Args::State]);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
CompilationError(fmt::Format("SC %u", sc_code));
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Compiler::B(s32 ll, u32 aa, u32 lk) {
|
void Compiler::B(s32 ll, u32 aa, u32 lk) {
|
||||||
|
@ -2955,7 +2969,15 @@ void Compiler::EQV(u32 ra, u32 rs, u32 rb, bool rc) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Compiler::ECIWX(u32 rd, u32 ra, u32 rb) {
|
void Compiler::ECIWX(u32 rd, u32 ra, u32 rb) {
|
||||||
InterpreterCall("ECIWX", &PPUInterpreter::ECIWX, rd, 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 mem_i32 = ReadMemory(addr_i64, 32);
|
||||||
|
auto mem_i64 = m_ir_builder->CreateZExt(mem_i32, m_ir_builder->getInt64Ty());
|
||||||
|
SetGpr(rd, mem_i64);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Compiler::LHZUX(u32 rd, u32 ra, u32 rb) {
|
void Compiler::LHZUX(u32 rd, u32 ra, u32 rb) {
|
||||||
|
@ -3106,7 +3128,13 @@ void Compiler::ORC(u32 ra, u32 rs, u32 rb, bool rc) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Compiler::ECOWX(u32 rs, u32 ra, u32 rb) {
|
void Compiler::ECOWX(u32 rs, u32 ra, u32 rb) {
|
||||||
InterpreterCall("ECOWX", &PPUInterpreter::ECOWX, rs, ra, rb);
|
auto addr_i64 = GetGpr(rb);
|
||||||
|
if (ra) {
|
||||||
|
auto ra_i64 = GetGpr(ra);
|
||||||
|
addr_i64 = m_ir_builder->CreateAdd(ra_i64, addr_i64);
|
||||||
|
}
|
||||||
|
|
||||||
|
WriteMemory(addr_i64, GetGpr(rs, 32));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Compiler::STHUX(u32 rs, u32 ra, u32 rb) {
|
void Compiler::STHUX(u32 rs, u32 ra, u32 rb) {
|
||||||
|
@ -4215,8 +4243,8 @@ void Compiler::FRSP(u32 frd, u32 frb, bool rc) {
|
||||||
|
|
||||||
void Compiler::FCTIW(u32 frd, u32 frb, bool rc) {
|
void Compiler::FCTIW(u32 frd, u32 frb, bool rc) {
|
||||||
auto rb_f64 = GetFpr(frb);
|
auto rb_f64 = GetFpr(frb);
|
||||||
auto max_i1 = m_ir_builder->CreateFCmpOGT(rb_f64, ConstantFP::get(m_ir_builder->getDoubleTy(), 0x7FFFFFFF));
|
auto max_i1 = m_ir_builder->CreateFCmpOGT(rb_f64, ConstantFP::get(m_ir_builder->getDoubleTy(), 2147483647.0));
|
||||||
auto min_i1 = m_ir_builder->CreateFCmpULT(rb_f64, ConstantFP::get(m_ir_builder->getDoubleTy(), -2147483648));
|
auto min_i1 = m_ir_builder->CreateFCmpULT(rb_f64, ConstantFP::get(m_ir_builder->getDoubleTy(), -2147483648.0));
|
||||||
auto res_i32 = m_ir_builder->CreateFPToSI(rb_f64, m_ir_builder->getInt32Ty());
|
auto res_i32 = m_ir_builder->CreateFPToSI(rb_f64, m_ir_builder->getInt32Ty());
|
||||||
auto res_i64 = m_ir_builder->CreateZExt(res_i32, m_ir_builder->getInt64Ty());
|
auto res_i64 = m_ir_builder->CreateZExt(res_i32, m_ir_builder->getInt64Ty());
|
||||||
res_i64 = m_ir_builder->CreateSelect(max_i1, m_ir_builder->getInt64(0x7FFFFFFF), res_i64);
|
res_i64 = m_ir_builder->CreateSelect(max_i1, m_ir_builder->getInt64(0x7FFFFFFF), res_i64);
|
||||||
|
@ -4229,26 +4257,24 @@ void Compiler::FCTIW(u32 frd, u32 frb, bool rc) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Set flags / Implement rounding modes
|
// TODO: Set flags / Implement rounding modes
|
||||||
//InterpreterCall("FCTIW", &PPUInterpreter::FCTIWZ, frd, frb, rc);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Compiler::FCTIWZ(u32 frd, u32 frb, bool rc) {
|
void Compiler::FCTIWZ(u32 frd, u32 frb, bool rc) {
|
||||||
//auto rb_f64 = GetFpr(frb);
|
auto rb_f64 = GetFpr(frb);
|
||||||
//auto max_i1 = m_ir_builder->CreateFCmpOGT(rb_f64, ConstantFP::get(m_ir_builder->getDoubleTy(), 0x7FFFFFFF));
|
auto max_i1 = m_ir_builder->CreateFCmpOGT(rb_f64, ConstantFP::get(m_ir_builder->getDoubleTy(), 2147483647.0));
|
||||||
//auto min_i1 = m_ir_builder->CreateFCmpULT(rb_f64, ConstantFP::get(m_ir_builder->getDoubleTy(), -2147483648));
|
auto min_i1 = m_ir_builder->CreateFCmpULT(rb_f64, ConstantFP::get(m_ir_builder->getDoubleTy(), -2147483648.0));
|
||||||
//auto res_i32 = m_ir_builder->CreateFPToSI(rb_f64, m_ir_builder->getInt32Ty());
|
auto res_i32 = m_ir_builder->CreateFPToSI(rb_f64, m_ir_builder->getInt32Ty());
|
||||||
//auto res_i64 = m_ir_builder->CreateZExt(res_i32, m_ir_builder->getInt64Ty());
|
auto res_i64 = m_ir_builder->CreateZExt(res_i32, m_ir_builder->getInt64Ty());
|
||||||
//res_i64 = m_ir_builder->CreateSelect(max_i1, m_ir_builder->getInt64(0x7FFFFFFF), res_i64);
|
res_i64 = m_ir_builder->CreateSelect(max_i1, m_ir_builder->getInt64(0x7FFFFFFF), res_i64);
|
||||||
//res_i64 = m_ir_builder->CreateSelect(min_i1, m_ir_builder->getInt64(0x80000000), res_i64);
|
res_i64 = m_ir_builder->CreateSelect(min_i1, m_ir_builder->getInt64(0x80000000), res_i64);
|
||||||
//SetFpr(frd, res_i64);
|
SetFpr(frd, res_i64);
|
||||||
|
|
||||||
//if (rc) {
|
if (rc) {
|
||||||
// // TODO: Implement this
|
// TODO: Implement this
|
||||||
// CompilationError("FCTIWZ.");
|
CompilationError("FCTIWZ.");
|
||||||
//}
|
}
|
||||||
|
|
||||||
// TODO: Set flags
|
// TODO: Set flags
|
||||||
InterpreterCall("FCTIWZ", &PPUInterpreter::FCTIWZ, frd, frb, rc);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Compiler::FDIV(u32 frd, u32 fra, u32 frb, bool rc) {
|
void Compiler::FDIV(u32 frd, u32 fra, u32 frb, bool rc) {
|
||||||
|
@ -4478,8 +4504,8 @@ void Compiler::FABS(u32 frd, u32 frb, bool rc) {
|
||||||
|
|
||||||
void Compiler::FCTID(u32 frd, u32 frb, bool rc) {
|
void Compiler::FCTID(u32 frd, u32 frb, bool rc) {
|
||||||
auto rb_f64 = GetFpr(frb);
|
auto rb_f64 = GetFpr(frb);
|
||||||
auto max_i1 = m_ir_builder->CreateFCmpOGT(rb_f64, ConstantFP::get(m_ir_builder->getDoubleTy(), 0x7FFFFFFFFFFFFFFFll));
|
auto max_i1 = m_ir_builder->CreateFCmpOGT(rb_f64, ConstantFP::get(m_ir_builder->getDoubleTy(), 9223372036854775807.0));
|
||||||
auto min_i1 = m_ir_builder->CreateFCmpULT(rb_f64, ConstantFP::get(m_ir_builder->getDoubleTy(), -9223372036854775808ll));
|
auto min_i1 = m_ir_builder->CreateFCmpULT(rb_f64, ConstantFP::get(m_ir_builder->getDoubleTy(), -9223372036854775808.0));
|
||||||
auto res_i64 = m_ir_builder->CreateFPToSI(rb_f64, m_ir_builder->getInt64Ty());
|
auto res_i64 = m_ir_builder->CreateFPToSI(rb_f64, m_ir_builder->getInt64Ty());
|
||||||
res_i64 = m_ir_builder->CreateSelect(max_i1, m_ir_builder->getInt64(0x7FFFFFFFFFFFFFFF), res_i64);
|
res_i64 = m_ir_builder->CreateSelect(max_i1, m_ir_builder->getInt64(0x7FFFFFFFFFFFFFFF), res_i64);
|
||||||
res_i64 = m_ir_builder->CreateSelect(min_i1, m_ir_builder->getInt64(0x8000000000000000), res_i64);
|
res_i64 = m_ir_builder->CreateSelect(min_i1, m_ir_builder->getInt64(0x8000000000000000), res_i64);
|
||||||
|
@ -4491,25 +4517,23 @@ void Compiler::FCTID(u32 frd, u32 frb, bool rc) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Set flags / Implement rounding modes
|
// TODO: Set flags / Implement rounding modes
|
||||||
//InterpreterCall("FCTIDZ", &PPUInterpreter::FCTID, frd, frb, rc);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Compiler::FCTIDZ(u32 frd, u32 frb, bool rc) {
|
void Compiler::FCTIDZ(u32 frd, u32 frb, bool rc) {
|
||||||
//auto rb_f64 = GetFpr(frb);
|
auto rb_f64 = GetFpr(frb);
|
||||||
//auto max_i1 = m_ir_builder->CreateFCmpOGT(rb_f64, ConstantFP::get(m_ir_builder->getDoubleTy(), 0x7FFFFFFFFFFFFFFFll));
|
auto max_i1 = m_ir_builder->CreateFCmpOGT(rb_f64, ConstantFP::get(m_ir_builder->getDoubleTy(), 9223372036854775807.0));
|
||||||
//auto min_i1 = m_ir_builder->CreateFCmpULT(rb_f64, ConstantFP::get(m_ir_builder->getDoubleTy(), -9223372036854775808ll));
|
auto min_i1 = m_ir_builder->CreateFCmpULT(rb_f64, ConstantFP::get(m_ir_builder->getDoubleTy(), -9223372036854775808.0));
|
||||||
//auto res_i64 = m_ir_builder->CreateFPToSI(rb_f64, m_ir_builder->getInt64Ty());
|
auto res_i64 = m_ir_builder->CreateFPToSI(rb_f64, m_ir_builder->getInt64Ty());
|
||||||
//res_i64 = m_ir_builder->CreateSelect(max_i1, m_ir_builder->getInt64(0x7FFFFFFFFFFFFFFF), res_i64);
|
res_i64 = m_ir_builder->CreateSelect(max_i1, m_ir_builder->getInt64(0x7FFFFFFFFFFFFFFF), res_i64);
|
||||||
//res_i64 = m_ir_builder->CreateSelect(min_i1, m_ir_builder->getInt64(0x8000000000000000), res_i64);
|
res_i64 = m_ir_builder->CreateSelect(min_i1, m_ir_builder->getInt64(0x8000000000000000), res_i64);
|
||||||
//SetFpr(frd, res_i64);
|
SetFpr(frd, res_i64);
|
||||||
|
|
||||||
//if (rc) {
|
if (rc) {
|
||||||
// // TODO: Implement this
|
// TODO: Implement this
|
||||||
// CompilationError("FCTIDZ.");
|
CompilationError("FCTIDZ.");
|
||||||
//}
|
}
|
||||||
|
|
||||||
// TODO: Set flags
|
// TODO: Set flags
|
||||||
InterpreterCall("FCTIDZ", &PPUInterpreter::FCTIDZ, frd, frb, rc);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Compiler::FCFID(u32 frd, u32 frb, bool rc) {
|
void Compiler::FCFID(u32 frd, u32 frb, bool rc) {
|
||||||
|
|
|
@ -703,6 +703,8 @@ void Compiler::RunAllTests() {
|
||||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LHZU, 0, input, 5, 14, 0x10000);
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LHZU, 0, input, 5, 14, 0x10000);
|
||||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LHZX, 0, input, 5, 0, 23);
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LHZX, 0, input, 5, 0, 23);
|
||||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LHZX, 1, input, 5, 14, 23);
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LHZX, 1, input, 5, 14, 23);
|
||||||
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER(ECIWX, 0, input, 5, 0, 23);
|
||||||
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER(ECIWX, 1, input, 5, 14, 23);
|
||||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LHZUX, 0, input, 5, 14, 23);
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LHZUX, 0, input, 5, 14, 23);
|
||||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LHA, 0, input, 5, 0, 0x100F0);
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LHA, 0, input, 5, 0, 0x100F0);
|
||||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LHA, 1, input, 5, 14, 0x100F0);
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER(LHA, 1, input, 5, 14, 0x100F0);
|
||||||
|
@ -789,6 +791,8 @@ void Compiler::RunAllTests() {
|
||||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STHU, 0, input, 3, 14, 0x10000);
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STHU, 0, input, 3, 14, 0x10000);
|
||||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STHX, 0, input, 3, 0, 23);
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STHX, 0, input, 3, 0, 23);
|
||||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STHX, 1, input, 3, 14, 23);
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STHX, 1, input, 3, 14, 23);
|
||||||
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER(ECOWX, 0, input, 3, 0, 23);
|
||||||
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER(ECOWX, 1, input, 3, 14, 23);
|
||||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STHUX, 0, input, 3, 14, 23);
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STHUX, 0, input, 3, 14, 23);
|
||||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STHBRX, 0, input, 3, 14, 23);
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STHBRX, 0, input, 3, 14, 23);
|
||||||
VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STW, 0, input, 3, 0, 0x10000);
|
VERIFY_INSTRUCTION_AGAINST_INTERPRETER(STW, 0, input, 3, 0, 0x10000);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue