crashanalysercmd/PerfToolsSharedLibraries/Engine/SymbianStructuresLib/Arm/Registers/General/ArmRegisterCollection.cs
changeset 0 818e61de6cd1
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/crashanalysercmd/PerfToolsSharedLibraries/Engine/SymbianStructuresLib/Arm/Registers/General/ArmRegisterCollection.cs	Thu Feb 11 15:50:58 2010 +0200
@@ -0,0 +1,533 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+* 
+* Description:
+*
+*/
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace SymbianStructuresLib.Arm.Registers
+{
+    public class ArmRegisterCollection : IEnumerable<ArmRegister>, IComparer<ArmRegister>
+    {
+        #region Constructors
+        public ArmRegisterCollection()
+            : this( TArmRegisterBank.ETypeUnknown )
+        {
+        }
+
+        public ArmRegisterCollection( TArmRegisterBank aBank )
+            : this( aBank, null )
+        {
+        }
+
+        public ArmRegisterCollection( TArmRegisterBank aBank, ArmRegisterCollection aLinkedWith )
+        {
+            iBank = aBank;
+            iLinkedWith = aLinkedWith;
+        }
+
+        public ArmRegisterCollection( ArmRegisterCollection aCopy )
+            : this( aCopy.Bank, aCopy.iLinkedWith )
+        {
+            foreach ( ArmRegister reg in aCopy )
+            {
+                ArmRegister copy = new ArmRegister( reg );
+                DoAdd( copy );
+            }
+        }
+        #endregion
+
+        #region API
+        public ArmRegister Add( ArmRegister aRegister )
+        {
+            ArmRegister entry = null;
+            //
+            if ( iBackingStore != null )
+            {
+                string name = aRegister.OriginalName;
+                entry = iBackingStore.ARCBSCreate( aRegister.RegType, name, aRegister.Value );
+                entry = DoAdd( entry );
+            }
+            else
+            {
+                entry = DoAdd( aRegister );
+            }
+            //
+            return entry;
+        }
+
+        public ArmRegister Add( TArmRegisterType aType, uint aValue )
+        {
+            ArmRegister entry = null;
+            if ( iBackingStore != null )
+            {
+                string name = ArmRegister.GetTypeName( aType );
+                entry = iBackingStore.ARCBSCreate( aType, name, aValue );
+            }
+            else
+            {
+                entry = new ArmRegister( aType, aValue );
+            }
+            //
+            entry = DoAdd( entry );
+            return entry;
+        }
+
+        public ArmRegister Add( string aName, uint aValue )
+        {
+            TArmRegisterType type = ArmRegister.GetTypeByName( aName );
+
+            ArmRegister entry = null;
+            if ( iBackingStore != null )
+            {
+                entry = iBackingStore.ARCBSCreate( type, aName, aValue );
+            }
+            else
+            {
+                entry = new ArmRegister( aName, aValue );
+            }
+            //
+            entry = DoAdd( entry );
+            return entry;
+        }
+
+        public void Copy( ArmRegisterCollection aCollection )
+        {
+            foreach ( ArmRegister reg in aCollection )
+            {
+                Add( reg.OriginalName, reg.Value );
+            }
+        }
+
+        public virtual void AddDefaults()
+        {
+            Clear();
+            //
+            Array items = Enum.GetValues( typeof( TArmRegisterType ) );
+            foreach ( object enumEntry in items )
+            {
+                TArmRegisterType value = (TArmRegisterType) enumEntry;
+                if ( value >= TArmRegisterType.EArmReg_00 && value <= TArmRegisterType.EArmReg_EXCPC )
+                {
+                    Add( value, 0 );
+                }
+            }
+        }
+
+        public void AddMany( params TArmRegisterType[] aTypes )
+        {
+            foreach ( TArmRegisterType reg in aTypes )
+            {
+                string name = ArmRegister.GetTypeName( reg );
+                Add( name, 0 );
+            }
+        }
+
+        public void SetAll( uint aValue )
+        {
+            foreach ( ArmRegister reg in this )
+            {
+                reg.Value = aValue;
+            }
+        }
+
+        public bool Contains( TArmRegisterType aType )
+        {
+            if ( aType == TArmRegisterType.EArmReg_Other )
+            {
+                throw new ArgumentException( "Type must be unique" );
+            }
+            //
+            bool ret = false;
+            //
+            foreach ( ArmRegister reg in this )
+            {
+                if ( reg.RegType == aType )
+                {
+                    ret = true;
+                    break;
+                }
+            }
+            //
+            return ret;
+        }
+
+        public bool Contains( string aName )
+        {
+            // Need this to map the specified name into a common name.
+            // I.e. convert R14_USR to R14
+            ArmRegister temp = new ArmRegister( aName, 0 );
+
+            // First try concrete entries
+            bool ret = iEntries.ContainsKey( temp.Name );
+            if ( !ret && iLinkedWith != null )
+            {
+                // Try linked
+                ret = iLinkedWith.Contains( temp.Name );
+            }
+
+            return ret;
+        }
+
+        public void Clear()
+        {
+            if ( iBackingStore != null )
+            {
+                iBackingStore.ARCBSClear();
+            }
+
+            iEntries.Clear();
+        }
+
+        public void Remove( TArmRegisterType aType )
+        {
+            ArmRegister temp = new ArmRegister( aType, 0 );
+            bool contains = iEntries.ContainsKey( temp.Name );
+            if ( contains )
+            {
+                temp = iEntries[ temp.Name ];
+                iEntries.Remove( temp.Name );
+                if ( iBackingStore != null )
+                {
+                    iBackingStore.ARCBSRemove( temp );
+                }
+            }
+        }
+        #endregion
+
+        #region Properties
+        public TArmRegisterBank Bank
+        {
+            get { return iBank; }
+        }
+
+        public ArmRegister this[ ArmRegister aRegister ]
+        {
+            get
+            {
+                ArmRegister ret = this[ aRegister.Name ];
+                return ret;
+            }
+        }
+
+        public ArmRegister this[ TArmRegisterType aType ]
+        {
+            get
+            {
+                // We can only find entries which have a well known name
+                if ( aType == TArmRegisterType.EArmReg_Other )
+                {
+                    throw new ArgumentException( "Type must be unique" );
+                }
+
+                // Check for existing entry
+                foreach ( ArmRegister entry in this )
+                {
+                    if ( entry.RegType == aType )
+                    {
+                        return entry;
+                    }
+                }
+                
+                // The specified entry did not exist so silently
+                // add it and return a reference to the new entry
+                ArmRegister ret = Add( aType, 0 );
+                return ret;
+            }
+        }
+
+        public ArmRegister this[ string aName ]
+        {
+            get
+            {
+                ArmRegister ret = new ArmRegister( aName, 0 );
+
+                // First try concrete entries in this object
+                if ( iEntries.ContainsKey( ret.Name ) )
+                {
+                    ret = iEntries[ ret.Name ];
+                }
+                else if ( iLinkedWith != null && iLinkedWith.Contains( ret.Name ) )
+                {
+                    // Try linked entries
+                    ret = iLinkedWith[ ret.Name ];
+                }
+                else
+                {
+                    // Not found
+                    Add( aName, 0 );
+                }
+                //
+                return ret;
+            }
+        }
+
+        public int Count
+        {
+            get
+            {
+                int ret = iEntries.Count;
+                //
+                if ( iLinkedWith != null )
+                {
+                    ret += iLinkedWith.Count;
+                }
+                //
+                return ret;
+            }
+        }
+
+        public bool IsEmpty
+        {
+            get
+            {
+                bool empty = true;
+                //
+                foreach ( ArmRegister reg in this )
+                {
+                    if ( reg.Value != 0 )
+                    {
+                        empty = false;
+                        break;
+                    }
+                }
+                //
+                return empty;
+            }
+        }
+
+        public object Tag
+        {
+            get { return iTag; }
+            set { iTag = value; }
+        }
+
+        public IARCBackingStore BackingStore
+        {
+            get { return iBackingStore; }
+            set { iBackingStore = value; }
+        }
+        #endregion
+
+        #region Internal methods
+        private void MakeDefaultEntries()
+        {
+            Add( TArmRegisterType.EArmReg_00, 0 );
+            Add( TArmRegisterType.EArmReg_01, 0 );
+            Add( TArmRegisterType.EArmReg_02, 0 );
+            Add( TArmRegisterType.EArmReg_03, 0 );
+            Add( TArmRegisterType.EArmReg_04, 0 );
+            Add( TArmRegisterType.EArmReg_05, 0 );
+            Add( TArmRegisterType.EArmReg_06, 0 );
+            Add( TArmRegisterType.EArmReg_07, 0 );
+            Add( TArmRegisterType.EArmReg_08, 0 );
+            Add( TArmRegisterType.EArmReg_09, 0 );
+            Add( TArmRegisterType.EArmReg_10, 0 );
+            Add( TArmRegisterType.EArmReg_11, 0 );
+            Add( TArmRegisterType.EArmReg_12, 0 );
+            Add( TArmRegisterType.EArmReg_SP, 0 );
+            Add( TArmRegisterType.EArmReg_LR, 0 );
+            Add( TArmRegisterType.EArmReg_PC, 0 );
+            Add( TArmRegisterType.EArmReg_CPSR, 0 );
+        }
+
+        private ArmRegister DoAdd( ArmRegister aRegister )
+        {
+            ArmRegister ret = aRegister;
+            //
+            bool exists = iEntries.ContainsKey( aRegister.Name );
+            if ( exists )
+            {
+                ret = iEntries[ aRegister.Name ];
+                ret.Value = aRegister.Value;
+            }
+            else
+            {
+                // Associate entry with this collection
+                aRegister.Parent = this;
+                iEntries.Add( aRegister.Name, aRegister );
+            }
+            //
+            return ret;
+        }
+        #endregion
+
+        #region From IComparer<ArmRegister>
+        public int Compare( ArmRegister aLeft, ArmRegister aRight )
+        {
+            int ret = -1;
+            //
+            if ( aLeft == null || aRight == null )
+            {
+                if ( aRight == null )
+                {
+                    ret = 1;
+                }
+            }
+            else
+            {
+                // Try to order the registers so that Rnn register names come first
+                // then CPSR, then the other stuff.
+                TArmRegisterType leftType = aLeft.RegType;
+                TArmRegisterType rightType = aRight.RegType;
+                //
+                if ( leftType != TArmRegisterType.EArmReg_Other && rightType == TArmRegisterType.EArmReg_Other )
+                {
+                    // Left is smaller since it's a standard register
+                    ret = -1;
+                }
+                else if ( leftType == TArmRegisterType.EArmReg_Other && rightType != TArmRegisterType.EArmReg_Other )
+                {
+                    // Right is smaller since it's a standard register
+                    ret = 1;
+                }
+                else if ( leftType == TArmRegisterType.EArmReg_Other && rightType == TArmRegisterType.EArmReg_Other )
+                {
+                    // Must compare names since both are non-standard registers
+                    ret = aLeft.OriginalName.CompareTo( aRight.OriginalName );
+                }
+                else
+                {
+                    // Registers are not non-standard, compare based upon numerical value
+                    if ( leftType == rightType )
+                    {
+                        ret = 0;
+                    }
+                    else if ( leftType > rightType )
+                    {
+                        ret = 1;
+                    }
+                }
+            }
+            //
+            return ret;
+        }
+        #endregion
+
+        #region From IEnumerable<ArmRegister>
+        public IEnumerator<ArmRegister> GetEnumerator()
+        {
+            SortedList<string, ArmRegister> entries = new SortedList<string, ArmRegister>();
+
+            // Get specific entries - we always take all of these
+            foreach ( KeyValuePair<string, ArmRegister> kvp in iEntries )
+            {
+                ArmRegister reg = kvp.Value;
+                entries.Add( reg.Name, reg );
+            }
+
+            // And also common entries
+            if ( iLinkedWith != null )
+            {
+                foreach ( ArmRegister reg in iLinkedWith )
+                {
+                    // Make sure that the concrete entries override
+                    // any common values
+                    if ( entries.ContainsKey( reg.Name ) == false )
+                    {
+                        entries.Add( reg.Name, reg );
+                    }
+                }
+            }
+
+            // Ensure list is really sorted.
+            List<ArmRegister> ret = new List<ArmRegister>();
+            foreach ( KeyValuePair<string, ArmRegister> pair in entries )
+            {
+                ret.Add( pair.Value );
+            }
+            ret.Sort( this );
+
+            // Now we can iterate...
+            foreach ( ArmRegister entry in ret )
+            {
+                yield return entry;
+            }
+        }
+
+        System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
+        {
+            SortedList<string, ArmRegister> entries = new SortedList<string, ArmRegister>();
+
+            // Get specific entries - we always take all of these
+            foreach ( KeyValuePair<string, ArmRegister> kvp in iEntries )
+            {
+                ArmRegister reg = kvp.Value;
+                entries.Add( reg.Name, reg );
+            }
+
+            // And also common entries
+            if ( iLinkedWith != null )
+            {
+                foreach ( ArmRegister reg in iLinkedWith )
+                {
+                    // Make sure that the concrete entries override
+                    // any common values
+                    if ( entries.ContainsKey( reg.Name ) == false )
+                    {
+                        entries.Add( reg.Name, reg );
+                    }
+                }
+            }
+
+            // Ensure list is really sorted.
+            List<ArmRegister> ret = new List<ArmRegister>();
+            foreach ( KeyValuePair<string, ArmRegister> pair in entries )
+            {
+                ret.Add( pair.Value );
+            }
+            ret.Sort( this );
+
+            // Now we can iterate...
+            foreach ( ArmRegister entry in ret )
+            {
+                yield return entry;
+            }
+        }
+        #endregion
+
+        #region From System.Object
+        public override string ToString()
+        {
+            StringBuilder ret = new StringBuilder();
+            foreach ( ArmRegister entry in this )
+            {
+                ret.AppendLine( entry.ToString() );
+            }
+            return ret.ToString();
+        }
+        #endregion
+
+        #region Data members
+        private object iTag = null;
+        private readonly TArmRegisterBank iBank;
+        private readonly ArmRegisterCollection iLinkedWith;
+        private string iName = string.Empty;
+        private IARCBackingStore iBackingStore = null;
+        private Dictionary<string, ArmRegister> iEntries = new Dictionary<string, ArmRegister>();
+        #endregion
+    }
+
+    #region Backing store interface
+    public interface IARCBackingStore
+    {
+        void ARCBSClear();
+
+        ArmRegister ARCBSCreate( TArmRegisterType aType, string aName, uint aValue );
+        void ARCBSRemove( ArmRegister aRegister );
+    }
+    #endregion
+}