diff --git a/ChocolArm64/AOpCodeTable.cs b/ChocolArm64/AOpCodeTable.cs index 6b250b4b00..5afdbd1ffe 100644 --- a/ChocolArm64/AOpCodeTable.cs +++ b/ChocolArm64/AOpCodeTable.cs @@ -243,6 +243,7 @@ namespace ChocolArm64 Set("0x00111100>>>xxx100001xxxxxxxxxx", AInstEmit.Shrn_V, typeof(AOpCodeSimdShImm)); Set("0x001110<<1xxxxx011001xxxxxxxxxx", AInstEmit.Smax_V, typeof(AOpCodeSimdReg)); Set("0x001110<<1xxxxx011011xxxxxxxxxx", AInstEmit.Smin_V, typeof(AOpCodeSimdReg)); + Set("0x001110<<1xxxxx100000xxxxxxxxxx", AInstEmit.Smlal_V, typeof(AOpCodeSimdReg)); Set("0x001110<<1xxxxx110000xxxxxxxxxx", AInstEmit.Smull_V, typeof(AOpCodeSimdReg)); Set("0>001110<<1xxxxx010001xxxxxxxxxx", AInstEmit.Sshl_V, typeof(AOpCodeSimdReg)); Set("0x00111100>>>xxx101001xxxxxxxxxx", AInstEmit.Sshll_V, typeof(AOpCodeSimdShImm)); diff --git a/ChocolArm64/Decoder/AOpCodeSimdExt.cs b/ChocolArm64/Decoder/AOpCodeSimdExt.cs index cf22d6546f..888e447030 100644 --- a/ChocolArm64/Decoder/AOpCodeSimdExt.cs +++ b/ChocolArm64/Decoder/AOpCodeSimdExt.cs @@ -8,7 +8,7 @@ namespace ChocolArm64.Decoder public AOpCodeSimdExt(AInst Inst, long Position, int OpCode) : base(Inst, Position, OpCode) { - int Imm4 = (OpCode >> 11) & 0xf; + Imm4 = (OpCode >> 11) & 0xf; } } } \ No newline at end of file diff --git a/ChocolArm64/Instruction/AInstEmitSimdArithmetic.cs b/ChocolArm64/Instruction/AInstEmitSimdArithmetic.cs index 9f5cc64f4c..b2d190f1a9 100644 --- a/ChocolArm64/Instruction/AInstEmitSimdArithmetic.cs +++ b/ChocolArm64/Instruction/AInstEmitSimdArithmetic.cs @@ -374,6 +374,15 @@ namespace ChocolArm64.Instruction EmitVectorBinaryOpSx(Context, () => Context.EmitCall(MthdInfo)); } + public static void Smlal_V(AILEmitterCtx Context) + { + EmitVectorWidenRnRmTernaryOpSx(Context, () => + { + Context.Emit(OpCodes.Mul); + Context.Emit(OpCodes.Add); + }); + } + public static void Smull_V(AILEmitterCtx Context) { EmitVectorWidenRnRmBinaryOpSx(Context, () => Context.Emit(OpCodes.Mul)); diff --git a/ChocolArm64/Instruction/AInstEmitSimdHelper.cs b/ChocolArm64/Instruction/AInstEmitSimdHelper.cs index 33e4d54874..e6ead99aa2 100644 --- a/ChocolArm64/Instruction/AInstEmitSimdHelper.cs +++ b/ChocolArm64/Instruction/AInstEmitSimdHelper.cs @@ -459,15 +459,25 @@ namespace ChocolArm64.Instruction public static void EmitVectorWidenRnRmBinaryOpSx(AILEmitterCtx Context, Action Emit) { - EmitVectorWidenRnRmBinaryOp(Context, Emit, true); + EmitVectorWidenRnRmOp(Context, Emit, false, true); } public static void EmitVectorWidenRnRmBinaryOpZx(AILEmitterCtx Context, Action Emit) { - EmitVectorWidenRnRmBinaryOp(Context, Emit, false); + EmitVectorWidenRnRmOp(Context, Emit, false, false); } - public static void EmitVectorWidenRnRmBinaryOp(AILEmitterCtx Context, Action Emit, bool Signed) + public static void EmitVectorWidenRnRmTernaryOpSx(AILEmitterCtx Context, Action Emit) + { + EmitVectorWidenRnRmOp(Context, Emit, true, true); + } + + public static void EmitVectorWidenRnRmTernaryOpZx(AILEmitterCtx Context, Action Emit) + { + EmitVectorWidenRnRmOp(Context, Emit, true, false); + } + + public static void EmitVectorWidenRnRmOp(AILEmitterCtx Context, Action Emit, bool Ternary, bool Signed) { AOpCodeSimdReg Op = (AOpCodeSimdReg)Context.CurrOp; @@ -477,6 +487,11 @@ namespace ChocolArm64.Instruction for (int Index = 0; Index < Elems; Index++) { + if (Ternary) + { + EmitVectorExtract(Context, Op.Rd, Index, Op.Size + 1, Signed); + } + EmitVectorExtract(Context, Op.Rn, Part + Index, Op.Size, Signed); EmitVectorExtract(Context, Op.Rm, Part + Index, Op.Size, Signed); diff --git a/ChocolArm64/Instruction/AInstEmitSimdMove.cs b/ChocolArm64/Instruction/AInstEmitSimdMove.cs index a4e533709e..3f427ad8ad 100644 --- a/ChocolArm64/Instruction/AInstEmitSimdMove.cs +++ b/ChocolArm64/Instruction/AInstEmitSimdMove.cs @@ -63,15 +63,18 @@ namespace ChocolArm64.Instruction int Bytes = Context.CurrOp.GetBitsCount() >> 3; + int Position = Op.Imm4; + for (int Index = 0; Index < Bytes; Index++) { - int Position = Op.Imm4 + Index; + int Reg = Op.Imm4 + Index < Bytes ? Op.Rn : Op.Rm; - int Reg = Position < Bytes ? Op.Rn : Op.Rm; + if (Position == Bytes) + { + Position = 0; + } - Position &= Bytes - 1; - - EmitVectorExtractZx(Context, Reg, Position, 0); + EmitVectorExtractZx(Context, Reg, Position++, 0); EmitVectorInsert(Context, Op.Rd, Index, 0); }