mirror of
https://github.com/hrydgard/ppsspp.git
synced 2024-11-27 15:30:35 +00:00
Merge pull request #17804 from unknownbrackets/riscv-jit
A couple more RISC-V ops
This commit is contained in:
commit
c20f508db2
@ -2148,6 +2148,7 @@ void RiscVEmitter::FCVT(FConv to, FConv from, RiscVReg rd, RiscVReg rs1, Round r
|
||||
_assert_msg_(rm == Round::DYNAMIC || rm == Round::NEAREST_EVEN, "Invalid rounding mode for widening FCVT");
|
||||
rm = Round::NEAREST_EVEN;
|
||||
}
|
||||
_assert_msg_(fromFmt != toFmt, "FCVT cannot convert to same float type");
|
||||
Write32(EncodeR(Opcode32::OP_FP, rd, (Funct3)rm, rs1, (RiscVReg)fromFmt, toFmt, Funct5::FCVT_SZ));
|
||||
} else {
|
||||
Funct5 funct5 = FConvToIntegerBits(to) == 0 ? Funct5::FCVT_FROMX : Funct5::FCVT_TOX;
|
||||
|
@ -315,6 +315,7 @@ enum : IRReg {
|
||||
IRREG_HI = 243,
|
||||
IRREG_FCR31 = 244,
|
||||
IRREG_FPCOND = 245,
|
||||
IRREG_LLBIT = 250,
|
||||
};
|
||||
|
||||
enum IRFlags {
|
||||
|
@ -221,18 +221,32 @@ void RiscVJit::CompIR_FAssign(IRInst inst) {
|
||||
void RiscVJit::CompIR_FRound(IRInst inst) {
|
||||
CONDITIONAL_DISABLE;
|
||||
|
||||
// TODO: If this is followed by a GPR transfer, might want to combine.
|
||||
fpr.MapDirtyIn(inst.dest, inst.src1);
|
||||
|
||||
switch (inst.op) {
|
||||
case IROp::FRound:
|
||||
FCVT(FConv::W, FConv::S, SCRATCH1, fpr.R(inst.src1), Round::NEAREST_EVEN);
|
||||
break;
|
||||
|
||||
case IROp::FTrunc:
|
||||
FCVT(FConv::W, FConv::S, SCRATCH1, fpr.R(inst.src1), Round::TOZERO);
|
||||
break;
|
||||
|
||||
case IROp::FCeil:
|
||||
FCVT(FConv::W, FConv::S, SCRATCH1, fpr.R(inst.src1), Round::UP);
|
||||
break;
|
||||
|
||||
case IROp::FFloor:
|
||||
CompIR_Generic(inst);
|
||||
FCVT(FConv::W, FConv::S, SCRATCH1, fpr.R(inst.src1), Round::DOWN);
|
||||
break;
|
||||
|
||||
default:
|
||||
INVALIDOP;
|
||||
break;
|
||||
}
|
||||
|
||||
FMV(FMv::W, FMv::X, fpr.R(inst.dest), SCRATCH1);
|
||||
}
|
||||
|
||||
void RiscVJit::CompIR_FCvt(IRInst inst) {
|
||||
@ -241,11 +255,17 @@ void RiscVJit::CompIR_FCvt(IRInst inst) {
|
||||
switch (inst.op) {
|
||||
case IROp::FCvtWS:
|
||||
case IROp::FCvtScaledWS:
|
||||
case IROp::FCvtSW:
|
||||
case IROp::FCvtScaledSW:
|
||||
CompIR_Generic(inst);
|
||||
break;
|
||||
|
||||
case IROp::FCvtSW:
|
||||
// TODO: This is probably proceeded by a GPR transfer, might be ideal to combine.
|
||||
fpr.MapDirtyIn(inst.dest, inst.src1);
|
||||
FMV(FMv::X, FMv::W, SCRATCH1, fpr.R(inst.src1));
|
||||
FCVT(FConv::S, FConv::W, fpr.R(inst.dest), SCRATCH1);
|
||||
break;
|
||||
|
||||
default:
|
||||
INVALIDOP;
|
||||
break;
|
||||
|
@ -113,7 +113,9 @@ void RiscVJit::CompIR_Load(IRInst inst) {
|
||||
break;
|
||||
|
||||
case IROp::Load32Linked:
|
||||
CompIR_Generic(inst);
|
||||
if (inst.dest != MIPS_REG_ZERO)
|
||||
LW(gpr.R(inst.dest), addrReg, imm);
|
||||
gpr.SetImm(IRREG_LLBIT, 1);
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -258,7 +260,41 @@ void RiscVJit::CompIR_CondStore(IRInst inst) {
|
||||
if (inst.op != IROp::Store32Conditional)
|
||||
INVALIDOP;
|
||||
|
||||
CompIR_Generic(inst);
|
||||
gpr.SpillLock(IRREG_LLBIT, inst.src3, inst.src1);
|
||||
RiscVReg addrReg = INVALID_REG;
|
||||
if (inst.src1 == MIPS_REG_ZERO) {
|
||||
// This will get changed by AdjustForAddressOffset.
|
||||
addrReg = MEMBASEREG;
|
||||
#ifdef MASKED_PSP_MEMORY
|
||||
inst.constant &= Memory::MEMVIEW32_MASK;
|
||||
#endif
|
||||
} else if ((jo.cachePointers || gpr.IsMappedAsPointer(inst.src1)) && inst.src3 != inst.src1) {
|
||||
addrReg = gpr.MapRegAsPointer(inst.src1);
|
||||
} else {
|
||||
SetScratch1ToSrc1Address(inst.src1);
|
||||
addrReg = SCRATCH1;
|
||||
}
|
||||
gpr.MapReg(inst.src3, inst.dest == MIPS_REG_ZERO ? MIPSMap::INIT : MIPSMap::DIRTY);
|
||||
gpr.MapReg(IRREG_LLBIT);
|
||||
gpr.ReleaseSpillLock(IRREG_LLBIT, inst.src3, inst.src1);
|
||||
|
||||
s32 imm = AdjustForAddressOffset(&addrReg, inst.constant);
|
||||
|
||||
// TODO: Safe memory? Or enough to have crash handler + validate?
|
||||
|
||||
FixupBranch condFailed = BEQ(gpr.R(IRREG_LLBIT), R_ZERO);
|
||||
SW(gpr.R(inst.src3), addrReg, imm);
|
||||
|
||||
if (inst.dest != MIPS_REG_ZERO) {
|
||||
LI(gpr.R(inst.dest), 1);
|
||||
FixupBranch finish = J();
|
||||
|
||||
SetJumpTarget(condFailed);
|
||||
LI(gpr.R(inst.dest), 0);
|
||||
SetJumpTarget(finish);
|
||||
} else {
|
||||
SetJumpTarget(condFailed);
|
||||
}
|
||||
}
|
||||
|
||||
void RiscVJit::CompIR_StoreShift(IRInst inst) {
|
||||
|
@ -20,6 +20,7 @@
|
||||
#endif
|
||||
|
||||
#include "Common/CPUDetect.h"
|
||||
#include "Core/MIPS/IR/IRInst.h"
|
||||
#include "Core/MIPS/RiscV/RiscVRegCache.h"
|
||||
#include "Core/MIPS/JitCommon/JitState.h"
|
||||
#include "Core/Reporting.h"
|
||||
@ -998,7 +999,7 @@ bool RiscVRegCache::IsValidReg(IRRegIndex r) const {
|
||||
if (r >= 224 && r < 224 + 16)
|
||||
return false;
|
||||
// Don't allow nextPC, etc. since it's probably a mistake.
|
||||
if (r > 245)
|
||||
if (r > IRREG_FPCOND && r != IRREG_LLBIT)
|
||||
return false;
|
||||
// Don't allow PC either.
|
||||
if (r == 241)
|
||||
|
Loading…
Reference in New Issue
Block a user