Merge pull request #17804 from unknownbrackets/riscv-jit

A couple more RISC-V ops
This commit is contained in:
Henrik Rydgård 2023-07-30 10:23:13 +02:00 committed by GitHub
commit c20f508db2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 64 additions and 5 deletions

View File

@ -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;

View File

@ -315,6 +315,7 @@ enum : IRReg {
IRREG_HI = 243,
IRREG_FCR31 = 244,
IRREG_FPCOND = 245,
IRREG_LLBIT = 250,
};
enum IRFlags {

View File

@ -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;

View File

@ -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) {

View File

@ -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)