4coder/test_data/lots_of_files/simulate.c

168 lines
3.8 KiB
C

/* EECS 370 LC-2K Instruction-level simulator */
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#define NUMMEMORY 65536 /* maximum number of words in memory */
#define NUMREGS 8 /* number of machine registers */
#define MAXLINELENGTH 1000
typedef struct stateStruct {
int pc;
int mem[NUMMEMORY];
int reg[NUMREGS];
int numMemory;
} stateType;
void printState(stateType *);
#define OP_FILL -1
#define OP_ADD 0
#define OP_NAND 1
#define OP_LW 2
#define OP_SW 3
#define OP_BEQ 4
#define OP_JALR 5
#define OP_HALT 6
#define OP_NOOP 7
#define SHIFT_OP 22
#define SHIFT_A 19
#define SHIFT_B 16
#define SHIFT_C 0
#define MASK_OP (7 << SHIFT_OP)
#define MASK_A (7 << SHIFT_A)
#define MASK_B (7 << SHIFT_B)
#define MASK_C (0xFFFF)
void
decode_insanity(int ins, int *o, int *a, int *b, int *c){
*o = (ins & (MASK_OP)) >> SHIFT_OP;
*a = (ins & (MASK_A)) >> SHIFT_A;
*b = (ins & (MASK_B)) >> SHIFT_B;
*c = (ins & (MASK_C)) >> SHIFT_C;
if (*c & 0x8000) *c |= 0xFFFF0000;
}
int DID_NOOP;
int
execute_insanity(stateType *state, int *e){
int r;
int o,a,b,c;
int m,pc;
pc = state->pc++;
decode_insanity(state->mem[pc], &o, &a, &b, &c);
DID_NOOP = 0;
r = 1;
switch (o){
case OP_ADD:
state->reg[c] = state->reg[a] + state->reg[b];
break;
case OP_NAND:
state->reg[c] = ~(state->reg[a] & state->reg[b]);
break;
case OP_LW:
m = state->reg[a] + c;
state->reg[b] = state->mem[m];
break;
case OP_SW:
m = state->reg[a] + c;
state->mem[m] = state->reg[b];
break;
case OP_BEQ:
if (state->reg[a] == state->reg[b]) state->pc += c;
break;
case OP_JALR:
state->reg[b] = pc+1;
state->pc = state->reg[a];
break;
case OP_HALT:
r = 0;
break;
case OP_NOOP: DID_NOOP = 1; break;
default: r = 0; *e = 1; break;
}
return (r);
}
int
main(int argc, char *argv[])
{
char line[MAXLINELENGTH];
stateType state;
FILE *filePtr;
int cont, e, step_count;
if (argc != 2) {
printf("error: usage: %s <machine-code file>\n", argv[0]);
exit(1);
}
filePtr = fopen(argv[1], "r");
if (filePtr == NULL) {
printf("error: can't open file %s", argv[1]);
perror("fopen");
exit(1);
}
state.pc = 0;
memset(state.reg, 0, sizeof(int)*NUMREGS);
memset(state.mem, 0, sizeof(int)*NUMMEMORY);
/* read in the entire machine-code file into memory */
for (state.numMemory = 0; fgets(line, MAXLINELENGTH, filePtr) != NULL;
state.numMemory++) {
if (sscanf(line, "%d", state.mem+state.numMemory) != 1) {
printf("error in reading address %d\n", state.numMemory);
exit(1);
}
printf("memory[%d]=%d\n", state.numMemory, state.mem[state.numMemory]);
}
step_count = 0;
cont = 1;
while (cont){
printf("steps: %d\n", step_count++);
cont = execute_insanity(&state, &e);
printState(&state);
int x = 0;
}
// if (e) { /*there was an error*/ }
printState(&state);
printf("steps: %d\n", step_count++);
return(0);
}
void
printState(stateType *statePtr)
{
int i;
printf("\n@@@\nstate:\n");
printf("\tpc %d\n", statePtr->pc);
printf("\tmemory:\n");
for (i=0; i<statePtr->numMemory; i++) {
printf("\t\tmem[ %d ] %d\n", i, statePtr->mem[i]);
}
printf("\tregisters:\n");
for (i=0; i<NUMREGS; i++) {
printf("\t\treg[ %d ] %d\n", i, statePtr->reg[i]);
}
printf("end state\n");
}