mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-07-09 00:11:24 +12:00
PPU: Implement more instructions in the recompiler. Fix some instructions in the interpreter.
This commit is contained in:
parent
6ea50567b6
commit
ce0f713f03
3 changed files with 131 additions and 20 deletions
|
@ -4112,7 +4112,7 @@ private:
|
|||
}
|
||||
void MTFSB1(u32 crbd, bool rc)
|
||||
{
|
||||
u64 mask = (1ULL << crbd);
|
||||
u64 mask = (1ULL << (31 - crbd));
|
||||
if ((crbd == 29) && !CPU.FPSCR.NI) LOG_WARNING(PPU, "Non-IEEE mode enabled");
|
||||
CPU.FPSCR.FPSCR |= mask;
|
||||
|
||||
|
@ -4120,13 +4120,32 @@ private:
|
|||
}
|
||||
void MCRFS(u32 crbd, u32 crbs)
|
||||
{
|
||||
u64 mask = (1ULL << crbd);
|
||||
CPU.CR.CR &= ~mask;
|
||||
CPU.CR.CR |= CPU.FPSCR.FPSCR & mask;
|
||||
CPU.SetCR(crbd, (CPU.FPSCR.FPSCR >> ((7 - crbs) * 4)) & 0xf);
|
||||
|
||||
switch (crbs)
|
||||
{
|
||||
case 0:
|
||||
CPU.FPSCR.FX = CPU.FPSCR.OX = 0;
|
||||
break;
|
||||
case 1:
|
||||
CPU.FPSCR.UX = CPU.FPSCR.ZX = CPU.FPSCR.XX = CPU.FPSCR.VXSNAN = 0;
|
||||
break;
|
||||
case 2:
|
||||
CPU.FPSCR.VXISI = CPU.FPSCR.VXIDI = CPU.FPSCR.VXZDZ = CPU.FPSCR.VXIMZ = 0;
|
||||
break;
|
||||
case 3:
|
||||
CPU.FPSCR.VXVC = 0;
|
||||
break;
|
||||
case 5:
|
||||
CPU.FPSCR.VXSOFT = CPU.FPSCR.VXSQRT = CPU.FPSCR.VXCVI = 0;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
void MTFSB0(u32 crbd, bool rc)
|
||||
{
|
||||
u64 mask = (1ULL << crbd);
|
||||
u64 mask = (1ULL << (31 - crbd));
|
||||
if ((crbd == 29) && !CPU.FPSCR.NI) LOG_WARNING(PPU, "Non-IEEE mode disabled");
|
||||
CPU.FPSCR.FPSCR &= ~mask;
|
||||
|
||||
|
@ -4134,17 +4153,18 @@ private:
|
|||
}
|
||||
void MTFSFI(u32 crfd, u32 i, bool rc)
|
||||
{
|
||||
u64 mask = (0x1ULL << crfd);
|
||||
u32 mask = 0xF0000000 >> (crfd * 4);
|
||||
u32 val = (i & 0xF) << ((7 - crfd) * 4);
|
||||
|
||||
if(i)
|
||||
const u32 oldNI = CPU.FPSCR.NI;
|
||||
CPU.FPSCR.FPSCR &= ~mask;
|
||||
CPU.FPSCR.FPSCR |= val;
|
||||
if (CPU.FPSCR.NI != oldNI)
|
||||
{
|
||||
if ((crfd == 29) && !CPU.FPSCR.NI) LOG_WARNING(PPU, "Non-IEEE mode enabled");
|
||||
CPU.FPSCR.FPSCR |= mask;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((crfd == 29) && CPU.FPSCR.NI) LOG_WARNING(PPU, "Non-IEEE mode disabled");
|
||||
CPU.FPSCR.FPSCR &= ~mask;
|
||||
if (oldNI)
|
||||
LOG_WARNING(PPU, "Non-IEEE mode disabled");
|
||||
else
|
||||
LOG_WARNING(PPU, "Non-IEEE mode enabled");
|
||||
}
|
||||
|
||||
if(rc) UNIMPLEMENTED();
|
||||
|
|
|
@ -4305,27 +4305,99 @@ void Compiler::STDU(u32 rs, u32 ra, s32 ds) {
|
|||
}
|
||||
|
||||
void Compiler::MTFSB1(u32 crbd, bool rc) {
|
||||
InterpreterCall("MTFSB1", &PPUInterpreter::MTFSB1, crbd, rc);
|
||||
auto fpscr_i32 = GetFpscr();
|
||||
SetBit(fpscr_i32, crbd, m_ir_builder->getInt32(1), false);
|
||||
SetFpscr(fpscr_i32);
|
||||
|
||||
if (rc) {
|
||||
// TODO: Implement this
|
||||
CompilationError("MTFSB1.");
|
||||
}
|
||||
}
|
||||
|
||||
void Compiler::MCRFS(u32 crbd, u32 crbs) {
|
||||
InterpreterCall("MCRFS", &PPUInterpreter::MCRFS, crbd, crbs);
|
||||
auto fpscr_i32 = GetFpscr();
|
||||
auto val_i32 = GetNibble(fpscr_i32, crbs);
|
||||
SetCrField(crbd, val_i32);
|
||||
|
||||
switch (crbs) {
|
||||
case 0:
|
||||
fpscr_i32 = ClrBit(fpscr_i32, 0);
|
||||
fpscr_i32 = ClrBit(fpscr_i32, 3);
|
||||
break;
|
||||
case 1:
|
||||
fpscr_i32 = ClrNibble(fpscr_i32, 1);
|
||||
break;
|
||||
case 2:
|
||||
fpscr_i32 = ClrNibble(fpscr_i32, 2);
|
||||
break;
|
||||
case 3:
|
||||
fpscr_i32 = ClrBit(fpscr_i32, 12);
|
||||
break;
|
||||
case 5:
|
||||
fpscr_i32 = ClrBit(fpscr_i32, 21);
|
||||
fpscr_i32 = ClrBit(fpscr_i32, 22);
|
||||
fpscr_i32 = ClrBit(fpscr_i32, 23);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
SetFpscr(fpscr_i32);
|
||||
}
|
||||
|
||||
void Compiler::MTFSB0(u32 crbd, bool rc) {
|
||||
InterpreterCall("MTFSB0", &PPUInterpreter::MTFSB0, crbd, rc);
|
||||
auto fpscr_i32 = GetFpscr();
|
||||
fpscr_i32 = ClrBit(fpscr_i32, crbd);
|
||||
SetFpscr(fpscr_i32);
|
||||
|
||||
if (rc) {
|
||||
// TODO: Implement this
|
||||
CompilationError("MTFSB0.");
|
||||
}
|
||||
}
|
||||
|
||||
void Compiler::MTFSFI(u32 crfd, u32 i, bool rc) {
|
||||
InterpreterCall("MTFSFI", &PPUInterpreter::MTFSFI, crfd, i, rc);
|
||||
auto fpscr_i32 = GetFpscr();
|
||||
fpscr_i32 = SetNibble(fpscr_i32, crfd, m_ir_builder->getInt32(i & 0xF));
|
||||
SetFpscr(fpscr_i32);
|
||||
|
||||
if (rc) {
|
||||
// TODO: Implement this
|
||||
CompilationError("MTFSFI.");
|
||||
}
|
||||
}
|
||||
|
||||
void Compiler::MFFS(u32 frd, bool rc) {
|
||||
InterpreterCall("MFFS", &PPUInterpreter::MFFS, frd, rc);
|
||||
auto fpscr_i32 = GetFpscr();
|
||||
auto fpscr_i64 = m_ir_builder->CreateZExt(fpscr_i32, m_ir_builder->getInt64Ty());
|
||||
SetFpr(frd, fpscr_i64);
|
||||
|
||||
if (rc) {
|
||||
// TODO: Implement this
|
||||
CompilationError("MFFS.");
|
||||
}
|
||||
}
|
||||
|
||||
void Compiler::MTFSF(u32 flm, u32 frb, bool rc) {
|
||||
InterpreterCall("MTFSF", &PPUInterpreter::MTFSF, flm, frb, rc);
|
||||
u32 mask = 0;
|
||||
for(u32 i = 0; i < 8; i++) {
|
||||
if (flm & (1 << i)) {
|
||||
mask |= 0xF << (i * 4);
|
||||
}
|
||||
}
|
||||
|
||||
auto rb_i32 = GetFpr(frb, 32, true);
|
||||
auto fpscr_i32 = GetFpscr();
|
||||
fpscr_i32 = m_ir_builder->CreateAnd(fpscr_i32, ~mask);
|
||||
rb_i32 = m_ir_builder->CreateAnd(rb_i32, mask);
|
||||
fpscr_i32 = m_ir_builder->CreateOr(fpscr_i32, rb_i32);
|
||||
SetFpscr(fpscr_i32);
|
||||
|
||||
if (rc) {
|
||||
// TODO: Implement this
|
||||
CompilationError("MTFSF.");
|
||||
}
|
||||
}
|
||||
|
||||
void Compiler::FCMPU(u32 crfd, u32 fra, u32 frb) {
|
||||
|
@ -4987,6 +5059,19 @@ void Compiler::SetUsprg0(Value * val_x64) {
|
|||
m_ir_builder->CreateAlignedStore(val_i64, usprg0_i64_ptr, 8);
|
||||
}
|
||||
|
||||
Value * Compiler::GetFpscr() {
|
||||
auto fpscr_i8_ptr = m_ir_builder->CreateConstGEP1_32(m_state.args[CompileTaskState::Args::State], (unsigned int)offsetof(PPUThread, FPSCR));
|
||||
auto fpscr_i32_ptr = m_ir_builder->CreateBitCast(fpscr_i8_ptr, m_ir_builder->getInt32Ty()->getPointerTo());
|
||||
return m_ir_builder->CreateAlignedLoad(fpscr_i32_ptr, 4);
|
||||
}
|
||||
|
||||
void Compiler::SetFpscr(Value * val_x32) {
|
||||
auto val_i32 = m_ir_builder->CreateBitCast(val_x32, m_ir_builder->getInt32Ty());
|
||||
auto fpscr_i8_ptr = m_ir_builder->CreateConstGEP1_32(m_state.args[CompileTaskState::Args::State], (unsigned int)offsetof(PPUThread, FPSCR));
|
||||
auto fpscr_i32_ptr = m_ir_builder->CreateBitCast(fpscr_i8_ptr, m_ir_builder->getInt32Ty()->getPointerTo());
|
||||
m_ir_builder->CreateAlignedStore(val_i32, fpscr_i32_ptr, 4);
|
||||
}
|
||||
|
||||
Value * Compiler::GetFpr(u32 r, u32 bits, bool as_int) {
|
||||
auto r_i8_ptr = m_ir_builder->CreateConstGEP1_32(m_state.args[CompileTaskState::Args::State], (unsigned int)offsetof(PPUThread, FPR[r]));
|
||||
if (!as_int) {
|
||||
|
|
|
@ -869,6 +869,12 @@ namespace ppu_recompiler_llvm {
|
|||
/// Set USPRG0
|
||||
void SetUsprg0(llvm::Value * val_x64);
|
||||
|
||||
/// Load FPSCR
|
||||
llvm::Value * GetFpscr();
|
||||
|
||||
/// Set FPSCR
|
||||
void SetFpscr(llvm::Value * val_x32);
|
||||
|
||||
/// Get FPR
|
||||
llvm::Value * GetFpr(u32 r, u32 bits = 64, bool as_int = false);
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue