|
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 ArmRegisterMachine : IEnumerable<ArmRegister> |
|
24 { |
|
25 #region Constructors |
|
26 public ArmRegisterMachine() |
|
27 : this( null ) |
|
28 { |
|
29 } |
|
30 |
|
31 public ArmRegisterMachine( IARMBackingStore aBackingStore ) |
|
32 { |
|
33 iBackingStore = aBackingStore; |
|
34 // |
|
35 Clear(); |
|
36 } |
|
37 #endregion |
|
38 |
|
39 #region API |
|
40 public void Clear() |
|
41 { |
|
42 iBanks.Clear(); |
|
43 |
|
44 // Common registers |
|
45 ArmRegisterCollection common = CreateCollection( TArmRegisterBank.ETypeCommon ); |
|
46 common.AddMany( TArmRegisterType.EArmReg_CPSR, |
|
47 TArmRegisterType.EArmReg_00, |
|
48 TArmRegisterType.EArmReg_01, |
|
49 TArmRegisterType.EArmReg_02, |
|
50 TArmRegisterType.EArmReg_03, |
|
51 TArmRegisterType.EArmReg_04, |
|
52 TArmRegisterType.EArmReg_05, |
|
53 TArmRegisterType.EArmReg_06, |
|
54 TArmRegisterType.EArmReg_07, |
|
55 TArmRegisterType.EArmReg_PC |
|
56 ); |
|
57 AddBank( common ); |
|
58 |
|
59 // User regs |
|
60 ArmRegisterCollection user = CreateCollection( TArmRegisterBank.ETypeUser, common ); |
|
61 user.AddMany( TArmRegisterType.EArmReg_08, |
|
62 TArmRegisterType.EArmReg_09, |
|
63 TArmRegisterType.EArmReg_10, |
|
64 TArmRegisterType.EArmReg_11, |
|
65 TArmRegisterType.EArmReg_12, |
|
66 TArmRegisterType.EArmReg_SP, |
|
67 TArmRegisterType.EArmReg_LR |
|
68 ); |
|
69 AddBank( user ); |
|
70 |
|
71 // These are all fairly normal. They have their own SP, LR and SPSR |
|
72 // The others are common. |
|
73 AddBank( TArmRegisterBank.ETypeAbort, user ); |
|
74 AddBank( TArmRegisterBank.ETypeInterrupt, user ); |
|
75 AddBank( TArmRegisterBank.ETypeSupervisor, user ); |
|
76 AddBank( TArmRegisterBank.ETypeSystem, user ); |
|
77 AddBank( TArmRegisterBank.ETypeUndefined, user ); |
|
78 |
|
79 // FIQ is special - it has shadows of R8->12 |
|
80 AddBank( TArmRegisterBank.ETypeFastInterrupt, common, |
|
81 TArmRegisterType.EArmReg_08, |
|
82 TArmRegisterType.EArmReg_09, |
|
83 TArmRegisterType.EArmReg_10, |
|
84 TArmRegisterType.EArmReg_11, |
|
85 TArmRegisterType.EArmReg_12 |
|
86 ); |
|
87 |
|
88 // Don't forget co-processor or exception regs |
|
89 ArmRegisterCollection exception = CreateCollection( TArmRegisterBank.ETypeException ); |
|
90 exception.AddMany( TArmRegisterType.EArmReg_EXCCODE |
|
91 ); |
|
92 AddBank( exception ); |
|
93 ArmRegisterCollection coprocessor = CreateCollection( TArmRegisterBank.ETypeCoProcessor ); |
|
94 coprocessor.AddMany( TArmRegisterType.EArmReg_FAR, |
|
95 TArmRegisterType.EArmReg_FSR |
|
96 ); |
|
97 AddBank( coprocessor ); |
|
98 } |
|
99 |
|
100 public bool Available( TArmRegisterBank aType ) |
|
101 { |
|
102 bool ret = iBanks.ContainsKey( aType ); |
|
103 return ret; |
|
104 } |
|
105 |
|
106 public ArmRegisterCollection CurrentRegisters() |
|
107 { |
|
108 // Combine all relevant register values into a complete register collection |
|
109 ArmRegisterCollection currentBank = CurrentBank; |
|
110 |
|
111 // Standard regs |
|
112 ArmRegisterCollection ret = CreateCollection( TArmRegisterBank.ETypeUnknown ); |
|
113 foreach( ArmRegister reg in currentBank ) |
|
114 { |
|
115 ret.Add( reg.OriginalName, reg.Value ); |
|
116 } |
|
117 |
|
118 // Co-processor |
|
119 ArmRegisterCollection cop = this[TArmRegisterBank.ETypeCoProcessor]; |
|
120 foreach ( ArmRegister reg in cop ) |
|
121 { |
|
122 ret.Add( reg.OriginalName, reg.Value ); |
|
123 } |
|
124 |
|
125 // Exception |
|
126 ArmRegisterCollection exc = this[ TArmRegisterBank.ETypeException ]; |
|
127 foreach ( ArmRegister reg in exc ) |
|
128 { |
|
129 ret.Add( reg.OriginalName, reg.Value ); |
|
130 } |
|
131 |
|
132 return ret; |
|
133 } |
|
134 #endregion |
|
135 |
|
136 #region Properties |
|
137 public int Count |
|
138 { |
|
139 get { return iBanks.Count; } |
|
140 } |
|
141 |
|
142 public ArmRegister CPSR |
|
143 { |
|
144 get |
|
145 { |
|
146 ArmRegister ret = this[ TArmRegisterBank.ETypeCommon, TArmRegisterType.EArmReg_CPSR ]; |
|
147 return ret; |
|
148 } |
|
149 set |
|
150 { |
|
151 ArmRegister cpsr = CPSR; |
|
152 cpsr.Value = value.Value; |
|
153 } |
|
154 } |
|
155 |
|
156 public TArmRegisterBank CPSRBankType |
|
157 { |
|
158 get |
|
159 { |
|
160 ArmRegister cpsr = CPSR; |
|
161 return ArmRegisterBankUtils.ExtractBank( cpsr ); |
|
162 } |
|
163 } |
|
164 |
|
165 public ArmRegister CurrentSP |
|
166 { |
|
167 get |
|
168 { |
|
169 TArmRegisterBank bank = CPSRBankType; |
|
170 ArmRegister ret = this[ bank, TArmRegisterType.EArmReg_SP ]; |
|
171 return ret; |
|
172 } |
|
173 } |
|
174 |
|
175 public ArmRegister CurrentLR |
|
176 { |
|
177 get |
|
178 { |
|
179 TArmRegisterBank bank = CPSRBankType; |
|
180 ArmRegister ret = this[ bank, TArmRegisterType.EArmReg_LR ]; |
|
181 return ret; |
|
182 } |
|
183 } |
|
184 |
|
185 public ArmRegisterCollection CurrentBank |
|
186 { |
|
187 get |
|
188 { |
|
189 TArmRegisterBank bank = CPSRBankType; |
|
190 return this[ bank ]; |
|
191 } |
|
192 } |
|
193 |
|
194 public ArmRegisterCollection this[ TArmRegisterBank aBank ] |
|
195 { |
|
196 get |
|
197 { |
|
198 ArmRegisterCollection ret = iBanks[ aBank ]; |
|
199 return ret; |
|
200 } |
|
201 } |
|
202 |
|
203 public ArmRegister this[ TArmRegisterBank aBank, string aName ] |
|
204 { |
|
205 get |
|
206 { |
|
207 ArmRegisterCollection bank = this[ aBank ]; |
|
208 return bank[ aName ]; |
|
209 } |
|
210 } |
|
211 |
|
212 public ArmRegister this[ TArmRegisterBank aBank, TArmRegisterType aType ] |
|
213 { |
|
214 get |
|
215 { |
|
216 ArmRegisterCollection bank = this[ aBank ]; |
|
217 return bank[ aType ]; |
|
218 } |
|
219 } |
|
220 #endregion |
|
221 |
|
222 #region Internal methods |
|
223 private ArmRegisterCollection AddBank( TArmRegisterBank aBank ) |
|
224 { |
|
225 return AddBank( aBank, null ); |
|
226 } |
|
227 |
|
228 private ArmRegisterCollection AddBank( TArmRegisterBank aBank, ArmRegisterCollection aLinkedWith ) |
|
229 { |
|
230 TArmRegisterType[] empty = new TArmRegisterType[] { }; |
|
231 return AddBank( aBank, aLinkedWith, empty ); |
|
232 } |
|
233 |
|
234 private ArmRegisterCollection AddBank( TArmRegisterBank aBank, ArmRegisterCollection aLinkedWith, params TArmRegisterType[] aExtraRegs ) |
|
235 { |
|
236 ArmRegisterCollection regSet = CreateCollection( aBank, aLinkedWith ); |
|
237 iBanks.Add( aBank, regSet ); |
|
238 |
|
239 // Create bank specific registers |
|
240 string bankName = ArmRegisterBankUtils.BankAsString( aBank ); |
|
241 regSet.Add( "R13_" + bankName, 0 ); |
|
242 regSet.Add( "R14_" + bankName, 0 ); |
|
243 regSet.Add( "SPSR_" + bankName, 0 ); |
|
244 |
|
245 // Create custom registers |
|
246 foreach( TArmRegisterType custom in aExtraRegs ) |
|
247 { |
|
248 string name = ArmRegister.GetTypeName( custom ) + "_" + bankName; |
|
249 regSet.Add( name, 0 ); |
|
250 } |
|
251 |
|
252 return regSet; |
|
253 } |
|
254 |
|
255 private ArmRegisterCollection AddBank( ArmRegisterCollection aRegSet ) |
|
256 { |
|
257 iBanks.Add( aRegSet.Bank, aRegSet ); |
|
258 return aRegSet; |
|
259 } |
|
260 |
|
261 private ArmRegisterCollection CreateCollection( TArmRegisterBank aBank ) |
|
262 { |
|
263 return CreateCollection( aBank, null ); |
|
264 } |
|
265 |
|
266 private ArmRegisterCollection CreateCollection( TArmRegisterBank aBank, ArmRegisterCollection aLinkedWith ) |
|
267 { |
|
268 ArmRegisterCollection ret = null; |
|
269 // |
|
270 if ( iBackingStore != null ) |
|
271 { |
|
272 ret = iBackingStore.ARMBSCreate( aBank, aLinkedWith ); |
|
273 } |
|
274 else |
|
275 { |
|
276 ret = new ArmRegisterCollection( aBank, aLinkedWith ); |
|
277 } |
|
278 // |
|
279 return ret; |
|
280 } |
|
281 #endregion |
|
282 |
|
283 #region Internal constants |
|
284 #endregion |
|
285 |
|
286 #region From System.Object |
|
287 public override string ToString() |
|
288 { |
|
289 return base.ToString(); |
|
290 } |
|
291 #endregion |
|
292 |
|
293 #region From IEnumerable<ArmRegister> |
|
294 public IEnumerator<ArmRegister> GetEnumerator() |
|
295 { |
|
296 SortedList<string, ArmRegister> entries = new SortedList<string, ArmRegister>(); |
|
297 |
|
298 // Get specific entries - we always take all of these |
|
299 foreach ( KeyValuePair<TArmRegisterBank, ArmRegisterCollection> kvp in iBanks ) |
|
300 { |
|
301 ArmRegisterCollection regs = kvp.Value; |
|
302 foreach ( ArmRegister reg in regs ) |
|
303 { |
|
304 string key = reg.Value.ToString( "x8" ) + "_" + reg.OriginalName; |
|
305 if ( !entries.ContainsKey( key ) ) |
|
306 { |
|
307 entries.Add( key, reg ); |
|
308 } |
|
309 } |
|
310 } |
|
311 |
|
312 // Now we can iterate... |
|
313 foreach ( ArmRegister entry in entries.Values ) |
|
314 { |
|
315 yield return entry; |
|
316 } |
|
317 } |
|
318 |
|
319 System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() |
|
320 { |
|
321 SortedList<string, ArmRegister> entries = new SortedList<string, ArmRegister>(); |
|
322 |
|
323 // Get specific entries - we always take all of these |
|
324 foreach ( KeyValuePair<TArmRegisterBank, ArmRegisterCollection> kvp in iBanks ) |
|
325 { |
|
326 ArmRegisterCollection regs = kvp.Value; |
|
327 foreach ( ArmRegister reg in regs ) |
|
328 { |
|
329 string key = reg.Value.ToString( "x8" ) + "_" + reg.OriginalName; |
|
330 if ( !entries.ContainsKey( key ) ) |
|
331 { |
|
332 entries.Add( key, reg ); |
|
333 } |
|
334 } |
|
335 } |
|
336 |
|
337 // Now we can iterate... |
|
338 foreach ( ArmRegister entry in entries.Values ) |
|
339 { |
|
340 yield return entry; |
|
341 } |
|
342 } |
|
343 #endregion |
|
344 |
|
345 #region Data members |
|
346 private IARMBackingStore iBackingStore = null; |
|
347 private Dictionary<TArmRegisterBank, ArmRegisterCollection> iBanks = new Dictionary<TArmRegisterBank, ArmRegisterCollection>(); |
|
348 #endregion |
|
349 } |
|
350 |
|
351 #region Machine backing store |
|
352 public interface IARMBackingStore |
|
353 { |
|
354 ArmRegisterCollection ARMBSCreate( TArmRegisterBank aBank, ArmRegisterCollection aLinkedWith ); |
|
355 } |
|
356 #endregion |
|
357 } |