forked from Mirror/Ryujinx
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
|
@ -11,11 +11,11 @@ namespace ChocolArm64
|
|||
#region "OpCode Table"
|
||||
//Integer
|
||||
Set("x0011010000xxxxx000000xxxxxxxxxx", AInstEmit.Adc, typeof(AOpCodeAluRs));
|
||||
Set("x0010001xxxxxxxxxxxxxxxxxxxxxxxx", AInstEmit.Add, typeof(AOpCodeAluImm));
|
||||
Set("x0001011xx0xxxxxxxxxxxxxxxxxxxxx", AInstEmit.Add, typeof(AOpCodeAluRs));
|
||||
Set("x00100010xxxxxxxxxxxxxxxxxxxxxxx", AInstEmit.Add, typeof(AOpCodeAluImm));
|
||||
Set("x0001011<<0xxxxxxxxxxxxxxxxxxxxx", AInstEmit.Add, typeof(AOpCodeAluRs));
|
||||
Set("x0001011001xxxxxxxxxxxxxxxxxxxxx", AInstEmit.Add, typeof(AOpCodeAluRx));
|
||||
Set("x0110001xxxxxxxxxxxxxxxxxxxxxxxx", AInstEmit.Adds, typeof(AOpCodeAluImm));
|
||||
Set("x0101011xx0xxxxxxxxxxxxxxxxxxxxx", AInstEmit.Adds, typeof(AOpCodeAluRs));
|
||||
Set("x01100010xxxxxxxxxxxxxxxxxxxxxxx", AInstEmit.Adds, typeof(AOpCodeAluImm));
|
||||
Set("x0101011<<0xxxxxxxxxxxxxxxxxxxxx", AInstEmit.Adds, typeof(AOpCodeAluRs));
|
||||
Set("x0101011001xxxxxxxxxxxxxxxxxxxxx", AInstEmit.Adds, typeof(AOpCodeAluRx));
|
||||
Set("0xx10000xxxxxxxxxxxxxxxxxxxxxxxx", AInstEmit.Adr, typeof(AOpCodeAdr));
|
||||
Set("1xx10000xxxxxxxxxxxxxxxxxxxxxxxx", AInstEmit.Adrp, typeof(AOpCodeAdr));
|
||||
|
@ -102,11 +102,11 @@ namespace ChocolArm64
|
|||
Set("xx111000001xxxxxxxxx10xxxxxxxxxx", AInstEmit.Str, typeof(AOpCodeMemReg));
|
||||
Set("1x001000001xxxxx0xxxxxxxxxxxxxxx", AInstEmit.Stxp, typeof(AOpCodeMemEx));
|
||||
Set("xx001000000xxxxx0xxxxxxxxxxxxxxx", AInstEmit.Stxr, typeof(AOpCodeMemEx));
|
||||
Set("x1010001xxxxxxxxxxxxxxxxxxxxxxxx", AInstEmit.Sub, typeof(AOpCodeAluImm));
|
||||
Set("x1001011xx0xxxxxxxxxxxxxxxxxxxxx", AInstEmit.Sub, typeof(AOpCodeAluRs));
|
||||
Set("x10100010xxxxxxxxxxxxxxxxxxxxxxx", AInstEmit.Sub, typeof(AOpCodeAluImm));
|
||||
Set("x1001011<<0xxxxxxxxxxxxxxxxxxxxx", AInstEmit.Sub, typeof(AOpCodeAluRs));
|
||||
Set("x1001011001xxxxxxxxxxxxxxxxxxxxx", AInstEmit.Sub, typeof(AOpCodeAluRx));
|
||||
Set("x1110001xxxxxxxxxxxxxxxxxxxxxxxx", AInstEmit.Subs, typeof(AOpCodeAluImm));
|
||||
Set("x1101011xx0xxxxxxxxxxxxxxxxxxxxx", AInstEmit.Subs, typeof(AOpCodeAluRs));
|
||||
Set("x11100010xxxxxxxxxxxxxxxxxxxxxxx", AInstEmit.Subs, typeof(AOpCodeAluImm));
|
||||
Set("x1101011<<0xxxxxxxxxxxxxxxxxxxxx", AInstEmit.Subs, typeof(AOpCodeAluRs));
|
||||
Set("x1101011001xxxxxxxxxxxxxxxxxxxxx", AInstEmit.Subs, typeof(AOpCodeAluRx));
|
||||
Set("11010100000xxxxxxxxxxxxxxxx00001", AInstEmit.Svc, typeof(AOpCodeException));
|
||||
Set("1101010100001xxxxxxxxxxxxxxxxxxx", AInstEmit.Sys, typeof(AOpCodeSystem));
|
||||
|
@ -119,24 +119,25 @@ namespace ChocolArm64
|
|||
Set("10011011110xxxxx0xxxxxxxxxxxxxxx", AInstEmit.Umulh, typeof(AOpCodeMul));
|
||||
|
||||
//Vector
|
||||
Set("0x001110xx1xxxxx100001xxxxxxxxxx", AInstEmit.Add_V, typeof(AOpCodeSimdReg));
|
||||
Set("0>001110<<1xxxxx100001xxxxxxxxxx", AInstEmit.Add_V, typeof(AOpCodeSimdReg));
|
||||
Set("01011110xx110001101110xxxxxxxxxx", AInstEmit.Addp_S, typeof(AOpCodeSimd));
|
||||
Set("0x001110xx1xxxxx101111xxxxxxxxxx", AInstEmit.Addp_V, typeof(AOpCodeSimdReg));
|
||||
Set("0x001110<<110001101110xxxxxxxxxx", AInstEmit.Addv_V, typeof(AOpCodeSimd));
|
||||
Set("0>001110<<1xxxxx101111xxxxxxxxxx", AInstEmit.Addp_V, typeof(AOpCodeSimdReg));
|
||||
Set("000011100x110001101110xxxxxxxxxx", AInstEmit.Addv_V, typeof(AOpCodeSimd));
|
||||
Set("01001110<<110001101110xxxxxxxxxx", AInstEmit.Addv_V, typeof(AOpCodeSimd));
|
||||
Set("0x001110001xxxxx000111xxxxxxxxxx", AInstEmit.And_V, typeof(AOpCodeSimdReg));
|
||||
Set("0x001110011xxxxx000111xxxxxxxxxx", AInstEmit.Bic_V, typeof(AOpCodeSimdReg));
|
||||
Set("0x10111100000xxx<<x101xxxxxxxxxx", AInstEmit.Bic_Vi, typeof(AOpCodeSimdImm));
|
||||
Set("0x101110011xxxxx000111xxxxxxxxxx", AInstEmit.Bsl_V, typeof(AOpCodeSimdReg));
|
||||
Set("0x101110xx1xxxxx100011xxxxxxxxxx", AInstEmit.Cmeq_V, typeof(AOpCodeSimdReg));
|
||||
Set("0x001110xx100000100110xxxxxxxxxx", AInstEmit.Cmeq_V, typeof(AOpCodeSimd));
|
||||
Set("0x001110xx1xxxxx001111xxxxxxxxxx", AInstEmit.Cmge_V, typeof(AOpCodeSimdReg));
|
||||
Set("0x101110xx100000100010xxxxxxxxxx", AInstEmit.Cmge_V, typeof(AOpCodeSimd));
|
||||
Set("0x001110xx1xxxxx001101xxxxxxxxxx", AInstEmit.Cmgt_V, typeof(AOpCodeSimdReg));
|
||||
Set("0x001110xx100000100010xxxxxxxxxx", AInstEmit.Cmgt_V, typeof(AOpCodeSimd));
|
||||
Set("0x101110xx1xxxxx001101xxxxxxxxxx", AInstEmit.Cmhi_V, typeof(AOpCodeSimdReg));
|
||||
Set("0x101110xx1xxxxx001111xxxxxxxxxx", AInstEmit.Cmhs_V, typeof(AOpCodeSimdReg));
|
||||
Set("0x101110xx100000100110xxxxxxxxxx", AInstEmit.Cmle_V, typeof(AOpCodeSimd));
|
||||
Set("0x001110xx100000101010xxxxxxxxxx", AInstEmit.Cmlt_V, typeof(AOpCodeSimd));
|
||||
Set("0>101110<<1xxxxx100011xxxxxxxxxx", AInstEmit.Cmeq_V, typeof(AOpCodeSimdReg));
|
||||
Set("0>001110<<100000100110xxxxxxxxxx", AInstEmit.Cmeq_V, typeof(AOpCodeSimd));
|
||||
Set("0>001110<<1xxxxx001111xxxxxxxxxx", AInstEmit.Cmge_V, typeof(AOpCodeSimdReg));
|
||||
Set("0>101110<<100000100010xxxxxxxxxx", AInstEmit.Cmge_V, typeof(AOpCodeSimd));
|
||||
Set("0>001110<<1xxxxx001101xxxxxxxxxx", AInstEmit.Cmgt_V, typeof(AOpCodeSimdReg));
|
||||
Set("0>001110<<100000100010xxxxxxxxxx", AInstEmit.Cmgt_V, typeof(AOpCodeSimd));
|
||||
Set("0>101110<<1xxxxx001101xxxxxxxxxx", AInstEmit.Cmhi_V, typeof(AOpCodeSimdReg));
|
||||
Set("0>101110<<1xxxxx001111xxxxxxxxxx", AInstEmit.Cmhs_V, typeof(AOpCodeSimdReg));
|
||||
Set("0>101110<<100000100110xxxxxxxxxx", AInstEmit.Cmle_V, typeof(AOpCodeSimd));
|
||||
Set("0>001110<<100000101010xxxxxxxxxx", AInstEmit.Cmlt_V, typeof(AOpCodeSimd));
|
||||
Set("0x00111000100000010110xxxxxxxxxx", AInstEmit.Cnt_V, typeof(AOpCodeSimd));
|
||||
Set("01011110000xxxxx000001xxxxxxxxxx", AInstEmit.Dup_S, typeof(AOpCodeSimdIns));
|
||||
Set("0x001110000xxxxx000011xxxxxxxxxx", AInstEmit.Dup_Gp, typeof(AOpCodeSimdIns));
|
||||
|
@ -199,26 +200,28 @@ namespace ChocolArm64
|
|||
Set("xx111101x1xxxxxxxxxxxxxxxxxxxxxx", AInstEmit.Ldr, typeof(AOpCodeSimdMemImm));
|
||||
Set("xx111100x11xxxxxxxxx10xxxxxxxxxx", AInstEmit.Ldr, typeof(AOpCodeSimdMemReg));
|
||||
Set("xx011100xxxxxxxxxxxxxxxxxxxxxxxx", AInstEmit.LdrLit, typeof(AOpCodeSimdMemLit));
|
||||
Set("0x001110xx1xxxxx100101xxxxxxxxxx", AInstEmit.Mla_V, typeof(AOpCodeSimdReg));
|
||||
Set("0x001110<<1xxxxx100101xxxxxxxxxx", AInstEmit.Mla_V, typeof(AOpCodeSimdReg));
|
||||
Set("0x00111100000xxx0xx001xxxxxxxxxx", AInstEmit.Movi_V, typeof(AOpCodeSimdImm));
|
||||
Set("0x00111100000xxx10x001xxxxxxxxxx", AInstEmit.Movi_V, typeof(AOpCodeSimdImm));
|
||||
Set("0x00111100000xxx110x01xxxxxxxxxx", AInstEmit.Movi_V, typeof(AOpCodeSimdImm));
|
||||
Set("0xx0111100000xxx111001xxxxxxxxxx", AInstEmit.Movi_V, typeof(AOpCodeSimdImm));
|
||||
Set("0x001110xx1xxxxx100111xxxxxxxxxx", AInstEmit.Mul_V, typeof(AOpCodeSimdReg));
|
||||
Set("0x001110<<1xxxxx100111xxxxxxxxxx", AInstEmit.Mul_V, typeof(AOpCodeSimdReg));
|
||||
Set("0x10111100000xxx0xx001xxxxxxxxxx", AInstEmit.Mvni_V, typeof(AOpCodeSimdImm));
|
||||
Set("0x10111100000xxx10x001xxxxxxxxxx", AInstEmit.Mvni_V, typeof(AOpCodeSimdImm));
|
||||
Set("0x10111100000xxx110x01xxxxxxxxxx", AInstEmit.Mvni_V, typeof(AOpCodeSimdImm));
|
||||
Set("0x101110xx100000101110xxxxxxxxxx", AInstEmit.Neg_V, typeof(AOpCodeSimdReg));
|
||||
Set("0>101110<<100000101110xxxxxxxxxx", AInstEmit.Neg_V, typeof(AOpCodeSimdReg));
|
||||
Set("0x10111000100000010110xxxxxxxxxx", AInstEmit.Not_V, typeof(AOpCodeSimd));
|
||||
Set("0x001110101xxxxx000111xxxxxxxxxx", AInstEmit.Orr_V, typeof(AOpCodeSimdReg));
|
||||
Set("0x00111100000xxx<<x101xxxxxxxxxx", AInstEmit.Orr_Vi, typeof(AOpCodeSimdImm));
|
||||
Set("0x001110<<1xxxxx000100xxxxxxxxxx", AInstEmit.Saddw_V, typeof(AOpCodeSimdReg));
|
||||
Set("x0011110xx100010000000xxxxxxxxxx", AInstEmit.Scvtf_Gp, typeof(AOpCodeSimdCvt));
|
||||
Set("010111100x100001110110xxxxxxxxxx", AInstEmit.Scvtf_S, typeof(AOpCodeSimd));
|
||||
Set("0x0011100x100001110110xxxxxxxxxx", AInstEmit.Scvtf_V, typeof(AOpCodeSimd));
|
||||
Set("010111110>>>>xxx010101xxxxxxxxxx", AInstEmit.Shl_S, typeof(AOpCodeSimdShImm));
|
||||
Set("0x0011110>>>>xxx010101xxxxxxxxxx", AInstEmit.Shl_V, typeof(AOpCodeSimdShImm));
|
||||
Set("0x001110<<1xxxxx011001xxxxxxxxxx", AInstEmit.Smax_V, typeof(AOpCodeSimdReg));
|
||||
Set("0x001110<<1xxxxx011011xxxxxxxxxx", AInstEmit.Smin_V, typeof(AOpCodeSimdReg));
|
||||
Set("0x001110xx1xxxxx010001xxxxxxxxxx", AInstEmit.Sshl_V, typeof(AOpCodeSimdReg));
|
||||
Set("0>001110<<1xxxxx010001xxxxxxxxxx", AInstEmit.Sshl_V, typeof(AOpCodeSimdReg));
|
||||
Set("0x00111100>>>xxx101001xxxxxxxxxx", AInstEmit.Sshll_V, typeof(AOpCodeSimdShImm));
|
||||
Set("010111110>>>>xxx000001xxxxxxxxxx", AInstEmit.Sshr_S, typeof(AOpCodeSimdShImm));
|
||||
Set("0x0011110>>>>xxx000001xxxxxxxxxx", AInstEmit.Sshr_V, typeof(AOpCodeSimdShImm));
|
||||
|
@ -231,9 +234,7 @@ namespace ChocolArm64
|
|||
Set("xx111101x0xxxxxxxxxxxxxxxxxxxxxx", AInstEmit.Str, typeof(AOpCodeSimdMemImm));
|
||||
Set("xx111100x01xxxxxxxxx10xxxxxxxxxx", AInstEmit.Str, typeof(AOpCodeSimdMemReg));
|
||||
Set("01111110xx1xxxxx100001xxxxxxxxxx", AInstEmit.Sub_S, typeof(AOpCodeSimdReg));
|
||||
Set("0x101110xx1xxxxx100001xxxxxxxxxx", AInstEmit.Sub_V, typeof(AOpCodeSimdReg));
|
||||
Set("x0011110xx100010000000xxxxxxxxxx", AInstEmit.Scvtf_Gp, typeof(AOpCodeSimdCvt));
|
||||
Set("010111100x100001110110xxxxxxxxxx", AInstEmit.Scvtf_S, typeof(AOpCodeSimd));
|
||||
Set("0>101110<<1xxxxx100001xxxxxxxxxx", AInstEmit.Sub_V, typeof(AOpCodeSimdReg));
|
||||
Set("0x001110000xxxxx0xx000xxxxxxxxxx", AInstEmit.Tbl_V, typeof(AOpCodeSimdTbl));
|
||||
Set("001011100x110000001110xxxxxxxxxx", AInstEmit.Uaddlv_V, typeof(AOpCodeSimd));
|
||||
Set("01101110<<110000001110xxxxxxxxxx", AInstEmit.Uaddlv_V, typeof(AOpCodeSimd));
|
||||
|
@ -241,7 +242,7 @@ namespace ChocolArm64
|
|||
Set("x0011110xx100011000000xxxxxxxxxx", AInstEmit.Ucvtf_Gp, typeof(AOpCodeSimdCvt));
|
||||
Set("011111100x100001110110xxxxxxxxxx", AInstEmit.Ucvtf_V, typeof(AOpCodeSimdReg));
|
||||
Set("0x001110000xxxxx001111xxxxxxxxxx", AInstEmit.Umov_S, typeof(AOpCodeSimdIns));
|
||||
Set("0x101110xx1xxxxx010001xxxxxxxxxx", AInstEmit.Ushl_V, typeof(AOpCodeSimdReg));
|
||||
Set("0>101110<<1xxxxx010001xxxxxxxxxx", AInstEmit.Ushl_V, typeof(AOpCodeSimdReg));
|
||||
Set("0x10111100>>>xxx101001xxxxxxxxxx", AInstEmit.Ushll_V, typeof(AOpCodeSimdShImm));
|
||||
Set("0x1011110>>>>xxx000001xxxxxxxxxx", AInstEmit.Ushr_V, typeof(AOpCodeSimdShImm));
|
||||
Set("0x1011110>>>>xxx000101xxxxxxxxxx", AInstEmit.Usra_V, typeof(AOpCodeSimdShImm));
|
||||
|
@ -311,9 +312,13 @@ namespace ChocolArm64
|
|||
{
|
||||
InsertTop(XMask, Value, Inst);
|
||||
}
|
||||
else if ((ZCount & OCount) != 0)
|
||||
else if (ZCount != 0 && OCount != 0)
|
||||
{
|
||||
for (int OCtr = 0; (uint)OCtr < (1 << OCount) - 1; OCtr++)
|
||||
//When both the > and the <, then a value is blacklisted,
|
||||
//with > indicating 0, and < indicating 1. So, for example, ><<
|
||||
//blacklists the pattern 011, but 000, 001, 010, 100, 101,
|
||||
//110 and 111 are valid.
|
||||
for (int OCtr = 0; (uint)OCtr < (1 << OCount); OCtr++)
|
||||
{
|
||||
int OVal = Value;
|
||||
|
||||
|
@ -322,7 +327,9 @@ namespace ChocolArm64
|
|||
OVal |= ((OCtr >> O) & 1) << OPos[O];
|
||||
}
|
||||
|
||||
InsertWithCtr(1, 1 << ZCount, ZCount, ZPos, XMask, OVal, Inst);
|
||||
int ZStart = OCtr == (1 << OCount) ? 1 : 0;
|
||||
|
||||
InsertWithCtr(ZStart, 1 << ZCount, ZCount, ZPos, XMask, OVal, Inst);
|
||||
}
|
||||
}
|
||||
else if (ZCount != 0)
|
||||
|
|
|
@ -15,8 +15,6 @@ namespace ChocolArm64.Decoder
|
|||
|
||||
int Shift = (OpCode >> 22) & 3;
|
||||
|
||||
//Assert Shift < 2
|
||||
|
||||
Imm <<= Shift * 12;
|
||||
}
|
||||
else if (DataOp == ADataOp.Logical)
|
||||
|
|
|
@ -11,11 +11,19 @@ namespace ChocolArm64.Decoder
|
|||
|
||||
public AOpCodeAluRs(AInst Inst, long Position, int OpCode) : base(Inst, Position, OpCode)
|
||||
{
|
||||
Shift = (OpCode >> 10) & 0x3f;
|
||||
int Shift = (OpCode >> 10) & 0x3f;
|
||||
|
||||
if (Shift >= GetBitsCount())
|
||||
{
|
||||
Emitter = AInstEmit.Und;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
this.Shift = Shift;
|
||||
|
||||
Rm = (OpCode >> 16) & 0x1f;
|
||||
ShiftType = (AShiftType)((OpCode >> 22) & 0x3);
|
||||
|
||||
//Assert ShiftType != 3
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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)
|
||||
{
|
||||
|
@ -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 enum ShrFlags
|
||||
{
|
||||
None = 0,
|
||||
Signed = 1 << 0,
|
||||
Rounding = 1 << 1,
|
||||
Accumulate = 1 << 2
|
||||
}
|
||||
|
||||
private static void EmitVectorShr(AILEmitterCtx Context, ShrFlags Flags)
|
||||
{
|
||||
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 EmitVectorFcvtS(AILEmitterCtx Context)
|
||||
{
|
||||
EmitVectorCvtOp(Context, CvtDir.Fcvt, true);
|
||||
}
|
||||
|
||||
private static void EmitVectorFcvtU(AILEmitterCtx Context)
|
||||
private static void EmitVectorFcvts(AILEmitterCtx Context)
|
||||
{
|
||||
EmitVectorCvtOp(Context, CvtDir.Fcvt, false);
|
||||
EmitVectorFcvtOp(Context, Signed: true);
|
||||
}
|
||||
|
||||
private static void EmitVectorCvtfS(AILEmitterCtx Context)
|
||||
private static void EmitVectorFcvtu(AILEmitterCtx Context)
|
||||
{
|
||||
EmitVectorCvtOp(Context, CvtDir.Cvtf, true);
|
||||
EmitVectorFcvtOp(Context, Signed: false);
|
||||
}
|
||||
|
||||
private static void EmitVectorCvtfU(AILEmitterCtx Context)
|
||||
private static void EmitVectorScvtf(AILEmitterCtx Context)
|
||||
{
|
||||
EmitVectorCvtOp(Context, CvtDir.Cvtf, false);
|
||||
EmitVectorCvtfOp(Context, Signed: true);
|
||||
}
|
||||
|
||||
private enum CvtDir
|
||||
private static void EmitVectorUcvtf(AILEmitterCtx Context)
|
||||
{
|
||||
Fcvt,
|
||||
Cvtf
|
||||
EmitVectorCvtfOp(Context, Signed: false);
|
||||
}
|
||||
|
||||
private static void EmitVectorCvtOp(AILEmitterCtx Context, CvtDir Dir, bool Signed)
|
||||
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,9 +824,6 @@ namespace ChocolArm64.Instruction
|
|||
|
||||
Context.EmitLdc_I4(FBits);
|
||||
|
||||
if (Dir == CvtDir.Fcvt)
|
||||
{
|
||||
//Float to Integer.
|
||||
if (SizeF == 0)
|
||||
{
|
||||
ASoftFallback.EmitCall(Context, Signed
|
||||
|
@ -837,12 +836,6 @@ namespace ChocolArm64.Instruction
|
|||
? nameof(ASoftFallback.SatDoubleToInt64)
|
||||
: nameof(ASoftFallback.SatDoubleToUInt64));
|
||||
}
|
||||
}
|
||||
else if (Dir == CvtDir.Cvtf)
|
||||
{
|
||||
//Integer to Float.
|
||||
//TODO.
|
||||
}
|
||||
|
||||
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);
|
||||
|
|
|
@ -10,9 +10,6 @@ namespace ChocolArm64.State
|
|||
internal const int ErgSizeLog2 = 4;
|
||||
internal const int DczSizeLog2 = 4;
|
||||
|
||||
private const long TicksPerS = 19_200_000;
|
||||
private const long TicksPerMS = TicksPerS / 1_000;
|
||||
|
||||
public ulong X0, X1, X2, X3, X4, X5, X6, X7,
|
||||
X8, X9, X10, X11, X12, X13, X14, X15,
|
||||
X16, X17, X18, X19, X20, X21, X22, X23,
|
||||
|
@ -40,23 +37,26 @@ namespace ChocolArm64.State
|
|||
public uint CtrEl0 => 0x8444c004;
|
||||
public uint DczidEl0 => 0x00000004;
|
||||
|
||||
private const long TicksPerS = 19_200_000;
|
||||
private const long TicksPerMS = TicksPerS / 1_000;
|
||||
|
||||
public long CntpctEl0 => Environment.TickCount * TicksPerMS;
|
||||
|
||||
public event EventHandler<AInstExceptEventArgs> Break;
|
||||
public event EventHandler<AInstExceptEventArgs> SvcCall;
|
||||
public event EventHandler<AInstUndEventArgs> Undefined;
|
||||
|
||||
public void OnBreak(int Imm)
|
||||
internal void OnBreak(int Imm)
|
||||
{
|
||||
Break?.Invoke(this, new AInstExceptEventArgs(Imm));
|
||||
}
|
||||
|
||||
public void OnSvcCall(int Imm)
|
||||
internal void OnSvcCall(int Imm)
|
||||
{
|
||||
SvcCall?.Invoke(this, new AInstExceptEventArgs(Imm));
|
||||
}
|
||||
|
||||
public void OnUndefined(long Position, int RawOpCode)
|
||||
internal void OnUndefined(long Position, int RawOpCode)
|
||||
{
|
||||
Undefined?.Invoke(this, new AInstUndEventArgs(Position, RawOpCode));
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue