mirror of
https://git.naxdy.org/Mirror/Ryujinx.git
synced 2025-03-25 02:00:17 +00:00
* Implement a new JIT for Arm devices * Auto-format * Make a lot of Assembler members read-only * More read-only * Fix more warnings * ObjectDisposedException.ThrowIf * New JIT cache for platforms that enforce W^X, currently unused * Remove unused using * Fix assert * Pass memory manager type around * Safe memory manager mode support + other improvements * Actual safe memory manager mode masking support * PR feedback
77 lines
3.1 KiB
C#
77 lines
3.1 KiB
C#
using Ryujinx.Cpu.LightningJit.CodeGen;
|
|
|
|
namespace Ryujinx.Cpu.LightningJit.Arm32.Target.Arm64
|
|
{
|
|
static class InstEmitNeonSystem
|
|
{
|
|
public static void Vmrs(CodeGenContext context, uint rt, uint reg)
|
|
{
|
|
if (context.ConsumeSkipNextInstruction())
|
|
{
|
|
// This case means that we managed to combine a VCMP and VMRS instruction,
|
|
// so we have nothing to do here as FCMP/FCMPE already set PSTATE.NZCV.
|
|
context.SetNzcvModified();
|
|
|
|
return;
|
|
}
|
|
|
|
if (reg == 1)
|
|
{
|
|
// FPSCR
|
|
|
|
Operand ctx = InstEmitSystem.Register(context.RegisterAllocator.FixedContextRegister);
|
|
|
|
if (rt == RegisterUtils.PcRegister)
|
|
{
|
|
using ScopedRegister fpsrRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped();
|
|
|
|
context.Arm64Assembler.LdrRiUn(fpsrRegister.Operand, ctx, NativeContextOffsets.FpFlagsBaseOffset);
|
|
context.Arm64Assembler.Lsr(fpsrRegister.Operand, fpsrRegister.Operand, InstEmitCommon.Const(28));
|
|
|
|
InstEmitCommon.RestoreNzcvFlags(context, fpsrRegister.Operand);
|
|
|
|
context.SetNzcvModified();
|
|
}
|
|
else
|
|
{
|
|
// FPSCR is a combination of the FPCR and FPSR registers.
|
|
// We also need to set the FPSR NZCV bits that no longer exist on AArch64.
|
|
|
|
using ScopedRegister tempRegister = context.RegisterAllocator.AllocateTempGprRegisterScoped();
|
|
|
|
Operand rtOperand = InstEmitCommon.GetOutputGpr(context, rt);
|
|
|
|
context.Arm64Assembler.MrsFpsr(rtOperand);
|
|
context.Arm64Assembler.MrsFpcr(tempRegister.Operand);
|
|
context.Arm64Assembler.Orr(rtOperand, rtOperand, tempRegister.Operand);
|
|
context.Arm64Assembler.LdrRiUn(tempRegister.Operand, ctx, NativeContextOffsets.FpFlagsBaseOffset);
|
|
context.Arm64Assembler.Bfc(tempRegister.Operand, 0, 28);
|
|
context.Arm64Assembler.Orr(rtOperand, rtOperand, tempRegister.Operand);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
Operand rtOperand = InstEmitCommon.GetOutputGpr(context, rt);
|
|
|
|
context.Arm64Assembler.Mov(rtOperand, 0u);
|
|
}
|
|
}
|
|
|
|
public static void Vmsr(CodeGenContext context, uint rt, uint reg)
|
|
{
|
|
if (reg == 1)
|
|
{
|
|
// FPSCR
|
|
|
|
// TODO: Do not set bits related to features that are not supported (like FP16)?
|
|
|
|
Operand ctx = InstEmitSystem.Register(context.RegisterAllocator.FixedContextRegister);
|
|
Operand rtOperand = InstEmitCommon.GetInputGpr(context, rt);
|
|
|
|
context.Arm64Assembler.MsrFpcr(rtOperand);
|
|
context.Arm64Assembler.MsrFpsr(rtOperand);
|
|
context.Arm64Assembler.StrRiUn(rtOperand, ctx, NativeContextOffsets.FpFlagsBaseOffset);
|
|
}
|
|
}
|
|
}
|
|
}
|