crashanalysercmd/PerfToolsSharedLibraries/Engine/SymbianStructuresLib/Arm/Registers/General/ArmRegisterCollection.cs
changeset 0 818e61de6cd1
equal deleted inserted replaced
-1:000000000000 0:818e61de6cd1
       
     1 /*
       
     2 * Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 * 
       
    14 * Description:
       
    15 *
       
    16 */
       
    17 using System;
       
    18 using System.Collections.Generic;
       
    19 using System.Text;
       
    20 
       
    21 namespace SymbianStructuresLib.Arm.Registers
       
    22 {
       
    23     public class ArmRegisterCollection : IEnumerable<ArmRegister>, IComparer<ArmRegister>
       
    24     {
       
    25         #region Constructors
       
    26         public ArmRegisterCollection()
       
    27             : this( TArmRegisterBank.ETypeUnknown )
       
    28         {
       
    29         }
       
    30 
       
    31         public ArmRegisterCollection( TArmRegisterBank aBank )
       
    32             : this( aBank, null )
       
    33         {
       
    34         }
       
    35 
       
    36         public ArmRegisterCollection( TArmRegisterBank aBank, ArmRegisterCollection aLinkedWith )
       
    37         {
       
    38             iBank = aBank;
       
    39             iLinkedWith = aLinkedWith;
       
    40         }
       
    41 
       
    42         public ArmRegisterCollection( ArmRegisterCollection aCopy )
       
    43             : this( aCopy.Bank, aCopy.iLinkedWith )
       
    44         {
       
    45             foreach ( ArmRegister reg in aCopy )
       
    46             {
       
    47                 ArmRegister copy = new ArmRegister( reg );
       
    48                 DoAdd( copy );
       
    49             }
       
    50         }
       
    51         #endregion
       
    52 
       
    53         #region API
       
    54         public ArmRegister Add( ArmRegister aRegister )
       
    55         {
       
    56             ArmRegister entry = null;
       
    57             //
       
    58             if ( iBackingStore != null )
       
    59             {
       
    60                 string name = aRegister.OriginalName;
       
    61                 entry = iBackingStore.ARCBSCreate( aRegister.RegType, name, aRegister.Value );
       
    62                 entry = DoAdd( entry );
       
    63             }
       
    64             else
       
    65             {
       
    66                 entry = DoAdd( aRegister );
       
    67             }
       
    68             //
       
    69             return entry;
       
    70         }
       
    71 
       
    72         public ArmRegister Add( TArmRegisterType aType, uint aValue )
       
    73         {
       
    74             ArmRegister entry = null;
       
    75             if ( iBackingStore != null )
       
    76             {
       
    77                 string name = ArmRegister.GetTypeName( aType );
       
    78                 entry = iBackingStore.ARCBSCreate( aType, name, aValue );
       
    79             }
       
    80             else
       
    81             {
       
    82                 entry = new ArmRegister( aType, aValue );
       
    83             }
       
    84             //
       
    85             entry = DoAdd( entry );
       
    86             return entry;
       
    87         }
       
    88 
       
    89         public ArmRegister Add( string aName, uint aValue )
       
    90         {
       
    91             TArmRegisterType type = ArmRegister.GetTypeByName( aName );
       
    92 
       
    93             ArmRegister entry = null;
       
    94             if ( iBackingStore != null )
       
    95             {
       
    96                 entry = iBackingStore.ARCBSCreate( type, aName, aValue );
       
    97             }
       
    98             else
       
    99             {
       
   100                 entry = new ArmRegister( aName, aValue );
       
   101             }
       
   102             //
       
   103             entry = DoAdd( entry );
       
   104             return entry;
       
   105         }
       
   106 
       
   107         public void Copy( ArmRegisterCollection aCollection )
       
   108         {
       
   109             foreach ( ArmRegister reg in aCollection )
       
   110             {
       
   111                 Add( reg.OriginalName, reg.Value );
       
   112             }
       
   113         }
       
   114 
       
   115         public virtual void AddDefaults()
       
   116         {
       
   117             Clear();
       
   118             //
       
   119             Array items = Enum.GetValues( typeof( TArmRegisterType ) );
       
   120             foreach ( object enumEntry in items )
       
   121             {
       
   122                 TArmRegisterType value = (TArmRegisterType) enumEntry;
       
   123                 if ( value >= TArmRegisterType.EArmReg_00 && value <= TArmRegisterType.EArmReg_EXCPC )
       
   124                 {
       
   125                     Add( value, 0 );
       
   126                 }
       
   127             }
       
   128         }
       
   129 
       
   130         public void AddMany( params TArmRegisterType[] aTypes )
       
   131         {
       
   132             foreach ( TArmRegisterType reg in aTypes )
       
   133             {
       
   134                 string name = ArmRegister.GetTypeName( reg );
       
   135                 Add( name, 0 );
       
   136             }
       
   137         }
       
   138 
       
   139         public void SetAll( uint aValue )
       
   140         {
       
   141             foreach ( ArmRegister reg in this )
       
   142             {
       
   143                 reg.Value = aValue;
       
   144             }
       
   145         }
       
   146 
       
   147         public bool Contains( TArmRegisterType aType )
       
   148         {
       
   149             if ( aType == TArmRegisterType.EArmReg_Other )
       
   150             {
       
   151                 throw new ArgumentException( "Type must be unique" );
       
   152             }
       
   153             //
       
   154             bool ret = false;
       
   155             //
       
   156             foreach ( ArmRegister reg in this )
       
   157             {
       
   158                 if ( reg.RegType == aType )
       
   159                 {
       
   160                     ret = true;
       
   161                     break;
       
   162                 }
       
   163             }
       
   164             //
       
   165             return ret;
       
   166         }
       
   167 
       
   168         public bool Contains( string aName )
       
   169         {
       
   170             // Need this to map the specified name into a common name.
       
   171             // I.e. convert R14_USR to R14
       
   172             ArmRegister temp = new ArmRegister( aName, 0 );
       
   173 
       
   174             // First try concrete entries
       
   175             bool ret = iEntries.ContainsKey( temp.Name );
       
   176             if ( !ret && iLinkedWith != null )
       
   177             {
       
   178                 // Try linked
       
   179                 ret = iLinkedWith.Contains( temp.Name );
       
   180             }
       
   181 
       
   182             return ret;
       
   183         }
       
   184 
       
   185         public void Clear()
       
   186         {
       
   187             if ( iBackingStore != null )
       
   188             {
       
   189                 iBackingStore.ARCBSClear();
       
   190             }
       
   191 
       
   192             iEntries.Clear();
       
   193         }
       
   194 
       
   195         public void Remove( TArmRegisterType aType )
       
   196         {
       
   197             ArmRegister temp = new ArmRegister( aType, 0 );
       
   198             bool contains = iEntries.ContainsKey( temp.Name );
       
   199             if ( contains )
       
   200             {
       
   201                 temp = iEntries[ temp.Name ];
       
   202                 iEntries.Remove( temp.Name );
       
   203                 if ( iBackingStore != null )
       
   204                 {
       
   205                     iBackingStore.ARCBSRemove( temp );
       
   206                 }
       
   207             }
       
   208         }
       
   209         #endregion
       
   210 
       
   211         #region Properties
       
   212         public TArmRegisterBank Bank
       
   213         {
       
   214             get { return iBank; }
       
   215         }
       
   216 
       
   217         public ArmRegister this[ ArmRegister aRegister ]
       
   218         {
       
   219             get
       
   220             {
       
   221                 ArmRegister ret = this[ aRegister.Name ];
       
   222                 return ret;
       
   223             }
       
   224         }
       
   225 
       
   226         public ArmRegister this[ TArmRegisterType aType ]
       
   227         {
       
   228             get
       
   229             {
       
   230                 // We can only find entries which have a well known name
       
   231                 if ( aType == TArmRegisterType.EArmReg_Other )
       
   232                 {
       
   233                     throw new ArgumentException( "Type must be unique" );
       
   234                 }
       
   235 
       
   236                 // Check for existing entry
       
   237                 foreach ( ArmRegister entry in this )
       
   238                 {
       
   239                     if ( entry.RegType == aType )
       
   240                     {
       
   241                         return entry;
       
   242                     }
       
   243                 }
       
   244                 
       
   245                 // The specified entry did not exist so silently
       
   246                 // add it and return a reference to the new entry
       
   247                 ArmRegister ret = Add( aType, 0 );
       
   248                 return ret;
       
   249             }
       
   250         }
       
   251 
       
   252         public ArmRegister this[ string aName ]
       
   253         {
       
   254             get
       
   255             {
       
   256                 ArmRegister ret = new ArmRegister( aName, 0 );
       
   257 
       
   258                 // First try concrete entries in this object
       
   259                 if ( iEntries.ContainsKey( ret.Name ) )
       
   260                 {
       
   261                     ret = iEntries[ ret.Name ];
       
   262                 }
       
   263                 else if ( iLinkedWith != null && iLinkedWith.Contains( ret.Name ) )
       
   264                 {
       
   265                     // Try linked entries
       
   266                     ret = iLinkedWith[ ret.Name ];
       
   267                 }
       
   268                 else
       
   269                 {
       
   270                     // Not found
       
   271                     Add( aName, 0 );
       
   272                 }
       
   273                 //
       
   274                 return ret;
       
   275             }
       
   276         }
       
   277 
       
   278         public int Count
       
   279         {
       
   280             get
       
   281             {
       
   282                 int ret = iEntries.Count;
       
   283                 //
       
   284                 if ( iLinkedWith != null )
       
   285                 {
       
   286                     ret += iLinkedWith.Count;
       
   287                 }
       
   288                 //
       
   289                 return ret;
       
   290             }
       
   291         }
       
   292 
       
   293         public bool IsEmpty
       
   294         {
       
   295             get
       
   296             {
       
   297                 bool empty = true;
       
   298                 //
       
   299                 foreach ( ArmRegister reg in this )
       
   300                 {
       
   301                     if ( reg.Value != 0 )
       
   302                     {
       
   303                         empty = false;
       
   304                         break;
       
   305                     }
       
   306                 }
       
   307                 //
       
   308                 return empty;
       
   309             }
       
   310         }
       
   311 
       
   312         public object Tag
       
   313         {
       
   314             get { return iTag; }
       
   315             set { iTag = value; }
       
   316         }
       
   317 
       
   318         public IARCBackingStore BackingStore
       
   319         {
       
   320             get { return iBackingStore; }
       
   321             set { iBackingStore = value; }
       
   322         }
       
   323         #endregion
       
   324 
       
   325         #region Internal methods
       
   326         private void MakeDefaultEntries()
       
   327         {
       
   328             Add( TArmRegisterType.EArmReg_00, 0 );
       
   329             Add( TArmRegisterType.EArmReg_01, 0 );
       
   330             Add( TArmRegisterType.EArmReg_02, 0 );
       
   331             Add( TArmRegisterType.EArmReg_03, 0 );
       
   332             Add( TArmRegisterType.EArmReg_04, 0 );
       
   333             Add( TArmRegisterType.EArmReg_05, 0 );
       
   334             Add( TArmRegisterType.EArmReg_06, 0 );
       
   335             Add( TArmRegisterType.EArmReg_07, 0 );
       
   336             Add( TArmRegisterType.EArmReg_08, 0 );
       
   337             Add( TArmRegisterType.EArmReg_09, 0 );
       
   338             Add( TArmRegisterType.EArmReg_10, 0 );
       
   339             Add( TArmRegisterType.EArmReg_11, 0 );
       
   340             Add( TArmRegisterType.EArmReg_12, 0 );
       
   341             Add( TArmRegisterType.EArmReg_SP, 0 );
       
   342             Add( TArmRegisterType.EArmReg_LR, 0 );
       
   343             Add( TArmRegisterType.EArmReg_PC, 0 );
       
   344             Add( TArmRegisterType.EArmReg_CPSR, 0 );
       
   345         }
       
   346 
       
   347         private ArmRegister DoAdd( ArmRegister aRegister )
       
   348         {
       
   349             ArmRegister ret = aRegister;
       
   350             //
       
   351             bool exists = iEntries.ContainsKey( aRegister.Name );
       
   352             if ( exists )
       
   353             {
       
   354                 ret = iEntries[ aRegister.Name ];
       
   355                 ret.Value = aRegister.Value;
       
   356             }
       
   357             else
       
   358             {
       
   359                 // Associate entry with this collection
       
   360                 aRegister.Parent = this;
       
   361                 iEntries.Add( aRegister.Name, aRegister );
       
   362             }
       
   363             //
       
   364             return ret;
       
   365         }
       
   366         #endregion
       
   367 
       
   368         #region From IComparer<ArmRegister>
       
   369         public int Compare( ArmRegister aLeft, ArmRegister aRight )
       
   370         {
       
   371             int ret = -1;
       
   372             //
       
   373             if ( aLeft == null || aRight == null )
       
   374             {
       
   375                 if ( aRight == null )
       
   376                 {
       
   377                     ret = 1;
       
   378                 }
       
   379             }
       
   380             else
       
   381             {
       
   382                 // Try to order the registers so that Rnn register names come first
       
   383                 // then CPSR, then the other stuff.
       
   384                 TArmRegisterType leftType = aLeft.RegType;
       
   385                 TArmRegisterType rightType = aRight.RegType;
       
   386                 //
       
   387                 if ( leftType != TArmRegisterType.EArmReg_Other && rightType == TArmRegisterType.EArmReg_Other )
       
   388                 {
       
   389                     // Left is smaller since it's a standard register
       
   390                     ret = -1;
       
   391                 }
       
   392                 else if ( leftType == TArmRegisterType.EArmReg_Other && rightType != TArmRegisterType.EArmReg_Other )
       
   393                 {
       
   394                     // Right is smaller since it's a standard register
       
   395                     ret = 1;
       
   396                 }
       
   397                 else if ( leftType == TArmRegisterType.EArmReg_Other && rightType == TArmRegisterType.EArmReg_Other )
       
   398                 {
       
   399                     // Must compare names since both are non-standard registers
       
   400                     ret = aLeft.OriginalName.CompareTo( aRight.OriginalName );
       
   401                 }
       
   402                 else
       
   403                 {
       
   404                     // Registers are not non-standard, compare based upon numerical value
       
   405                     if ( leftType == rightType )
       
   406                     {
       
   407                         ret = 0;
       
   408                     }
       
   409                     else if ( leftType > rightType )
       
   410                     {
       
   411                         ret = 1;
       
   412                     }
       
   413                 }
       
   414             }
       
   415             //
       
   416             return ret;
       
   417         }
       
   418         #endregion
       
   419 
       
   420         #region From IEnumerable<ArmRegister>
       
   421         public IEnumerator<ArmRegister> GetEnumerator()
       
   422         {
       
   423             SortedList<string, ArmRegister> entries = new SortedList<string, ArmRegister>();
       
   424 
       
   425             // Get specific entries - we always take all of these
       
   426             foreach ( KeyValuePair<string, ArmRegister> kvp in iEntries )
       
   427             {
       
   428                 ArmRegister reg = kvp.Value;
       
   429                 entries.Add( reg.Name, reg );
       
   430             }
       
   431 
       
   432             // And also common entries
       
   433             if ( iLinkedWith != null )
       
   434             {
       
   435                 foreach ( ArmRegister reg in iLinkedWith )
       
   436                 {
       
   437                     // Make sure that the concrete entries override
       
   438                     // any common values
       
   439                     if ( entries.ContainsKey( reg.Name ) == false )
       
   440                     {
       
   441                         entries.Add( reg.Name, reg );
       
   442                     }
       
   443                 }
       
   444             }
       
   445 
       
   446             // Ensure list is really sorted.
       
   447             List<ArmRegister> ret = new List<ArmRegister>();
       
   448             foreach ( KeyValuePair<string, ArmRegister> pair in entries )
       
   449             {
       
   450                 ret.Add( pair.Value );
       
   451             }
       
   452             ret.Sort( this );
       
   453 
       
   454             // Now we can iterate...
       
   455             foreach ( ArmRegister entry in ret )
       
   456             {
       
   457                 yield return entry;
       
   458             }
       
   459         }
       
   460 
       
   461         System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
       
   462         {
       
   463             SortedList<string, ArmRegister> entries = new SortedList<string, ArmRegister>();
       
   464 
       
   465             // Get specific entries - we always take all of these
       
   466             foreach ( KeyValuePair<string, ArmRegister> kvp in iEntries )
       
   467             {
       
   468                 ArmRegister reg = kvp.Value;
       
   469                 entries.Add( reg.Name, reg );
       
   470             }
       
   471 
       
   472             // And also common entries
       
   473             if ( iLinkedWith != null )
       
   474             {
       
   475                 foreach ( ArmRegister reg in iLinkedWith )
       
   476                 {
       
   477                     // Make sure that the concrete entries override
       
   478                     // any common values
       
   479                     if ( entries.ContainsKey( reg.Name ) == false )
       
   480                     {
       
   481                         entries.Add( reg.Name, reg );
       
   482                     }
       
   483                 }
       
   484             }
       
   485 
       
   486             // Ensure list is really sorted.
       
   487             List<ArmRegister> ret = new List<ArmRegister>();
       
   488             foreach ( KeyValuePair<string, ArmRegister> pair in entries )
       
   489             {
       
   490                 ret.Add( pair.Value );
       
   491             }
       
   492             ret.Sort( this );
       
   493 
       
   494             // Now we can iterate...
       
   495             foreach ( ArmRegister entry in ret )
       
   496             {
       
   497                 yield return entry;
       
   498             }
       
   499         }
       
   500         #endregion
       
   501 
       
   502         #region From System.Object
       
   503         public override string ToString()
       
   504         {
       
   505             StringBuilder ret = new StringBuilder();
       
   506             foreach ( ArmRegister entry in this )
       
   507             {
       
   508                 ret.AppendLine( entry.ToString() );
       
   509             }
       
   510             return ret.ToString();
       
   511         }
       
   512         #endregion
       
   513 
       
   514         #region Data members
       
   515         private object iTag = null;
       
   516         private readonly TArmRegisterBank iBank;
       
   517         private readonly ArmRegisterCollection iLinkedWith;
       
   518         private string iName = string.Empty;
       
   519         private IARCBackingStore iBackingStore = null;
       
   520         private Dictionary<string, ArmRegister> iEntries = new Dictionary<string, ArmRegister>();
       
   521         #endregion
       
   522     }
       
   523 
       
   524     #region Backing store interface
       
   525     public interface IARCBackingStore
       
   526     {
       
   527         void ARCBSClear();
       
   528 
       
   529         ArmRegister ARCBSCreate( TArmRegisterType aType, string aName, uint aValue );
       
   530         void ARCBSRemove( ArmRegister aRegister );
       
   531     }
       
   532     #endregion
       
   533 }