Float operands don't need to use the same register when VEX is supported

This commit is contained in:
gdkchan 2019-07-29 13:56:00 -03:00
parent c7e78bcb45
commit 9f4e6815c7
4 changed files with 49 additions and 13 deletions

View file

@ -272,21 +272,24 @@ namespace ARMeilleure.CodeGen.X86
// - The dividend is always in RDX:RAX.
// - The result is always in RAX.
// - Additionally it also writes the remainder in RDX.
Operand src1 = operation.GetSource(0);
if (dest.Type.IsInteger())
{
Operand src1 = operation.GetSource(0);
Operand rax = Gpr(X86Register.Rax, src1.Type);
Operand rdx = Gpr(X86Register.Rdx, src1.Type);
Operand rax = Gpr(X86Register.Rax, src1.Type);
Operand rdx = Gpr(X86Register.Rdx, src1.Type);
nodes.AddBefore(node, new Operation(Instruction.Copy, rax, src1));
nodes.AddBefore(node, new Operation(Instruction.Clobber, rdx));
nodes.AddBefore(node, new Operation(Instruction.Copy, rax, src1));
nodes.AddBefore(node, new Operation(Instruction.Clobber, rdx));
node = nodes.AddAfter(node, new Operation(Instruction.Copy, dest, rax));
node = nodes.AddAfter(node, new Operation(Instruction.Copy, dest, rax));
operation.SetDestinations(new Operand[] { rdx, rax });
operation.SetDestinations(new Operand[] { rdx, rax });
operation.SetSources(new Operand[] { rdx, rax, operation.GetSource(1) });
operation.SetSources(new Operand[] { rdx, rax, operation.GetSource(1) });
operation.Destination = rax;
operation.Destination = rax;
}
break;
}
@ -1115,20 +1118,25 @@ namespace ARMeilleure.CodeGen.X86
switch (operation.Instruction)
{
case Instruction.Add:
case Instruction.Multiply:
case Instruction.Subtract:
return !HardwareCapabilities.SupportsVexEncoding || operation.Destination.Type.IsInteger();
case Instruction.BitwiseAnd:
case Instruction.BitwiseExclusiveOr:
case Instruction.BitwiseNot:
case Instruction.BitwiseOr:
case Instruction.ByteSwap:
case Instruction.Multiply:
case Instruction.Negate:
case Instruction.RotateRight:
case Instruction.ShiftLeft:
case Instruction.ShiftRightSI:
case Instruction.ShiftRightUI:
case Instruction.Subtract:
return true;
case Instruction.Divide:
return !HardwareCapabilities.SupportsVexEncoding && !operation.Destination.Type.IsInteger();
case Instruction.VectorInsert:
case Instruction.VectorInsert16:
case Instruction.VectorInsert8:

View file

@ -417,6 +417,10 @@ namespace ARMeilleure.Instructions
{
EmitScalarBinaryOpF(context, Intrinsic.X86Divss, Intrinsic.X86Divsd);
}
else if (Optimizations.FastFP)
{
EmitScalarBinaryOpF(context, (op1, op2) => context.Divide(op1, op2));
}
else
{
EmitScalarBinaryOpF(context, (op1, op2) =>
@ -432,6 +436,10 @@ namespace ARMeilleure.Instructions
{
EmitVectorBinaryOpF(context, Intrinsic.X86Divps, Intrinsic.X86Divpd);
}
else if (Optimizations.FastFP)
{
EmitVectorBinaryOpF(context, (op1, op2) => context.Divide(op1, op2));
}
else
{
EmitVectorBinaryOpF(context, (op1, op2) =>
@ -841,6 +849,10 @@ namespace ARMeilleure.Instructions
{
EmitScalarBinaryOpF(context, Intrinsic.X86Mulss, Intrinsic.X86Mulsd);
}
else if (Optimizations.FastFP)
{
EmitScalarBinaryOpF(context, (op1, op2) => context.Multiply(op1, op2));
}
else
{
EmitScalarBinaryOpF(context, (op1, op2) =>
@ -861,6 +873,10 @@ namespace ARMeilleure.Instructions
{
EmitVectorBinaryOpF(context, Intrinsic.X86Mulps, Intrinsic.X86Mulpd);
}
else if (Optimizations.FastFP)
{
EmitVectorBinaryOpF(context, (op1, op2) => context.Multiply(op1, op2));
}
else
{
EmitVectorBinaryOpF(context, (op1, op2) =>
@ -907,6 +923,10 @@ namespace ARMeilleure.Instructions
context.Copy(GetVec(op.Rd), res);
}
}
else if (Optimizations.FastFP)
{
EmitVectorBinaryOpByElemF(context, (op1, op2) => context.Multiply(op1, op2));
}
else
{
EmitVectorBinaryOpByElemF(context, (op1, op2) =>
@ -1552,6 +1572,10 @@ namespace ARMeilleure.Instructions
{
EmitScalarBinaryOpF(context, Intrinsic.X86Subss, Intrinsic.X86Subsd);
}
else if (Optimizations.FastFP)
{
EmitScalarBinaryOpF(context, (op1, op2) => context.Subtract(op1, op2));
}
else
{
EmitScalarBinaryOpF(context, (op1, op2) =>
@ -1567,6 +1591,10 @@ namespace ARMeilleure.Instructions
{
EmitVectorBinaryOpF(context, Intrinsic.X86Subps, Intrinsic.X86Subpd);
}
else if (Optimizations.FastFP)
{
EmitVectorBinaryOpF(context, (op1, op2) => context.Subtract(op1, op2));
}
else
{
EmitVectorBinaryOpF(context, (op1, op2) =>

View file

@ -80,7 +80,7 @@ namespace ARMeilleure.Translation
public Operand Call(Delegate func, params Operand[] callArgs)
{
//Add the delegate to the cache to ensure it will not be garbage collected.
// Add the delegate to the cache to ensure it will not be garbage collected.
func = DelegateCache.GetOrAdd(func);
IntPtr ptr = Marshal.GetFunctionPointerForDelegate<Delegate>(func);

View file

@ -70,7 +70,7 @@ namespace ARMeilleure.Translation
public static void RunPass(ControlFlowGraph cfg)
{
// Computer local register inputs and outputs used inside blocks.
// Compute local register inputs and outputs used inside blocks.
RegisterMask[] localInputs = new RegisterMask[cfg.Blocks.Count];
RegisterMask[] localOutputs = new RegisterMask[cfg.Blocks.Count];