Generate CIL for SCVTF (vector), add undefined encodings for some instructions
This commit is contained in:
parent
9e8d99f30d
commit
7d11a146c0
7 changed files with 340 additions and 285 deletions
|
@ -1,12 +1,14 @@
|
|||
using ChocolArm64.Decoder;
|
||||
using ChocolArm64.State;
|
||||
using ChocolArm64.Translation;
|
||||
using System;
|
||||
using System.Reflection;
|
||||
|
||||
namespace ChocolArm64.Instruction
|
||||
{
|
||||
static partial class AInstEmit
|
||||
{
|
||||
private const BindingFlags Binding = BindingFlags.NonPublic | BindingFlags.Instance;
|
||||
|
||||
public static void Brk(AILEmitterCtx Context)
|
||||
{
|
||||
EmitExceptionCall(Context, nameof(ARegisters.OnBreak));
|
||||
|
@ -27,7 +29,9 @@ namespace ChocolArm64.Instruction
|
|||
|
||||
Context.EmitLdc_I4(Op.Id);
|
||||
|
||||
Context.EmitCall(typeof(ARegisters), MthdName);
|
||||
MethodInfo MthdInfo = typeof(ARegisters).GetMethod(MthdName, Binding);
|
||||
|
||||
Context.EmitCall(MthdInfo);
|
||||
|
||||
if (Context.CurrBlock.Next != null)
|
||||
{
|
||||
|
@ -46,7 +50,11 @@ namespace ChocolArm64.Instruction
|
|||
Context.EmitLdc_I8(Op.Position);
|
||||
Context.EmitLdc_I4(Op.RawOpCode);
|
||||
|
||||
Context.EmitCall(typeof(ARegisters), nameof(ARegisters.OnUndefined));
|
||||
string MthdName = nameof(ARegisters.OnUndefined);
|
||||
|
||||
MethodInfo MthdInfo = typeof(ARegisters).GetMethod(MthdName, Binding);
|
||||
|
||||
Context.EmitCall(MthdInfo);
|
||||
|
||||
if (Context.CurrBlock.Next != null)
|
||||
{
|
||||
|
|
|
@ -104,8 +104,8 @@ namespace ChocolArm64.Instruction
|
|||
|
||||
public static void Fadd_V(AILEmitterCtx Context) => EmitVectorBinaryFOp(Context, OpCodes.Add);
|
||||
|
||||
public static void Fcvtzs_V(AILEmitterCtx Context) => EmitVectorFcvtS(Context);
|
||||
public static void Fcvtzu_V(AILEmitterCtx Context) => EmitVectorFcvtU(Context);
|
||||
public static void Fcvtzs_V(AILEmitterCtx Context) => EmitVectorFcvts(Context);
|
||||
public static void Fcvtzu_V(AILEmitterCtx Context) => EmitVectorFcvtu(Context);
|
||||
|
||||
public static void Fmla_V(AILEmitterCtx Context)
|
||||
{
|
||||
|
@ -264,19 +264,7 @@ namespace ChocolArm64.Instruction
|
|||
Context.EmitStvec(Op.Rd);
|
||||
}
|
||||
|
||||
public static void Scvtf_V(AILEmitterCtx Context)
|
||||
{
|
||||
AOpCodeSimd Op = (AOpCodeSimd)Context.CurrOp;
|
||||
|
||||
Context.EmitLdvec(Op.Rn);
|
||||
Context.EmitLdc_I4(Op.SizeF);
|
||||
|
||||
ASoftFallback.EmitCall(Context,
|
||||
nameof(ASoftFallback.Scvtf_V64),
|
||||
nameof(ASoftFallback.Scvtf_V128));
|
||||
|
||||
Context.EmitStvec(Op.Rd);
|
||||
}
|
||||
public static void Scvtf_V(AILEmitterCtx Context) => EmitVectorScvtf(Context);
|
||||
|
||||
public static void Shl_V(AILEmitterCtx Context)
|
||||
{
|
||||
|
@ -346,7 +334,7 @@ namespace ChocolArm64.Instruction
|
|||
nameof(ASoftFallback.Tbl4_V128)); break;
|
||||
|
||||
default: throw new InvalidOperationException();
|
||||
}
|
||||
}
|
||||
|
||||
Context.EmitStvec(Op.Rd);
|
||||
}
|
||||
|
@ -434,33 +422,12 @@ namespace ChocolArm64.Instruction
|
|||
|
||||
public static void Ushr_V(AILEmitterCtx Context)
|
||||
{
|
||||
AOpCodeSimdShImm Op = (AOpCodeSimdShImm)Context.CurrOp;
|
||||
|
||||
Context.EmitLdvec(Op.Rn);
|
||||
Context.EmitLdc_I4((8 << (Op.Size + 1)) - Op.Imm);
|
||||
Context.EmitLdc_I4(Op.Size);
|
||||
|
||||
ASoftFallback.EmitCall(Context,
|
||||
nameof(ASoftFallback.Ushr64),
|
||||
nameof(ASoftFallback.Ushr128));
|
||||
|
||||
Context.EmitStvec(Op.Rd);
|
||||
EmitVectorShr(Context, ShrFlags.None);
|
||||
}
|
||||
|
||||
public static void Usra_V(AILEmitterCtx Context)
|
||||
{
|
||||
AOpCodeSimdShImm Op = (AOpCodeSimdShImm)Context.CurrOp;
|
||||
|
||||
Context.EmitLdvec(Op.Rd);
|
||||
Context.EmitLdvec(Op.Rn);
|
||||
Context.EmitLdc_I4((8 << (Op.Size + 1)) - Op.Imm);
|
||||
Context.EmitLdc_I4(Op.Size);
|
||||
|
||||
ASoftFallback.EmitCall(Context,
|
||||
nameof(ASoftFallback.Usra64),
|
||||
nameof(ASoftFallback.Usra128));
|
||||
|
||||
Context.EmitStvec(Op.Rd);
|
||||
EmitVectorShr(Context, ShrFlags.Accumulate);
|
||||
}
|
||||
|
||||
public static void Uzp1_V(AILEmitterCtx Context)
|
||||
|
@ -651,11 +618,11 @@ namespace ChocolArm64.Instruction
|
|||
Context.EmitLdc_I4(0);
|
||||
Context.EmitLdc_I4(Op.Size);
|
||||
|
||||
EmitVectorExtractZx(Context, Op.Rn, 0);
|
||||
EmitVectorExtractZx(Context, Op.Rn, 0, Op.Size);
|
||||
|
||||
for (int Index = 1; Index < (Bytes >> Op.Size); Index++)
|
||||
{
|
||||
EmitVectorExtractZx(Context, Op.Rn, Index);
|
||||
EmitVectorExtractZx(Context, Op.Rn, Op.Size, Index);
|
||||
|
||||
Context.Emit(OpCodes.Add);
|
||||
}
|
||||
|
@ -730,7 +697,7 @@ namespace ChocolArm64.Instruction
|
|||
|
||||
int MaxShift = 8 << Op.Size;
|
||||
|
||||
EmitVectorBinaryZx(Context, () =>
|
||||
Action Emit = () =>
|
||||
{
|
||||
AILLabel LblShl = new AILLabel();
|
||||
AILLabel LblZero = new AILLabel();
|
||||
|
@ -771,48 +738,83 @@ namespace ChocolArm64.Instruction
|
|||
Context.EmitLdc_I8(0);
|
||||
|
||||
Context.MarkLabel(LblEnd);
|
||||
});
|
||||
};
|
||||
|
||||
if (Signed)
|
||||
{
|
||||
EmitVectorBinarySx(Context, Emit);
|
||||
}
|
||||
else
|
||||
{
|
||||
EmitVectorBinaryZx(Context, Emit);
|
||||
}
|
||||
}
|
||||
|
||||
private static void EmitVectorFcvtS(AILEmitterCtx Context)
|
||||
private enum ShrFlags
|
||||
{
|
||||
EmitVectorCvtOp(Context, CvtDir.Fcvt, true);
|
||||
None = 0,
|
||||
Signed = 1 << 0,
|
||||
Rounding = 1 << 1,
|
||||
Accumulate = 1 << 2
|
||||
}
|
||||
|
||||
private static void EmitVectorFcvtU(AILEmitterCtx Context)
|
||||
private static void EmitVectorShr(AILEmitterCtx Context, ShrFlags Flags)
|
||||
{
|
||||
EmitVectorCvtOp(Context, CvtDir.Fcvt, false);
|
||||
AOpCodeSimdShImm Op = (AOpCodeSimdShImm)Context.CurrOp;
|
||||
|
||||
int Shift = (8 << (Op.Size + 1)) - Op.Imm;
|
||||
|
||||
if (Flags.HasFlag(ShrFlags.Accumulate))
|
||||
{
|
||||
Action Emit = () =>
|
||||
{
|
||||
Context.EmitLdc_I4(Shift);
|
||||
|
||||
Context.Emit(OpCodes.Shr_Un);
|
||||
Context.Emit(OpCodes.Add);
|
||||
};
|
||||
|
||||
EmitVectorOp(Context, Emit, OperFlags.RdRn, Signed: false);
|
||||
}
|
||||
else
|
||||
{
|
||||
EmitVectorUnaryZx(Context, () =>
|
||||
{
|
||||
Context.EmitLdc_I4(Shift);
|
||||
|
||||
Context.Emit(OpCodes.Shr_Un);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private static void EmitVectorCvtfS(AILEmitterCtx Context)
|
||||
private static void EmitVectorFcvts(AILEmitterCtx Context)
|
||||
{
|
||||
EmitVectorCvtOp(Context, CvtDir.Cvtf, true);
|
||||
EmitVectorFcvtOp(Context, Signed: true);
|
||||
}
|
||||
|
||||
private static void EmitVectorCvtfU(AILEmitterCtx Context)
|
||||
private static void EmitVectorFcvtu(AILEmitterCtx Context)
|
||||
{
|
||||
EmitVectorCvtOp(Context, CvtDir.Cvtf, false);
|
||||
EmitVectorFcvtOp(Context, Signed: false);
|
||||
}
|
||||
|
||||
private enum CvtDir
|
||||
private static void EmitVectorScvtf(AILEmitterCtx Context)
|
||||
{
|
||||
Fcvt,
|
||||
Cvtf
|
||||
EmitVectorCvtfOp(Context, Signed: true);
|
||||
}
|
||||
|
||||
private static void EmitVectorCvtOp(AILEmitterCtx Context, CvtDir Dir, bool Signed)
|
||||
private static void EmitVectorUcvtf(AILEmitterCtx Context)
|
||||
{
|
||||
EmitVectorCvtfOp(Context, Signed: false);
|
||||
}
|
||||
|
||||
private static void EmitVectorFcvtOp(AILEmitterCtx Context, bool Signed)
|
||||
{
|
||||
AOpCodeSimd Op = (AOpCodeSimd)Context.CurrOp;
|
||||
|
||||
int SizeF = Op.Size & 1;
|
||||
int SizeI = SizeF + 2;
|
||||
|
||||
int FBits = 0;
|
||||
|
||||
if (Op is AOpCodeSimdShImm OpImm)
|
||||
{
|
||||
FBits = (8 << (Op.Size + 1)) - OpImm.Imm;
|
||||
}
|
||||
int FBits = GetFBits(Context);
|
||||
|
||||
int Bytes = Context.CurrOp.GetBitsCount() >> 3;
|
||||
|
||||
|
@ -822,26 +824,17 @@ namespace ChocolArm64.Instruction
|
|||
|
||||
Context.EmitLdc_I4(FBits);
|
||||
|
||||
if (Dir == CvtDir.Fcvt)
|
||||
if (SizeF == 0)
|
||||
{
|
||||
//Float to Integer.
|
||||
if (SizeF == 0)
|
||||
{
|
||||
ASoftFallback.EmitCall(Context, Signed
|
||||
? nameof(ASoftFallback.SatSingleToInt32)
|
||||
: nameof(ASoftFallback.SatSingleToUInt32));
|
||||
}
|
||||
else if (SizeF == 1)
|
||||
{
|
||||
ASoftFallback.EmitCall(Context, Signed
|
||||
? nameof(ASoftFallback.SatDoubleToInt64)
|
||||
: nameof(ASoftFallback.SatDoubleToUInt64));
|
||||
}
|
||||
ASoftFallback.EmitCall(Context, Signed
|
||||
? nameof(ASoftFallback.SatSingleToInt32)
|
||||
: nameof(ASoftFallback.SatSingleToUInt32));
|
||||
}
|
||||
else if (Dir == CvtDir.Cvtf)
|
||||
else if (SizeF == 1)
|
||||
{
|
||||
//Integer to Float.
|
||||
//TODO.
|
||||
ASoftFallback.EmitCall(Context, Signed
|
||||
? nameof(ASoftFallback.SatDoubleToInt64)
|
||||
: nameof(ASoftFallback.SatDoubleToUInt64));
|
||||
}
|
||||
|
||||
EmitVectorInsert(Context, Op.Rd, Index, SizeI);
|
||||
|
@ -853,6 +846,57 @@ namespace ChocolArm64.Instruction
|
|||
}
|
||||
}
|
||||
|
||||
private static void EmitVectorCvtfOp(AILEmitterCtx Context, bool Signed)
|
||||
{
|
||||
AOpCodeSimd Op = (AOpCodeSimd)Context.CurrOp;
|
||||
|
||||
int SizeF = Op.Size & 1;
|
||||
int SizeI = SizeF + 2;
|
||||
|
||||
int FBits = GetFBits(Context);
|
||||
|
||||
int Bytes = Context.CurrOp.GetBitsCount() >> 3;
|
||||
|
||||
for (int Index = 0; Index < (Bytes >> SizeI); Index++)
|
||||
{
|
||||
EmitVectorExtract(Context, Op.Rn, Index, SizeI, Signed);
|
||||
|
||||
Context.EmitLdc_I4(FBits);
|
||||
|
||||
if (SizeF == 0)
|
||||
{
|
||||
Context.Emit(OpCodes.Conv_I4);
|
||||
|
||||
ASoftFallback.EmitCall(Context, Signed
|
||||
? nameof(ASoftFallback.Int32ToSingle)
|
||||
: nameof(ASoftFallback.UInt32ToSingle));
|
||||
}
|
||||
else if (SizeF == 1)
|
||||
{
|
||||
ASoftFallback.EmitCall(Context, Signed
|
||||
? nameof(ASoftFallback.Int64ToDouble)
|
||||
: nameof(ASoftFallback.UInt64ToDouble));
|
||||
}
|
||||
|
||||
EmitVectorInsertF(Context, Op.Rd, Index, SizeF);
|
||||
}
|
||||
|
||||
if (Op.RegisterSize == ARegisterSize.SIMD64)
|
||||
{
|
||||
EmitVectorZeroUpper(Context, Op.Rd);
|
||||
}
|
||||
}
|
||||
|
||||
private static int GetFBits(AILEmitterCtx Context)
|
||||
{
|
||||
if (Context.CurrOp is AOpCodeSimdShImm Op)
|
||||
{
|
||||
return (8 << (Op.Size + 1)) - Op.Imm;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
private static void EmitVectorBinaryFOp(AILEmitterCtx Context, OpCode ILOp)
|
||||
{
|
||||
EmitVectorBinaryFOp(Context, () => Context.Emit(ILOp));
|
||||
|
@ -899,36 +943,43 @@ namespace ChocolArm64.Instruction
|
|||
|
||||
private static void EmitVectorUnarySx(AILEmitterCtx Context, Action Emit)
|
||||
{
|
||||
EmitVectorOp(Context, Emit, 1, true);
|
||||
EmitVectorOp(Context, Emit, OperFlags.Rn, true);
|
||||
}
|
||||
|
||||
private static void EmitVectorBinarySx(AILEmitterCtx Context, Action Emit)
|
||||
{
|
||||
EmitVectorOp(Context, Emit, 2, true);
|
||||
EmitVectorOp(Context, Emit, OperFlags.RnRm, true);
|
||||
}
|
||||
|
||||
private static void EmitVectorUnaryZx(AILEmitterCtx Context, Action Emit)
|
||||
{
|
||||
EmitVectorOp(Context, Emit, 1, false);
|
||||
EmitVectorOp(Context, Emit, OperFlags.Rn, false);
|
||||
}
|
||||
|
||||
private static void EmitVectorBinaryZx(AILEmitterCtx Context, Action Emit)
|
||||
{
|
||||
EmitVectorOp(Context, Emit, 2, false);
|
||||
EmitVectorOp(Context, Emit, OperFlags.RnRm, false);
|
||||
}
|
||||
|
||||
private static void EmitVectorTernaryZx(AILEmitterCtx Context, Action Emit)
|
||||
{
|
||||
EmitVectorOp(Context, Emit, 3, false);
|
||||
EmitVectorOp(Context, Emit, OperFlags.RdRnRm, false);
|
||||
}
|
||||
|
||||
private static void EmitVectorOp(AILEmitterCtx Context, Action Emit, int Opers, bool Signed)
|
||||
[Flags]
|
||||
private enum OperFlags
|
||||
{
|
||||
if (Opers < 1 || Opers > 3)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException(nameof(Opers));
|
||||
}
|
||||
Rd = 1 << 0,
|
||||
Rn = 1 << 1,
|
||||
Rm = 1 << 2,
|
||||
|
||||
RnRm = Rn | Rm,
|
||||
RdRn = Rd | Rn,
|
||||
RdRnRm = Rd | Rn | Rm
|
||||
}
|
||||
|
||||
private static void EmitVectorOp(AILEmitterCtx Context, Action Emit, OperFlags Opers, bool Signed)
|
||||
{
|
||||
AOpCodeSimd Op = (AOpCodeSimd)Context.CurrOp;
|
||||
|
||||
int Bytes = Context.CurrOp.GetBitsCount() >> 3;
|
||||
|
@ -939,19 +990,19 @@ namespace ChocolArm64.Instruction
|
|||
Context.EmitLdc_I4(Index);
|
||||
Context.EmitLdc_I4(Op.Size);
|
||||
|
||||
if (Opers == 3)
|
||||
if (Opers.HasFlag(OperFlags.Rd))
|
||||
{
|
||||
EmitVectorExtract(Context, Op.Rd, Index, Signed);
|
||||
EmitVectorExtract(Context, Op.Rd, Index, Op.Size, Signed);
|
||||
}
|
||||
|
||||
if (Opers >= 1)
|
||||
if (Opers.HasFlag(OperFlags.Rn))
|
||||
{
|
||||
EmitVectorExtract(Context, Op.Rn, Index, Signed);
|
||||
EmitVectorExtract(Context, Op.Rn, Index, Op.Size, Signed);
|
||||
}
|
||||
|
||||
if (Opers >= 2)
|
||||
if (Opers.HasFlag(OperFlags.Rm))
|
||||
{
|
||||
EmitVectorExtract(Context, ((AOpCodeSimdReg)Op).Rm, Index, Signed);
|
||||
EmitVectorExtract(Context, ((AOpCodeSimdReg)Op).Rm, Index, Op.Size, Signed);
|
||||
}
|
||||
|
||||
Emit();
|
||||
|
@ -999,7 +1050,7 @@ namespace ChocolArm64.Instruction
|
|||
Context.EmitLdc_I4(Index);
|
||||
Context.EmitLdc_I4(Op.Size);
|
||||
|
||||
EmitVectorExtract(Context, Op.Rn, Index, Signed);
|
||||
EmitVectorExtract(Context, Op.Rn, Index, Op.Size, Signed);
|
||||
|
||||
Context.EmitLdc_I8(Imm);
|
||||
|
||||
|
@ -1026,11 +1077,11 @@ namespace ChocolArm64.Instruction
|
|||
|
||||
for (int Index = 0; Index < (Bytes >> Op.Size); Index++)
|
||||
{
|
||||
EmitVectorExtractSx(Context, Op.Rn, Index);
|
||||
EmitVectorExtractSx(Context, Op.Rn, Index, Op.Size);
|
||||
|
||||
if (Op is AOpCodeSimdReg BinOp)
|
||||
{
|
||||
EmitVectorExtractSx(Context, BinOp.Rm, Index);
|
||||
EmitVectorExtractSx(Context, BinOp.Rm, Index, Op.Size);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1078,29 +1129,39 @@ namespace ChocolArm64.Instruction
|
|||
}
|
||||
}
|
||||
|
||||
private static void EmitVectorExtractSx(AILEmitterCtx Context, int Reg, int Index)
|
||||
private static void EmitVectorExtractSx(AILEmitterCtx Context, int Reg, int Index, int Size)
|
||||
{
|
||||
EmitVectorExtract(Context, Reg, Index, true);
|
||||
EmitVectorExtract(Context, Reg, Index, Size, true);
|
||||
}
|
||||
|
||||
private static void EmitVectorExtractZx(AILEmitterCtx Context, int Reg, int Index)
|
||||
private static void EmitVectorExtractZx(AILEmitterCtx Context, int Reg, int Index, int Size)
|
||||
{
|
||||
EmitVectorExtract(Context, Reg, Index, false);
|
||||
EmitVectorExtract(Context, Reg, Index, Size, false);
|
||||
}
|
||||
|
||||
private static void EmitVectorExtract(AILEmitterCtx Context, int Reg, int Index, bool Signed)
|
||||
private static void EmitVectorExtract(AILEmitterCtx Context, int Reg, int Index, int Size, bool Signed)
|
||||
{
|
||||
IAOpCodeSimd Op = (IAOpCodeSimd)Context.CurrOp;
|
||||
|
||||
Context.EmitLdvec(Reg);
|
||||
Context.EmitLdc_I4(Index);
|
||||
Context.EmitLdc_I4(Op.Size);
|
||||
Context.EmitLdc_I4(Size);
|
||||
|
||||
ASoftFallback.EmitCall(Context, Signed
|
||||
? nameof(ASoftFallback.ExtractSVec)
|
||||
: nameof(ASoftFallback.ExtractVec));
|
||||
}
|
||||
|
||||
private static void EmitVectorZeroLower(AILEmitterCtx Context, int Rd)
|
||||
{
|
||||
EmitVectorInsert(Context, Rd, 0, 3, 0);
|
||||
}
|
||||
|
||||
private static void EmitVectorZeroUpper(AILEmitterCtx Context, int Rd)
|
||||
{
|
||||
EmitVectorInsert(Context, Rd, 1, 3, 0);
|
||||
}
|
||||
|
||||
private static void EmitVectorInsertF(AILEmitterCtx Context, int Reg, int Index, int Size)
|
||||
{
|
||||
Context.EmitLdvec(Reg);
|
||||
|
@ -1122,16 +1183,6 @@ namespace ChocolArm64.Instruction
|
|||
Context.EmitStvec(Reg);
|
||||
}
|
||||
|
||||
private static void EmitVectorZeroLower(AILEmitterCtx Context, int Rd)
|
||||
{
|
||||
EmitVectorInsert(Context, Rd, 0, 3, 0);
|
||||
}
|
||||
|
||||
private static void EmitVectorZeroUpper(AILEmitterCtx Context, int Rd)
|
||||
{
|
||||
EmitVectorInsert(Context, Rd, 1, 3, 0);
|
||||
}
|
||||
|
||||
private static void EmitVectorInsert(AILEmitterCtx Context, int Reg, int Index, int Size)
|
||||
{
|
||||
Context.EmitLdvec(Reg);
|
||||
|
|
|
@ -97,39 +97,7 @@ namespace ChocolArm64.Instruction
|
|||
throw new ArgumentException(nameof(Size));
|
||||
}
|
||||
|
||||
public static int SatDoubleToInt32(double Value, int FBits = 0)
|
||||
{
|
||||
if (FBits != 0) Value *= Math.Pow(2, FBits);
|
||||
|
||||
return Value > int.MaxValue ? int.MaxValue :
|
||||
Value < int.MinValue ? int.MinValue : (int)Value;
|
||||
}
|
||||
|
||||
public static long SatDoubleToInt64(double Value, int FBits = 0)
|
||||
{
|
||||
if (FBits != 0) Value *= Math.Pow(2, FBits);
|
||||
|
||||
return Value > long.MaxValue ? long.MaxValue :
|
||||
Value < long.MinValue ? long.MinValue : (long)Value;
|
||||
}
|
||||
|
||||
public static uint SatDoubleToUInt32(double Value, int FBits = 0)
|
||||
{
|
||||
if (FBits != 0) Value *= Math.Pow(2, FBits);
|
||||
|
||||
return Value > uint.MaxValue ? uint.MaxValue :
|
||||
Value < uint.MinValue ? uint.MinValue : (uint)Value;
|
||||
}
|
||||
|
||||
public static ulong SatDoubleToUInt64(double Value, int FBits = 0)
|
||||
{
|
||||
if (FBits != 0) Value *= Math.Pow(2, FBits);
|
||||
|
||||
return Value > ulong.MaxValue ? ulong.MaxValue :
|
||||
Value < ulong.MinValue ? ulong.MinValue : (ulong)Value;
|
||||
}
|
||||
|
||||
public static int SatSingleToInt32(float Value, int FBits = 0)
|
||||
public static int SatSingleToInt32(float Value, int FBits)
|
||||
{
|
||||
if (FBits != 0) Value *= MathF.Pow(2, FBits);
|
||||
|
||||
|
@ -137,7 +105,7 @@ namespace ChocolArm64.Instruction
|
|||
Value < int.MinValue ? int.MinValue : (int)Value;
|
||||
}
|
||||
|
||||
public static long SatSingleToInt64(float Value, int FBits = 0)
|
||||
public static long SatSingleToInt64(float Value, int FBits)
|
||||
{
|
||||
if (FBits != 0) Value *= MathF.Pow(2, FBits);
|
||||
|
||||
|
@ -145,7 +113,7 @@ namespace ChocolArm64.Instruction
|
|||
Value < long.MinValue ? long.MinValue : (long)Value;
|
||||
}
|
||||
|
||||
public static uint SatSingleToUInt32(float Value, int FBits = 0)
|
||||
public static uint SatSingleToUInt32(float Value, int FBits)
|
||||
{
|
||||
if (FBits != 0) Value *= MathF.Pow(2, FBits);
|
||||
|
||||
|
@ -153,7 +121,7 @@ namespace ChocolArm64.Instruction
|
|||
Value < uint.MinValue ? uint.MinValue : (uint)Value;
|
||||
}
|
||||
|
||||
public static ulong SatSingleToUInt64(float Value, int FBits = 0)
|
||||
public static ulong SatSingleToUInt64(float Value, int FBits)
|
||||
{
|
||||
if (FBits != 0) Value *= MathF.Pow(2, FBits);
|
||||
|
||||
|
@ -161,6 +129,110 @@ namespace ChocolArm64.Instruction
|
|||
Value < ulong.MinValue ? ulong.MinValue : (ulong)Value;
|
||||
}
|
||||
|
||||
public static int SatDoubleToInt32(double Value, int FBits)
|
||||
{
|
||||
if (FBits != 0) Value *= Math.Pow(2, FBits);
|
||||
|
||||
return Value > int.MaxValue ? int.MaxValue :
|
||||
Value < int.MinValue ? int.MinValue : (int)Value;
|
||||
}
|
||||
|
||||
public static long SatDoubleToInt64(double Value, int FBits)
|
||||
{
|
||||
if (FBits != 0) Value *= Math.Pow(2, FBits);
|
||||
|
||||
return Value > long.MaxValue ? long.MaxValue :
|
||||
Value < long.MinValue ? long.MinValue : (long)Value;
|
||||
}
|
||||
|
||||
public static uint SatDoubleToUInt32(double Value, int FBits)
|
||||
{
|
||||
if (FBits != 0) Value *= Math.Pow(2, FBits);
|
||||
|
||||
return Value > uint.MaxValue ? uint.MaxValue :
|
||||
Value < uint.MinValue ? uint.MinValue : (uint)Value;
|
||||
}
|
||||
|
||||
public static ulong SatDoubleToUInt64(double Value, int FBits)
|
||||
{
|
||||
if (FBits != 0) Value *= Math.Pow(2, FBits);
|
||||
|
||||
return Value > ulong.MaxValue ? ulong.MaxValue :
|
||||
Value < ulong.MinValue ? ulong.MinValue : (ulong)Value;
|
||||
}
|
||||
|
||||
public static float Int32ToSingle(int Value, int FBits)
|
||||
{
|
||||
float ValueF = Value;
|
||||
|
||||
if (FBits != 0) ValueF *= 1 / MathF.Pow(2, FBits);
|
||||
|
||||
return ValueF;
|
||||
}
|
||||
|
||||
public static float Int64ToSingle(long Value, int FBits)
|
||||
{
|
||||
float ValueF = Value;
|
||||
|
||||
if (FBits != 0) ValueF *= 1 / MathF.Pow(2, FBits);
|
||||
|
||||
return ValueF;
|
||||
}
|
||||
|
||||
public static float UInt32ToSingle(uint Value, int FBits)
|
||||
{
|
||||
float ValueF = Value;
|
||||
|
||||
if (FBits != 0) ValueF *= 1 / MathF.Pow(2, FBits);
|
||||
|
||||
return ValueF;
|
||||
}
|
||||
|
||||
public static float UInt64ToSingle(ulong Value, int FBits)
|
||||
{
|
||||
float ValueF = Value;
|
||||
|
||||
if (FBits != 0) ValueF *= 1 / MathF.Pow(2, FBits);
|
||||
|
||||
return ValueF;
|
||||
}
|
||||
|
||||
public static float Int32ToDouble(int Value, int FBits)
|
||||
{
|
||||
float ValueF = Value;
|
||||
|
||||
if (FBits != 0) ValueF *= 1 / MathF.Pow(2, FBits);
|
||||
|
||||
return ValueF;
|
||||
}
|
||||
|
||||
public static float Int64ToDouble(long Value, int FBits)
|
||||
{
|
||||
float ValueF = Value;
|
||||
|
||||
if (FBits != 0) ValueF *= 1 / MathF.Pow(2, FBits);
|
||||
|
||||
return ValueF;
|
||||
}
|
||||
|
||||
public static float UInt32ToDouble(uint Value, int FBits)
|
||||
{
|
||||
float ValueF = Value;
|
||||
|
||||
if (FBits != 0) ValueF *= 1 / MathF.Pow(2, FBits);
|
||||
|
||||
return ValueF;
|
||||
}
|
||||
|
||||
public static float UInt64ToDouble(ulong Value, int FBits)
|
||||
{
|
||||
float ValueF = Value;
|
||||
|
||||
if (FBits != 0) ValueF *= 1 / MathF.Pow(2, FBits);
|
||||
|
||||
return ValueF;
|
||||
}
|
||||
|
||||
public static ulong SMulHi128(ulong LHS, ulong RHS)
|
||||
{
|
||||
long LLo = (uint)(LHS >> 0);
|
||||
|
@ -556,44 +628,6 @@ namespace ChocolArm64.Instruction
|
|||
return Res;
|
||||
}
|
||||
|
||||
public static AVec Scvtf_V64(AVec Vector, int Size)
|
||||
{
|
||||
return Scvtf_V(Vector, Size, 2);
|
||||
}
|
||||
|
||||
public static AVec Scvtf_V128(AVec Vector, int Size)
|
||||
{
|
||||
return Scvtf_V(Vector, Size, 4);
|
||||
}
|
||||
|
||||
private static AVec Scvtf_V(AVec Vector, int Size, int Bytes)
|
||||
{
|
||||
AVec Res = new AVec();
|
||||
|
||||
int Elems = Bytes >> Size;
|
||||
|
||||
if (Size == 0)
|
||||
{
|
||||
for (int Index = 0; Index < Elems; Index++)
|
||||
{
|
||||
int Value = (int)ExtractSVec(Vector, Index, Size + 2);
|
||||
|
||||
Res = AVec.InsertSingle(Res, Index, Value);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int Index = 0; Index < Elems; Index++)
|
||||
{
|
||||
long Value = ExtractSVec(Vector, Index, Size + 2);
|
||||
|
||||
Res = AVec.InsertDouble(Res, Index, Value);
|
||||
}
|
||||
}
|
||||
|
||||
return Res;
|
||||
}
|
||||
|
||||
public static AVec Sshll(AVec Vector, int Shift, int Size)
|
||||
{
|
||||
return Sshll_(Vector, Shift, Size, false);
|
||||
|
@ -785,57 +819,6 @@ namespace ChocolArm64.Instruction
|
|||
return Res;
|
||||
}
|
||||
|
||||
public static AVec Ushr64(AVec Vector, int Shift, int Size)
|
||||
{
|
||||
return Ushr(Vector, Shift, Size, 8);
|
||||
}
|
||||
|
||||
public static AVec Ushr128(AVec Vector, int Shift, int Size)
|
||||
{
|
||||
return Ushr(Vector, Shift, Size, 16);
|
||||
}
|
||||
|
||||
private static AVec Ushr(AVec Vector, int Shift, int Size, int Bytes)
|
||||
{
|
||||
AVec Res = new AVec();
|
||||
|
||||
int Elems = Bytes >> Size;
|
||||
|
||||
for (int Index = 0; Index < Elems; Index++)
|
||||
{
|
||||
ulong Value = ExtractVec(Vector, Index, Size);
|
||||
|
||||
Res = InsertVec(Res, Index, Size, Value >> Shift);
|
||||
}
|
||||
|
||||
return Res;
|
||||
}
|
||||
|
||||
public static AVec Usra64(AVec Res, AVec Vector, int Shift, int Size)
|
||||
{
|
||||
return Usra(Res, Vector, Shift, Size, 8);
|
||||
}
|
||||
|
||||
public static AVec Usra128(AVec Res, AVec Vector, int Shift, int Size)
|
||||
{
|
||||
return Usra(Res, Vector, Shift, Size, 16);
|
||||
}
|
||||
|
||||
private static AVec Usra(AVec Res, AVec Vector, int Shift, int Size, int Bytes)
|
||||
{
|
||||
int Elems = Bytes >> Size;
|
||||
|
||||
for (int Index = 0; Index < Elems; Index++)
|
||||
{
|
||||
ulong Value = ExtractVec(Vector, Index, Size);
|
||||
ulong Addend = ExtractVec(Res, Index, Size);
|
||||
|
||||
Res = InsertVec(Res, Index, Size, Addend + (Value >> Shift));
|
||||
}
|
||||
|
||||
return Res;
|
||||
}
|
||||
|
||||
public static AVec Uzp1_V64(AVec LHS, AVec RHS, int Size)
|
||||
{
|
||||
return Uzp(LHS, RHS, Size, 0, 8);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue