mirror of
https://git.ryujinx.app/ryubing/ryujinx.git
synced 2025-07-29 17:19:50 -06:00
112 lines
2.8 KiB
C#
112 lines
2.8 KiB
C#
using ARMeilleure.State;
|
|
using System;
|
|
using System.Diagnostics;
|
|
|
|
namespace ARMeilleure.Instructions
|
|
{
|
|
static class SoftFloat
|
|
{
|
|
static SoftFloat()
|
|
{
|
|
RecipEstimateTable = BuildRecipEstimateTable();
|
|
RecipSqrtEstimateTable = BuildRecipSqrtEstimateTable();
|
|
}
|
|
|
|
public static readonly byte[] RecipEstimateTable;
|
|
public static readonly byte[] RecipSqrtEstimateTable;
|
|
|
|
private static byte[] BuildRecipEstimateTable()
|
|
{
|
|
byte[] tbl = new byte[256];
|
|
|
|
for (int idx = 0; idx < 256; idx++)
|
|
{
|
|
uint src = (uint)idx + 256u;
|
|
|
|
Debug.Assert(src is >= 256u and < 512u);
|
|
|
|
src = (src << 1) + 1u;
|
|
|
|
uint aux = (1u << 19) / src;
|
|
|
|
uint dst = (aux + 1u) >> 1;
|
|
|
|
Debug.Assert(dst is >= 256u and < 512u);
|
|
|
|
tbl[idx] = (byte)(dst - 256u);
|
|
}
|
|
|
|
return tbl;
|
|
}
|
|
|
|
private static byte[] BuildRecipSqrtEstimateTable()
|
|
{
|
|
byte[] tbl = new byte[384];
|
|
|
|
for (int idx = 0; idx < 384; idx++)
|
|
{
|
|
uint src = (uint)idx + 128u;
|
|
|
|
Debug.Assert(src is >= 128u and < 512u);
|
|
|
|
if (src < 256u)
|
|
{
|
|
src = (src << 1) + 1u;
|
|
}
|
|
else
|
|
{
|
|
src = (src >> 1) << 1;
|
|
src = (src + 1u) << 1;
|
|
}
|
|
|
|
uint aux = 512u;
|
|
|
|
while (src * (aux + 1u) * (aux + 1u) < (1u << 28))
|
|
{
|
|
aux++;
|
|
}
|
|
|
|
uint dst = (aux + 1u) >> 1;
|
|
|
|
Debug.Assert(dst is >= 256u and < 512u);
|
|
|
|
tbl[idx] = (byte)(dst - 256u);
|
|
}
|
|
|
|
return tbl;
|
|
}
|
|
|
|
public static void FPProcessException(FPException exc, ExecutionContext context)
|
|
{
|
|
FPProcessException(exc, context, context.Fpcr);
|
|
}
|
|
|
|
public static void FPProcessException(FPException exc, ExecutionContext context, FPCR fpcr)
|
|
{
|
|
int enable = (int)exc + 8;
|
|
|
|
if ((fpcr & (FPCR)(1 << enable)) != 0)
|
|
{
|
|
throw new NotImplementedException("Floating-point trap handling.");
|
|
}
|
|
else
|
|
{
|
|
context.Fpsr |= (FPSR)(1 << (int)exc);
|
|
}
|
|
}
|
|
|
|
extension(FPCR fpcr)
|
|
{
|
|
public FPRoundingMode RoundingMode
|
|
{
|
|
get
|
|
{
|
|
const int RModeShift = 22;
|
|
|
|
return (FPRoundingMode)(((uint)fpcr >> RModeShift) & 3u);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|