diff options
| author | LDj3SNuD <35856442+LDj3SNuD@users.noreply.github.com> | 2018-04-20 17:40:15 +0200 |
|---|---|---|
| committer | gdkchan <gab.dark.100@gmail.com> | 2018-04-20 12:40:15 -0300 |
| commit | 2ccd995cb27d95d056f8b6f270cb74012bfb7a33 (patch) | |
| tree | 4c550626f7a352b0456edcaa22bf9d5d5bf87a9a /ChocolArm64/Instruction/AInstEmitSimdArithmetic.cs | |
| parent | 03002f6537e3208e6951bc9092e958985e200c7d (diff) | |
Add ADDHN{2}, RADDHN{2}, SUBHN{2}, RSUBHN{2} (vector) instructions. Add 8 Tests. (#92)
* Update AOpCodeTable.cs
* Update AInstEmitSimdArithmetic.cs
* Update Pseudocode.cs
* Update Instructions.cs
* Update Bits.cs
* Create CpuTestSimd.cs
* Create CpuTestSimdReg.cs
* Update CpuTestSimd.cs
Provide a better supply of input values for the 20 Simd Tests.
* Update CpuTestSimdReg.cs
Provide a better supply of input values for the 20 Simd Tests.
* Update AOpCodeTable.cs
* Update AInstEmitSimdArithmetic.cs
* Update CpuTestSimd.cs
* Update CpuTestSimdReg.cs
Diffstat (limited to 'ChocolArm64/Instruction/AInstEmitSimdArithmetic.cs')
| -rw-r--r-- | ChocolArm64/Instruction/AInstEmitSimdArithmetic.cs | 55 |
1 files changed, 54 insertions, 1 deletions
diff --git a/ChocolArm64/Instruction/AInstEmitSimdArithmetic.cs b/ChocolArm64/Instruction/AInstEmitSimdArithmetic.cs index 6b65c156..2dce7410 100644 --- a/ChocolArm64/Instruction/AInstEmitSimdArithmetic.cs +++ b/ChocolArm64/Instruction/AInstEmitSimdArithmetic.cs @@ -26,7 +26,6 @@ namespace ChocolArm64.Instruction AILLabel LblTrue = new AILLabel(); Context.Emit(OpCodes.Dup); - Context.Emit(OpCodes.Ldc_I4_0); Context.Emit(OpCodes.Bge_S, LblTrue); @@ -45,6 +44,11 @@ namespace ChocolArm64.Instruction EmitVectorBinaryOpZx(Context, () => Context.Emit(OpCodes.Add)); } + public static void Addhn_V(AILEmitterCtx Context) + { + EmitHighNarrow(Context, () => Context.Emit(OpCodes.Add), Round: false); + } + public static void Addp_S(AILEmitterCtx Context) { AOpCodeSimd Op = (AOpCodeSimd)Context.CurrOp; @@ -130,6 +134,40 @@ namespace ChocolArm64.Instruction } } + private static void EmitHighNarrow(AILEmitterCtx Context, Action Emit, bool Round) + { + AOpCodeSimdReg Op = (AOpCodeSimdReg)Context.CurrOp; + + int Elems = 8 >> Op.Size; + int ESize = 8 << Op.Size; + + int Part = Op.RegisterSize == ARegisterSize.SIMD128 ? Elems : 0; + + for (int Index = 0; Index < Elems; Index++) + { + EmitVectorExtractZx(Context, Op.Rn, Index, Op.Size + 1); + EmitVectorExtractZx(Context, Op.Rm, Index, Op.Size + 1); + + Emit(); + + if (Round) + { + Context.EmitLdc_I8(1L << (ESize - 1)); + + Context.Emit(OpCodes.Add); + } + + Context.EmitLsr(ESize); + + EmitVectorInsert(Context, Op.Rd, Part + Index, Op.Size); + } + + if (Part == 0) + { + EmitVectorZeroUpper(Context, Op.Rd); + } + } + public static void Fabd_S(AILEmitterCtx Context) { EmitScalarBinaryOpF(Context, () => @@ -849,6 +887,16 @@ namespace ChocolArm64.Instruction EmitVectorUnaryOpSx(Context, () => Context.Emit(OpCodes.Neg)); } + public static void Raddhn_V(AILEmitterCtx Context) + { + EmitHighNarrow(Context, () => Context.Emit(OpCodes.Add), Round: true); + } + + public static void Rsubhn_V(AILEmitterCtx Context) + { + EmitHighNarrow(Context, () => Context.Emit(OpCodes.Sub), Round: true); + } + public static void Saddw_V(AILEmitterCtx Context) { EmitVectorWidenRmBinaryOpSx(Context, () => Context.Emit(OpCodes.Add)); @@ -896,6 +944,11 @@ namespace ChocolArm64.Instruction EmitVectorBinaryOpZx(Context, () => Context.Emit(OpCodes.Sub)); } + public static void Subhn_V(AILEmitterCtx Context) + { + EmitHighNarrow(Context, () => Context.Emit(OpCodes.Sub), Round: false); + } + public static void Uabd_V(AILEmitterCtx Context) { EmitVectorBinaryOpZx(Context, () => EmitAbd(Context)); |
