-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathInstruction.cs
339 lines (310 loc) · 11.9 KB
/
Instruction.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace armsimGUI
{
/// <summary>
/// Class: Instruction
/// Purpose: Holds core instruction values and provides methods to load each
/// Methods: TestBit(uint, byte)
/// GetOperationType(uint)
/// DataRegImmShiftedReg()
/// DataRegShiftedReg()
/// DataImmediate()
/// GetLdStoreAddress()
/// LdStrImmShiftedReg()
/// LdStrMultiple()
/// LoadCond()
/// LoadOptype()
/// LoadRD()
/// LoadRM()
/// LoadRN()
/// LoadShiftVal()
/// LoadShiftType()
/// LoadDataBasics()
/// LoadLdStoreBasics()
///
/// virtual LoadRS()
/// virtual LoadP()
/// virtual LoadB()
/// virtual LoadU()
/// virtual LoadW()
/// virtual LoadL()
/// virtual LoadOpcode()
/// virtual LoadSbit()
/// virtual LoadRotate()
/// virtual LoadRegList()
/// virtual LoadImmediateByte()
/// virtual LoadImmediateInt()
/// </summary>
public class Instruction
{
public byte cond { get; internal set; } // condition value
public byte optype { get; internal set; } // operation type
public byte RN { get; internal set; } // base register RN
public byte RD { get; internal set; } // destination register RD
public byte shiftVal { get; internal set; } // value to shift immediate by
public byte shiftType { get; internal set; } // type of shift operation
public byte RM { get; internal set; } // register shift RM
public uint instructionData { get; internal set; } // copy of instruction data
public bool haltExecution { get; internal set; } // is true if instruction is SWI 0x11, otherwise is false
public bool isBranch { get; internal set; }
public Disassembly disasm { get; internal set; } // object to hold disassembly pieces
public Operation ops { get; internal set; } // operation object to perform operations
public Instruction()
{
Disassembly d = new Disassembly();
ops = new Operation();
disasm = d;
}
#region Public Members
//--------------------------------------------------------------
// Purpose: Tests the value of <bit> in <data>
// Returns: A bool depending on value of <bit>
//--------------------------------------------------------------
public static bool TestBit(uint data, byte bit)
{
uint bits = data & (1U << bit);
return (bits & (1 << bit)) != 0;
}
//--------------------------------------------------------------
// Purpose: Extracts bits 25-27 of <data> (the operation type bits)
// Returns: A byte containing bits 25-27 of <data>
//--------------------------------------------------------------
public static byte GetOperationType(uint data)
{
uint bits = Memory.ExtractBits(data, 25, 27);
byte operationType = (byte)(bits >> 25);
return operationType;
}
//--------------------------------------------------------------
// Purpose: Loads properties corresponding with a register/immediate-shifted register
// data processing instruction
// Returns: nothing
//--------------------------------------------------------------
public void DataRegImmShiftedReg()
{
this.LoadDataBasics();
this.LoadShiftVal();
this.LoadShiftType();
this.LoadRM();
}
//--------------------------------------------------------------
// Purpose: Loads properties corresponding with a register/shifted-register
// data processing instruction
// Returns: nothing
//--------------------------------------------------------------
public void DataRegShiftedReg()
{
this.LoadDataBasics();
this.LoadRS();
this.LoadShiftType();
this.LoadRM();
}
//--------------------------------------------------------------
// Purpose: Loads properties corresponding with an immediate data processing instruction
// Returns: nothing
//--------------------------------------------------------------
public void DataImmediate()
{
this.LoadDataBasics();
this.LoadRotate();
this.LoadImmediateByte();
}
//--------------------------------------------------------------
// Purpose: Loads properties corresponding with an immediate load/store instruction
// Returns: nothing
//--------------------------------------------------------------
public void LdStrImmediate()
{
this.LoadLdStoreBasics();
this.LoadImmediateInt();
this.LoadRD();
}
//--------------------------------------------------------------
// Purpose: Loads properties corresponding with an immediate-shifted register
// load/store instruction
// Returns: nothing
//--------------------------------------------------------------
public void LdStrImmShiftedReg()
{
this.LoadLdStoreBasics();
this.LoadShiftVal();
this.LoadShiftType();
this.LoadRM();
this.LoadRD();
}
//--------------------------------------------------------------
// Purpose: Loads properties corresponding with a load/store multiple instruction
// Returns: nothing
//--------------------------------------------------------------
public void LdStrMultiple()
{
this.LoadLdStoreBasics();
this.LoadRegList();
}
public void LoadDataSWI()
{
this.LoadCond();
optype = 0x0f;
this.LoadDisasmAddrAndCode();
}
public void DataMul()
{
this.LoadCond();
this.LoadOptype();
this.LoadOpcode();
this.LoadSbit();
RD = (byte)(Memory.ExtractBits(this.instructionData, 16, 19) >> 16);
this.LoadRM();
this.LoadRS();
this.LoadDisasmAddrAndCode();
}
public void Branch()
{
this.LoadBranchBasics();
}
public string ShiftTypeToString()
{
switch (this.shiftType)
{
case 0x00:
return "lsl";
case 0x01:
return "lsr";
case 0x02:
return "asr";
case 0x03:
return "ror";
}
return "";
}
#endregion
#region Private Members
//--------------------------------------------------------------
// Purpose: Loads condition property
// Returns: nothing
//--------------------------------------------------------------
private void LoadCond()
{
uint bits = Memory.ExtractBits(instructionData, 28, 31);
cond = (byte)(bits >> 28);
}
//--------------------------------------------------------------
// Purpose: Loads optype property
// Returns: nothing
//--------------------------------------------------------------
private void LoadOptype()
{
uint bits = Memory.ExtractBits(instructionData, 25, 27);
optype = (byte)(bits >> 25);
}
//--------------------------------------------------------------
// Purpose: Loads RD property
// Returns: nothing
//--------------------------------------------------------------
private void LoadRD()
{
uint bits = Memory.ExtractBits(instructionData, 12, 15);
RD = (byte)(bits >> 12);
}
//--------------------------------------------------------------
// Purpose: Loads RM property
// Returns: nothing
//--------------------------------------------------------------
private void LoadRM()
{
RM = (byte)Memory.ExtractBits(instructionData, 0, 3);
}
//--------------------------------------------------------------
// Purpose: Loads RN property
// Returns: nothing
//--------------------------------------------------------------
private void LoadRN()
{
uint bits = Memory.ExtractBits(instructionData, 16, 19);
RN = (byte)(bits >> 16);
}
//--------------------------------------------------------------
// Purpose: Loads shiftVal property
// Returns: nothing
//--------------------------------------------------------------
private void LoadShiftVal()
{
uint bits = Memory.ExtractBits(instructionData, 7, 11);
shiftVal = (byte)(bits >> 7);
}
//--------------------------------------------------------------
// Purpose: Loads shiftType property
// Returns: nothing
//--------------------------------------------------------------
private void LoadShiftType()
{
uint bits = Memory.ExtractBits(instructionData, 5, 6);
shiftType = (byte)(bits >> 5);
}
//--------------------------------------------------------------
// Purpose: Loads the properties common to all data processing instructions
// Returns: nothing
//--------------------------------------------------------------
private void LoadDataBasics()
{
this.LoadBit4();
this.LoadCond();
this.LoadOptype();
this.LoadOpcode();
this.LoadRN();
this.LoadRD();
this.LoadSbit();
this.LoadDisasmAddrAndCode();
}
//--------------------------------------------------------------
// Purpose: Loads the properties common to all load/store instructions
// Returns: nothing
//--------------------------------------------------------------
private void LoadLdStoreBasics()
{
this.LoadP();
this.LoadB();
this.LoadU();
this.LoadW();
this.LoadL();
this.LoadRN();
this.LoadDisasmAddrAndCode();
}
private void LoadBranchBasics()
{
this.LoadDisasmAddrAndCode();
this.LoadCond();
this.LoadType();
this.LoadImmediateInt();
this.LoadLBit();
this.LoadRM();
}
private void LoadDisasmAddrAndCode()
{
this.disasm.address = "0x" + Computer.GetCPU().registers.ReadWord((uint)regs.PC).ToString("x8");
this.disasm.instrCode = "0x" + this.instructionData.ToString("x8");
}
#endregion
#region Virtual Methods
internal virtual void LoadRS() { }
internal virtual void LoadP() { }
internal virtual void LoadB() { }
internal virtual void LoadU() { }
internal virtual void LoadW() { }
internal virtual void LoadL() { }
internal virtual void LoadOpcode() { }
internal virtual void LoadSbit() { }
internal virtual void LoadRotate() { }
internal virtual void LoadRegList() { }
internal virtual void LoadImmediateByte() { }
internal virtual void LoadImmediateInt() { }
internal virtual void LoadBit4() { }
internal virtual void LoadLBit() { }
internal virtual void LoadType() { }
public virtual void ExecuteInstruction(bool b) { }
#endregion
}
}