public InstOp(ulong address, ulong rawOpCode, InstName name, InstEmitter emitter, InstProps props) { Address = address; RawOpCode = rawOpCode; Name = name; Emitter = emitter; Props = props; }
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()); }