aboutsummaryrefslogtreecommitdiff
path: root/ARMeilleure/CodeGen/PreAllocatorCommon.cs
diff options
context:
space:
mode:
Diffstat (limited to 'ARMeilleure/CodeGen/PreAllocatorCommon.cs')
-rw-r--r--ARMeilleure/CodeGen/PreAllocatorCommon.cs57
1 files changed, 57 insertions, 0 deletions
diff --git a/ARMeilleure/CodeGen/PreAllocatorCommon.cs b/ARMeilleure/CodeGen/PreAllocatorCommon.cs
new file mode 100644
index 00000000..53f279fb
--- /dev/null
+++ b/ARMeilleure/CodeGen/PreAllocatorCommon.cs
@@ -0,0 +1,57 @@
+using ARMeilleure.IntermediateRepresentation;
+using System;
+using static ARMeilleure.IntermediateRepresentation.Operand.Factory;
+
+namespace ARMeilleure.CodeGen
+{
+ static class PreAllocatorCommon
+ {
+ public static void Propagate(ref Span<Operation> buffer, Operand dest, Operand value)
+ {
+ ReadOnlySpan<Operation> uses = dest.GetUses(ref buffer);
+
+ foreach (Operation use in uses)
+ {
+ for (int srcIndex = 0; srcIndex < use.SourcesCount; srcIndex++)
+ {
+ Operand useSrc = use.GetSource(srcIndex);
+
+ if (useSrc == dest)
+ {
+ use.SetSource(srcIndex, value);
+ }
+ else if (useSrc.Kind == OperandKind.Memory)
+ {
+ MemoryOperand memoryOp = useSrc.GetMemory();
+
+ Operand baseAddr = memoryOp.BaseAddress;
+ Operand index = memoryOp.Index;
+ bool changed = false;
+
+ if (baseAddr == dest)
+ {
+ baseAddr = value;
+ changed = true;
+ }
+
+ if (index == dest)
+ {
+ index = value;
+ changed = true;
+ }
+
+ if (changed)
+ {
+ use.SetSource(srcIndex, MemoryOp(
+ useSrc.Type,
+ baseAddr,
+ index,
+ memoryOp.Scale,
+ memoryOp.Displacement));
+ }
+ }
+ }
+ }
+ }
+ }
+}