mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-10-01 14:58:14 +00:00
RISC-V/LoongArch IR: Get vrot's sine and cosine from one call
Like arm64 and x64, call vfpu_sincos_packed and split the double it returns. Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
This commit is contained in:
1 parent
f92340c092
commit
c38d04a10c
2 files changed
+32
-22
No files matched your search
@@ -562,7 +562,7 @@ void LoongArch64JitBackend::CompIR_RoundingMode(IRInst inst) {
|
||||
void LoongArch64JitBackend::CompIR_FSpecial(IRInst inst) {
|
||||
CONDITIONAL_DISABLE;
|
||||
|
||||
auto callFuncF_F = [&](float (*func)(float)) {
|
||||
auto callWithF0 = [&](const u8 *func) {
|
||||
regs_.FlushBeforeCall();
|
||||
WriteDebugProfilerStatus(IRProfilerStatus::MATH_HELPER);
|
||||
|
||||
@@ -579,6 +579,10 @@ void LoongArch64JitBackend::CompIR_FSpecial(IRInst inst) {
|
||||
FLD_S(F0, CTXREG, offset);
|
||||
}
|
||||
QuickCallFunction(func, SCRATCH1);
|
||||
};
|
||||
|
||||
auto callFuncF_F = [&](float (*func)(float)) {
|
||||
callWithF0((const u8 *)func);
|
||||
|
||||
regs_.MapFPR(inst.dest, MIPSMap::NOINIT);
|
||||
// If it's already F0, we're done - MapReg doesn't actually overwrite the reg in that case.
|
||||
@@ -627,17 +631,18 @@ void LoongArch64JitBackend::CompIR_FSpecial(IRInst inst) {
|
||||
break;
|
||||
|
||||
case IROp::FSinCos:
|
||||
{
|
||||
// Two calls here. The frontend makes sure dest doesn't overlap src1.
|
||||
IRInst sinInst = inst;
|
||||
sinInst.op = IROp::FSin;
|
||||
CompIR_FSpecial(sinInst);
|
||||
IRInst cosInst = inst;
|
||||
cosInst.op = IROp::FCos;
|
||||
cosInst.dest = inst.dest + 1;
|
||||
CompIR_FSpecial(cosInst);
|
||||
// The sine comes back in the low 32 bits of F0, the cosine in the high.
|
||||
callWithF0((const u8 *)&vfpu_sincos_packed);
|
||||
MOVFR2GR_S(SCRATCH1, F0);
|
||||
MOVFRH2GR_S(SCRATCH2, F0);
|
||||
regs_.SpillLockFPR(inst.dest, inst.dest + 1);
|
||||
regs_.MapFPR(inst.dest, MIPSMap::NOINIT);
|
||||
regs_.MapFPR(inst.dest + 1, MIPSMap::NOINIT);
|
||||
regs_.ReleaseSpillLockFPR(inst.dest, inst.dest + 1);
|
||||
MOVGR2FR_W(regs_.F(inst.dest), SCRATCH1);
|
||||
MOVGR2FR_W(regs_.F(inst.dest + 1), SCRATCH2);
|
||||
WriteDebugProfilerStatus(IRProfilerStatus::IN_JIT);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
INVALIDOP;
|
||||
|
||||
@@ -589,7 +589,7 @@ void RiscVJitBackend::CompIR_FSpecial(IRInst inst) {
|
||||
#error Currently hard float is required.
|
||||
#endif
|
||||
|
||||
auto callFuncF_F = [&](float (*func)(float)) {
|
||||
auto callWithF10 = [&](const u8 *func) {
|
||||
regs_.FlushBeforeCall();
|
||||
WriteDebugProfilerStatus(IRProfilerStatus::MATH_HELPER);
|
||||
|
||||
@@ -602,6 +602,10 @@ void RiscVJitBackend::CompIR_FSpecial(IRInst inst) {
|
||||
FL(32, F10, CTXREG, offset);
|
||||
}
|
||||
QuickCallFunction(func, SCRATCH1);
|
||||
};
|
||||
|
||||
auto callFuncF_F = [&](float (*func)(float)) {
|
||||
callWithF10((const u8 *)func);
|
||||
|
||||
regs_.MapFPR(inst.dest, MIPSMap::NOINIT);
|
||||
// If it's already F10, we're done - MapReg doesn't actually overwrite the reg in that case.
|
||||
@@ -650,17 +654,18 @@ void RiscVJitBackend::CompIR_FSpecial(IRInst inst) {
|
||||
break;
|
||||
|
||||
case IROp::FSinCos:
|
||||
{
|
||||
// Two calls here. The frontend makes sure dest doesn't overlap src1.
|
||||
IRInst sinInst = inst;
|
||||
sinInst.op = IROp::FSin;
|
||||
CompIR_FSpecial(sinInst);
|
||||
IRInst cosInst = inst;
|
||||
cosInst.op = IROp::FCos;
|
||||
cosInst.dest = inst.dest + 1;
|
||||
CompIR_FSpecial(cosInst);
|
||||
// The sine comes back in the low 32 bits of F10, the cosine in the high.
|
||||
callWithF10((const u8 *)&vfpu_sincos_packed);
|
||||
FMV(FMv::X, FMv::D, SCRATCH1, F10);
|
||||
regs_.SpillLockFPR(inst.dest, inst.dest + 1);
|
||||
regs_.MapFPR(inst.dest, MIPSMap::NOINIT);
|
||||
regs_.MapFPR(inst.dest + 1, MIPSMap::NOINIT);
|
||||
regs_.ReleaseSpillLockFPR(inst.dest, inst.dest + 1);
|
||||
FMV(FMv::W, FMv::X, regs_.F(inst.dest), SCRATCH1);
|
||||
SRLI(SCRATCH1, SCRATCH1, 32);
|
||||
FMV(FMv::W, FMv::X, regs_.F(inst.dest + 1), SCRATCH1);
|
||||
WriteDebugProfilerStatus(IRProfilerStatus::IN_JIT);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
INVALIDOP;
|
||||
|
||||
Reference in new issue
Block a user