diff options
| author | gdkchan <gab.dark.100@gmail.com> | 2018-07-14 13:13:02 -0300 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2018-07-14 13:13:02 -0300 |
| commit | 514218ab98acc1f0ace2e2cc0b8c1091ffccc6ce (patch) | |
| tree | ce7c44f11aa1dad7143678b2444bc297b98e5bff /ChocolArm64/Instruction/AInstEmitSimdShift.cs | |
| parent | 2f37583ab3b49aa5064a72c8d3b4e8245ebb6b5b (diff) | |
Add SMLSL, SQRSHRN and SRSHR (Vector) cpu instructions, nits (#225)
* Add SMLSL, SQRSHRN and SRSHR (Vector) cpu instructions
* Address PR feedback
* Address PR feedback
* Remove another useless temp var
* nit: Alignment
* Replace Context.CurrOp.GetBitsCount() with Op.GetBitsCount()
* Fix encodings and move flag bit test out of the loop
Diffstat (limited to 'ChocolArm64/Instruction/AInstEmitSimdShift.cs')
| -rw-r--r-- | ChocolArm64/Instruction/AInstEmitSimdShift.cs | 108 |
1 files changed, 80 insertions, 28 deletions
diff --git a/ChocolArm64/Instruction/AInstEmitSimdShift.cs b/ChocolArm64/Instruction/AInstEmitSimdShift.cs index 24d35abe..6f6b5606 100644 --- a/ChocolArm64/Instruction/AInstEmitSimdShift.cs +++ b/ChocolArm64/Instruction/AInstEmitSimdShift.cs @@ -27,9 +27,7 @@ namespace ChocolArm64.Instruction { AOpCodeSimdShImm Op = (AOpCodeSimdShImm)Context.CurrOp; - int Shift = Op.Imm - (8 << Op.Size); - - EmitVectorShImmBinaryZx(Context, () => Context.Emit(OpCodes.Shl), Shift); + EmitVectorShImmBinaryZx(Context, () => Context.Emit(OpCodes.Shl), GetImmShl(Op)); } public static void Shll_V(AILEmitterCtx Context) @@ -45,22 +43,21 @@ namespace ChocolArm64.Instruction { AOpCodeSimdShImm Op = (AOpCodeSimdShImm)Context.CurrOp; - int Shift = (8 << (Op.Size + 1)) - Op.Imm; - - EmitVectorShImmNarrowBinaryZx(Context, () => Context.Emit(OpCodes.Shr_Un), Shift); + EmitVectorShImmNarrowBinaryZx(Context, () => Context.Emit(OpCodes.Shr_Un), GetImmShr(Op)); } public static void Sli_V(AILEmitterCtx Context) { AOpCodeSimdShImm Op = (AOpCodeSimdShImm)Context.CurrOp; - int Bytes = Context.CurrOp.GetBitsCount() >> 3; + int Bytes = Op.GetBitsCount() >> 3; + int Elems = Bytes >> Op.Size; - int Shift = Op.Imm - (8 << Op.Size); + int Shift = GetImmShl(Op); - ulong Mask = Shift != 0 ? ulong.MaxValue >> (64 - Shift) : 0; + ulong Mask = Shift != 0 ? ulong.MaxValue >> (64 - Shift) : 0; - for (int Index = 0; Index < (Bytes >> Op.Size); Index++) + for (int Index = 0; Index < Elems; Index++) { EmitVectorExtractZx(Context, Op.Rn, Index, Op.Size); @@ -84,6 +81,39 @@ namespace ChocolArm64.Instruction } } + public static void Sqrshrn_V(AILEmitterCtx Context) + { + AOpCodeSimdShImm Op = (AOpCodeSimdShImm)Context.CurrOp; + + int Shift = GetImmShr(Op); + + long RoundConst = 1L << (Shift - 1); + + Action Emit = () => + { + Context.EmitLdc_I8(RoundConst); + + Context.Emit(OpCodes.Add); + + Context.EmitLdc_I4(Shift); + + Context.Emit(OpCodes.Shr); + }; + + EmitVectorSaturatingNarrowOpSxSx(Context, Emit); + } + + public static void Srshr_V(AILEmitterCtx Context) + { + AOpCodeSimdShImm Op = (AOpCodeSimdShImm)Context.CurrOp; + + int Shift = GetImmShr(Op); + + long RoundConst = 1L << (Shift - 1); + + EmitVectorRoundShImmBinarySx(Context, () => Context.Emit(OpCodes.Shr), Shift, RoundConst); + } + public static void Sshl_V(AILEmitterCtx Context) { EmitVectorShl(Context, Signed: true); @@ -93,9 +123,7 @@ namespace ChocolArm64.Instruction { AOpCodeSimdShImm Op = (AOpCodeSimdShImm)Context.CurrOp; - int Shift = Op.Imm - (8 << Op.Size); - - EmitVectorShImmWidenBinarySx(Context, () => Context.Emit(OpCodes.Shl), Shift); + EmitVectorShImmWidenBinarySx(Context, () => Context.Emit(OpCodes.Shl), GetImmShl(Op)); } public static void Sshr_S(AILEmitterCtx Context) @@ -115,24 +143,20 @@ namespace ChocolArm64.Instruction { AOpCodeSimdShImm Op = (AOpCodeSimdShImm)Context.CurrOp; - int Shift = (8 << (Op.Size + 1)) - Op.Imm; - - EmitVectorShImmBinarySx(Context, () => Context.Emit(OpCodes.Shr), Shift); + EmitVectorShImmBinarySx(Context, () => Context.Emit(OpCodes.Shr), GetImmShr(Op)); } public static void Ssra_V(AILEmitterCtx Context) { AOpCodeSimdShImm Op = (AOpCodeSimdShImm)Context.CurrOp; - int Shift = (8 << (Op.Size + 1)) - Op.Imm; - Action Emit = () => { Context.Emit(OpCodes.Shr); Context.Emit(OpCodes.Add); }; - EmitVectorShImmTernarySx(Context, Emit, Shift); + EmitVectorShImmTernarySx(Context, Emit, GetImmShr(Op)); } public static void Ushl_V(AILEmitterCtx Context) @@ -144,9 +168,7 @@ namespace ChocolArm64.Instruction { AOpCodeSimdShImm Op = (AOpCodeSimdShImm)Context.CurrOp; - int Shift = Op.Imm - (8 << Op.Size); - - EmitVectorShImmWidenBinaryZx(Context, () => Context.Emit(OpCodes.Shl), Shift); + EmitVectorShImmWidenBinaryZx(Context, () => Context.Emit(OpCodes.Shl), GetImmShl(Op)); } public static void Ushr_S(AILEmitterCtx Context) @@ -251,28 +273,51 @@ namespace ChocolArm64.Instruction } } + [Flags] + private enum ShImmFlags + { + None = 0, + + Signed = 1 << 0, + Ternary = 1 << 1, + Rounded = 1 << 2, + + SignedTernary = Signed | Ternary, + SignedRounded = Signed | Rounded + } + private static void EmitVectorShImmBinarySx(AILEmitterCtx Context, Action Emit, int Imm) { - EmitVectorShImmOp(Context, Emit, Imm, false, true); + EmitVectorShImmOp(Context, Emit, Imm, ShImmFlags.Signed); } private static void EmitVectorShImmTernarySx(AILEmitterCtx Context, Action Emit, int Imm) { - EmitVectorShImmOp(Context, Emit, Imm, true, true); + EmitVectorShImmOp(Context, Emit, Imm, ShImmFlags.SignedTernary); } private static void EmitVectorShImmBinaryZx(AILEmitterCtx Context, Action Emit, int Imm) { - EmitVectorShImmOp(Context, Emit, Imm, false, false); + EmitVectorShImmOp(Context, Emit, Imm, ShImmFlags.None); + } + + private static void EmitVectorRoundShImmBinarySx(AILEmitterCtx Context, Action Emit, int Imm, long Rc) + { + EmitVectorShImmOp(Context, Emit, Imm, ShImmFlags.SignedRounded, Rc); } - private static void EmitVectorShImmOp(AILEmitterCtx Context, Action Emit, int Imm, bool Ternary, bool Signed) + private static void EmitVectorShImmOp(AILEmitterCtx Context, Action Emit, int Imm, ShImmFlags Flags, long Rc = 0) { AOpCodeSimd Op = (AOpCodeSimd)Context.CurrOp; - int Bytes = Context.CurrOp.GetBitsCount() >> 3; + int Bytes = Op.GetBitsCount() >> 3; + int Elems = Bytes >> Op.Size; + + bool Signed = (Flags & ShImmFlags.Signed) != 0; + bool Ternary = (Flags & ShImmFlags.Ternary) != 0; + bool Rounded = (Flags & ShImmFlags.Rounded) != 0; - for (int Index = 0; Index < (Bytes >> Op.Size); Index++) + for (int Index = 0; Index < Elems; Index++) { if (Ternary) { @@ -281,6 +326,13 @@ namespace ChocolArm64.Instruction EmitVectorExtract(Context, Op.Rn, Index, Op.Size, Signed); + if (Rounded) + { + Context.EmitLdc_I8(Rc); + + Context.Emit(OpCodes.Add); + } + Context.EmitLdc_I4(Imm); Emit(); |
