From bc4ada20c724c5d00143314ee740f6f173f62e37 Mon Sep 17 00:00:00 2001 From: LDj3SNuD <35856442+LDj3SNuD@users.noreply.github.com> Date: Fri, 20 Apr 2018 17:40:15 +0200 Subject: [PATCH] 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 --- AOpCodeTable.cs | 4 ++ Instruction/AInstEmitSimdArithmetic.cs | 55 +++++++++++++++++++++++++- 2 files changed, 58 insertions(+), 1 deletion(-) diff --git a/AOpCodeTable.cs b/AOpCodeTable.cs index fb74f89..154affe 100644 --- a/AOpCodeTable.cs +++ b/AOpCodeTable.cs @@ -137,6 +137,7 @@ namespace ChocolArm64 Set("0>001110<<100000101110xxxxxxxxxx", AInstEmit.Abs_V, typeof(AOpCodeSimd)); Set("01011110111xxxxx100001xxxxxxxxxx", AInstEmit.Add_S, typeof(AOpCodeSimdReg)); Set("0>001110<<1xxxxx100001xxxxxxxxxx", AInstEmit.Add_V, typeof(AOpCodeSimdReg)); + Set("0x001110<<1xxxxx010000xxxxxxxxxx", AInstEmit.Addhn_V, typeof(AOpCodeSimdReg)); Set("01011110xx110001101110xxxxxxxxxx", AInstEmit.Addp_S, typeof(AOpCodeSimd)); Set("0>001110<<1xxxxx101111xxxxxxxxxx", AInstEmit.Addp_V, typeof(AOpCodeSimdReg)); Set("000011100x110001101110xxxxxxxxxx", AInstEmit.Addv_V, typeof(AOpCodeSimd)); @@ -290,7 +291,9 @@ namespace ChocolArm64 Set("0x10111000100000010110xxxxxxxxxx", AInstEmit.Not_V, typeof(AOpCodeSimd)); Set("0x001110101xxxxx000111xxxxxxxxxx", AInstEmit.Orr_V, typeof(AOpCodeSimdReg)); Set("0x00111100000xxx<101110<<1xxxxx100001xxxxxxxxxx", AInstEmit.Sub_V, typeof(AOpCodeSimdReg)); + Set("0x001110<<1xxxxx011000xxxxxxxxxx", AInstEmit.Subhn_V, typeof(AOpCodeSimdReg)); Set("0x001110000xxxxx0xx000xxxxxxxxxx", AInstEmit.Tbl_V, typeof(AOpCodeSimdTbl)); Set("0>001110<<0xxxxx001010xxxxxxxxxx", AInstEmit.Trn1_V, typeof(AOpCodeSimdReg)); Set("0>001110<<0xxxxx011010xxxxxxxxxx", AInstEmit.Trn2_V, typeof(AOpCodeSimdReg)); diff --git a/Instruction/AInstEmitSimdArithmetic.cs b/Instruction/AInstEmitSimdArithmetic.cs index 6b65c15..2dce741 100644 --- a/Instruction/AInstEmitSimdArithmetic.cs +++ b/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));