Add StandardFPSCRValue behaviour for all Arithmetic instructions
This commit is contained in:
parent
a66ada4f26
commit
70a9e12e4e
4 changed files with 506 additions and 141 deletions
|
@ -4,6 +4,7 @@ using System;
|
|||
namespace ARMeilleure.Instructions
|
||||
{
|
||||
delegate double _F64_F64(double a1);
|
||||
delegate double _F64_F64_Bool(double a1, bool a2);
|
||||
delegate double _F64_F64_F64(double a1, double a2);
|
||||
delegate double _F64_F64_F64_Bool(double a1, double a2, bool a3);
|
||||
delegate double _F64_F64_F64_F64(double a1, double a2, double a3);
|
||||
|
@ -11,6 +12,7 @@ namespace ARMeilleure.Instructions
|
|||
delegate double _F64_F64_MidpointRounding(double a1, MidpointRounding a2);
|
||||
|
||||
delegate float _F32_F32(float a1);
|
||||
delegate float _F32_F32_Bool(float a1, bool a2);
|
||||
delegate float _F32_F32_F32(float a1, float a2);
|
||||
delegate float _F32_F32_F32_Bool(float a1, float a2, bool a3);
|
||||
delegate float _F32_F32_F32_F32(float a1, float a2, float a3);
|
||||
|
|
|
@ -229,17 +229,17 @@ namespace ARMeilleure.Instructions
|
|||
public static void VmaxminNm_V(ArmEmitterContext context)
|
||||
{
|
||||
bool max = (context.CurrOp.RawOpCode & (1 << 21)) == 0;
|
||||
_F32_F32_F32 f32 = max ? new _F32_F32_F32(SoftFloat32.FPMaxNum) : new _F32_F32_F32(SoftFloat32.FPMinNum);
|
||||
_F64_F64_F64 f64 = max ? new _F64_F64_F64(SoftFloat64.FPMaxNum) : new _F64_F64_F64(SoftFloat64.FPMinNum);
|
||||
_F32_F32_F32_Bool f32 = max ? new _F32_F32_F32_Bool(SoftFloat32.FPMaxNumFpscr) : new _F32_F32_F32_Bool(SoftFloat32.FPMinNumFpscr);
|
||||
_F64_F64_F64_Bool f64 = max ? new _F64_F64_F64_Bool(SoftFloat64.FPMaxNumFpscr) : new _F64_F64_F64_Bool(SoftFloat64.FPMinNumFpscr);
|
||||
|
||||
EmitVectorBinaryOpSx32(context, (op1, op2) => EmitSoftFloatCall(context, f32, f64, op1, op2));
|
||||
EmitVectorBinaryOpSx32(context, (op1, op2) => EmitSoftFloatCallDefaultFpscr(context, f32, f64, op1, op2));
|
||||
}
|
||||
|
||||
public static void Vmax_V(ArmEmitterContext context)
|
||||
{
|
||||
EmitVectorBinaryOpF32(context, (op1, op2) =>
|
||||
{
|
||||
return EmitSoftFloatCall(context, SoftFloat32.FPMax, SoftFloat64.FPMax, op1, op2);
|
||||
return EmitSoftFloatCallDefaultFpscr(context, SoftFloat32.FPMaxFpscr, SoftFloat64.FPMaxFpscr, op1, op2);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -260,7 +260,7 @@ namespace ARMeilleure.Instructions
|
|||
{
|
||||
EmitVectorBinaryOpF32(context, (op1, op2) =>
|
||||
{
|
||||
return EmitSoftFloatCall(context, SoftFloat32.FPMin, SoftFloat64.FPMin, op1, op2);
|
||||
return EmitSoftFloatCallDefaultFpscr(context, SoftFloat32.FPMinFpscr, SoftFloat64.FPMinFpscr, op1, op2);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -505,34 +505,49 @@ namespace ARMeilleure.Instructions
|
|||
}
|
||||
|
||||
public static void Vrecpe(ArmEmitterContext context)
|
||||
{
|
||||
OpCode32SimdSqrte op = (OpCode32SimdSqrte)context.CurrOp;
|
||||
if (op.F)
|
||||
{
|
||||
EmitVectorUnaryOpF32(context, (op1) =>
|
||||
{
|
||||
return EmitSoftFloatCall(context, SoftFloat32.FPRecipEstimate, SoftFloat64.FPRecipEstimate, op1);
|
||||
return EmitSoftFloatCallDefaultFpscr(context, SoftFloat32.FPRecipEstimateFpscr, SoftFloat64.FPRecipEstimateFpscr, op1);
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new NotImplementedException("Integer Vrecpe not currently implemented.");
|
||||
}
|
||||
}
|
||||
|
||||
public static void Vrecps(ArmEmitterContext context)
|
||||
{
|
||||
EmitVectorBinaryOpF32(context, (op1, op2) =>
|
||||
{
|
||||
return EmitSoftFloatCall(context, SoftFloat32.FPRecipStepFused, SoftFloat64.FPRecipStepFused, op1, op2);
|
||||
return EmitSoftFloatCall(context, SoftFloat32.FPRecipStep, SoftFloat64.FPRecipStep, op1, op2);
|
||||
});
|
||||
}
|
||||
|
||||
public static void Vrsqrte(ArmEmitterContext context)
|
||||
{
|
||||
OpCode32SimdSqrte op = (OpCode32SimdSqrte)context.CurrOp;
|
||||
if (op.F)
|
||||
{
|
||||
EmitVectorUnaryOpF32(context, (op1) =>
|
||||
{
|
||||
return EmitSoftFloatCall(context, SoftFloat32.FPRSqrtEstimate, SoftFloat64.FPRSqrtEstimate, op1);
|
||||
return EmitSoftFloatCallDefaultFpscr(context, SoftFloat32.FPRSqrtEstimateFpscr, SoftFloat64.FPRSqrtEstimateFpscr, op1);
|
||||
});
|
||||
} else
|
||||
{
|
||||
throw new NotImplementedException("Integer Vrsqrte not currently implemented.");
|
||||
}
|
||||
}
|
||||
|
||||
public static void Vrsqrts(ArmEmitterContext context)
|
||||
{
|
||||
EmitVectorBinaryOpF32(context, (op1, op2) =>
|
||||
{
|
||||
return EmitSoftFloatCall(context, SoftFloat32.FPRSqrtStepFused, SoftFloat64.FPRSqrtStepFused, op1, op2);
|
||||
return EmitSoftFloatCall(context, SoftFloat32.FPRSqrtStep, SoftFloat64.FPRSqrtStep, op1, op2);
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -458,6 +458,22 @@ namespace ARMeilleure.Instructions
|
|||
|
||||
// Generic Functions
|
||||
|
||||
public static Operand EmitSoftFloatCallDefaultFpscr(
|
||||
ArmEmitterContext context,
|
||||
_F32_F32_Bool f32,
|
||||
_F64_F64_Bool f64,
|
||||
params Operand[] callArgs)
|
||||
{
|
||||
IOpCodeSimd op = (IOpCodeSimd)context.CurrOp;
|
||||
|
||||
Delegate dlg = (op.Size & 1) == 0 ? (Delegate)f32 : (Delegate)f64;
|
||||
|
||||
Array.Resize(ref callArgs, callArgs.Length + 1);
|
||||
callArgs[callArgs.Length - 1] = Const(1);
|
||||
|
||||
return context.Call(dlg, callArgs);
|
||||
}
|
||||
|
||||
public static Operand EmitSoftFloatCallDefaultFpscr(
|
||||
ArmEmitterContext context,
|
||||
_F32_F32_F32_Bool f32,
|
||||
|
|
File diff suppressed because it is too large
Load diff
Loading…
Add table
Add a link
Reference in a new issue