Float operands don't need to use the same register when VEX is supported
This commit is contained in:
parent
c7e78bcb45
commit
9f4e6815c7
4 changed files with 49 additions and 13 deletions
|
@ -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:
|
||||
|
|
|
@ -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) =>
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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];
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue