diff -r 000000000000 -r 818e61de6cd1 crashanalysercmd/PerfToolsSharedLibraries/Engine/SymbianStructuresLib/Arm/Registers/General/ArmRegisterCollection.cs --- /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, IComparer + { + #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 + 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 + public IEnumerator GetEnumerator() + { + SortedList entries = new SortedList(); + + // Get specific entries - we always take all of these + foreach ( KeyValuePair 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 ret = new List(); + foreach ( KeyValuePair 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 entries = new SortedList(); + + // Get specific entries - we always take all of these + foreach ( KeyValuePair 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 ret = new List(); + foreach ( KeyValuePair 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 iEntries = new Dictionary(); + #endregion + } + + #region Backing store interface + public interface IARCBackingStore + { + void ARCBSClear(); + + ArmRegister ARCBSCreate( TArmRegisterType aType, string aName, uint aValue ); + void ARCBSRemove( ArmRegister aRegister ); + } + #endregion +}