Просмотр исходного кода

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 #
sharmander 5 лет назад
Родитель
Сommit
40797a1283

+ 40 - 9
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);
-            }
-            else if (dest.Type == OperandType.FP32)
-            {
-                context.Assembler.Addss(dest, src1, src2);
+                // 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.FP64) */
+            else 
             {
-                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);
+                }
             }
         }
 

+ 1 - 0
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();

+ 1 - 1
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";