Add StandardFPSCRValue behaviour to compare instructions.

This commit is contained in:
riperiperi 2020-01-18 17:37:21 +00:00
parent 70a9e12e4e
commit 3d67259c9e
2 changed files with 95 additions and 60 deletions

View file

@ -16,7 +16,7 @@ namespace ARMeilleure.Instructions
{
public static void Vceq_V(ArmEmitterContext context)
{
EmitCmpOpF32(context, SoftFloat32.FPCompareEQ, SoftFloat64.FPCompareEQ, false);
EmitCmpOpF32(context, SoftFloat32.FPCompareEQFpscr, SoftFloat64.FPCompareEQFpscr, false);
}
public static void Vceq_I(ArmEmitterContext context)
@ -30,7 +30,7 @@ namespace ARMeilleure.Instructions
OpCode32Simd op = (OpCode32Simd)context.CurrOp;
if (op.F)
{
EmitCmpOpF32(context, SoftFloat32.FPCompareEQ, SoftFloat64.FPCompareEQ, true);
EmitCmpOpF32(context, SoftFloat32.FPCompareEQFpscr, SoftFloat64.FPCompareEQFpscr, true);
}
else
{
@ -40,7 +40,7 @@ namespace ARMeilleure.Instructions
public static void Vcge_V(ArmEmitterContext context)
{
EmitCmpOpF32(context, SoftFloat32.FPCompareGE, SoftFloat64.FPCompareGE, false);
EmitCmpOpF32(context, SoftFloat32.FPCompareGEFpscr, SoftFloat64.FPCompareGEFpscr, false);
}
public static void Vcge_I(ArmEmitterContext context)
@ -54,7 +54,7 @@ namespace ARMeilleure.Instructions
OpCode32Simd op = (OpCode32Simd)context.CurrOp;
if (op.F)
{
EmitCmpOpF32(context, SoftFloat32.FPCompareGE, SoftFloat64.FPCompareGE, true);
EmitCmpOpF32(context, SoftFloat32.FPCompareGEFpscr, SoftFloat64.FPCompareGEFpscr, true);
}
else
{
@ -64,7 +64,7 @@ namespace ARMeilleure.Instructions
public static void Vcgt_V(ArmEmitterContext context)
{
EmitCmpOpF32(context, SoftFloat32.FPCompareGT, SoftFloat64.FPCompareGT, false);
EmitCmpOpF32(context, SoftFloat32.FPCompareGTFpscr, SoftFloat64.FPCompareGTFpscr, false);
}
public static void Vcgt_I(ArmEmitterContext context)
@ -78,7 +78,7 @@ namespace ARMeilleure.Instructions
OpCode32Simd op = (OpCode32Simd)context.CurrOp;
if (op.F)
{
EmitCmpOpF32(context, SoftFloat32.FPCompareGT, SoftFloat64.FPCompareGT, true);
EmitCmpOpF32(context, SoftFloat32.FPCompareGTFpscr, SoftFloat64.FPCompareGTFpscr, true);
}
else
{
@ -86,23 +86,12 @@ namespace ARMeilleure.Instructions
}
}
public static void Vcle_V(ArmEmitterContext context)
{
EmitCmpOpF32(context, SoftFloat32.FPCompareLE, SoftFloat64.FPCompareLE, false);
}
public static void Vcle_I(ArmEmitterContext context)
{
OpCode32SimdReg op = (OpCode32SimdReg)context.CurrOp;
EmitCmpOpI32(context, context.ICompareLessOrEqual, context.ICompareLessOrEqualUI, false, !op.U);
}
public static void Vcle_Z(ArmEmitterContext context)
{
OpCode32Simd op = (OpCode32Simd)context.CurrOp;
if (op.F)
{
EmitCmpOpF32(context, SoftFloat32.FPCompareLE, SoftFloat64.FPCompareLE, true);
EmitCmpOpF32(context, SoftFloat32.FPCompareLEFpscr, SoftFloat64.FPCompareLEFpscr, true);
}
else
{
@ -110,23 +99,12 @@ namespace ARMeilleure.Instructions
}
}
public static void Vclt_V(ArmEmitterContext context)
{
EmitCmpOpF32(context, SoftFloat32.FPCompareLT, SoftFloat64.FPCompareLT, false);
}
public static void Vclt_I(ArmEmitterContext context)
{
OpCode32SimdReg op = (OpCode32SimdReg)context.CurrOp;
EmitCmpOpI32(context, context.ICompareLess, context.ICompareLessUI, false, !op.U);
}
public static void Vclt_Z(ArmEmitterContext context)
{
OpCode32Simd op = (OpCode32Simd)context.CurrOp;
if (op.F)
{
EmitCmpOpF32(context, SoftFloat32.FPCompareLT, SoftFloat64.FPCompareLT, true);
EmitCmpOpF32(context, SoftFloat32.FPCompareLTFpscr, SoftFloat64.FPCompareLTFpscr, true);
}
else
{
@ -136,18 +114,19 @@ namespace ARMeilleure.Instructions
private static void EmitCmpOpF32(
ArmEmitterContext context,
_F32_F32_F32 f32,
_F64_F64_F64 f64,
_F32_F32_F32_Bool f32,
_F64_F64_F64_Bool f64,
bool zero)
{
Operand one = Const(1);
if (zero)
{
EmitVectorUnaryOpF32(context, (m) =>
{
OperandType type = m.Type;
if (type == OperandType.FP64) return context.Call(f64, m, new Operand(0.0));
else return context.Call(f32, m, new Operand(0.0));
if (type == OperandType.FP64) return context.Call(f64, m, new Operand(0.0), one);
else return context.Call(f32, m, new Operand(0.0), one);
});
}
else
@ -156,8 +135,8 @@ namespace ARMeilleure.Instructions
{
OperandType type = n.Type;
if (type == OperandType.FP64) return context.Call(f64, n, m);
else return context.Call(f32, n, m);
if (type == OperandType.FP64) return context.Call(f64, n, m, one);
else return context.Call(f32, n, m, one);
});
}
}

View file

@ -708,10 +708,16 @@ namespace ARMeilleure.Instructions
public static float FPCompareEQ(float value1, float value2)
{
ExecutionContext context = NativeInterface.GetContext();
return FPCompareEQFpscr(value1, value2, false);
}
value1 = value1.FPUnpack(out FPType type1, out _, out _, context);
value2 = value2.FPUnpack(out FPType type2, out _, out _, context);
public static float FPCompareEQFpscr(float value1, float value2, bool standardFpscr)
{
ExecutionContext context = NativeInterface.GetContext();
FPCR fpcr = standardFpscr ? context.StandardFpcrValue : context.Fpcr;
value1 = value1.FPUnpack(out FPType type1, out _, out _, context, fpcr);
value2 = value2.FPUnpack(out FPType type2, out _, out _, context, fpcr);
float result;
@ -721,7 +727,7 @@ namespace ARMeilleure.Instructions
if (type1 == FPType.SNaN || type2 == FPType.SNaN)
{
FPProcessException(FPException.InvalidOp, context);
FPProcessException(FPException.InvalidOp, context, fpcr);
}
}
else
@ -734,10 +740,16 @@ namespace ARMeilleure.Instructions
public static float FPCompareGE(float value1, float value2)
{
ExecutionContext context = NativeInterface.GetContext();
return FPCompareGEFpscr(value1, value2, false);
}
value1 = value1.FPUnpack(out FPType type1, out _, out _, context);
value2 = value2.FPUnpack(out FPType type2, out _, out _, context);
public static float FPCompareGEFpscr(float value1, float value2, bool standardFpscr)
{
ExecutionContext context = NativeInterface.GetContext();
FPCR fpcr = standardFpscr ? context.StandardFpcrValue : context.Fpcr;
value1 = value1.FPUnpack(out FPType type1, out _, out _, context, fpcr);
value2 = value2.FPUnpack(out FPType type2, out _, out _, context, fpcr);
float result;
@ -745,7 +757,7 @@ namespace ARMeilleure.Instructions
{
result = ZerosOrOnes(false);
FPProcessException(FPException.InvalidOp, context);
FPProcessException(FPException.InvalidOp, context, fpcr);
}
else
{
@ -757,10 +769,16 @@ namespace ARMeilleure.Instructions
public static float FPCompareGT(float value1, float value2)
{
ExecutionContext context = NativeInterface.GetContext();
return FPCompareGTFpscr(value1, value2, false);
}
value1 = value1.FPUnpack(out FPType type1, out _, out _, context);
value2 = value2.FPUnpack(out FPType type2, out _, out _, context);
public static float FPCompareGTFpscr(float value1, float value2, bool standardFpscr)
{
ExecutionContext context = NativeInterface.GetContext();
FPCR fpcr = standardFpscr ? context.StandardFpcrValue : context.Fpcr;
value1 = value1.FPUnpack(out FPType type1, out _, out _, context, fpcr);
value2 = value2.FPUnpack(out FPType type2, out _, out _, context, fpcr);
float result;
@ -768,7 +786,7 @@ namespace ARMeilleure.Instructions
{
result = ZerosOrOnes(false);
FPProcessException(FPException.InvalidOp, context);
FPProcessException(FPException.InvalidOp, context, fpcr);
}
else
{
@ -788,6 +806,16 @@ namespace ARMeilleure.Instructions
return FPCompareGT(value2, value1);
}
public static float FPCompareLEFpscr(float value1, float value2, bool standardFpscr)
{
return FPCompareGEFpscr(value2, value1, standardFpscr);
}
public static float FPCompareLTFpscr(float value1, float value2, bool standardFpscr)
{
return FPCompareGTFpscr(value2, value1, standardFpscr);
}
public static float FPDiv(float value1, float value2)
{
ExecutionContext context = NativeInterface.GetContext();
@ -1971,10 +1999,16 @@ namespace ARMeilleure.Instructions
public static double FPCompareEQ(double value1, double value2)
{
ExecutionContext context = NativeInterface.GetContext();
return FPCompareEQFpscr(value1, value2, false);
}
value1 = value1.FPUnpack(out FPType type1, out _, out _, context);
value2 = value2.FPUnpack(out FPType type2, out _, out _, context);
public static double FPCompareEQFpscr(double value1, double value2, bool standardFpscr)
{
ExecutionContext context = NativeInterface.GetContext();
FPCR fpcr = standardFpscr ? context.StandardFpcrValue : context.Fpcr;
value1 = value1.FPUnpack(out FPType type1, out _, out _, context, fpcr);
value2 = value2.FPUnpack(out FPType type2, out _, out _, context, fpcr);
double result;
@ -1984,7 +2018,7 @@ namespace ARMeilleure.Instructions
if (type1 == FPType.SNaN || type2 == FPType.SNaN)
{
FPProcessException(FPException.InvalidOp, context);
FPProcessException(FPException.InvalidOp, context, fpcr);
}
}
else
@ -1997,10 +2031,16 @@ namespace ARMeilleure.Instructions
public static double FPCompareGE(double value1, double value2)
{
ExecutionContext context = NativeInterface.GetContext();
return FPCompareGEFpscr(value1, value2, false);
}
value1 = value1.FPUnpack(out FPType type1, out _, out _, context);
value2 = value2.FPUnpack(out FPType type2, out _, out _, context);
public static double FPCompareGEFpscr(double value1, double value2, bool standardFpscr)
{
ExecutionContext context = NativeInterface.GetContext();
FPCR fpcr = standardFpscr ? context.StandardFpcrValue : context.Fpcr;
value1 = value1.FPUnpack(out FPType type1, out _, out _, context, fpcr);
value2 = value2.FPUnpack(out FPType type2, out _, out _, context, fpcr);
double result;
@ -2008,7 +2048,7 @@ namespace ARMeilleure.Instructions
{
result = ZerosOrOnes(false);
FPProcessException(FPException.InvalidOp, context);
FPProcessException(FPException.InvalidOp, context, fpcr);
}
else
{
@ -2020,10 +2060,16 @@ namespace ARMeilleure.Instructions
public static double FPCompareGT(double value1, double value2)
{
ExecutionContext context = NativeInterface.GetContext();
return FPCompareGTFpscr(value1, value2, false);
}
value1 = value1.FPUnpack(out FPType type1, out _, out _, context);
value2 = value2.FPUnpack(out FPType type2, out _, out _, context);
public static double FPCompareGTFpscr(double value1, double value2, bool standardFpscr)
{
ExecutionContext context = NativeInterface.GetContext();
FPCR fpcr = standardFpscr ? context.StandardFpcrValue : context.Fpcr;
value1 = value1.FPUnpack(out FPType type1, out _, out _, context, fpcr);
value2 = value2.FPUnpack(out FPType type2, out _, out _, context, fpcr);
double result;
@ -2031,7 +2077,7 @@ namespace ARMeilleure.Instructions
{
result = ZerosOrOnes(false);
FPProcessException(FPException.InvalidOp, context);
FPProcessException(FPException.InvalidOp, context, fpcr);
}
else
{
@ -2051,6 +2097,16 @@ namespace ARMeilleure.Instructions
return FPCompareGT(value2, value1);
}
public static double FPCompareLEFpscr(double value1, double value2, bool standardFpscr)
{
return FPCompareGEFpscr(value2, value1, standardFpscr);
}
public static double FPCompareLTFpscr(double value1, double value2, bool standardFpscr)
{
return FPCompareGTFpscr(value2, value1, standardFpscr);
}
public static double FPDiv(double value1, double value2)
{
ExecutionContext context = NativeInterface.GetContext();