diff options
| author | gdkchan <gab.dark.100@gmail.com> | 2018-04-06 10:20:17 -0300 |
|---|---|---|
| committer | gdkchan <gab.dark.100@gmail.com> | 2018-04-06 10:20:17 -0300 |
| commit | df3cbadcebe48d40a6b8a8e510d21d452d0e0ab3 (patch) | |
| tree | 6b81ea97fa56c4b0cb7400a9a95a5ce9f8f069de | |
| parent | a7ecf6dd2dcbe4ff03118435d9d203bcc8500718 (diff) | |
Fix FRSQRTS and FCM* (scalar) instructions
| -rw-r--r-- | ChocolArm64/Instruction/AInstEmitSimdArithmetic.cs | 37 | ||||
| -rw-r--r-- | ChocolArm64/Instruction/AInstEmitSimdCmp.cs | 32 |
2 files changed, 51 insertions, 18 deletions
diff --git a/ChocolArm64/Instruction/AInstEmitSimdArithmetic.cs b/ChocolArm64/Instruction/AInstEmitSimdArithmetic.cs index 772b7955..bf119a18 100644 --- a/ChocolArm64/Instruction/AInstEmitSimdArithmetic.cs +++ b/ChocolArm64/Instruction/AInstEmitSimdArithmetic.cs @@ -512,22 +512,34 @@ namespace ChocolArm64.Instruction public static void Frsqrts_S(AILEmitterCtx Context) { - EmitScalarBinaryOpF(Context, () => EmitFrsqrts(Context)); + EmitFrsqrts(Context, 0, Scalar: true); } public static void Frsqrts_V(AILEmitterCtx Context) { - EmitVectorBinaryOpF(Context, () => EmitFrsqrts(Context)); + AOpCodeSimd Op = (AOpCodeSimd)Context.CurrOp; + + int SizeF = Op.Size & 1; + + int Bytes = Context.CurrOp.GetBitsCount() >> 3; + + for (int Index = 0; Index < Bytes >> SizeF + 2; Index++) + { + EmitFrsqrts(Context, Index, Scalar: false); + } + + if (Op.RegisterSize == ARegisterSize.SIMD64) + { + EmitVectorZeroUpper(Context, Op.Rd); + } } - private static void EmitFrsqrts(AILEmitterCtx Context) + private static void EmitFrsqrts(AILEmitterCtx Context, int Index, bool Scalar) { - IAOpCodeSimd Op = (IAOpCodeSimd)Context.CurrOp; + AOpCodeSimdReg Op = (AOpCodeSimdReg)Context.CurrOp; int SizeF = Op.Size & 1; - Context.Emit(OpCodes.Mul); - if (SizeF == 0) { Context.EmitLdc_R4(3); @@ -537,7 +549,11 @@ namespace ChocolArm64.Instruction Context.EmitLdc_R8(3); } - Context.Emit(OpCodes.Add); + EmitVectorExtractF(Context, Op.Rn, Index, SizeF); + EmitVectorExtractF(Context, Op.Rm, Index, SizeF); + + Context.Emit(OpCodes.Mul); + Context.Emit(OpCodes.Sub); if (SizeF == 0) { @@ -549,6 +565,13 @@ namespace ChocolArm64.Instruction } Context.Emit(OpCodes.Mul); + + if (Scalar) + { + EmitVectorZeroAll(Context, Op.Rd); + } + + EmitVectorInsertF(Context, Op.Rd, Index, SizeF); } public static void Fsqrt_S(AILEmitterCtx Context) diff --git a/ChocolArm64/Instruction/AInstEmitSimdCmp.cs b/ChocolArm64/Instruction/AInstEmitSimdCmp.cs index a71b6d42..f155d7e8 100644 --- a/ChocolArm64/Instruction/AInstEmitSimdCmp.cs +++ b/ChocolArm64/Instruction/AInstEmitSimdCmp.cs @@ -313,13 +313,7 @@ namespace ChocolArm64.Instruction private static void EmitScalarFcmp(AILEmitterCtx Context, OpCode ILOp) { - AOpCodeSimd Op = (AOpCodeSimd)Context.CurrOp; - - int SizeF = Op.Size & 1; - - EmitFcmp(Context, ILOp, 0); - - EmitScalarSetF(Context, Op.Rd, SizeF); + EmitFcmp(Context, ILOp, 0, Scalar: true); } private static void EmitVectorFcmp(AILEmitterCtx Context, OpCode ILOp) @@ -332,7 +326,7 @@ namespace ChocolArm64.Instruction for (int Index = 0; Index < Bytes >> SizeF + 2; Index++) { - EmitFcmp(Context, ILOp, Index); + EmitFcmp(Context, ILOp, Index, Scalar: false); } if (Op.RegisterSize == ARegisterSize.SIMD64) @@ -341,7 +335,7 @@ namespace ChocolArm64.Instruction } } - private static void EmitFcmp(AILEmitterCtx Context, OpCode ILOp, int Index) + private static void EmitFcmp(AILEmitterCtx Context, OpCode ILOp, int Index, bool Scalar) { AOpCodeSimd Op = (AOpCodeSimd)Context.CurrOp; @@ -369,13 +363,29 @@ namespace ChocolArm64.Instruction Context.Emit(ILOp, LblTrue); - EmitVectorInsert(Context, Op.Rd, Index, SizeF + 2, 0); + if (Scalar) + { + EmitVectorZeroAll(Context, Op.Rd); + } + else + { + EmitVectorInsert(Context, Op.Rd, Index, SizeF + 2, 0); + } Context.Emit(OpCodes.Br_S, LblEnd); Context.MarkLabel(LblTrue); - EmitVectorInsert(Context, Op.Rd, Index, SizeF + 2, (long)SzMask); + if (Scalar) + { + EmitVectorInsert(Context, Op.Rd, Index, 3, (long)SzMask); + + EmitVectorZeroUpper(Context, Op.Rd); + } + else + { + EmitVectorInsert(Context, Op.Rd, Index, SizeF + 2, (long)SzMask); + } Context.MarkLabel(LblEnd); } |
