Generate CIL for SCVTF (vector), add undefined encodings for some instructions

This commit is contained in:
gdkchan 2018-02-12 00:37:20 -03:00
parent 9e8d99f30d
commit 7d11a146c0
7 changed files with 340 additions and 285 deletions

View file

@ -11,11 +11,11 @@ namespace ChocolArm64
#region "OpCode Table" #region "OpCode Table"
//Integer //Integer
Set("x0011010000xxxxx000000xxxxxxxxxx", AInstEmit.Adc, typeof(AOpCodeAluRs)); Set("x0011010000xxxxx000000xxxxxxxxxx", AInstEmit.Adc, typeof(AOpCodeAluRs));
Set("x0010001xxxxxxxxxxxxxxxxxxxxxxxx", AInstEmit.Add, typeof(AOpCodeAluImm)); Set("x00100010xxxxxxxxxxxxxxxxxxxxxxx", AInstEmit.Add, typeof(AOpCodeAluImm));
Set("x0001011xx0xxxxxxxxxxxxxxxxxxxxx", AInstEmit.Add, typeof(AOpCodeAluRs)); Set("x0001011<<0xxxxxxxxxxxxxxxxxxxxx", AInstEmit.Add, typeof(AOpCodeAluRs));
Set("x0001011001xxxxxxxxxxxxxxxxxxxxx", AInstEmit.Add, typeof(AOpCodeAluRx)); Set("x0001011001xxxxxxxxxxxxxxxxxxxxx", AInstEmit.Add, typeof(AOpCodeAluRx));
Set("x0110001xxxxxxxxxxxxxxxxxxxxxxxx", AInstEmit.Adds, typeof(AOpCodeAluImm)); Set("x01100010xxxxxxxxxxxxxxxxxxxxxxx", AInstEmit.Adds, typeof(AOpCodeAluImm));
Set("x0101011xx0xxxxxxxxxxxxxxxxxxxxx", AInstEmit.Adds, typeof(AOpCodeAluRs)); Set("x0101011<<0xxxxxxxxxxxxxxxxxxxxx", AInstEmit.Adds, typeof(AOpCodeAluRs));
Set("x0101011001xxxxxxxxxxxxxxxxxxxxx", AInstEmit.Adds, typeof(AOpCodeAluRx)); Set("x0101011001xxxxxxxxxxxxxxxxxxxxx", AInstEmit.Adds, typeof(AOpCodeAluRx));
Set("0xx10000xxxxxxxxxxxxxxxxxxxxxxxx", AInstEmit.Adr, typeof(AOpCodeAdr)); Set("0xx10000xxxxxxxxxxxxxxxxxxxxxxxx", AInstEmit.Adr, typeof(AOpCodeAdr));
Set("1xx10000xxxxxxxxxxxxxxxxxxxxxxxx", AInstEmit.Adrp, typeof(AOpCodeAdr)); Set("1xx10000xxxxxxxxxxxxxxxxxxxxxxxx", AInstEmit.Adrp, typeof(AOpCodeAdr));
@ -102,11 +102,11 @@ namespace ChocolArm64
Set("xx111000001xxxxxxxxx10xxxxxxxxxx", AInstEmit.Str, typeof(AOpCodeMemReg)); Set("xx111000001xxxxxxxxx10xxxxxxxxxx", AInstEmit.Str, typeof(AOpCodeMemReg));
Set("1x001000001xxxxx0xxxxxxxxxxxxxxx", AInstEmit.Stxp, typeof(AOpCodeMemEx)); Set("1x001000001xxxxx0xxxxxxxxxxxxxxx", AInstEmit.Stxp, typeof(AOpCodeMemEx));
Set("xx001000000xxxxx0xxxxxxxxxxxxxxx", AInstEmit.Stxr, typeof(AOpCodeMemEx)); Set("xx001000000xxxxx0xxxxxxxxxxxxxxx", AInstEmit.Stxr, typeof(AOpCodeMemEx));
Set("x1010001xxxxxxxxxxxxxxxxxxxxxxxx", AInstEmit.Sub, typeof(AOpCodeAluImm)); Set("x10100010xxxxxxxxxxxxxxxxxxxxxxx", AInstEmit.Sub, typeof(AOpCodeAluImm));
Set("x1001011xx0xxxxxxxxxxxxxxxxxxxxx", AInstEmit.Sub, typeof(AOpCodeAluRs)); Set("x1001011<<0xxxxxxxxxxxxxxxxxxxxx", AInstEmit.Sub, typeof(AOpCodeAluRs));
Set("x1001011001xxxxxxxxxxxxxxxxxxxxx", AInstEmit.Sub, typeof(AOpCodeAluRx)); Set("x1001011001xxxxxxxxxxxxxxxxxxxxx", AInstEmit.Sub, typeof(AOpCodeAluRx));
Set("x1110001xxxxxxxxxxxxxxxxxxxxxxxx", AInstEmit.Subs, typeof(AOpCodeAluImm)); Set("x11100010xxxxxxxxxxxxxxxxxxxxxxx", AInstEmit.Subs, typeof(AOpCodeAluImm));
Set("x1101011xx0xxxxxxxxxxxxxxxxxxxxx", AInstEmit.Subs, typeof(AOpCodeAluRs)); Set("x1101011<<0xxxxxxxxxxxxxxxxxxxxx", AInstEmit.Subs, typeof(AOpCodeAluRs));
Set("x1101011001xxxxxxxxxxxxxxxxxxxxx", AInstEmit.Subs, typeof(AOpCodeAluRx)); Set("x1101011001xxxxxxxxxxxxxxxxxxxxx", AInstEmit.Subs, typeof(AOpCodeAluRx));
Set("11010100000xxxxxxxxxxxxxxxx00001", AInstEmit.Svc, typeof(AOpCodeException)); Set("11010100000xxxxxxxxxxxxxxxx00001", AInstEmit.Svc, typeof(AOpCodeException));
Set("1101010100001xxxxxxxxxxxxxxxxxxx", AInstEmit.Sys, typeof(AOpCodeSystem)); Set("1101010100001xxxxxxxxxxxxxxxxxxx", AInstEmit.Sys, typeof(AOpCodeSystem));
@ -119,24 +119,25 @@ namespace ChocolArm64
Set("10011011110xxxxx0xxxxxxxxxxxxxxx", AInstEmit.Umulh, typeof(AOpCodeMul)); Set("10011011110xxxxx0xxxxxxxxxxxxxxx", AInstEmit.Umulh, typeof(AOpCodeMul));
//Vector //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("01011110xx110001101110xxxxxxxxxx", AInstEmit.Addp_S, typeof(AOpCodeSimd));
Set("0x001110xx1xxxxx101111xxxxxxxxxx", AInstEmit.Addp_V, typeof(AOpCodeSimdReg)); Set("0>001110<<1xxxxx101111xxxxxxxxxx", AInstEmit.Addp_V, typeof(AOpCodeSimdReg));
Set("0x001110<<110001101110xxxxxxxxxx", AInstEmit.Addv_V, typeof(AOpCodeSimd)); Set("000011100x110001101110xxxxxxxxxx", AInstEmit.Addv_V, typeof(AOpCodeSimd));
Set("01001110<<110001101110xxxxxxxxxx", AInstEmit.Addv_V, typeof(AOpCodeSimd));
Set("0x001110001xxxxx000111xxxxxxxxxx", AInstEmit.And_V, typeof(AOpCodeSimdReg)); Set("0x001110001xxxxx000111xxxxxxxxxx", AInstEmit.And_V, typeof(AOpCodeSimdReg));
Set("0x001110011xxxxx000111xxxxxxxxxx", AInstEmit.Bic_V, typeof(AOpCodeSimdReg)); Set("0x001110011xxxxx000111xxxxxxxxxx", AInstEmit.Bic_V, typeof(AOpCodeSimdReg));
Set("0x10111100000xxx<<x101xxxxxxxxxx", AInstEmit.Bic_Vi, typeof(AOpCodeSimdImm)); Set("0x10111100000xxx<<x101xxxxxxxxxx", AInstEmit.Bic_Vi, typeof(AOpCodeSimdImm));
Set("0x101110011xxxxx000111xxxxxxxxxx", AInstEmit.Bsl_V, typeof(AOpCodeSimdReg)); Set("0x101110011xxxxx000111xxxxxxxxxx", AInstEmit.Bsl_V, typeof(AOpCodeSimdReg));
Set("0x101110xx1xxxxx100011xxxxxxxxxx", AInstEmit.Cmeq_V, typeof(AOpCodeSimdReg)); Set("0>101110<<1xxxxx100011xxxxxxxxxx", AInstEmit.Cmeq_V, typeof(AOpCodeSimdReg));
Set("0x001110xx100000100110xxxxxxxxxx", AInstEmit.Cmeq_V, typeof(AOpCodeSimd)); Set("0>001110<<100000100110xxxxxxxxxx", AInstEmit.Cmeq_V, typeof(AOpCodeSimd));
Set("0x001110xx1xxxxx001111xxxxxxxxxx", AInstEmit.Cmge_V, typeof(AOpCodeSimdReg)); Set("0>001110<<1xxxxx001111xxxxxxxxxx", AInstEmit.Cmge_V, typeof(AOpCodeSimdReg));
Set("0x101110xx100000100010xxxxxxxxxx", AInstEmit.Cmge_V, typeof(AOpCodeSimd)); Set("0>101110<<100000100010xxxxxxxxxx", AInstEmit.Cmge_V, typeof(AOpCodeSimd));
Set("0x001110xx1xxxxx001101xxxxxxxxxx", AInstEmit.Cmgt_V, typeof(AOpCodeSimdReg)); Set("0>001110<<1xxxxx001101xxxxxxxxxx", AInstEmit.Cmgt_V, typeof(AOpCodeSimdReg));
Set("0x001110xx100000100010xxxxxxxxxx", AInstEmit.Cmgt_V, typeof(AOpCodeSimd)); Set("0>001110<<100000100010xxxxxxxxxx", AInstEmit.Cmgt_V, typeof(AOpCodeSimd));
Set("0x101110xx1xxxxx001101xxxxxxxxxx", AInstEmit.Cmhi_V, typeof(AOpCodeSimdReg)); Set("0>101110<<1xxxxx001101xxxxxxxxxx", AInstEmit.Cmhi_V, typeof(AOpCodeSimdReg));
Set("0x101110xx1xxxxx001111xxxxxxxxxx", AInstEmit.Cmhs_V, typeof(AOpCodeSimdReg)); Set("0>101110<<1xxxxx001111xxxxxxxxxx", AInstEmit.Cmhs_V, typeof(AOpCodeSimdReg));
Set("0x101110xx100000100110xxxxxxxxxx", AInstEmit.Cmle_V, typeof(AOpCodeSimd)); Set("0>101110<<100000100110xxxxxxxxxx", AInstEmit.Cmle_V, typeof(AOpCodeSimd));
Set("0x001110xx100000101010xxxxxxxxxx", AInstEmit.Cmlt_V, typeof(AOpCodeSimd)); Set("0>001110<<100000101010xxxxxxxxxx", AInstEmit.Cmlt_V, typeof(AOpCodeSimd));
Set("0x00111000100000010110xxxxxxxxxx", AInstEmit.Cnt_V, typeof(AOpCodeSimd)); Set("0x00111000100000010110xxxxxxxxxx", AInstEmit.Cnt_V, typeof(AOpCodeSimd));
Set("01011110000xxxxx000001xxxxxxxxxx", AInstEmit.Dup_S, typeof(AOpCodeSimdIns)); Set("01011110000xxxxx000001xxxxxxxxxx", AInstEmit.Dup_S, typeof(AOpCodeSimdIns));
Set("0x001110000xxxxx000011xxxxxxxxxx", AInstEmit.Dup_Gp, typeof(AOpCodeSimdIns)); Set("0x001110000xxxxx000011xxxxxxxxxx", AInstEmit.Dup_Gp, typeof(AOpCodeSimdIns));
@ -199,26 +200,28 @@ namespace ChocolArm64
Set("xx111101x1xxxxxxxxxxxxxxxxxxxxxx", AInstEmit.Ldr, typeof(AOpCodeSimdMemImm)); Set("xx111101x1xxxxxxxxxxxxxxxxxxxxxx", AInstEmit.Ldr, typeof(AOpCodeSimdMemImm));
Set("xx111100x11xxxxxxxxx10xxxxxxxxxx", AInstEmit.Ldr, typeof(AOpCodeSimdMemReg)); Set("xx111100x11xxxxxxxxx10xxxxxxxxxx", AInstEmit.Ldr, typeof(AOpCodeSimdMemReg));
Set("xx011100xxxxxxxxxxxxxxxxxxxxxxxx", AInstEmit.LdrLit, typeof(AOpCodeSimdMemLit)); 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("0x00111100000xxx0xx001xxxxxxxxxx", AInstEmit.Movi_V, typeof(AOpCodeSimdImm));
Set("0x00111100000xxx10x001xxxxxxxxxx", AInstEmit.Movi_V, typeof(AOpCodeSimdImm)); Set("0x00111100000xxx10x001xxxxxxxxxx", AInstEmit.Movi_V, typeof(AOpCodeSimdImm));
Set("0x00111100000xxx110x01xxxxxxxxxx", AInstEmit.Movi_V, typeof(AOpCodeSimdImm)); Set("0x00111100000xxx110x01xxxxxxxxxx", AInstEmit.Movi_V, typeof(AOpCodeSimdImm));
Set("0xx0111100000xxx111001xxxxxxxxxx", 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("0x10111100000xxx0xx001xxxxxxxxxx", AInstEmit.Mvni_V, typeof(AOpCodeSimdImm));
Set("0x10111100000xxx10x001xxxxxxxxxx", AInstEmit.Mvni_V, typeof(AOpCodeSimdImm)); Set("0x10111100000xxx10x001xxxxxxxxxx", AInstEmit.Mvni_V, typeof(AOpCodeSimdImm));
Set("0x10111100000xxx110x01xxxxxxxxxx", 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("0x10111000100000010110xxxxxxxxxx", AInstEmit.Not_V, typeof(AOpCodeSimd));
Set("0x001110101xxxxx000111xxxxxxxxxx", AInstEmit.Orr_V, typeof(AOpCodeSimdReg)); Set("0x001110101xxxxx000111xxxxxxxxxx", AInstEmit.Orr_V, typeof(AOpCodeSimdReg));
Set("0x00111100000xxx<<x101xxxxxxxxxx", AInstEmit.Orr_Vi, typeof(AOpCodeSimdImm)); Set("0x00111100000xxx<<x101xxxxxxxxxx", AInstEmit.Orr_Vi, typeof(AOpCodeSimdImm));
Set("0x001110<<1xxxxx000100xxxxxxxxxx", AInstEmit.Saddw_V, typeof(AOpCodeSimdReg)); 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("0x0011100x100001110110xxxxxxxxxx", AInstEmit.Scvtf_V, typeof(AOpCodeSimd));
Set("010111110>>>>xxx010101xxxxxxxxxx", AInstEmit.Shl_S, typeof(AOpCodeSimdShImm)); Set("010111110>>>>xxx010101xxxxxxxxxx", AInstEmit.Shl_S, typeof(AOpCodeSimdShImm));
Set("0x0011110>>>>xxx010101xxxxxxxxxx", AInstEmit.Shl_V, typeof(AOpCodeSimdShImm)); Set("0x0011110>>>>xxx010101xxxxxxxxxx", AInstEmit.Shl_V, typeof(AOpCodeSimdShImm));
Set("0x001110<<1xxxxx011001xxxxxxxxxx", AInstEmit.Smax_V, typeof(AOpCodeSimdReg)); Set("0x001110<<1xxxxx011001xxxxxxxxxx", AInstEmit.Smax_V, typeof(AOpCodeSimdReg));
Set("0x001110<<1xxxxx011011xxxxxxxxxx", AInstEmit.Smin_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("0x00111100>>>xxx101001xxxxxxxxxx", AInstEmit.Sshll_V, typeof(AOpCodeSimdShImm));
Set("010111110>>>>xxx000001xxxxxxxxxx", AInstEmit.Sshr_S, typeof(AOpCodeSimdShImm)); Set("010111110>>>>xxx000001xxxxxxxxxx", AInstEmit.Sshr_S, typeof(AOpCodeSimdShImm));
Set("0x0011110>>>>xxx000001xxxxxxxxxx", AInstEmit.Sshr_V, typeof(AOpCodeSimdShImm)); Set("0x0011110>>>>xxx000001xxxxxxxxxx", AInstEmit.Sshr_V, typeof(AOpCodeSimdShImm));
@ -231,9 +234,7 @@ namespace ChocolArm64
Set("xx111101x0xxxxxxxxxxxxxxxxxxxxxx", AInstEmit.Str, typeof(AOpCodeSimdMemImm)); Set("xx111101x0xxxxxxxxxxxxxxxxxxxxxx", AInstEmit.Str, typeof(AOpCodeSimdMemImm));
Set("xx111100x01xxxxxxxxx10xxxxxxxxxx", AInstEmit.Str, typeof(AOpCodeSimdMemReg)); Set("xx111100x01xxxxxxxxx10xxxxxxxxxx", AInstEmit.Str, typeof(AOpCodeSimdMemReg));
Set("01111110xx1xxxxx100001xxxxxxxxxx", AInstEmit.Sub_S, typeof(AOpCodeSimdReg)); Set("01111110xx1xxxxx100001xxxxxxxxxx", AInstEmit.Sub_S, typeof(AOpCodeSimdReg));
Set("0x101110xx1xxxxx100001xxxxxxxxxx", AInstEmit.Sub_V, typeof(AOpCodeSimdReg)); Set("0>101110<<1xxxxx100001xxxxxxxxxx", AInstEmit.Sub_V, typeof(AOpCodeSimdReg));
Set("x0011110xx100010000000xxxxxxxxxx", AInstEmit.Scvtf_Gp, typeof(AOpCodeSimdCvt));
Set("010111100x100001110110xxxxxxxxxx", AInstEmit.Scvtf_S, typeof(AOpCodeSimd));
Set("0x001110000xxxxx0xx000xxxxxxxxxx", AInstEmit.Tbl_V, typeof(AOpCodeSimdTbl)); Set("0x001110000xxxxx0xx000xxxxxxxxxx", AInstEmit.Tbl_V, typeof(AOpCodeSimdTbl));
Set("001011100x110000001110xxxxxxxxxx", AInstEmit.Uaddlv_V, typeof(AOpCodeSimd)); Set("001011100x110000001110xxxxxxxxxx", AInstEmit.Uaddlv_V, typeof(AOpCodeSimd));
Set("01101110<<110000001110xxxxxxxxxx", 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("x0011110xx100011000000xxxxxxxxxx", AInstEmit.Ucvtf_Gp, typeof(AOpCodeSimdCvt));
Set("011111100x100001110110xxxxxxxxxx", AInstEmit.Ucvtf_V, typeof(AOpCodeSimdReg)); Set("011111100x100001110110xxxxxxxxxx", AInstEmit.Ucvtf_V, typeof(AOpCodeSimdReg));
Set("0x001110000xxxxx001111xxxxxxxxxx", AInstEmit.Umov_S, typeof(AOpCodeSimdIns)); 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("0x10111100>>>xxx101001xxxxxxxxxx", AInstEmit.Ushll_V, typeof(AOpCodeSimdShImm));
Set("0x1011110>>>>xxx000001xxxxxxxxxx", AInstEmit.Ushr_V, typeof(AOpCodeSimdShImm)); Set("0x1011110>>>>xxx000001xxxxxxxxxx", AInstEmit.Ushr_V, typeof(AOpCodeSimdShImm));
Set("0x1011110>>>>xxx000101xxxxxxxxxx", AInstEmit.Usra_V, typeof(AOpCodeSimdShImm)); Set("0x1011110>>>>xxx000101xxxxxxxxxx", AInstEmit.Usra_V, typeof(AOpCodeSimdShImm));
@ -311,9 +312,13 @@ namespace ChocolArm64
{ {
InsertTop(XMask, Value, Inst); 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; int OVal = Value;
@ -322,7 +327,9 @@ namespace ChocolArm64
OVal |= ((OCtr >> O) & 1) << OPos[O]; 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) else if (ZCount != 0)

View file

@ -15,8 +15,6 @@ namespace ChocolArm64.Decoder
int Shift = (OpCode >> 22) & 3; int Shift = (OpCode >> 22) & 3;
//Assert Shift < 2
Imm <<= Shift * 12; Imm <<= Shift * 12;
} }
else if (DataOp == ADataOp.Logical) else if (DataOp == ADataOp.Logical)

View file

@ -11,11 +11,19 @@ namespace ChocolArm64.Decoder
public AOpCodeAluRs(AInst Inst, long Position, int OpCode) : base(Inst, Position, OpCode) 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; Rm = (OpCode >> 16) & 0x1f;
ShiftType = (AShiftType)((OpCode >> 22) & 0x3); ShiftType = (AShiftType)((OpCode >> 22) & 0x3);
//Assert ShiftType != 3
} }
} }
} }

View file

@ -1,12 +1,14 @@
using ChocolArm64.Decoder; using ChocolArm64.Decoder;
using ChocolArm64.State; using ChocolArm64.State;
using ChocolArm64.Translation; using ChocolArm64.Translation;
using System; using System.Reflection;
namespace ChocolArm64.Instruction namespace ChocolArm64.Instruction
{ {
static partial class AInstEmit static partial class AInstEmit
{ {
private const BindingFlags Binding = BindingFlags.NonPublic | BindingFlags.Instance;
public static void Brk(AILEmitterCtx Context) public static void Brk(AILEmitterCtx Context)
{ {
EmitExceptionCall(Context, nameof(ARegisters.OnBreak)); EmitExceptionCall(Context, nameof(ARegisters.OnBreak));
@ -27,7 +29,9 @@ namespace ChocolArm64.Instruction
Context.EmitLdc_I4(Op.Id); 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) if (Context.CurrBlock.Next != null)
{ {
@ -46,7 +50,11 @@ namespace ChocolArm64.Instruction
Context.EmitLdc_I8(Op.Position); Context.EmitLdc_I8(Op.Position);
Context.EmitLdc_I4(Op.RawOpCode); 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) if (Context.CurrBlock.Next != null)
{ {

View file

@ -104,8 +104,8 @@ namespace ChocolArm64.Instruction
public static void Fadd_V(AILEmitterCtx Context) => EmitVectorBinaryFOp(Context, OpCodes.Add); public static void Fadd_V(AILEmitterCtx Context) => EmitVectorBinaryFOp(Context, OpCodes.Add);
public static void Fcvtzs_V(AILEmitterCtx Context) => EmitVectorFcvtS(Context); public static void Fcvtzs_V(AILEmitterCtx Context) => EmitVectorFcvts(Context);
public static void Fcvtzu_V(AILEmitterCtx Context) => EmitVectorFcvtU(Context); public static void Fcvtzu_V(AILEmitterCtx Context) => EmitVectorFcvtu(Context);
public static void Fmla_V(AILEmitterCtx Context) public static void Fmla_V(AILEmitterCtx Context)
{ {
@ -264,19 +264,7 @@ namespace ChocolArm64.Instruction
Context.EmitStvec(Op.Rd); Context.EmitStvec(Op.Rd);
} }
public static void Scvtf_V(AILEmitterCtx Context) public static void Scvtf_V(AILEmitterCtx Context) => EmitVectorScvtf(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 Shl_V(AILEmitterCtx Context) public static void Shl_V(AILEmitterCtx Context)
{ {
@ -434,33 +422,12 @@ namespace ChocolArm64.Instruction
public static void Ushr_V(AILEmitterCtx Context) public static void Ushr_V(AILEmitterCtx Context)
{ {
AOpCodeSimdShImm Op = (AOpCodeSimdShImm)Context.CurrOp; EmitVectorShr(Context, ShrFlags.None);
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);
} }
public static void Usra_V(AILEmitterCtx Context) public static void Usra_V(AILEmitterCtx Context)
{ {
AOpCodeSimdShImm Op = (AOpCodeSimdShImm)Context.CurrOp; EmitVectorShr(Context, ShrFlags.Accumulate);
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);
} }
public static void Uzp1_V(AILEmitterCtx Context) public static void Uzp1_V(AILEmitterCtx Context)
@ -651,11 +618,11 @@ namespace ChocolArm64.Instruction
Context.EmitLdc_I4(0); Context.EmitLdc_I4(0);
Context.EmitLdc_I4(Op.Size); 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++) 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); Context.Emit(OpCodes.Add);
} }
@ -730,7 +697,7 @@ namespace ChocolArm64.Instruction
int MaxShift = 8 << Op.Size; int MaxShift = 8 << Op.Size;
EmitVectorBinaryZx(Context, () => Action Emit = () =>
{ {
AILLabel LblShl = new AILLabel(); AILLabel LblShl = new AILLabel();
AILLabel LblZero = new AILLabel(); AILLabel LblZero = new AILLabel();
@ -771,48 +738,83 @@ namespace ChocolArm64.Instruction
Context.EmitLdc_I8(0); Context.EmitLdc_I8(0);
Context.MarkLabel(LblEnd); 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, EmitVectorCvtfOp(Context, Signed: true);
Cvtf
} }
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; AOpCodeSimd Op = (AOpCodeSimd)Context.CurrOp;
int SizeF = Op.Size & 1; int SizeF = Op.Size & 1;
int SizeI = SizeF + 2; int SizeI = SizeF + 2;
int FBits = 0; int FBits = GetFBits(Context);
if (Op is AOpCodeSimdShImm OpImm)
{
FBits = (8 << (Op.Size + 1)) - OpImm.Imm;
}
int Bytes = Context.CurrOp.GetBitsCount() >> 3; int Bytes = Context.CurrOp.GetBitsCount() >> 3;
@ -822,26 +824,17 @@ namespace ChocolArm64.Instruction
Context.EmitLdc_I4(FBits); Context.EmitLdc_I4(FBits);
if (Dir == CvtDir.Fcvt) if (SizeF == 0)
{ {
//Float to Integer. ASoftFallback.EmitCall(Context, Signed
if (SizeF == 0) ? nameof(ASoftFallback.SatSingleToInt32)
{ : nameof(ASoftFallback.SatSingleToUInt32));
ASoftFallback.EmitCall(Context, Signed
? nameof(ASoftFallback.SatSingleToInt32)
: nameof(ASoftFallback.SatSingleToUInt32));
}
else if (SizeF == 1)
{
ASoftFallback.EmitCall(Context, Signed
? nameof(ASoftFallback.SatDoubleToInt64)
: nameof(ASoftFallback.SatDoubleToUInt64));
}
} }
else if (Dir == CvtDir.Cvtf) else if (SizeF == 1)
{ {
//Integer to Float. ASoftFallback.EmitCall(Context, Signed
//TODO. ? nameof(ASoftFallback.SatDoubleToInt64)
: nameof(ASoftFallback.SatDoubleToUInt64));
} }
EmitVectorInsert(Context, Op.Rd, Index, SizeI); 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) private static void EmitVectorBinaryFOp(AILEmitterCtx Context, OpCode ILOp)
{ {
EmitVectorBinaryFOp(Context, () => Context.Emit(ILOp)); EmitVectorBinaryFOp(Context, () => Context.Emit(ILOp));
@ -899,36 +943,43 @@ namespace ChocolArm64.Instruction
private static void EmitVectorUnarySx(AILEmitterCtx Context, Action Emit) 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) 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) 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) 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) 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) Rd = 1 << 0,
{ Rn = 1 << 1,
throw new ArgumentOutOfRangeException(nameof(Opers)); 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; AOpCodeSimd Op = (AOpCodeSimd)Context.CurrOp;
int Bytes = Context.CurrOp.GetBitsCount() >> 3; int Bytes = Context.CurrOp.GetBitsCount() >> 3;
@ -939,19 +990,19 @@ namespace ChocolArm64.Instruction
Context.EmitLdc_I4(Index); Context.EmitLdc_I4(Index);
Context.EmitLdc_I4(Op.Size); 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(); Emit();
@ -999,7 +1050,7 @@ namespace ChocolArm64.Instruction
Context.EmitLdc_I4(Index); Context.EmitLdc_I4(Index);
Context.EmitLdc_I4(Op.Size); Context.EmitLdc_I4(Op.Size);
EmitVectorExtract(Context, Op.Rn, Index, Signed); EmitVectorExtract(Context, Op.Rn, Index, Op.Size, Signed);
Context.EmitLdc_I8(Imm); Context.EmitLdc_I8(Imm);
@ -1026,11 +1077,11 @@ namespace ChocolArm64.Instruction
for (int Index = 0; Index < (Bytes >> Op.Size); Index++) 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) if (Op is AOpCodeSimdReg BinOp)
{ {
EmitVectorExtractSx(Context, BinOp.Rm, Index); EmitVectorExtractSx(Context, BinOp.Rm, Index, Op.Size);
} }
else 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; IAOpCodeSimd Op = (IAOpCodeSimd)Context.CurrOp;
Context.EmitLdvec(Reg); Context.EmitLdvec(Reg);
Context.EmitLdc_I4(Index); Context.EmitLdc_I4(Index);
Context.EmitLdc_I4(Op.Size); Context.EmitLdc_I4(Size);
ASoftFallback.EmitCall(Context, Signed ASoftFallback.EmitCall(Context, Signed
? nameof(ASoftFallback.ExtractSVec) ? nameof(ASoftFallback.ExtractSVec)
: nameof(ASoftFallback.ExtractVec)); : 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) private static void EmitVectorInsertF(AILEmitterCtx Context, int Reg, int Index, int Size)
{ {
Context.EmitLdvec(Reg); Context.EmitLdvec(Reg);
@ -1122,16 +1183,6 @@ namespace ChocolArm64.Instruction
Context.EmitStvec(Reg); 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) private static void EmitVectorInsert(AILEmitterCtx Context, int Reg, int Index, int Size)
{ {
Context.EmitLdvec(Reg); Context.EmitLdvec(Reg);

View file

@ -97,39 +97,7 @@ namespace ChocolArm64.Instruction
throw new ArgumentException(nameof(Size)); throw new ArgumentException(nameof(Size));
} }
public static int SatDoubleToInt32(double Value, int FBits = 0) public static int SatSingleToInt32(float 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 = 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)
{ {
if (FBits != 0) Value *= MathF.Pow(2, FBits); if (FBits != 0) Value *= MathF.Pow(2, FBits);
@ -137,7 +105,7 @@ namespace ChocolArm64.Instruction
Value < int.MinValue ? int.MinValue : (int)Value; 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); if (FBits != 0) Value *= MathF.Pow(2, FBits);
@ -145,7 +113,7 @@ namespace ChocolArm64.Instruction
Value < long.MinValue ? long.MinValue : (long)Value; 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); if (FBits != 0) Value *= MathF.Pow(2, FBits);
@ -153,7 +121,7 @@ namespace ChocolArm64.Instruction
Value < uint.MinValue ? uint.MinValue : (uint)Value; 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); if (FBits != 0) Value *= MathF.Pow(2, FBits);
@ -161,6 +129,110 @@ namespace ChocolArm64.Instruction
Value < ulong.MinValue ? ulong.MinValue : (ulong)Value; 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) public static ulong SMulHi128(ulong LHS, ulong RHS)
{ {
long LLo = (uint)(LHS >> 0); long LLo = (uint)(LHS >> 0);
@ -556,44 +628,6 @@ namespace ChocolArm64.Instruction
return Res; 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) public static AVec Sshll(AVec Vector, int Shift, int Size)
{ {
return Sshll_(Vector, Shift, Size, false); return Sshll_(Vector, Shift, Size, false);
@ -785,57 +819,6 @@ namespace ChocolArm64.Instruction
return Res; 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) public static AVec Uzp1_V64(AVec LHS, AVec RHS, int Size)
{ {
return Uzp(LHS, RHS, Size, 0, 8); return Uzp(LHS, RHS, Size, 0, 8);

View file

@ -10,9 +10,6 @@ namespace ChocolArm64.State
internal const int ErgSizeLog2 = 4; internal const int ErgSizeLog2 = 4;
internal const int DczSizeLog2 = 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, public ulong X0, X1, X2, X3, X4, X5, X6, X7,
X8, X9, X10, X11, X12, X13, X14, X15, X8, X9, X10, X11, X12, X13, X14, X15,
X16, X17, X18, X19, X20, X21, X22, X23, X16, X17, X18, X19, X20, X21, X22, X23,
@ -40,23 +37,26 @@ namespace ChocolArm64.State
public uint CtrEl0 => 0x8444c004; public uint CtrEl0 => 0x8444c004;
public uint DczidEl0 => 0x00000004; 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 long CntpctEl0 => Environment.TickCount * TicksPerMS;
public event EventHandler<AInstExceptEventArgs> Break; public event EventHandler<AInstExceptEventArgs> Break;
public event EventHandler<AInstExceptEventArgs> SvcCall; public event EventHandler<AInstExceptEventArgs> SvcCall;
public event EventHandler<AInstUndEventArgs> Undefined; public event EventHandler<AInstUndEventArgs> Undefined;
public void OnBreak(int Imm) internal void OnBreak(int Imm)
{ {
Break?.Invoke(this, new AInstExceptEventArgs(Imm)); Break?.Invoke(this, new AInstExceptEventArgs(Imm));
} }
public void OnSvcCall(int Imm) internal void OnSvcCall(int Imm)
{ {
SvcCall?.Invoke(this, new AInstExceptEventArgs(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)); Undefined?.Invoke(this, new AInstUndEventArgs(Position, RawOpCode));
} }