diff --git a/ARMeilleure/CodeGen/X86/X86Optimizer.cs b/ARMeilleure/CodeGen/X86/X86Optimizer.cs index 643b515f61..fa8b54e840 100644 --- a/ARMeilleure/CodeGen/X86/X86Optimizer.cs +++ b/ARMeilleure/CodeGen/X86/X86Optimizer.cs @@ -1,6 +1,7 @@ using ARMeilleure.CodeGen.Optimizations; using ARMeilleure.IntermediateRepresentation; using ARMeilleure.Translation; +using System.Collections.Generic; using static ARMeilleure.IntermediateRepresentation.OperandHelper; using static ARMeilleure.IntermediateRepresentation.OperationHelper; @@ -11,8 +12,28 @@ namespace ARMeilleure.CodeGen.X86 { public static void RunPass(ControlFlowGraph cfg) { + var constants = new Dictionary(); + + Operand GetConstantCopy(BasicBlock block, Operation operation, Operand source) + { + if (!constants.TryGetValue(source.Value, out var constant)) + { + constant = Local(source.Type); + + Operation copyOp = Operation(Instruction.Copy, constant, source); + + block.Operations.AddBefore(operation, copyOp); + + constants.Add(source.Value, constant); + } + + return constant; + } + for (BasicBlock block = cfg.Blocks.First; block != null; block = block.ListNext) { + constants.Clear(); + Node nextNode; for (Node node = block.Operations.First; node != null; node = nextNode) @@ -33,24 +54,12 @@ namespace ARMeilleure.CodeGen.X86 if (src1.Kind == OperandKind.Constant && (src1.Relocatable || CodeGenCommon.IsLongConst(src1))) { - Operand temp = Local(src1.Type); - - Operation copyOp = Operation(Instruction.Copy, temp, src1); - - block.Operations.AddBefore(operation, copyOp); - - operation.SetSource(0, temp); + operation.SetSource(0, GetConstantCopy(block, operation, src1)); } if (src2.Kind == OperandKind.Constant && (src2.Relocatable || CodeGenCommon.IsLongConst(src2))) { - Operand temp = Local(src2.Type); - - Operation copyOp = Operation(Instruction.Copy, temp, src2); - - block.Operations.AddBefore(operation, copyOp); - - operation.SetSource(1, temp); + operation.SetSource(1, GetConstantCopy(block, operation, src2)); } } @@ -111,6 +120,11 @@ namespace ARMeilleure.CodeGen.X86 return null; } + if (imm == 0 && scale == Multiplier.x1 && indexOp != null) + { + imm = GetConstOp(ref indexOp); + } + return MemoryOp(type, baseOp, indexOp, scale, imm); } diff --git a/ARMeilleure/Instructions/InstEmitMemory.cs b/ARMeilleure/Instructions/InstEmitMemory.cs index 1d5953fb24..87564fdcdb 100644 --- a/ARMeilleure/Instructions/InstEmitMemory.cs +++ b/ARMeilleure/Instructions/InstEmitMemory.cs @@ -87,8 +87,7 @@ namespace ARMeilleure.Instructions } Operand address = GetAddress(context); - - Operand address2 = context.Add(address, Const(1L << op.Size)); + Operand address2 = GetAddress(context, 1L << op.Size); EmitLoad(op.Rt, address); EmitLoad(op.Rt2, address2); @@ -112,8 +111,7 @@ namespace ARMeilleure.Instructions OpCodeMemPair op = (OpCodeMemPair)context.CurrOp; Operand address = GetAddress(context); - - Operand address2 = context.Add(address, Const(1L << op.Size)); + Operand address2 = GetAddress(context, 1L << op.Size); InstEmitMemoryHelper.EmitStore(context, address, op.Rt, op.Size); InstEmitMemoryHelper.EmitStore(context, address2, op.Rt2, op.Size); @@ -121,7 +119,7 @@ namespace ARMeilleure.Instructions EmitWBackIfNeeded(context, address); } - private static Operand GetAddress(ArmEmitterContext context) + private static Operand GetAddress(ArmEmitterContext context, long addend = 0) { Operand address = null; @@ -134,7 +132,11 @@ namespace ARMeilleure.Instructions // Pre-indexing. if (!op.PostIdx) { - address = context.Add(address, Const(op.Immediate)); + address = context.Add(address, Const(op.Immediate + addend)); + } + else if (addend != 0) + { + address = context.Add(address, Const(addend)); } break; @@ -153,6 +155,11 @@ namespace ARMeilleure.Instructions address = context.Add(n, m); + if (addend != 0) + { + address = context.Add(address, Const(addend)); + } + break; } } diff --git a/ARMeilleure/Translation/PTC/Ptc.cs b/ARMeilleure/Translation/PTC/Ptc.cs index 4b5f317387..1bb8659c3a 100644 --- a/ARMeilleure/Translation/PTC/Ptc.cs +++ b/ARMeilleure/Translation/PTC/Ptc.cs @@ -28,7 +28,7 @@ namespace ARMeilleure.Translation.PTC private const string OuterHeaderMagicString = "PTCohd\0\0"; private const string InnerHeaderMagicString = "PTCihd\0\0"; - private const uint InternalVersion = 1866; //! To be incremented manually for each change to the ARMeilleure project. + private const uint InternalVersion = 2285; //! To be incremented manually for each change to the ARMeilleure project. private const string ActualDir = "0"; private const string BackupDir = "1";