-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathISS.c
More file actions
294 lines (236 loc) · 7.65 KB
/
ISS.c
File metadata and controls
294 lines (236 loc) · 7.65 KB
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
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
/*
Simple Instruction Set Simulator (ISS): Loads assembly code in from file, simulates
execution of limited set of instructions. Reports total cycle count, total # executed
instructions, total number instructions in code, #hits to cache, # LD/ST executed
System Specs:
8-bit processor
6 8-bit integer registers [R1,R6]
byte-addressable 256Byte cache
Supported instructions:
MOV Rn, <num> --> stores 8-bit integer [-128,127] in register Rn
ADD Rn, Rm --> Adds registers and stores result in Rn
ADD Rn, <num> --> Adds immediate to value stored in Rn
CMP Rn, RM --> Tests for equality b/w registers, sets flag
JE <Address> --> jumps to instruction at Address IF CMP flag is set
JMP <Address> --> unconditional jump
LD Rn, [Rm] --> Loads from address stored in Rm into Rn
ST [Rm], Rn --> Stores contents of Rn into memory address in Rm
Cycles per instruction:
MOV, ADD, JMP --> 1cycle
CMP --> 2cycle
LD/ST --> 2cycle (hit) or 40cycle (miss)
*/
// Assembly code constraints
#define MAX_INSTR 512 // Arbitrary code size limit
int entryPt = 1024; // stores min instruction index (starts at max)
int exitPt = -1; // stores max instruction index
// Hardware variables
int isEqual = 0; // CMP result flag (0 means unequal, 1 means equal)
int8_t registers[6]; // 6 8-bit registers
int8_t cache[256]; // 256B byte-addressable memory
uint8_t valid[256] = {0}; // valid bits for cache
// Counters for output
int executed = 0;
int cycles = 0;
int hits = 0;
int LdSt = 0;
// functions for parsing/executing assembly code
void parse_assembly(char *filename, char opCodes[], int8_t operands[][2]);
void exec_assembly(char opCodes[], int8_t operands[][2]);
int main(int argc, char* argv[]) {
char opCodes[MAX_INSTR]; // store instructions as characters
int8_t operands[MAX_INSTR][2]; // store operands as 8-bit integers
/* Check input arguments */
if( argc != 2)
{printf("enter assembly code filename\n");exit(0);}
// decompose assembly into char operations and int operands
parse_assembly(argv[1], opCodes, operands);
// Execute assembly code
exec_assembly(opCodes, operands);
printf("Total number of instructions in the code: %d\n", exitPt - entryPt + 1);
printf("Total number of executed instructions: %d\n", executed);
printf("Total number of clock cycles: %d\n", cycles);
printf("Number of hits to local memory: %d\n", hits);
printf("Total number of executed LD/ST instructions: %d\n", LdSt);
/*
// print out parsed assembly
int i,j;
for (i=entryPt; i <= exitPt; i++) {
printf("%d: [%c]", i, opCodes[i]);
for (j = 0; j < 2; j++) {
printf("[%d]", operands[i][j]);
if(opCodes[i] == 'j' || opCodes[i] == 'J') j++;
}
printf("\n");
}
*/
return 0;
}
void exec_assembly(char opCodes[], int8_t operands[][2]) {
int ip = entryPt; // Instruction pointer
while (ip <= exitPt) {
// printf("%d\n", ip);
executed++; //Increment executed instruction count
switch( opCodes[ip] ) {
case 'm': // MOV
registers[ operands[ip][0] ] = operands[ip][1];
cycles++;
ip++;
break;
case 'a': // ADD (Register)
registers[ operands[ip][0] ] = registers[ operands[ip][0] ] + registers[ operands[ip][1] ];
cycles++;
ip++;
break;
case 'A': // ADD (Immediate)
registers[ operands[ip][0] ] = registers[ operands[ip][0] ] + operands[ip][1];
cycles++;
ip++;
break;
case 'l': // LD
registers[ operands[ip][0] ] = cache[ operands[ip][1] ];
if(valid[ registers[ operands[ip][1] ] ] ==0) { // cache miss
cycles += 40;
valid[ registers[ operands[ip][1] ] ] = 1;
}
else { // cache hit
cycles += 2;
hits++;
}
ip++;
LdSt++;
break;
case 's': // ST
cache[ operands[ip][0] ] = registers[ operands[ip][1] ];
if(valid[ registers[ operands[ip][0] ] ] ==0) { // cache miss
cycles += 40;
valid[ registers[ operands[ip][0] ] ] = 1;
}
else { // cache hit
cycles += 2;
hits++;
}
ip++;
LdSt++;
break;
case 'c': // CMP
if (registers[ operands[ip][0] ] == registers[ operands[ip][1] ])
isEqual = 1;
else
isEqual = 0;
ip++;
cycles+=2;
break;
case 'j': // JE (conditional)
if(isEqual == 1)
ip = operands[ip][0];
else
ip++;
cycles++;
break;
case 'J': // JMP (unconditional)
ip = operands[ip][0];
cycles++;
break;
}
}
}
void parse_assembly(char *filename, char opCodes[], int8_t operands[][2]) {
// File i/o
FILE *assembly = fopen(filename, "r");
char line[256]; /* buffer for each line */
// Line parsing
char *token; //holds current substring
const char tab[2] = "\t";
const char spc[2] = " ";
const char com[2] = ",";
const char nln[2] = "\n";
const char brk[2] = "]";
int index;
char op;
// Read each line from file, parse into operands
while (fgets(line, sizeof(line), assembly)) {
// Grab line number
token = strtok(line, tab);
// findindex, update program bounds
index = atoi(token);
if ( entryPt > index) entryPt = index;
if ( exitPt < index) exitPt = index;
// Grab operation
token = strtok(NULL, spc);
// Encode operation as character
if(strcmp("MOV", token) == 0) op = 'm';
else if(strcmp("ADD", token) == 0) op = 'a'; //AddImmediate updates further down
else if(strcmp("LD", token) == 0) op = 'l';
else if(strcmp("ST", token) == 0) op = 's';
else if(strcmp("CMP", token) == 0) op = 'c';
else if(strcmp("JE", token) == 0) op = 'j';
else if(strcmp("JMP", token) == 0) op = 'J';
else{printf("invalid instruction\n"); exit(0);}
switch (op) {
case 'm':
// Grab first operand
token = strtok(NULL, com);
token++; // Remove 'R'
operands[index][0] = (int8_t)atoi(token);
// Grab second operand --> Never a register
token = strtok(NULL, spc);
operands[index][1] = (int8_t)atoi(token);
break;
case 'a':
// Grab first operand
token = strtok(NULL, com);
token++; // Remove 'R'
operands[index][0] = (int8_t)atoi(token);
// Grab second operand --> may be register or Immediate
token = strtok(NULL, spc);
if(token[0] == 'R')
token++; // If register, remove 'R'
else
op = 'A'; // Else, redesignate as Add Immediate
operands[index][1] = (int8_t)atoi(token);
break;
case 'c':
// Grab first operand
token = strtok(NULL, com);
token++; // Remove 'R'
operands[index][0] = (int8_t)atoi(token);
// Grab second operand --> Always a register
token = strtok(NULL, spc);
token++; // Remove 'R'
operands[index][1] = (int8_t)atoi(token);
break;
case 'l':
// Grab first operand
token = strtok(NULL, com);
token++; // Remove 'R'
operands[index][0] = (int8_t)atoi(token);
// Grab second operand --> Always memory indirect
token = strtok(NULL, brk);
token += 3; // Remove ' [R'
operands[index][1] = (int8_t)atoi(token);
break;
case 's':
// Grab first operand --> Always memory indirect
token = strtok(NULL, brk);
token += 2; // Remove "[R"
operands[index][0] = (int8_t)atoi(token);
// Grab second operand --> Always register
token = strtok(NULL, brk);
token += 3; // Remove ", R"
operands[index][1] = (int8_t)atoi(token);
break;
case 'j': case 'J':
// Grab ONLY operand --> never a register
token = strtok(NULL, spc);
operands[index][0] = (int8_t)atoi(token);
break;
}
opCodes[index] = op; // store opCode
}
fclose(assembly);
}