mirror of
				https://github.com/Ryujinx/Ryujinx.git
				synced 2025-11-04 02:23:42 +00:00 
			
		
		
		
	Improve IRDumper (#1135)
* Improve IRDumper
* Make Symbols.Add(ulong, ulong, ulong, string) thread safe
* Use a StringBuilder for MemoryOperand
* Add #if M_DEBUG guards
* Fix JMP_TABLE typo
* Fix using in Symbols
* Use Conditional("M_DEBUG") instead
Address gdkchan's feedback
* Use a struct instead of 4-tuple
Address gdkchan's feedback
* Place symbols in comments instead
Address gdkchan's feedback
* Use StringBuilder throughout
* Handle offsetted symbols
* Fix naming convention of Builder
* Avoid ArgumentException
* Remove unnecessary using
* Use switch expression instead
* Turn into a class
* Clean up
* Remove unnecessary using
			
			
This commit is contained in:
		
							parent
							
								
									53369e79bd
								
							
						
					
					
						commit
						180ad8605d
					
				@ -2,168 +2,282 @@ using ARMeilleure.IntermediateRepresentation;
 | 
			
		||||
using ARMeilleure.Translation;
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using System.Text;
 | 
			
		||||
 | 
			
		||||
namespace ARMeilleure.Diagnostics
 | 
			
		||||
{
 | 
			
		||||
    static class IRDumper
 | 
			
		||||
    class IRDumper
 | 
			
		||||
    {
 | 
			
		||||
        private const string Indentation = " ";
 | 
			
		||||
 | 
			
		||||
        public static string GetDump(ControlFlowGraph cfg)
 | 
			
		||||
        private int _indentLevel;
 | 
			
		||||
 | 
			
		||||
        private readonly StringBuilder _builder;
 | 
			
		||||
 | 
			
		||||
        private readonly Dictionary<Operand, string> _localNames;
 | 
			
		||||
        private readonly Dictionary<ulong, string> _symbolNames;
 | 
			
		||||
 | 
			
		||||
        private IRDumper(int indent)
 | 
			
		||||
        {
 | 
			
		||||
            StringBuilder sb = new StringBuilder();
 | 
			
		||||
            _indentLevel = indent;
 | 
			
		||||
 | 
			
		||||
            Dictionary<Operand, string> localNames = new Dictionary<Operand, string>();
 | 
			
		||||
            _builder = new StringBuilder();
 | 
			
		||||
 | 
			
		||||
            string indentation = string.Empty;
 | 
			
		||||
 | 
			
		||||
            void IncreaseIndentation()
 | 
			
		||||
            {
 | 
			
		||||
                indentation += Indentation;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            void DecreaseIndentation()
 | 
			
		||||
            {
 | 
			
		||||
                indentation = indentation.Substring(0, indentation.Length - Indentation.Length);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            void AppendLine(string text)
 | 
			
		||||
            {
 | 
			
		||||
                sb.AppendLine(indentation + text);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            IncreaseIndentation();
 | 
			
		||||
 | 
			
		||||
            for (BasicBlock block = cfg.Blocks.First; block != null; block = block.ListNext)
 | 
			
		||||
            {
 | 
			
		||||
                string blockName = GetBlockName(block);
 | 
			
		||||
 | 
			
		||||
                if (block.Next != null)
 | 
			
		||||
                {
 | 
			
		||||
                    blockName += $" (next {GetBlockName(block.Next)})";
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                if (block.Branch != null)
 | 
			
		||||
                {
 | 
			
		||||
                    blockName += $" (branch {GetBlockName(block.Branch)})";
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                blockName += ":";
 | 
			
		||||
 | 
			
		||||
                AppendLine(blockName);
 | 
			
		||||
 | 
			
		||||
                IncreaseIndentation();
 | 
			
		||||
 | 
			
		||||
                for (Node node = block.Operations.First; node != null; node = node.ListNext)
 | 
			
		||||
                {
 | 
			
		||||
                    string[] sources = new string[node.SourcesCount];
 | 
			
		||||
 | 
			
		||||
                    string instName = string.Empty;
 | 
			
		||||
 | 
			
		||||
                    if (node is PhiNode phi)
 | 
			
		||||
                    {
 | 
			
		||||
                        for (int index = 0; index < sources.Length; index++)
 | 
			
		||||
                        {
 | 
			
		||||
                            string phiBlockName = GetBlockName(phi.GetBlock(index));
 | 
			
		||||
 | 
			
		||||
                            string operName = GetOperandName(phi.GetSource(index), localNames);
 | 
			
		||||
 | 
			
		||||
                            sources[index] = $"({phiBlockName}: {operName})";
 | 
			
		||||
                        }
 | 
			
		||||
 | 
			
		||||
                        instName = "Phi";
 | 
			
		||||
                    }
 | 
			
		||||
                    else if (node is Operation operation)
 | 
			
		||||
                    {
 | 
			
		||||
                        for (int index = 0; index < sources.Length; index++)
 | 
			
		||||
                        {
 | 
			
		||||
                            sources[index] = GetOperandName(operation.GetSource(index), localNames);
 | 
			
		||||
                        }
 | 
			
		||||
 | 
			
		||||
                        instName = operation.Instruction.ToString();
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    string allSources = string.Join(", ", sources);
 | 
			
		||||
 | 
			
		||||
                    string line = instName + " " + allSources;
 | 
			
		||||
 | 
			
		||||
                    if (node.Destination != null)
 | 
			
		||||
                    {
 | 
			
		||||
                        line = GetOperandName(node.Destination, localNames) + " = " + line;
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    AppendLine(line);
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                DecreaseIndentation();
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return sb.ToString();
 | 
			
		||||
            _localNames = new Dictionary<Operand, string>();
 | 
			
		||||
            _symbolNames = new Dictionary<ulong, string>();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private static string GetBlockName(BasicBlock block)
 | 
			
		||||
        private void Indent()
 | 
			
		||||
        {
 | 
			
		||||
            return $"block{block.Index}";
 | 
			
		||||
            _builder.EnsureCapacity(_builder.Capacity + _indentLevel * Indentation.Length);
 | 
			
		||||
 | 
			
		||||
            for (int index = 0; index < _indentLevel; index++)
 | 
			
		||||
            {
 | 
			
		||||
                _builder.Append(Indentation);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private static string GetOperandName(Operand operand, Dictionary<Operand, string> localNames)
 | 
			
		||||
        private void IncreaseIndentation()
 | 
			
		||||
        {
 | 
			
		||||
            _indentLevel++;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void DecreaseIndentation()
 | 
			
		||||
        {
 | 
			
		||||
            _indentLevel--;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void DumpBlockName(BasicBlock block)
 | 
			
		||||
        {
 | 
			
		||||
            _builder.Append("block").Append(block.Index);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void DumpBlockHeader(BasicBlock block)
 | 
			
		||||
        {
 | 
			
		||||
            DumpBlockName(block);
 | 
			
		||||
 | 
			
		||||
            if (block.Next != null)
 | 
			
		||||
            {
 | 
			
		||||
                _builder.Append(" (next ");
 | 
			
		||||
                DumpBlockName(block.Next);
 | 
			
		||||
                _builder.Append(')');
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (block.Branch != null)
 | 
			
		||||
            {
 | 
			
		||||
                _builder.Append(" (branch ");
 | 
			
		||||
                DumpBlockName(block.Branch);
 | 
			
		||||
                _builder.Append(')');
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            _builder.Append(':');
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void DumpOperand(Operand operand)
 | 
			
		||||
        {
 | 
			
		||||
            if (operand == null)
 | 
			
		||||
            {
 | 
			
		||||
                return "<NULL>";
 | 
			
		||||
                _builder.Append("<NULL>");
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            string name = string.Empty;
 | 
			
		||||
            _builder.Append(GetTypeName(operand.Type)).Append(' ');
 | 
			
		||||
 | 
			
		||||
            if (operand.Kind == OperandKind.LocalVariable)
 | 
			
		||||
            switch (operand.Kind)
 | 
			
		||||
            {
 | 
			
		||||
                if (!localNames.TryGetValue(operand, out string localName))
 | 
			
		||||
                {
 | 
			
		||||
                    localName = "%" + localNames.Count;
 | 
			
		||||
                case OperandKind.LocalVariable:
 | 
			
		||||
                    if (!_localNames.TryGetValue(operand, out string localName))
 | 
			
		||||
                    {
 | 
			
		||||
                        localName = $"%{_localNames.Count}";
 | 
			
		||||
 | 
			
		||||
                    localNames.Add(operand, localName);
 | 
			
		||||
                        _localNames.Add(operand, localName);
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    _builder.Append(localName);
 | 
			
		||||
                    break;
 | 
			
		||||
 | 
			
		||||
                case OperandKind.Register:
 | 
			
		||||
                    Register reg = operand.GetRegister();
 | 
			
		||||
 | 
			
		||||
                    switch (reg.Type)
 | 
			
		||||
                    {
 | 
			
		||||
                        case RegisterType.Flag:    _builder.Append('b'); break;
 | 
			
		||||
                        case RegisterType.FpFlag:  _builder.Append('f'); break;
 | 
			
		||||
                        case RegisterType.Integer: _builder.Append('r'); break;
 | 
			
		||||
                        case RegisterType.Vector:  _builder.Append('v'); break;
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    _builder.Append(reg.Index);
 | 
			
		||||
                    break;
 | 
			
		||||
 | 
			
		||||
                case OperandKind.Constant:
 | 
			
		||||
                    string symbolName = Symbols.Get(operand.Value);
 | 
			
		||||
 | 
			
		||||
                    if (symbolName != null && !_symbolNames.ContainsKey(operand.Value))
 | 
			
		||||
                    {
 | 
			
		||||
                        _symbolNames.Add(operand.Value, symbolName);
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    _builder.Append("0x").Append(operand.Value.ToString("X"));
 | 
			
		||||
                    break;
 | 
			
		||||
 | 
			
		||||
                case OperandKind.Memory:
 | 
			
		||||
                    var memOp = (MemoryOperand)operand;
 | 
			
		||||
 | 
			
		||||
                    _builder.Append('[');
 | 
			
		||||
 | 
			
		||||
                    DumpOperand(memOp.BaseAddress);
 | 
			
		||||
 | 
			
		||||
                    if (memOp.Index != null)
 | 
			
		||||
                    {
 | 
			
		||||
                        _builder.Append(" + ");
 | 
			
		||||
 | 
			
		||||
                        DumpOperand(memOp.Index);
 | 
			
		||||
 | 
			
		||||
                        switch (memOp.Scale)
 | 
			
		||||
                        {
 | 
			
		||||
                            case Multiplier.x2: _builder.Append("*2"); break;
 | 
			
		||||
                            case Multiplier.x4: _builder.Append("*4"); break;
 | 
			
		||||
                            case Multiplier.x8: _builder.Append("*8"); break;
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    if (memOp.Displacement != 0)
 | 
			
		||||
                    {
 | 
			
		||||
                        _builder.Append(" + 0x").Append(memOp.Displacement.ToString("X"));
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    _builder.Append(']');
 | 
			
		||||
                    break;
 | 
			
		||||
 | 
			
		||||
                default:
 | 
			
		||||
                    _builder.Append(operand.Type);
 | 
			
		||||
                    break;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void DumpNode(Node node)
 | 
			
		||||
        {
 | 
			
		||||
            for (int index = 0; index < node.DestinationsCount; index++)
 | 
			
		||||
            {
 | 
			
		||||
                DumpOperand(node.GetDestination(index));
 | 
			
		||||
 | 
			
		||||
                if (index == node.DestinationsCount - 1)
 | 
			
		||||
                {
 | 
			
		||||
                    _builder.Append(" = ");
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                name = localName;
 | 
			
		||||
            }
 | 
			
		||||
            else if (operand.Kind == OperandKind.Register)
 | 
			
		||||
            {
 | 
			
		||||
                Register reg = operand.GetRegister();
 | 
			
		||||
 | 
			
		||||
                switch (reg.Type)
 | 
			
		||||
                else
 | 
			
		||||
                {
 | 
			
		||||
                    case RegisterType.Flag:    name = "b" + reg.Index; break;
 | 
			
		||||
                    case RegisterType.FpFlag:  name = "f" + reg.Index; break;
 | 
			
		||||
                    case RegisterType.Integer: name = "r" + reg.Index; break;
 | 
			
		||||
                    case RegisterType.Vector:  name = "v" + reg.Index; break;
 | 
			
		||||
                    _builder.Append(", ");
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            else if (operand.Kind == OperandKind.Constant)
 | 
			
		||||
 | 
			
		||||
            switch (node)
 | 
			
		||||
            {
 | 
			
		||||
                name = "0x" + operand.Value.ToString("X");
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                name = operand.Kind.ToString().ToLower();
 | 
			
		||||
                case PhiNode phi:
 | 
			
		||||
                    _builder.Append("Phi ");
 | 
			
		||||
 | 
			
		||||
                    for (int index = 0; index < phi.SourcesCount; index++)
 | 
			
		||||
                    {
 | 
			
		||||
                        _builder.Append('(');
 | 
			
		||||
 | 
			
		||||
                        DumpBlockName(phi.GetBlock(index));
 | 
			
		||||
 | 
			
		||||
                        _builder.Append(": ");
 | 
			
		||||
 | 
			
		||||
                        DumpOperand(phi.GetSource(index));
 | 
			
		||||
 | 
			
		||||
                        _builder.Append(')');
 | 
			
		||||
 | 
			
		||||
                        if (index < phi.SourcesCount - 1)
 | 
			
		||||
                        {
 | 
			
		||||
                            _builder.Append(", ");
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                    break;
 | 
			
		||||
 | 
			
		||||
                case Operation operation:
 | 
			
		||||
                    _builder.Append(operation.Instruction);
 | 
			
		||||
 | 
			
		||||
                    if (operation.Instruction == Instruction.Extended)
 | 
			
		||||
                    {
 | 
			
		||||
                        var intrinOp = (IntrinsicOperation)operation;
 | 
			
		||||
 | 
			
		||||
                        _builder.Append('.').Append(intrinOp.Intrinsic);
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    _builder.Append(' ');
 | 
			
		||||
 | 
			
		||||
                    for (int index = 0; index < operation.SourcesCount; index++)
 | 
			
		||||
                    {
 | 
			
		||||
                        DumpOperand(operation.GetSource(index));
 | 
			
		||||
 | 
			
		||||
                        if (index < operation.SourcesCount - 1)
 | 
			
		||||
                        {
 | 
			
		||||
                            _builder.Append(", ");
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                    break;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return GetTypeName(operand.Type) + " " + name;
 | 
			
		||||
            if (_symbolNames.Count == 1)
 | 
			
		||||
            {
 | 
			
		||||
                _builder.Append(" ;; ").Append(_symbolNames.First().Value);
 | 
			
		||||
            }
 | 
			
		||||
            else if (_symbolNames.Count > 1)
 | 
			
		||||
            {
 | 
			
		||||
                _builder.Append(" ;;");
 | 
			
		||||
 | 
			
		||||
                foreach ((ulong value, string name) in _symbolNames)
 | 
			
		||||
                {
 | 
			
		||||
                    _builder.Append(" 0x").Append(value.ToString("X")).Append(" = ").Append(name);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // Reset the set of symbols for the next Node we're going to dump.
 | 
			
		||||
            _symbolNames.Clear();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public static string GetDump(ControlFlowGraph cfg)
 | 
			
		||||
        {
 | 
			
		||||
            var dumper = new IRDumper(1);
 | 
			
		||||
 | 
			
		||||
            for (BasicBlock block = cfg.Blocks.First; block != null; block = block.ListNext)
 | 
			
		||||
            {
 | 
			
		||||
                dumper.Indent();
 | 
			
		||||
                dumper.DumpBlockHeader(block);
 | 
			
		||||
 | 
			
		||||
                dumper._builder.AppendLine();
 | 
			
		||||
 | 
			
		||||
                dumper.IncreaseIndentation();
 | 
			
		||||
 | 
			
		||||
                for (Node node = block.Operations.First; node != null; node = node.ListNext)
 | 
			
		||||
                {
 | 
			
		||||
                    dumper.Indent();
 | 
			
		||||
                    dumper.DumpNode(node);
 | 
			
		||||
 | 
			
		||||
                    dumper._builder.AppendLine();
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                dumper.DecreaseIndentation();
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return dumper._builder.ToString();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private static string GetTypeName(OperandType type)
 | 
			
		||||
        {
 | 
			
		||||
            switch (type)
 | 
			
		||||
            return type switch
 | 
			
		||||
            {
 | 
			
		||||
                case OperandType.FP32: return "f32";
 | 
			
		||||
                case OperandType.FP64: return "f64";
 | 
			
		||||
                case OperandType.I32:  return "i32";
 | 
			
		||||
                case OperandType.I64:  return "i64";
 | 
			
		||||
                case OperandType.None: return "none";
 | 
			
		||||
                case OperandType.V128: return "v128";
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            throw new ArgumentException($"Invalid operand type \"{type}\".");
 | 
			
		||||
                OperandType.None => "none",
 | 
			
		||||
                OperandType.I32 => "i32",
 | 
			
		||||
                OperandType.I64 => "i64",
 | 
			
		||||
                OperandType.FP32 => "f32",
 | 
			
		||||
                OperandType.FP64 => "f64",
 | 
			
		||||
                OperandType.V128 => "v128",
 | 
			
		||||
                _ => throw new ArgumentException($"Invalid operand type \"{type}\"."),
 | 
			
		||||
            };
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										84
									
								
								ARMeilleure/Diagnostics/Symbols.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										84
									
								
								ARMeilleure/Diagnostics/Symbols.cs
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,84 @@
 | 
			
		||||
using System.Collections.Concurrent;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Diagnostics;
 | 
			
		||||
 | 
			
		||||
namespace ARMeilleure.Diagnostics
 | 
			
		||||
{
 | 
			
		||||
    static class Symbols
 | 
			
		||||
    {
 | 
			
		||||
        private struct RangedSymbol
 | 
			
		||||
        {
 | 
			
		||||
            public readonly ulong Start;
 | 
			
		||||
            public readonly ulong End;
 | 
			
		||||
            public readonly ulong ElementSize;
 | 
			
		||||
            public readonly string Name;
 | 
			
		||||
 | 
			
		||||
            public RangedSymbol(ulong start, ulong end, ulong elemSize, string name)
 | 
			
		||||
            {
 | 
			
		||||
                Start = start;
 | 
			
		||||
                End = end;
 | 
			
		||||
                ElementSize = elemSize;
 | 
			
		||||
                Name = name;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private static readonly ConcurrentDictionary<ulong, string> _symbols;
 | 
			
		||||
        private static readonly List<RangedSymbol> _rangedSymbols;
 | 
			
		||||
 | 
			
		||||
        static Symbols()
 | 
			
		||||
        {
 | 
			
		||||
            _symbols = new ConcurrentDictionary<ulong, string>();
 | 
			
		||||
            _rangedSymbols = new List<RangedSymbol>();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public static string Get(ulong address)
 | 
			
		||||
        {
 | 
			
		||||
            string result;
 | 
			
		||||
 | 
			
		||||
            if (_symbols.TryGetValue(address, out result))
 | 
			
		||||
            {
 | 
			
		||||
                return result;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            lock (_rangedSymbols)
 | 
			
		||||
            {
 | 
			
		||||
                foreach (RangedSymbol symbol in _rangedSymbols)
 | 
			
		||||
                {
 | 
			
		||||
                    if (address >= symbol.Start && address <= symbol.End)
 | 
			
		||||
                    {
 | 
			
		||||
                        ulong diff = address - symbol.Start;
 | 
			
		||||
                        ulong rem = diff % symbol.ElementSize;
 | 
			
		||||
 | 
			
		||||
                        result = symbol.Name + "_" + diff / symbol.ElementSize;
 | 
			
		||||
 | 
			
		||||
                        if (rem != 0)
 | 
			
		||||
                        {
 | 
			
		||||
                            result += "+" + rem;
 | 
			
		||||
                        }
 | 
			
		||||
 | 
			
		||||
                        _symbols.TryAdd(address, result);
 | 
			
		||||
 | 
			
		||||
                        return result;
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return null;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Conditional("M_DEBUG")]
 | 
			
		||||
        public static void Add(ulong address, string name)
 | 
			
		||||
        {
 | 
			
		||||
            _symbols.TryAdd(address, name);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Conditional("M_DEBUG")]
 | 
			
		||||
        public static void Add(ulong address, ulong size, ulong elemSize, string name)
 | 
			
		||||
        {
 | 
			
		||||
            lock (_rangedSymbols)
 | 
			
		||||
            {
 | 
			
		||||
                _rangedSymbols.Add(new RangedSymbol(address, address + size, elemSize, name));
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -1,3 +1,4 @@
 | 
			
		||||
using ARMeilleure.Diagnostics;
 | 
			
		||||
using ARMeilleure.IntermediateRepresentation;
 | 
			
		||||
using ARMeilleure.State;
 | 
			
		||||
using System;
 | 
			
		||||
@ -85,6 +86,8 @@ namespace ARMeilleure.Translation
 | 
			
		||||
 | 
			
		||||
            IntPtr ptr = Marshal.GetFunctionPointerForDelegate<Delegate>(func);
 | 
			
		||||
 | 
			
		||||
            Symbols.Add((ulong)ptr.ToInt64(), func.Method.Name);
 | 
			
		||||
 | 
			
		||||
            OperandType returnType = GetOperandType(func.Method.ReturnType);
 | 
			
		||||
 | 
			
		||||
            return Call(Const(ptr.ToInt64()), returnType, callArgs);
 | 
			
		||||
 | 
			
		||||
@ -1,4 +1,5 @@
 | 
			
		||||
using ARMeilleure.Memory;
 | 
			
		||||
using ARMeilleure.Diagnostics;
 | 
			
		||||
using ARMeilleure.Memory;
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Concurrent;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
@ -60,6 +61,9 @@ namespace ARMeilleure.Translation
 | 
			
		||||
 | 
			
		||||
            _targets = new ConcurrentDictionary<ulong, TranslatedFunction>();
 | 
			
		||||
            _dependants = new ConcurrentDictionary<ulong, LinkedList<int>>();
 | 
			
		||||
 | 
			
		||||
            Symbols.Add((ulong)_jumpRegion.Pointer.ToInt64(), JumpTableByteSize, JumpTableStride, "JMP_TABLE");
 | 
			
		||||
            Symbols.Add((ulong)_dynamicRegion.Pointer.ToInt64(), DynamicTableByteSize, DynamicTableStride, "DYN_TABLE");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void RegisterFunction(ulong address, TranslatedFunction func)
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user