diff options
| author | gdkchan <gab.dark.100@gmail.com> | 2018-03-14 00:12:05 -0300 |
|---|---|---|
| committer | gdkchan <gab.dark.100@gmail.com> | 2018-03-14 00:12:05 -0300 |
| commit | 553ba659c40013cde0198c2bdd10b31bdd6f3d97 (patch) | |
| tree | 266b13399ec274a61497ae430abd036f9196c1ee /ChocolArm64/Instruction/AInstEmitSimdShift.cs | |
| parent | 19564e570baab98754cb808c704fbd9c924abc60 (diff) | |
Add CRC32 instruction and SLI (vector)
Diffstat (limited to 'ChocolArm64/Instruction/AInstEmitSimdShift.cs')
| -rw-r--r-- | ChocolArm64/Instruction/AInstEmitSimdShift.cs | 54 |
1 files changed, 44 insertions, 10 deletions
diff --git a/ChocolArm64/Instruction/AInstEmitSimdShift.cs b/ChocolArm64/Instruction/AInstEmitSimdShift.cs index bb8a8f17..bffed57e 100644 --- a/ChocolArm64/Instruction/AInstEmitSimdShift.cs +++ b/ChocolArm64/Instruction/AInstEmitSimdShift.cs @@ -29,7 +29,7 @@ namespace ChocolArm64.Instruction int Shift = Op.Imm - (8 << Op.Size); - EmitVectorBinaryShImmBinaryZx(Context, () => Context.Emit(OpCodes.Shl), Shift); + EmitVectorShImmBinaryZx(Context, () => Context.Emit(OpCodes.Shl), Shift); } public static void Shll_V(AILEmitterCtx Context) @@ -50,6 +50,40 @@ namespace ChocolArm64.Instruction EmitVectorShImmNarrowBinaryZx(Context, () => Context.Emit(OpCodes.Shr_Un), Shift); } + public static void Sli_V(AILEmitterCtx Context) + { + AOpCodeSimdShImm Op = (AOpCodeSimdShImm)Context.CurrOp; + + int Bytes = Context.CurrOp.GetBitsCount() >> 3; + + int Shift = Op.Imm - (8 << Op.Size); + + ulong Mask = ulong.MaxValue >> (64 - Shift); + + for (int Index = 0; Index < (Bytes >> Op.Size); Index++) + { + EmitVectorExtractZx(Context, Op.Rn, Index, Op.Size); + + Context.EmitLdc_I4(Shift); + + Context.Emit(OpCodes.Shl); + + EmitVectorExtractZx(Context, Op.Rd, Index, Op.Size); + + Context.EmitLdc_I8((long)Mask); + + Context.Emit(OpCodes.And); + Context.Emit(OpCodes.Or); + + EmitVectorInsert(Context, Op.Rd, Index, Op.Size); + } + + if (Op.RegisterSize == ARegisterSize.SIMD64) + { + EmitVectorZeroUpper(Context, Op.Rd); + } + } + public static void Sshl_V(AILEmitterCtx Context) { EmitVectorShl(Context, Signed: true); @@ -83,7 +117,7 @@ namespace ChocolArm64.Instruction int Shift = (8 << (Op.Size + 1)) - Op.Imm; - EmitVectorBinaryShImmBinarySx(Context, () => Context.Emit(OpCodes.Shr), Shift); + EmitVectorShImmBinarySx(Context, () => Context.Emit(OpCodes.Shr), Shift); } public static void Ssra_V(AILEmitterCtx Context) @@ -98,7 +132,7 @@ namespace ChocolArm64.Instruction Context.Emit(OpCodes.Add); }; - EmitVectorTernaryShImmBinarySx(Context, Emit, Shift); + EmitVectorShImmTernarySx(Context, Emit, Shift); } public static void Ushl_V(AILEmitterCtx Context) @@ -217,22 +251,22 @@ namespace ChocolArm64.Instruction } } - private static void EmitVectorBinaryShImmBinarySx(AILEmitterCtx Context, Action Emit, int Imm) + private static void EmitVectorShImmBinarySx(AILEmitterCtx Context, Action Emit, int Imm) { - EmitVectorShImmBinaryOp(Context, Emit, Imm, false, true); + EmitVectorShImmOp(Context, Emit, Imm, false, true); } - private static void EmitVectorTernaryShImmBinarySx(AILEmitterCtx Context, Action Emit, int Imm) + private static void EmitVectorShImmTernarySx(AILEmitterCtx Context, Action Emit, int Imm) { - EmitVectorShImmBinaryOp(Context, Emit, Imm, true, true); + EmitVectorShImmOp(Context, Emit, Imm, true, true); } - private static void EmitVectorBinaryShImmBinaryZx(AILEmitterCtx Context, Action Emit, int Imm) + private static void EmitVectorShImmBinaryZx(AILEmitterCtx Context, Action Emit, int Imm) { - EmitVectorShImmBinaryOp(Context, Emit, Imm, false, false); + EmitVectorShImmOp(Context, Emit, Imm, false, false); } - private static void EmitVectorShImmBinaryOp(AILEmitterCtx Context, Action Emit, int Imm, bool Ternary, bool Signed) + private static void EmitVectorShImmOp(AILEmitterCtx Context, Action Emit, int Imm, bool Ternary, bool Signed) { AOpCodeSimd Op = (AOpCodeSimd)Context.CurrOp; |
