From 09f3842a32b6bc2a34e521bc1d0f53b327de777e Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sun, 30 Jul 2023 13:39:53 -0700 Subject: [PATCH 1/5] riscv: Fix VFPU compare typos. --- Core/MIPS/RiscV/RiscVCompFPU.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Core/MIPS/RiscV/RiscVCompFPU.cpp b/Core/MIPS/RiscV/RiscVCompFPU.cpp index ead8244712..5e0fb66156 100644 --- a/Core/MIPS/RiscV/RiscVCompFPU.cpp +++ b/Core/MIPS/RiscV/RiscVCompFPU.cpp @@ -423,7 +423,7 @@ void RiscVJit::CompIR_FCompare(IRInst inst) { case VC_NZ: fpr.MapReg(inst.src1); // Zero is either 0x10 or 0x08. - FCLASS(32, SCRATCH1, gpr.R(inst.src1)); + FCLASS(32, SCRATCH1, fpr.R(inst.src1)); ANDI(SCRATCH1, SCRATCH1, 0x18); if ((inst.dest & 4) == 0) SNEZ(SCRATCH1, SCRATCH1); @@ -434,7 +434,7 @@ void RiscVJit::CompIR_FCompare(IRInst inst) { case VC_NN: fpr.MapReg(inst.src1); // NAN is either 0x100 or 0x200. - FCLASS(32, SCRATCH1, gpr.R(inst.src1)); + FCLASS(32, SCRATCH1, fpr.R(inst.src1)); ANDI(SCRATCH1, SCRATCH1, 0x300); if ((inst.dest & 4) == 0) SNEZ(SCRATCH1, SCRATCH1); @@ -445,7 +445,7 @@ void RiscVJit::CompIR_FCompare(IRInst inst) { case VC_NI: fpr.MapReg(inst.src1); // Infinity is either 0x80 or 0x01. - FCLASS(32, SCRATCH1, gpr.R(inst.src1)); + FCLASS(32, SCRATCH1, fpr.R(inst.src1)); ANDI(SCRATCH1, SCRATCH1, 0x81); if ((inst.dest & 4) == 0) SNEZ(SCRATCH1, SCRATCH1); @@ -456,7 +456,7 @@ void RiscVJit::CompIR_FCompare(IRInst inst) { case VC_NS: fpr.MapReg(inst.src1); // Infinity is either 0x80 or 0x01, NAN is either 0x100 or 0x200. - FCLASS(32, SCRATCH1, gpr.R(inst.src1)); + FCLASS(32, SCRATCH1, fpr.R(inst.src1)); ANDI(SCRATCH1, SCRATCH1, 0x381); if ((inst.dest & 4) == 0) SNEZ(SCRATCH1, SCRATCH1); From d1dc346899728f27fe0e23b5d3b533503250094f Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sun, 30 Jul 2023 14:05:43 -0700 Subject: [PATCH 2/5] riscv: Fix pointer add/sub. --- Core/MIPS/RiscV/RiscVCompALU.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Core/MIPS/RiscV/RiscVCompALU.cpp b/Core/MIPS/RiscV/RiscVCompALU.cpp index 1b29413797..3b4fe4ec79 100644 --- a/Core/MIPS/RiscV/RiscVCompALU.cpp +++ b/Core/MIPS/RiscV/RiscVCompALU.cpp @@ -39,7 +39,7 @@ void RiscVJit::CompIR_Arith(IRInst inst) { CONDITIONAL_DISABLE; bool allowPtrMath = true; -#ifndef MASKED_PSP_MEMORY +#ifdef MASKED_PSP_MEMORY // Since we modify it, we can't safely. allowPtrMath = false; #endif From e34736fbb2a2df8444b09d860afaaab2ce0fe734 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sun, 30 Jul 2023 09:12:09 -0700 Subject: [PATCH 3/5] riscv: Reduce norms in Slt/Sltu overlap cases. We can skip an SEXT.W in common cases where the dest and src overlap. --- Core/MIPS/RiscV/RiscVCompALU.cpp | 35 ++++++++++++++++++++------------ 1 file changed, 22 insertions(+), 13 deletions(-) diff --git a/Core/MIPS/RiscV/RiscVCompALU.cpp b/Core/MIPS/RiscV/RiscVCompALU.cpp index 3b4fe4ec79..5cb2ff256c 100644 --- a/Core/MIPS/RiscV/RiscVCompALU.cpp +++ b/Core/MIPS/RiscV/RiscVCompALU.cpp @@ -374,21 +374,27 @@ void RiscVJit::CompIR_Compare(IRInst inst) { RiscVReg rhs = INVALID_REG; switch (inst.op) { case IROp::Slt: - // Not using the NORM32 flag so we don't confuse ourselves on overlap. - gpr.MapDirtyInIn(inst.dest, inst.src1, inst.src2); + gpr.SpillLock(inst.dest, inst.src1, inst.src2); + gpr.MapReg(inst.src1); + gpr.MapReg(inst.src2); NormalizeSrc12(inst, &lhs, &rhs, SCRATCH1, SCRATCH2, true); + gpr.MapReg(inst.dest, MIPSMap::NOINIT | MIPSMap::MARK_NORM32); + gpr.ReleaseSpillLock(inst.dest, inst.src1, inst.src2); + SLT(gpr.R(inst.dest), lhs, rhs); - gpr.MarkDirty(gpr.R(inst.dest), true); break; case IROp::SltConst: - // Not using the NORM32 flag so we don't confuse ourselves on overlap. - gpr.MapDirtyIn(inst.dest, inst.src1); if (inst.constant == 0) { // Basically, getting the sign bit. Let's shift instead. + gpr.MapDirtyIn(inst.dest, inst.src1, MapType::AVOID_LOAD_MARK_NORM32); SRLIW(gpr.R(inst.dest), gpr.R(inst.src1), 31); } else { + gpr.SpillLock(inst.dest, inst.src1); + gpr.MapReg(inst.src1); NormalizeSrc1(inst, &lhs, SCRATCH1, false); + gpr.MapReg(inst.dest, MIPSMap::NOINIT | MIPSMap::MARK_NORM32); + gpr.ReleaseSpillLock(inst.dest, inst.src1); if ((int32_t)inst.constant >= -2048 && (int32_t)inst.constant <= 2047) { SLTI(gpr.R(inst.dest), lhs, (int32_t)inst.constant); @@ -396,26 +402,31 @@ void RiscVJit::CompIR_Compare(IRInst inst) { LI(SCRATCH2, (int32_t)inst.constant); SLT(gpr.R(inst.dest), lhs, SCRATCH2); } + gpr.MarkDirty(gpr.R(inst.dest), true); } - gpr.MarkDirty(gpr.R(inst.dest), true); break; case IROp::SltU: - // Not using the NORM32 flag so we don't confuse ourselves on overlap. - gpr.MapDirtyInIn(inst.dest, inst.src1, inst.src2); + gpr.SpillLock(inst.dest, inst.src1, inst.src2); + gpr.MapReg(inst.src1); + gpr.MapReg(inst.src2); // It's still fine to sign extend, the biggest just get even bigger. NormalizeSrc12(inst, &lhs, &rhs, SCRATCH1, SCRATCH2, true); + gpr.MapReg(inst.dest, MIPSMap::NOINIT | MIPSMap::MARK_NORM32); + gpr.ReleaseSpillLock(inst.dest, inst.src1, inst.src2); + SLTU(gpr.R(inst.dest), lhs, rhs); - gpr.MarkDirty(gpr.R(inst.dest), true); break; case IROp::SltUConst: - // Not using the NORM32 flag so we don't confuse ourselves on overlap. - gpr.MapDirtyIn(inst.dest, inst.src1); if (inst.constant == 0) { gpr.SetImm(inst.dest, 0); } else { + gpr.SpillLock(inst.dest, inst.src1); + gpr.MapReg(inst.src1); NormalizeSrc1(inst, &lhs, SCRATCH1, false); + gpr.MapReg(inst.dest, MIPSMap::NOINIT | MIPSMap::MARK_NORM32); + gpr.ReleaseSpillLock(inst.dest, inst.src1); // We sign extend because we're comparing against something normalized. // It's also the most efficient to set. @@ -425,8 +436,6 @@ void RiscVJit::CompIR_Compare(IRInst inst) { LI(SCRATCH2, (int32_t)inst.constant); SLTU(gpr.R(inst.dest), lhs, SCRATCH2); } - - gpr.MarkDirty(gpr.R(inst.dest), true); } break; From 9f917488c34b0c7773ba59ca9eae3d49cd2a2d11 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sun, 30 Jul 2023 09:11:16 -0700 Subject: [PATCH 4/5] riscv: Fix PC in disassembly. --- Core/MIPS/JitCommon/JitCommon.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Core/MIPS/JitCommon/JitCommon.cpp b/Core/MIPS/JitCommon/JitCommon.cpp index 4156732d5d..b6b3df1205 100644 --- a/Core/MIPS/JitCommon/JitCommon.cpp +++ b/Core/MIPS/JitCommon/JitCommon.cpp @@ -340,7 +340,7 @@ std::vector DisassembleRV64(const u8 *data, int size) { } invalid_flush(); - riscv_disasm_inst(temp, sizeof(temp), rv64, i * 4, inst); + riscv_disasm_inst(temp, sizeof(temp), rv64, (uintptr_t)data + i, inst); lines.push_back(ReplaceAll(temp, "\t", " ")); i += (int)len; From 5ef4b2b5fafad6eb91ad5a80af02b637d94b3a84 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sun, 30 Jul 2023 13:27:25 -0700 Subject: [PATCH 5/5] riscv: Fix assert when flushing not mapped reg. --- Core/MIPS/RiscV/RiscVRegCache.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Core/MIPS/RiscV/RiscVRegCache.cpp b/Core/MIPS/RiscV/RiscVRegCache.cpp index 25f7b5db59..43905d1f83 100644 --- a/Core/MIPS/RiscV/RiscVRegCache.cpp +++ b/Core/MIPS/RiscV/RiscVRegCache.cpp @@ -663,7 +663,6 @@ void RiscVRegCache::MapDirtyDirtyInIn(IRRegIndex rd1, IRRegIndex rd2, IRRegIndex void RiscVRegCache::FlushRiscVReg(RiscVReg r) { _dbg_assert_(r > X0 && r <= X31); _dbg_assert_(ar[r].mipsReg != MIPS_REG_ZERO); - _dbg_assert_(!mr[ar[r].mipsReg].isStatic); if (r == INVALID_REG) { ERROR_LOG(JIT, "FlushRiscVReg called on invalid register %d", r); return; @@ -673,6 +672,7 @@ void RiscVRegCache::FlushRiscVReg(RiscVReg r) { _dbg_assert_(!ar[r].isDirty); return; } + _dbg_assert_(!mr[ar[r].mipsReg].isStatic); if (mr[ar[r].mipsReg].isStatic) { ERROR_LOG(JIT, "Cannot FlushRiscVReg a statically mapped register"); return;