diff --git a/ARMeilleure/Instructions/InstEmitSimdArithmetic.cs b/ARMeilleure/Instructions/InstEmitSimdArithmetic.cs index 9a632fd63..a35e28a15 100644 --- a/ARMeilleure/Instructions/InstEmitSimdArithmetic.cs +++ b/ARMeilleure/Instructions/InstEmitSimdArithmetic.cs @@ -726,7 +726,7 @@ namespace ARMeilleure.Instructions { EmitVectorAcrossVectorOpF(context, (op1, op2) => { - return context.Call(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPMaxNum)), op1, op2); + return EmitSoftFloatCall(context, nameof(SoftFloat32.FPMaxNum), op1, op2); }); } } @@ -774,7 +774,7 @@ namespace ARMeilleure.Instructions { EmitVectorAcrossVectorOpF(context, (op1, op2) => { - return context.Call(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPMax)), op1, op2); + return EmitSoftFloatCall(context, nameof(SoftFloat32.FPMax), op1, op2); }); } } @@ -900,7 +900,7 @@ namespace ARMeilleure.Instructions { EmitVectorAcrossVectorOpF(context, (op1, op2) => { - return context.Call(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPMinNum)), op1, op2); + return EmitSoftFloatCall(context, nameof(SoftFloat32.FPMinNum), op1, op2); }); } } @@ -948,7 +948,7 @@ namespace ARMeilleure.Instructions { EmitVectorAcrossVectorOpF(context, (op1, op2) => { - return context.Call(typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPMin)), op1, op2); + return EmitSoftFloatCall(context, nameof(SoftFloat32.FPMin), op1, op2); }); } } @@ -1633,37 +1633,17 @@ namespace ARMeilleure.Instructions public static void Frinti_S(ArmEmitterContext context) { - OpCodeSimd op = (OpCodeSimd)context.CurrOp; - EmitScalarUnaryOpF(context, (op1) => { - if (op.Size == 0) - { - return context.Call(typeof(SoftFallback).GetMethod(nameof(SoftFallback.RoundF)), op1); - } - else /* if (op.Size == 1) */ - { - return context.Call(typeof(SoftFallback).GetMethod(nameof(SoftFallback.Round)), op1); - } + return EmitRoundByRMode(context, op1); }); } public static void Frinti_V(ArmEmitterContext context) { - OpCodeSimd op = (OpCodeSimd)context.CurrOp; - - int sizeF = op.Size & 1; - EmitVectorUnaryOpF(context, (op1) => { - if (sizeF == 0) - { - return context.Call(typeof(SoftFallback).GetMethod(nameof(SoftFallback.RoundF)), op1); - } - else /* if (sizeF == 1) */ - { - return context.Call(typeof(SoftFallback).GetMethod(nameof(SoftFallback.Round)), op1); - } + return EmitRoundByRMode(context, op1); }); } @@ -1759,37 +1739,17 @@ namespace ARMeilleure.Instructions public static void Frintx_S(ArmEmitterContext context) { - OpCodeSimd op = (OpCodeSimd)context.CurrOp; - EmitScalarUnaryOpF(context, (op1) => { - if (op.Size == 0) - { - return context.Call(typeof(SoftFallback).GetMethod(nameof(SoftFallback.RoundF)), op1); - } - else /* if (op.Size == 1) */ - { - return context.Call(typeof(SoftFallback).GetMethod(nameof(SoftFallback.Round)), op1); - } + return EmitRoundByRMode(context, op1); }); } public static void Frintx_V(ArmEmitterContext context) { - OpCodeSimd op = (OpCodeSimd)context.CurrOp; - - int sizeF = op.Size & 1; - EmitVectorUnaryOpF(context, (op1) => { - if (sizeF == 0) - { - return context.Call(typeof(SoftFallback).GetMethod(nameof(SoftFallback.RoundF)), op1); - } - else /* if (sizeF == 1) */ - { - return context.Call(typeof(SoftFallback).GetMethod(nameof(SoftFallback.Round)), op1); - } + return EmitRoundByRMode(context, op1); }); } diff --git a/ARMeilleure/Instructions/InstEmitSimdCmp32.cs b/ARMeilleure/Instructions/InstEmitSimdCmp32.cs index 1acc74657..339d32939 100644 --- a/ARMeilleure/Instructions/InstEmitSimdCmp32.cs +++ b/ARMeilleure/Instructions/InstEmitSimdCmp32.cs @@ -3,7 +3,6 @@ using ARMeilleure.IntermediateRepresentation; using ARMeilleure.State; using ARMeilleure.Translation; using System; -using System.Reflection; using static ARMeilleure.Instructions.InstEmitHelper; using static ARMeilleure.Instructions.InstEmitSimdHelper; @@ -178,37 +177,20 @@ namespace ARMeilleure.Instructions private static void EmitCmpOpF32(ArmEmitterContext context, string name, bool zero) { - Operand one = Const(1); if (zero) { EmitVectorUnaryOpF32(context, (m) => { - OperandType type = m.Type; + Operand zeroOp = m.Type == OperandType.FP64 ? ConstF(0.0d) : ConstF(0.0f); - if (type == OperandType.FP64) - { - return context.Call(typeof(SoftFloat64).GetMethod(name), m, ConstF(0.0d), one); - } - else - { - return context.Call(typeof(SoftFloat32).GetMethod(name), m, ConstF(0.0f), one); - } + return EmitSoftFloatCallDefaultFpscr(context, name, m, zeroOp); }); } else { EmitVectorBinaryOpF32(context, (n, m) => { - OperandType type = n.Type; - - if (type == OperandType.FP64) - { - return context.Call(typeof(SoftFloat64).GetMethod(name), n, m, one); - } - else - { - return context.Call(typeof(SoftFloat32).GetMethod(name), n, m, one); - } + return EmitSoftFloatCallDefaultFpscr(context, name, n, m); }); } } @@ -357,11 +339,7 @@ namespace ARMeilleure.Instructions me = ExtractScalar(context, type, op.Vm); } - MethodInfo info = sizeF != 0 - ? typeof(SoftFloat64).GetMethod(nameof(SoftFloat64.FPCompare)) - : typeof(SoftFloat32).GetMethod(nameof(SoftFloat32.FPCompare)); - - Operand nzcv = context.Call(info, ne, me, Const(signalNaNs)); + Operand nzcv = EmitSoftFloatCall(context, nameof(SoftFloat32.FPCompare), ne, me, Const(signalNaNs)); EmitSetFpscrNzcv(context, nzcv); } diff --git a/ARMeilleure/Instructions/InstEmitSimdCvt.cs b/ARMeilleure/Instructions/InstEmitSimdCvt.cs index 6994643ed..c8c427b79 100644 --- a/ARMeilleure/Instructions/InstEmitSimdCvt.cs +++ b/ARMeilleure/Instructions/InstEmitSimdCvt.cs @@ -76,7 +76,9 @@ namespace ARMeilleure.Instructions { Operand ne = context.VectorExtract(OperandType.FP32, GetVec(op.Rn), 0); + context.StoreToContext(); Operand res = context.Call(typeof(SoftFloat32_16).GetMethod(nameof(SoftFloat32_16.FPConvert)), ne); + context.LoadFromContext(); res = context.ZeroExtend16(OperandType.I64, res); @@ -98,7 +100,9 @@ namespace ARMeilleure.Instructions { Operand ne = EmitVectorExtractZx(context, op.Rn, 0, 1); + context.StoreToContext(); Operand res = context.Call(typeof(SoftFloat16_32).GetMethod(nameof(SoftFloat16_32.FPConvert)), ne); + context.LoadFromContext(); context.Copy(GetVec(op.Rd), context.VectorInsert(context.VectorZero(), res, 0)); } @@ -120,7 +124,9 @@ namespace ARMeilleure.Instructions { Operand ne = context.VectorExtract(OperandType.FP64, GetVec(op.Rn), 0); + context.StoreToContext(); Operand res = context.Call(typeof(SoftFloat64_16).GetMethod(nameof(SoftFloat64_16.FPConvert)), ne); + context.LoadFromContext(); res = context.ZeroExtend16(OperandType.I64, res); @@ -143,7 +149,9 @@ namespace ARMeilleure.Instructions { Operand ne = EmitVectorExtractZx(context, op.Rn, 0, 1); + context.StoreToContext(); Operand res = context.Call(typeof(SoftFloat16_64).GetMethod(nameof(SoftFloat16_64.FPConvert)), ne); + context.LoadFromContext(); context.Copy(GetVec(op.Rd), context.VectorInsert(context.VectorZero(), res, 0)); } @@ -224,7 +232,9 @@ namespace ARMeilleure.Instructions { Operand ne = EmitVectorExtractZx(context, op.Rn, part + index, 1); + context.StoreToContext(); Operand e = context.Call(typeof(SoftFloat16_32).GetMethod(nameof(SoftFloat16_32.FPConvert)), ne); + context.LoadFromContext(); res = context.VectorInsert(res, e, index); } @@ -333,7 +343,9 @@ namespace ARMeilleure.Instructions if (sizeF == 0) { + context.StoreToContext(); Operand e = context.Call(typeof(SoftFloat32_16).GetMethod(nameof(SoftFloat32_16.FPConvert)), ne); + context.LoadFromContext(); e = context.ZeroExtend16(OperandType.I64, e); diff --git a/ARMeilleure/Instructions/InstEmitSimdCvt32.cs b/ARMeilleure/Instructions/InstEmitSimdCvt32.cs index b06ddd5e7..69ba42747 100644 --- a/ARMeilleure/Instructions/InstEmitSimdCvt32.cs +++ b/ARMeilleure/Instructions/InstEmitSimdCvt32.cs @@ -161,34 +161,15 @@ namespace ARMeilleure.Instructions { Operand toConvert = ExtractScalar(context, floatSize, op.Vm); - Operand asInteger; - // TODO: Fast Path. if (roundWithFpscr) { - MethodInfo info; - - if (floatSize == OperandType.FP64) - { - info = unsigned - ? typeof(SoftFallback).GetMethod(nameof(SoftFallback.DoubleToUInt32)) - : typeof(SoftFallback).GetMethod(nameof(SoftFallback.DoubleToInt32)); - } - else - { - info = unsigned - ? typeof(SoftFallback).GetMethod(nameof(SoftFallback.FloatToUInt32)) - : typeof(SoftFallback).GetMethod(nameof(SoftFallback.FloatToInt32)); - } - - asInteger = context.Call(info, toConvert); - } - else - { - // Round towards zero. - asInteger = EmitSaturateFloatToInt(context, toConvert, unsigned); + toConvert = EmitRoundByRMode(context, toConvert); } + // Round towards zero. + Operand asInteger = EmitSaturateFloatToInt(context, toConvert, unsigned); + InsertScalar(context, op.Vd, asInteger); } } @@ -271,9 +252,7 @@ namespace ARMeilleure.Instructions break; } - Operand asInteger; - - asInteger = EmitSaturateFloatToInt(context, toConvert, unsigned); + Operand asInteger = EmitSaturateFloatToInt(context, toConvert, unsigned); InsertScalar(context, op.Vd, asInteger); } @@ -399,15 +378,9 @@ namespace ARMeilleure.Instructions // VRINTX (floating-point). public static void Vrintx_S(ArmEmitterContext context) { - OpCode32SimdS op = (OpCode32SimdS)context.CurrOp; - - bool doubleSize = (op.Size & 1) == 1; - string methodName = doubleSize ? nameof(SoftFallback.Round) : nameof(SoftFallback.RoundF); - EmitScalarUnaryOpF32(context, (op1) => { - MethodInfo info = typeof(SoftFallback).GetMethod(methodName); - return context.Call(info, op1); + return EmitRoundByRMode(context, op1); }); } diff --git a/ARMeilleure/Instructions/InstEmitSimdHelper.cs b/ARMeilleure/Instructions/InstEmitSimdHelper.cs index 80dfc6889..49c9e6879 100644 --- a/ARMeilleure/Instructions/InstEmitSimdHelper.cs +++ b/ARMeilleure/Instructions/InstEmitSimdHelper.cs @@ -361,6 +361,54 @@ namespace ARMeilleure.Instructions return context.Call(info, n, Const((int)roundMode)); } + public static Operand EmitGetRoundingMode(ArmEmitterContext context) + { + Operand rMode = context.ShiftLeft(GetFpFlag(FPState.RMode1Flag), Const(1)); + rMode = context.BitwiseOr(rMode, GetFpFlag(FPState.RMode0Flag)); + + return rMode; + } + + public static Operand EmitRoundByRMode(ArmEmitterContext context, Operand op) + { + Debug.Assert(op.Type == OperandType.FP32 || op.Type == OperandType.FP64); + + Operand lbl1 = Label(); + Operand lbl2 = Label(); + Operand lbl3 = Label(); + Operand lblEnd = Label(); + + Operand rN = Const((int)FPRoundingMode.ToNearest); + Operand rP = Const((int)FPRoundingMode.TowardsPlusInfinity); + Operand rM = Const((int)FPRoundingMode.TowardsMinusInfinity); + + Operand res = context.AllocateLocal(op.Type); + + Operand rMode = EmitGetRoundingMode(context); + + context.BranchIf(lbl1, rMode, rN, Comparison.NotEqual); + context.Copy(res, EmitRoundMathCall(context, MidpointRounding.ToEven, op)); + context.Branch(lblEnd); + + context.MarkLabel(lbl1); + context.BranchIf(lbl2, rMode, rP, Comparison.NotEqual); + context.Copy(res, EmitUnaryMathCall(context, nameof(Math.Ceiling), op)); + context.Branch(lblEnd); + + context.MarkLabel(lbl2); + context.BranchIf(lbl3, rMode, rM, Comparison.NotEqual); + context.Copy(res, EmitUnaryMathCall(context, nameof(Math.Floor), op)); + context.Branch(lblEnd); + + context.MarkLabel(lbl3); + context.Copy(res, EmitUnaryMathCall(context, nameof(Math.Truncate), op)); + context.Branch(lblEnd); + + context.MarkLabel(lblEnd); + + return res; + } + public static Operand EmitSoftFloatCall(ArmEmitterContext context, string name, params Operand[] callArgs) { IOpCodeSimd op = (IOpCodeSimd)context.CurrOp; @@ -369,7 +417,11 @@ namespace ARMeilleure.Instructions ? typeof(SoftFloat32).GetMethod(name) : typeof(SoftFloat64).GetMethod(name); - return context.Call(info, callArgs); + context.StoreToContext(); + Operand res = context.Call(info, callArgs); + context.LoadFromContext(); + + return res; } public static void EmitScalarBinaryOpByElemF(ArmEmitterContext context, Func2I emit) @@ -1269,7 +1321,7 @@ namespace ARMeilleure.Instructions public static void EmitSseOrAvxEnterFtzAndDazModesOpF(ArmEmitterContext context, out Operand isTrue) { - isTrue = context.Call(typeof(NativeInterface).GetMethod(nameof(NativeInterface.GetFpcrFz))); + isTrue = GetFpFlag(FPState.FzFlag); Operand lblTrue = Label(); context.BranchIfFalse(lblTrue, isTrue); @@ -1281,9 +1333,7 @@ namespace ARMeilleure.Instructions public static void EmitSseOrAvxExitFtzAndDazModesOpF(ArmEmitterContext context, Operand isTrue = default) { - isTrue = isTrue == default - ? context.Call(typeof(NativeInterface).GetMethod(nameof(NativeInterface.GetFpcrFz))) - : isTrue; + isTrue = isTrue == default ? GetFpFlag(FPState.FzFlag) : isTrue; Operand lblTrue = Label(); context.BranchIfFalse(lblTrue, isTrue); @@ -1552,13 +1602,13 @@ namespace ARMeilleure.Instructions context.BranchIf(lbl1, op, zeroL, Comparison.LessOrEqual); context.Copy(res, maxT); - context.Call(typeof(NativeInterface).GetMethod(nameof(NativeInterface.SetFpsrQc))); + SetFpFlag(context, FPState.QcFlag, Const(1)); context.Branch(lblEnd); context.MarkLabel(lbl1); context.BranchIf(lblEnd, op, zeroL, Comparison.GreaterOrEqual); context.Copy(res, minT); - context.Call(typeof(NativeInterface).GetMethod(nameof(NativeInterface.SetFpsrQc))); + SetFpFlag(context, FPState.QcFlag, Const(1)); context.Branch(lblEnd); context.MarkLabel(lblEnd); @@ -1583,7 +1633,7 @@ namespace ARMeilleure.Instructions context.BranchIf(lblEnd, op, zeroUL, Comparison.LessOrEqualUI); context.Copy(res, maxT); - context.Call(typeof(NativeInterface).GetMethod(nameof(NativeInterface.SetFpsrQc))); + SetFpFlag(context, FPState.QcFlag, Const(1)); context.Branch(lblEnd); context.MarkLabel(lblEnd); @@ -1610,13 +1660,13 @@ namespace ARMeilleure.Instructions context.BranchIf(lbl1, op, maxT, Comparison.LessOrEqual); context.Copy(res, maxT); - context.Call(typeof(NativeInterface).GetMethod(nameof(NativeInterface.SetFpsrQc))); + SetFpFlag(context, FPState.QcFlag, Const(1)); context.Branch(lblEnd); context.MarkLabel(lbl1); context.BranchIf(lblEnd, op, minT, Comparison.GreaterOrEqual); context.Copy(res, minT); - context.Call(typeof(NativeInterface).GetMethod(nameof(NativeInterface.SetFpsrQc))); + SetFpFlag(context, FPState.QcFlag, Const(1)); context.Branch(lblEnd); context.MarkLabel(lblEnd); @@ -1641,7 +1691,7 @@ namespace ARMeilleure.Instructions context.BranchIf(lblEnd, op, maxT, Comparison.LessOrEqualUI); context.Copy(res, maxT); - context.Call(typeof(NativeInterface).GetMethod(nameof(NativeInterface.SetFpsrQc))); + SetFpFlag(context, FPState.QcFlag, Const(1)); context.Branch(lblEnd); context.MarkLabel(lblEnd); @@ -1663,7 +1713,7 @@ namespace ARMeilleure.Instructions context.BranchIf(lblEnd, op, minL, Comparison.NotEqual); context.Copy(res, maxL); - context.Call(typeof(NativeInterface).GetMethod(nameof(NativeInterface.SetFpsrQc))); + SetFpFlag(context, FPState.QcFlag, Const(1)); context.Branch(lblEnd); context.MarkLabel(lblEnd); @@ -1691,7 +1741,7 @@ namespace ARMeilleure.Instructions Operand isPositive = context.ICompareGreaterOrEqual(op1, zeroL); context.Copy(res, context.ConditionalSelect(isPositive, maxL, minL)); - context.Call(typeof(NativeInterface).GetMethod(nameof(NativeInterface.SetFpsrQc))); + SetFpFlag(context, FPState.QcFlag, Const(1)); context.Branch(lblEnd); context.MarkLabel(lblEnd); @@ -1713,7 +1763,7 @@ namespace ARMeilleure.Instructions context.BranchIf(lblEnd, add, op1, Comparison.GreaterOrEqualUI); context.Copy(res, maxUL); - context.Call(typeof(NativeInterface).GetMethod(nameof(NativeInterface.SetFpsrQc))); + SetFpFlag(context, FPState.QcFlag, Const(1)); context.Branch(lblEnd); context.MarkLabel(lblEnd); @@ -1741,7 +1791,7 @@ namespace ARMeilleure.Instructions Operand isPositive = context.ICompareGreaterOrEqual(op1, zeroL); context.Copy(res, context.ConditionalSelect(isPositive, maxL, minL)); - context.Call(typeof(NativeInterface).GetMethod(nameof(NativeInterface.SetFpsrQc))); + SetFpFlag(context, FPState.QcFlag, Const(1)); context.Branch(lblEnd); context.MarkLabel(lblEnd); @@ -1763,7 +1813,7 @@ namespace ARMeilleure.Instructions context.BranchIf(lblEnd, op1, op2, Comparison.GreaterOrEqualUI); context.Copy(res, zeroL); - context.Call(typeof(NativeInterface).GetMethod(nameof(NativeInterface.SetFpsrQc))); + SetFpFlag(context, FPState.QcFlag, Const(1)); context.Branch(lblEnd); context.MarkLabel(lblEnd); @@ -1790,19 +1840,19 @@ namespace ARMeilleure.Instructions Operand notOp2AndRes = context.BitwiseAnd(context.BitwiseNot(op2), add); context.BranchIf(lblEnd, notOp2AndRes, zeroL, Comparison.GreaterOrEqual); context.Copy(res, maxL); - context.Call(typeof(NativeInterface).GetMethod(nameof(NativeInterface.SetFpsrQc))); + SetFpFlag(context, FPState.QcFlag, Const(1)); context.Branch(lblEnd); context.MarkLabel(lbl1); context.BranchIf(lbl2, op2, zeroL, Comparison.Less); context.Copy(res, maxL); - context.Call(typeof(NativeInterface).GetMethod(nameof(NativeInterface.SetFpsrQc))); + SetFpFlag(context, FPState.QcFlag, Const(1)); context.Branch(lblEnd); context.MarkLabel(lbl2); context.BranchIf(lblEnd, add, maxL, Comparison.LessOrEqualUI); context.Copy(res, maxL); - context.Call(typeof(NativeInterface).GetMethod(nameof(NativeInterface.SetFpsrQc))); + SetFpFlag(context, FPState.QcFlag, Const(1)); context.Branch(lblEnd); context.MarkLabel(lblEnd); @@ -1828,14 +1878,14 @@ namespace ARMeilleure.Instructions context.BranchIf(lbl1, op1, zeroL, Comparison.Less); context.BranchIf(lblEnd, add, op1, Comparison.GreaterOrEqualUI); context.Copy(res, maxUL); - context.Call(typeof(NativeInterface).GetMethod(nameof(NativeInterface.SetFpsrQc))); + SetFpFlag(context, FPState.QcFlag, Const(1)); context.Branch(lblEnd); context.MarkLabel(lbl1); context.BranchIf(lblEnd, op2, maxL, Comparison.GreaterUI); context.BranchIf(lblEnd, add, zeroL, Comparison.GreaterOrEqual); context.Copy(res, zeroL); - context.Call(typeof(NativeInterface).GetMethod(nameof(NativeInterface.SetFpsrQc))); + SetFpFlag(context, FPState.QcFlag, Const(1)); context.Branch(lblEnd); context.MarkLabel(lblEnd); diff --git a/ARMeilleure/Instructions/InstEmitSimdHelper32.cs b/ARMeilleure/Instructions/InstEmitSimdHelper32.cs index c530985fa..0620ea332 100644 --- a/ARMeilleure/Instructions/InstEmitSimdHelper32.cs +++ b/ARMeilleure/Instructions/InstEmitSimdHelper32.cs @@ -1181,7 +1181,11 @@ namespace ARMeilleure.Instructions Array.Resize(ref callArgs, callArgs.Length + 1); callArgs[callArgs.Length - 1] = Const(1); - return context.Call(info, callArgs); + context.StoreToContext(); + Operand res = context.Call(info, callArgs); + context.LoadFromContext(); + + return res; } public static Operand EmitVectorExtractSx32(ArmEmitterContext context, int reg, int index, int size) diff --git a/ARMeilleure/Instructions/InstEmitSimdShift32.cs b/ARMeilleure/Instructions/InstEmitSimdShift32.cs index e0968b7b1..9ac680884 100644 --- a/ARMeilleure/Instructions/InstEmitSimdShift32.cs +++ b/ARMeilleure/Instructions/InstEmitSimdShift32.cs @@ -1,5 +1,6 @@ using ARMeilleure.Decoders; using ARMeilleure.IntermediateRepresentation; +using ARMeilleure.State; using ARMeilleure.Translation; using System; using System.Diagnostics; @@ -378,7 +379,7 @@ namespace ARMeilleure.Instructions context.BranchIfFalse(lblNoSat, context.BitwiseOr(gt, lt)); - context.Call(typeof(NativeInterface).GetMethod(nameof(NativeInterface.SetFpsrQc))); + SetFpFlag(context, FPState.QcFlag, Const(1)); context.MarkLabel(lblNoSat); diff --git a/ARMeilleure/Instructions/InstEmitSystem.cs b/ARMeilleure/Instructions/InstEmitSystem.cs index cdfaa26ec..cc32228c3 100644 --- a/ARMeilleure/Instructions/InstEmitSystem.cs +++ b/ARMeilleure/Instructions/InstEmitSystem.cs @@ -31,8 +31,8 @@ namespace ARMeilleure.Instructions case 0b11_011_0000_0000_001: info = typeof(NativeInterface).GetMethod(nameof(NativeInterface.GetCtrEl0)); break; case 0b11_011_0000_0000_111: info = typeof(NativeInterface).GetMethod(nameof(NativeInterface.GetDczidEl0)); break; case 0b11_011_0100_0010_000: EmitGetNzcv(context); return; - case 0b11_011_0100_0100_000: info = typeof(NativeInterface).GetMethod(nameof(NativeInterface.GetFpcr)); break; - case 0b11_011_0100_0100_001: info = typeof(NativeInterface).GetMethod(nameof(NativeInterface.GetFpsr)); break; + case 0b11_011_0100_0100_000: EmitGetFpcr(context); return; + case 0b11_011_0100_0100_001: EmitGetFpsr(context); return; case 0b11_011_1101_0000_010: info = typeof(NativeInterface).GetMethod(nameof(NativeInterface.GetTpidrEl0)); break; case 0b11_011_1101_0000_011: info = typeof(NativeInterface).GetMethod(nameof(NativeInterface.GetTpidrroEl0)); break; case 0b11_011_1110_0000_000: info = typeof(NativeInterface).GetMethod(nameof(NativeInterface.GetCntfrqEl0)); break; @@ -53,9 +53,9 @@ namespace ARMeilleure.Instructions switch (GetPackedId(op)) { - case 0b11_011_0100_0010_000: EmitSetNzcv(context); return; - case 0b11_011_0100_0100_000: info = typeof(NativeInterface).GetMethod(nameof(NativeInterface.SetFpcr)); break; - case 0b11_011_0100_0100_001: info = typeof(NativeInterface).GetMethod(nameof(NativeInterface.SetFpsr)); break; + case 0b11_011_0100_0010_000: EmitSetNzcv(context); return; + case 0b11_011_0100_0100_000: EmitSetFpcr(context); return; + case 0b11_011_0100_0100_001: EmitSetFpsr(context); return; case 0b11_011_1101_0000_010: info = typeof(NativeInterface).GetMethod(nameof(NativeInterface.SetTpidrEl0)); break; default: throw new NotImplementedException($"Unknown MSR 0x{op.RawOpCode:X8} at 0x{op.Address:X16}."); @@ -121,39 +121,91 @@ namespace ARMeilleure.Instructions { OpCodeSystem op = (OpCodeSystem)context.CurrOp; - Operand vSh = context.ShiftLeft(GetFlag(PState.VFlag), Const((int)PState.VFlag)); - Operand cSh = context.ShiftLeft(GetFlag(PState.CFlag), Const((int)PState.CFlag)); - Operand zSh = context.ShiftLeft(GetFlag(PState.ZFlag), Const((int)PState.ZFlag)); - Operand nSh = context.ShiftLeft(GetFlag(PState.NFlag), Const((int)PState.NFlag)); + Operand nzcv = context.ShiftLeft(GetFlag(PState.VFlag), Const((int)PState.VFlag)); + nzcv = context.BitwiseOr(nzcv, context.ShiftLeft(GetFlag(PState.CFlag), Const((int)PState.CFlag))); + nzcv = context.BitwiseOr(nzcv, context.ShiftLeft(GetFlag(PState.ZFlag), Const((int)PState.ZFlag))); + nzcv = context.BitwiseOr(nzcv, context.ShiftLeft(GetFlag(PState.NFlag), Const((int)PState.NFlag))); - Operand nzcvSh = context.BitwiseOr(context.BitwiseOr(nSh, zSh), context.BitwiseOr(cSh, vSh)); + SetIntOrZR(context, op.Rt, nzcv); + } - SetIntOrZR(context, op.Rt, nzcvSh); + private static void EmitGetFpcr(ArmEmitterContext context) + { + OpCodeSystem op = (OpCodeSystem)context.CurrOp; + + Operand fpcr = Const(0); + + for (int flag = 0; flag < RegisterConsts.FpFlagsCount; flag++) + { + if (FPCR.Mask.HasFlag((FPCR)(1u << flag))) + { + fpcr = context.BitwiseOr(fpcr, context.ShiftLeft(GetFpFlag((FPState)flag), Const(flag))); + } + } + + SetIntOrZR(context, op.Rt, fpcr); + } + + private static void EmitGetFpsr(ArmEmitterContext context) + { + OpCodeSystem op = (OpCodeSystem)context.CurrOp; + + Operand fpsr = Const(0); + + for (int flag = 0; flag < RegisterConsts.FpFlagsCount; flag++) + { + if (FPSR.Mask.HasFlag((FPSR)(1u << flag))) + { + fpsr = context.BitwiseOr(fpsr, context.ShiftLeft(GetFpFlag((FPState)flag), Const(flag))); + } + } + + SetIntOrZR(context, op.Rt, fpsr); } private static void EmitSetNzcv(ArmEmitterContext context) { OpCodeSystem op = (OpCodeSystem)context.CurrOp; - Operand t = GetIntOrZR(context, op.Rt); - t = context.ConvertI64ToI32(t); + Operand nzcv = GetIntOrZR(context, op.Rt); + nzcv = context.ConvertI64ToI32(nzcv); - Operand v = context.ShiftRightUI(t, Const((int)PState.VFlag)); - v = context.BitwiseAnd (v, Const(1)); + SetFlag(context, PState.VFlag, context.BitwiseAnd(context.ShiftRightUI(nzcv, Const((int)PState.VFlag)), Const(1))); + SetFlag(context, PState.CFlag, context.BitwiseAnd(context.ShiftRightUI(nzcv, Const((int)PState.CFlag)), Const(1))); + SetFlag(context, PState.ZFlag, context.BitwiseAnd(context.ShiftRightUI(nzcv, Const((int)PState.ZFlag)), Const(1))); + SetFlag(context, PState.NFlag, context.BitwiseAnd(context.ShiftRightUI(nzcv, Const((int)PState.NFlag)), Const(1))); + } - Operand c = context.ShiftRightUI(t, Const((int)PState.CFlag)); - c = context.BitwiseAnd (c, Const(1)); + private static void EmitSetFpcr(ArmEmitterContext context) + { + OpCodeSystem op = (OpCodeSystem)context.CurrOp; - Operand z = context.ShiftRightUI(t, Const((int)PState.ZFlag)); - z = context.BitwiseAnd (z, Const(1)); + Operand fpcr = GetIntOrZR(context, op.Rt); + fpcr = context.ConvertI64ToI32(fpcr); - Operand n = context.ShiftRightUI(t, Const((int)PState.NFlag)); - n = context.BitwiseAnd (n, Const(1)); + for (int flag = 0; flag < RegisterConsts.FpFlagsCount; flag++) + { + if (FPCR.Mask.HasFlag((FPCR)(1u << flag))) + { + SetFpFlag(context, (FPState)flag, context.BitwiseAnd(context.ShiftRightUI(fpcr, Const(flag)), Const(1))); + } + } + } - SetFlag(context, PState.VFlag, v); - SetFlag(context, PState.CFlag, c); - SetFlag(context, PState.ZFlag, z); - SetFlag(context, PState.NFlag, n); + private static void EmitSetFpsr(ArmEmitterContext context) + { + OpCodeSystem op = (OpCodeSystem)context.CurrOp; + + Operand fpsr = GetIntOrZR(context, op.Rt); + fpsr = context.ConvertI64ToI32(fpsr); + + for (int flag = 0; flag < RegisterConsts.FpFlagsCount; flag++) + { + if (FPSR.Mask.HasFlag((FPSR)(1u << flag))) + { + SetFpFlag(context, (FPState)flag, context.BitwiseAnd(context.ShiftRightUI(fpsr, Const(flag)), Const(1))); + } + } } } } diff --git a/ARMeilleure/Instructions/InstEmitSystem32.cs b/ARMeilleure/Instructions/InstEmitSystem32.cs index acd17045f..e07db4121 100644 --- a/ARMeilleure/Instructions/InstEmitSystem32.cs +++ b/ARMeilleure/Instructions/InstEmitSystem32.cs @@ -169,14 +169,11 @@ namespace ARMeilleure.Instructions } else { - Operand vSh = context.ShiftLeft(GetFlag(PState.VFlag), Const((int)PState.VFlag)); - Operand cSh = context.ShiftLeft(GetFlag(PState.CFlag), Const((int)PState.CFlag)); - Operand zSh = context.ShiftLeft(GetFlag(PState.ZFlag), Const((int)PState.ZFlag)); - Operand nSh = context.ShiftLeft(GetFlag(PState.NFlag), Const((int)PState.NFlag)); - Operand qSh = context.ShiftLeft(GetFlag(PState.QFlag), Const((int)PState.QFlag)); - - Operand spsr = context.BitwiseOr(context.BitwiseOr(nSh, zSh), context.BitwiseOr(cSh, vSh)); - spsr = context.BitwiseOr(spsr, qSh); + Operand spsr = context.ShiftLeft(GetFlag(PState.VFlag), Const((int)PState.VFlag)); + spsr = context.BitwiseOr(spsr, context.ShiftLeft(GetFlag(PState.CFlag), Const((int)PState.CFlag))); + spsr = context.BitwiseOr(spsr, context.ShiftLeft(GetFlag(PState.ZFlag), Const((int)PState.ZFlag))); + spsr = context.BitwiseOr(spsr, context.ShiftLeft(GetFlag(PState.NFlag), Const((int)PState.NFlag))); + spsr = context.BitwiseOr(spsr, context.ShiftLeft(GetFlag(PState.QFlag), Const((int)PState.QFlag))); // TODO: Remaining flags. @@ -200,8 +197,7 @@ namespace ARMeilleure.Instructions EmitSetNzcv(context, value); - Operand q = context.ShiftRightUI(value, Const((int)PState.QFlag)); - q = context.BitwiseAnd(q, Const(1)); + Operand q = context.BitwiseAnd(context.ShiftRightUI(value, Const((int)PState.QFlag)), Const(1)); SetFlag(context, PState.QFlag, q); } @@ -284,17 +280,10 @@ namespace ARMeilleure.Instructions private static void EmitSetNzcv(ArmEmitterContext context, Operand t) { - Operand v = context.ShiftRightUI(t, Const((int)PState.VFlag)); - v = context.BitwiseAnd(v, Const(1)); - - Operand c = context.ShiftRightUI(t, Const((int)PState.CFlag)); - c = context.BitwiseAnd(c, Const(1)); - - Operand z = context.ShiftRightUI(t, Const((int)PState.ZFlag)); - z = context.BitwiseAnd(z, Const(1)); - - Operand n = context.ShiftRightUI(t, Const((int)PState.NFlag)); - n = context.BitwiseAnd(n, Const(1)); + Operand v = context.BitwiseAnd(context.ShiftRightUI(t, Const((int)PState.VFlag)), Const(1)); + Operand c = context.BitwiseAnd(context.ShiftRightUI(t, Const((int)PState.CFlag)), Const(1)); + Operand z = context.BitwiseAnd(context.ShiftRightUI(t, Const((int)PState.ZFlag)), Const(1)); + Operand n = context.BitwiseAnd(context.ShiftRightUI(t, Const((int)PState.NFlag)), Const(1)); SetFlag(context, PState.VFlag, v); SetFlag(context, PState.CFlag, c); @@ -306,42 +295,32 @@ namespace ARMeilleure.Instructions { OpCode32SimdSpecial op = (OpCode32SimdSpecial)context.CurrOp; - Operand vSh = context.ShiftLeft(GetFpFlag(FPState.VFlag), Const((int)FPState.VFlag)); - Operand cSh = context.ShiftLeft(GetFpFlag(FPState.CFlag), Const((int)FPState.CFlag)); - Operand zSh = context.ShiftLeft(GetFpFlag(FPState.ZFlag), Const((int)FPState.ZFlag)); - Operand nSh = context.ShiftLeft(GetFpFlag(FPState.NFlag), Const((int)FPState.NFlag)); + Operand fpscr = Const(0); - Operand nzcvSh = context.BitwiseOr(context.BitwiseOr(nSh, zSh), context.BitwiseOr(cSh, vSh)); + for (int flag = 0; flag < RegisterConsts.FpFlagsCount; flag++) + { + if (FPSCR.Mask.HasFlag((FPSCR)(1u << flag))) + { + fpscr = context.BitwiseOr(fpscr, context.ShiftLeft(GetFpFlag((FPState)flag), Const(flag))); + } + } - Operand fpscr = context.Call(typeof(NativeInterface).GetMethod(nameof(NativeInterface.GetFpscr))); - - SetIntA32(context, op.Rt, context.BitwiseOr(nzcvSh, fpscr)); + SetIntA32(context, op.Rt, fpscr); } private static void EmitSetFpscr(ArmEmitterContext context) { OpCode32SimdSpecial op = (OpCode32SimdSpecial)context.CurrOp; - Operand t = GetIntA32(context, op.Rt); + Operand fpscr = GetIntA32(context, op.Rt); - Operand v = context.ShiftRightUI(t, Const((int)FPState.VFlag)); - v = context.BitwiseAnd(v, Const(1)); - - Operand c = context.ShiftRightUI(t, Const((int)FPState.CFlag)); - c = context.BitwiseAnd(c, Const(1)); - - Operand z = context.ShiftRightUI(t, Const((int)FPState.ZFlag)); - z = context.BitwiseAnd(z, Const(1)); - - Operand n = context.ShiftRightUI(t, Const((int)FPState.NFlag)); - n = context.BitwiseAnd(n, Const(1)); - - SetFpFlag(context, FPState.VFlag, v); - SetFpFlag(context, FPState.CFlag, c); - SetFpFlag(context, FPState.ZFlag, z); - SetFpFlag(context, FPState.NFlag, n); - - context.Call(typeof(NativeInterface).GetMethod(nameof(NativeInterface.SetFpscr)), t); + for (int flag = 0; flag < RegisterConsts.FpFlagsCount; flag++) + { + if (FPSCR.Mask.HasFlag((FPSCR)(1u << flag))) + { + SetFpFlag(context, (FPState)flag, context.BitwiseAnd(context.ShiftRightUI(fpscr, Const(flag)), Const(1))); + } + } } } } diff --git a/ARMeilleure/Instructions/NativeInterface.cs b/ARMeilleure/Instructions/NativeInterface.cs index ca4133ada..2ac748a9a 100644 --- a/ARMeilleure/Instructions/NativeInterface.cs +++ b/ARMeilleure/Instructions/NativeInterface.cs @@ -72,29 +72,6 @@ namespace ARMeilleure.Instructions return (ulong)GetContext().DczidEl0; } - public static ulong GetFpcr() - { - return (ulong)GetContext().Fpcr; - } - - public static bool GetFpcrFz() - { - return (GetContext().Fpcr & FPCR.Fz) != 0; - } - - public static ulong GetFpsr() - { - return (ulong)GetContext().Fpsr; - } - - public static uint GetFpscr() - { - ExecutionContext context = GetContext(); - - return (uint)(context.Fpsr & FPSR.A32Mask & ~FPSR.Nzcv) | - (uint)(context.Fpcr & FPCR.A32Mask); - } - public static ulong GetTpidrEl0() { return (ulong)GetContext().TpidrEl0; @@ -130,29 +107,6 @@ namespace ARMeilleure.Instructions return GetContext().CntvctEl0; } - public static void SetFpcr(ulong value) - { - GetContext().Fpcr = (FPCR)value; - } - - public static void SetFpsr(ulong value) - { - GetContext().Fpsr = (FPSR)value; - } - - public static void SetFpsrQc() - { - GetContext().Fpsr |= FPSR.Qc; - } - - public static void SetFpscr(uint fpscr) - { - ExecutionContext context = GetContext(); - - context.Fpsr = FPSR.A32Mask & (FPSR)fpscr; - context.Fpcr = FPCR.A32Mask & (FPCR)fpscr; - } - public static void SetTpidrEl0(ulong value) { GetContext().TpidrEl0 = (long)value; diff --git a/ARMeilleure/Instructions/SoftFallback.cs b/ARMeilleure/Instructions/SoftFallback.cs index d5e1ab65d..06d76a67c 100644 --- a/ARMeilleure/Instructions/SoftFallback.cs +++ b/ARMeilleure/Instructions/SoftFallback.cs @@ -91,76 +91,6 @@ namespace ARMeilleure.Instructions } #endregion -#region "Rounding" - public static double Round(double value) - { - ExecutionContext context = NativeInterface.GetContext(); - - FPRoundingMode roundMode = context.Fpcr.GetRoundingMode(); - - if (roundMode == FPRoundingMode.ToNearest) - { - return Math.Round(value); // even - } - else if (roundMode == FPRoundingMode.TowardsPlusInfinity) - { - return Math.Ceiling(value); - } - else if (roundMode == FPRoundingMode.TowardsMinusInfinity) - { - return Math.Floor(value); - } - else /* if (roundMode == FPRoundingMode.TowardsZero) */ - { - return Math.Truncate(value); - } - } - - public static float RoundF(float value) - { - ExecutionContext context = NativeInterface.GetContext(); - - FPRoundingMode roundMode = context.Fpcr.GetRoundingMode(); - - if (roundMode == FPRoundingMode.ToNearest) - { - return MathF.Round(value); // even - } - else if (roundMode == FPRoundingMode.TowardsPlusInfinity) - { - return MathF.Ceiling(value); - } - else if (roundMode == FPRoundingMode.TowardsMinusInfinity) - { - return MathF.Floor(value); - } - else /* if (roundMode == FPRoundingMode.TowardsZero) */ - { - return MathF.Truncate(value); - } - } - - public static int FloatToInt32(float value) - { - return SatF32ToS32(RoundF(value)); - } - - public static int DoubleToInt32(double value) - { - return SatF64ToS32(Round(value)); - } - - public static uint FloatToUInt32(float value) - { - return SatF32ToU32(RoundF(value)); - } - - public static uint DoubleToUInt32(double value) - { - return SatF64ToU32(Round(value)); - } -#endregion - #region "Saturation" public static int SatF32ToS32(float value) { diff --git a/ARMeilleure/Instructions/SoftFloat.cs b/ARMeilleure/Instructions/SoftFloat.cs index a138f5df2..9e3db68d9 100644 --- a/ARMeilleure/Instructions/SoftFloat.cs +++ b/ARMeilleure/Instructions/SoftFloat.cs @@ -12,8 +12,8 @@ namespace ARMeilleure.Instructions RecipSqrtEstimateTable = BuildRecipSqrtEstimateTable(); } - internal static readonly byte[] RecipEstimateTable; - internal static readonly byte[] RecipSqrtEstimateTable; + public static readonly byte[] RecipEstimateTable; + public static readonly byte[] RecipSqrtEstimateTable; private static byte[] BuildRecipEstimateTable() { @@ -94,6 +94,13 @@ namespace ARMeilleure.Instructions context.Fpsr |= (FPSR)(1 << (int)exc); } } + + public static FPRoundingMode GetRoundingMode(this FPCR fpcr) + { + const int RModeShift = 22; + + return (FPRoundingMode)(((uint)fpcr >> RModeShift) & 3u); + } } static class SoftFloat16 diff --git a/ARMeilleure/State/ExecutionContext.cs b/ARMeilleure/State/ExecutionContext.cs index c73ca197d..5d18e6ed8 100644 --- a/ARMeilleure/State/ExecutionContext.cs +++ b/ARMeilleure/State/ExecutionContext.cs @@ -36,10 +36,25 @@ namespace ARMeilleure.State set => _nativeContext.SetPstate(value); } - public FPCR Fpcr { get; set; } - public FPSR Fpsr { get; set; } + public FPSR Fpsr + { + get => (FPSR)_nativeContext.GetFPState((uint)FPSR.Mask); + set => _nativeContext.SetFPState((uint)value, (uint)FPSR.Mask); + } + + public FPCR Fpcr + { + get => (FPCR)_nativeContext.GetFPState((uint)FPCR.Mask); + set => _nativeContext.SetFPState((uint)value, (uint)FPCR.Mask); + } public FPCR StandardFpcrValue => (Fpcr & (FPCR.Ahp)) | FPCR.Dn | FPCR.Fz; + public FPSCR Fpscr + { + get => (FPSCR)_nativeContext.GetFPState((uint)FPSCR.Mask); + set => _nativeContext.SetFPState((uint)value, (uint)FPSCR.Mask); + } + public bool IsAarch32 { get; set; } internal ExecutionMode ExecutionMode diff --git a/ARMeilleure/State/FPCR.cs b/ARMeilleure/State/FPCR.cs index 40d560455..6f707de7d 100644 --- a/ARMeilleure/State/FPCR.cs +++ b/ARMeilleure/State/FPCR.cs @@ -5,21 +5,18 @@ namespace ARMeilleure.State [Flags] public enum FPCR : uint { + Ioe = 1u << 8, + Dze = 1u << 9, + Ofe = 1u << 10, Ufe = 1u << 11, + Ixe = 1u << 12, + Ide = 1u << 15, + RMode0 = 1u << 22, + RMode1 = 1u << 23, Fz = 1u << 24, Dn = 1u << 25, Ahp = 1u << 26, - A32Mask = 0x07FF9F00u - } - - public static class FPCRExtensions - { - private const int RModeShift = 22; - - public static FPRoundingMode GetRoundingMode(this FPCR fpcr) - { - return (FPRoundingMode)(((int)fpcr >> RModeShift) & 3); - } + Mask = Ahp | Dn | Fz | RMode1 | RMode0 | Ide | Ixe | Ufe | Ofe | Dze | Ioe // 0x07C09F00u } } diff --git a/ARMeilleure/State/FPSCR.cs b/ARMeilleure/State/FPSCR.cs new file mode 100644 index 000000000..d6d2fc26a --- /dev/null +++ b/ARMeilleure/State/FPSCR.cs @@ -0,0 +1,15 @@ +using System; + +namespace ARMeilleure.State +{ + [Flags] + public enum FPSCR : uint + { + V = 1u << 28, + C = 1u << 29, + Z = 1u << 30, + N = 1u << 31, + + Mask = N | Z | C | V | FPSR.Mask | FPCR.Mask // 0xFFC09F9Fu + } +} diff --git a/ARMeilleure/State/FPSR.cs b/ARMeilleure/State/FPSR.cs index 800dcd10c..5e66d5ce1 100644 --- a/ARMeilleure/State/FPSR.cs +++ b/ARMeilleure/State/FPSR.cs @@ -5,11 +5,14 @@ namespace ARMeilleure.State [Flags] public enum FPSR : uint { + Ioc = 1u << 0, + Dzc = 1u << 1, + Ofc = 1u << 2, Ufc = 1u << 3, - Qc = 1u << 27, + Ixc = 1u << 4, + Idc = 1u << 7, + Qc = 1u << 27, - Nzcv = (1u << 31) | (1u << 30) | (1u << 29) | (1u << 28), - - A32Mask = 0xF800009Fu + Mask = Qc | Idc | Ixc | Ufc | Ofc | Dzc | Ioc // 0x0800009Fu } } diff --git a/ARMeilleure/State/FPState.cs b/ARMeilleure/State/FPState.cs index 60c7126c3..fa6ab9d46 100644 --- a/ARMeilleure/State/FPState.cs +++ b/ARMeilleure/State/FPState.cs @@ -2,9 +2,30 @@ { public enum FPState { + // FPSR Flags. + IocFlag = 0, + DzcFlag = 1, + OfcFlag = 2, + UfcFlag = 3, + IxcFlag = 4, + IdcFlag = 7, + QcFlag = 27, VFlag = 28, CFlag = 29, ZFlag = 30, - NFlag = 31 + NFlag = 31, + + // FPCR Flags. + IoeFlag = 8, + DzeFlag = 9, + OfeFlag = 10, + UfeFlag = 11, + IxeFlag = 12, + IdeFlag = 15, + RMode0Flag = 22, + RMode1Flag = 23, + FzFlag = 24, + DnFlag = 25, + AhpFlag = 26 } } diff --git a/ARMeilleure/State/NativeContext.cs b/ARMeilleure/State/NativeContext.cs index 11ab5ca3a..89e875d12 100644 --- a/ARMeilleure/State/NativeContext.cs +++ b/ARMeilleure/State/NativeContext.cs @@ -140,6 +140,34 @@ namespace ARMeilleure.State GetStorage().FpFlags[(int)flag] = value ? 1u : 0u; } + public unsafe uint GetFPState(uint mask = uint.MaxValue) + { + uint value = 0; + for (int flag = 0; flag < RegisterConsts.FpFlagsCount; flag++) + { + uint bit = 1u << flag; + + if ((mask & bit) == bit) + { + value |= GetStorage().FpFlags[flag] != 0 ? bit : 0u; + } + } + return value; + } + + public unsafe void SetFPState(uint value, uint mask = uint.MaxValue) + { + for (int flag = 0; flag < RegisterConsts.FpFlagsCount; flag++) + { + uint bit = 1u << flag; + + if ((mask & bit) == bit) + { + GetStorage().FpFlags[flag] = (value & bit) == bit ? 1u : 0u; + } + } + } + public int GetCounter() => GetStorage().Counter; public void SetCounter(int value) => GetStorage().Counter = value; diff --git a/ARMeilleure/Translation/Delegates.cs b/ARMeilleure/Translation/Delegates.cs index 0da69ebc3..fef1f4ef7 100644 --- a/ARMeilleure/Translation/Delegates.cs +++ b/ARMeilleure/Translation/Delegates.cs @@ -109,10 +109,6 @@ namespace ARMeilleure.Translation SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.GetCntvctEl0))); SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.GetCtrEl0))); SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.GetDczidEl0))); - SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.GetFpcr))); - SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.GetFpcrFz))); - SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.GetFpscr))); // A32 only. - SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.GetFpsr))); SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.GetFunctionAddress))); SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.InvalidateCacheLine))); SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.GetTpidrroEl0))); @@ -124,10 +120,6 @@ namespace ARMeilleure.Translation SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.ReadUInt32))); SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.ReadUInt64))); SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.ReadVector128))); - SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.SetFpcr))); - SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.SetFpscr))); // A32 only. - SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.SetFpsr))); - SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.SetFpsrQc))); SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.SetTpidrEl0))); SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.SetTpidrEl032))); // A32 only. SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.SignalMemoryTracking))); @@ -151,12 +143,8 @@ namespace ARMeilleure.Translation SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.Crc32w))); SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.Crc32x))); SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.Decrypt))); - SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.DoubleToInt32))); // A32 only. - SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.DoubleToUInt32))); // A32 only. SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.Encrypt))); SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.FixedRotate))); - SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.FloatToInt32))); // A32 only. - SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.FloatToUInt32))); // A32 only. SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.HashChoose))); SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.HashLower))); SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.HashMajority))); @@ -165,8 +153,6 @@ namespace ARMeilleure.Translation SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.InverseMixColumns))); SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.MixColumns))); SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.PolynomialMult64_128))); - SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.Round))); - SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.RoundF))); SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.SatF32ToS32))); SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.SatF32ToS64))); SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.SatF32ToU32))); diff --git a/ARMeilleure/Translation/PTC/Ptc.cs b/ARMeilleure/Translation/PTC/Ptc.cs index 01f089882..f4ae411b7 100644 --- a/ARMeilleure/Translation/PTC/Ptc.cs +++ b/ARMeilleure/Translation/PTC/Ptc.cs @@ -27,7 +27,7 @@ namespace ARMeilleure.Translation.PTC private const string OuterHeaderMagicString = "PTCohd\0\0"; private const string InnerHeaderMagicString = "PTCihd\0\0"; - private const uint InternalVersion = 3700; //! To be incremented manually for each change to the ARMeilleure project. + private const uint InternalVersion = 3703; //! To be incremented manually for each change to the ARMeilleure project. private const string ActualDir = "0"; private const string BackupDir = "1"; diff --git a/Ryujinx.Tests/Cpu/CpuTest32.cs b/Ryujinx.Tests/Cpu/CpuTest32.cs index be8df8dfc..aaf0ecfb6 100644 --- a/Ryujinx.Tests/Cpu/CpuTest32.cs +++ b/Ryujinx.Tests/Cpu/CpuTest32.cs @@ -162,7 +162,7 @@ namespace Ryujinx.Tests.Cpu _context.SetPstateFlag(PState.ZFlag, zero); _context.SetPstateFlag(PState.NFlag, negative); - SetFpscr((uint)fpscr); + _context.Fpscr = (FPSCR)fpscr; _context.SetPstateFlag(PState.TFlag, thumb); @@ -467,7 +467,7 @@ namespace Ryujinx.Tests.Cpu Assert.That(_context.GetPstateFlag(PState.NFlag), Is.EqualTo(_unicornEmu.NegativeFlag), "NFlag"); }); - Assert.That((int)GetFpscr() & (int)fpsrMask, Is.EqualTo(_unicornEmu.Fpscr & (int)fpsrMask), "Fpscr"); + Assert.That((int)_context.Fpscr & (int)fpsrMask, Is.EqualTo(_unicornEmu.Fpscr & (int)fpsrMask), "Fpscr"); if (_usingMemory) { @@ -650,28 +650,5 @@ namespace Ryujinx.Tests.Cpu return rnd & 0x800FFFFFFFFFFFFFul; } - - private uint GetFpscr() - { - uint fpscr = (uint)(_context.Fpsr & FPSR.A32Mask & ~FPSR.Nzcv) | (uint)(_context.Fpcr & FPCR.A32Mask); - - fpscr |= _context.GetFPstateFlag(FPState.NFlag) ? (1u << (int)FPState.NFlag) : 0; - fpscr |= _context.GetFPstateFlag(FPState.ZFlag) ? (1u << (int)FPState.ZFlag) : 0; - fpscr |= _context.GetFPstateFlag(FPState.CFlag) ? (1u << (int)FPState.CFlag) : 0; - fpscr |= _context.GetFPstateFlag(FPState.VFlag) ? (1u << (int)FPState.VFlag) : 0; - - return fpscr; - } - - private void SetFpscr(uint fpscr) - { - _context.Fpsr = FPSR.A32Mask & (FPSR)fpscr; - _context.Fpcr = FPCR.A32Mask & (FPCR)fpscr; - - _context.SetFPstateFlag(FPState.NFlag, (fpscr & (1u << (int)FPState.NFlag)) != 0); - _context.SetFPstateFlag(FPState.ZFlag, (fpscr & (1u << (int)FPState.ZFlag)) != 0); - _context.SetFPstateFlag(FPState.CFlag, (fpscr & (1u << (int)FPState.CFlag)) != 0); - _context.SetFPstateFlag(FPState.VFlag, (fpscr & (1u << (int)FPState.VFlag)) != 0); - } } } \ No newline at end of file