From 40797a1283ce9119f5f132693089c42442a4aa71 Mon Sep 17 00:00:00 2001 From: sharmander Date: Sun, 7 Feb 2021 18:49:46 -0500 Subject: [PATCH] Optimization | Modify Add (Integer) Instruction to use LEA instead. (#1971) * Optimization | Modify Add Instruction to use LEA instead. Currently, the add instruction requires 4 registers to take place. By using LEA, we can effectively perform the same working using 3 registers, reducing memory spills and improving translation efficiency. * Fix IsSameOperandDestSrc1 Check for Add * Use LEA if Dest != SRC1 * Update IsSameOperandDestSrc1 to account for Cases where Dest and Src1 can be same for add * Fix error in logic * Typo * Add paranthesis for clarity * Compare registers as requested. * Cleanup if statement, use same comparison method as generateCopy * Make change as recommended by gdk * Perform check only when Add calls are made * use ensure sametype for lea, fix else * Update comment * Update version # --- ARMeilleure/CodeGen/X86/CodeGenerator.cs | 49 +++++++++++++++++++----- ARMeilleure/CodeGen/X86/PreAllocator.cs | 1 + ARMeilleure/Translation/PTC/Ptc.cs | 2 +- 3 files changed, 42 insertions(+), 10 deletions(-) diff --git a/ARMeilleure/CodeGen/X86/CodeGenerator.cs b/ARMeilleure/CodeGen/X86/CodeGenerator.cs index 5f41ff79..ca1f1ceb 100644 --- a/ARMeilleure/CodeGen/X86/CodeGenerator.cs +++ b/ARMeilleure/CodeGen/X86/CodeGenerator.cs @@ -514,19 +514,50 @@ namespace ARMeilleure.CodeGen.X86 Operand src1 = operation.GetSource(0); Operand src2 = operation.GetSource(1); - ValidateBinOp(dest, src1, src2); - if (dest.Type.IsInteger()) { - context.Assembler.Add(dest, src2, dest.Type); + // If Destination and Source 1 Operands are the same, perform a standard add as there are no benefits to using LEA. + if (dest.Kind == src1.Kind && dest.Value == src1.Value) + { + ValidateBinOp(dest, src1, src2); + + context.Assembler.Add(dest, src2, dest.Type); + } + else + { + EnsureSameType(dest, src1, src2); + + int offset; + Operand index; + + if (src2.Kind == OperandKind.Constant) + { + offset = src2.AsInt32(); + index = null; + } + else + { + offset = 0; + index = src2; + } + + MemoryOperand memOp = MemoryOp(dest.Type, src1, index, Multiplier.x1, offset); + + context.Assembler.Lea(dest, memOp, dest.Type); + } } - else if (dest.Type == OperandType.FP32) + else { - context.Assembler.Addss(dest, src1, src2); - } - else /* if (dest.Type == OperandType.FP64) */ - { - context.Assembler.Addsd(dest, src1, src2); + ValidateBinOp(dest, src1, src2); + + if (dest.Type == OperandType.FP32) + { + context.Assembler.Addss(dest, src1, src2); + } + else /* if (dest.Type == OperandType.FP64) */ + { + context.Assembler.Addsd(dest, src1, src2); + } } } diff --git a/ARMeilleure/CodeGen/X86/PreAllocator.cs b/ARMeilleure/CodeGen/X86/PreAllocator.cs index 55bc778b..cb2476b4 100644 --- a/ARMeilleure/CodeGen/X86/PreAllocator.cs +++ b/ARMeilleure/CodeGen/X86/PreAllocator.cs @@ -1273,6 +1273,7 @@ namespace ARMeilleure.CodeGen.X86 switch (operation.Instruction) { case Instruction.Add: + return !HardwareCapabilities.SupportsVexEncoding && !operation.Destination.Type.IsInteger(); case Instruction.Multiply: case Instruction.Subtract: return !HardwareCapabilities.SupportsVexEncoding || operation.Destination.Type.IsInteger(); diff --git a/ARMeilleure/Translation/PTC/Ptc.cs b/ARMeilleure/Translation/PTC/Ptc.cs index fd69077b..846c01cd 100644 --- a/ARMeilleure/Translation/PTC/Ptc.cs +++ b/ARMeilleure/Translation/PTC/Ptc.cs @@ -22,7 +22,7 @@ namespace ARMeilleure.Translation.PTC { private const string HeaderMagic = "PTChd"; - private const int InternalVersion = 1943; //! To be incremented manually for each change to the ARMeilleure project. + private const int InternalVersion = 1971; //! To be incremented manually for each change to the ARMeilleure project. private const string ActualDir = "0"; private const string BackupDir = "1";