Add StandardFPSCRValue behaviour to compare instructions.
This commit is contained in:
parent
70a9e12e4e
commit
3d67259c9e
2 changed files with 95 additions and 60 deletions
|
@ -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);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
|
Loading…
Add table
Reference in a new issue