diff --git a/ARMeilleure/CodeGen/X86/PreAllocator.cs b/ARMeilleure/CodeGen/X86/PreAllocator.cs index 9b98ab0254..ccfea24b86 100644 --- a/ARMeilleure/CodeGen/X86/PreAllocator.cs +++ b/ARMeilleure/CodeGen/X86/PreAllocator.cs @@ -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: diff --git a/ARMeilleure/Instructions/InstEmitSimdArithmetic.cs b/ARMeilleure/Instructions/InstEmitSimdArithmetic.cs index 7b1592bc20..44659e8057 100644 --- a/ARMeilleure/Instructions/InstEmitSimdArithmetic.cs +++ b/ARMeilleure/Instructions/InstEmitSimdArithmetic.cs @@ -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) => diff --git a/ARMeilleure/Translation/EmitterContext.cs b/ARMeilleure/Translation/EmitterContext.cs index 0cfd3e527e..13cf677c77 100644 --- a/ARMeilleure/Translation/EmitterContext.cs +++ b/ARMeilleure/Translation/EmitterContext.cs @@ -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(func); diff --git a/ARMeilleure/Translation/RegisterUsage.cs b/ARMeilleure/Translation/RegisterUsage.cs index 4d256dee4a..e1f9030602 100644 --- a/ARMeilleure/Translation/RegisterUsage.cs +++ b/ARMeilleure/Translation/RegisterUsage.cs @@ -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];