forked from Mirror/Ryujinx
Add EXT, CMTST (vector) and UMULL (vector) instructions
This commit is contained in:
parent
1d71e33171
commit
f39a864050
5 changed files with 86 additions and 0 deletions
|
@ -142,11 +142,13 @@ namespace ChocolArm64
|
||||||
Set("0>101110<<1xxxxx001111xxxxxxxxxx", AInstEmit.Cmhs_V, typeof(AOpCodeSimdReg));
|
Set("0>101110<<1xxxxx001111xxxxxxxxxx", AInstEmit.Cmhs_V, typeof(AOpCodeSimdReg));
|
||||||
Set("0>101110<<100000100110xxxxxxxxxx", AInstEmit.Cmle_V, typeof(AOpCodeSimd));
|
Set("0>101110<<100000100110xxxxxxxxxx", AInstEmit.Cmle_V, typeof(AOpCodeSimd));
|
||||||
Set("0>001110<<100000101010xxxxxxxxxx", AInstEmit.Cmlt_V, typeof(AOpCodeSimd));
|
Set("0>001110<<100000101010xxxxxxxxxx", AInstEmit.Cmlt_V, typeof(AOpCodeSimd));
|
||||||
|
Set("0>001110<<1xxxxx100011xxxxxxxxxx", AInstEmit.Cmtst_V, typeof(AOpCodeSimdReg));
|
||||||
Set("0x00111000100000010110xxxxxxxxxx", AInstEmit.Cnt_V, typeof(AOpCodeSimd));
|
Set("0x00111000100000010110xxxxxxxxxx", AInstEmit.Cnt_V, typeof(AOpCodeSimd));
|
||||||
Set("0x001110000xxxxx000011xxxxxxxxxx", AInstEmit.Dup_Gp, typeof(AOpCodeSimdIns));
|
Set("0x001110000xxxxx000011xxxxxxxxxx", AInstEmit.Dup_Gp, typeof(AOpCodeSimdIns));
|
||||||
Set("01011110000xxxxx000001xxxxxxxxxx", AInstEmit.Dup_S, typeof(AOpCodeSimdIns));
|
Set("01011110000xxxxx000001xxxxxxxxxx", AInstEmit.Dup_S, typeof(AOpCodeSimdIns));
|
||||||
Set("0x001110000xxxxx000001xxxxxxxxxx", AInstEmit.Dup_V, typeof(AOpCodeSimdIns));
|
Set("0x001110000xxxxx000001xxxxxxxxxx", AInstEmit.Dup_V, typeof(AOpCodeSimdIns));
|
||||||
Set("0x101110001xxxxx000111xxxxxxxxxx", AInstEmit.Eor_V, typeof(AOpCodeSimdReg));
|
Set("0x101110001xxxxx000111xxxxxxxxxx", AInstEmit.Eor_V, typeof(AOpCodeSimdReg));
|
||||||
|
Set("0>101110000xxxxx0<xxx0xxxxxxxxxx", AInstEmit.Ext_V, typeof(AOpCodeSimdExt));
|
||||||
Set("011111101x1xxxxx110101xxxxxxxxxx", AInstEmit.Fabd_S, typeof(AOpCodeSimdReg));
|
Set("011111101x1xxxxx110101xxxxxxxxxx", AInstEmit.Fabd_S, typeof(AOpCodeSimdReg));
|
||||||
Set("000111100x100000110000xxxxxxxxxx", AInstEmit.Fabs_S, typeof(AOpCodeSimd));
|
Set("000111100x100000110000xxxxxxxxxx", AInstEmit.Fabs_S, typeof(AOpCodeSimd));
|
||||||
Set("000111100x1xxxxx001010xxxxxxxxxx", AInstEmit.Fadd_S, typeof(AOpCodeSimdReg));
|
Set("000111100x1xxxxx001010xxxxxxxxxx", AInstEmit.Fadd_S, typeof(AOpCodeSimdReg));
|
||||||
|
@ -262,6 +264,7 @@ namespace ChocolArm64
|
||||||
Set("011111100x100001110110xxxxxxxxxx", AInstEmit.Ucvtf_S, typeof(AOpCodeSimd));
|
Set("011111100x100001110110xxxxxxxxxx", AInstEmit.Ucvtf_S, typeof(AOpCodeSimd));
|
||||||
Set("0x1011100x100001110110xxxxxxxxxx", AInstEmit.Ucvtf_V, typeof(AOpCodeSimd));
|
Set("0x1011100x100001110110xxxxxxxxxx", AInstEmit.Ucvtf_V, typeof(AOpCodeSimd));
|
||||||
Set("0x001110000xxxxx001111xxxxxxxxxx", AInstEmit.Umov_S, typeof(AOpCodeSimdIns));
|
Set("0x001110000xxxxx001111xxxxxxxxxx", AInstEmit.Umov_S, typeof(AOpCodeSimdIns));
|
||||||
|
Set("0x101110<<1xxxxx110000xxxxxxxxxx", AInstEmit.Umull_V, typeof(AOpCodeSimdReg));
|
||||||
Set("0>101110<<1xxxxx010001xxxxxxxxxx", 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("011111110>>>>xxx000001xxxxxxxxxx", AInstEmit.Ushr_S, typeof(AOpCodeSimdShImm));
|
Set("011111110>>>>xxx000001xxxxxxxxxx", AInstEmit.Ushr_S, typeof(AOpCodeSimdShImm));
|
||||||
|
|
14
ChocolArm64/Decoder/AOpCodeSimdExt.cs
Normal file
14
ChocolArm64/Decoder/AOpCodeSimdExt.cs
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
using ChocolArm64.Instruction;
|
||||||
|
|
||||||
|
namespace ChocolArm64.Decoder
|
||||||
|
{
|
||||||
|
class AOpCodeSimdExt : AOpCodeSimdReg
|
||||||
|
{
|
||||||
|
public int Imm4 { get; private set; }
|
||||||
|
|
||||||
|
public AOpCodeSimdExt(AInst Inst, long Position, int OpCode) : base(Inst, Position, OpCode)
|
||||||
|
{
|
||||||
|
int Imm4 = (OpCode >> 11) & 0xf;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -406,5 +406,10 @@ namespace ChocolArm64.Instruction
|
||||||
{
|
{
|
||||||
EmitVectorWidenRmBinaryOpZx(Context, () => Context.Emit(OpCodes.Add));
|
EmitVectorWidenRmBinaryOpZx(Context, () => Context.Emit(OpCodes.Add));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void Umull_V(AILEmitterCtx Context)
|
||||||
|
{
|
||||||
|
EmitVectorWidenRnRmBinaryOpZx(Context, () => Context.Emit(OpCodes.Mul));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -46,6 +46,45 @@ namespace ChocolArm64.Instruction
|
||||||
EmitVectorCmp(Context, OpCodes.Blt_S);
|
EmitVectorCmp(Context, OpCodes.Blt_S);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void Cmtst_V(AILEmitterCtx Context)
|
||||||
|
{
|
||||||
|
AOpCodeSimdReg Op = (AOpCodeSimdReg)Context.CurrOp;
|
||||||
|
|
||||||
|
int Bytes = Context.CurrOp.GetBitsCount() >> 3;
|
||||||
|
|
||||||
|
ulong SzMask = ulong.MaxValue >> (64 - (8 << Op.Size));
|
||||||
|
|
||||||
|
for (int Index = 0; Index < (Bytes >> Op.Size); Index++)
|
||||||
|
{
|
||||||
|
EmitVectorExtractZx(Context, Op.Rn, Index, Op.Size);
|
||||||
|
EmitVectorExtractZx(Context, Op.Rm, Index, Op.Size);
|
||||||
|
|
||||||
|
AILLabel LblTrue = new AILLabel();
|
||||||
|
AILLabel LblEnd = new AILLabel();
|
||||||
|
|
||||||
|
Context.Emit(OpCodes.And);
|
||||||
|
|
||||||
|
Context.EmitLdc_I4(0);
|
||||||
|
|
||||||
|
Context.Emit(OpCodes.Bne_Un_S, LblTrue);
|
||||||
|
|
||||||
|
EmitVectorInsert(Context, Op.Rd, Index, Op.Size, 0);
|
||||||
|
|
||||||
|
Context.Emit(OpCodes.Br_S, LblEnd);
|
||||||
|
|
||||||
|
Context.MarkLabel(LblTrue);
|
||||||
|
|
||||||
|
EmitVectorInsert(Context, Op.Rd, Index, Op.Size, (long)SzMask);
|
||||||
|
|
||||||
|
Context.MarkLabel(LblEnd);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Op.RegisterSize == ARegisterSize.SIMD64)
|
||||||
|
{
|
||||||
|
EmitVectorZeroUpper(Context, Op.Rd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static void Fccmp_S(AILEmitterCtx Context)
|
public static void Fccmp_S(AILEmitterCtx Context)
|
||||||
{
|
{
|
||||||
AOpCodeSimdFcond Op = (AOpCodeSimdFcond)Context.CurrOp;
|
AOpCodeSimdFcond Op = (AOpCodeSimdFcond)Context.CurrOp;
|
||||||
|
|
|
@ -57,6 +57,31 @@ namespace ChocolArm64.Instruction
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void Ext_V(AILEmitterCtx Context)
|
||||||
|
{
|
||||||
|
AOpCodeSimdExt Op = (AOpCodeSimdExt)Context.CurrOp;
|
||||||
|
|
||||||
|
int Bytes = Context.CurrOp.GetBitsCount() >> 3;
|
||||||
|
|
||||||
|
for (int Index = 0; Index < Bytes; Index++)
|
||||||
|
{
|
||||||
|
int Position = Op.Imm4 + Index;
|
||||||
|
|
||||||
|
int Reg = Position < Bytes ? Op.Rn : Op.Rm;
|
||||||
|
|
||||||
|
Position &= Bytes - 1;
|
||||||
|
|
||||||
|
EmitVectorExtractZx(Context, Reg, Position, 0);
|
||||||
|
|
||||||
|
EmitVectorInsert(Context, Op.Rd, Index, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Op.RegisterSize == ARegisterSize.SIMD64)
|
||||||
|
{
|
||||||
|
EmitVectorZeroUpper(Context, Op.Rd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static void Fcsel_S(AILEmitterCtx Context)
|
public static void Fcsel_S(AILEmitterCtx Context)
|
||||||
{
|
{
|
||||||
AOpCodeSimdFcond Op = (AOpCodeSimdFcond)Context.CurrOp;
|
AOpCodeSimdFcond Op = (AOpCodeSimdFcond)Context.CurrOp;
|
||||||
|
|
Loading…
Reference in a new issue