diff options
| author | gdkchan <gab.dark.100@gmail.com> | 2018-03-02 19:21:54 -0300 |
|---|---|---|
| committer | gdkchan <gab.dark.100@gmail.com> | 2018-03-02 19:23:38 -0300 |
| commit | f39a864050589ac7e757a9d72b46ac693125b382 (patch) | |
| tree | ba56ae59aabca61e0efd4d68ce227b93a6b78477 /ChocolArm64/Instruction | |
| parent | 1d71e33171f78fb40b097108fbd5915f18c608c4 (diff) | |
Add EXT, CMTST (vector) and UMULL (vector) instructions
Diffstat (limited to 'ChocolArm64/Instruction')
| -rw-r--r-- | ChocolArm64/Instruction/AInstEmitSimdArithmetic.cs | 5 | ||||
| -rw-r--r-- | ChocolArm64/Instruction/AInstEmitSimdCmp.cs | 39 | ||||
| -rw-r--r-- | ChocolArm64/Instruction/AInstEmitSimdMove.cs | 25 |
3 files changed, 69 insertions, 0 deletions
diff --git a/ChocolArm64/Instruction/AInstEmitSimdArithmetic.cs b/ChocolArm64/Instruction/AInstEmitSimdArithmetic.cs index e790d678..9c1bc286 100644 --- a/ChocolArm64/Instruction/AInstEmitSimdArithmetic.cs +++ b/ChocolArm64/Instruction/AInstEmitSimdArithmetic.cs @@ -406,5 +406,10 @@ namespace ChocolArm64.Instruction { EmitVectorWidenRmBinaryOpZx(Context, () => Context.Emit(OpCodes.Add)); } + + public static void Umull_V(AILEmitterCtx Context) + { + EmitVectorWidenRnRmBinaryOpZx(Context, () => Context.Emit(OpCodes.Mul)); + } } }
\ No newline at end of file diff --git a/ChocolArm64/Instruction/AInstEmitSimdCmp.cs b/ChocolArm64/Instruction/AInstEmitSimdCmp.cs index 97ccf0ab..76861b73 100644 --- a/ChocolArm64/Instruction/AInstEmitSimdCmp.cs +++ b/ChocolArm64/Instruction/AInstEmitSimdCmp.cs @@ -46,6 +46,45 @@ namespace ChocolArm64.Instruction 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) { AOpCodeSimdFcond Op = (AOpCodeSimdFcond)Context.CurrOp; diff --git a/ChocolArm64/Instruction/AInstEmitSimdMove.cs b/ChocolArm64/Instruction/AInstEmitSimdMove.cs index aabb8f34..a4e53370 100644 --- a/ChocolArm64/Instruction/AInstEmitSimdMove.cs +++ b/ChocolArm64/Instruction/AInstEmitSimdMove.cs @@ -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) { AOpCodeSimdFcond Op = (AOpCodeSimdFcond)Context.CurrOp; |
