Beispiel #1
0
 public InstOp(ulong address, ulong rawOpCode, InstName name, InstEmitter emitter, InstProps props)
 {
     Address   = address;
     RawOpCode = rawOpCode;
     Name      = name;
     Emitter   = emitter;
     Props     = props;
 }
Beispiel #2
0
        private static TreeNode[] BuildTree(Block[] blocks)
        {
            List <TreeNode> nodes = new List <TreeNode>();

            Dictionary <ulong, TreeNode> labels = new Dictionary <ulong, TreeNode>();

            TreeNodeUse[] predDefs = new TreeNodeUse[RegisterConsts.PredsCount];
            TreeNodeUse[] gprDefs  = new TreeNodeUse[RegisterConsts.GprsCount];

            void DefPred(byte predIndex, int index, TreeNode node)
            {
                if (predIndex != RegisterConsts.PredicateTrueIndex)
                {
                    predDefs[predIndex] = new TreeNodeUse(index, node);
                }
            }

            void DefGpr(byte regIndex, int index, TreeNode node)
            {
                if (regIndex != RegisterConsts.RegisterZeroIndex)
                {
                    gprDefs[regIndex] = new TreeNodeUse(index, node);
                }
            }

            TreeNodeUse UsePred(byte predIndex, bool predInv)
            {
                if (predIndex != RegisterConsts.PredicateTrueIndex)
                {
                    TreeNodeUse use = predDefs[predIndex];

                    if (use.Node != null)
                    {
                        nodes.Remove(use.Node);
                    }
                    else
                    {
                        use = new TreeNodeUse(-(predIndex + 2), null);
                    }

                    return(predInv ? use.Flip() : use);
                }

                return(new TreeNodeUse(-1, null));
            }

            TreeNodeUse UseGpr(byte regIndex)
            {
                if (regIndex != RegisterConsts.RegisterZeroIndex)
                {
                    TreeNodeUse use = gprDefs[regIndex];

                    if (use.Node != null)
                    {
                        nodes.Remove(use.Node);
                    }
                    else
                    {
                        use = new TreeNodeUse(-(regIndex + 2), null);
                    }

                    return(use);
                }

                return(new TreeNodeUse(-1, null));
            }

            byte order = 0;

            for (int index = 0; index < blocks.Length; index++)
            {
                Block block = blocks[index];

                if (block.Predecessors.Count > 1)
                {
                    TreeNode label = new TreeNode(order++);
                    nodes.Add(label);
                    labels.Add(block.Address, label);
                }

                for (int opIndex = 0; opIndex < block.OpCodes.Count; opIndex++)
                {
                    InstOp op = block.OpCodes[opIndex];

                    TreeNode node = new TreeNode(op, IsOrderDependant(op.Name) ? order : (byte)0);

                    // Add uses.

                    if (!op.Props.HasFlag(InstProps.NoPred))
                    {
                        byte predIndex = (byte)((op.RawOpCode >> 16) & 7);
                        bool predInv   = (op.RawOpCode & 0x80000) != 0;
                        node.Uses.Add(UsePred(predIndex, predInv));
                    }

                    if (op.Props.HasFlag(InstProps.Ps))
                    {
                        byte predIndex = (byte)((op.RawOpCode >> 39) & 7);
                        bool predInv   = (op.RawOpCode & 0x40000000000) != 0;
                        node.Uses.Add(UsePred(predIndex, predInv));
                    }

                    if (op.Props.HasFlag(InstProps.Ra))
                    {
                        byte ra = (byte)(op.RawOpCode >> 8);
                        node.Uses.Add(UseGpr(ra));
                    }

                    if ((op.Props & (InstProps.Rb | InstProps.Rb2)) != 0)
                    {
                        byte rb = op.Props.HasFlag(InstProps.Rb2) ? (byte)op.RawOpCode : (byte)(op.RawOpCode >> 20);
                        node.Uses.Add(UseGpr(rb));
                    }

                    if (op.Props.HasFlag(InstProps.Rc))
                    {
                        byte rc = (byte)(op.RawOpCode >> 39);
                        node.Uses.Add(UseGpr(rc));
                    }

                    if (op.Name == InstName.Bra && labels.TryGetValue(op.GetAbsoluteAddress(), out TreeNode label))
                    {
                        node.Uses.Add(new TreeNodeUse(0, label));
                    }

                    // Make definitions.

                    int defIndex = 0;

                    InstProps pdType = op.Props & InstProps.PdMask;

                    if (pdType != 0)
                    {
                        int bit = pdType switch
                        {
                            InstProps.Pd => 3,
                            InstProps.LPd => 48,
                            InstProps.SPd => 30,
                            InstProps.TPd => 51,
                            InstProps.VPd => 45,
                            _ => throw new InvalidOperationException($"Table has unknown predicate destination {pdType}.")
                        };

                        byte predIndex = (byte)((op.RawOpCode >> bit) & 7);
                        DefPred(predIndex, defIndex++, node);
                    }

                    if (op.Props.HasFlag(InstProps.Rd))
                    {
                        byte rd = (byte)op.RawOpCode;
                        DefGpr(rd, defIndex++, node);
                    }

                    nodes.Add(node);
                }
            }

            return(nodes.ToArray());
        }