aboutsummaryrefslogtreecommitdiff
path: root/src/ARMeilleure/CodeGen/PreAllocatorCommon.cs
blob: 53f279fb9a1b975ae23bd2f9f5d88bc6dee2896a (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
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));
                        }
                    }
                }
            }
        }
    }
}